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 "llvm/ADT/APFloat.h"
15 #include "llvm/ADT/STLExtras.h"
16 #include "llvm/ADT/SmallString.h"
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/ADT/StringSwitch.h"
19 #include "llvm/ADT/Twine.h"
20 #include "llvm/MC/MCContext.h"
21 #include "llvm/MC/MCExpr.h"
22 #include "llvm/MC/MCInst.h"
23 #include "llvm/MC/MCInstrInfo.h"
24 #include "llvm/MC/MCParser/MCAsmLexer.h"
25 #include "llvm/MC/MCParser/MCAsmParser.h"
26 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
27 #include "llvm/MC/MCRegisterInfo.h"
28 #include "llvm/MC/MCSection.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 {
60 const MCInstrInfo &MII;
61 ParseInstructionInfo *InstInfo;
62 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);
159 // Push any remaining operators onto the postfix stack.
160 while (!InfixOperatorStack.empty()) {
161 InfixCalculatorTok StackOp = InfixOperatorStack.pop_back_val();
162 if (StackOp != IC_LPAREN && StackOp != IC_RPAREN)
163 PostfixStack.push_back(std::make_pair(StackOp, 0));
166 if (PostfixStack.empty())
169 SmallVector<ICToken, 16> OperandStack;
170 for (unsigned i = 0, e = PostfixStack.size(); i != e; ++i) {
171 ICToken Op = PostfixStack[i];
172 if (Op.first == IC_IMM || Op.first == IC_REGISTER) {
173 OperandStack.push_back(Op);
175 assert (OperandStack.size() > 1 && "Too few operands.");
177 ICToken Op2 = OperandStack.pop_back_val();
178 ICToken Op1 = OperandStack.pop_back_val();
181 report_fatal_error("Unexpected operator!");
184 Val = Op1.second + Op2.second;
185 OperandStack.push_back(std::make_pair(IC_IMM, Val));
188 Val = Op1.second - Op2.second;
189 OperandStack.push_back(std::make_pair(IC_IMM, Val));
192 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
193 "Multiply operation with an immediate and a register!");
194 Val = Op1.second * Op2.second;
195 OperandStack.push_back(std::make_pair(IC_IMM, Val));
198 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
199 "Divide operation with an immediate and a register!");
200 assert (Op2.second != 0 && "Division by zero!");
201 Val = Op1.second / Op2.second;
202 OperandStack.push_back(std::make_pair(IC_IMM, Val));
205 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
206 "Or operation with an immediate and a register!");
207 Val = Op1.second | Op2.second;
208 OperandStack.push_back(std::make_pair(IC_IMM, Val));
211 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
212 "Xor operation with an immediate and a register!");
213 Val = Op1.second ^ Op2.second;
214 OperandStack.push_back(std::make_pair(IC_IMM, Val));
217 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
218 "And operation with an immediate and a register!");
219 Val = Op1.second & Op2.second;
220 OperandStack.push_back(std::make_pair(IC_IMM, Val));
223 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
224 "Left shift operation with an immediate and a register!");
225 Val = Op1.second << Op2.second;
226 OperandStack.push_back(std::make_pair(IC_IMM, Val));
229 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
230 "Right shift operation with an immediate and a register!");
231 Val = Op1.second >> Op2.second;
232 OperandStack.push_back(std::make_pair(IC_IMM, Val));
237 assert (OperandStack.size() == 1 && "Expected a single result.");
238 return OperandStack.pop_back_val().second;
242 enum IntelExprState {
263 class IntelExprStateMachine {
264 IntelExprState State, PrevState;
265 unsigned BaseReg, IndexReg, TmpReg, Scale;
269 bool StopOnLBrac, AddImmPrefix;
271 InlineAsmIdentifierInfo Info;
274 IntelExprStateMachine(int64_t imm, bool stoponlbrac, bool addimmprefix) :
275 State(IES_PLUS), PrevState(IES_ERROR), BaseReg(0), IndexReg(0), TmpReg(0),
276 Scale(1), Imm(imm), Sym(nullptr), StopOnLBrac(stoponlbrac),
277 AddImmPrefix(addimmprefix) { Info.clear(); }
279 unsigned getBaseReg() { return BaseReg; }
280 unsigned getIndexReg() { return IndexReg; }
281 unsigned getScale() { return Scale; }
282 const MCExpr *getSym() { return Sym; }
283 StringRef getSymName() { return SymName; }
284 int64_t getImm() { return Imm + IC.execute(); }
285 bool isValidEndState() {
286 return State == IES_RBRAC || State == IES_INTEGER;
288 bool getStopOnLBrac() { return StopOnLBrac; }
289 bool getAddImmPrefix() { return AddImmPrefix; }
290 bool hadError() { return State == IES_ERROR; }
292 InlineAsmIdentifierInfo &getIdentifierInfo() {
297 IntelExprState CurrState = State;
306 IC.pushOperator(IC_OR);
309 PrevState = CurrState;
312 IntelExprState CurrState = State;
321 IC.pushOperator(IC_XOR);
324 PrevState = CurrState;
327 IntelExprState CurrState = State;
336 IC.pushOperator(IC_AND);
339 PrevState = CurrState;
342 IntelExprState CurrState = State;
351 IC.pushOperator(IC_LSHIFT);
354 PrevState = CurrState;
357 IntelExprState CurrState = State;
366 IC.pushOperator(IC_RSHIFT);
369 PrevState = CurrState;
372 IntelExprState CurrState = State;
381 IC.pushOperator(IC_PLUS);
382 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
383 // If we already have a BaseReg, then assume this is the IndexReg with
388 assert (!IndexReg && "BaseReg/IndexReg already set!");
395 PrevState = CurrState;
398 IntelExprState CurrState = State;
414 // Only push the minus operator if it is not a unary operator.
415 if (!(CurrState == IES_PLUS || CurrState == IES_MINUS ||
416 CurrState == IES_MULTIPLY || CurrState == IES_DIVIDE ||
417 CurrState == IES_LPAREN || CurrState == IES_LBRAC))
418 IC.pushOperator(IC_MINUS);
419 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
420 // If we already have a BaseReg, then assume this is the IndexReg with
425 assert (!IndexReg && "BaseReg/IndexReg already set!");
432 PrevState = CurrState;
435 IntelExprState CurrState = State;
445 PrevState = CurrState;
447 void onRegister(unsigned Reg) {
448 IntelExprState CurrState = State;
455 State = IES_REGISTER;
457 IC.pushOperand(IC_REGISTER);
460 // Index Register - Scale * Register
461 if (PrevState == IES_INTEGER) {
462 assert (!IndexReg && "IndexReg already set!");
463 State = IES_REGISTER;
465 // Get the scale and replace the 'Scale * Register' with '0'.
466 Scale = IC.popOperand();
467 IC.pushOperand(IC_IMM);
474 PrevState = CurrState;
476 void onIdentifierExpr(const MCExpr *SymRef, StringRef SymRefName) {
487 SymName = SymRefName;
488 IC.pushOperand(IC_IMM);
492 bool onInteger(int64_t TmpInt, StringRef &ErrMsg) {
493 IntelExprState CurrState = State;
510 if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
511 // Index Register - Register * Scale
512 assert (!IndexReg && "IndexReg already set!");
515 if(Scale != 1 && Scale != 2 && Scale != 4 && Scale != 8) {
516 ErrMsg = "scale factor in address must be 1, 2, 4 or 8";
519 // Get the scale and replace the 'Register * Scale' with '0'.
521 } else if ((PrevState == IES_PLUS || PrevState == IES_MINUS ||
522 PrevState == IES_OR || PrevState == IES_AND ||
523 PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||
524 PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
525 PrevState == IES_LPAREN || PrevState == IES_LBRAC ||
526 PrevState == IES_NOT || PrevState == IES_XOR) &&
527 CurrState == IES_MINUS) {
528 // Unary minus. No need to pop the minus operand because it was never
530 IC.pushOperand(IC_IMM, -TmpInt); // Push -Imm.
531 } else if ((PrevState == IES_PLUS || PrevState == IES_MINUS ||
532 PrevState == IES_OR || PrevState == IES_AND ||
533 PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||
534 PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
535 PrevState == IES_LPAREN || PrevState == IES_LBRAC ||
536 PrevState == IES_NOT || PrevState == IES_XOR) &&
537 CurrState == IES_NOT) {
538 // Unary not. No need to pop the not operand because it was never
540 IC.pushOperand(IC_IMM, ~TmpInt); // Push ~Imm.
542 IC.pushOperand(IC_IMM, TmpInt);
546 PrevState = CurrState;
558 State = IES_MULTIPLY;
559 IC.pushOperator(IC_MULTIPLY);
572 IC.pushOperator(IC_DIVIDE);
584 IC.pushOperator(IC_PLUS);
589 IntelExprState CurrState = State;
598 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
599 // If we already have a BaseReg, then assume this is the IndexReg with
604 assert (!IndexReg && "BaseReg/IndexReg already set!");
611 PrevState = CurrState;
614 IntelExprState CurrState = State;
630 // FIXME: We don't handle this type of unary minus or not, yet.
631 if ((PrevState == IES_PLUS || PrevState == IES_MINUS ||
632 PrevState == IES_OR || PrevState == IES_AND ||
633 PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||
634 PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
635 PrevState == IES_LPAREN || PrevState == IES_LBRAC ||
636 PrevState == IES_NOT || PrevState == IES_XOR) &&
637 (CurrState == IES_MINUS || CurrState == IES_NOT)) {
642 IC.pushOperator(IC_LPAREN);
645 PrevState = CurrState;
657 IC.pushOperator(IC_RPAREN);
663 bool Error(SMLoc L, const Twine &Msg,
664 ArrayRef<SMRange> Ranges = None,
665 bool MatchingInlineAsm = false) {
666 MCAsmParser &Parser = getParser();
667 if (MatchingInlineAsm) return true;
668 return Parser.Error(L, Msg, Ranges);
671 bool ErrorAndEatStatement(SMLoc L, const Twine &Msg,
672 ArrayRef<SMRange> Ranges = None,
673 bool MatchingInlineAsm = false) {
674 MCAsmParser &Parser = getParser();
675 Parser.eatToEndOfStatement();
676 return Error(L, Msg, Ranges, MatchingInlineAsm);
679 std::nullptr_t ErrorOperand(SMLoc Loc, StringRef Msg) {
684 std::unique_ptr<X86Operand> DefaultMemSIOperand(SMLoc Loc);
685 std::unique_ptr<X86Operand> DefaultMemDIOperand(SMLoc Loc);
686 void AddDefaultSrcDestOperands(
687 OperandVector& Operands, std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
688 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst);
689 std::unique_ptr<X86Operand> ParseOperand();
690 std::unique_ptr<X86Operand> ParseATTOperand();
691 std::unique_ptr<X86Operand> ParseIntelOperand();
692 std::unique_ptr<X86Operand> ParseIntelOffsetOfOperator();
693 bool ParseIntelDotOperator(const MCExpr *Disp, const MCExpr *&NewDisp);
694 std::unique_ptr<X86Operand> ParseIntelOperator(unsigned OpKind);
695 std::unique_ptr<X86Operand>
696 ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start, unsigned Size);
697 std::unique_ptr<X86Operand>
698 ParseIntelMemOperand(int64_t ImmDisp, SMLoc StartLoc, unsigned Size);
699 std::unique_ptr<X86Operand> ParseRoundingModeOp(SMLoc Start, SMLoc End);
700 bool ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End);
701 std::unique_ptr<X86Operand> ParseIntelBracExpression(unsigned SegReg,
705 bool ParseIntelIdentifier(const MCExpr *&Val, StringRef &Identifier,
706 InlineAsmIdentifierInfo &Info,
707 bool IsUnevaluatedOperand, SMLoc &End);
709 std::unique_ptr<X86Operand> ParseMemOperand(unsigned SegReg, SMLoc StartLoc);
711 std::unique_ptr<X86Operand>
712 CreateMemForInlineAsm(unsigned SegReg, const MCExpr *Disp, unsigned BaseReg,
713 unsigned IndexReg, unsigned Scale, SMLoc Start,
714 SMLoc End, unsigned Size, StringRef Identifier,
715 InlineAsmIdentifierInfo &Info);
717 bool parseDirectiveEven(SMLoc L);
718 bool ParseDirectiveWord(unsigned Size, SMLoc L);
719 bool ParseDirectiveCode(StringRef IDVal, SMLoc L);
721 bool processInstruction(MCInst &Inst, const OperandVector &Ops);
723 /// Wrapper around MCStreamer::EmitInstruction(). Possibly adds
724 /// instrumentation around Inst.
725 void EmitInstruction(MCInst &Inst, OperandVector &Operands, MCStreamer &Out);
727 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
728 OperandVector &Operands, MCStreamer &Out,
730 bool MatchingInlineAsm) override;
732 void MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op, OperandVector &Operands,
733 MCStreamer &Out, bool MatchingInlineAsm);
735 bool ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
736 bool MatchingInlineAsm);
738 bool MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
739 OperandVector &Operands, MCStreamer &Out,
741 bool MatchingInlineAsm);
743 bool MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
744 OperandVector &Operands, MCStreamer &Out,
746 bool MatchingInlineAsm);
748 bool OmitRegisterFromClobberLists(unsigned RegNo) override;
750 /// doSrcDstMatch - Returns true if operands are matching in their
751 /// word size (%si and %di, %esi and %edi, etc.). Order depends on
752 /// the parsing mode (Intel vs. AT&T).
753 bool doSrcDstMatch(X86Operand &Op1, X86Operand &Op2);
755 /// Parses AVX512 specific operand primitives: masked registers ({%k<NUM>}, {z})
756 /// and memory broadcasting ({1to<NUM>}) primitives, updating Operands vector if required.
757 /// \return \c true if no parsing errors occurred, \c false otherwise.
758 bool HandleAVX512Operand(OperandVector &Operands,
759 const MCParsedAsmOperand &Op);
761 bool is64BitMode() const {
762 // FIXME: Can tablegen auto-generate this?
763 return getSTI().getFeatureBits()[X86::Mode64Bit];
765 bool is32BitMode() const {
766 // FIXME: Can tablegen auto-generate this?
767 return getSTI().getFeatureBits()[X86::Mode32Bit];
769 bool is16BitMode() const {
770 // FIXME: Can tablegen auto-generate this?
771 return getSTI().getFeatureBits()[X86::Mode16Bit];
773 void SwitchMode(unsigned mode) {
774 MCSubtargetInfo &STI = copySTI();
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(const MCSubtargetInfo &sti, MCAsmParser &Parser,
805 const MCInstrInfo &mii, const MCTargetOptions &Options)
806 : MCTargetAsmParser(Options, sti), MII(mii), InstInfo(nullptr) {
808 // Initialize the set of available features.
809 setAvailableFeatures(ComputeAvailableFeatures(getSTI().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("FWORD", "fword", 48)
1054 .Cases("QWORD", "qword", 64)
1055 .Cases("MMWORD","mmword", 64)
1056 .Cases("XWORD", "xword", 80)
1057 .Cases("TBYTE", "tbyte", 80)
1058 .Cases("XMMWORD", "xmmword", 128)
1059 .Cases("YMMWORD", "ymmword", 256)
1060 .Cases("ZMMWORD", "zmmword", 512)
1061 .Cases("OPAQUE", "opaque", -1U) // needs to be non-zero, but doesn't matter
1066 std::unique_ptr<X86Operand> X86AsmParser::CreateMemForInlineAsm(
1067 unsigned SegReg, const MCExpr *Disp, unsigned BaseReg, unsigned IndexReg,
1068 unsigned Scale, SMLoc Start, SMLoc End, unsigned Size, StringRef Identifier,
1069 InlineAsmIdentifierInfo &Info) {
1070 // If we found a decl other than a VarDecl, then assume it is a FuncDecl or
1071 // some other label reference.
1072 if (isa<MCSymbolRefExpr>(Disp) && Info.OpDecl && !Info.IsVarDecl) {
1073 // Insert an explicit size if the user didn't have one.
1075 Size = getPointerWidth();
1076 InstInfo->AsmRewrites->emplace_back(AOK_SizeDirective, Start,
1080 // Create an absolute memory reference in order to match against
1081 // instructions taking a PC relative operand.
1082 return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size,
1083 Identifier, Info.OpDecl);
1086 // We either have a direct symbol reference, or an offset from a symbol. The
1087 // parser always puts the symbol on the LHS, so look there for size
1088 // calculation purposes.
1089 const MCBinaryExpr *BinOp = dyn_cast<MCBinaryExpr>(Disp);
1091 isa<MCSymbolRefExpr>(BinOp ? BinOp->getLHS() : Disp);
1094 Size = Info.Type * 8; // Size is in terms of bits in this context.
1096 InstInfo->AsmRewrites->emplace_back(AOK_SizeDirective, Start,
1101 // When parsing inline assembly we set the base register to a non-zero value
1102 // if we don't know the actual value at this time. This is necessary to
1103 // get the matching correct in some cases.
1104 BaseReg = BaseReg ? BaseReg : 1;
1105 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
1106 IndexReg, Scale, Start, End, Size, Identifier,
1111 RewriteIntelBracExpression(SmallVectorImpl<AsmRewrite> &AsmRewrites,
1112 StringRef SymName, int64_t ImmDisp,
1113 int64_t FinalImmDisp, SMLoc &BracLoc,
1114 SMLoc &StartInBrac, SMLoc &End) {
1115 // Remove the '[' and ']' from the IR string.
1116 AsmRewrites.emplace_back(AOK_Skip, BracLoc, 1);
1117 AsmRewrites.emplace_back(AOK_Skip, End, 1);
1119 // If ImmDisp is non-zero, then we parsed a displacement before the
1120 // bracketed expression (i.e., ImmDisp [ BaseReg + Scale*IndexReg + Disp])
1121 // If ImmDisp doesn't match the displacement computed by the state machine
1122 // then we have an additional displacement in the bracketed expression.
1123 if (ImmDisp != FinalImmDisp) {
1125 // We have an immediate displacement before the bracketed expression.
1126 // Adjust this to match the final immediate displacement.
1128 for (AsmRewrite &AR : AsmRewrites) {
1129 if (AR.Loc.getPointer() > BracLoc.getPointer())
1131 if (AR.Kind == AOK_ImmPrefix || AR.Kind == AOK_Imm) {
1132 assert (!Found && "ImmDisp already rewritten.");
1134 AR.Len = BracLoc.getPointer() - AR.Loc.getPointer();
1135 AR.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 (AsmRewrite &AR : AsmRewrites) {
1151 if (AR.Loc.getPointer() < StartInBrac.getPointer())
1153 if (AR.Kind == AOK_ImmPrefix)
1154 AR.Kind = AOK_Delete;
1156 const char *SymLocPtr = SymName.data();
1157 // Skip everything before the symbol.
1158 if (unsigned Len = SymLocPtr - StartInBrac.getPointer()) {
1159 assert(Len > 0 && "Expected a non-negative length.");
1160 AsmRewrites.emplace_back(AOK_Skip, StartInBrac, Len);
1162 // Skip everything after the symbol.
1163 if (unsigned Len = End.getPointer() - (SymLocPtr + SymName.size())) {
1164 SMLoc Loc = SMLoc::getFromPointer(SymLocPtr + SymName.size());
1165 assert(Len > 0 && "Expected a non-negative length.");
1166 AsmRewrites.emplace_back(AOK_Skip, Loc, Len);
1170 bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
1171 MCAsmParser &Parser = getParser();
1172 const AsmToken &Tok = Parser.getTok();
1174 AsmToken::TokenKind PrevTK = AsmToken::Error;
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 &&
1219 PrevTK == AsmToken::RBrac) {
1222 InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
1223 if (ParseIntelIdentifier(Val, Identifier, Info,
1224 /*Unevaluated=*/false, End))
1228 SM.onIdentifierExpr(Val, Identifier);
1229 UpdateLocLex = false;
1232 return Error(Tok.getLoc(), "Unexpected identifier!");
1234 case AsmToken::Integer: {
1236 if (isParsingInlineAsm() && SM.getAddImmPrefix())
1237 InstInfo->AsmRewrites->emplace_back(AOK_ImmPrefix, Tok.getLoc());
1238 // Look for 'b' or 'f' following an Integer as a directional label
1239 SMLoc Loc = getTok().getLoc();
1240 int64_t IntVal = getTok().getIntVal();
1241 End = consumeToken();
1242 UpdateLocLex = false;
1243 if (getLexer().getKind() == AsmToken::Identifier) {
1244 StringRef IDVal = getTok().getString();
1245 if (IDVal == "f" || IDVal == "b") {
1247 getContext().getDirectionalLocalSymbol(IntVal, IDVal == "b");
1248 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1250 MCSymbolRefExpr::create(Sym, Variant, getContext());
1251 if (IDVal == "b" && Sym->isUndefined())
1252 return Error(Loc, "invalid reference to undefined symbol");
1253 StringRef Identifier = Sym->getName();
1254 SM.onIdentifierExpr(Val, Identifier);
1255 End = consumeToken();
1257 if (SM.onInteger(IntVal, ErrMsg))
1258 return Error(Loc, ErrMsg);
1261 if (SM.onInteger(IntVal, ErrMsg))
1262 return Error(Loc, ErrMsg);
1266 case AsmToken::Plus: SM.onPlus(); break;
1267 case AsmToken::Minus: SM.onMinus(); break;
1268 case AsmToken::Tilde: SM.onNot(); break;
1269 case AsmToken::Star: SM.onStar(); break;
1270 case AsmToken::Slash: SM.onDivide(); break;
1271 case AsmToken::Pipe: SM.onOr(); break;
1272 case AsmToken::Caret: SM.onXor(); break;
1273 case AsmToken::Amp: SM.onAnd(); break;
1274 case AsmToken::LessLess:
1275 SM.onLShift(); break;
1276 case AsmToken::GreaterGreater:
1277 SM.onRShift(); break;
1278 case AsmToken::LBrac: SM.onLBrac(); break;
1279 case AsmToken::RBrac: SM.onRBrac(); break;
1280 case AsmToken::LParen: SM.onLParen(); break;
1281 case AsmToken::RParen: SM.onRParen(); break;
1284 return Error(Tok.getLoc(), "unknown token in expression");
1286 if (!Done && UpdateLocLex)
1287 End = consumeToken();
1294 std::unique_ptr<X86Operand>
1295 X86AsmParser::ParseIntelBracExpression(unsigned SegReg, SMLoc Start,
1296 int64_t ImmDisp, unsigned Size) {
1297 MCAsmParser &Parser = getParser();
1298 const AsmToken &Tok = Parser.getTok();
1299 SMLoc BracLoc = Tok.getLoc(), End = Tok.getEndLoc();
1300 if (getLexer().isNot(AsmToken::LBrac))
1301 return ErrorOperand(BracLoc, "Expected '[' token!");
1302 Parser.Lex(); // Eat '['
1304 SMLoc StartInBrac = Tok.getLoc();
1305 // Parse [ Symbol + ImmDisp ] and [ BaseReg + Scale*IndexReg + ImmDisp ]. We
1306 // may have already parsed an immediate displacement before the bracketed
1308 IntelExprStateMachine SM(ImmDisp, /*StopOnLBrac=*/false, /*AddImmPrefix=*/true);
1309 if (ParseIntelExpression(SM, End))
1312 const MCExpr *Disp = nullptr;
1313 if (const MCExpr *Sym = SM.getSym()) {
1314 // A symbolic displacement.
1316 if (isParsingInlineAsm())
1317 RewriteIntelBracExpression(*InstInfo->AsmRewrites, SM.getSymName(),
1318 ImmDisp, SM.getImm(), BracLoc, StartInBrac,
1322 if (SM.getImm() || !Disp) {
1323 const MCExpr *Imm = MCConstantExpr::create(SM.getImm(), getContext());
1325 Disp = MCBinaryExpr::createAdd(Disp, Imm, getContext());
1327 Disp = Imm; // An immediate displacement only.
1330 // Parse struct field access. Intel requires a dot, but MSVC doesn't. MSVC
1331 // will in fact do global lookup the field name inside all global typedefs,
1332 // but we don't emulate that.
1333 if (Tok.getString().find('.') != StringRef::npos) {
1334 const MCExpr *NewDisp;
1335 if (ParseIntelDotOperator(Disp, NewDisp))
1338 End = Tok.getEndLoc();
1339 Parser.Lex(); // Eat the field.
1343 int BaseReg = SM.getBaseReg();
1344 int IndexReg = SM.getIndexReg();
1345 int Scale = SM.getScale();
1346 if (!isParsingInlineAsm()) {
1348 if (!BaseReg && !IndexReg) {
1350 return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size);
1351 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
1355 if (CheckBaseRegAndIndexReg(BaseReg, IndexReg, ErrMsg)) {
1356 Error(StartInBrac, ErrMsg);
1359 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
1360 IndexReg, Scale, Start, End, Size);
1363 InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
1364 return CreateMemForInlineAsm(SegReg, Disp, BaseReg, IndexReg, Scale, Start,
1365 End, Size, SM.getSymName(), Info);
1368 // Inline assembly may use variable names with namespace alias qualifiers.
1369 bool X86AsmParser::ParseIntelIdentifier(const MCExpr *&Val,
1370 StringRef &Identifier,
1371 InlineAsmIdentifierInfo &Info,
1372 bool IsUnevaluatedOperand, SMLoc &End) {
1373 MCAsmParser &Parser = getParser();
1374 assert(isParsingInlineAsm() && "Expected to be parsing inline assembly.");
1377 StringRef LineBuf(Identifier.data());
1379 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);
1381 const AsmToken &Tok = Parser.getTok();
1382 SMLoc Loc = Tok.getLoc();
1384 // Advance the token stream until the end of the current token is
1385 // after the end of what the frontend claimed.
1386 const char *EndPtr = Tok.getLoc().getPointer() + LineBuf.size();
1388 End = Tok.getEndLoc();
1390 } while (End.getPointer() < EndPtr);
1391 Identifier = LineBuf;
1393 // The frontend should end parsing on an assembler token boundary, unless it
1395 assert((End.getPointer() == EndPtr || !Result) &&
1396 "frontend claimed part of a token?");
1398 // If the identifier lookup was unsuccessful, assume that we are dealing with
1401 StringRef InternalName =
1402 SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(),
1404 assert(InternalName.size() && "We should have an internal name here.");
1405 // Push a rewrite for replacing the identifier name with the internal name.
1406 InstInfo->AsmRewrites->emplace_back(AOK_Label, Loc, Identifier.size(),
1410 // Create the symbol reference.
1411 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
1412 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1413 Val = MCSymbolRefExpr::create(Sym, Variant, getParser().getContext());
1417 /// \brief Parse intel style segment override.
1418 std::unique_ptr<X86Operand>
1419 X86AsmParser::ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start,
1421 MCAsmParser &Parser = getParser();
1422 assert(SegReg != 0 && "Tried to parse a segment override without a segment!");
1423 const AsmToken &Tok = Parser.getTok(); // Eat colon.
1424 if (Tok.isNot(AsmToken::Colon))
1425 return ErrorOperand(Tok.getLoc(), "Expected ':' token!");
1426 Parser.Lex(); // Eat ':'
1428 int64_t ImmDisp = 0;
1429 if (getLexer().is(AsmToken::Integer)) {
1430 ImmDisp = Tok.getIntVal();
1431 AsmToken ImmDispToken = Parser.Lex(); // Eat the integer.
1433 if (isParsingInlineAsm())
1434 InstInfo->AsmRewrites->emplace_back(AOK_ImmPrefix, ImmDispToken.getLoc());
1436 if (getLexer().isNot(AsmToken::LBrac)) {
1437 // An immediate following a 'segment register', 'colon' token sequence can
1438 // be followed by a bracketed expression. If it isn't we know we have our
1439 // final segment override.
1440 const MCExpr *Disp = MCConstantExpr::create(ImmDisp, getContext());
1441 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp,
1442 /*BaseReg=*/0, /*IndexReg=*/0, /*Scale=*/1,
1443 Start, ImmDispToken.getEndLoc(), Size);
1447 if (getLexer().is(AsmToken::LBrac))
1448 return ParseIntelBracExpression(SegReg, Start, ImmDisp, Size);
1452 if (!isParsingInlineAsm()) {
1453 if (getParser().parsePrimaryExpr(Val, End))
1454 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1456 return X86Operand::CreateMem(getPointerWidth(), Val, Start, End, Size);
1459 InlineAsmIdentifierInfo Info;
1460 StringRef Identifier = Tok.getString();
1461 if (ParseIntelIdentifier(Val, Identifier, Info,
1462 /*Unevaluated=*/false, End))
1464 return CreateMemForInlineAsm(/*SegReg=*/0, Val, /*BaseReg=*/0,/*IndexReg=*/0,
1465 /*Scale=*/1, Start, End, Size, Identifier, Info);
1468 //ParseRoundingModeOp - Parse AVX-512 rounding mode operand
1469 std::unique_ptr<X86Operand>
1470 X86AsmParser::ParseRoundingModeOp(SMLoc Start, SMLoc End) {
1471 MCAsmParser &Parser = getParser();
1472 const AsmToken &Tok = Parser.getTok();
1473 // Eat "{" and mark the current place.
1474 const SMLoc consumedToken = consumeToken();
1475 if (Tok.getIdentifier().startswith("r")){
1476 int rndMode = StringSwitch<int>(Tok.getIdentifier())
1477 .Case("rn", X86::STATIC_ROUNDING::TO_NEAREST_INT)
1478 .Case("rd", X86::STATIC_ROUNDING::TO_NEG_INF)
1479 .Case("ru", X86::STATIC_ROUNDING::TO_POS_INF)
1480 .Case("rz", X86::STATIC_ROUNDING::TO_ZERO)
1483 return ErrorOperand(Tok.getLoc(), "Invalid rounding mode.");
1484 Parser.Lex(); // Eat "r*" of r*-sae
1485 if (!getLexer().is(AsmToken::Minus))
1486 return ErrorOperand(Tok.getLoc(), "Expected - at this point");
1487 Parser.Lex(); // Eat "-"
1488 Parser.Lex(); // Eat the sae
1489 if (!getLexer().is(AsmToken::RCurly))
1490 return ErrorOperand(Tok.getLoc(), "Expected } at this point");
1491 Parser.Lex(); // Eat "}"
1492 const MCExpr *RndModeOp =
1493 MCConstantExpr::create(rndMode, Parser.getContext());
1494 return X86Operand::CreateImm(RndModeOp, Start, End);
1496 if(Tok.getIdentifier().equals("sae")){
1497 Parser.Lex(); // Eat the sae
1498 if (!getLexer().is(AsmToken::RCurly))
1499 return ErrorOperand(Tok.getLoc(), "Expected } at this point");
1500 Parser.Lex(); // Eat "}"
1501 return X86Operand::CreateToken("{sae}", consumedToken);
1503 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1505 /// ParseIntelMemOperand - Parse intel style memory operand.
1506 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelMemOperand(int64_t ImmDisp,
1509 MCAsmParser &Parser = getParser();
1510 const AsmToken &Tok = Parser.getTok();
1513 // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
1514 if (getLexer().is(AsmToken::LBrac))
1515 return ParseIntelBracExpression(/*SegReg=*/0, Start, ImmDisp, Size);
1516 assert(ImmDisp == 0);
1519 if (!isParsingInlineAsm()) {
1520 if (getParser().parsePrimaryExpr(Val, End))
1521 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1523 return X86Operand::CreateMem(getPointerWidth(), Val, Start, End, Size);
1526 InlineAsmIdentifierInfo Info;
1527 StringRef Identifier = Tok.getString();
1528 if (ParseIntelIdentifier(Val, Identifier, Info,
1529 /*Unevaluated=*/false, End))
1532 if (!getLexer().is(AsmToken::LBrac))
1533 return CreateMemForInlineAsm(/*SegReg=*/0, Val, /*BaseReg=*/0, /*IndexReg=*/0,
1534 /*Scale=*/1, Start, End, Size, Identifier, Info);
1536 Parser.Lex(); // Eat '['
1538 // Parse Identifier [ ImmDisp ]
1539 IntelExprStateMachine SM(/*ImmDisp=*/0, /*StopOnLBrac=*/true,
1540 /*AddImmPrefix=*/false);
1541 if (ParseIntelExpression(SM, End))
1545 Error(Start, "cannot use more than one symbol in memory operand");
1548 if (SM.getBaseReg()) {
1549 Error(Start, "cannot use base register with variable reference");
1552 if (SM.getIndexReg()) {
1553 Error(Start, "cannot use index register with variable reference");
1557 const MCExpr *Disp = MCConstantExpr::create(SM.getImm(), getContext());
1558 // BaseReg is non-zero to avoid assertions. In the context of inline asm,
1559 // we're pointing to a local variable in memory, so the base register is
1560 // really the frame or stack pointer.
1561 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
1562 /*BaseReg=*/1, /*IndexReg=*/0, /*Scale=*/1,
1563 Start, End, Size, Identifier, Info.OpDecl);
1566 /// Parse the '.' operator.
1567 bool X86AsmParser::ParseIntelDotOperator(const MCExpr *Disp,
1568 const MCExpr *&NewDisp) {
1569 MCAsmParser &Parser = getParser();
1570 const AsmToken &Tok = Parser.getTok();
1571 int64_t OrigDispVal, DotDispVal;
1573 // FIXME: Handle non-constant expressions.
1574 if (const MCConstantExpr *OrigDisp = dyn_cast<MCConstantExpr>(Disp))
1575 OrigDispVal = OrigDisp->getValue();
1577 return Error(Tok.getLoc(), "Non-constant offsets are not supported!");
1579 // Drop the optional '.'.
1580 StringRef DotDispStr = Tok.getString();
1581 if (DotDispStr.startswith("."))
1582 DotDispStr = DotDispStr.drop_front(1);
1584 // .Imm gets lexed as a real.
1585 if (Tok.is(AsmToken::Real)) {
1587 DotDispStr.getAsInteger(10, DotDisp);
1588 DotDispVal = DotDisp.getZExtValue();
1589 } else if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) {
1591 std::pair<StringRef, StringRef> BaseMember = DotDispStr.split('.');
1592 if (SemaCallback->LookupInlineAsmField(BaseMember.first, BaseMember.second,
1594 return Error(Tok.getLoc(), "Unable to lookup field reference!");
1595 DotDispVal = DotDisp;
1597 return Error(Tok.getLoc(), "Unexpected token type!");
1599 if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) {
1600 SMLoc Loc = SMLoc::getFromPointer(DotDispStr.data());
1601 unsigned Len = DotDispStr.size();
1602 unsigned Val = OrigDispVal + DotDispVal;
1603 InstInfo->AsmRewrites->emplace_back(AOK_DotOperator, Loc, Len, Val);
1606 NewDisp = MCConstantExpr::create(OrigDispVal + DotDispVal, getContext());
1610 /// Parse the 'offset' operator. This operator is used to specify the
1611 /// location rather then the content of a variable.
1612 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOffsetOfOperator() {
1613 MCAsmParser &Parser = getParser();
1614 const AsmToken &Tok = Parser.getTok();
1615 SMLoc OffsetOfLoc = Tok.getLoc();
1616 Parser.Lex(); // Eat offset.
1619 InlineAsmIdentifierInfo Info;
1620 SMLoc Start = Tok.getLoc(), End;
1621 StringRef Identifier = Tok.getString();
1622 if (ParseIntelIdentifier(Val, Identifier, Info,
1623 /*Unevaluated=*/false, End))
1626 // Don't emit the offset operator.
1627 InstInfo->AsmRewrites->emplace_back(AOK_Skip, OffsetOfLoc, 7);
1629 // The offset operator will have an 'r' constraint, thus we need to create
1630 // register operand to ensure proper matching. Just pick a GPR based on
1631 // the size of a pointer.
1633 is64BitMode() ? X86::RBX : (is32BitMode() ? X86::EBX : X86::BX);
1634 return X86Operand::CreateReg(RegNo, Start, End, /*GetAddress=*/true,
1635 OffsetOfLoc, Identifier, Info.OpDecl);
1638 enum IntelOperatorKind {
1644 /// Parse the 'LENGTH', 'TYPE' and 'SIZE' operators. The LENGTH operator
1645 /// returns the number of elements in an array. It returns the value 1 for
1646 /// non-array variables. The SIZE operator returns the size of a C or C++
1647 /// variable. A variable's size is the product of its LENGTH and TYPE. The
1648 /// TYPE operator returns the size of a C or C++ type or variable. If the
1649 /// variable is an array, TYPE returns the size of a single element.
1650 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperator(unsigned OpKind) {
1651 MCAsmParser &Parser = getParser();
1652 const AsmToken &Tok = Parser.getTok();
1653 SMLoc TypeLoc = Tok.getLoc();
1654 Parser.Lex(); // Eat operator.
1656 const MCExpr *Val = nullptr;
1657 InlineAsmIdentifierInfo Info;
1658 SMLoc Start = Tok.getLoc(), End;
1659 StringRef Identifier = Tok.getString();
1660 if (ParseIntelIdentifier(Val, Identifier, Info,
1661 /*Unevaluated=*/true, End))
1665 return ErrorOperand(Start, "unable to lookup expression");
1669 default: llvm_unreachable("Unexpected operand kind!");
1670 case IOK_LENGTH: CVal = Info.Length; break;
1671 case IOK_SIZE: CVal = Info.Size; break;
1672 case IOK_TYPE: CVal = Info.Type; break;
1675 // Rewrite the type operator and the C or C++ type or variable in terms of an
1676 // immediate. E.g. TYPE foo -> $$4
1677 unsigned Len = End.getPointer() - TypeLoc.getPointer();
1678 InstInfo->AsmRewrites->emplace_back(AOK_Imm, TypeLoc, Len, CVal);
1680 const MCExpr *Imm = MCConstantExpr::create(CVal, getContext());
1681 return X86Operand::CreateImm(Imm, Start, End);
1684 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand() {
1685 MCAsmParser &Parser = getParser();
1686 const AsmToken &Tok = Parser.getTok();
1689 // Offset, length, type and size operators.
1690 if (isParsingInlineAsm()) {
1691 StringRef AsmTokStr = Tok.getString();
1692 if (AsmTokStr == "offset" || AsmTokStr == "OFFSET")
1693 return ParseIntelOffsetOfOperator();
1694 if (AsmTokStr == "length" || AsmTokStr == "LENGTH")
1695 return ParseIntelOperator(IOK_LENGTH);
1696 if (AsmTokStr == "size" || AsmTokStr == "SIZE")
1697 return ParseIntelOperator(IOK_SIZE);
1698 if (AsmTokStr == "type" || AsmTokStr == "TYPE")
1699 return ParseIntelOperator(IOK_TYPE);
1702 bool PtrInOperand = false;
1703 unsigned Size = getIntelMemOperandSize(Tok.getString());
1705 Parser.Lex(); // Eat operand size (e.g., byte, word).
1706 if (Tok.getString() != "PTR" && Tok.getString() != "ptr")
1707 return ErrorOperand(Tok.getLoc(), "Expected 'PTR' or 'ptr' token!");
1708 Parser.Lex(); // Eat ptr.
1709 PtrInOperand = true;
1711 Start = Tok.getLoc();
1714 if (getLexer().is(AsmToken::Integer) || getLexer().is(AsmToken::Minus) ||
1715 getLexer().is(AsmToken::Tilde) || getLexer().is(AsmToken::LParen)) {
1716 AsmToken StartTok = Tok;
1717 IntelExprStateMachine SM(/*Imm=*/0, /*StopOnLBrac=*/true,
1718 /*AddImmPrefix=*/false);
1719 if (ParseIntelExpression(SM, End))
1722 int64_t Imm = SM.getImm();
1723 if (isParsingInlineAsm()) {
1724 unsigned Len = Tok.getLoc().getPointer() - Start.getPointer();
1725 if (StartTok.getString().size() == Len)
1726 // Just add a prefix if this wasn't a complex immediate expression.
1727 InstInfo->AsmRewrites->emplace_back(AOK_ImmPrefix, Start);
1729 // Otherwise, rewrite the complex expression as a single immediate.
1730 InstInfo->AsmRewrites->emplace_back(AOK_Imm, Start, Len, Imm);
1733 if (getLexer().isNot(AsmToken::LBrac)) {
1734 // If a directional label (ie. 1f or 2b) was parsed above from
1735 // ParseIntelExpression() then SM.getSym() was set to a pointer to
1736 // to the MCExpr with the directional local symbol and this is a
1737 // memory operand not an immediate operand.
1739 return X86Operand::CreateMem(getPointerWidth(), SM.getSym(), Start, End,
1742 const MCExpr *ImmExpr = MCConstantExpr::create(Imm, getContext());
1743 return X86Operand::CreateImm(ImmExpr, Start, End);
1746 // Only positive immediates are valid.
1748 return ErrorOperand(Start, "expected a positive immediate displacement "
1749 "before bracketed expr.");
1751 // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
1752 return ParseIntelMemOperand(Imm, Start, Size);
1755 // rounding mode token
1756 if (getSTI().getFeatureBits()[X86::FeatureAVX512] &&
1757 getLexer().is(AsmToken::LCurly))
1758 return ParseRoundingModeOp(Start, End);
1762 if (!ParseRegister(RegNo, Start, End)) {
1763 // If this is a segment register followed by a ':', then this is the start
1764 // of a segment override, otherwise this is a normal register reference.
1765 // In case it is a normal register and there is ptr in the operand this
1767 if (getLexer().isNot(AsmToken::Colon)){
1769 return ErrorOperand(Start, "expected memory operand after "
1770 "'ptr', found register operand instead");
1772 return X86Operand::CreateReg(RegNo, Start, End);
1775 return ParseIntelSegmentOverride(/*SegReg=*/RegNo, Start, Size);
1779 return ParseIntelMemOperand(/*Disp=*/0, Start, Size);
1782 std::unique_ptr<X86Operand> X86AsmParser::ParseATTOperand() {
1783 MCAsmParser &Parser = getParser();
1784 switch (getLexer().getKind()) {
1786 // Parse a memory operand with no segment register.
1787 return ParseMemOperand(0, Parser.getTok().getLoc());
1788 case AsmToken::Percent: {
1789 // Read the register.
1792 if (ParseRegister(RegNo, Start, End)) return nullptr;
1793 if (RegNo == X86::EIZ || RegNo == X86::RIZ) {
1794 Error(Start, "%eiz and %riz can only be used as index registers",
1795 SMRange(Start, End));
1799 // If this is a segment register followed by a ':', then this is the start
1800 // of a memory reference, otherwise this is a normal register reference.
1801 if (getLexer().isNot(AsmToken::Colon))
1802 return X86Operand::CreateReg(RegNo, Start, End);
1804 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo))
1805 return ErrorOperand(Start, "invalid segment register");
1807 getParser().Lex(); // Eat the colon.
1808 return ParseMemOperand(RegNo, Start);
1810 case AsmToken::Dollar: {
1811 // $42 -> immediate.
1812 SMLoc Start = Parser.getTok().getLoc(), End;
1815 if (getParser().parseExpression(Val, End))
1817 return X86Operand::CreateImm(Val, Start, End);
1819 case AsmToken::LCurly:{
1820 SMLoc Start = Parser.getTok().getLoc(), End;
1821 if (getSTI().getFeatureBits()[X86::FeatureAVX512])
1822 return ParseRoundingModeOp(Start, End);
1823 return ErrorOperand(Start, "unknown token in expression");
1828 bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands,
1829 const MCParsedAsmOperand &Op) {
1830 MCAsmParser &Parser = getParser();
1831 if(getSTI().getFeatureBits()[X86::FeatureAVX512]) {
1832 if (getLexer().is(AsmToken::LCurly)) {
1833 // Eat "{" and mark the current place.
1834 const SMLoc consumedToken = consumeToken();
1835 // Distinguish {1to<NUM>} from {%k<NUM>}.
1836 if(getLexer().is(AsmToken::Integer)) {
1837 // Parse memory broadcasting ({1to<NUM>}).
1838 if (getLexer().getTok().getIntVal() != 1)
1839 return !ErrorAndEatStatement(getLexer().getLoc(),
1840 "Expected 1to<NUM> at this point");
1841 Parser.Lex(); // Eat "1" of 1to8
1842 if (!getLexer().is(AsmToken::Identifier) ||
1843 !getLexer().getTok().getIdentifier().startswith("to"))
1844 return !ErrorAndEatStatement(getLexer().getLoc(),
1845 "Expected 1to<NUM> at this point");
1846 // Recognize only reasonable suffixes.
1847 const char *BroadcastPrimitive =
1848 StringSwitch<const char*>(getLexer().getTok().getIdentifier())
1849 .Case("to2", "{1to2}")
1850 .Case("to4", "{1to4}")
1851 .Case("to8", "{1to8}")
1852 .Case("to16", "{1to16}")
1854 if (!BroadcastPrimitive)
1855 return !ErrorAndEatStatement(getLexer().getLoc(),
1856 "Invalid memory broadcast primitive.");
1857 Parser.Lex(); // Eat "toN" of 1toN
1858 if (!getLexer().is(AsmToken::RCurly))
1859 return !ErrorAndEatStatement(getLexer().getLoc(),
1860 "Expected } at this point");
1861 Parser.Lex(); // Eat "}"
1862 Operands.push_back(X86Operand::CreateToken(BroadcastPrimitive,
1864 // No AVX512 specific primitives can pass
1865 // after memory broadcasting, so return.
1868 // Parse mask register {%k1}
1869 Operands.push_back(X86Operand::CreateToken("{", consumedToken));
1870 if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
1871 Operands.push_back(std::move(Op));
1872 if (!getLexer().is(AsmToken::RCurly))
1873 return !ErrorAndEatStatement(getLexer().getLoc(),
1874 "Expected } at this point");
1875 Operands.push_back(X86Operand::CreateToken("}", consumeToken()));
1877 // Parse "zeroing non-masked" semantic {z}
1878 if (getLexer().is(AsmToken::LCurly)) {
1879 Operands.push_back(X86Operand::CreateToken("{z}", consumeToken()));
1880 if (!getLexer().is(AsmToken::Identifier) ||
1881 getLexer().getTok().getIdentifier() != "z")
1882 return !ErrorAndEatStatement(getLexer().getLoc(),
1883 "Expected z at this point");
1884 Parser.Lex(); // Eat the z
1885 if (!getLexer().is(AsmToken::RCurly))
1886 return !ErrorAndEatStatement(getLexer().getLoc(),
1887 "Expected } at this point");
1888 Parser.Lex(); // Eat the }
1897 /// ParseMemOperand: segment: disp(basereg, indexreg, scale). The '%ds:' prefix
1898 /// has already been parsed if present.
1899 std::unique_ptr<X86Operand> X86AsmParser::ParseMemOperand(unsigned SegReg,
1902 MCAsmParser &Parser = getParser();
1903 // We have to disambiguate a parenthesized expression "(4+5)" from the start
1904 // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)". The
1905 // only way to do this without lookahead is to eat the '(' and see what is
1907 const MCExpr *Disp = MCConstantExpr::create(0, getParser().getContext());
1908 if (getLexer().isNot(AsmToken::LParen)) {
1910 if (getParser().parseExpression(Disp, ExprEnd)) return nullptr;
1912 // After parsing the base expression we could either have a parenthesized
1913 // memory address or not. If not, return now. If so, eat the (.
1914 if (getLexer().isNot(AsmToken::LParen)) {
1915 // Unless we have a segment register, treat this as an immediate.
1917 return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, ExprEnd);
1918 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
1925 // Okay, we have a '('. We don't know if this is an expression or not, but
1926 // so we have to eat the ( to see beyond it.
1927 SMLoc LParenLoc = Parser.getTok().getLoc();
1928 Parser.Lex(); // Eat the '('.
1930 if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) {
1931 // Nothing to do here, fall into the code below with the '(' part of the
1932 // memory operand consumed.
1936 // It must be an parenthesized expression, parse it now.
1937 if (getParser().parseParenExpression(Disp, ExprEnd))
1940 // After parsing the base expression we could either have a parenthesized
1941 // memory address or not. If not, return now. If so, eat the (.
1942 if (getLexer().isNot(AsmToken::LParen)) {
1943 // Unless we have a segment register, treat this as an immediate.
1945 return X86Operand::CreateMem(getPointerWidth(), Disp, LParenLoc,
1947 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
1956 // If we reached here, then we just ate the ( of the memory operand. Process
1957 // the rest of the memory operand.
1958 unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
1959 SMLoc IndexLoc, BaseLoc;
1961 if (getLexer().is(AsmToken::Percent)) {
1962 SMLoc StartLoc, EndLoc;
1963 BaseLoc = Parser.getTok().getLoc();
1964 if (ParseRegister(BaseReg, StartLoc, EndLoc)) return nullptr;
1965 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) {
1966 Error(StartLoc, "eiz and riz can only be used as index registers",
1967 SMRange(StartLoc, EndLoc));
1972 if (getLexer().is(AsmToken::Comma)) {
1973 Parser.Lex(); // Eat the comma.
1974 IndexLoc = Parser.getTok().getLoc();
1976 // Following the comma we should have either an index register, or a scale
1977 // value. We don't support the later form, but we want to parse it
1980 // Not that even though it would be completely consistent to support syntax
1981 // like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this.
1982 if (getLexer().is(AsmToken::Percent)) {
1984 if (ParseRegister(IndexReg, L, L)) return nullptr;
1986 if (getLexer().isNot(AsmToken::RParen)) {
1987 // Parse the scale amount:
1988 // ::= ',' [scale-expression]
1989 if (getLexer().isNot(AsmToken::Comma)) {
1990 Error(Parser.getTok().getLoc(),
1991 "expected comma in scale expression");
1994 Parser.Lex(); // Eat the comma.
1996 if (getLexer().isNot(AsmToken::RParen)) {
1997 SMLoc Loc = Parser.getTok().getLoc();
2000 if (getParser().parseAbsoluteExpression(ScaleVal)){
2001 Error(Loc, "expected scale expression");
2005 // Validate the scale amount.
2006 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
2008 Error(Loc, "scale factor in 16-bit address must be 1");
2011 if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 &&
2013 Error(Loc, "scale factor in address must be 1, 2, 4 or 8");
2016 Scale = (unsigned)ScaleVal;
2019 } else if (getLexer().isNot(AsmToken::RParen)) {
2020 // A scale amount without an index is ignored.
2022 SMLoc Loc = Parser.getTok().getLoc();
2025 if (getParser().parseAbsoluteExpression(Value))
2029 Warning(Loc, "scale factor without index register is ignored");
2034 // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
2035 if (getLexer().isNot(AsmToken::RParen)) {
2036 Error(Parser.getTok().getLoc(), "unexpected token in memory operand");
2039 SMLoc MemEnd = Parser.getTok().getEndLoc();
2040 Parser.Lex(); // Eat the ')'.
2042 // Check for use of invalid 16-bit registers. Only BX/BP/SI/DI are allowed,
2043 // and then only in non-64-bit modes. Except for DX, which is a special case
2044 // because an unofficial form of in/out instructions uses it.
2045 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
2046 (is64BitMode() || (BaseReg != X86::BX && BaseReg != X86::BP &&
2047 BaseReg != X86::SI && BaseReg != X86::DI)) &&
2048 BaseReg != X86::DX) {
2049 Error(BaseLoc, "invalid 16-bit base register");
2053 X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg)) {
2054 Error(IndexLoc, "16-bit memory operand may not include only index register");
2059 if (CheckBaseRegAndIndexReg(BaseReg, IndexReg, ErrMsg)) {
2060 Error(BaseLoc, ErrMsg);
2064 if (SegReg || BaseReg || IndexReg)
2065 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
2066 IndexReg, Scale, MemStart, MemEnd);
2067 return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, MemEnd);
2070 bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2071 SMLoc NameLoc, OperandVector &Operands) {
2072 MCAsmParser &Parser = getParser();
2074 StringRef PatchedName = Name;
2076 // FIXME: Hack to recognize setneb as setne.
2077 if (PatchedName.startswith("set") && PatchedName.endswith("b") &&
2078 PatchedName != "setb" && PatchedName != "setnb")
2079 PatchedName = PatchedName.substr(0, Name.size()-1);
2081 // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}.
2082 if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) &&
2083 (PatchedName.endswith("ss") || PatchedName.endswith("sd") ||
2084 PatchedName.endswith("ps") || PatchedName.endswith("pd"))) {
2085 bool IsVCMP = PatchedName[0] == 'v';
2086 unsigned CCIdx = IsVCMP ? 4 : 3;
2087 unsigned ComparisonCode = StringSwitch<unsigned>(
2088 PatchedName.slice(CCIdx, PatchedName.size() - 2))
2092 .Case("unord", 0x03)
2097 /* AVX only from here */
2098 .Case("eq_uq", 0x08)
2101 .Case("false", 0x0B)
2102 .Case("neq_oq", 0x0C)
2106 .Case("eq_os", 0x10)
2107 .Case("lt_oq", 0x11)
2108 .Case("le_oq", 0x12)
2109 .Case("unord_s", 0x13)
2110 .Case("neq_us", 0x14)
2111 .Case("nlt_uq", 0x15)
2112 .Case("nle_uq", 0x16)
2113 .Case("ord_s", 0x17)
2114 .Case("eq_us", 0x18)
2115 .Case("nge_uq", 0x19)
2116 .Case("ngt_uq", 0x1A)
2117 .Case("false_os", 0x1B)
2118 .Case("neq_os", 0x1C)
2119 .Case("ge_oq", 0x1D)
2120 .Case("gt_oq", 0x1E)
2121 .Case("true_us", 0x1F)
2123 if (ComparisonCode != ~0U && (IsVCMP || ComparisonCode < 8)) {
2125 Operands.push_back(X86Operand::CreateToken(PatchedName.slice(0, CCIdx),
2128 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2129 getParser().getContext());
2130 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2132 PatchedName = PatchedName.substr(PatchedName.size() - 2);
2136 // FIXME: Hack to recognize vpcmp<comparison code>{ub,uw,ud,uq,b,w,d,q}.
2137 if (PatchedName.startswith("vpcmp") &&
2138 (PatchedName.endswith("b") || PatchedName.endswith("w") ||
2139 PatchedName.endswith("d") || PatchedName.endswith("q"))) {
2140 unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1;
2141 unsigned ComparisonCode = StringSwitch<unsigned>(
2142 PatchedName.slice(5, PatchedName.size() - CCIdx))
2143 .Case("eq", 0x0) // Only allowed on unsigned. Checked below.
2146 //.Case("false", 0x3) // Not a documented alias.
2150 //.Case("true", 0x7) // Not a documented alias.
2152 if (ComparisonCode != ~0U && (ComparisonCode != 0 || CCIdx == 2)) {
2153 Operands.push_back(X86Operand::CreateToken("vpcmp", NameLoc));
2155 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2156 getParser().getContext());
2157 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2159 PatchedName = PatchedName.substr(PatchedName.size() - CCIdx);
2163 // FIXME: Hack to recognize vpcom<comparison code>{ub,uw,ud,uq,b,w,d,q}.
2164 if (PatchedName.startswith("vpcom") &&
2165 (PatchedName.endswith("b") || PatchedName.endswith("w") ||
2166 PatchedName.endswith("d") || PatchedName.endswith("q"))) {
2167 unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1;
2168 unsigned ComparisonCode = StringSwitch<unsigned>(
2169 PatchedName.slice(5, PatchedName.size() - CCIdx))
2179 if (ComparisonCode != ~0U) {
2180 Operands.push_back(X86Operand::CreateToken("vpcom", NameLoc));
2182 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2183 getParser().getContext());
2184 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2186 PatchedName = PatchedName.substr(PatchedName.size() - CCIdx);
2190 Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
2192 // Determine whether this is an instruction prefix.
2194 Name == "lock" || Name == "rep" ||
2195 Name == "repe" || Name == "repz" ||
2196 Name == "repne" || Name == "repnz" ||
2197 Name == "rex64" || Name == "data16";
2199 // This does the actual operand parsing. Don't parse any more if we have a
2200 // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we
2201 // just want to parse the "lock" as the first instruction and the "incl" as
2203 if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) {
2205 // Parse '*' modifier.
2206 if (getLexer().is(AsmToken::Star))
2207 Operands.push_back(X86Operand::CreateToken("*", consumeToken()));
2209 // Read the operands.
2211 if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
2212 Operands.push_back(std::move(Op));
2213 if (!HandleAVX512Operand(Operands, *Operands.back()))
2216 Parser.eatToEndOfStatement();
2219 // check for comma and eat it
2220 if (getLexer().is(AsmToken::Comma))
2226 if (getLexer().isNot(AsmToken::EndOfStatement))
2227 return ErrorAndEatStatement(getLexer().getLoc(),
2228 "unexpected token in argument list");
2231 // Consume the EndOfStatement or the prefix separator Slash
2232 if (getLexer().is(AsmToken::EndOfStatement) ||
2233 (isPrefix && getLexer().is(AsmToken::Slash)))
2236 // This is for gas compatibility and cannot be done in td.
2237 // Adding "p" for some floating point with no argument.
2238 // For example: fsub --> fsubp
2240 Name == "fsub" || Name == "fdiv" || Name == "fsubr" || Name == "fdivr";
2241 if (IsFp && Operands.size() == 1) {
2242 const char *Repl = StringSwitch<const char *>(Name)
2243 .Case("fsub", "fsubp")
2244 .Case("fdiv", "fdivp")
2245 .Case("fsubr", "fsubrp")
2246 .Case("fdivr", "fdivrp");
2247 static_cast<X86Operand &>(*Operands[0]).setTokenValue(Repl);
2250 // This is a terrible hack to handle "out[bwl]? %al, (%dx)" ->
2251 // "outb %al, %dx". Out doesn't take a memory form, but this is a widely
2252 // documented form in various unofficial manuals, so a lot of code uses it.
2253 if ((Name == "outb" || Name == "outw" || Name == "outl" || Name == "out") &&
2254 Operands.size() == 3) {
2255 X86Operand &Op = (X86Operand &)*Operands.back();
2256 if (Op.isMem() && Op.Mem.SegReg == 0 &&
2257 isa<MCConstantExpr>(Op.Mem.Disp) &&
2258 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
2259 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
2260 SMLoc Loc = Op.getEndLoc();
2261 Operands.back() = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
2264 // Same hack for "in[bwl]? (%dx), %al" -> "inb %dx, %al".
2265 if ((Name == "inb" || Name == "inw" || Name == "inl" || Name == "in") &&
2266 Operands.size() == 3) {
2267 X86Operand &Op = (X86Operand &)*Operands[1];
2268 if (Op.isMem() && Op.Mem.SegReg == 0 &&
2269 isa<MCConstantExpr>(Op.Mem.Disp) &&
2270 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
2271 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
2272 SMLoc Loc = Op.getEndLoc();
2273 Operands[1] = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
2277 // Append default arguments to "ins[bwld]"
2278 if (Name.startswith("ins") && Operands.size() == 1 &&
2279 (Name == "insb" || Name == "insw" || Name == "insl" || Name == "insd")) {
2280 AddDefaultSrcDestOperands(Operands,
2281 X86Operand::CreateReg(X86::DX, NameLoc, NameLoc),
2282 DefaultMemDIOperand(NameLoc));
2285 // Append default arguments to "outs[bwld]"
2286 if (Name.startswith("outs") && Operands.size() == 1 &&
2287 (Name == "outsb" || Name == "outsw" || Name == "outsl" ||
2288 Name == "outsd" )) {
2289 AddDefaultSrcDestOperands(Operands,
2290 DefaultMemSIOperand(NameLoc),
2291 X86Operand::CreateReg(X86::DX, NameLoc, NameLoc));
2294 // Transform "lods[bwlq]" into "lods[bwlq] ($SIREG)" for appropriate
2295 // values of $SIREG according to the mode. It would be nice if this
2296 // could be achieved with InstAlias in the tables.
2297 if (Name.startswith("lods") && Operands.size() == 1 &&
2298 (Name == "lods" || Name == "lodsb" || Name == "lodsw" ||
2299 Name == "lodsl" || Name == "lodsd" || Name == "lodsq"))
2300 Operands.push_back(DefaultMemSIOperand(NameLoc));
2302 // Transform "stos[bwlq]" into "stos[bwlq] ($DIREG)" for appropriate
2303 // values of $DIREG according to the mode. It would be nice if this
2304 // could be achieved with InstAlias in the tables.
2305 if (Name.startswith("stos") && Operands.size() == 1 &&
2306 (Name == "stos" || Name == "stosb" || Name == "stosw" ||
2307 Name == "stosl" || Name == "stosd" || Name == "stosq"))
2308 Operands.push_back(DefaultMemDIOperand(NameLoc));
2310 // Transform "scas[bwlq]" into "scas[bwlq] ($DIREG)" for appropriate
2311 // values of $DIREG according to the mode. It would be nice if this
2312 // could be achieved with InstAlias in the tables.
2313 if (Name.startswith("scas") && Operands.size() == 1 &&
2314 (Name == "scas" || Name == "scasb" || Name == "scasw" ||
2315 Name == "scasl" || Name == "scasd" || Name == "scasq"))
2316 Operands.push_back(DefaultMemDIOperand(NameLoc));
2318 // Add default SI and DI operands to "cmps[bwlq]".
2319 if (Name.startswith("cmps") &&
2320 (Name == "cmps" || Name == "cmpsb" || Name == "cmpsw" ||
2321 Name == "cmpsl" || Name == "cmpsd" || Name == "cmpsq")) {
2322 if (Operands.size() == 1) {
2323 AddDefaultSrcDestOperands(Operands,
2324 DefaultMemDIOperand(NameLoc),
2325 DefaultMemSIOperand(NameLoc));
2326 } else if (Operands.size() == 3) {
2327 X86Operand &Op = (X86Operand &)*Operands[1];
2328 X86Operand &Op2 = (X86Operand &)*Operands[2];
2329 if (!doSrcDstMatch(Op, Op2))
2330 return Error(Op.getStartLoc(),
2331 "mismatching source and destination index registers");
2335 // Add default SI and DI operands to "movs[bwlq]".
2336 if ((Name.startswith("movs") &&
2337 (Name == "movs" || Name == "movsb" || Name == "movsw" ||
2338 Name == "movsl" || Name == "movsd" || Name == "movsq")) ||
2339 (Name.startswith("smov") &&
2340 (Name == "smov" || Name == "smovb" || Name == "smovw" ||
2341 Name == "smovl" || Name == "smovd" || Name == "smovq"))) {
2342 if (Operands.size() == 1) {
2343 if (Name == "movsd")
2344 Operands.back() = X86Operand::CreateToken("movsl", NameLoc);
2345 AddDefaultSrcDestOperands(Operands,
2346 DefaultMemSIOperand(NameLoc),
2347 DefaultMemDIOperand(NameLoc));
2348 } else if (Operands.size() == 3) {
2349 X86Operand &Op = (X86Operand &)*Operands[1];
2350 X86Operand &Op2 = (X86Operand &)*Operands[2];
2351 if (!doSrcDstMatch(Op, Op2))
2352 return Error(Op.getStartLoc(),
2353 "mismatching source and destination index registers");
2357 // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>. Canonicalize to
2359 if ((Name.startswith("shr") || Name.startswith("sar") ||
2360 Name.startswith("shl") || Name.startswith("sal") ||
2361 Name.startswith("rcl") || Name.startswith("rcr") ||
2362 Name.startswith("rol") || Name.startswith("ror")) &&
2363 Operands.size() == 3) {
2364 if (isParsingIntelSyntax()) {
2366 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[2]);
2367 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2368 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2369 Operands.pop_back();
2371 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2372 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2373 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2374 Operands.erase(Operands.begin() + 1);
2378 // Transforms "int $3" into "int3" as a size optimization. We can't write an
2379 // instalias with an immediate operand yet.
2380 if (Name == "int" && Operands.size() == 2) {
2381 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2383 if (auto *CE = dyn_cast<MCConstantExpr>(Op1.getImm()))
2384 if (CE->getValue() == 3) {
2385 Operands.erase(Operands.begin() + 1);
2386 static_cast<X86Operand &>(*Operands[0]).setTokenValue("int3");
2393 bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) {
2394 switch (Inst.getOpcode()) {
2395 default: return false;
2396 case X86::VMOVZPQILo2PQIrr:
2397 case X86::VMOVAPDrr:
2398 case X86::VMOVAPDYrr:
2399 case X86::VMOVAPSrr:
2400 case X86::VMOVAPSYrr:
2401 case X86::VMOVDQArr:
2402 case X86::VMOVDQAYrr:
2403 case X86::VMOVDQUrr:
2404 case X86::VMOVDQUYrr:
2405 case X86::VMOVUPDrr:
2406 case X86::VMOVUPDYrr:
2407 case X86::VMOVUPSrr:
2408 case X86::VMOVUPSYrr: {
2409 if (X86II::isX86_64ExtendedReg(Inst.getOperand(0).getReg()) ||
2410 !X86II::isX86_64ExtendedReg(Inst.getOperand(1).getReg()))
2414 switch (Inst.getOpcode()) {
2415 default: llvm_unreachable("Invalid opcode");
2416 case X86::VMOVZPQILo2PQIrr: NewOpc = X86::VMOVPQI2QIrr; break;
2417 case X86::VMOVAPDrr: NewOpc = X86::VMOVAPDrr_REV; break;
2418 case X86::VMOVAPDYrr: NewOpc = X86::VMOVAPDYrr_REV; break;
2419 case X86::VMOVAPSrr: NewOpc = X86::VMOVAPSrr_REV; break;
2420 case X86::VMOVAPSYrr: NewOpc = X86::VMOVAPSYrr_REV; break;
2421 case X86::VMOVDQArr: NewOpc = X86::VMOVDQArr_REV; break;
2422 case X86::VMOVDQAYrr: NewOpc = X86::VMOVDQAYrr_REV; break;
2423 case X86::VMOVDQUrr: NewOpc = X86::VMOVDQUrr_REV; break;
2424 case X86::VMOVDQUYrr: NewOpc = X86::VMOVDQUYrr_REV; break;
2425 case X86::VMOVUPDrr: NewOpc = X86::VMOVUPDrr_REV; break;
2426 case X86::VMOVUPDYrr: NewOpc = X86::VMOVUPDYrr_REV; break;
2427 case X86::VMOVUPSrr: NewOpc = X86::VMOVUPSrr_REV; break;
2428 case X86::VMOVUPSYrr: NewOpc = X86::VMOVUPSYrr_REV; break;
2430 Inst.setOpcode(NewOpc);
2434 case X86::VMOVSSrr: {
2435 if (X86II::isX86_64ExtendedReg(Inst.getOperand(0).getReg()) ||
2436 !X86II::isX86_64ExtendedReg(Inst.getOperand(2).getReg()))
2439 switch (Inst.getOpcode()) {
2440 default: llvm_unreachable("Invalid opcode");
2441 case X86::VMOVSDrr: NewOpc = X86::VMOVSDrr_REV; break;
2442 case X86::VMOVSSrr: NewOpc = X86::VMOVSSrr_REV; break;
2444 Inst.setOpcode(NewOpc);
2450 static const char *getSubtargetFeatureName(uint64_t Val);
2452 void X86AsmParser::EmitInstruction(MCInst &Inst, OperandVector &Operands,
2454 Instrumentation->InstrumentAndEmitInstruction(Inst, Operands, getContext(),
2458 bool X86AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2459 OperandVector &Operands,
2460 MCStreamer &Out, uint64_t &ErrorInfo,
2461 bool MatchingInlineAsm) {
2462 if (isParsingIntelSyntax())
2463 return MatchAndEmitIntelInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2465 return MatchAndEmitATTInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2469 void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op,
2470 OperandVector &Operands, MCStreamer &Out,
2471 bool MatchingInlineAsm) {
2472 // FIXME: This should be replaced with a real .td file alias mechanism.
2473 // Also, MatchInstructionImpl should actually *do* the EmitInstruction
2475 const char *Repl = StringSwitch<const char *>(Op.getToken())
2476 .Case("finit", "fninit")
2477 .Case("fsave", "fnsave")
2478 .Case("fstcw", "fnstcw")
2479 .Case("fstcww", "fnstcw")
2480 .Case("fstenv", "fnstenv")
2481 .Case("fstsw", "fnstsw")
2482 .Case("fstsww", "fnstsw")
2483 .Case("fclex", "fnclex")
2487 Inst.setOpcode(X86::WAIT);
2489 if (!MatchingInlineAsm)
2490 EmitInstruction(Inst, Operands, Out);
2491 Operands[0] = X86Operand::CreateToken(Repl, IDLoc);
2495 bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
2496 bool MatchingInlineAsm) {
2497 assert(ErrorInfo && "Unknown missing feature!");
2498 ArrayRef<SMRange> EmptyRanges = None;
2499 SmallString<126> Msg;
2500 raw_svector_ostream OS(Msg);
2501 OS << "instruction requires:";
2503 for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
2504 if (ErrorInfo & Mask)
2505 OS << ' ' << getSubtargetFeatureName(ErrorInfo & Mask);
2508 return Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
2511 bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
2512 OperandVector &Operands,
2514 uint64_t &ErrorInfo,
2515 bool MatchingInlineAsm) {
2516 assert(!Operands.empty() && "Unexpect empty operand list!");
2517 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2518 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
2519 ArrayRef<SMRange> EmptyRanges = None;
2521 // First, handle aliases that expand to multiple instructions.
2522 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2524 bool WasOriginallyInvalidOperand = false;
2527 // First, try a direct match.
2528 switch (MatchInstructionImpl(Operands, Inst,
2529 ErrorInfo, MatchingInlineAsm,
2530 isParsingIntelSyntax())) {
2531 default: llvm_unreachable("Unexpected match result!");
2533 // Some instructions need post-processing to, for example, tweak which
2534 // encoding is selected. Loop on it while changes happen so the
2535 // individual transformations can chain off each other.
2536 if (!MatchingInlineAsm)
2537 while (processInstruction(Inst, Operands))
2541 if (!MatchingInlineAsm)
2542 EmitInstruction(Inst, Operands, Out);
2543 Opcode = Inst.getOpcode();
2545 case Match_MissingFeature:
2546 return ErrorMissingFeature(IDLoc, ErrorInfo, MatchingInlineAsm);
2547 case Match_InvalidOperand:
2548 WasOriginallyInvalidOperand = true;
2550 case Match_MnemonicFail:
2554 // FIXME: Ideally, we would only attempt suffix matches for things which are
2555 // valid prefixes, and we could just infer the right unambiguous
2556 // type. However, that requires substantially more matcher support than the
2559 // Change the operand to point to a temporary token.
2560 StringRef Base = Op.getToken();
2561 SmallString<16> Tmp;
2564 Op.setTokenValue(Tmp);
2566 // If this instruction starts with an 'f', then it is a floating point stack
2567 // instruction. These come in up to three forms for 32-bit, 64-bit, and
2568 // 80-bit floating point, which use the suffixes s,l,t respectively.
2570 // Otherwise, we assume that this may be an integer instruction, which comes
2571 // in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively.
2572 const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0";
2574 // Check for the various suffix matches.
2575 uint64_t ErrorInfoIgnore;
2576 uint64_t ErrorInfoMissingFeature = 0; // Init suppresses compiler warnings.
2579 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I) {
2580 Tmp.back() = Suffixes[I];
2581 Match[I] = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
2582 MatchingInlineAsm, isParsingIntelSyntax());
2583 // If this returned as a missing feature failure, remember that.
2584 if (Match[I] == Match_MissingFeature)
2585 ErrorInfoMissingFeature = ErrorInfoIgnore;
2588 // Restore the old token.
2589 Op.setTokenValue(Base);
2591 // If exactly one matched, then we treat that as a successful match (and the
2592 // instruction will already have been filled in correctly, since the failing
2593 // matches won't have modified it).
2594 unsigned NumSuccessfulMatches =
2595 std::count(std::begin(Match), std::end(Match), Match_Success);
2596 if (NumSuccessfulMatches == 1) {
2598 if (!MatchingInlineAsm)
2599 EmitInstruction(Inst, Operands, Out);
2600 Opcode = Inst.getOpcode();
2604 // Otherwise, the match failed, try to produce a decent error message.
2606 // If we had multiple suffix matches, then identify this as an ambiguous
2608 if (NumSuccessfulMatches > 1) {
2610 unsigned NumMatches = 0;
2611 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I)
2612 if (Match[I] == Match_Success)
2613 MatchChars[NumMatches++] = Suffixes[I];
2615 SmallString<126> Msg;
2616 raw_svector_ostream OS(Msg);
2617 OS << "ambiguous instructions require an explicit suffix (could be ";
2618 for (unsigned i = 0; i != NumMatches; ++i) {
2621 if (i + 1 == NumMatches)
2623 OS << "'" << Base << MatchChars[i] << "'";
2626 Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
2630 // Okay, we know that none of the variants matched successfully.
2632 // If all of the instructions reported an invalid mnemonic, then the original
2633 // mnemonic was invalid.
2634 if (std::count(std::begin(Match), std::end(Match), Match_MnemonicFail) == 4) {
2635 if (!WasOriginallyInvalidOperand) {
2636 ArrayRef<SMRange> Ranges =
2637 MatchingInlineAsm ? EmptyRanges : Op.getLocRange();
2638 return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'",
2639 Ranges, MatchingInlineAsm);
2642 // Recover location info for the operand if we know which was the problem.
2643 if (ErrorInfo != ~0ULL) {
2644 if (ErrorInfo >= Operands.size())
2645 return Error(IDLoc, "too few operands for instruction",
2646 EmptyRanges, MatchingInlineAsm);
2648 X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo];
2649 if (Operand.getStartLoc().isValid()) {
2650 SMRange OperandRange = Operand.getLocRange();
2651 return Error(Operand.getStartLoc(), "invalid operand for instruction",
2652 OperandRange, MatchingInlineAsm);
2656 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2660 // If one instruction matched with a missing feature, report this as a
2662 if (std::count(std::begin(Match), std::end(Match),
2663 Match_MissingFeature) == 1) {
2664 ErrorInfo = ErrorInfoMissingFeature;
2665 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
2669 // If one instruction matched with an invalid operand, report this as an
2671 if (std::count(std::begin(Match), std::end(Match),
2672 Match_InvalidOperand) == 1) {
2673 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2677 // If all of these were an outright failure, report it in a useless way.
2678 Error(IDLoc, "unknown use of instruction mnemonic without a size suffix",
2679 EmptyRanges, MatchingInlineAsm);
2683 bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
2684 OperandVector &Operands,
2686 uint64_t &ErrorInfo,
2687 bool MatchingInlineAsm) {
2688 assert(!Operands.empty() && "Unexpect empty operand list!");
2689 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2690 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
2691 StringRef Mnemonic = Op.getToken();
2692 ArrayRef<SMRange> EmptyRanges = None;
2694 // First, handle aliases that expand to multiple instructions.
2695 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2699 // Find one unsized memory operand, if present.
2700 X86Operand *UnsizedMemOp = nullptr;
2701 for (const auto &Op : Operands) {
2702 X86Operand *X86Op = static_cast<X86Operand *>(Op.get());
2703 if (X86Op->isMemUnsized())
2704 UnsizedMemOp = X86Op;
2707 // Allow some instructions to have implicitly pointer-sized operands. This is
2708 // compatible with gas.
2710 static const char *const PtrSizedInstrs[] = {"call", "jmp", "push"};
2711 for (const char *Instr : PtrSizedInstrs) {
2712 if (Mnemonic == Instr) {
2713 UnsizedMemOp->Mem.Size = getPointerWidth();
2719 // If an unsized memory operand is present, try to match with each memory
2720 // operand size. In Intel assembly, the size is not part of the instruction
2722 SmallVector<unsigned, 8> Match;
2723 uint64_t ErrorInfoMissingFeature = 0;
2724 if (UnsizedMemOp && UnsizedMemOp->isMemUnsized()) {
2725 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
2726 for (unsigned Size : MopSizes) {
2727 UnsizedMemOp->Mem.Size = Size;
2728 uint64_t ErrorInfoIgnore;
2729 unsigned LastOpcode = Inst.getOpcode();
2731 MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
2732 MatchingInlineAsm, isParsingIntelSyntax());
2733 if (Match.empty() || LastOpcode != Inst.getOpcode())
2736 // If this returned as a missing feature failure, remember that.
2737 if (Match.back() == Match_MissingFeature)
2738 ErrorInfoMissingFeature = ErrorInfoIgnore;
2741 // Restore the size of the unsized memory operand if we modified it.
2743 UnsizedMemOp->Mem.Size = 0;
2746 // If we haven't matched anything yet, this is not a basic integer or FPU
2747 // operation. There shouldn't be any ambiguity in our mnemonic table, so try
2748 // matching with the unsized operand.
2749 if (Match.empty()) {
2750 Match.push_back(MatchInstructionImpl(Operands, Inst, ErrorInfo,
2752 isParsingIntelSyntax()));
2753 // If this returned as a missing feature failure, remember that.
2754 if (Match.back() == Match_MissingFeature)
2755 ErrorInfoMissingFeature = ErrorInfo;
2758 // Restore the size of the unsized memory operand if we modified it.
2760 UnsizedMemOp->Mem.Size = 0;
2762 // If it's a bad mnemonic, all results will be the same.
2763 if (Match.back() == Match_MnemonicFail) {
2764 ArrayRef<SMRange> Ranges =
2765 MatchingInlineAsm ? EmptyRanges : Op.getLocRange();
2766 return Error(IDLoc, "invalid instruction mnemonic '" + Mnemonic + "'",
2767 Ranges, MatchingInlineAsm);
2770 // If exactly one matched, then we treat that as a successful match (and the
2771 // instruction will already have been filled in correctly, since the failing
2772 // matches won't have modified it).
2773 unsigned NumSuccessfulMatches =
2774 std::count(std::begin(Match), std::end(Match), Match_Success);
2775 if (NumSuccessfulMatches == 1) {
2776 // Some instructions need post-processing to, for example, tweak which
2777 // encoding is selected. Loop on it while changes happen so the individual
2778 // transformations can chain off each other.
2779 if (!MatchingInlineAsm)
2780 while (processInstruction(Inst, Operands))
2783 if (!MatchingInlineAsm)
2784 EmitInstruction(Inst, Operands, Out);
2785 Opcode = Inst.getOpcode();
2787 } else if (NumSuccessfulMatches > 1) {
2788 assert(UnsizedMemOp &&
2789 "multiple matches only possible with unsized memory operands");
2790 ArrayRef<SMRange> Ranges =
2791 MatchingInlineAsm ? EmptyRanges : UnsizedMemOp->getLocRange();
2792 return Error(UnsizedMemOp->getStartLoc(),
2793 "ambiguous operand size for instruction '" + Mnemonic + "\'",
2794 Ranges, MatchingInlineAsm);
2797 // If one instruction matched with a missing feature, report this as a
2799 if (std::count(std::begin(Match), std::end(Match),
2800 Match_MissingFeature) == 1) {
2801 ErrorInfo = ErrorInfoMissingFeature;
2802 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
2806 // If one instruction matched with an invalid operand, report this as an
2808 if (std::count(std::begin(Match), std::end(Match),
2809 Match_InvalidOperand) == 1) {
2810 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2814 // If all of these were an outright failure, report it in a useless way.
2815 return Error(IDLoc, "unknown instruction mnemonic", EmptyRanges,
2819 bool X86AsmParser::OmitRegisterFromClobberLists(unsigned RegNo) {
2820 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo);
2823 bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
2824 MCAsmParser &Parser = getParser();
2825 StringRef IDVal = DirectiveID.getIdentifier();
2826 if (IDVal == ".word")
2827 return ParseDirectiveWord(2, DirectiveID.getLoc());
2828 else if (IDVal.startswith(".code"))
2829 return ParseDirectiveCode(IDVal, DirectiveID.getLoc());
2830 else if (IDVal.startswith(".att_syntax")) {
2831 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2832 if (Parser.getTok().getString() == "prefix")
2834 else if (Parser.getTok().getString() == "noprefix")
2835 return Error(DirectiveID.getLoc(), "'.att_syntax noprefix' is not "
2836 "supported: registers must have a "
2837 "'%' prefix in .att_syntax");
2839 getParser().setAssemblerDialect(0);
2841 } else if (IDVal.startswith(".intel_syntax")) {
2842 getParser().setAssemblerDialect(1);
2843 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2844 if (Parser.getTok().getString() == "noprefix")
2846 else if (Parser.getTok().getString() == "prefix")
2847 return Error(DirectiveID.getLoc(), "'.intel_syntax prefix' is not "
2848 "supported: registers must not have "
2849 "a '%' prefix in .intel_syntax");
2852 } else if (IDVal == ".even")
2853 return parseDirectiveEven(DirectiveID.getLoc());
2857 /// parseDirectiveEven
2859 bool X86AsmParser::parseDirectiveEven(SMLoc L) {
2860 const MCSection *Section = getStreamer().getCurrentSection().first;
2861 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2862 TokError("unexpected token in directive");
2866 getStreamer().InitSections(false);
2867 Section = getStreamer().getCurrentSection().first;
2869 if (Section->UseCodeAlign())
2870 getStreamer().EmitCodeAlignment(2, 0);
2872 getStreamer().EmitValueToAlignment(2, 0, 1, 0);
2875 /// ParseDirectiveWord
2876 /// ::= .word [ expression (, expression)* ]
2877 bool X86AsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
2878 MCAsmParser &Parser = getParser();
2879 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2881 const MCExpr *Value;
2882 SMLoc ExprLoc = getLexer().getLoc();
2883 if (getParser().parseExpression(Value))
2886 if (const auto *MCE = dyn_cast<MCConstantExpr>(Value)) {
2887 assert(Size <= 8 && "Invalid size");
2888 uint64_t IntValue = MCE->getValue();
2889 if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))
2890 return Error(ExprLoc, "literal value out of range for directive");
2891 getStreamer().EmitIntValue(IntValue, Size);
2893 getStreamer().EmitValue(Value, Size, ExprLoc);
2896 if (getLexer().is(AsmToken::EndOfStatement))
2899 // FIXME: Improve diagnostic.
2900 if (getLexer().isNot(AsmToken::Comma)) {
2901 Error(L, "unexpected token in directive");
2912 /// ParseDirectiveCode
2913 /// ::= .code16 | .code32 | .code64
2914 bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
2915 MCAsmParser &Parser = getParser();
2916 if (IDVal == ".code16") {
2918 if (!is16BitMode()) {
2919 SwitchMode(X86::Mode16Bit);
2920 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
2922 } else if (IDVal == ".code32") {
2924 if (!is32BitMode()) {
2925 SwitchMode(X86::Mode32Bit);
2926 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
2928 } else if (IDVal == ".code64") {
2930 if (!is64BitMode()) {
2931 SwitchMode(X86::Mode64Bit);
2932 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code64);
2935 Error(L, "unknown directive " + IDVal);
2942 // Force static initialization.
2943 extern "C" void LLVMInitializeX86AsmParser() {
2944 RegisterMCAsmParser<X86AsmParser> X(TheX86_32Target);
2945 RegisterMCAsmParser<X86AsmParser> Y(TheX86_64Target);
2948 #define GET_REGISTER_MATCHER
2949 #define GET_MATCHER_IMPLEMENTATION
2950 #define GET_SUBTARGET_FEATURE_NAME
2951 #include "X86GenAsmMatcher.inc"