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 FeatureBitset AllModes({X86::Mode64Bit, X86::Mode32Bit, X86::Mode16Bit});
774 FeatureBitset OldMode = STI.getFeatureBits() & AllModes;
775 unsigned FB = ComputeAvailableFeatures(
776 STI.ToggleFeature(OldMode.flip(mode)));
777 setAvailableFeatures(FB);
779 assert(FeatureBitset({mode}) == (STI.getFeatureBits() & AllModes));
782 unsigned getPointerWidth() {
783 if (is16BitMode()) return 16;
784 if (is32BitMode()) return 32;
785 if (is64BitMode()) return 64;
786 llvm_unreachable("invalid mode");
789 bool isParsingIntelSyntax() {
790 return getParser().getAssemblerDialect();
793 /// @name Auto-generated Matcher Functions
796 #define GET_ASSEMBLER_HEADER
797 #include "X86GenAsmMatcher.inc"
802 X86AsmParser(MCSubtargetInfo &sti, MCAsmParser &Parser,
803 const MCInstrInfo &mii, const MCTargetOptions &Options)
804 : MCTargetAsmParser(Options, sti), MII(mii), InstInfo(nullptr) {
806 // Initialize the set of available features.
807 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
808 Instrumentation.reset(
809 CreateX86AsmInstrumentation(Options, Parser.getContext(), STI));
812 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
814 void SetFrameRegister(unsigned RegNo) override;
816 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
817 SMLoc NameLoc, OperandVector &Operands) override;
819 bool ParseDirective(AsmToken DirectiveID) override;
821 } // end anonymous namespace
823 /// @name Auto-generated Match Functions
826 static unsigned MatchRegisterName(StringRef Name);
830 static bool CheckBaseRegAndIndexReg(unsigned BaseReg, unsigned IndexReg,
832 // If we have both a base register and an index register make sure they are
833 // both 64-bit or 32-bit registers.
834 // To support VSIB, IndexReg can be 128-bit or 256-bit registers.
835 if (BaseReg != 0 && IndexReg != 0) {
836 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) &&
837 (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
838 X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg)) &&
839 IndexReg != X86::RIZ) {
840 ErrMsg = "base register is 64-bit, but index register is not";
843 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg) &&
844 (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
845 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) &&
846 IndexReg != X86::EIZ){
847 ErrMsg = "base register is 32-bit, but index register is not";
850 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg)) {
851 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg) ||
852 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) {
853 ErrMsg = "base register is 16-bit, but index register is not";
856 if (((BaseReg == X86::BX || BaseReg == X86::BP) &&
857 IndexReg != X86::SI && IndexReg != X86::DI) ||
858 ((BaseReg == X86::SI || BaseReg == X86::DI) &&
859 IndexReg != X86::BX && IndexReg != X86::BP)) {
860 ErrMsg = "invalid 16-bit base/index register combination";
868 bool X86AsmParser::doSrcDstMatch(X86Operand &Op1, X86Operand &Op2)
870 // Return true and let a normal complaint about bogus operands happen.
871 if (!Op1.isMem() || !Op2.isMem())
874 // Actually these might be the other way round if Intel syntax is
875 // being used. It doesn't matter.
876 unsigned diReg = Op1.Mem.BaseReg;
877 unsigned siReg = Op2.Mem.BaseReg;
879 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(siReg))
880 return X86MCRegisterClasses[X86::GR16RegClassID].contains(diReg);
881 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(siReg))
882 return X86MCRegisterClasses[X86::GR32RegClassID].contains(diReg);
883 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(siReg))
884 return X86MCRegisterClasses[X86::GR64RegClassID].contains(diReg);
885 // Again, return true and let another error happen.
889 bool X86AsmParser::ParseRegister(unsigned &RegNo,
890 SMLoc &StartLoc, SMLoc &EndLoc) {
891 MCAsmParser &Parser = getParser();
893 const AsmToken &PercentTok = Parser.getTok();
894 StartLoc = PercentTok.getLoc();
896 // If we encounter a %, ignore it. This code handles registers with and
897 // without the prefix, unprefixed registers can occur in cfi directives.
898 if (!isParsingIntelSyntax() && PercentTok.is(AsmToken::Percent))
899 Parser.Lex(); // Eat percent token.
901 const AsmToken &Tok = Parser.getTok();
902 EndLoc = Tok.getEndLoc();
904 if (Tok.isNot(AsmToken::Identifier)) {
905 if (isParsingIntelSyntax()) return true;
906 return Error(StartLoc, "invalid register name",
907 SMRange(StartLoc, EndLoc));
910 RegNo = MatchRegisterName(Tok.getString());
912 // If the match failed, try the register name as lowercase.
914 RegNo = MatchRegisterName(Tok.getString().lower());
916 // The "flags" register cannot be referenced directly.
917 // Treat it as an identifier instead.
918 if (isParsingInlineAsm() && isParsingIntelSyntax() && RegNo == X86::EFLAGS)
921 if (!is64BitMode()) {
922 // FIXME: This should be done using Requires<Not64BitMode> and
923 // Requires<In64BitMode> so "eiz" usage in 64-bit instructions can be also
925 // FIXME: Check AH, CH, DH, BH cannot be used in an instruction requiring a
927 if (RegNo == X86::RIZ ||
928 X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo) ||
929 X86II::isX86_64NonExtLowByteReg(RegNo) ||
930 X86II::isX86_64ExtendedReg(RegNo))
931 return Error(StartLoc, "register %"
932 + Tok.getString() + " is only available in 64-bit mode",
933 SMRange(StartLoc, EndLoc));
936 // Parse "%st" as "%st(0)" and "%st(1)", which is multiple tokens.
937 if (RegNo == 0 && (Tok.getString() == "st" || Tok.getString() == "ST")) {
939 Parser.Lex(); // Eat 'st'
941 // Check to see if we have '(4)' after %st.
942 if (getLexer().isNot(AsmToken::LParen))
947 const AsmToken &IntTok = Parser.getTok();
948 if (IntTok.isNot(AsmToken::Integer))
949 return Error(IntTok.getLoc(), "expected stack index");
950 switch (IntTok.getIntVal()) {
951 case 0: RegNo = X86::ST0; break;
952 case 1: RegNo = X86::ST1; break;
953 case 2: RegNo = X86::ST2; break;
954 case 3: RegNo = X86::ST3; break;
955 case 4: RegNo = X86::ST4; break;
956 case 5: RegNo = X86::ST5; break;
957 case 6: RegNo = X86::ST6; break;
958 case 7: RegNo = X86::ST7; break;
959 default: return Error(IntTok.getLoc(), "invalid stack index");
962 if (getParser().Lex().isNot(AsmToken::RParen))
963 return Error(Parser.getTok().getLoc(), "expected ')'");
965 EndLoc = Parser.getTok().getEndLoc();
966 Parser.Lex(); // Eat ')'
970 EndLoc = Parser.getTok().getEndLoc();
972 // If this is "db[0-7]", match it as an alias
974 if (RegNo == 0 && Tok.getString().size() == 3 &&
975 Tok.getString().startswith("db")) {
976 switch (Tok.getString()[2]) {
977 case '0': RegNo = X86::DR0; break;
978 case '1': RegNo = X86::DR1; break;
979 case '2': RegNo = X86::DR2; break;
980 case '3': RegNo = X86::DR3; break;
981 case '4': RegNo = X86::DR4; break;
982 case '5': RegNo = X86::DR5; break;
983 case '6': RegNo = X86::DR6; break;
984 case '7': RegNo = X86::DR7; break;
988 EndLoc = Parser.getTok().getEndLoc();
989 Parser.Lex(); // Eat it.
995 if (isParsingIntelSyntax()) return true;
996 return Error(StartLoc, "invalid register name",
997 SMRange(StartLoc, EndLoc));
1000 Parser.Lex(); // Eat identifier token.
1004 void X86AsmParser::SetFrameRegister(unsigned RegNo) {
1005 Instrumentation->SetInitialFrameRegister(RegNo);
1008 std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(SMLoc Loc) {
1010 is64BitMode() ? X86::RSI : (is32BitMode() ? X86::ESI : X86::SI);
1011 const MCExpr *Disp = MCConstantExpr::create(0, getContext());
1012 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
1013 /*BaseReg=*/basereg, /*IndexReg=*/0, /*Scale=*/1,
1017 std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand(SMLoc Loc) {
1019 is64BitMode() ? X86::RDI : (is32BitMode() ? X86::EDI : X86::DI);
1020 const MCExpr *Disp = MCConstantExpr::create(0, getContext());
1021 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
1022 /*BaseReg=*/basereg, /*IndexReg=*/0, /*Scale=*/1,
1026 void X86AsmParser::AddDefaultSrcDestOperands(
1027 OperandVector& Operands, std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
1028 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst) {
1029 if (isParsingIntelSyntax()) {
1030 Operands.push_back(std::move(Dst));
1031 Operands.push_back(std::move(Src));
1034 Operands.push_back(std::move(Src));
1035 Operands.push_back(std::move(Dst));
1039 std::unique_ptr<X86Operand> X86AsmParser::ParseOperand() {
1040 if (isParsingIntelSyntax())
1041 return ParseIntelOperand();
1042 return ParseATTOperand();
1045 /// getIntelMemOperandSize - Return intel memory operand size.
1046 static unsigned getIntelMemOperandSize(StringRef OpStr) {
1047 unsigned Size = StringSwitch<unsigned>(OpStr)
1048 .Cases("BYTE", "byte", 8)
1049 .Cases("WORD", "word", 16)
1050 .Cases("DWORD", "dword", 32)
1051 .Cases("QWORD", "qword", 64)
1052 .Cases("MMWORD","mmword", 64)
1053 .Cases("XWORD", "xword", 80)
1054 .Cases("TBYTE", "tbyte", 80)
1055 .Cases("XMMWORD", "xmmword", 128)
1056 .Cases("YMMWORD", "ymmword", 256)
1057 .Cases("ZMMWORD", "zmmword", 512)
1058 .Cases("OPAQUE", "opaque", -1U) // needs to be non-zero, but doesn't matter
1063 std::unique_ptr<X86Operand> X86AsmParser::CreateMemForInlineAsm(
1064 unsigned SegReg, const MCExpr *Disp, unsigned BaseReg, unsigned IndexReg,
1065 unsigned Scale, SMLoc Start, SMLoc End, unsigned Size, StringRef Identifier,
1066 InlineAsmIdentifierInfo &Info) {
1067 // If we found a decl other than a VarDecl, then assume it is a FuncDecl or
1068 // some other label reference.
1069 if (isa<MCSymbolRefExpr>(Disp) && Info.OpDecl && !Info.IsVarDecl) {
1070 // Insert an explicit size if the user didn't have one.
1072 Size = getPointerWidth();
1073 InstInfo->AsmRewrites->emplace_back(AOK_SizeDirective, Start,
1077 // Create an absolute memory reference in order to match against
1078 // instructions taking a PC relative operand.
1079 return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size,
1080 Identifier, Info.OpDecl);
1083 // We either have a direct symbol reference, or an offset from a symbol. The
1084 // parser always puts the symbol on the LHS, so look there for size
1085 // calculation purposes.
1086 const MCBinaryExpr *BinOp = dyn_cast<MCBinaryExpr>(Disp);
1088 isa<MCSymbolRefExpr>(BinOp ? BinOp->getLHS() : Disp);
1091 Size = Info.Type * 8; // Size is in terms of bits in this context.
1093 InstInfo->AsmRewrites->emplace_back(AOK_SizeDirective, Start,
1098 // When parsing inline assembly we set the base register to a non-zero value
1099 // if we don't know the actual value at this time. This is necessary to
1100 // get the matching correct in some cases.
1101 BaseReg = BaseReg ? BaseReg : 1;
1102 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
1103 IndexReg, Scale, Start, End, Size, Identifier,
1108 RewriteIntelBracExpression(SmallVectorImpl<AsmRewrite> &AsmRewrites,
1109 StringRef SymName, int64_t ImmDisp,
1110 int64_t FinalImmDisp, SMLoc &BracLoc,
1111 SMLoc &StartInBrac, SMLoc &End) {
1112 // Remove the '[' and ']' from the IR string.
1113 AsmRewrites.emplace_back(AOK_Skip, BracLoc, 1);
1114 AsmRewrites.emplace_back(AOK_Skip, End, 1);
1116 // If ImmDisp is non-zero, then we parsed a displacement before the
1117 // bracketed expression (i.e., ImmDisp [ BaseReg + Scale*IndexReg + Disp])
1118 // If ImmDisp doesn't match the displacement computed by the state machine
1119 // then we have an additional displacement in the bracketed expression.
1120 if (ImmDisp != FinalImmDisp) {
1122 // We have an immediate displacement before the bracketed expression.
1123 // Adjust this to match the final immediate displacement.
1125 for (AsmRewrite &AR : AsmRewrites) {
1126 if (AR.Loc.getPointer() > BracLoc.getPointer())
1128 if (AR.Kind == AOK_ImmPrefix || AR.Kind == AOK_Imm) {
1129 assert (!Found && "ImmDisp already rewritten.");
1131 AR.Len = BracLoc.getPointer() - AR.Loc.getPointer();
1132 AR.Val = FinalImmDisp;
1137 assert (Found && "Unable to rewrite ImmDisp.");
1140 // We have a symbolic and an immediate displacement, but no displacement
1141 // before the bracketed expression. Put the immediate displacement
1142 // before the bracketed expression.
1143 AsmRewrites.emplace_back(AOK_Imm, BracLoc, 0, FinalImmDisp);
1146 // Remove all the ImmPrefix rewrites within the brackets.
1147 for (AsmRewrite &AR : AsmRewrites) {
1148 if (AR.Loc.getPointer() < StartInBrac.getPointer())
1150 if (AR.Kind == AOK_ImmPrefix)
1151 AR.Kind = AOK_Delete;
1153 const char *SymLocPtr = SymName.data();
1154 // Skip everything before the symbol.
1155 if (unsigned Len = SymLocPtr - StartInBrac.getPointer()) {
1156 assert(Len > 0 && "Expected a non-negative length.");
1157 AsmRewrites.emplace_back(AOK_Skip, StartInBrac, Len);
1159 // Skip everything after the symbol.
1160 if (unsigned Len = End.getPointer() - (SymLocPtr + SymName.size())) {
1161 SMLoc Loc = SMLoc::getFromPointer(SymLocPtr + SymName.size());
1162 assert(Len > 0 && "Expected a non-negative length.");
1163 AsmRewrites.emplace_back(AOK_Skip, Loc, Len);
1167 bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
1168 MCAsmParser &Parser = getParser();
1169 const AsmToken &Tok = Parser.getTok();
1173 bool UpdateLocLex = true;
1175 // The period in the dot operator (e.g., [ebx].foo.bar) is parsed as an
1176 // identifier. Don't try an parse it as a register.
1177 if (Tok.getString().startswith("."))
1180 // If we're parsing an immediate expression, we don't expect a '['.
1181 if (SM.getStopOnLBrac() && getLexer().getKind() == AsmToken::LBrac)
1184 AsmToken::TokenKind TK = getLexer().getKind();
1187 if (SM.isValidEndState()) {
1191 return Error(Tok.getLoc(), "unknown token in expression");
1193 case AsmToken::EndOfStatement: {
1197 case AsmToken::String:
1198 case AsmToken::Identifier: {
1199 // This could be a register or a symbolic displacement.
1202 SMLoc IdentLoc = Tok.getLoc();
1203 StringRef Identifier = Tok.getString();
1204 if (TK != AsmToken::String && !ParseRegister(TmpReg, IdentLoc, End)) {
1205 SM.onRegister(TmpReg);
1206 UpdateLocLex = false;
1209 if (!isParsingInlineAsm()) {
1210 if (getParser().parsePrimaryExpr(Val, End))
1211 return Error(Tok.getLoc(), "Unexpected identifier!");
1213 // This is a dot operator, not an adjacent identifier.
1214 if (Identifier.find('.') != StringRef::npos) {
1217 InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
1218 if (ParseIntelIdentifier(Val, Identifier, Info,
1219 /*Unevaluated=*/false, End))
1223 SM.onIdentifierExpr(Val, Identifier);
1224 UpdateLocLex = false;
1227 return Error(Tok.getLoc(), "Unexpected identifier!");
1229 case AsmToken::Integer: {
1231 if (isParsingInlineAsm() && SM.getAddImmPrefix())
1232 InstInfo->AsmRewrites->emplace_back(AOK_ImmPrefix, Tok.getLoc());
1233 // Look for 'b' or 'f' following an Integer as a directional label
1234 SMLoc Loc = getTok().getLoc();
1235 int64_t IntVal = getTok().getIntVal();
1236 End = consumeToken();
1237 UpdateLocLex = false;
1238 if (getLexer().getKind() == AsmToken::Identifier) {
1239 StringRef IDVal = getTok().getString();
1240 if (IDVal == "f" || IDVal == "b") {
1242 getContext().getDirectionalLocalSymbol(IntVal, IDVal == "b");
1243 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1245 MCSymbolRefExpr::create(Sym, Variant, getContext());
1246 if (IDVal == "b" && Sym->isUndefined())
1247 return Error(Loc, "invalid reference to undefined symbol");
1248 StringRef Identifier = Sym->getName();
1249 SM.onIdentifierExpr(Val, Identifier);
1250 End = consumeToken();
1252 if (SM.onInteger(IntVal, ErrMsg))
1253 return Error(Loc, ErrMsg);
1256 if (SM.onInteger(IntVal, ErrMsg))
1257 return Error(Loc, ErrMsg);
1261 case AsmToken::Plus: SM.onPlus(); break;
1262 case AsmToken::Minus: SM.onMinus(); break;
1263 case AsmToken::Tilde: SM.onNot(); break;
1264 case AsmToken::Star: SM.onStar(); break;
1265 case AsmToken::Slash: SM.onDivide(); break;
1266 case AsmToken::Pipe: SM.onOr(); break;
1267 case AsmToken::Caret: SM.onXor(); break;
1268 case AsmToken::Amp: SM.onAnd(); break;
1269 case AsmToken::LessLess:
1270 SM.onLShift(); break;
1271 case AsmToken::GreaterGreater:
1272 SM.onRShift(); break;
1273 case AsmToken::LBrac: SM.onLBrac(); break;
1274 case AsmToken::RBrac: SM.onRBrac(); break;
1275 case AsmToken::LParen: SM.onLParen(); break;
1276 case AsmToken::RParen: SM.onRParen(); break;
1279 return Error(Tok.getLoc(), "unknown token in expression");
1281 if (!Done && UpdateLocLex)
1282 End = consumeToken();
1287 std::unique_ptr<X86Operand>
1288 X86AsmParser::ParseIntelBracExpression(unsigned SegReg, SMLoc Start,
1289 int64_t ImmDisp, unsigned Size) {
1290 MCAsmParser &Parser = getParser();
1291 const AsmToken &Tok = Parser.getTok();
1292 SMLoc BracLoc = Tok.getLoc(), End = Tok.getEndLoc();
1293 if (getLexer().isNot(AsmToken::LBrac))
1294 return ErrorOperand(BracLoc, "Expected '[' token!");
1295 Parser.Lex(); // Eat '['
1297 SMLoc StartInBrac = Tok.getLoc();
1298 // Parse [ Symbol + ImmDisp ] and [ BaseReg + Scale*IndexReg + ImmDisp ]. We
1299 // may have already parsed an immediate displacement before the bracketed
1301 IntelExprStateMachine SM(ImmDisp, /*StopOnLBrac=*/false, /*AddImmPrefix=*/true);
1302 if (ParseIntelExpression(SM, End))
1305 const MCExpr *Disp = nullptr;
1306 if (const MCExpr *Sym = SM.getSym()) {
1307 // A symbolic displacement.
1309 if (isParsingInlineAsm())
1310 RewriteIntelBracExpression(*InstInfo->AsmRewrites, SM.getSymName(),
1311 ImmDisp, SM.getImm(), BracLoc, StartInBrac,
1315 if (SM.getImm() || !Disp) {
1316 const MCExpr *Imm = MCConstantExpr::create(SM.getImm(), getContext());
1318 Disp = MCBinaryExpr::createAdd(Disp, Imm, getContext());
1320 Disp = Imm; // An immediate displacement only.
1323 // Parse struct field access. Intel requires a dot, but MSVC doesn't. MSVC
1324 // will in fact do global lookup the field name inside all global typedefs,
1325 // but we don't emulate that.
1326 if (Tok.getString().find('.') != StringRef::npos) {
1327 const MCExpr *NewDisp;
1328 if (ParseIntelDotOperator(Disp, NewDisp))
1331 End = Tok.getEndLoc();
1332 Parser.Lex(); // Eat the field.
1336 int BaseReg = SM.getBaseReg();
1337 int IndexReg = SM.getIndexReg();
1338 int Scale = SM.getScale();
1339 if (!isParsingInlineAsm()) {
1341 if (!BaseReg && !IndexReg) {
1343 return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size);
1344 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
1348 if (CheckBaseRegAndIndexReg(BaseReg, IndexReg, ErrMsg)) {
1349 Error(StartInBrac, ErrMsg);
1352 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
1353 IndexReg, Scale, Start, End, Size);
1356 InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
1357 return CreateMemForInlineAsm(SegReg, Disp, BaseReg, IndexReg, Scale, Start,
1358 End, Size, SM.getSymName(), Info);
1361 // Inline assembly may use variable names with namespace alias qualifiers.
1362 bool X86AsmParser::ParseIntelIdentifier(const MCExpr *&Val,
1363 StringRef &Identifier,
1364 InlineAsmIdentifierInfo &Info,
1365 bool IsUnevaluatedOperand, SMLoc &End) {
1366 MCAsmParser &Parser = getParser();
1367 assert(isParsingInlineAsm() && "Expected to be parsing inline assembly.");
1370 StringRef LineBuf(Identifier.data());
1372 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);
1374 const AsmToken &Tok = Parser.getTok();
1375 SMLoc Loc = Tok.getLoc();
1377 // Advance the token stream until the end of the current token is
1378 // after the end of what the frontend claimed.
1379 const char *EndPtr = Tok.getLoc().getPointer() + LineBuf.size();
1381 End = Tok.getEndLoc();
1383 } while (End.getPointer() < EndPtr);
1384 Identifier = LineBuf;
1386 // The frontend should end parsing on an assembler token boundary, unless it
1388 assert((End.getPointer() == EndPtr || !Result) &&
1389 "frontend claimed part of a token?");
1391 // If the identifier lookup was unsuccessful, assume that we are dealing with
1394 StringRef InternalName =
1395 SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(),
1397 assert(InternalName.size() && "We should have an internal name here.");
1398 // Push a rewrite for replacing the identifier name with the internal name.
1399 InstInfo->AsmRewrites->emplace_back(AOK_Label, Loc, Identifier.size(),
1403 // Create the symbol reference.
1404 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
1405 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1406 Val = MCSymbolRefExpr::create(Sym, Variant, getParser().getContext());
1410 /// \brief Parse intel style segment override.
1411 std::unique_ptr<X86Operand>
1412 X86AsmParser::ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start,
1414 MCAsmParser &Parser = getParser();
1415 assert(SegReg != 0 && "Tried to parse a segment override without a segment!");
1416 const AsmToken &Tok = Parser.getTok(); // Eat colon.
1417 if (Tok.isNot(AsmToken::Colon))
1418 return ErrorOperand(Tok.getLoc(), "Expected ':' token!");
1419 Parser.Lex(); // Eat ':'
1421 int64_t ImmDisp = 0;
1422 if (getLexer().is(AsmToken::Integer)) {
1423 ImmDisp = Tok.getIntVal();
1424 AsmToken ImmDispToken = Parser.Lex(); // Eat the integer.
1426 if (isParsingInlineAsm())
1427 InstInfo->AsmRewrites->emplace_back(AOK_ImmPrefix, ImmDispToken.getLoc());
1429 if (getLexer().isNot(AsmToken::LBrac)) {
1430 // An immediate following a 'segment register', 'colon' token sequence can
1431 // be followed by a bracketed expression. If it isn't we know we have our
1432 // final segment override.
1433 const MCExpr *Disp = MCConstantExpr::create(ImmDisp, getContext());
1434 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp,
1435 /*BaseReg=*/0, /*IndexReg=*/0, /*Scale=*/1,
1436 Start, ImmDispToken.getEndLoc(), Size);
1440 if (getLexer().is(AsmToken::LBrac))
1441 return ParseIntelBracExpression(SegReg, Start, ImmDisp, Size);
1445 if (!isParsingInlineAsm()) {
1446 if (getParser().parsePrimaryExpr(Val, End))
1447 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1449 return X86Operand::CreateMem(getPointerWidth(), Val, Start, End, Size);
1452 InlineAsmIdentifierInfo Info;
1453 StringRef Identifier = Tok.getString();
1454 if (ParseIntelIdentifier(Val, Identifier, Info,
1455 /*Unevaluated=*/false, End))
1457 return CreateMemForInlineAsm(/*SegReg=*/0, Val, /*BaseReg=*/0,/*IndexReg=*/0,
1458 /*Scale=*/1, Start, End, Size, Identifier, Info);
1461 //ParseRoundingModeOp - Parse AVX-512 rounding mode operand
1462 std::unique_ptr<X86Operand>
1463 X86AsmParser::ParseRoundingModeOp(SMLoc Start, SMLoc End) {
1464 MCAsmParser &Parser = getParser();
1465 const AsmToken &Tok = Parser.getTok();
1466 // Eat "{" and mark the current place.
1467 const SMLoc consumedToken = consumeToken();
1468 if (Tok.getIdentifier().startswith("r")){
1469 int rndMode = StringSwitch<int>(Tok.getIdentifier())
1470 .Case("rn", X86::STATIC_ROUNDING::TO_NEAREST_INT)
1471 .Case("rd", X86::STATIC_ROUNDING::TO_NEG_INF)
1472 .Case("ru", X86::STATIC_ROUNDING::TO_POS_INF)
1473 .Case("rz", X86::STATIC_ROUNDING::TO_ZERO)
1476 return ErrorOperand(Tok.getLoc(), "Invalid rounding mode.");
1477 Parser.Lex(); // Eat "r*" of r*-sae
1478 if (!getLexer().is(AsmToken::Minus))
1479 return ErrorOperand(Tok.getLoc(), "Expected - at this point");
1480 Parser.Lex(); // Eat "-"
1481 Parser.Lex(); // Eat the sae
1482 if (!getLexer().is(AsmToken::RCurly))
1483 return ErrorOperand(Tok.getLoc(), "Expected } at this point");
1484 Parser.Lex(); // Eat "}"
1485 const MCExpr *RndModeOp =
1486 MCConstantExpr::create(rndMode, Parser.getContext());
1487 return X86Operand::CreateImm(RndModeOp, Start, End);
1489 if(Tok.getIdentifier().equals("sae")){
1490 Parser.Lex(); // Eat the sae
1491 if (!getLexer().is(AsmToken::RCurly))
1492 return ErrorOperand(Tok.getLoc(), "Expected } at this point");
1493 Parser.Lex(); // Eat "}"
1494 return X86Operand::CreateToken("{sae}", consumedToken);
1496 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1498 /// ParseIntelMemOperand - Parse intel style memory operand.
1499 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelMemOperand(int64_t ImmDisp,
1502 MCAsmParser &Parser = getParser();
1503 const AsmToken &Tok = Parser.getTok();
1506 // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
1507 if (getLexer().is(AsmToken::LBrac))
1508 return ParseIntelBracExpression(/*SegReg=*/0, Start, ImmDisp, Size);
1509 assert(ImmDisp == 0);
1512 if (!isParsingInlineAsm()) {
1513 if (getParser().parsePrimaryExpr(Val, End))
1514 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1516 return X86Operand::CreateMem(getPointerWidth(), Val, Start, End, Size);
1519 InlineAsmIdentifierInfo Info;
1520 StringRef Identifier = Tok.getString();
1521 if (ParseIntelIdentifier(Val, Identifier, Info,
1522 /*Unevaluated=*/false, End))
1525 if (!getLexer().is(AsmToken::LBrac))
1526 return CreateMemForInlineAsm(/*SegReg=*/0, Val, /*BaseReg=*/0, /*IndexReg=*/0,
1527 /*Scale=*/1, Start, End, Size, Identifier, Info);
1529 Parser.Lex(); // Eat '['
1531 // Parse Identifier [ ImmDisp ]
1532 IntelExprStateMachine SM(/*ImmDisp=*/0, /*StopOnLBrac=*/true,
1533 /*AddImmPrefix=*/false);
1534 if (ParseIntelExpression(SM, End))
1538 Error(Start, "cannot use more than one symbol in memory operand");
1541 if (SM.getBaseReg()) {
1542 Error(Start, "cannot use base register with variable reference");
1545 if (SM.getIndexReg()) {
1546 Error(Start, "cannot use index register with variable reference");
1550 const MCExpr *Disp = MCConstantExpr::create(SM.getImm(), getContext());
1551 // BaseReg is non-zero to avoid assertions. In the context of inline asm,
1552 // we're pointing to a local variable in memory, so the base register is
1553 // really the frame or stack pointer.
1554 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
1555 /*BaseReg=*/1, /*IndexReg=*/0, /*Scale=*/1,
1556 Start, End, Size, Identifier, Info.OpDecl);
1559 /// Parse the '.' operator.
1560 bool X86AsmParser::ParseIntelDotOperator(const MCExpr *Disp,
1561 const MCExpr *&NewDisp) {
1562 MCAsmParser &Parser = getParser();
1563 const AsmToken &Tok = Parser.getTok();
1564 int64_t OrigDispVal, DotDispVal;
1566 // FIXME: Handle non-constant expressions.
1567 if (const MCConstantExpr *OrigDisp = dyn_cast<MCConstantExpr>(Disp))
1568 OrigDispVal = OrigDisp->getValue();
1570 return Error(Tok.getLoc(), "Non-constant offsets are not supported!");
1572 // Drop the optional '.'.
1573 StringRef DotDispStr = Tok.getString();
1574 if (DotDispStr.startswith("."))
1575 DotDispStr = DotDispStr.drop_front(1);
1577 // .Imm gets lexed as a real.
1578 if (Tok.is(AsmToken::Real)) {
1580 DotDispStr.getAsInteger(10, DotDisp);
1581 DotDispVal = DotDisp.getZExtValue();
1582 } else if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) {
1584 std::pair<StringRef, StringRef> BaseMember = DotDispStr.split('.');
1585 if (SemaCallback->LookupInlineAsmField(BaseMember.first, BaseMember.second,
1587 return Error(Tok.getLoc(), "Unable to lookup field reference!");
1588 DotDispVal = DotDisp;
1590 return Error(Tok.getLoc(), "Unexpected token type!");
1592 if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) {
1593 SMLoc Loc = SMLoc::getFromPointer(DotDispStr.data());
1594 unsigned Len = DotDispStr.size();
1595 unsigned Val = OrigDispVal + DotDispVal;
1596 InstInfo->AsmRewrites->emplace_back(AOK_DotOperator, Loc, Len, Val);
1599 NewDisp = MCConstantExpr::create(OrigDispVal + DotDispVal, getContext());
1603 /// Parse the 'offset' operator. This operator is used to specify the
1604 /// location rather then the content of a variable.
1605 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOffsetOfOperator() {
1606 MCAsmParser &Parser = getParser();
1607 const AsmToken &Tok = Parser.getTok();
1608 SMLoc OffsetOfLoc = Tok.getLoc();
1609 Parser.Lex(); // Eat offset.
1612 InlineAsmIdentifierInfo Info;
1613 SMLoc Start = Tok.getLoc(), End;
1614 StringRef Identifier = Tok.getString();
1615 if (ParseIntelIdentifier(Val, Identifier, Info,
1616 /*Unevaluated=*/false, End))
1619 // Don't emit the offset operator.
1620 InstInfo->AsmRewrites->emplace_back(AOK_Skip, OffsetOfLoc, 7);
1622 // The offset operator will have an 'r' constraint, thus we need to create
1623 // register operand to ensure proper matching. Just pick a GPR based on
1624 // the size of a pointer.
1626 is64BitMode() ? X86::RBX : (is32BitMode() ? X86::EBX : X86::BX);
1627 return X86Operand::CreateReg(RegNo, Start, End, /*GetAddress=*/true,
1628 OffsetOfLoc, Identifier, Info.OpDecl);
1631 enum IntelOperatorKind {
1637 /// Parse the 'LENGTH', 'TYPE' and 'SIZE' operators. The LENGTH operator
1638 /// returns the number of elements in an array. It returns the value 1 for
1639 /// non-array variables. The SIZE operator returns the size of a C or C++
1640 /// variable. A variable's size is the product of its LENGTH and TYPE. The
1641 /// TYPE operator returns the size of a C or C++ type or variable. If the
1642 /// variable is an array, TYPE returns the size of a single element.
1643 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperator(unsigned OpKind) {
1644 MCAsmParser &Parser = getParser();
1645 const AsmToken &Tok = Parser.getTok();
1646 SMLoc TypeLoc = Tok.getLoc();
1647 Parser.Lex(); // Eat operator.
1649 const MCExpr *Val = nullptr;
1650 InlineAsmIdentifierInfo Info;
1651 SMLoc Start = Tok.getLoc(), End;
1652 StringRef Identifier = Tok.getString();
1653 if (ParseIntelIdentifier(Val, Identifier, Info,
1654 /*Unevaluated=*/true, End))
1658 return ErrorOperand(Start, "unable to lookup expression");
1662 default: llvm_unreachable("Unexpected operand kind!");
1663 case IOK_LENGTH: CVal = Info.Length; break;
1664 case IOK_SIZE: CVal = Info.Size; break;
1665 case IOK_TYPE: CVal = Info.Type; break;
1668 // Rewrite the type operator and the C or C++ type or variable in terms of an
1669 // immediate. E.g. TYPE foo -> $$4
1670 unsigned Len = End.getPointer() - TypeLoc.getPointer();
1671 InstInfo->AsmRewrites->emplace_back(AOK_Imm, TypeLoc, Len, CVal);
1673 const MCExpr *Imm = MCConstantExpr::create(CVal, getContext());
1674 return X86Operand::CreateImm(Imm, Start, End);
1677 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand() {
1678 MCAsmParser &Parser = getParser();
1679 const AsmToken &Tok = Parser.getTok();
1682 // Offset, length, type and size operators.
1683 if (isParsingInlineAsm()) {
1684 StringRef AsmTokStr = Tok.getString();
1685 if (AsmTokStr == "offset" || AsmTokStr == "OFFSET")
1686 return ParseIntelOffsetOfOperator();
1687 if (AsmTokStr == "length" || AsmTokStr == "LENGTH")
1688 return ParseIntelOperator(IOK_LENGTH);
1689 if (AsmTokStr == "size" || AsmTokStr == "SIZE")
1690 return ParseIntelOperator(IOK_SIZE);
1691 if (AsmTokStr == "type" || AsmTokStr == "TYPE")
1692 return ParseIntelOperator(IOK_TYPE);
1695 unsigned Size = getIntelMemOperandSize(Tok.getString());
1697 Parser.Lex(); // Eat operand size (e.g., byte, word).
1698 if (Tok.getString() != "PTR" && Tok.getString() != "ptr")
1699 return ErrorOperand(Tok.getLoc(), "Expected 'PTR' or 'ptr' token!");
1700 Parser.Lex(); // Eat ptr.
1702 Start = Tok.getLoc();
1705 if (getLexer().is(AsmToken::Integer) || getLexer().is(AsmToken::Minus) ||
1706 getLexer().is(AsmToken::Tilde) || getLexer().is(AsmToken::LParen)) {
1707 AsmToken StartTok = Tok;
1708 IntelExprStateMachine SM(/*Imm=*/0, /*StopOnLBrac=*/true,
1709 /*AddImmPrefix=*/false);
1710 if (ParseIntelExpression(SM, End))
1713 int64_t Imm = SM.getImm();
1714 if (isParsingInlineAsm()) {
1715 unsigned Len = Tok.getLoc().getPointer() - Start.getPointer();
1716 if (StartTok.getString().size() == Len)
1717 // Just add a prefix if this wasn't a complex immediate expression.
1718 InstInfo->AsmRewrites->emplace_back(AOK_ImmPrefix, Start);
1720 // Otherwise, rewrite the complex expression as a single immediate.
1721 InstInfo->AsmRewrites->emplace_back(AOK_Imm, Start, Len, Imm);
1724 if (getLexer().isNot(AsmToken::LBrac)) {
1725 // If a directional label (ie. 1f or 2b) was parsed above from
1726 // ParseIntelExpression() then SM.getSym() was set to a pointer to
1727 // to the MCExpr with the directional local symbol and this is a
1728 // memory operand not an immediate operand.
1730 return X86Operand::CreateMem(getPointerWidth(), SM.getSym(), Start, End,
1733 const MCExpr *ImmExpr = MCConstantExpr::create(Imm, getContext());
1734 return X86Operand::CreateImm(ImmExpr, Start, End);
1737 // Only positive immediates are valid.
1739 return ErrorOperand(Start, "expected a positive immediate displacement "
1740 "before bracketed expr.");
1742 // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
1743 return ParseIntelMemOperand(Imm, Start, Size);
1746 // rounding mode token
1747 if (getSTI().getFeatureBits()[X86::FeatureAVX512] &&
1748 getLexer().is(AsmToken::LCurly))
1749 return ParseRoundingModeOp(Start, End);
1753 if (!ParseRegister(RegNo, Start, End)) {
1754 // If this is a segment register followed by a ':', then this is the start
1755 // of a segment override, otherwise this is a normal register reference.
1756 if (getLexer().isNot(AsmToken::Colon))
1757 return X86Operand::CreateReg(RegNo, Start, End);
1759 return ParseIntelSegmentOverride(/*SegReg=*/RegNo, Start, Size);
1763 return ParseIntelMemOperand(/*Disp=*/0, Start, Size);
1766 std::unique_ptr<X86Operand> X86AsmParser::ParseATTOperand() {
1767 MCAsmParser &Parser = getParser();
1768 switch (getLexer().getKind()) {
1770 // Parse a memory operand with no segment register.
1771 return ParseMemOperand(0, Parser.getTok().getLoc());
1772 case AsmToken::Percent: {
1773 // Read the register.
1776 if (ParseRegister(RegNo, Start, End)) return nullptr;
1777 if (RegNo == X86::EIZ || RegNo == X86::RIZ) {
1778 Error(Start, "%eiz and %riz can only be used as index registers",
1779 SMRange(Start, End));
1783 // If this is a segment register followed by a ':', then this is the start
1784 // of a memory reference, otherwise this is a normal register reference.
1785 if (getLexer().isNot(AsmToken::Colon))
1786 return X86Operand::CreateReg(RegNo, Start, End);
1788 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo))
1789 return ErrorOperand(Start, "invalid segment register");
1791 getParser().Lex(); // Eat the colon.
1792 return ParseMemOperand(RegNo, Start);
1794 case AsmToken::Dollar: {
1795 // $42 -> immediate.
1796 SMLoc Start = Parser.getTok().getLoc(), End;
1799 if (getParser().parseExpression(Val, End))
1801 return X86Operand::CreateImm(Val, Start, End);
1803 case AsmToken::LCurly:{
1804 SMLoc Start = Parser.getTok().getLoc(), End;
1805 if (getSTI().getFeatureBits()[X86::FeatureAVX512])
1806 return ParseRoundingModeOp(Start, End);
1807 return ErrorOperand(Start, "unknown token in expression");
1812 bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands,
1813 const MCParsedAsmOperand &Op) {
1814 MCAsmParser &Parser = getParser();
1815 if(getSTI().getFeatureBits()[X86::FeatureAVX512]) {
1816 if (getLexer().is(AsmToken::LCurly)) {
1817 // Eat "{" and mark the current place.
1818 const SMLoc consumedToken = consumeToken();
1819 // Distinguish {1to<NUM>} from {%k<NUM>}.
1820 if(getLexer().is(AsmToken::Integer)) {
1821 // Parse memory broadcasting ({1to<NUM>}).
1822 if (getLexer().getTok().getIntVal() != 1)
1823 return !ErrorAndEatStatement(getLexer().getLoc(),
1824 "Expected 1to<NUM> at this point");
1825 Parser.Lex(); // Eat "1" of 1to8
1826 if (!getLexer().is(AsmToken::Identifier) ||
1827 !getLexer().getTok().getIdentifier().startswith("to"))
1828 return !ErrorAndEatStatement(getLexer().getLoc(),
1829 "Expected 1to<NUM> at this point");
1830 // Recognize only reasonable suffixes.
1831 const char *BroadcastPrimitive =
1832 StringSwitch<const char*>(getLexer().getTok().getIdentifier())
1833 .Case("to2", "{1to2}")
1834 .Case("to4", "{1to4}")
1835 .Case("to8", "{1to8}")
1836 .Case("to16", "{1to16}")
1838 if (!BroadcastPrimitive)
1839 return !ErrorAndEatStatement(getLexer().getLoc(),
1840 "Invalid memory broadcast primitive.");
1841 Parser.Lex(); // Eat "toN" of 1toN
1842 if (!getLexer().is(AsmToken::RCurly))
1843 return !ErrorAndEatStatement(getLexer().getLoc(),
1844 "Expected } at this point");
1845 Parser.Lex(); // Eat "}"
1846 Operands.push_back(X86Operand::CreateToken(BroadcastPrimitive,
1848 // No AVX512 specific primitives can pass
1849 // after memory broadcasting, so return.
1852 // Parse mask register {%k1}
1853 Operands.push_back(X86Operand::CreateToken("{", consumedToken));
1854 if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
1855 Operands.push_back(std::move(Op));
1856 if (!getLexer().is(AsmToken::RCurly))
1857 return !ErrorAndEatStatement(getLexer().getLoc(),
1858 "Expected } at this point");
1859 Operands.push_back(X86Operand::CreateToken("}", consumeToken()));
1861 // Parse "zeroing non-masked" semantic {z}
1862 if (getLexer().is(AsmToken::LCurly)) {
1863 Operands.push_back(X86Operand::CreateToken("{z}", consumeToken()));
1864 if (!getLexer().is(AsmToken::Identifier) ||
1865 getLexer().getTok().getIdentifier() != "z")
1866 return !ErrorAndEatStatement(getLexer().getLoc(),
1867 "Expected z at this point");
1868 Parser.Lex(); // Eat the z
1869 if (!getLexer().is(AsmToken::RCurly))
1870 return !ErrorAndEatStatement(getLexer().getLoc(),
1871 "Expected } at this point");
1872 Parser.Lex(); // Eat the }
1881 /// ParseMemOperand: segment: disp(basereg, indexreg, scale). The '%ds:' prefix
1882 /// has already been parsed if present.
1883 std::unique_ptr<X86Operand> X86AsmParser::ParseMemOperand(unsigned SegReg,
1886 MCAsmParser &Parser = getParser();
1887 // We have to disambiguate a parenthesized expression "(4+5)" from the start
1888 // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)". The
1889 // only way to do this without lookahead is to eat the '(' and see what is
1891 const MCExpr *Disp = MCConstantExpr::create(0, getParser().getContext());
1892 if (getLexer().isNot(AsmToken::LParen)) {
1894 if (getParser().parseExpression(Disp, ExprEnd)) return nullptr;
1896 // After parsing the base expression we could either have a parenthesized
1897 // memory address or not. If not, return now. If so, eat the (.
1898 if (getLexer().isNot(AsmToken::LParen)) {
1899 // Unless we have a segment register, treat this as an immediate.
1901 return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, ExprEnd);
1902 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
1909 // Okay, we have a '('. We don't know if this is an expression or not, but
1910 // so we have to eat the ( to see beyond it.
1911 SMLoc LParenLoc = Parser.getTok().getLoc();
1912 Parser.Lex(); // Eat the '('.
1914 if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) {
1915 // Nothing to do here, fall into the code below with the '(' part of the
1916 // memory operand consumed.
1920 // It must be an parenthesized expression, parse it now.
1921 if (getParser().parseParenExpression(Disp, ExprEnd))
1924 // After parsing the base expression we could either have a parenthesized
1925 // memory address or not. If not, return now. If so, eat the (.
1926 if (getLexer().isNot(AsmToken::LParen)) {
1927 // Unless we have a segment register, treat this as an immediate.
1929 return X86Operand::CreateMem(getPointerWidth(), Disp, LParenLoc,
1931 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
1940 // If we reached here, then we just ate the ( of the memory operand. Process
1941 // the rest of the memory operand.
1942 unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
1943 SMLoc IndexLoc, BaseLoc;
1945 if (getLexer().is(AsmToken::Percent)) {
1946 SMLoc StartLoc, EndLoc;
1947 BaseLoc = Parser.getTok().getLoc();
1948 if (ParseRegister(BaseReg, StartLoc, EndLoc)) return nullptr;
1949 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) {
1950 Error(StartLoc, "eiz and riz can only be used as index registers",
1951 SMRange(StartLoc, EndLoc));
1956 if (getLexer().is(AsmToken::Comma)) {
1957 Parser.Lex(); // Eat the comma.
1958 IndexLoc = Parser.getTok().getLoc();
1960 // Following the comma we should have either an index register, or a scale
1961 // value. We don't support the later form, but we want to parse it
1964 // Not that even though it would be completely consistent to support syntax
1965 // like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this.
1966 if (getLexer().is(AsmToken::Percent)) {
1968 if (ParseRegister(IndexReg, L, L)) return nullptr;
1970 if (getLexer().isNot(AsmToken::RParen)) {
1971 // Parse the scale amount:
1972 // ::= ',' [scale-expression]
1973 if (getLexer().isNot(AsmToken::Comma)) {
1974 Error(Parser.getTok().getLoc(),
1975 "expected comma in scale expression");
1978 Parser.Lex(); // Eat the comma.
1980 if (getLexer().isNot(AsmToken::RParen)) {
1981 SMLoc Loc = Parser.getTok().getLoc();
1984 if (getParser().parseAbsoluteExpression(ScaleVal)){
1985 Error(Loc, "expected scale expression");
1989 // Validate the scale amount.
1990 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
1992 Error(Loc, "scale factor in 16-bit address must be 1");
1995 if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 &&
1997 Error(Loc, "scale factor in address must be 1, 2, 4 or 8");
2000 Scale = (unsigned)ScaleVal;
2003 } else if (getLexer().isNot(AsmToken::RParen)) {
2004 // A scale amount without an index is ignored.
2006 SMLoc Loc = Parser.getTok().getLoc();
2009 if (getParser().parseAbsoluteExpression(Value))
2013 Warning(Loc, "scale factor without index register is ignored");
2018 // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
2019 if (getLexer().isNot(AsmToken::RParen)) {
2020 Error(Parser.getTok().getLoc(), "unexpected token in memory operand");
2023 SMLoc MemEnd = Parser.getTok().getEndLoc();
2024 Parser.Lex(); // Eat the ')'.
2026 // Check for use of invalid 16-bit registers. Only BX/BP/SI/DI are allowed,
2027 // and then only in non-64-bit modes. Except for DX, which is a special case
2028 // because an unofficial form of in/out instructions uses it.
2029 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
2030 (is64BitMode() || (BaseReg != X86::BX && BaseReg != X86::BP &&
2031 BaseReg != X86::SI && BaseReg != X86::DI)) &&
2032 BaseReg != X86::DX) {
2033 Error(BaseLoc, "invalid 16-bit base register");
2037 X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg)) {
2038 Error(IndexLoc, "16-bit memory operand may not include only index register");
2043 if (CheckBaseRegAndIndexReg(BaseReg, IndexReg, ErrMsg)) {
2044 Error(BaseLoc, ErrMsg);
2048 if (SegReg || BaseReg || IndexReg)
2049 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
2050 IndexReg, Scale, MemStart, MemEnd);
2051 return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, MemEnd);
2054 bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2055 SMLoc NameLoc, OperandVector &Operands) {
2056 MCAsmParser &Parser = getParser();
2058 StringRef PatchedName = Name;
2060 // FIXME: Hack to recognize setneb as setne.
2061 if (PatchedName.startswith("set") && PatchedName.endswith("b") &&
2062 PatchedName != "setb" && PatchedName != "setnb")
2063 PatchedName = PatchedName.substr(0, Name.size()-1);
2065 // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}.
2066 if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) &&
2067 (PatchedName.endswith("ss") || PatchedName.endswith("sd") ||
2068 PatchedName.endswith("ps") || PatchedName.endswith("pd"))) {
2069 bool IsVCMP = PatchedName[0] == 'v';
2070 unsigned CCIdx = IsVCMP ? 4 : 3;
2071 unsigned ComparisonCode = StringSwitch<unsigned>(
2072 PatchedName.slice(CCIdx, PatchedName.size() - 2))
2076 .Case("unord", 0x03)
2081 /* AVX only from here */
2082 .Case("eq_uq", 0x08)
2085 .Case("false", 0x0B)
2086 .Case("neq_oq", 0x0C)
2090 .Case("eq_os", 0x10)
2091 .Case("lt_oq", 0x11)
2092 .Case("le_oq", 0x12)
2093 .Case("unord_s", 0x13)
2094 .Case("neq_us", 0x14)
2095 .Case("nlt_uq", 0x15)
2096 .Case("nle_uq", 0x16)
2097 .Case("ord_s", 0x17)
2098 .Case("eq_us", 0x18)
2099 .Case("nge_uq", 0x19)
2100 .Case("ngt_uq", 0x1A)
2101 .Case("false_os", 0x1B)
2102 .Case("neq_os", 0x1C)
2103 .Case("ge_oq", 0x1D)
2104 .Case("gt_oq", 0x1E)
2105 .Case("true_us", 0x1F)
2107 if (ComparisonCode != ~0U && (IsVCMP || ComparisonCode < 8)) {
2109 Operands.push_back(X86Operand::CreateToken(PatchedName.slice(0, CCIdx),
2112 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2113 getParser().getContext());
2114 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2116 PatchedName = PatchedName.substr(PatchedName.size() - 2);
2120 // FIXME: Hack to recognize vpcmp<comparison code>{ub,uw,ud,uq,b,w,d,q}.
2121 if (PatchedName.startswith("vpcmp") &&
2122 (PatchedName.endswith("b") || PatchedName.endswith("w") ||
2123 PatchedName.endswith("d") || PatchedName.endswith("q"))) {
2124 unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1;
2125 unsigned ComparisonCode = StringSwitch<unsigned>(
2126 PatchedName.slice(5, PatchedName.size() - CCIdx))
2127 .Case("eq", 0x0) // Only allowed on unsigned. Checked below.
2130 //.Case("false", 0x3) // Not a documented alias.
2134 //.Case("true", 0x7) // Not a documented alias.
2136 if (ComparisonCode != ~0U && (ComparisonCode != 0 || CCIdx == 2)) {
2137 Operands.push_back(X86Operand::CreateToken("vpcmp", NameLoc));
2139 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2140 getParser().getContext());
2141 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2143 PatchedName = PatchedName.substr(PatchedName.size() - CCIdx);
2147 // FIXME: Hack to recognize vpcom<comparison code>{ub,uw,ud,uq,b,w,d,q}.
2148 if (PatchedName.startswith("vpcom") &&
2149 (PatchedName.endswith("b") || PatchedName.endswith("w") ||
2150 PatchedName.endswith("d") || PatchedName.endswith("q"))) {
2151 unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1;
2152 unsigned ComparisonCode = StringSwitch<unsigned>(
2153 PatchedName.slice(5, PatchedName.size() - CCIdx))
2163 if (ComparisonCode != ~0U) {
2164 Operands.push_back(X86Operand::CreateToken("vpcom", NameLoc));
2166 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2167 getParser().getContext());
2168 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2170 PatchedName = PatchedName.substr(PatchedName.size() - CCIdx);
2174 Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
2176 // Determine whether this is an instruction prefix.
2178 Name == "lock" || Name == "rep" ||
2179 Name == "repe" || Name == "repz" ||
2180 Name == "repne" || Name == "repnz" ||
2181 Name == "rex64" || Name == "data16";
2183 // This does the actual operand parsing. Don't parse any more if we have a
2184 // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we
2185 // just want to parse the "lock" as the first instruction and the "incl" as
2187 if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) {
2189 // Parse '*' modifier.
2190 if (getLexer().is(AsmToken::Star))
2191 Operands.push_back(X86Operand::CreateToken("*", consumeToken()));
2193 // Read the operands.
2195 if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
2196 Operands.push_back(std::move(Op));
2197 if (!HandleAVX512Operand(Operands, *Operands.back()))
2200 Parser.eatToEndOfStatement();
2203 // check for comma and eat it
2204 if (getLexer().is(AsmToken::Comma))
2210 if (getLexer().isNot(AsmToken::EndOfStatement))
2211 return ErrorAndEatStatement(getLexer().getLoc(),
2212 "unexpected token in argument list");
2215 // Consume the EndOfStatement or the prefix separator Slash
2216 if (getLexer().is(AsmToken::EndOfStatement) ||
2217 (isPrefix && getLexer().is(AsmToken::Slash)))
2220 // This is for gas compatibility and cannot be done in td.
2221 // Adding "p" for some floating point with no argument.
2222 // For example: fsub --> fsubp
2224 Name == "fsub" || Name == "fdiv" || Name == "fsubr" || Name == "fdivr";
2225 if (IsFp && Operands.size() == 1) {
2226 const char *Repl = StringSwitch<const char *>(Name)
2227 .Case("fsub", "fsubp")
2228 .Case("fdiv", "fdivp")
2229 .Case("fsubr", "fsubrp")
2230 .Case("fdivr", "fdivrp");
2231 static_cast<X86Operand &>(*Operands[0]).setTokenValue(Repl);
2234 // This is a terrible hack to handle "out[bwl]? %al, (%dx)" ->
2235 // "outb %al, %dx". Out doesn't take a memory form, but this is a widely
2236 // documented form in various unofficial manuals, so a lot of code uses it.
2237 if ((Name == "outb" || Name == "outw" || Name == "outl" || Name == "out") &&
2238 Operands.size() == 3) {
2239 X86Operand &Op = (X86Operand &)*Operands.back();
2240 if (Op.isMem() && Op.Mem.SegReg == 0 &&
2241 isa<MCConstantExpr>(Op.Mem.Disp) &&
2242 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
2243 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
2244 SMLoc Loc = Op.getEndLoc();
2245 Operands.back() = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
2248 // Same hack for "in[bwl]? (%dx), %al" -> "inb %dx, %al".
2249 if ((Name == "inb" || Name == "inw" || Name == "inl" || Name == "in") &&
2250 Operands.size() == 3) {
2251 X86Operand &Op = (X86Operand &)*Operands[1];
2252 if (Op.isMem() && Op.Mem.SegReg == 0 &&
2253 isa<MCConstantExpr>(Op.Mem.Disp) &&
2254 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
2255 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
2256 SMLoc Loc = Op.getEndLoc();
2257 Operands[1] = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
2261 // Append default arguments to "ins[bwld]"
2262 if (Name.startswith("ins") && Operands.size() == 1 &&
2263 (Name == "insb" || Name == "insw" || Name == "insl" || Name == "insd")) {
2264 AddDefaultSrcDestOperands(Operands,
2265 X86Operand::CreateReg(X86::DX, NameLoc, NameLoc),
2266 DefaultMemDIOperand(NameLoc));
2269 // Append default arguments to "outs[bwld]"
2270 if (Name.startswith("outs") && Operands.size() == 1 &&
2271 (Name == "outsb" || Name == "outsw" || Name == "outsl" ||
2272 Name == "outsd" )) {
2273 AddDefaultSrcDestOperands(Operands,
2274 DefaultMemSIOperand(NameLoc),
2275 X86Operand::CreateReg(X86::DX, NameLoc, NameLoc));
2278 // Transform "lods[bwlq]" into "lods[bwlq] ($SIREG)" for appropriate
2279 // values of $SIREG according to the mode. It would be nice if this
2280 // could be achieved with InstAlias in the tables.
2281 if (Name.startswith("lods") && Operands.size() == 1 &&
2282 (Name == "lods" || Name == "lodsb" || Name == "lodsw" ||
2283 Name == "lodsl" || Name == "lodsd" || Name == "lodsq"))
2284 Operands.push_back(DefaultMemSIOperand(NameLoc));
2286 // Transform "stos[bwlq]" into "stos[bwlq] ($DIREG)" for appropriate
2287 // values of $DIREG according to the mode. It would be nice if this
2288 // could be achieved with InstAlias in the tables.
2289 if (Name.startswith("stos") && Operands.size() == 1 &&
2290 (Name == "stos" || Name == "stosb" || Name == "stosw" ||
2291 Name == "stosl" || Name == "stosd" || Name == "stosq"))
2292 Operands.push_back(DefaultMemDIOperand(NameLoc));
2294 // Transform "scas[bwlq]" into "scas[bwlq] ($DIREG)" for appropriate
2295 // values of $DIREG according to the mode. It would be nice if this
2296 // could be achieved with InstAlias in the tables.
2297 if (Name.startswith("scas") && Operands.size() == 1 &&
2298 (Name == "scas" || Name == "scasb" || Name == "scasw" ||
2299 Name == "scasl" || Name == "scasd" || Name == "scasq"))
2300 Operands.push_back(DefaultMemDIOperand(NameLoc));
2302 // Add default SI and DI operands to "cmps[bwlq]".
2303 if (Name.startswith("cmps") &&
2304 (Name == "cmps" || Name == "cmpsb" || Name == "cmpsw" ||
2305 Name == "cmpsl" || Name == "cmpsd" || Name == "cmpsq")) {
2306 if (Operands.size() == 1) {
2307 AddDefaultSrcDestOperands(Operands,
2308 DefaultMemDIOperand(NameLoc),
2309 DefaultMemSIOperand(NameLoc));
2310 } else if (Operands.size() == 3) {
2311 X86Operand &Op = (X86Operand &)*Operands[1];
2312 X86Operand &Op2 = (X86Operand &)*Operands[2];
2313 if (!doSrcDstMatch(Op, Op2))
2314 return Error(Op.getStartLoc(),
2315 "mismatching source and destination index registers");
2319 // Add default SI and DI operands to "movs[bwlq]".
2320 if ((Name.startswith("movs") &&
2321 (Name == "movs" || Name == "movsb" || Name == "movsw" ||
2322 Name == "movsl" || Name == "movsd" || Name == "movsq")) ||
2323 (Name.startswith("smov") &&
2324 (Name == "smov" || Name == "smovb" || Name == "smovw" ||
2325 Name == "smovl" || Name == "smovd" || Name == "smovq"))) {
2326 if (Operands.size() == 1) {
2327 if (Name == "movsd")
2328 Operands.back() = X86Operand::CreateToken("movsl", NameLoc);
2329 AddDefaultSrcDestOperands(Operands,
2330 DefaultMemSIOperand(NameLoc),
2331 DefaultMemDIOperand(NameLoc));
2332 } else if (Operands.size() == 3) {
2333 X86Operand &Op = (X86Operand &)*Operands[1];
2334 X86Operand &Op2 = (X86Operand &)*Operands[2];
2335 if (!doSrcDstMatch(Op, Op2))
2336 return Error(Op.getStartLoc(),
2337 "mismatching source and destination index registers");
2341 // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>. Canonicalize to
2343 if ((Name.startswith("shr") || Name.startswith("sar") ||
2344 Name.startswith("shl") || Name.startswith("sal") ||
2345 Name.startswith("rcl") || Name.startswith("rcr") ||
2346 Name.startswith("rol") || Name.startswith("ror")) &&
2347 Operands.size() == 3) {
2348 if (isParsingIntelSyntax()) {
2350 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[2]);
2351 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2352 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2353 Operands.pop_back();
2355 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2356 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2357 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2358 Operands.erase(Operands.begin() + 1);
2362 // Transforms "int $3" into "int3" as a size optimization. We can't write an
2363 // instalias with an immediate operand yet.
2364 if (Name == "int" && Operands.size() == 2) {
2365 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2367 if (auto *CE = dyn_cast<MCConstantExpr>(Op1.getImm()))
2368 if (CE->getValue() == 3) {
2369 Operands.erase(Operands.begin() + 1);
2370 static_cast<X86Operand &>(*Operands[0]).setTokenValue("int3");
2377 bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) {
2378 switch (Inst.getOpcode()) {
2379 default: return false;
2380 case X86::VMOVZPQILo2PQIrr:
2381 case X86::VMOVAPDrr:
2382 case X86::VMOVAPDYrr:
2383 case X86::VMOVAPSrr:
2384 case X86::VMOVAPSYrr:
2385 case X86::VMOVDQArr:
2386 case X86::VMOVDQAYrr:
2387 case X86::VMOVDQUrr:
2388 case X86::VMOVDQUYrr:
2389 case X86::VMOVUPDrr:
2390 case X86::VMOVUPDYrr:
2391 case X86::VMOVUPSrr:
2392 case X86::VMOVUPSYrr: {
2393 if (X86II::isX86_64ExtendedReg(Inst.getOperand(0).getReg()) ||
2394 !X86II::isX86_64ExtendedReg(Inst.getOperand(1).getReg()))
2398 switch (Inst.getOpcode()) {
2399 default: llvm_unreachable("Invalid opcode");
2400 case X86::VMOVZPQILo2PQIrr: NewOpc = X86::VMOVPQI2QIrr; break;
2401 case X86::VMOVAPDrr: NewOpc = X86::VMOVAPDrr_REV; break;
2402 case X86::VMOVAPDYrr: NewOpc = X86::VMOVAPDYrr_REV; break;
2403 case X86::VMOVAPSrr: NewOpc = X86::VMOVAPSrr_REV; break;
2404 case X86::VMOVAPSYrr: NewOpc = X86::VMOVAPSYrr_REV; break;
2405 case X86::VMOVDQArr: NewOpc = X86::VMOVDQArr_REV; break;
2406 case X86::VMOVDQAYrr: NewOpc = X86::VMOVDQAYrr_REV; break;
2407 case X86::VMOVDQUrr: NewOpc = X86::VMOVDQUrr_REV; break;
2408 case X86::VMOVDQUYrr: NewOpc = X86::VMOVDQUYrr_REV; break;
2409 case X86::VMOVUPDrr: NewOpc = X86::VMOVUPDrr_REV; break;
2410 case X86::VMOVUPDYrr: NewOpc = X86::VMOVUPDYrr_REV; break;
2411 case X86::VMOVUPSrr: NewOpc = X86::VMOVUPSrr_REV; break;
2412 case X86::VMOVUPSYrr: NewOpc = X86::VMOVUPSYrr_REV; break;
2414 Inst.setOpcode(NewOpc);
2418 case X86::VMOVSSrr: {
2419 if (X86II::isX86_64ExtendedReg(Inst.getOperand(0).getReg()) ||
2420 !X86II::isX86_64ExtendedReg(Inst.getOperand(2).getReg()))
2423 switch (Inst.getOpcode()) {
2424 default: llvm_unreachable("Invalid opcode");
2425 case X86::VMOVSDrr: NewOpc = X86::VMOVSDrr_REV; break;
2426 case X86::VMOVSSrr: NewOpc = X86::VMOVSSrr_REV; break;
2428 Inst.setOpcode(NewOpc);
2434 static const char *getSubtargetFeatureName(uint64_t Val);
2436 void X86AsmParser::EmitInstruction(MCInst &Inst, OperandVector &Operands,
2438 Instrumentation->InstrumentAndEmitInstruction(Inst, Operands, getContext(),
2442 bool X86AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2443 OperandVector &Operands,
2444 MCStreamer &Out, uint64_t &ErrorInfo,
2445 bool MatchingInlineAsm) {
2446 if (isParsingIntelSyntax())
2447 return MatchAndEmitIntelInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2449 return MatchAndEmitATTInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2453 void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op,
2454 OperandVector &Operands, MCStreamer &Out,
2455 bool MatchingInlineAsm) {
2456 // FIXME: This should be replaced with a real .td file alias mechanism.
2457 // Also, MatchInstructionImpl should actually *do* the EmitInstruction
2459 const char *Repl = StringSwitch<const char *>(Op.getToken())
2460 .Case("finit", "fninit")
2461 .Case("fsave", "fnsave")
2462 .Case("fstcw", "fnstcw")
2463 .Case("fstcww", "fnstcw")
2464 .Case("fstenv", "fnstenv")
2465 .Case("fstsw", "fnstsw")
2466 .Case("fstsww", "fnstsw")
2467 .Case("fclex", "fnclex")
2471 Inst.setOpcode(X86::WAIT);
2473 if (!MatchingInlineAsm)
2474 EmitInstruction(Inst, Operands, Out);
2475 Operands[0] = X86Operand::CreateToken(Repl, IDLoc);
2479 bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
2480 bool MatchingInlineAsm) {
2481 assert(ErrorInfo && "Unknown missing feature!");
2482 ArrayRef<SMRange> EmptyRanges = None;
2483 SmallString<126> Msg;
2484 raw_svector_ostream OS(Msg);
2485 OS << "instruction requires:";
2487 for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
2488 if (ErrorInfo & Mask)
2489 OS << ' ' << getSubtargetFeatureName(ErrorInfo & Mask);
2492 return Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
2495 bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
2496 OperandVector &Operands,
2498 uint64_t &ErrorInfo,
2499 bool MatchingInlineAsm) {
2500 assert(!Operands.empty() && "Unexpect empty operand list!");
2501 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2502 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
2503 ArrayRef<SMRange> EmptyRanges = None;
2505 // First, handle aliases that expand to multiple instructions.
2506 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2508 bool WasOriginallyInvalidOperand = false;
2511 // First, try a direct match.
2512 switch (MatchInstructionImpl(Operands, Inst,
2513 ErrorInfo, MatchingInlineAsm,
2514 isParsingIntelSyntax())) {
2515 default: llvm_unreachable("Unexpected match result!");
2517 // Some instructions need post-processing to, for example, tweak which
2518 // encoding is selected. Loop on it while changes happen so the
2519 // individual transformations can chain off each other.
2520 if (!MatchingInlineAsm)
2521 while (processInstruction(Inst, Operands))
2525 if (!MatchingInlineAsm)
2526 EmitInstruction(Inst, Operands, Out);
2527 Opcode = Inst.getOpcode();
2529 case Match_MissingFeature:
2530 return ErrorMissingFeature(IDLoc, ErrorInfo, MatchingInlineAsm);
2531 case Match_InvalidOperand:
2532 WasOriginallyInvalidOperand = true;
2534 case Match_MnemonicFail:
2538 // FIXME: Ideally, we would only attempt suffix matches for things which are
2539 // valid prefixes, and we could just infer the right unambiguous
2540 // type. However, that requires substantially more matcher support than the
2543 // Change the operand to point to a temporary token.
2544 StringRef Base = Op.getToken();
2545 SmallString<16> Tmp;
2548 Op.setTokenValue(Tmp);
2550 // If this instruction starts with an 'f', then it is a floating point stack
2551 // instruction. These come in up to three forms for 32-bit, 64-bit, and
2552 // 80-bit floating point, which use the suffixes s,l,t respectively.
2554 // Otherwise, we assume that this may be an integer instruction, which comes
2555 // in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively.
2556 const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0";
2558 // Check for the various suffix matches.
2559 uint64_t ErrorInfoIgnore;
2560 uint64_t ErrorInfoMissingFeature = 0; // Init suppresses compiler warnings.
2563 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I) {
2564 Tmp.back() = Suffixes[I];
2565 Match[I] = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
2566 MatchingInlineAsm, isParsingIntelSyntax());
2567 // If this returned as a missing feature failure, remember that.
2568 if (Match[I] == Match_MissingFeature)
2569 ErrorInfoMissingFeature = ErrorInfoIgnore;
2572 // Restore the old token.
2573 Op.setTokenValue(Base);
2575 // If exactly one matched, then we treat that as a successful match (and the
2576 // instruction will already have been filled in correctly, since the failing
2577 // matches won't have modified it).
2578 unsigned NumSuccessfulMatches =
2579 std::count(std::begin(Match), std::end(Match), Match_Success);
2580 if (NumSuccessfulMatches == 1) {
2582 if (!MatchingInlineAsm)
2583 EmitInstruction(Inst, Operands, Out);
2584 Opcode = Inst.getOpcode();
2588 // Otherwise, the match failed, try to produce a decent error message.
2590 // If we had multiple suffix matches, then identify this as an ambiguous
2592 if (NumSuccessfulMatches > 1) {
2594 unsigned NumMatches = 0;
2595 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I)
2596 if (Match[I] == Match_Success)
2597 MatchChars[NumMatches++] = Suffixes[I];
2599 SmallString<126> Msg;
2600 raw_svector_ostream OS(Msg);
2601 OS << "ambiguous instructions require an explicit suffix (could be ";
2602 for (unsigned i = 0; i != NumMatches; ++i) {
2605 if (i + 1 == NumMatches)
2607 OS << "'" << Base << MatchChars[i] << "'";
2610 Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
2614 // Okay, we know that none of the variants matched successfully.
2616 // If all of the instructions reported an invalid mnemonic, then the original
2617 // mnemonic was invalid.
2618 if (std::count(std::begin(Match), std::end(Match), Match_MnemonicFail) == 4) {
2619 if (!WasOriginallyInvalidOperand) {
2620 ArrayRef<SMRange> Ranges =
2621 MatchingInlineAsm ? EmptyRanges : Op.getLocRange();
2622 return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'",
2623 Ranges, MatchingInlineAsm);
2626 // Recover location info for the operand if we know which was the problem.
2627 if (ErrorInfo != ~0ULL) {
2628 if (ErrorInfo >= Operands.size())
2629 return Error(IDLoc, "too few operands for instruction",
2630 EmptyRanges, MatchingInlineAsm);
2632 X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo];
2633 if (Operand.getStartLoc().isValid()) {
2634 SMRange OperandRange = Operand.getLocRange();
2635 return Error(Operand.getStartLoc(), "invalid operand for instruction",
2636 OperandRange, MatchingInlineAsm);
2640 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2644 // If one instruction matched with a missing feature, report this as a
2646 if (std::count(std::begin(Match), std::end(Match),
2647 Match_MissingFeature) == 1) {
2648 ErrorInfo = ErrorInfoMissingFeature;
2649 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
2653 // If one instruction matched with an invalid operand, report this as an
2655 if (std::count(std::begin(Match), std::end(Match),
2656 Match_InvalidOperand) == 1) {
2657 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2661 // If all of these were an outright failure, report it in a useless way.
2662 Error(IDLoc, "unknown use of instruction mnemonic without a size suffix",
2663 EmptyRanges, MatchingInlineAsm);
2667 bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
2668 OperandVector &Operands,
2670 uint64_t &ErrorInfo,
2671 bool MatchingInlineAsm) {
2672 assert(!Operands.empty() && "Unexpect empty operand list!");
2673 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2674 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
2675 StringRef Mnemonic = Op.getToken();
2676 ArrayRef<SMRange> EmptyRanges = None;
2678 // First, handle aliases that expand to multiple instructions.
2679 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2683 // Find one unsized memory operand, if present.
2684 X86Operand *UnsizedMemOp = nullptr;
2685 for (const auto &Op : Operands) {
2686 X86Operand *X86Op = static_cast<X86Operand *>(Op.get());
2687 if (X86Op->isMemUnsized())
2688 UnsizedMemOp = X86Op;
2691 // Allow some instructions to have implicitly pointer-sized operands. This is
2692 // compatible with gas.
2694 static const char *const PtrSizedInstrs[] = {"call", "jmp", "push"};
2695 for (const char *Instr : PtrSizedInstrs) {
2696 if (Mnemonic == Instr) {
2697 UnsizedMemOp->Mem.Size = getPointerWidth();
2703 // If an unsized memory operand is present, try to match with each memory
2704 // operand size. In Intel assembly, the size is not part of the instruction
2706 SmallVector<unsigned, 8> Match;
2707 uint64_t ErrorInfoMissingFeature = 0;
2708 if (UnsizedMemOp && UnsizedMemOp->isMemUnsized()) {
2709 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
2710 for (unsigned Size : MopSizes) {
2711 UnsizedMemOp->Mem.Size = Size;
2712 uint64_t ErrorInfoIgnore;
2713 unsigned LastOpcode = Inst.getOpcode();
2715 MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
2716 MatchingInlineAsm, isParsingIntelSyntax());
2717 if (Match.empty() || LastOpcode != Inst.getOpcode())
2720 // If this returned as a missing feature failure, remember that.
2721 if (Match.back() == Match_MissingFeature)
2722 ErrorInfoMissingFeature = ErrorInfoIgnore;
2725 // Restore the size of the unsized memory operand if we modified it.
2727 UnsizedMemOp->Mem.Size = 0;
2730 // If we haven't matched anything yet, this is not a basic integer or FPU
2731 // operation. There shouldn't be any ambiguity in our mnemonic table, so try
2732 // matching with the unsized operand.
2733 if (Match.empty()) {
2734 Match.push_back(MatchInstructionImpl(Operands, Inst, ErrorInfo,
2736 isParsingIntelSyntax()));
2737 // If this returned as a missing feature failure, remember that.
2738 if (Match.back() == Match_MissingFeature)
2739 ErrorInfoMissingFeature = ErrorInfo;
2742 // Restore the size of the unsized memory operand if we modified it.
2744 UnsizedMemOp->Mem.Size = 0;
2746 // If it's a bad mnemonic, all results will be the same.
2747 if (Match.back() == Match_MnemonicFail) {
2748 ArrayRef<SMRange> Ranges =
2749 MatchingInlineAsm ? EmptyRanges : Op.getLocRange();
2750 return Error(IDLoc, "invalid instruction mnemonic '" + Mnemonic + "'",
2751 Ranges, MatchingInlineAsm);
2754 // If exactly one matched, then we treat that as a successful match (and the
2755 // instruction will already have been filled in correctly, since the failing
2756 // matches won't have modified it).
2757 unsigned NumSuccessfulMatches =
2758 std::count(std::begin(Match), std::end(Match), Match_Success);
2759 if (NumSuccessfulMatches == 1) {
2760 // Some instructions need post-processing to, for example, tweak which
2761 // encoding is selected. Loop on it while changes happen so the individual
2762 // transformations can chain off each other.
2763 if (!MatchingInlineAsm)
2764 while (processInstruction(Inst, Operands))
2767 if (!MatchingInlineAsm)
2768 EmitInstruction(Inst, Operands, Out);
2769 Opcode = Inst.getOpcode();
2771 } else if (NumSuccessfulMatches > 1) {
2772 assert(UnsizedMemOp &&
2773 "multiple matches only possible with unsized memory operands");
2774 ArrayRef<SMRange> Ranges =
2775 MatchingInlineAsm ? EmptyRanges : UnsizedMemOp->getLocRange();
2776 return Error(UnsizedMemOp->getStartLoc(),
2777 "ambiguous operand size for instruction '" + Mnemonic + "\'",
2778 Ranges, MatchingInlineAsm);
2781 // If one instruction matched with a missing feature, report this as a
2783 if (std::count(std::begin(Match), std::end(Match),
2784 Match_MissingFeature) == 1) {
2785 ErrorInfo = ErrorInfoMissingFeature;
2786 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
2790 // If one instruction matched with an invalid operand, report this as an
2792 if (std::count(std::begin(Match), std::end(Match),
2793 Match_InvalidOperand) == 1) {
2794 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2798 // If all of these were an outright failure, report it in a useless way.
2799 return Error(IDLoc, "unknown instruction mnemonic", EmptyRanges,
2803 bool X86AsmParser::OmitRegisterFromClobberLists(unsigned RegNo) {
2804 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo);
2807 bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
2808 MCAsmParser &Parser = getParser();
2809 StringRef IDVal = DirectiveID.getIdentifier();
2810 if (IDVal == ".word")
2811 return ParseDirectiveWord(2, DirectiveID.getLoc());
2812 else if (IDVal.startswith(".code"))
2813 return ParseDirectiveCode(IDVal, DirectiveID.getLoc());
2814 else if (IDVal.startswith(".att_syntax")) {
2815 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2816 if (Parser.getTok().getString() == "prefix")
2818 else if (Parser.getTok().getString() == "noprefix")
2819 return Error(DirectiveID.getLoc(), "'.att_syntax noprefix' is not "
2820 "supported: registers must have a "
2821 "'%' prefix in .att_syntax");
2823 getParser().setAssemblerDialect(0);
2825 } else if (IDVal.startswith(".intel_syntax")) {
2826 getParser().setAssemblerDialect(1);
2827 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2828 if (Parser.getTok().getString() == "noprefix")
2830 else if (Parser.getTok().getString() == "prefix")
2831 return Error(DirectiveID.getLoc(), "'.intel_syntax prefix' is not "
2832 "supported: registers must not have "
2833 "a '%' prefix in .intel_syntax");
2840 /// ParseDirectiveWord
2841 /// ::= .word [ expression (, expression)* ]
2842 bool X86AsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
2843 MCAsmParser &Parser = getParser();
2844 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2846 const MCExpr *Value;
2847 SMLoc ExprLoc = getLexer().getLoc();
2848 if (getParser().parseExpression(Value))
2851 if (const auto *MCE = dyn_cast<MCConstantExpr>(Value)) {
2852 assert(Size <= 8 && "Invalid size");
2853 uint64_t IntValue = MCE->getValue();
2854 if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))
2855 return Error(ExprLoc, "literal value out of range for directive");
2856 getStreamer().EmitIntValue(IntValue, Size);
2858 getStreamer().EmitValue(Value, Size, ExprLoc);
2861 if (getLexer().is(AsmToken::EndOfStatement))
2864 // FIXME: Improve diagnostic.
2865 if (getLexer().isNot(AsmToken::Comma)) {
2866 Error(L, "unexpected token in directive");
2877 /// ParseDirectiveCode
2878 /// ::= .code16 | .code32 | .code64
2879 bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
2880 MCAsmParser &Parser = getParser();
2881 if (IDVal == ".code16") {
2883 if (!is16BitMode()) {
2884 SwitchMode(X86::Mode16Bit);
2885 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
2887 } else if (IDVal == ".code32") {
2889 if (!is32BitMode()) {
2890 SwitchMode(X86::Mode32Bit);
2891 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
2893 } else if (IDVal == ".code64") {
2895 if (!is64BitMode()) {
2896 SwitchMode(X86::Mode64Bit);
2897 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code64);
2900 Error(L, "unknown directive " + IDVal);
2907 // Force static initialization.
2908 extern "C" void LLVMInitializeX86AsmParser() {
2909 RegisterMCAsmParser<X86AsmParser> X(TheX86_32Target);
2910 RegisterMCAsmParser<X86AsmParser> Y(TheX86_64Target);
2913 #define GET_REGISTER_MATCHER
2914 #define GET_MATCHER_IMPLEMENTATION
2915 #define GET_SUBTARGET_FEATURE_NAME
2916 #include "X86GenAsmMatcher.inc"