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 {
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 ParseDirectiveWord(unsigned Size, SMLoc L);
718 bool ParseDirectiveCode(StringRef IDVal, SMLoc L);
720 bool processInstruction(MCInst &Inst, const OperandVector &Ops);
722 /// Wrapper around MCStreamer::EmitInstruction(). Possibly adds
723 /// instrumentation around Inst.
724 void EmitInstruction(MCInst &Inst, OperandVector &Operands, MCStreamer &Out);
726 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
727 OperandVector &Operands, MCStreamer &Out,
729 bool MatchingInlineAsm) override;
731 void MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op, OperandVector &Operands,
732 MCStreamer &Out, bool MatchingInlineAsm);
734 bool ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
735 bool MatchingInlineAsm);
737 bool MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
738 OperandVector &Operands, MCStreamer &Out,
740 bool MatchingInlineAsm);
742 bool MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
743 OperandVector &Operands, MCStreamer &Out,
745 bool MatchingInlineAsm);
747 bool OmitRegisterFromClobberLists(unsigned RegNo) override;
749 /// doSrcDstMatch - Returns true if operands are matching in their
750 /// word size (%si and %di, %esi and %edi, etc.). Order depends on
751 /// the parsing mode (Intel vs. AT&T).
752 bool doSrcDstMatch(X86Operand &Op1, X86Operand &Op2);
754 /// Parses AVX512 specific operand primitives: masked registers ({%k<NUM>}, {z})
755 /// and memory broadcasting ({1to<NUM>}) primitives, updating Operands vector if required.
756 /// \return \c true if no parsing errors occurred, \c false otherwise.
757 bool HandleAVX512Operand(OperandVector &Operands,
758 const MCParsedAsmOperand &Op);
760 bool is64BitMode() const {
761 // FIXME: Can tablegen auto-generate this?
762 return getSTI().getFeatureBits()[X86::Mode64Bit];
764 bool is32BitMode() const {
765 // FIXME: Can tablegen auto-generate this?
766 return getSTI().getFeatureBits()[X86::Mode32Bit];
768 bool is16BitMode() const {
769 // FIXME: Can tablegen auto-generate this?
770 return getSTI().getFeatureBits()[X86::Mode16Bit];
772 void SwitchMode(unsigned mode) {
773 MCSubtargetInfo &STI = copySTI();
774 FeatureBitset AllModes({X86::Mode64Bit, X86::Mode32Bit, X86::Mode16Bit});
775 FeatureBitset OldMode = STI.getFeatureBits() & AllModes;
776 unsigned FB = ComputeAvailableFeatures(
777 STI.ToggleFeature(OldMode.flip(mode)));
778 setAvailableFeatures(FB);
780 assert(FeatureBitset({mode}) == (STI.getFeatureBits() & AllModes));
783 unsigned getPointerWidth() {
784 if (is16BitMode()) return 16;
785 if (is32BitMode()) return 32;
786 if (is64BitMode()) return 64;
787 llvm_unreachable("invalid mode");
790 bool isParsingIntelSyntax() {
791 return getParser().getAssemblerDialect();
794 /// @name Auto-generated Matcher Functions
797 #define GET_ASSEMBLER_HEADER
798 #include "X86GenAsmMatcher.inc"
803 X86AsmParser(const MCSubtargetInfo &sti, MCAsmParser &Parser,
804 const MCInstrInfo &mii, const MCTargetOptions &Options)
805 : MCTargetAsmParser(Options, sti), MII(mii), InstInfo(nullptr) {
807 // Initialize the set of available features.
808 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
809 Instrumentation.reset(
810 CreateX86AsmInstrumentation(Options, Parser.getContext(), STI));
813 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
815 void SetFrameRegister(unsigned RegNo) override;
817 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
818 SMLoc NameLoc, OperandVector &Operands) override;
820 bool ParseDirective(AsmToken DirectiveID) override;
822 } // end anonymous namespace
824 /// @name Auto-generated Match Functions
827 static unsigned MatchRegisterName(StringRef Name);
831 static bool CheckBaseRegAndIndexReg(unsigned BaseReg, unsigned IndexReg,
833 // If we have both a base register and an index register make sure they are
834 // both 64-bit or 32-bit registers.
835 // To support VSIB, IndexReg can be 128-bit or 256-bit registers.
836 if (BaseReg != 0 && IndexReg != 0) {
837 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) &&
838 (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
839 X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg)) &&
840 IndexReg != X86::RIZ) {
841 ErrMsg = "base register is 64-bit, but index register is not";
844 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg) &&
845 (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
846 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) &&
847 IndexReg != X86::EIZ){
848 ErrMsg = "base register is 32-bit, but index register is not";
851 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg)) {
852 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg) ||
853 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) {
854 ErrMsg = "base register is 16-bit, but index register is not";
857 if (((BaseReg == X86::BX || BaseReg == X86::BP) &&
858 IndexReg != X86::SI && IndexReg != X86::DI) ||
859 ((BaseReg == X86::SI || BaseReg == X86::DI) &&
860 IndexReg != X86::BX && IndexReg != X86::BP)) {
861 ErrMsg = "invalid 16-bit base/index register combination";
869 bool X86AsmParser::doSrcDstMatch(X86Operand &Op1, X86Operand &Op2)
871 // Return true and let a normal complaint about bogus operands happen.
872 if (!Op1.isMem() || !Op2.isMem())
875 // Actually these might be the other way round if Intel syntax is
876 // being used. It doesn't matter.
877 unsigned diReg = Op1.Mem.BaseReg;
878 unsigned siReg = Op2.Mem.BaseReg;
880 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(siReg))
881 return X86MCRegisterClasses[X86::GR16RegClassID].contains(diReg);
882 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(siReg))
883 return X86MCRegisterClasses[X86::GR32RegClassID].contains(diReg);
884 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(siReg))
885 return X86MCRegisterClasses[X86::GR64RegClassID].contains(diReg);
886 // Again, return true and let another error happen.
890 bool X86AsmParser::ParseRegister(unsigned &RegNo,
891 SMLoc &StartLoc, SMLoc &EndLoc) {
892 MCAsmParser &Parser = getParser();
894 const AsmToken &PercentTok = Parser.getTok();
895 StartLoc = PercentTok.getLoc();
897 // If we encounter a %, ignore it. This code handles registers with and
898 // without the prefix, unprefixed registers can occur in cfi directives.
899 if (!isParsingIntelSyntax() && PercentTok.is(AsmToken::Percent))
900 Parser.Lex(); // Eat percent token.
902 const AsmToken &Tok = Parser.getTok();
903 EndLoc = Tok.getEndLoc();
905 if (Tok.isNot(AsmToken::Identifier)) {
906 if (isParsingIntelSyntax()) return true;
907 return Error(StartLoc, "invalid register name",
908 SMRange(StartLoc, EndLoc));
911 RegNo = MatchRegisterName(Tok.getString());
913 // If the match failed, try the register name as lowercase.
915 RegNo = MatchRegisterName(Tok.getString().lower());
917 // The "flags" register cannot be referenced directly.
918 // Treat it as an identifier instead.
919 if (isParsingInlineAsm() && isParsingIntelSyntax() && RegNo == X86::EFLAGS)
922 if (!is64BitMode()) {
923 // FIXME: This should be done using Requires<Not64BitMode> and
924 // Requires<In64BitMode> so "eiz" usage in 64-bit instructions can be also
926 // FIXME: Check AH, CH, DH, BH cannot be used in an instruction requiring a
928 if (RegNo == X86::RIZ ||
929 X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo) ||
930 X86II::isX86_64NonExtLowByteReg(RegNo) ||
931 X86II::isX86_64ExtendedReg(RegNo))
932 return Error(StartLoc, "register %"
933 + Tok.getString() + " is only available in 64-bit mode",
934 SMRange(StartLoc, EndLoc));
937 // Parse "%st" as "%st(0)" and "%st(1)", which is multiple tokens.
938 if (RegNo == 0 && (Tok.getString() == "st" || Tok.getString() == "ST")) {
940 Parser.Lex(); // Eat 'st'
942 // Check to see if we have '(4)' after %st.
943 if (getLexer().isNot(AsmToken::LParen))
948 const AsmToken &IntTok = Parser.getTok();
949 if (IntTok.isNot(AsmToken::Integer))
950 return Error(IntTok.getLoc(), "expected stack index");
951 switch (IntTok.getIntVal()) {
952 case 0: RegNo = X86::ST0; break;
953 case 1: RegNo = X86::ST1; break;
954 case 2: RegNo = X86::ST2; break;
955 case 3: RegNo = X86::ST3; break;
956 case 4: RegNo = X86::ST4; break;
957 case 5: RegNo = X86::ST5; break;
958 case 6: RegNo = X86::ST6; break;
959 case 7: RegNo = X86::ST7; break;
960 default: return Error(IntTok.getLoc(), "invalid stack index");
963 if (getParser().Lex().isNot(AsmToken::RParen))
964 return Error(Parser.getTok().getLoc(), "expected ')'");
966 EndLoc = Parser.getTok().getEndLoc();
967 Parser.Lex(); // Eat ')'
971 EndLoc = Parser.getTok().getEndLoc();
973 // If this is "db[0-7]", match it as an alias
975 if (RegNo == 0 && Tok.getString().size() == 3 &&
976 Tok.getString().startswith("db")) {
977 switch (Tok.getString()[2]) {
978 case '0': RegNo = X86::DR0; break;
979 case '1': RegNo = X86::DR1; break;
980 case '2': RegNo = X86::DR2; break;
981 case '3': RegNo = X86::DR3; break;
982 case '4': RegNo = X86::DR4; break;
983 case '5': RegNo = X86::DR5; break;
984 case '6': RegNo = X86::DR6; break;
985 case '7': RegNo = X86::DR7; break;
989 EndLoc = Parser.getTok().getEndLoc();
990 Parser.Lex(); // Eat it.
996 if (isParsingIntelSyntax()) return true;
997 return Error(StartLoc, "invalid register name",
998 SMRange(StartLoc, EndLoc));
1001 Parser.Lex(); // Eat identifier token.
1005 void X86AsmParser::SetFrameRegister(unsigned RegNo) {
1006 Instrumentation->SetInitialFrameRegister(RegNo);
1009 std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(SMLoc Loc) {
1011 is64BitMode() ? X86::RSI : (is32BitMode() ? X86::ESI : X86::SI);
1012 const MCExpr *Disp = MCConstantExpr::create(0, getContext());
1013 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
1014 /*BaseReg=*/basereg, /*IndexReg=*/0, /*Scale=*/1,
1018 std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand(SMLoc Loc) {
1020 is64BitMode() ? X86::RDI : (is32BitMode() ? X86::EDI : X86::DI);
1021 const MCExpr *Disp = MCConstantExpr::create(0, getContext());
1022 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
1023 /*BaseReg=*/basereg, /*IndexReg=*/0, /*Scale=*/1,
1027 void X86AsmParser::AddDefaultSrcDestOperands(
1028 OperandVector& Operands, std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
1029 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst) {
1030 if (isParsingIntelSyntax()) {
1031 Operands.push_back(std::move(Dst));
1032 Operands.push_back(std::move(Src));
1035 Operands.push_back(std::move(Src));
1036 Operands.push_back(std::move(Dst));
1040 std::unique_ptr<X86Operand> X86AsmParser::ParseOperand() {
1041 if (isParsingIntelSyntax())
1042 return ParseIntelOperand();
1043 return ParseATTOperand();
1046 /// getIntelMemOperandSize - Return intel memory operand size.
1047 static unsigned getIntelMemOperandSize(StringRef OpStr) {
1048 unsigned Size = StringSwitch<unsigned>(OpStr)
1049 .Cases("BYTE", "byte", 8)
1050 .Cases("WORD", "word", 16)
1051 .Cases("DWORD", "dword", 32)
1052 .Cases("FWORD", "fword", 48)
1053 .Cases("QWORD", "qword", 64)
1054 .Cases("MMWORD","mmword", 64)
1055 .Cases("XWORD", "xword", 80)
1056 .Cases("TBYTE", "tbyte", 80)
1057 .Cases("XMMWORD", "xmmword", 128)
1058 .Cases("YMMWORD", "ymmword", 256)
1059 .Cases("ZMMWORD", "zmmword", 512)
1060 .Cases("OPAQUE", "opaque", -1U) // needs to be non-zero, but doesn't matter
1065 std::unique_ptr<X86Operand> X86AsmParser::CreateMemForInlineAsm(
1066 unsigned SegReg, const MCExpr *Disp, unsigned BaseReg, unsigned IndexReg,
1067 unsigned Scale, SMLoc Start, SMLoc End, unsigned Size, StringRef Identifier,
1068 InlineAsmIdentifierInfo &Info) {
1069 // If we found a decl other than a VarDecl, then assume it is a FuncDecl or
1070 // some other label reference.
1071 if (isa<MCSymbolRefExpr>(Disp) && Info.OpDecl && !Info.IsVarDecl) {
1072 // Insert an explicit size if the user didn't have one.
1074 Size = getPointerWidth();
1075 InstInfo->AsmRewrites->emplace_back(AOK_SizeDirective, Start,
1079 // Create an absolute memory reference in order to match against
1080 // instructions taking a PC relative operand.
1081 return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size,
1082 Identifier, Info.OpDecl);
1085 // We either have a direct symbol reference, or an offset from a symbol. The
1086 // parser always puts the symbol on the LHS, so look there for size
1087 // calculation purposes.
1088 const MCBinaryExpr *BinOp = dyn_cast<MCBinaryExpr>(Disp);
1090 isa<MCSymbolRefExpr>(BinOp ? BinOp->getLHS() : Disp);
1093 Size = Info.Type * 8; // Size is in terms of bits in this context.
1095 InstInfo->AsmRewrites->emplace_back(AOK_SizeDirective, Start,
1100 // When parsing inline assembly we set the base register to a non-zero value
1101 // if we don't know the actual value at this time. This is necessary to
1102 // get the matching correct in some cases.
1103 BaseReg = BaseReg ? BaseReg : 1;
1104 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
1105 IndexReg, Scale, Start, End, Size, Identifier,
1110 RewriteIntelBracExpression(SmallVectorImpl<AsmRewrite> &AsmRewrites,
1111 StringRef SymName, int64_t ImmDisp,
1112 int64_t FinalImmDisp, SMLoc &BracLoc,
1113 SMLoc &StartInBrac, SMLoc &End) {
1114 // Remove the '[' and ']' from the IR string.
1115 AsmRewrites.emplace_back(AOK_Skip, BracLoc, 1);
1116 AsmRewrites.emplace_back(AOK_Skip, End, 1);
1118 // If ImmDisp is non-zero, then we parsed a displacement before the
1119 // bracketed expression (i.e., ImmDisp [ BaseReg + Scale*IndexReg + Disp])
1120 // If ImmDisp doesn't match the displacement computed by the state machine
1121 // then we have an additional displacement in the bracketed expression.
1122 if (ImmDisp != FinalImmDisp) {
1124 // We have an immediate displacement before the bracketed expression.
1125 // Adjust this to match the final immediate displacement.
1127 for (AsmRewrite &AR : AsmRewrites) {
1128 if (AR.Loc.getPointer() > BracLoc.getPointer())
1130 if (AR.Kind == AOK_ImmPrefix || AR.Kind == AOK_Imm) {
1131 assert (!Found && "ImmDisp already rewritten.");
1133 AR.Len = BracLoc.getPointer() - AR.Loc.getPointer();
1134 AR.Val = FinalImmDisp;
1139 assert (Found && "Unable to rewrite ImmDisp.");
1142 // We have a symbolic and an immediate displacement, but no displacement
1143 // before the bracketed expression. Put the immediate displacement
1144 // before the bracketed expression.
1145 AsmRewrites.emplace_back(AOK_Imm, BracLoc, 0, FinalImmDisp);
1148 // Remove all the ImmPrefix rewrites within the brackets.
1149 for (AsmRewrite &AR : AsmRewrites) {
1150 if (AR.Loc.getPointer() < StartInBrac.getPointer())
1152 if (AR.Kind == AOK_ImmPrefix)
1153 AR.Kind = AOK_Delete;
1155 const char *SymLocPtr = SymName.data();
1156 // Skip everything before the symbol.
1157 if (unsigned Len = SymLocPtr - StartInBrac.getPointer()) {
1158 assert(Len > 0 && "Expected a non-negative length.");
1159 AsmRewrites.emplace_back(AOK_Skip, StartInBrac, Len);
1161 // Skip everything after the symbol.
1162 if (unsigned Len = End.getPointer() - (SymLocPtr + SymName.size())) {
1163 SMLoc Loc = SMLoc::getFromPointer(SymLocPtr + SymName.size());
1164 assert(Len > 0 && "Expected a non-negative length.");
1165 AsmRewrites.emplace_back(AOK_Skip, Loc, Len);
1169 bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
1170 MCAsmParser &Parser = getParser();
1171 const AsmToken &Tok = Parser.getTok();
1175 bool UpdateLocLex = true;
1177 // The period in the dot operator (e.g., [ebx].foo.bar) is parsed as an
1178 // identifier. Don't try an parse it as a register.
1179 if (Tok.getString().startswith("."))
1182 // If we're parsing an immediate expression, we don't expect a '['.
1183 if (SM.getStopOnLBrac() && getLexer().getKind() == AsmToken::LBrac)
1186 AsmToken::TokenKind TK = getLexer().getKind();
1189 if (SM.isValidEndState()) {
1193 return Error(Tok.getLoc(), "unknown token in expression");
1195 case AsmToken::EndOfStatement: {
1199 case AsmToken::String:
1200 case AsmToken::Identifier: {
1201 // This could be a register or a symbolic displacement.
1204 SMLoc IdentLoc = Tok.getLoc();
1205 StringRef Identifier = Tok.getString();
1206 if (TK != AsmToken::String && !ParseRegister(TmpReg, IdentLoc, End)) {
1207 SM.onRegister(TmpReg);
1208 UpdateLocLex = false;
1211 if (!isParsingInlineAsm()) {
1212 if (getParser().parsePrimaryExpr(Val, End))
1213 return Error(Tok.getLoc(), "Unexpected identifier!");
1215 // This is a dot operator, not an adjacent identifier.
1216 if (Identifier.find('.') != StringRef::npos) {
1219 InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
1220 if (ParseIntelIdentifier(Val, Identifier, Info,
1221 /*Unevaluated=*/false, End))
1225 SM.onIdentifierExpr(Val, Identifier);
1226 UpdateLocLex = false;
1229 return Error(Tok.getLoc(), "Unexpected identifier!");
1231 case AsmToken::Integer: {
1233 if (isParsingInlineAsm() && SM.getAddImmPrefix())
1234 InstInfo->AsmRewrites->emplace_back(AOK_ImmPrefix, Tok.getLoc());
1235 // Look for 'b' or 'f' following an Integer as a directional label
1236 SMLoc Loc = getTok().getLoc();
1237 int64_t IntVal = getTok().getIntVal();
1238 End = consumeToken();
1239 UpdateLocLex = false;
1240 if (getLexer().getKind() == AsmToken::Identifier) {
1241 StringRef IDVal = getTok().getString();
1242 if (IDVal == "f" || IDVal == "b") {
1244 getContext().getDirectionalLocalSymbol(IntVal, IDVal == "b");
1245 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1247 MCSymbolRefExpr::create(Sym, Variant, getContext());
1248 if (IDVal == "b" && Sym->isUndefined())
1249 return Error(Loc, "invalid reference to undefined symbol");
1250 StringRef Identifier = Sym->getName();
1251 SM.onIdentifierExpr(Val, Identifier);
1252 End = consumeToken();
1254 if (SM.onInteger(IntVal, ErrMsg))
1255 return Error(Loc, ErrMsg);
1258 if (SM.onInteger(IntVal, ErrMsg))
1259 return Error(Loc, ErrMsg);
1263 case AsmToken::Plus: SM.onPlus(); break;
1264 case AsmToken::Minus: SM.onMinus(); break;
1265 case AsmToken::Tilde: SM.onNot(); break;
1266 case AsmToken::Star: SM.onStar(); break;
1267 case AsmToken::Slash: SM.onDivide(); break;
1268 case AsmToken::Pipe: SM.onOr(); break;
1269 case AsmToken::Caret: SM.onXor(); break;
1270 case AsmToken::Amp: SM.onAnd(); break;
1271 case AsmToken::LessLess:
1272 SM.onLShift(); break;
1273 case AsmToken::GreaterGreater:
1274 SM.onRShift(); break;
1275 case AsmToken::LBrac: SM.onLBrac(); break;
1276 case AsmToken::RBrac: SM.onRBrac(); break;
1277 case AsmToken::LParen: SM.onLParen(); break;
1278 case AsmToken::RParen: SM.onRParen(); break;
1281 return Error(Tok.getLoc(), "unknown token in expression");
1283 if (!Done && UpdateLocLex)
1284 End = consumeToken();
1289 std::unique_ptr<X86Operand>
1290 X86AsmParser::ParseIntelBracExpression(unsigned SegReg, SMLoc Start,
1291 int64_t ImmDisp, unsigned Size) {
1292 MCAsmParser &Parser = getParser();
1293 const AsmToken &Tok = Parser.getTok();
1294 SMLoc BracLoc = Tok.getLoc(), End = Tok.getEndLoc();
1295 if (getLexer().isNot(AsmToken::LBrac))
1296 return ErrorOperand(BracLoc, "Expected '[' token!");
1297 Parser.Lex(); // Eat '['
1299 SMLoc StartInBrac = Tok.getLoc();
1300 // Parse [ Symbol + ImmDisp ] and [ BaseReg + Scale*IndexReg + ImmDisp ]. We
1301 // may have already parsed an immediate displacement before the bracketed
1303 IntelExprStateMachine SM(ImmDisp, /*StopOnLBrac=*/false, /*AddImmPrefix=*/true);
1304 if (ParseIntelExpression(SM, End))
1307 const MCExpr *Disp = nullptr;
1308 if (const MCExpr *Sym = SM.getSym()) {
1309 // A symbolic displacement.
1311 if (isParsingInlineAsm())
1312 RewriteIntelBracExpression(*InstInfo->AsmRewrites, SM.getSymName(),
1313 ImmDisp, SM.getImm(), BracLoc, StartInBrac,
1317 if (SM.getImm() || !Disp) {
1318 const MCExpr *Imm = MCConstantExpr::create(SM.getImm(), getContext());
1320 Disp = MCBinaryExpr::createAdd(Disp, Imm, getContext());
1322 Disp = Imm; // An immediate displacement only.
1325 // Parse struct field access. Intel requires a dot, but MSVC doesn't. MSVC
1326 // will in fact do global lookup the field name inside all global typedefs,
1327 // but we don't emulate that.
1328 if (Tok.getString().find('.') != StringRef::npos) {
1329 const MCExpr *NewDisp;
1330 if (ParseIntelDotOperator(Disp, NewDisp))
1333 End = Tok.getEndLoc();
1334 Parser.Lex(); // Eat the field.
1338 int BaseReg = SM.getBaseReg();
1339 int IndexReg = SM.getIndexReg();
1340 int Scale = SM.getScale();
1341 if (!isParsingInlineAsm()) {
1343 if (!BaseReg && !IndexReg) {
1345 return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size);
1346 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
1350 if (CheckBaseRegAndIndexReg(BaseReg, IndexReg, ErrMsg)) {
1351 Error(StartInBrac, ErrMsg);
1354 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
1355 IndexReg, Scale, Start, End, Size);
1358 InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
1359 return CreateMemForInlineAsm(SegReg, Disp, BaseReg, IndexReg, Scale, Start,
1360 End, Size, SM.getSymName(), Info);
1363 // Inline assembly may use variable names with namespace alias qualifiers.
1364 bool X86AsmParser::ParseIntelIdentifier(const MCExpr *&Val,
1365 StringRef &Identifier,
1366 InlineAsmIdentifierInfo &Info,
1367 bool IsUnevaluatedOperand, SMLoc &End) {
1368 MCAsmParser &Parser = getParser();
1369 assert(isParsingInlineAsm() && "Expected to be parsing inline assembly.");
1372 StringRef LineBuf(Identifier.data());
1374 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);
1376 const AsmToken &Tok = Parser.getTok();
1377 SMLoc Loc = Tok.getLoc();
1379 // Advance the token stream until the end of the current token is
1380 // after the end of what the frontend claimed.
1381 const char *EndPtr = Tok.getLoc().getPointer() + LineBuf.size();
1383 End = Tok.getEndLoc();
1385 } while (End.getPointer() < EndPtr);
1386 Identifier = LineBuf;
1388 // The frontend should end parsing on an assembler token boundary, unless it
1390 assert((End.getPointer() == EndPtr || !Result) &&
1391 "frontend claimed part of a token?");
1393 // If the identifier lookup was unsuccessful, assume that we are dealing with
1396 StringRef InternalName =
1397 SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(),
1399 assert(InternalName.size() && "We should have an internal name here.");
1400 // Push a rewrite for replacing the identifier name with the internal name.
1401 InstInfo->AsmRewrites->emplace_back(AOK_Label, Loc, Identifier.size(),
1405 // Create the symbol reference.
1406 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
1407 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1408 Val = MCSymbolRefExpr::create(Sym, Variant, getParser().getContext());
1412 /// \brief Parse intel style segment override.
1413 std::unique_ptr<X86Operand>
1414 X86AsmParser::ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start,
1416 MCAsmParser &Parser = getParser();
1417 assert(SegReg != 0 && "Tried to parse a segment override without a segment!");
1418 const AsmToken &Tok = Parser.getTok(); // Eat colon.
1419 if (Tok.isNot(AsmToken::Colon))
1420 return ErrorOperand(Tok.getLoc(), "Expected ':' token!");
1421 Parser.Lex(); // Eat ':'
1423 int64_t ImmDisp = 0;
1424 if (getLexer().is(AsmToken::Integer)) {
1425 ImmDisp = Tok.getIntVal();
1426 AsmToken ImmDispToken = Parser.Lex(); // Eat the integer.
1428 if (isParsingInlineAsm())
1429 InstInfo->AsmRewrites->emplace_back(AOK_ImmPrefix, ImmDispToken.getLoc());
1431 if (getLexer().isNot(AsmToken::LBrac)) {
1432 // An immediate following a 'segment register', 'colon' token sequence can
1433 // be followed by a bracketed expression. If it isn't we know we have our
1434 // final segment override.
1435 const MCExpr *Disp = MCConstantExpr::create(ImmDisp, getContext());
1436 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp,
1437 /*BaseReg=*/0, /*IndexReg=*/0, /*Scale=*/1,
1438 Start, ImmDispToken.getEndLoc(), Size);
1442 if (getLexer().is(AsmToken::LBrac))
1443 return ParseIntelBracExpression(SegReg, Start, ImmDisp, Size);
1447 if (!isParsingInlineAsm()) {
1448 if (getParser().parsePrimaryExpr(Val, End))
1449 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1451 return X86Operand::CreateMem(getPointerWidth(), Val, Start, End, Size);
1454 InlineAsmIdentifierInfo Info;
1455 StringRef Identifier = Tok.getString();
1456 if (ParseIntelIdentifier(Val, Identifier, Info,
1457 /*Unevaluated=*/false, End))
1459 return CreateMemForInlineAsm(/*SegReg=*/0, Val, /*BaseReg=*/0,/*IndexReg=*/0,
1460 /*Scale=*/1, Start, End, Size, Identifier, Info);
1463 //ParseRoundingModeOp - Parse AVX-512 rounding mode operand
1464 std::unique_ptr<X86Operand>
1465 X86AsmParser::ParseRoundingModeOp(SMLoc Start, SMLoc End) {
1466 MCAsmParser &Parser = getParser();
1467 const AsmToken &Tok = Parser.getTok();
1468 // Eat "{" and mark the current place.
1469 const SMLoc consumedToken = consumeToken();
1470 if (Tok.getIdentifier().startswith("r")){
1471 int rndMode = StringSwitch<int>(Tok.getIdentifier())
1472 .Case("rn", X86::STATIC_ROUNDING::TO_NEAREST_INT)
1473 .Case("rd", X86::STATIC_ROUNDING::TO_NEG_INF)
1474 .Case("ru", X86::STATIC_ROUNDING::TO_POS_INF)
1475 .Case("rz", X86::STATIC_ROUNDING::TO_ZERO)
1478 return ErrorOperand(Tok.getLoc(), "Invalid rounding mode.");
1479 Parser.Lex(); // Eat "r*" of r*-sae
1480 if (!getLexer().is(AsmToken::Minus))
1481 return ErrorOperand(Tok.getLoc(), "Expected - at this point");
1482 Parser.Lex(); // Eat "-"
1483 Parser.Lex(); // Eat the sae
1484 if (!getLexer().is(AsmToken::RCurly))
1485 return ErrorOperand(Tok.getLoc(), "Expected } at this point");
1486 Parser.Lex(); // Eat "}"
1487 const MCExpr *RndModeOp =
1488 MCConstantExpr::create(rndMode, Parser.getContext());
1489 return X86Operand::CreateImm(RndModeOp, Start, End);
1491 if(Tok.getIdentifier().equals("sae")){
1492 Parser.Lex(); // Eat the sae
1493 if (!getLexer().is(AsmToken::RCurly))
1494 return ErrorOperand(Tok.getLoc(), "Expected } at this point");
1495 Parser.Lex(); // Eat "}"
1496 return X86Operand::CreateToken("{sae}", consumedToken);
1498 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1500 /// ParseIntelMemOperand - Parse intel style memory operand.
1501 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelMemOperand(int64_t ImmDisp,
1504 MCAsmParser &Parser = getParser();
1505 const AsmToken &Tok = Parser.getTok();
1508 // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
1509 if (getLexer().is(AsmToken::LBrac))
1510 return ParseIntelBracExpression(/*SegReg=*/0, Start, ImmDisp, Size);
1511 assert(ImmDisp == 0);
1514 if (!isParsingInlineAsm()) {
1515 if (getParser().parsePrimaryExpr(Val, End))
1516 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1518 return X86Operand::CreateMem(getPointerWidth(), Val, Start, End, Size);
1521 InlineAsmIdentifierInfo Info;
1522 StringRef Identifier = Tok.getString();
1523 if (ParseIntelIdentifier(Val, Identifier, Info,
1524 /*Unevaluated=*/false, End))
1527 if (!getLexer().is(AsmToken::LBrac))
1528 return CreateMemForInlineAsm(/*SegReg=*/0, Val, /*BaseReg=*/0, /*IndexReg=*/0,
1529 /*Scale=*/1, Start, End, Size, Identifier, Info);
1531 Parser.Lex(); // Eat '['
1533 // Parse Identifier [ ImmDisp ]
1534 IntelExprStateMachine SM(/*ImmDisp=*/0, /*StopOnLBrac=*/true,
1535 /*AddImmPrefix=*/false);
1536 if (ParseIntelExpression(SM, End))
1540 Error(Start, "cannot use more than one symbol in memory operand");
1543 if (SM.getBaseReg()) {
1544 Error(Start, "cannot use base register with variable reference");
1547 if (SM.getIndexReg()) {
1548 Error(Start, "cannot use index register with variable reference");
1552 const MCExpr *Disp = MCConstantExpr::create(SM.getImm(), getContext());
1553 // BaseReg is non-zero to avoid assertions. In the context of inline asm,
1554 // we're pointing to a local variable in memory, so the base register is
1555 // really the frame or stack pointer.
1556 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
1557 /*BaseReg=*/1, /*IndexReg=*/0, /*Scale=*/1,
1558 Start, End, Size, Identifier, Info.OpDecl);
1561 /// Parse the '.' operator.
1562 bool X86AsmParser::ParseIntelDotOperator(const MCExpr *Disp,
1563 const MCExpr *&NewDisp) {
1564 MCAsmParser &Parser = getParser();
1565 const AsmToken &Tok = Parser.getTok();
1566 int64_t OrigDispVal, DotDispVal;
1568 // FIXME: Handle non-constant expressions.
1569 if (const MCConstantExpr *OrigDisp = dyn_cast<MCConstantExpr>(Disp))
1570 OrigDispVal = OrigDisp->getValue();
1572 return Error(Tok.getLoc(), "Non-constant offsets are not supported!");
1574 // Drop the optional '.'.
1575 StringRef DotDispStr = Tok.getString();
1576 if (DotDispStr.startswith("."))
1577 DotDispStr = DotDispStr.drop_front(1);
1579 // .Imm gets lexed as a real.
1580 if (Tok.is(AsmToken::Real)) {
1582 DotDispStr.getAsInteger(10, DotDisp);
1583 DotDispVal = DotDisp.getZExtValue();
1584 } else if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) {
1586 std::pair<StringRef, StringRef> BaseMember = DotDispStr.split('.');
1587 if (SemaCallback->LookupInlineAsmField(BaseMember.first, BaseMember.second,
1589 return Error(Tok.getLoc(), "Unable to lookup field reference!");
1590 DotDispVal = DotDisp;
1592 return Error(Tok.getLoc(), "Unexpected token type!");
1594 if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) {
1595 SMLoc Loc = SMLoc::getFromPointer(DotDispStr.data());
1596 unsigned Len = DotDispStr.size();
1597 unsigned Val = OrigDispVal + DotDispVal;
1598 InstInfo->AsmRewrites->emplace_back(AOK_DotOperator, Loc, Len, Val);
1601 NewDisp = MCConstantExpr::create(OrigDispVal + DotDispVal, getContext());
1605 /// Parse the 'offset' operator. This operator is used to specify the
1606 /// location rather then the content of a variable.
1607 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOffsetOfOperator() {
1608 MCAsmParser &Parser = getParser();
1609 const AsmToken &Tok = Parser.getTok();
1610 SMLoc OffsetOfLoc = Tok.getLoc();
1611 Parser.Lex(); // Eat offset.
1614 InlineAsmIdentifierInfo Info;
1615 SMLoc Start = Tok.getLoc(), End;
1616 StringRef Identifier = Tok.getString();
1617 if (ParseIntelIdentifier(Val, Identifier, Info,
1618 /*Unevaluated=*/false, End))
1621 // Don't emit the offset operator.
1622 InstInfo->AsmRewrites->emplace_back(AOK_Skip, OffsetOfLoc, 7);
1624 // The offset operator will have an 'r' constraint, thus we need to create
1625 // register operand to ensure proper matching. Just pick a GPR based on
1626 // the size of a pointer.
1628 is64BitMode() ? X86::RBX : (is32BitMode() ? X86::EBX : X86::BX);
1629 return X86Operand::CreateReg(RegNo, Start, End, /*GetAddress=*/true,
1630 OffsetOfLoc, Identifier, Info.OpDecl);
1633 enum IntelOperatorKind {
1639 /// Parse the 'LENGTH', 'TYPE' and 'SIZE' operators. The LENGTH operator
1640 /// returns the number of elements in an array. It returns the value 1 for
1641 /// non-array variables. The SIZE operator returns the size of a C or C++
1642 /// variable. A variable's size is the product of its LENGTH and TYPE. The
1643 /// TYPE operator returns the size of a C or C++ type or variable. If the
1644 /// variable is an array, TYPE returns the size of a single element.
1645 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperator(unsigned OpKind) {
1646 MCAsmParser &Parser = getParser();
1647 const AsmToken &Tok = Parser.getTok();
1648 SMLoc TypeLoc = Tok.getLoc();
1649 Parser.Lex(); // Eat operator.
1651 const MCExpr *Val = nullptr;
1652 InlineAsmIdentifierInfo Info;
1653 SMLoc Start = Tok.getLoc(), End;
1654 StringRef Identifier = Tok.getString();
1655 if (ParseIntelIdentifier(Val, Identifier, Info,
1656 /*Unevaluated=*/true, End))
1660 return ErrorOperand(Start, "unable to lookup expression");
1664 default: llvm_unreachable("Unexpected operand kind!");
1665 case IOK_LENGTH: CVal = Info.Length; break;
1666 case IOK_SIZE: CVal = Info.Size; break;
1667 case IOK_TYPE: CVal = Info.Type; break;
1670 // Rewrite the type operator and the C or C++ type or variable in terms of an
1671 // immediate. E.g. TYPE foo -> $$4
1672 unsigned Len = End.getPointer() - TypeLoc.getPointer();
1673 InstInfo->AsmRewrites->emplace_back(AOK_Imm, TypeLoc, Len, CVal);
1675 const MCExpr *Imm = MCConstantExpr::create(CVal, getContext());
1676 return X86Operand::CreateImm(Imm, Start, End);
1679 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand() {
1680 MCAsmParser &Parser = getParser();
1681 const AsmToken &Tok = Parser.getTok();
1684 // Offset, length, type and size operators.
1685 if (isParsingInlineAsm()) {
1686 StringRef AsmTokStr = Tok.getString();
1687 if (AsmTokStr == "offset" || AsmTokStr == "OFFSET")
1688 return ParseIntelOffsetOfOperator();
1689 if (AsmTokStr == "length" || AsmTokStr == "LENGTH")
1690 return ParseIntelOperator(IOK_LENGTH);
1691 if (AsmTokStr == "size" || AsmTokStr == "SIZE")
1692 return ParseIntelOperator(IOK_SIZE);
1693 if (AsmTokStr == "type" || AsmTokStr == "TYPE")
1694 return ParseIntelOperator(IOK_TYPE);
1697 bool PtrInOperand = false;
1698 unsigned Size = getIntelMemOperandSize(Tok.getString());
1700 Parser.Lex(); // Eat operand size (e.g., byte, word).
1701 if (Tok.getString() != "PTR" && Tok.getString() != "ptr")
1702 return ErrorOperand(Tok.getLoc(), "Expected 'PTR' or 'ptr' token!");
1703 Parser.Lex(); // Eat ptr.
1704 PtrInOperand = true;
1706 Start = Tok.getLoc();
1709 if (getLexer().is(AsmToken::Integer) || getLexer().is(AsmToken::Minus) ||
1710 getLexer().is(AsmToken::Tilde) || getLexer().is(AsmToken::LParen)) {
1711 AsmToken StartTok = Tok;
1712 IntelExprStateMachine SM(/*Imm=*/0, /*StopOnLBrac=*/true,
1713 /*AddImmPrefix=*/false);
1714 if (ParseIntelExpression(SM, End))
1717 int64_t Imm = SM.getImm();
1718 if (isParsingInlineAsm()) {
1719 unsigned Len = Tok.getLoc().getPointer() - Start.getPointer();
1720 if (StartTok.getString().size() == Len)
1721 // Just add a prefix if this wasn't a complex immediate expression.
1722 InstInfo->AsmRewrites->emplace_back(AOK_ImmPrefix, Start);
1724 // Otherwise, rewrite the complex expression as a single immediate.
1725 InstInfo->AsmRewrites->emplace_back(AOK_Imm, Start, Len, Imm);
1728 if (getLexer().isNot(AsmToken::LBrac)) {
1729 // If a directional label (ie. 1f or 2b) was parsed above from
1730 // ParseIntelExpression() then SM.getSym() was set to a pointer to
1731 // to the MCExpr with the directional local symbol and this is a
1732 // memory operand not an immediate operand.
1734 return X86Operand::CreateMem(getPointerWidth(), SM.getSym(), Start, End,
1737 const MCExpr *ImmExpr = MCConstantExpr::create(Imm, getContext());
1738 return X86Operand::CreateImm(ImmExpr, Start, End);
1741 // Only positive immediates are valid.
1743 return ErrorOperand(Start, "expected a positive immediate displacement "
1744 "before bracketed expr.");
1746 // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
1747 return ParseIntelMemOperand(Imm, Start, Size);
1750 // rounding mode token
1751 if (getSTI().getFeatureBits()[X86::FeatureAVX512] &&
1752 getLexer().is(AsmToken::LCurly))
1753 return ParseRoundingModeOp(Start, End);
1757 if (!ParseRegister(RegNo, Start, End)) {
1758 // If this is a segment register followed by a ':', then this is the start
1759 // of a segment override, otherwise this is a normal register reference.
1760 // In case it is a normal register and there is ptr in the operand this
1762 if (getLexer().isNot(AsmToken::Colon)){
1764 return ErrorOperand(Start, "expected memory operand after "
1765 "'ptr', found register operand instead");
1767 return X86Operand::CreateReg(RegNo, Start, End);
1770 return ParseIntelSegmentOverride(/*SegReg=*/RegNo, Start, Size);
1774 return ParseIntelMemOperand(/*Disp=*/0, Start, Size);
1777 std::unique_ptr<X86Operand> X86AsmParser::ParseATTOperand() {
1778 MCAsmParser &Parser = getParser();
1779 switch (getLexer().getKind()) {
1781 // Parse a memory operand with no segment register.
1782 return ParseMemOperand(0, Parser.getTok().getLoc());
1783 case AsmToken::Percent: {
1784 // Read the register.
1787 if (ParseRegister(RegNo, Start, End)) return nullptr;
1788 if (RegNo == X86::EIZ || RegNo == X86::RIZ) {
1789 Error(Start, "%eiz and %riz can only be used as index registers",
1790 SMRange(Start, End));
1794 // If this is a segment register followed by a ':', then this is the start
1795 // of a memory reference, otherwise this is a normal register reference.
1796 if (getLexer().isNot(AsmToken::Colon))
1797 return X86Operand::CreateReg(RegNo, Start, End);
1799 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo))
1800 return ErrorOperand(Start, "invalid segment register");
1802 getParser().Lex(); // Eat the colon.
1803 return ParseMemOperand(RegNo, Start);
1805 case AsmToken::Dollar: {
1806 // $42 -> immediate.
1807 SMLoc Start = Parser.getTok().getLoc(), End;
1810 if (getParser().parseExpression(Val, End))
1812 return X86Operand::CreateImm(Val, Start, End);
1814 case AsmToken::LCurly:{
1815 SMLoc Start = Parser.getTok().getLoc(), End;
1816 if (getSTI().getFeatureBits()[X86::FeatureAVX512])
1817 return ParseRoundingModeOp(Start, End);
1818 return ErrorOperand(Start, "unknown token in expression");
1823 bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands,
1824 const MCParsedAsmOperand &Op) {
1825 MCAsmParser &Parser = getParser();
1826 if(getSTI().getFeatureBits()[X86::FeatureAVX512]) {
1827 if (getLexer().is(AsmToken::LCurly)) {
1828 // Eat "{" and mark the current place.
1829 const SMLoc consumedToken = consumeToken();
1830 // Distinguish {1to<NUM>} from {%k<NUM>}.
1831 if(getLexer().is(AsmToken::Integer)) {
1832 // Parse memory broadcasting ({1to<NUM>}).
1833 if (getLexer().getTok().getIntVal() != 1)
1834 return !ErrorAndEatStatement(getLexer().getLoc(),
1835 "Expected 1to<NUM> at this point");
1836 Parser.Lex(); // Eat "1" of 1to8
1837 if (!getLexer().is(AsmToken::Identifier) ||
1838 !getLexer().getTok().getIdentifier().startswith("to"))
1839 return !ErrorAndEatStatement(getLexer().getLoc(),
1840 "Expected 1to<NUM> at this point");
1841 // Recognize only reasonable suffixes.
1842 const char *BroadcastPrimitive =
1843 StringSwitch<const char*>(getLexer().getTok().getIdentifier())
1844 .Case("to2", "{1to2}")
1845 .Case("to4", "{1to4}")
1846 .Case("to8", "{1to8}")
1847 .Case("to16", "{1to16}")
1849 if (!BroadcastPrimitive)
1850 return !ErrorAndEatStatement(getLexer().getLoc(),
1851 "Invalid memory broadcast primitive.");
1852 Parser.Lex(); // Eat "toN" of 1toN
1853 if (!getLexer().is(AsmToken::RCurly))
1854 return !ErrorAndEatStatement(getLexer().getLoc(),
1855 "Expected } at this point");
1856 Parser.Lex(); // Eat "}"
1857 Operands.push_back(X86Operand::CreateToken(BroadcastPrimitive,
1859 // No AVX512 specific primitives can pass
1860 // after memory broadcasting, so return.
1863 // Parse mask register {%k1}
1864 Operands.push_back(X86Operand::CreateToken("{", consumedToken));
1865 if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
1866 Operands.push_back(std::move(Op));
1867 if (!getLexer().is(AsmToken::RCurly))
1868 return !ErrorAndEatStatement(getLexer().getLoc(),
1869 "Expected } at this point");
1870 Operands.push_back(X86Operand::CreateToken("}", consumeToken()));
1872 // Parse "zeroing non-masked" semantic {z}
1873 if (getLexer().is(AsmToken::LCurly)) {
1874 Operands.push_back(X86Operand::CreateToken("{z}", consumeToken()));
1875 if (!getLexer().is(AsmToken::Identifier) ||
1876 getLexer().getTok().getIdentifier() != "z")
1877 return !ErrorAndEatStatement(getLexer().getLoc(),
1878 "Expected z at this point");
1879 Parser.Lex(); // Eat the z
1880 if (!getLexer().is(AsmToken::RCurly))
1881 return !ErrorAndEatStatement(getLexer().getLoc(),
1882 "Expected } at this point");
1883 Parser.Lex(); // Eat the }
1892 /// ParseMemOperand: segment: disp(basereg, indexreg, scale). The '%ds:' prefix
1893 /// has already been parsed if present.
1894 std::unique_ptr<X86Operand> X86AsmParser::ParseMemOperand(unsigned SegReg,
1897 MCAsmParser &Parser = getParser();
1898 // We have to disambiguate a parenthesized expression "(4+5)" from the start
1899 // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)". The
1900 // only way to do this without lookahead is to eat the '(' and see what is
1902 const MCExpr *Disp = MCConstantExpr::create(0, getParser().getContext());
1903 if (getLexer().isNot(AsmToken::LParen)) {
1905 if (getParser().parseExpression(Disp, ExprEnd)) return nullptr;
1907 // After parsing the base expression we could either have a parenthesized
1908 // memory address or not. If not, return now. If so, eat the (.
1909 if (getLexer().isNot(AsmToken::LParen)) {
1910 // Unless we have a segment register, treat this as an immediate.
1912 return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, ExprEnd);
1913 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
1920 // Okay, we have a '('. We don't know if this is an expression or not, but
1921 // so we have to eat the ( to see beyond it.
1922 SMLoc LParenLoc = Parser.getTok().getLoc();
1923 Parser.Lex(); // Eat the '('.
1925 if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) {
1926 // Nothing to do here, fall into the code below with the '(' part of the
1927 // memory operand consumed.
1931 // It must be an parenthesized expression, parse it now.
1932 if (getParser().parseParenExpression(Disp, ExprEnd))
1935 // After parsing the base expression we could either have a parenthesized
1936 // memory address or not. If not, return now. If so, eat the (.
1937 if (getLexer().isNot(AsmToken::LParen)) {
1938 // Unless we have a segment register, treat this as an immediate.
1940 return X86Operand::CreateMem(getPointerWidth(), Disp, LParenLoc,
1942 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
1951 // If we reached here, then we just ate the ( of the memory operand. Process
1952 // the rest of the memory operand.
1953 unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
1954 SMLoc IndexLoc, BaseLoc;
1956 if (getLexer().is(AsmToken::Percent)) {
1957 SMLoc StartLoc, EndLoc;
1958 BaseLoc = Parser.getTok().getLoc();
1959 if (ParseRegister(BaseReg, StartLoc, EndLoc)) return nullptr;
1960 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) {
1961 Error(StartLoc, "eiz and riz can only be used as index registers",
1962 SMRange(StartLoc, EndLoc));
1967 if (getLexer().is(AsmToken::Comma)) {
1968 Parser.Lex(); // Eat the comma.
1969 IndexLoc = Parser.getTok().getLoc();
1971 // Following the comma we should have either an index register, or a scale
1972 // value. We don't support the later form, but we want to parse it
1975 // Not that even though it would be completely consistent to support syntax
1976 // like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this.
1977 if (getLexer().is(AsmToken::Percent)) {
1979 if (ParseRegister(IndexReg, L, L)) return nullptr;
1981 if (getLexer().isNot(AsmToken::RParen)) {
1982 // Parse the scale amount:
1983 // ::= ',' [scale-expression]
1984 if (getLexer().isNot(AsmToken::Comma)) {
1985 Error(Parser.getTok().getLoc(),
1986 "expected comma in scale expression");
1989 Parser.Lex(); // Eat the comma.
1991 if (getLexer().isNot(AsmToken::RParen)) {
1992 SMLoc Loc = Parser.getTok().getLoc();
1995 if (getParser().parseAbsoluteExpression(ScaleVal)){
1996 Error(Loc, "expected scale expression");
2000 // Validate the scale amount.
2001 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
2003 Error(Loc, "scale factor in 16-bit address must be 1");
2006 if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 &&
2008 Error(Loc, "scale factor in address must be 1, 2, 4 or 8");
2011 Scale = (unsigned)ScaleVal;
2014 } else if (getLexer().isNot(AsmToken::RParen)) {
2015 // A scale amount without an index is ignored.
2017 SMLoc Loc = Parser.getTok().getLoc();
2020 if (getParser().parseAbsoluteExpression(Value))
2024 Warning(Loc, "scale factor without index register is ignored");
2029 // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
2030 if (getLexer().isNot(AsmToken::RParen)) {
2031 Error(Parser.getTok().getLoc(), "unexpected token in memory operand");
2034 SMLoc MemEnd = Parser.getTok().getEndLoc();
2035 Parser.Lex(); // Eat the ')'.
2037 // Check for use of invalid 16-bit registers. Only BX/BP/SI/DI are allowed,
2038 // and then only in non-64-bit modes. Except for DX, which is a special case
2039 // because an unofficial form of in/out instructions uses it.
2040 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
2041 (is64BitMode() || (BaseReg != X86::BX && BaseReg != X86::BP &&
2042 BaseReg != X86::SI && BaseReg != X86::DI)) &&
2043 BaseReg != X86::DX) {
2044 Error(BaseLoc, "invalid 16-bit base register");
2048 X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg)) {
2049 Error(IndexLoc, "16-bit memory operand may not include only index register");
2054 if (CheckBaseRegAndIndexReg(BaseReg, IndexReg, ErrMsg)) {
2055 Error(BaseLoc, ErrMsg);
2059 if (SegReg || BaseReg || IndexReg)
2060 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
2061 IndexReg, Scale, MemStart, MemEnd);
2062 return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, MemEnd);
2065 bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2066 SMLoc NameLoc, OperandVector &Operands) {
2067 MCAsmParser &Parser = getParser();
2069 StringRef PatchedName = Name;
2071 // FIXME: Hack to recognize setneb as setne.
2072 if (PatchedName.startswith("set") && PatchedName.endswith("b") &&
2073 PatchedName != "setb" && PatchedName != "setnb")
2074 PatchedName = PatchedName.substr(0, Name.size()-1);
2076 // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}.
2077 if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) &&
2078 (PatchedName.endswith("ss") || PatchedName.endswith("sd") ||
2079 PatchedName.endswith("ps") || PatchedName.endswith("pd"))) {
2080 bool IsVCMP = PatchedName[0] == 'v';
2081 unsigned CCIdx = IsVCMP ? 4 : 3;
2082 unsigned ComparisonCode = StringSwitch<unsigned>(
2083 PatchedName.slice(CCIdx, PatchedName.size() - 2))
2087 .Case("unord", 0x03)
2092 /* AVX only from here */
2093 .Case("eq_uq", 0x08)
2096 .Case("false", 0x0B)
2097 .Case("neq_oq", 0x0C)
2101 .Case("eq_os", 0x10)
2102 .Case("lt_oq", 0x11)
2103 .Case("le_oq", 0x12)
2104 .Case("unord_s", 0x13)
2105 .Case("neq_us", 0x14)
2106 .Case("nlt_uq", 0x15)
2107 .Case("nle_uq", 0x16)
2108 .Case("ord_s", 0x17)
2109 .Case("eq_us", 0x18)
2110 .Case("nge_uq", 0x19)
2111 .Case("ngt_uq", 0x1A)
2112 .Case("false_os", 0x1B)
2113 .Case("neq_os", 0x1C)
2114 .Case("ge_oq", 0x1D)
2115 .Case("gt_oq", 0x1E)
2116 .Case("true_us", 0x1F)
2118 if (ComparisonCode != ~0U && (IsVCMP || ComparisonCode < 8)) {
2120 Operands.push_back(X86Operand::CreateToken(PatchedName.slice(0, CCIdx),
2123 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2124 getParser().getContext());
2125 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2127 PatchedName = PatchedName.substr(PatchedName.size() - 2);
2131 // FIXME: Hack to recognize vpcmp<comparison code>{ub,uw,ud,uq,b,w,d,q}.
2132 if (PatchedName.startswith("vpcmp") &&
2133 (PatchedName.endswith("b") || PatchedName.endswith("w") ||
2134 PatchedName.endswith("d") || PatchedName.endswith("q"))) {
2135 unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1;
2136 unsigned ComparisonCode = StringSwitch<unsigned>(
2137 PatchedName.slice(5, PatchedName.size() - CCIdx))
2138 .Case("eq", 0x0) // Only allowed on unsigned. Checked below.
2141 //.Case("false", 0x3) // Not a documented alias.
2145 //.Case("true", 0x7) // Not a documented alias.
2147 if (ComparisonCode != ~0U && (ComparisonCode != 0 || CCIdx == 2)) {
2148 Operands.push_back(X86Operand::CreateToken("vpcmp", NameLoc));
2150 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2151 getParser().getContext());
2152 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2154 PatchedName = PatchedName.substr(PatchedName.size() - CCIdx);
2158 // FIXME: Hack to recognize vpcom<comparison code>{ub,uw,ud,uq,b,w,d,q}.
2159 if (PatchedName.startswith("vpcom") &&
2160 (PatchedName.endswith("b") || PatchedName.endswith("w") ||
2161 PatchedName.endswith("d") || PatchedName.endswith("q"))) {
2162 unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1;
2163 unsigned ComparisonCode = StringSwitch<unsigned>(
2164 PatchedName.slice(5, PatchedName.size() - CCIdx))
2174 if (ComparisonCode != ~0U) {
2175 Operands.push_back(X86Operand::CreateToken("vpcom", NameLoc));
2177 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2178 getParser().getContext());
2179 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2181 PatchedName = PatchedName.substr(PatchedName.size() - CCIdx);
2185 Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
2187 // Determine whether this is an instruction prefix.
2189 Name == "lock" || Name == "rep" ||
2190 Name == "repe" || Name == "repz" ||
2191 Name == "repne" || Name == "repnz" ||
2192 Name == "rex64" || Name == "data16";
2194 // This does the actual operand parsing. Don't parse any more if we have a
2195 // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we
2196 // just want to parse the "lock" as the first instruction and the "incl" as
2198 if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) {
2200 // Parse '*' modifier.
2201 if (getLexer().is(AsmToken::Star))
2202 Operands.push_back(X86Operand::CreateToken("*", consumeToken()));
2204 // Read the operands.
2206 if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
2207 Operands.push_back(std::move(Op));
2208 if (!HandleAVX512Operand(Operands, *Operands.back()))
2211 Parser.eatToEndOfStatement();
2214 // check for comma and eat it
2215 if (getLexer().is(AsmToken::Comma))
2221 if (getLexer().isNot(AsmToken::EndOfStatement))
2222 return ErrorAndEatStatement(getLexer().getLoc(),
2223 "unexpected token in argument list");
2226 // Consume the EndOfStatement or the prefix separator Slash
2227 if (getLexer().is(AsmToken::EndOfStatement) ||
2228 (isPrefix && getLexer().is(AsmToken::Slash)))
2231 // This is for gas compatibility and cannot be done in td.
2232 // Adding "p" for some floating point with no argument.
2233 // For example: fsub --> fsubp
2235 Name == "fsub" || Name == "fdiv" || Name == "fsubr" || Name == "fdivr";
2236 if (IsFp && Operands.size() == 1) {
2237 const char *Repl = StringSwitch<const char *>(Name)
2238 .Case("fsub", "fsubp")
2239 .Case("fdiv", "fdivp")
2240 .Case("fsubr", "fsubrp")
2241 .Case("fdivr", "fdivrp");
2242 static_cast<X86Operand &>(*Operands[0]).setTokenValue(Repl);
2245 // This is a terrible hack to handle "out[bwl]? %al, (%dx)" ->
2246 // "outb %al, %dx". Out doesn't take a memory form, but this is a widely
2247 // documented form in various unofficial manuals, so a lot of code uses it.
2248 if ((Name == "outb" || Name == "outw" || Name == "outl" || Name == "out") &&
2249 Operands.size() == 3) {
2250 X86Operand &Op = (X86Operand &)*Operands.back();
2251 if (Op.isMem() && Op.Mem.SegReg == 0 &&
2252 isa<MCConstantExpr>(Op.Mem.Disp) &&
2253 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
2254 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
2255 SMLoc Loc = Op.getEndLoc();
2256 Operands.back() = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
2259 // Same hack for "in[bwl]? (%dx), %al" -> "inb %dx, %al".
2260 if ((Name == "inb" || Name == "inw" || Name == "inl" || Name == "in") &&
2261 Operands.size() == 3) {
2262 X86Operand &Op = (X86Operand &)*Operands[1];
2263 if (Op.isMem() && Op.Mem.SegReg == 0 &&
2264 isa<MCConstantExpr>(Op.Mem.Disp) &&
2265 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
2266 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
2267 SMLoc Loc = Op.getEndLoc();
2268 Operands[1] = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
2272 // Append default arguments to "ins[bwld]"
2273 if (Name.startswith("ins") && Operands.size() == 1 &&
2274 (Name == "insb" || Name == "insw" || Name == "insl" || Name == "insd")) {
2275 AddDefaultSrcDestOperands(Operands,
2276 X86Operand::CreateReg(X86::DX, NameLoc, NameLoc),
2277 DefaultMemDIOperand(NameLoc));
2280 // Append default arguments to "outs[bwld]"
2281 if (Name.startswith("outs") && Operands.size() == 1 &&
2282 (Name == "outsb" || Name == "outsw" || Name == "outsl" ||
2283 Name == "outsd" )) {
2284 AddDefaultSrcDestOperands(Operands,
2285 DefaultMemSIOperand(NameLoc),
2286 X86Operand::CreateReg(X86::DX, NameLoc, NameLoc));
2289 // Transform "lods[bwlq]" into "lods[bwlq] ($SIREG)" for appropriate
2290 // values of $SIREG according to the mode. It would be nice if this
2291 // could be achieved with InstAlias in the tables.
2292 if (Name.startswith("lods") && Operands.size() == 1 &&
2293 (Name == "lods" || Name == "lodsb" || Name == "lodsw" ||
2294 Name == "lodsl" || Name == "lodsd" || Name == "lodsq"))
2295 Operands.push_back(DefaultMemSIOperand(NameLoc));
2297 // Transform "stos[bwlq]" into "stos[bwlq] ($DIREG)" for appropriate
2298 // values of $DIREG according to the mode. It would be nice if this
2299 // could be achieved with InstAlias in the tables.
2300 if (Name.startswith("stos") && Operands.size() == 1 &&
2301 (Name == "stos" || Name == "stosb" || Name == "stosw" ||
2302 Name == "stosl" || Name == "stosd" || Name == "stosq"))
2303 Operands.push_back(DefaultMemDIOperand(NameLoc));
2305 // Transform "scas[bwlq]" into "scas[bwlq] ($DIREG)" for appropriate
2306 // values of $DIREG according to the mode. It would be nice if this
2307 // could be achieved with InstAlias in the tables.
2308 if (Name.startswith("scas") && Operands.size() == 1 &&
2309 (Name == "scas" || Name == "scasb" || Name == "scasw" ||
2310 Name == "scasl" || Name == "scasd" || Name == "scasq"))
2311 Operands.push_back(DefaultMemDIOperand(NameLoc));
2313 // Add default SI and DI operands to "cmps[bwlq]".
2314 if (Name.startswith("cmps") &&
2315 (Name == "cmps" || Name == "cmpsb" || Name == "cmpsw" ||
2316 Name == "cmpsl" || Name == "cmpsd" || Name == "cmpsq")) {
2317 if (Operands.size() == 1) {
2318 AddDefaultSrcDestOperands(Operands,
2319 DefaultMemDIOperand(NameLoc),
2320 DefaultMemSIOperand(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 // Add default SI and DI operands to "movs[bwlq]".
2331 if ((Name.startswith("movs") &&
2332 (Name == "movs" || Name == "movsb" || Name == "movsw" ||
2333 Name == "movsl" || Name == "movsd" || Name == "movsq")) ||
2334 (Name.startswith("smov") &&
2335 (Name == "smov" || Name == "smovb" || Name == "smovw" ||
2336 Name == "smovl" || Name == "smovd" || Name == "smovq"))) {
2337 if (Operands.size() == 1) {
2338 if (Name == "movsd")
2339 Operands.back() = X86Operand::CreateToken("movsl", NameLoc);
2340 AddDefaultSrcDestOperands(Operands,
2341 DefaultMemSIOperand(NameLoc),
2342 DefaultMemDIOperand(NameLoc));
2343 } else if (Operands.size() == 3) {
2344 X86Operand &Op = (X86Operand &)*Operands[1];
2345 X86Operand &Op2 = (X86Operand &)*Operands[2];
2346 if (!doSrcDstMatch(Op, Op2))
2347 return Error(Op.getStartLoc(),
2348 "mismatching source and destination index registers");
2352 // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>. Canonicalize to
2354 if ((Name.startswith("shr") || Name.startswith("sar") ||
2355 Name.startswith("shl") || Name.startswith("sal") ||
2356 Name.startswith("rcl") || Name.startswith("rcr") ||
2357 Name.startswith("rol") || Name.startswith("ror")) &&
2358 Operands.size() == 3) {
2359 if (isParsingIntelSyntax()) {
2361 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[2]);
2362 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2363 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2364 Operands.pop_back();
2366 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2367 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2368 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2369 Operands.erase(Operands.begin() + 1);
2373 // Transforms "int $3" into "int3" as a size optimization. We can't write an
2374 // instalias with an immediate operand yet.
2375 if (Name == "int" && Operands.size() == 2) {
2376 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2378 if (auto *CE = dyn_cast<MCConstantExpr>(Op1.getImm()))
2379 if (CE->getValue() == 3) {
2380 Operands.erase(Operands.begin() + 1);
2381 static_cast<X86Operand &>(*Operands[0]).setTokenValue("int3");
2388 bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) {
2389 switch (Inst.getOpcode()) {
2390 default: return false;
2391 case X86::VMOVZPQILo2PQIrr:
2392 case X86::VMOVAPDrr:
2393 case X86::VMOVAPDYrr:
2394 case X86::VMOVAPSrr:
2395 case X86::VMOVAPSYrr:
2396 case X86::VMOVDQArr:
2397 case X86::VMOVDQAYrr:
2398 case X86::VMOVDQUrr:
2399 case X86::VMOVDQUYrr:
2400 case X86::VMOVUPDrr:
2401 case X86::VMOVUPDYrr:
2402 case X86::VMOVUPSrr:
2403 case X86::VMOVUPSYrr: {
2404 if (X86II::isX86_64ExtendedReg(Inst.getOperand(0).getReg()) ||
2405 !X86II::isX86_64ExtendedReg(Inst.getOperand(1).getReg()))
2409 switch (Inst.getOpcode()) {
2410 default: llvm_unreachable("Invalid opcode");
2411 case X86::VMOVZPQILo2PQIrr: NewOpc = X86::VMOVPQI2QIrr; break;
2412 case X86::VMOVAPDrr: NewOpc = X86::VMOVAPDrr_REV; break;
2413 case X86::VMOVAPDYrr: NewOpc = X86::VMOVAPDYrr_REV; break;
2414 case X86::VMOVAPSrr: NewOpc = X86::VMOVAPSrr_REV; break;
2415 case X86::VMOVAPSYrr: NewOpc = X86::VMOVAPSYrr_REV; break;
2416 case X86::VMOVDQArr: NewOpc = X86::VMOVDQArr_REV; break;
2417 case X86::VMOVDQAYrr: NewOpc = X86::VMOVDQAYrr_REV; break;
2418 case X86::VMOVDQUrr: NewOpc = X86::VMOVDQUrr_REV; break;
2419 case X86::VMOVDQUYrr: NewOpc = X86::VMOVDQUYrr_REV; break;
2420 case X86::VMOVUPDrr: NewOpc = X86::VMOVUPDrr_REV; break;
2421 case X86::VMOVUPDYrr: NewOpc = X86::VMOVUPDYrr_REV; break;
2422 case X86::VMOVUPSrr: NewOpc = X86::VMOVUPSrr_REV; break;
2423 case X86::VMOVUPSYrr: NewOpc = X86::VMOVUPSYrr_REV; break;
2425 Inst.setOpcode(NewOpc);
2429 case X86::VMOVSSrr: {
2430 if (X86II::isX86_64ExtendedReg(Inst.getOperand(0).getReg()) ||
2431 !X86II::isX86_64ExtendedReg(Inst.getOperand(2).getReg()))
2434 switch (Inst.getOpcode()) {
2435 default: llvm_unreachable("Invalid opcode");
2436 case X86::VMOVSDrr: NewOpc = X86::VMOVSDrr_REV; break;
2437 case X86::VMOVSSrr: NewOpc = X86::VMOVSSrr_REV; break;
2439 Inst.setOpcode(NewOpc);
2445 static const char *getSubtargetFeatureName(uint64_t Val);
2447 void X86AsmParser::EmitInstruction(MCInst &Inst, OperandVector &Operands,
2449 Instrumentation->InstrumentAndEmitInstruction(Inst, Operands, getContext(),
2453 bool X86AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2454 OperandVector &Operands,
2455 MCStreamer &Out, uint64_t &ErrorInfo,
2456 bool MatchingInlineAsm) {
2457 if (isParsingIntelSyntax())
2458 return MatchAndEmitIntelInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2460 return MatchAndEmitATTInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2464 void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op,
2465 OperandVector &Operands, MCStreamer &Out,
2466 bool MatchingInlineAsm) {
2467 // FIXME: This should be replaced with a real .td file alias mechanism.
2468 // Also, MatchInstructionImpl should actually *do* the EmitInstruction
2470 const char *Repl = StringSwitch<const char *>(Op.getToken())
2471 .Case("finit", "fninit")
2472 .Case("fsave", "fnsave")
2473 .Case("fstcw", "fnstcw")
2474 .Case("fstcww", "fnstcw")
2475 .Case("fstenv", "fnstenv")
2476 .Case("fstsw", "fnstsw")
2477 .Case("fstsww", "fnstsw")
2478 .Case("fclex", "fnclex")
2482 Inst.setOpcode(X86::WAIT);
2484 if (!MatchingInlineAsm)
2485 EmitInstruction(Inst, Operands, Out);
2486 Operands[0] = X86Operand::CreateToken(Repl, IDLoc);
2490 bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
2491 bool MatchingInlineAsm) {
2492 assert(ErrorInfo && "Unknown missing feature!");
2493 ArrayRef<SMRange> EmptyRanges = None;
2494 SmallString<126> Msg;
2495 raw_svector_ostream OS(Msg);
2496 OS << "instruction requires:";
2498 for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
2499 if (ErrorInfo & Mask)
2500 OS << ' ' << getSubtargetFeatureName(ErrorInfo & Mask);
2503 return Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
2506 bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
2507 OperandVector &Operands,
2509 uint64_t &ErrorInfo,
2510 bool MatchingInlineAsm) {
2511 assert(!Operands.empty() && "Unexpect empty operand list!");
2512 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2513 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
2514 ArrayRef<SMRange> EmptyRanges = None;
2516 // First, handle aliases that expand to multiple instructions.
2517 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2519 bool WasOriginallyInvalidOperand = false;
2522 // First, try a direct match.
2523 switch (MatchInstructionImpl(Operands, Inst,
2524 ErrorInfo, MatchingInlineAsm,
2525 isParsingIntelSyntax())) {
2526 default: llvm_unreachable("Unexpected match result!");
2528 // Some instructions need post-processing to, for example, tweak which
2529 // encoding is selected. Loop on it while changes happen so the
2530 // individual transformations can chain off each other.
2531 if (!MatchingInlineAsm)
2532 while (processInstruction(Inst, Operands))
2536 if (!MatchingInlineAsm)
2537 EmitInstruction(Inst, Operands, Out);
2538 Opcode = Inst.getOpcode();
2540 case Match_MissingFeature:
2541 return ErrorMissingFeature(IDLoc, ErrorInfo, MatchingInlineAsm);
2542 case Match_InvalidOperand:
2543 WasOriginallyInvalidOperand = true;
2545 case Match_MnemonicFail:
2549 // FIXME: Ideally, we would only attempt suffix matches for things which are
2550 // valid prefixes, and we could just infer the right unambiguous
2551 // type. However, that requires substantially more matcher support than the
2554 // Change the operand to point to a temporary token.
2555 StringRef Base = Op.getToken();
2556 SmallString<16> Tmp;
2559 Op.setTokenValue(Tmp);
2561 // If this instruction starts with an 'f', then it is a floating point stack
2562 // instruction. These come in up to three forms for 32-bit, 64-bit, and
2563 // 80-bit floating point, which use the suffixes s,l,t respectively.
2565 // Otherwise, we assume that this may be an integer instruction, which comes
2566 // in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively.
2567 const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0";
2569 // Check for the various suffix matches.
2570 uint64_t ErrorInfoIgnore;
2571 uint64_t ErrorInfoMissingFeature = 0; // Init suppresses compiler warnings.
2574 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I) {
2575 Tmp.back() = Suffixes[I];
2576 Match[I] = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
2577 MatchingInlineAsm, isParsingIntelSyntax());
2578 // If this returned as a missing feature failure, remember that.
2579 if (Match[I] == Match_MissingFeature)
2580 ErrorInfoMissingFeature = ErrorInfoIgnore;
2583 // Restore the old token.
2584 Op.setTokenValue(Base);
2586 // If exactly one matched, then we treat that as a successful match (and the
2587 // instruction will already have been filled in correctly, since the failing
2588 // matches won't have modified it).
2589 unsigned NumSuccessfulMatches =
2590 std::count(std::begin(Match), std::end(Match), Match_Success);
2591 if (NumSuccessfulMatches == 1) {
2593 if (!MatchingInlineAsm)
2594 EmitInstruction(Inst, Operands, Out);
2595 Opcode = Inst.getOpcode();
2599 // Otherwise, the match failed, try to produce a decent error message.
2601 // If we had multiple suffix matches, then identify this as an ambiguous
2603 if (NumSuccessfulMatches > 1) {
2605 unsigned NumMatches = 0;
2606 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I)
2607 if (Match[I] == Match_Success)
2608 MatchChars[NumMatches++] = Suffixes[I];
2610 SmallString<126> Msg;
2611 raw_svector_ostream OS(Msg);
2612 OS << "ambiguous instructions require an explicit suffix (could be ";
2613 for (unsigned i = 0; i != NumMatches; ++i) {
2616 if (i + 1 == NumMatches)
2618 OS << "'" << Base << MatchChars[i] << "'";
2621 Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
2625 // Okay, we know that none of the variants matched successfully.
2627 // If all of the instructions reported an invalid mnemonic, then the original
2628 // mnemonic was invalid.
2629 if (std::count(std::begin(Match), std::end(Match), Match_MnemonicFail) == 4) {
2630 if (!WasOriginallyInvalidOperand) {
2631 ArrayRef<SMRange> Ranges =
2632 MatchingInlineAsm ? EmptyRanges : Op.getLocRange();
2633 return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'",
2634 Ranges, MatchingInlineAsm);
2637 // Recover location info for the operand if we know which was the problem.
2638 if (ErrorInfo != ~0ULL) {
2639 if (ErrorInfo >= Operands.size())
2640 return Error(IDLoc, "too few operands for instruction",
2641 EmptyRanges, MatchingInlineAsm);
2643 X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo];
2644 if (Operand.getStartLoc().isValid()) {
2645 SMRange OperandRange = Operand.getLocRange();
2646 return Error(Operand.getStartLoc(), "invalid operand for instruction",
2647 OperandRange, MatchingInlineAsm);
2651 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2655 // If one instruction matched with a missing feature, report this as a
2657 if (std::count(std::begin(Match), std::end(Match),
2658 Match_MissingFeature) == 1) {
2659 ErrorInfo = ErrorInfoMissingFeature;
2660 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
2664 // If one instruction matched with an invalid operand, report this as an
2666 if (std::count(std::begin(Match), std::end(Match),
2667 Match_InvalidOperand) == 1) {
2668 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2672 // If all of these were an outright failure, report it in a useless way.
2673 Error(IDLoc, "unknown use of instruction mnemonic without a size suffix",
2674 EmptyRanges, MatchingInlineAsm);
2678 bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
2679 OperandVector &Operands,
2681 uint64_t &ErrorInfo,
2682 bool MatchingInlineAsm) {
2683 assert(!Operands.empty() && "Unexpect empty operand list!");
2684 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2685 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
2686 StringRef Mnemonic = Op.getToken();
2687 ArrayRef<SMRange> EmptyRanges = None;
2689 // First, handle aliases that expand to multiple instructions.
2690 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2694 // Find one unsized memory operand, if present.
2695 X86Operand *UnsizedMemOp = nullptr;
2696 for (const auto &Op : Operands) {
2697 X86Operand *X86Op = static_cast<X86Operand *>(Op.get());
2698 if (X86Op->isMemUnsized())
2699 UnsizedMemOp = X86Op;
2702 // Allow some instructions to have implicitly pointer-sized operands. This is
2703 // compatible with gas.
2705 static const char *const PtrSizedInstrs[] = {"call", "jmp", "push"};
2706 for (const char *Instr : PtrSizedInstrs) {
2707 if (Mnemonic == Instr) {
2708 UnsizedMemOp->Mem.Size = getPointerWidth();
2714 // If an unsized memory operand is present, try to match with each memory
2715 // operand size. In Intel assembly, the size is not part of the instruction
2717 SmallVector<unsigned, 8> Match;
2718 uint64_t ErrorInfoMissingFeature = 0;
2719 if (UnsizedMemOp && UnsizedMemOp->isMemUnsized()) {
2720 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
2721 for (unsigned Size : MopSizes) {
2722 UnsizedMemOp->Mem.Size = Size;
2723 uint64_t ErrorInfoIgnore;
2724 unsigned LastOpcode = Inst.getOpcode();
2726 MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
2727 MatchingInlineAsm, isParsingIntelSyntax());
2728 if (Match.empty() || LastOpcode != Inst.getOpcode())
2731 // If this returned as a missing feature failure, remember that.
2732 if (Match.back() == Match_MissingFeature)
2733 ErrorInfoMissingFeature = ErrorInfoIgnore;
2736 // Restore the size of the unsized memory operand if we modified it.
2738 UnsizedMemOp->Mem.Size = 0;
2741 // If we haven't matched anything yet, this is not a basic integer or FPU
2742 // operation. There shouldn't be any ambiguity in our mnemonic table, so try
2743 // matching with the unsized operand.
2744 if (Match.empty()) {
2745 Match.push_back(MatchInstructionImpl(Operands, Inst, ErrorInfo,
2747 isParsingIntelSyntax()));
2748 // If this returned as a missing feature failure, remember that.
2749 if (Match.back() == Match_MissingFeature)
2750 ErrorInfoMissingFeature = ErrorInfo;
2753 // Restore the size of the unsized memory operand if we modified it.
2755 UnsizedMemOp->Mem.Size = 0;
2757 // If it's a bad mnemonic, all results will be the same.
2758 if (Match.back() == Match_MnemonicFail) {
2759 ArrayRef<SMRange> Ranges =
2760 MatchingInlineAsm ? EmptyRanges : Op.getLocRange();
2761 return Error(IDLoc, "invalid instruction mnemonic '" + Mnemonic + "'",
2762 Ranges, MatchingInlineAsm);
2765 // If exactly one matched, then we treat that as a successful match (and the
2766 // instruction will already have been filled in correctly, since the failing
2767 // matches won't have modified it).
2768 unsigned NumSuccessfulMatches =
2769 std::count(std::begin(Match), std::end(Match), Match_Success);
2770 if (NumSuccessfulMatches == 1) {
2771 // Some instructions need post-processing to, for example, tweak which
2772 // encoding is selected. Loop on it while changes happen so the individual
2773 // transformations can chain off each other.
2774 if (!MatchingInlineAsm)
2775 while (processInstruction(Inst, Operands))
2778 if (!MatchingInlineAsm)
2779 EmitInstruction(Inst, Operands, Out);
2780 Opcode = Inst.getOpcode();
2782 } else if (NumSuccessfulMatches > 1) {
2783 assert(UnsizedMemOp &&
2784 "multiple matches only possible with unsized memory operands");
2785 ArrayRef<SMRange> Ranges =
2786 MatchingInlineAsm ? EmptyRanges : UnsizedMemOp->getLocRange();
2787 return Error(UnsizedMemOp->getStartLoc(),
2788 "ambiguous operand size for instruction '" + Mnemonic + "\'",
2789 Ranges, MatchingInlineAsm);
2792 // If one instruction matched with a missing feature, report this as a
2794 if (std::count(std::begin(Match), std::end(Match),
2795 Match_MissingFeature) == 1) {
2796 ErrorInfo = ErrorInfoMissingFeature;
2797 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
2801 // If one instruction matched with an invalid operand, report this as an
2803 if (std::count(std::begin(Match), std::end(Match),
2804 Match_InvalidOperand) == 1) {
2805 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2809 // If all of these were an outright failure, report it in a useless way.
2810 return Error(IDLoc, "unknown instruction mnemonic", EmptyRanges,
2814 bool X86AsmParser::OmitRegisterFromClobberLists(unsigned RegNo) {
2815 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo);
2818 bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
2819 MCAsmParser &Parser = getParser();
2820 StringRef IDVal = DirectiveID.getIdentifier();
2821 if (IDVal == ".word")
2822 return ParseDirectiveWord(2, DirectiveID.getLoc());
2823 else if (IDVal.startswith(".code"))
2824 return ParseDirectiveCode(IDVal, DirectiveID.getLoc());
2825 else if (IDVal.startswith(".att_syntax")) {
2826 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2827 if (Parser.getTok().getString() == "prefix")
2829 else if (Parser.getTok().getString() == "noprefix")
2830 return Error(DirectiveID.getLoc(), "'.att_syntax noprefix' is not "
2831 "supported: registers must have a "
2832 "'%' prefix in .att_syntax");
2834 getParser().setAssemblerDialect(0);
2836 } else if (IDVal.startswith(".intel_syntax")) {
2837 getParser().setAssemblerDialect(1);
2838 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2839 if (Parser.getTok().getString() == "noprefix")
2841 else if (Parser.getTok().getString() == "prefix")
2842 return Error(DirectiveID.getLoc(), "'.intel_syntax prefix' is not "
2843 "supported: registers must not have "
2844 "a '%' prefix in .intel_syntax");
2851 /// ParseDirectiveWord
2852 /// ::= .word [ expression (, expression)* ]
2853 bool X86AsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
2854 MCAsmParser &Parser = getParser();
2855 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2857 const MCExpr *Value;
2858 SMLoc ExprLoc = getLexer().getLoc();
2859 if (getParser().parseExpression(Value))
2862 if (const auto *MCE = dyn_cast<MCConstantExpr>(Value)) {
2863 assert(Size <= 8 && "Invalid size");
2864 uint64_t IntValue = MCE->getValue();
2865 if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))
2866 return Error(ExprLoc, "literal value out of range for directive");
2867 getStreamer().EmitIntValue(IntValue, Size);
2869 getStreamer().EmitValue(Value, Size, ExprLoc);
2872 if (getLexer().is(AsmToken::EndOfStatement))
2875 // FIXME: Improve diagnostic.
2876 if (getLexer().isNot(AsmToken::Comma)) {
2877 Error(L, "unexpected token in directive");
2888 /// ParseDirectiveCode
2889 /// ::= .code16 | .code32 | .code64
2890 bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
2891 MCAsmParser &Parser = getParser();
2892 if (IDVal == ".code16") {
2894 if (!is16BitMode()) {
2895 SwitchMode(X86::Mode16Bit);
2896 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
2898 } else if (IDVal == ".code32") {
2900 if (!is32BitMode()) {
2901 SwitchMode(X86::Mode32Bit);
2902 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
2904 } else if (IDVal == ".code64") {
2906 if (!is64BitMode()) {
2907 SwitchMode(X86::Mode64Bit);
2908 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code64);
2911 Error(L, "unknown directive " + IDVal);
2918 // Force static initialization.
2919 extern "C" void LLVMInitializeX86AsmParser() {
2920 RegisterMCAsmParser<X86AsmParser> X(TheX86_32Target);
2921 RegisterMCAsmParser<X86AsmParser> Y(TheX86_64Target);
2924 #define GET_REGISTER_MATCHER
2925 #define GET_MATCHER_IMPLEMENTATION
2926 #define GET_SUBTARGET_FEATURE_NAME
2927 #include "X86GenAsmMatcher.inc"