1 //===-- X86AsmParser.cpp - Parse X86 assembly to MCInst instructions ------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "MCTargetDesc/X86BaseInfo.h"
11 #include "X86AsmInstrumentation.h"
12 #include "X86AsmParserCommon.h"
13 #include "X86Operand.h"
14 #include "X86ISelLowering.h"
15 #include "llvm/ADT/APFloat.h"
16 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/ADT/SmallString.h"
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/ADT/StringSwitch.h"
20 #include "llvm/ADT/Twine.h"
21 #include "llvm/MC/MCContext.h"
22 #include "llvm/MC/MCExpr.h"
23 #include "llvm/MC/MCInst.h"
24 #include "llvm/MC/MCInstrInfo.h"
25 #include "llvm/MC/MCParser/MCAsmLexer.h"
26 #include "llvm/MC/MCParser/MCAsmParser.h"
27 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
28 #include "llvm/MC/MCRegisterInfo.h"
29 #include "llvm/MC/MCStreamer.h"
30 #include "llvm/MC/MCSubtargetInfo.h"
31 #include "llvm/MC/MCSymbol.h"
32 #include "llvm/MC/MCTargetAsmParser.h"
33 #include "llvm/Support/SourceMgr.h"
34 #include "llvm/Support/TargetRegistry.h"
35 #include "llvm/Support/raw_ostream.h"
43 static const char OpPrecedence[] = {
59 class X86AsmParser : public MCTargetAsmParser {
61 const MCInstrInfo &MII;
62 ParseInstructionInfo *InstInfo;
63 std::unique_ptr<X86AsmInstrumentation> Instrumentation;
66 SMLoc consumeToken() {
67 MCAsmParser &Parser = getParser();
68 SMLoc Result = Parser.getTok().getLoc();
73 enum InfixCalculatorTok {
89 class InfixCalculator {
90 typedef std::pair< InfixCalculatorTok, int64_t > ICToken;
91 SmallVector<InfixCalculatorTok, 4> InfixOperatorStack;
92 SmallVector<ICToken, 4> PostfixStack;
95 int64_t popOperand() {
96 assert (!PostfixStack.empty() && "Poped an empty stack!");
97 ICToken Op = PostfixStack.pop_back_val();
98 assert ((Op.first == IC_IMM || Op.first == IC_REGISTER)
99 && "Expected and immediate or register!");
102 void pushOperand(InfixCalculatorTok Op, int64_t Val = 0) {
103 assert ((Op == IC_IMM || Op == IC_REGISTER) &&
104 "Unexpected operand!");
105 PostfixStack.push_back(std::make_pair(Op, Val));
108 void popOperator() { InfixOperatorStack.pop_back(); }
109 void pushOperator(InfixCalculatorTok Op) {
110 // Push the new operator if the stack is empty.
111 if (InfixOperatorStack.empty()) {
112 InfixOperatorStack.push_back(Op);
116 // Push the new operator if it has a higher precedence than the operator
117 // on the top of the stack or the operator on the top of the stack is a
119 unsigned Idx = InfixOperatorStack.size() - 1;
120 InfixCalculatorTok StackOp = InfixOperatorStack[Idx];
121 if (OpPrecedence[Op] > OpPrecedence[StackOp] || StackOp == IC_LPAREN) {
122 InfixOperatorStack.push_back(Op);
126 // The operator on the top of the stack has higher precedence than the
128 unsigned ParenCount = 0;
130 // Nothing to process.
131 if (InfixOperatorStack.empty())
134 Idx = InfixOperatorStack.size() - 1;
135 StackOp = InfixOperatorStack[Idx];
136 if (!(OpPrecedence[StackOp] >= OpPrecedence[Op] || ParenCount))
139 // If we have an even parentheses count and we see a left parentheses,
140 // then stop processing.
141 if (!ParenCount && StackOp == IC_LPAREN)
144 if (StackOp == IC_RPAREN) {
146 InfixOperatorStack.pop_back();
147 } else if (StackOp == IC_LPAREN) {
149 InfixOperatorStack.pop_back();
151 InfixOperatorStack.pop_back();
152 PostfixStack.push_back(std::make_pair(StackOp, 0));
155 // Push the new operator.
156 InfixOperatorStack.push_back(Op);
160 // Push any remaining operators onto the postfix stack.
161 while (!InfixOperatorStack.empty()) {
162 InfixCalculatorTok StackOp = InfixOperatorStack.pop_back_val();
163 if (StackOp != IC_LPAREN && StackOp != IC_RPAREN)
164 PostfixStack.push_back(std::make_pair(StackOp, 0));
167 if (PostfixStack.empty())
170 SmallVector<ICToken, 16> OperandStack;
171 for (unsigned i = 0, e = PostfixStack.size(); i != e; ++i) {
172 ICToken Op = PostfixStack[i];
173 if (Op.first == IC_IMM || Op.first == IC_REGISTER) {
174 OperandStack.push_back(Op);
176 assert (OperandStack.size() > 1 && "Too few operands.");
178 ICToken Op2 = OperandStack.pop_back_val();
179 ICToken Op1 = OperandStack.pop_back_val();
182 report_fatal_error("Unexpected operator!");
185 Val = Op1.second + Op2.second;
186 OperandStack.push_back(std::make_pair(IC_IMM, Val));
189 Val = Op1.second - Op2.second;
190 OperandStack.push_back(std::make_pair(IC_IMM, Val));
193 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
194 "Multiply operation with an immediate and a register!");
195 Val = Op1.second * Op2.second;
196 OperandStack.push_back(std::make_pair(IC_IMM, Val));
199 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
200 "Divide operation with an immediate and a register!");
201 assert (Op2.second != 0 && "Division by zero!");
202 Val = Op1.second / Op2.second;
203 OperandStack.push_back(std::make_pair(IC_IMM, Val));
206 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
207 "Or operation with an immediate and a register!");
208 Val = Op1.second | Op2.second;
209 OperandStack.push_back(std::make_pair(IC_IMM, Val));
212 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
213 "Xor operation with an immediate and a register!");
214 Val = Op1.second ^ Op2.second;
215 OperandStack.push_back(std::make_pair(IC_IMM, Val));
218 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
219 "And operation with an immediate and a register!");
220 Val = Op1.second & Op2.second;
221 OperandStack.push_back(std::make_pair(IC_IMM, Val));
224 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
225 "Left shift operation with an immediate and a register!");
226 Val = Op1.second << Op2.second;
227 OperandStack.push_back(std::make_pair(IC_IMM, Val));
230 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
231 "Right shift operation with an immediate and a register!");
232 Val = Op1.second >> Op2.second;
233 OperandStack.push_back(std::make_pair(IC_IMM, Val));
238 assert (OperandStack.size() == 1 && "Expected a single result.");
239 return OperandStack.pop_back_val().second;
243 enum IntelExprState {
264 class IntelExprStateMachine {
265 IntelExprState State, PrevState;
266 unsigned BaseReg, IndexReg, TmpReg, Scale;
270 bool StopOnLBrac, AddImmPrefix;
272 InlineAsmIdentifierInfo Info;
275 IntelExprStateMachine(int64_t imm, bool stoponlbrac, bool addimmprefix) :
276 State(IES_PLUS), PrevState(IES_ERROR), BaseReg(0), IndexReg(0), TmpReg(0),
277 Scale(1), Imm(imm), Sym(nullptr), StopOnLBrac(stoponlbrac),
278 AddImmPrefix(addimmprefix) { Info.clear(); }
280 unsigned getBaseReg() { return BaseReg; }
281 unsigned getIndexReg() { return IndexReg; }
282 unsigned getScale() { return Scale; }
283 const MCExpr *getSym() { return Sym; }
284 StringRef getSymName() { return SymName; }
285 int64_t getImm() { return Imm + IC.execute(); }
286 bool isValidEndState() {
287 return State == IES_RBRAC || State == IES_INTEGER;
289 bool getStopOnLBrac() { return StopOnLBrac; }
290 bool getAddImmPrefix() { return AddImmPrefix; }
291 bool hadError() { return State == IES_ERROR; }
293 InlineAsmIdentifierInfo &getIdentifierInfo() {
298 IntelExprState CurrState = State;
307 IC.pushOperator(IC_OR);
310 PrevState = CurrState;
313 IntelExprState CurrState = State;
322 IC.pushOperator(IC_XOR);
325 PrevState = CurrState;
328 IntelExprState CurrState = State;
337 IC.pushOperator(IC_AND);
340 PrevState = CurrState;
343 IntelExprState CurrState = State;
352 IC.pushOperator(IC_LSHIFT);
355 PrevState = CurrState;
358 IntelExprState CurrState = State;
367 IC.pushOperator(IC_RSHIFT);
370 PrevState = CurrState;
373 IntelExprState CurrState = State;
382 IC.pushOperator(IC_PLUS);
383 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
384 // If we already have a BaseReg, then assume this is the IndexReg with
389 assert (!IndexReg && "BaseReg/IndexReg already set!");
396 PrevState = CurrState;
399 IntelExprState CurrState = State;
415 // Only push the minus operator if it is not a unary operator.
416 if (!(CurrState == IES_PLUS || CurrState == IES_MINUS ||
417 CurrState == IES_MULTIPLY || CurrState == IES_DIVIDE ||
418 CurrState == IES_LPAREN || CurrState == IES_LBRAC))
419 IC.pushOperator(IC_MINUS);
420 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
421 // If we already have a BaseReg, then assume this is the IndexReg with
426 assert (!IndexReg && "BaseReg/IndexReg already set!");
433 PrevState = CurrState;
436 IntelExprState CurrState = State;
446 PrevState = CurrState;
448 void onRegister(unsigned Reg) {
449 IntelExprState CurrState = State;
456 State = IES_REGISTER;
458 IC.pushOperand(IC_REGISTER);
461 // Index Register - Scale * Register
462 if (PrevState == IES_INTEGER) {
463 assert (!IndexReg && "IndexReg already set!");
464 State = IES_REGISTER;
466 // Get the scale and replace the 'Scale * Register' with '0'.
467 Scale = IC.popOperand();
468 IC.pushOperand(IC_IMM);
475 PrevState = CurrState;
477 void onIdentifierExpr(const MCExpr *SymRef, StringRef SymRefName) {
488 SymName = SymRefName;
489 IC.pushOperand(IC_IMM);
493 bool onInteger(int64_t TmpInt, StringRef &ErrMsg) {
494 IntelExprState CurrState = State;
511 if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
512 // Index Register - Register * Scale
513 assert (!IndexReg && "IndexReg already set!");
516 if(Scale != 1 && Scale != 2 && Scale != 4 && Scale != 8) {
517 ErrMsg = "scale factor in address must be 1, 2, 4 or 8";
520 // Get the scale and replace the 'Register * Scale' with '0'.
522 } else if ((PrevState == IES_PLUS || PrevState == IES_MINUS ||
523 PrevState == IES_OR || PrevState == IES_AND ||
524 PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||
525 PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
526 PrevState == IES_LPAREN || PrevState == IES_LBRAC ||
527 PrevState == IES_NOT || PrevState == IES_XOR) &&
528 CurrState == IES_MINUS) {
529 // Unary minus. No need to pop the minus operand because it was never
531 IC.pushOperand(IC_IMM, -TmpInt); // Push -Imm.
532 } else if ((PrevState == IES_PLUS || PrevState == IES_MINUS ||
533 PrevState == IES_OR || PrevState == IES_AND ||
534 PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||
535 PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
536 PrevState == IES_LPAREN || PrevState == IES_LBRAC ||
537 PrevState == IES_NOT || PrevState == IES_XOR) &&
538 CurrState == IES_NOT) {
539 // Unary not. No need to pop the not operand because it was never
541 IC.pushOperand(IC_IMM, ~TmpInt); // Push ~Imm.
543 IC.pushOperand(IC_IMM, TmpInt);
547 PrevState = CurrState;
559 State = IES_MULTIPLY;
560 IC.pushOperator(IC_MULTIPLY);
573 IC.pushOperator(IC_DIVIDE);
585 IC.pushOperator(IC_PLUS);
590 IntelExprState CurrState = State;
599 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
600 // If we already have a BaseReg, then assume this is the IndexReg with
605 assert (!IndexReg && "BaseReg/IndexReg already set!");
612 PrevState = CurrState;
615 IntelExprState CurrState = State;
631 // FIXME: We don't handle this type of unary minus or not, yet.
632 if ((PrevState == IES_PLUS || PrevState == IES_MINUS ||
633 PrevState == IES_OR || PrevState == IES_AND ||
634 PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||
635 PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
636 PrevState == IES_LPAREN || PrevState == IES_LBRAC ||
637 PrevState == IES_NOT || PrevState == IES_XOR) &&
638 (CurrState == IES_MINUS || CurrState == IES_NOT)) {
643 IC.pushOperator(IC_LPAREN);
646 PrevState = CurrState;
658 IC.pushOperator(IC_RPAREN);
664 bool Error(SMLoc L, const Twine &Msg,
665 ArrayRef<SMRange> Ranges = None,
666 bool MatchingInlineAsm = false) {
667 MCAsmParser &Parser = getParser();
668 if (MatchingInlineAsm) return true;
669 return Parser.Error(L, Msg, Ranges);
672 bool ErrorAndEatStatement(SMLoc L, const Twine &Msg,
673 ArrayRef<SMRange> Ranges = None,
674 bool MatchingInlineAsm = false) {
675 MCAsmParser &Parser = getParser();
676 Parser.eatToEndOfStatement();
677 return Error(L, Msg, Ranges, MatchingInlineAsm);
680 std::nullptr_t ErrorOperand(SMLoc Loc, StringRef Msg) {
685 std::unique_ptr<X86Operand> DefaultMemSIOperand(SMLoc Loc);
686 std::unique_ptr<X86Operand> DefaultMemDIOperand(SMLoc Loc);
687 void AddDefaultSrcDestOperands(
688 OperandVector& Operands, std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
689 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst);
690 std::unique_ptr<X86Operand> ParseOperand();
691 std::unique_ptr<X86Operand> ParseATTOperand();
692 std::unique_ptr<X86Operand> ParseIntelOperand();
693 std::unique_ptr<X86Operand> ParseIntelOffsetOfOperator();
694 bool ParseIntelDotOperator(const MCExpr *Disp, const MCExpr *&NewDisp);
695 std::unique_ptr<X86Operand> ParseIntelOperator(unsigned OpKind);
696 std::unique_ptr<X86Operand>
697 ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start, unsigned Size);
698 std::unique_ptr<X86Operand>
699 ParseIntelMemOperand(int64_t ImmDisp, SMLoc StartLoc, unsigned Size);
700 std::unique_ptr<X86Operand> ParseRoundingModeOp(SMLoc Start, SMLoc End);
701 bool ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End);
702 std::unique_ptr<X86Operand> ParseIntelBracExpression(unsigned SegReg,
706 bool ParseIntelIdentifier(const MCExpr *&Val, StringRef &Identifier,
707 InlineAsmIdentifierInfo &Info,
708 bool IsUnevaluatedOperand, SMLoc &End);
710 std::unique_ptr<X86Operand> ParseMemOperand(unsigned SegReg, SMLoc StartLoc);
712 std::unique_ptr<X86Operand>
713 CreateMemForInlineAsm(unsigned SegReg, const MCExpr *Disp, unsigned BaseReg,
714 unsigned IndexReg, unsigned Scale, SMLoc Start,
715 SMLoc End, unsigned Size, StringRef Identifier,
716 InlineAsmIdentifierInfo &Info);
718 bool ParseDirectiveWord(unsigned Size, SMLoc L);
719 bool ParseDirectiveCode(StringRef IDVal, SMLoc L);
721 bool processInstruction(MCInst &Inst, const OperandVector &Ops);
723 /// Wrapper around MCStreamer::EmitInstruction(). Possibly adds
724 /// instrumentation around Inst.
725 void EmitInstruction(MCInst &Inst, OperandVector &Operands, MCStreamer &Out);
727 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
728 OperandVector &Operands, MCStreamer &Out,
730 bool MatchingInlineAsm) override;
732 void MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op, OperandVector &Operands,
733 MCStreamer &Out, bool MatchingInlineAsm);
735 bool ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
736 bool MatchingInlineAsm);
738 bool MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
739 OperandVector &Operands, MCStreamer &Out,
741 bool MatchingInlineAsm);
743 bool MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
744 OperandVector &Operands, MCStreamer &Out,
746 bool MatchingInlineAsm);
748 bool OmitRegisterFromClobberLists(unsigned RegNo) override;
750 /// doSrcDstMatch - Returns true if operands are matching in their
751 /// word size (%si and %di, %esi and %edi, etc.). Order depends on
752 /// the parsing mode (Intel vs. AT&T).
753 bool doSrcDstMatch(X86Operand &Op1, X86Operand &Op2);
755 /// Parses AVX512 specific operand primitives: masked registers ({%k<NUM>}, {z})
756 /// and memory broadcasting ({1to<NUM>}) primitives, updating Operands vector if required.
757 /// \return \c true if no parsing errors occurred, \c false otherwise.
758 bool HandleAVX512Operand(OperandVector &Operands,
759 const MCParsedAsmOperand &Op);
761 bool is64BitMode() const {
762 // FIXME: Can tablegen auto-generate this?
763 return STI.getFeatureBits()[X86::Mode64Bit];
765 bool is32BitMode() const {
766 // FIXME: Can tablegen auto-generate this?
767 return STI.getFeatureBits()[X86::Mode32Bit];
769 bool is16BitMode() const {
770 // FIXME: Can tablegen auto-generate this?
771 return STI.getFeatureBits()[X86::Mode16Bit];
773 void SwitchMode(unsigned mode) {
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(MCSubtargetInfo &sti, MCAsmParser &Parser,
804 const MCInstrInfo &mii, const MCTargetOptions &Options)
805 : MCTargetAsmParser(Options), STI(sti), MII(mii), InstInfo(nullptr) {
807 // Initialize the set of available features.
808 setAvailableFeatures(ComputeAvailableFeatures(STI.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("QWORD", "qword", 64)
1053 .Cases("MMWORD","mmword", 64)
1054 .Cases("XWORD", "xword", 80)
1055 .Cases("TBYTE", "tbyte", 80)
1056 .Cases("XMMWORD", "xmmword", 128)
1057 .Cases("YMMWORD", "ymmword", 256)
1058 .Cases("ZMMWORD", "zmmword", 512)
1059 .Cases("OPAQUE", "opaque", -1U) // needs to be non-zero, but doesn't matter
1064 std::unique_ptr<X86Operand> X86AsmParser::CreateMemForInlineAsm(
1065 unsigned SegReg, const MCExpr *Disp, unsigned BaseReg, unsigned IndexReg,
1066 unsigned Scale, SMLoc Start, SMLoc End, unsigned Size, StringRef Identifier,
1067 InlineAsmIdentifierInfo &Info) {
1068 // If we found a decl other than a VarDecl, then assume it is a FuncDecl or
1069 // some other label reference.
1070 if (isa<MCSymbolRefExpr>(Disp) && Info.OpDecl && !Info.IsVarDecl) {
1071 // Insert an explicit size if the user didn't have one.
1073 Size = getPointerWidth();
1074 InstInfo->AsmRewrites->emplace_back(AOK_SizeDirective, Start,
1078 // Create an absolute memory reference in order to match against
1079 // instructions taking a PC relative operand.
1080 return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size,
1081 Identifier, Info.OpDecl);
1084 // We either have a direct symbol reference, or an offset from a symbol. The
1085 // parser always puts the symbol on the LHS, so look there for size
1086 // calculation purposes.
1087 const MCBinaryExpr *BinOp = dyn_cast<MCBinaryExpr>(Disp);
1089 isa<MCSymbolRefExpr>(BinOp ? BinOp->getLHS() : Disp);
1092 Size = Info.Type * 8; // Size is in terms of bits in this context.
1094 InstInfo->AsmRewrites->emplace_back(AOK_SizeDirective, Start,
1099 // When parsing inline assembly we set the base register to a non-zero value
1100 // if we don't know the actual value at this time. This is necessary to
1101 // get the matching correct in some cases.
1102 BaseReg = BaseReg ? BaseReg : 1;
1103 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
1104 IndexReg, Scale, Start, End, Size, Identifier,
1109 RewriteIntelBracExpression(SmallVectorImpl<AsmRewrite> &AsmRewrites,
1110 StringRef SymName, int64_t ImmDisp,
1111 int64_t FinalImmDisp, SMLoc &BracLoc,
1112 SMLoc &StartInBrac, SMLoc &End) {
1113 // Remove the '[' and ']' from the IR string.
1114 AsmRewrites.emplace_back(AOK_Skip, BracLoc, 1);
1115 AsmRewrites.emplace_back(AOK_Skip, End, 1);
1117 // If ImmDisp is non-zero, then we parsed a displacement before the
1118 // bracketed expression (i.e., ImmDisp [ BaseReg + Scale*IndexReg + Disp])
1119 // If ImmDisp doesn't match the displacement computed by the state machine
1120 // then we have an additional displacement in the bracketed expression.
1121 if (ImmDisp != FinalImmDisp) {
1123 // We have an immediate displacement before the bracketed expression.
1124 // Adjust this to match the final immediate displacement.
1126 for (AsmRewrite &AR : AsmRewrites) {
1127 if (AR.Loc.getPointer() > BracLoc.getPointer())
1129 if (AR.Kind == AOK_ImmPrefix || AR.Kind == AOK_Imm) {
1130 assert (!Found && "ImmDisp already rewritten.");
1132 AR.Len = BracLoc.getPointer() - AR.Loc.getPointer();
1133 AR.Val = FinalImmDisp;
1138 assert (Found && "Unable to rewrite ImmDisp.");
1141 // We have a symbolic and an immediate displacement, but no displacement
1142 // before the bracketed expression. Put the immediate displacement
1143 // before the bracketed expression.
1144 AsmRewrites.emplace_back(AOK_Imm, BracLoc, 0, FinalImmDisp);
1147 // Remove all the ImmPrefix rewrites within the brackets.
1148 for (AsmRewrite &AR : AsmRewrites) {
1149 if (AR.Loc.getPointer() < StartInBrac.getPointer())
1151 if (AR.Kind == AOK_ImmPrefix)
1152 AR.Kind = AOK_Delete;
1154 const char *SymLocPtr = SymName.data();
1155 // Skip everything before the symbol.
1156 if (unsigned Len = SymLocPtr - StartInBrac.getPointer()) {
1157 assert(Len > 0 && "Expected a non-negative length.");
1158 AsmRewrites.emplace_back(AOK_Skip, StartInBrac, Len);
1160 // Skip everything after the symbol.
1161 if (unsigned Len = End.getPointer() - (SymLocPtr + SymName.size())) {
1162 SMLoc Loc = SMLoc::getFromPointer(SymLocPtr + SymName.size());
1163 assert(Len > 0 && "Expected a non-negative length.");
1164 AsmRewrites.emplace_back(AOK_Skip, Loc, Len);
1168 bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
1169 MCAsmParser &Parser = getParser();
1170 const AsmToken &Tok = Parser.getTok();
1174 bool UpdateLocLex = true;
1176 // The period in the dot operator (e.g., [ebx].foo.bar) is parsed as an
1177 // identifier. Don't try an parse it as a register.
1178 if (Tok.getString().startswith("."))
1181 // If we're parsing an immediate expression, we don't expect a '['.
1182 if (SM.getStopOnLBrac() && getLexer().getKind() == AsmToken::LBrac)
1185 AsmToken::TokenKind TK = getLexer().getKind();
1188 if (SM.isValidEndState()) {
1192 return Error(Tok.getLoc(), "unknown token in expression");
1194 case AsmToken::EndOfStatement: {
1198 case AsmToken::String:
1199 case AsmToken::Identifier: {
1200 // This could be a register or a symbolic displacement.
1203 SMLoc IdentLoc = Tok.getLoc();
1204 StringRef Identifier = Tok.getString();
1205 if (TK != AsmToken::String && !ParseRegister(TmpReg, IdentLoc, End)) {
1206 SM.onRegister(TmpReg);
1207 UpdateLocLex = false;
1210 if (!isParsingInlineAsm()) {
1211 if (getParser().parsePrimaryExpr(Val, End))
1212 return Error(Tok.getLoc(), "Unexpected identifier!");
1214 // This is a dot operator, not an adjacent identifier.
1215 if (Identifier.find('.') != StringRef::npos) {
1218 InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
1219 if (ParseIntelIdentifier(Val, Identifier, Info,
1220 /*Unevaluated=*/false, End))
1224 SM.onIdentifierExpr(Val, Identifier);
1225 UpdateLocLex = false;
1228 return Error(Tok.getLoc(), "Unexpected identifier!");
1230 case AsmToken::Integer: {
1232 if (isParsingInlineAsm() && SM.getAddImmPrefix())
1233 InstInfo->AsmRewrites->emplace_back(AOK_ImmPrefix, Tok.getLoc());
1234 // Look for 'b' or 'f' following an Integer as a directional label
1235 SMLoc Loc = getTok().getLoc();
1236 int64_t IntVal = getTok().getIntVal();
1237 End = consumeToken();
1238 UpdateLocLex = false;
1239 if (getLexer().getKind() == AsmToken::Identifier) {
1240 StringRef IDVal = getTok().getString();
1241 if (IDVal == "f" || IDVal == "b") {
1243 getContext().getDirectionalLocalSymbol(IntVal, IDVal == "b");
1244 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1246 MCSymbolRefExpr::create(Sym, Variant, getContext());
1247 if (IDVal == "b" && Sym->isUndefined())
1248 return Error(Loc, "invalid reference to undefined symbol");
1249 StringRef Identifier = Sym->getName();
1250 SM.onIdentifierExpr(Val, Identifier);
1251 End = consumeToken();
1253 if (SM.onInteger(IntVal, ErrMsg))
1254 return Error(Loc, ErrMsg);
1257 if (SM.onInteger(IntVal, ErrMsg))
1258 return Error(Loc, ErrMsg);
1262 case AsmToken::Plus: SM.onPlus(); break;
1263 case AsmToken::Minus: SM.onMinus(); break;
1264 case AsmToken::Tilde: SM.onNot(); break;
1265 case AsmToken::Star: SM.onStar(); break;
1266 case AsmToken::Slash: SM.onDivide(); break;
1267 case AsmToken::Pipe: SM.onOr(); break;
1268 case AsmToken::Caret: SM.onXor(); break;
1269 case AsmToken::Amp: SM.onAnd(); break;
1270 case AsmToken::LessLess:
1271 SM.onLShift(); break;
1272 case AsmToken::GreaterGreater:
1273 SM.onRShift(); break;
1274 case AsmToken::LBrac: SM.onLBrac(); break;
1275 case AsmToken::RBrac: SM.onRBrac(); break;
1276 case AsmToken::LParen: SM.onLParen(); break;
1277 case AsmToken::RParen: SM.onRParen(); break;
1280 return Error(Tok.getLoc(), "unknown token in expression");
1282 if (!Done && UpdateLocLex)
1283 End = consumeToken();
1288 std::unique_ptr<X86Operand>
1289 X86AsmParser::ParseIntelBracExpression(unsigned SegReg, SMLoc Start,
1290 int64_t ImmDisp, unsigned Size) {
1291 MCAsmParser &Parser = getParser();
1292 const AsmToken &Tok = Parser.getTok();
1293 SMLoc BracLoc = Tok.getLoc(), End = Tok.getEndLoc();
1294 if (getLexer().isNot(AsmToken::LBrac))
1295 return ErrorOperand(BracLoc, "Expected '[' token!");
1296 Parser.Lex(); // Eat '['
1298 SMLoc StartInBrac = Tok.getLoc();
1299 // Parse [ Symbol + ImmDisp ] and [ BaseReg + Scale*IndexReg + ImmDisp ]. We
1300 // may have already parsed an immediate displacement before the bracketed
1302 IntelExprStateMachine SM(ImmDisp, /*StopOnLBrac=*/false, /*AddImmPrefix=*/true);
1303 if (ParseIntelExpression(SM, End))
1306 const MCExpr *Disp = nullptr;
1307 if (const MCExpr *Sym = SM.getSym()) {
1308 // A symbolic displacement.
1310 if (isParsingInlineAsm())
1311 RewriteIntelBracExpression(*InstInfo->AsmRewrites, SM.getSymName(),
1312 ImmDisp, SM.getImm(), BracLoc, StartInBrac,
1316 if (SM.getImm() || !Disp) {
1317 const MCExpr *Imm = MCConstantExpr::create(SM.getImm(), getContext());
1319 Disp = MCBinaryExpr::createAdd(Disp, Imm, getContext());
1321 Disp = Imm; // An immediate displacement only.
1324 // Parse struct field access. Intel requires a dot, but MSVC doesn't. MSVC
1325 // will in fact do global lookup the field name inside all global typedefs,
1326 // but we don't emulate that.
1327 if (Tok.getString().find('.') != StringRef::npos) {
1328 const MCExpr *NewDisp;
1329 if (ParseIntelDotOperator(Disp, NewDisp))
1332 End = Tok.getEndLoc();
1333 Parser.Lex(); // Eat the field.
1337 int BaseReg = SM.getBaseReg();
1338 int IndexReg = SM.getIndexReg();
1339 int Scale = SM.getScale();
1340 if (!isParsingInlineAsm()) {
1342 if (!BaseReg && !IndexReg) {
1344 return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size);
1345 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
1349 if (CheckBaseRegAndIndexReg(BaseReg, IndexReg, ErrMsg)) {
1350 Error(StartInBrac, ErrMsg);
1353 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
1354 IndexReg, Scale, Start, End, Size);
1357 InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
1358 return CreateMemForInlineAsm(SegReg, Disp, BaseReg, IndexReg, Scale, Start,
1359 End, Size, SM.getSymName(), Info);
1362 // Inline assembly may use variable names with namespace alias qualifiers.
1363 bool X86AsmParser::ParseIntelIdentifier(const MCExpr *&Val,
1364 StringRef &Identifier,
1365 InlineAsmIdentifierInfo &Info,
1366 bool IsUnevaluatedOperand, SMLoc &End) {
1367 MCAsmParser &Parser = getParser();
1368 assert(isParsingInlineAsm() && "Expected to be parsing inline assembly.");
1371 StringRef LineBuf(Identifier.data());
1373 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);
1375 const AsmToken &Tok = Parser.getTok();
1376 SMLoc Loc = Tok.getLoc();
1378 // Advance the token stream until the end of the current token is
1379 // after the end of what the frontend claimed.
1380 const char *EndPtr = Tok.getLoc().getPointer() + LineBuf.size();
1382 End = Tok.getEndLoc();
1384 } while (End.getPointer() < EndPtr);
1385 Identifier = LineBuf;
1387 // The frontend should end parsing on an assembler token boundary, unless it
1389 assert((End.getPointer() == EndPtr || !Result) &&
1390 "frontend claimed part of a token?");
1392 // If the identifier lookup was unsuccessful, assume that we are dealing with
1395 StringRef InternalName =
1396 SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(),
1398 assert(InternalName.size() && "We should have an internal name here.");
1399 // Push a rewrite for replacing the identifier name with the internal name.
1400 InstInfo->AsmRewrites->emplace_back(AOK_Label, Loc, Identifier.size(),
1404 // Create the symbol reference.
1405 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
1406 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1407 Val = MCSymbolRefExpr::create(Sym, Variant, getParser().getContext());
1411 /// \brief Parse intel style segment override.
1412 std::unique_ptr<X86Operand>
1413 X86AsmParser::ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start,
1415 MCAsmParser &Parser = getParser();
1416 assert(SegReg != 0 && "Tried to parse a segment override without a segment!");
1417 const AsmToken &Tok = Parser.getTok(); // Eat colon.
1418 if (Tok.isNot(AsmToken::Colon))
1419 return ErrorOperand(Tok.getLoc(), "Expected ':' token!");
1420 Parser.Lex(); // Eat ':'
1422 int64_t ImmDisp = 0;
1423 if (getLexer().is(AsmToken::Integer)) {
1424 ImmDisp = Tok.getIntVal();
1425 AsmToken ImmDispToken = Parser.Lex(); // Eat the integer.
1427 if (isParsingInlineAsm())
1428 InstInfo->AsmRewrites->emplace_back(AOK_ImmPrefix, ImmDispToken.getLoc());
1430 if (getLexer().isNot(AsmToken::LBrac)) {
1431 // An immediate following a 'segment register', 'colon' token sequence can
1432 // be followed by a bracketed expression. If it isn't we know we have our
1433 // final segment override.
1434 const MCExpr *Disp = MCConstantExpr::create(ImmDisp, getContext());
1435 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp,
1436 /*BaseReg=*/0, /*IndexReg=*/0, /*Scale=*/1,
1437 Start, ImmDispToken.getEndLoc(), Size);
1441 if (getLexer().is(AsmToken::LBrac))
1442 return ParseIntelBracExpression(SegReg, Start, ImmDisp, Size);
1446 if (!isParsingInlineAsm()) {
1447 if (getParser().parsePrimaryExpr(Val, End))
1448 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1450 return X86Operand::CreateMem(getPointerWidth(), Val, Start, End, Size);
1453 InlineAsmIdentifierInfo Info;
1454 StringRef Identifier = Tok.getString();
1455 if (ParseIntelIdentifier(Val, Identifier, Info,
1456 /*Unevaluated=*/false, End))
1458 return CreateMemForInlineAsm(/*SegReg=*/0, Val, /*BaseReg=*/0,/*IndexReg=*/0,
1459 /*Scale=*/1, Start, End, Size, Identifier, Info);
1462 //ParseRoundingModeOp - Parse AVX-512 rounding mode operand
1463 std::unique_ptr<X86Operand>
1464 X86AsmParser::ParseRoundingModeOp(SMLoc Start, SMLoc End) {
1465 MCAsmParser &Parser = getParser();
1466 const AsmToken &Tok = Parser.getTok();
1467 // Eat "{" and mark the current place.
1468 const SMLoc consumedToken = consumeToken();
1469 if (Tok.getIdentifier().startswith("r")){
1470 int rndMode = StringSwitch<int>(Tok.getIdentifier())
1471 .Case("rn", X86::STATIC_ROUNDING::TO_NEAREST_INT)
1472 .Case("rd", X86::STATIC_ROUNDING::TO_NEG_INF)
1473 .Case("ru", X86::STATIC_ROUNDING::TO_POS_INF)
1474 .Case("rz", X86::STATIC_ROUNDING::TO_ZERO)
1477 return ErrorOperand(Tok.getLoc(), "Invalid rounding mode.");
1478 Parser.Lex(); // Eat "r*" of r*-sae
1479 if (!getLexer().is(AsmToken::Minus))
1480 return ErrorOperand(Tok.getLoc(), "Expected - at this point");
1481 Parser.Lex(); // Eat "-"
1482 Parser.Lex(); // Eat the sae
1483 if (!getLexer().is(AsmToken::RCurly))
1484 return ErrorOperand(Tok.getLoc(), "Expected } at this point");
1485 Parser.Lex(); // Eat "}"
1486 const MCExpr *RndModeOp =
1487 MCConstantExpr::create(rndMode, Parser.getContext());
1488 return X86Operand::CreateImm(RndModeOp, Start, End);
1490 if(Tok.getIdentifier().equals("sae")){
1491 Parser.Lex(); // Eat the sae
1492 if (!getLexer().is(AsmToken::RCurly))
1493 return ErrorOperand(Tok.getLoc(), "Expected } at this point");
1494 Parser.Lex(); // Eat "}"
1495 return X86Operand::CreateToken("{sae}", consumedToken);
1497 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1499 /// ParseIntelMemOperand - Parse intel style memory operand.
1500 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelMemOperand(int64_t ImmDisp,
1503 MCAsmParser &Parser = getParser();
1504 const AsmToken &Tok = Parser.getTok();
1507 // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
1508 if (getLexer().is(AsmToken::LBrac))
1509 return ParseIntelBracExpression(/*SegReg=*/0, Start, ImmDisp, Size);
1510 assert(ImmDisp == 0);
1513 if (!isParsingInlineAsm()) {
1514 if (getParser().parsePrimaryExpr(Val, End))
1515 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1517 return X86Operand::CreateMem(getPointerWidth(), Val, Start, End, Size);
1520 InlineAsmIdentifierInfo Info;
1521 StringRef Identifier = Tok.getString();
1522 if (ParseIntelIdentifier(Val, Identifier, Info,
1523 /*Unevaluated=*/false, End))
1526 if (!getLexer().is(AsmToken::LBrac))
1527 return CreateMemForInlineAsm(/*SegReg=*/0, Val, /*BaseReg=*/0, /*IndexReg=*/0,
1528 /*Scale=*/1, Start, End, Size, Identifier, Info);
1530 Parser.Lex(); // Eat '['
1532 // Parse Identifier [ ImmDisp ]
1533 IntelExprStateMachine SM(/*ImmDisp=*/0, /*StopOnLBrac=*/true,
1534 /*AddImmPrefix=*/false);
1535 if (ParseIntelExpression(SM, End))
1539 Error(Start, "cannot use more than one symbol in memory operand");
1542 if (SM.getBaseReg()) {
1543 Error(Start, "cannot use base register with variable reference");
1546 if (SM.getIndexReg()) {
1547 Error(Start, "cannot use index register with variable reference");
1551 const MCExpr *Disp = MCConstantExpr::create(SM.getImm(), getContext());
1552 // BaseReg is non-zero to avoid assertions. In the context of inline asm,
1553 // we're pointing to a local variable in memory, so the base register is
1554 // really the frame or stack pointer.
1555 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
1556 /*BaseReg=*/1, /*IndexReg=*/0, /*Scale=*/1,
1557 Start, End, Size, Identifier, Info.OpDecl);
1560 /// Parse the '.' operator.
1561 bool X86AsmParser::ParseIntelDotOperator(const MCExpr *Disp,
1562 const MCExpr *&NewDisp) {
1563 MCAsmParser &Parser = getParser();
1564 const AsmToken &Tok = Parser.getTok();
1565 int64_t OrigDispVal, DotDispVal;
1567 // FIXME: Handle non-constant expressions.
1568 if (const MCConstantExpr *OrigDisp = dyn_cast<MCConstantExpr>(Disp))
1569 OrigDispVal = OrigDisp->getValue();
1571 return Error(Tok.getLoc(), "Non-constant offsets are not supported!");
1573 // Drop the optional '.'.
1574 StringRef DotDispStr = Tok.getString();
1575 if (DotDispStr.startswith("."))
1576 DotDispStr = DotDispStr.drop_front(1);
1578 // .Imm gets lexed as a real.
1579 if (Tok.is(AsmToken::Real)) {
1581 DotDispStr.getAsInteger(10, DotDisp);
1582 DotDispVal = DotDisp.getZExtValue();
1583 } else if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) {
1585 std::pair<StringRef, StringRef> BaseMember = DotDispStr.split('.');
1586 if (SemaCallback->LookupInlineAsmField(BaseMember.first, BaseMember.second,
1588 return Error(Tok.getLoc(), "Unable to lookup field reference!");
1589 DotDispVal = DotDisp;
1591 return Error(Tok.getLoc(), "Unexpected token type!");
1593 if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) {
1594 SMLoc Loc = SMLoc::getFromPointer(DotDispStr.data());
1595 unsigned Len = DotDispStr.size();
1596 unsigned Val = OrigDispVal + DotDispVal;
1597 InstInfo->AsmRewrites->emplace_back(AOK_DotOperator, Loc, Len, Val);
1600 NewDisp = MCConstantExpr::create(OrigDispVal + DotDispVal, getContext());
1604 /// Parse the 'offset' operator. This operator is used to specify the
1605 /// location rather then the content of a variable.
1606 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOffsetOfOperator() {
1607 MCAsmParser &Parser = getParser();
1608 const AsmToken &Tok = Parser.getTok();
1609 SMLoc OffsetOfLoc = Tok.getLoc();
1610 Parser.Lex(); // Eat offset.
1613 InlineAsmIdentifierInfo Info;
1614 SMLoc Start = Tok.getLoc(), End;
1615 StringRef Identifier = Tok.getString();
1616 if (ParseIntelIdentifier(Val, Identifier, Info,
1617 /*Unevaluated=*/false, End))
1620 // Don't emit the offset operator.
1621 InstInfo->AsmRewrites->emplace_back(AOK_Skip, OffsetOfLoc, 7);
1623 // The offset operator will have an 'r' constraint, thus we need to create
1624 // register operand to ensure proper matching. Just pick a GPR based on
1625 // the size of a pointer.
1627 is64BitMode() ? X86::RBX : (is32BitMode() ? X86::EBX : X86::BX);
1628 return X86Operand::CreateReg(RegNo, Start, End, /*GetAddress=*/true,
1629 OffsetOfLoc, Identifier, Info.OpDecl);
1632 enum IntelOperatorKind {
1638 /// Parse the 'LENGTH', 'TYPE' and 'SIZE' operators. The LENGTH operator
1639 /// returns the number of elements in an array. It returns the value 1 for
1640 /// non-array variables. The SIZE operator returns the size of a C or C++
1641 /// variable. A variable's size is the product of its LENGTH and TYPE. The
1642 /// TYPE operator returns the size of a C or C++ type or variable. If the
1643 /// variable is an array, TYPE returns the size of a single element.
1644 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperator(unsigned OpKind) {
1645 MCAsmParser &Parser = getParser();
1646 const AsmToken &Tok = Parser.getTok();
1647 SMLoc TypeLoc = Tok.getLoc();
1648 Parser.Lex(); // Eat operator.
1650 const MCExpr *Val = nullptr;
1651 InlineAsmIdentifierInfo Info;
1652 SMLoc Start = Tok.getLoc(), End;
1653 StringRef Identifier = Tok.getString();
1654 if (ParseIntelIdentifier(Val, Identifier, Info,
1655 /*Unevaluated=*/true, End))
1659 return ErrorOperand(Start, "unable to lookup expression");
1663 default: llvm_unreachable("Unexpected operand kind!");
1664 case IOK_LENGTH: CVal = Info.Length; break;
1665 case IOK_SIZE: CVal = Info.Size; break;
1666 case IOK_TYPE: CVal = Info.Type; break;
1669 // Rewrite the type operator and the C or C++ type or variable in terms of an
1670 // immediate. E.g. TYPE foo -> $$4
1671 unsigned Len = End.getPointer() - TypeLoc.getPointer();
1672 InstInfo->AsmRewrites->emplace_back(AOK_Imm, TypeLoc, Len, CVal);
1674 const MCExpr *Imm = MCConstantExpr::create(CVal, getContext());
1675 return X86Operand::CreateImm(Imm, Start, End);
1678 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand() {
1679 MCAsmParser &Parser = getParser();
1680 const AsmToken &Tok = Parser.getTok();
1683 // Offset, length, type and size operators.
1684 if (isParsingInlineAsm()) {
1685 StringRef AsmTokStr = Tok.getString();
1686 if (AsmTokStr == "offset" || AsmTokStr == "OFFSET")
1687 return ParseIntelOffsetOfOperator();
1688 if (AsmTokStr == "length" || AsmTokStr == "LENGTH")
1689 return ParseIntelOperator(IOK_LENGTH);
1690 if (AsmTokStr == "size" || AsmTokStr == "SIZE")
1691 return ParseIntelOperator(IOK_SIZE);
1692 if (AsmTokStr == "type" || AsmTokStr == "TYPE")
1693 return ParseIntelOperator(IOK_TYPE);
1696 unsigned Size = getIntelMemOperandSize(Tok.getString());
1698 Parser.Lex(); // Eat operand size (e.g., byte, word).
1699 if (Tok.getString() != "PTR" && Tok.getString() != "ptr")
1700 return ErrorOperand(Tok.getLoc(), "Expected 'PTR' or 'ptr' token!");
1701 Parser.Lex(); // Eat ptr.
1703 Start = Tok.getLoc();
1706 if (getLexer().is(AsmToken::Integer) || getLexer().is(AsmToken::Minus) ||
1707 getLexer().is(AsmToken::Tilde) || getLexer().is(AsmToken::LParen)) {
1708 AsmToken StartTok = Tok;
1709 IntelExprStateMachine SM(/*Imm=*/0, /*StopOnLBrac=*/true,
1710 /*AddImmPrefix=*/false);
1711 if (ParseIntelExpression(SM, End))
1714 int64_t Imm = SM.getImm();
1715 if (isParsingInlineAsm()) {
1716 unsigned Len = Tok.getLoc().getPointer() - Start.getPointer();
1717 if (StartTok.getString().size() == Len)
1718 // Just add a prefix if this wasn't a complex immediate expression.
1719 InstInfo->AsmRewrites->emplace_back(AOK_ImmPrefix, Start);
1721 // Otherwise, rewrite the complex expression as a single immediate.
1722 InstInfo->AsmRewrites->emplace_back(AOK_Imm, Start, Len, Imm);
1725 if (getLexer().isNot(AsmToken::LBrac)) {
1726 // If a directional label (ie. 1f or 2b) was parsed above from
1727 // ParseIntelExpression() then SM.getSym() was set to a pointer to
1728 // to the MCExpr with the directional local symbol and this is a
1729 // memory operand not an immediate operand.
1731 return X86Operand::CreateMem(getPointerWidth(), SM.getSym(), Start, End,
1734 const MCExpr *ImmExpr = MCConstantExpr::create(Imm, getContext());
1735 return X86Operand::CreateImm(ImmExpr, Start, End);
1738 // Only positive immediates are valid.
1740 return ErrorOperand(Start, "expected a positive immediate displacement "
1741 "before bracketed expr.");
1743 // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
1744 return ParseIntelMemOperand(Imm, Start, Size);
1747 // rounding mode token
1748 if (STI.getFeatureBits()[X86::FeatureAVX512] &&
1749 getLexer().is(AsmToken::LCurly))
1750 return ParseRoundingModeOp(Start, End);
1754 if (!ParseRegister(RegNo, Start, End)) {
1755 // If this is a segment register followed by a ':', then this is the start
1756 // of a segment override, otherwise this is a normal register reference.
1757 if (getLexer().isNot(AsmToken::Colon))
1758 return X86Operand::CreateReg(RegNo, Start, End);
1760 return ParseIntelSegmentOverride(/*SegReg=*/RegNo, Start, Size);
1764 return ParseIntelMemOperand(/*Disp=*/0, Start, Size);
1767 std::unique_ptr<X86Operand> X86AsmParser::ParseATTOperand() {
1768 MCAsmParser &Parser = getParser();
1769 switch (getLexer().getKind()) {
1771 // Parse a memory operand with no segment register.
1772 return ParseMemOperand(0, Parser.getTok().getLoc());
1773 case AsmToken::Percent: {
1774 // Read the register.
1777 if (ParseRegister(RegNo, Start, End)) return nullptr;
1778 if (RegNo == X86::EIZ || RegNo == X86::RIZ) {
1779 Error(Start, "%eiz and %riz can only be used as index registers",
1780 SMRange(Start, End));
1784 // If this is a segment register followed by a ':', then this is the start
1785 // of a memory reference, otherwise this is a normal register reference.
1786 if (getLexer().isNot(AsmToken::Colon))
1787 return X86Operand::CreateReg(RegNo, Start, End);
1789 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo))
1790 return ErrorOperand(Start, "invalid segment register");
1792 getParser().Lex(); // Eat the colon.
1793 return ParseMemOperand(RegNo, Start);
1795 case AsmToken::Dollar: {
1796 // $42 -> immediate.
1797 SMLoc Start = Parser.getTok().getLoc(), End;
1800 if (getParser().parseExpression(Val, End))
1802 return X86Operand::CreateImm(Val, Start, End);
1804 case AsmToken::LCurly:{
1805 SMLoc Start = Parser.getTok().getLoc(), End;
1806 if (STI.getFeatureBits()[X86::FeatureAVX512])
1807 return ParseRoundingModeOp(Start, End);
1808 return ErrorOperand(Start, "unknown token in expression");
1813 bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands,
1814 const MCParsedAsmOperand &Op) {
1815 MCAsmParser &Parser = getParser();
1816 if(STI.getFeatureBits()[X86::FeatureAVX512]) {
1817 if (getLexer().is(AsmToken::LCurly)) {
1818 // Eat "{" and mark the current place.
1819 const SMLoc consumedToken = consumeToken();
1820 // Distinguish {1to<NUM>} from {%k<NUM>}.
1821 if(getLexer().is(AsmToken::Integer)) {
1822 // Parse memory broadcasting ({1to<NUM>}).
1823 if (getLexer().getTok().getIntVal() != 1)
1824 return !ErrorAndEatStatement(getLexer().getLoc(),
1825 "Expected 1to<NUM> at this point");
1826 Parser.Lex(); // Eat "1" of 1to8
1827 if (!getLexer().is(AsmToken::Identifier) ||
1828 !getLexer().getTok().getIdentifier().startswith("to"))
1829 return !ErrorAndEatStatement(getLexer().getLoc(),
1830 "Expected 1to<NUM> at this point");
1831 // Recognize only reasonable suffixes.
1832 const char *BroadcastPrimitive =
1833 StringSwitch<const char*>(getLexer().getTok().getIdentifier())
1834 .Case("to2", "{1to2}")
1835 .Case("to4", "{1to4}")
1836 .Case("to8", "{1to8}")
1837 .Case("to16", "{1to16}")
1839 if (!BroadcastPrimitive)
1840 return !ErrorAndEatStatement(getLexer().getLoc(),
1841 "Invalid memory broadcast primitive.");
1842 Parser.Lex(); // Eat "toN" of 1toN
1843 if (!getLexer().is(AsmToken::RCurly))
1844 return !ErrorAndEatStatement(getLexer().getLoc(),
1845 "Expected } at this point");
1846 Parser.Lex(); // Eat "}"
1847 Operands.push_back(X86Operand::CreateToken(BroadcastPrimitive,
1849 // No AVX512 specific primitives can pass
1850 // after memory broadcasting, so return.
1853 // Parse mask register {%k1}
1854 Operands.push_back(X86Operand::CreateToken("{", consumedToken));
1855 if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
1856 Operands.push_back(std::move(Op));
1857 if (!getLexer().is(AsmToken::RCurly))
1858 return !ErrorAndEatStatement(getLexer().getLoc(),
1859 "Expected } at this point");
1860 Operands.push_back(X86Operand::CreateToken("}", consumeToken()));
1862 // Parse "zeroing non-masked" semantic {z}
1863 if (getLexer().is(AsmToken::LCurly)) {
1864 Operands.push_back(X86Operand::CreateToken("{z}", consumeToken()));
1865 if (!getLexer().is(AsmToken::Identifier) ||
1866 getLexer().getTok().getIdentifier() != "z")
1867 return !ErrorAndEatStatement(getLexer().getLoc(),
1868 "Expected z at this point");
1869 Parser.Lex(); // Eat the z
1870 if (!getLexer().is(AsmToken::RCurly))
1871 return !ErrorAndEatStatement(getLexer().getLoc(),
1872 "Expected } at this point");
1873 Parser.Lex(); // Eat the }
1882 /// ParseMemOperand: segment: disp(basereg, indexreg, scale). The '%ds:' prefix
1883 /// has already been parsed if present.
1884 std::unique_ptr<X86Operand> X86AsmParser::ParseMemOperand(unsigned SegReg,
1887 MCAsmParser &Parser = getParser();
1888 // We have to disambiguate a parenthesized expression "(4+5)" from the start
1889 // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)". The
1890 // only way to do this without lookahead is to eat the '(' and see what is
1892 const MCExpr *Disp = MCConstantExpr::create(0, getParser().getContext());
1893 if (getLexer().isNot(AsmToken::LParen)) {
1895 if (getParser().parseExpression(Disp, ExprEnd)) return nullptr;
1897 // After parsing the base expression we could either have a parenthesized
1898 // memory address or not. If not, return now. If so, eat the (.
1899 if (getLexer().isNot(AsmToken::LParen)) {
1900 // Unless we have a segment register, treat this as an immediate.
1902 return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, ExprEnd);
1903 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
1910 // Okay, we have a '('. We don't know if this is an expression or not, but
1911 // so we have to eat the ( to see beyond it.
1912 SMLoc LParenLoc = Parser.getTok().getLoc();
1913 Parser.Lex(); // Eat the '('.
1915 if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) {
1916 // Nothing to do here, fall into the code below with the '(' part of the
1917 // memory operand consumed.
1921 // It must be an parenthesized expression, parse it now.
1922 if (getParser().parseParenExpression(Disp, ExprEnd))
1925 // After parsing the base expression we could either have a parenthesized
1926 // memory address or not. If not, return now. If so, eat the (.
1927 if (getLexer().isNot(AsmToken::LParen)) {
1928 // Unless we have a segment register, treat this as an immediate.
1930 return X86Operand::CreateMem(getPointerWidth(), Disp, LParenLoc,
1932 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
1941 // If we reached here, then we just ate the ( of the memory operand. Process
1942 // the rest of the memory operand.
1943 unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
1944 SMLoc IndexLoc, BaseLoc;
1946 if (getLexer().is(AsmToken::Percent)) {
1947 SMLoc StartLoc, EndLoc;
1948 BaseLoc = Parser.getTok().getLoc();
1949 if (ParseRegister(BaseReg, StartLoc, EndLoc)) return nullptr;
1950 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) {
1951 Error(StartLoc, "eiz and riz can only be used as index registers",
1952 SMRange(StartLoc, EndLoc));
1957 if (getLexer().is(AsmToken::Comma)) {
1958 Parser.Lex(); // Eat the comma.
1959 IndexLoc = Parser.getTok().getLoc();
1961 // Following the comma we should have either an index register, or a scale
1962 // value. We don't support the later form, but we want to parse it
1965 // Not that even though it would be completely consistent to support syntax
1966 // like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this.
1967 if (getLexer().is(AsmToken::Percent)) {
1969 if (ParseRegister(IndexReg, L, L)) return nullptr;
1971 if (getLexer().isNot(AsmToken::RParen)) {
1972 // Parse the scale amount:
1973 // ::= ',' [scale-expression]
1974 if (getLexer().isNot(AsmToken::Comma)) {
1975 Error(Parser.getTok().getLoc(),
1976 "expected comma in scale expression");
1979 Parser.Lex(); // Eat the comma.
1981 if (getLexer().isNot(AsmToken::RParen)) {
1982 SMLoc Loc = Parser.getTok().getLoc();
1985 if (getParser().parseAbsoluteExpression(ScaleVal)){
1986 Error(Loc, "expected scale expression");
1990 // Validate the scale amount.
1991 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
1993 Error(Loc, "scale factor in 16-bit address must be 1");
1996 if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 &&
1998 Error(Loc, "scale factor in address must be 1, 2, 4 or 8");
2001 Scale = (unsigned)ScaleVal;
2004 } else if (getLexer().isNot(AsmToken::RParen)) {
2005 // A scale amount without an index is ignored.
2007 SMLoc Loc = Parser.getTok().getLoc();
2010 if (getParser().parseAbsoluteExpression(Value))
2014 Warning(Loc, "scale factor without index register is ignored");
2019 // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
2020 if (getLexer().isNot(AsmToken::RParen)) {
2021 Error(Parser.getTok().getLoc(), "unexpected token in memory operand");
2024 SMLoc MemEnd = Parser.getTok().getEndLoc();
2025 Parser.Lex(); // Eat the ')'.
2027 // Check for use of invalid 16-bit registers. Only BX/BP/SI/DI are allowed,
2028 // and then only in non-64-bit modes. Except for DX, which is a special case
2029 // because an unofficial form of in/out instructions uses it.
2030 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
2031 (is64BitMode() || (BaseReg != X86::BX && BaseReg != X86::BP &&
2032 BaseReg != X86::SI && BaseReg != X86::DI)) &&
2033 BaseReg != X86::DX) {
2034 Error(BaseLoc, "invalid 16-bit base register");
2038 X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg)) {
2039 Error(IndexLoc, "16-bit memory operand may not include only index register");
2044 if (CheckBaseRegAndIndexReg(BaseReg, IndexReg, ErrMsg)) {
2045 Error(BaseLoc, ErrMsg);
2049 if (SegReg || BaseReg || IndexReg)
2050 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
2051 IndexReg, Scale, MemStart, MemEnd);
2052 return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, MemEnd);
2055 bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2056 SMLoc NameLoc, OperandVector &Operands) {
2057 MCAsmParser &Parser = getParser();
2059 StringRef PatchedName = Name;
2061 // FIXME: Hack to recognize setneb as setne.
2062 if (PatchedName.startswith("set") && PatchedName.endswith("b") &&
2063 PatchedName != "setb" && PatchedName != "setnb")
2064 PatchedName = PatchedName.substr(0, Name.size()-1);
2066 // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}.
2067 if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) &&
2068 (PatchedName.endswith("ss") || PatchedName.endswith("sd") ||
2069 PatchedName.endswith("ps") || PatchedName.endswith("pd"))) {
2070 bool IsVCMP = PatchedName[0] == 'v';
2071 unsigned CCIdx = IsVCMP ? 4 : 3;
2072 unsigned ComparisonCode = StringSwitch<unsigned>(
2073 PatchedName.slice(CCIdx, PatchedName.size() - 2))
2077 .Case("unord", 0x03)
2082 /* AVX only from here */
2083 .Case("eq_uq", 0x08)
2086 .Case("false", 0x0B)
2087 .Case("neq_oq", 0x0C)
2091 .Case("eq_os", 0x10)
2092 .Case("lt_oq", 0x11)
2093 .Case("le_oq", 0x12)
2094 .Case("unord_s", 0x13)
2095 .Case("neq_us", 0x14)
2096 .Case("nlt_uq", 0x15)
2097 .Case("nle_uq", 0x16)
2098 .Case("ord_s", 0x17)
2099 .Case("eq_us", 0x18)
2100 .Case("nge_uq", 0x19)
2101 .Case("ngt_uq", 0x1A)
2102 .Case("false_os", 0x1B)
2103 .Case("neq_os", 0x1C)
2104 .Case("ge_oq", 0x1D)
2105 .Case("gt_oq", 0x1E)
2106 .Case("true_us", 0x1F)
2108 if (ComparisonCode != ~0U && (IsVCMP || ComparisonCode < 8)) {
2110 Operands.push_back(X86Operand::CreateToken(PatchedName.slice(0, CCIdx),
2113 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2114 getParser().getContext());
2115 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2117 PatchedName = PatchedName.substr(PatchedName.size() - 2);
2121 // FIXME: Hack to recognize vpcmp<comparison code>{ub,uw,ud,uq,b,w,d,q}.
2122 if (PatchedName.startswith("vpcmp") &&
2123 (PatchedName.endswith("b") || PatchedName.endswith("w") ||
2124 PatchedName.endswith("d") || PatchedName.endswith("q"))) {
2125 unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1;
2126 unsigned ComparisonCode = StringSwitch<unsigned>(
2127 PatchedName.slice(5, PatchedName.size() - CCIdx))
2128 .Case("eq", 0x0) // Only allowed on unsigned. Checked below.
2131 //.Case("false", 0x3) // Not a documented alias.
2135 //.Case("true", 0x7) // Not a documented alias.
2137 if (ComparisonCode != ~0U && (ComparisonCode != 0 || CCIdx == 2)) {
2138 Operands.push_back(X86Operand::CreateToken("vpcmp", NameLoc));
2140 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2141 getParser().getContext());
2142 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2144 PatchedName = PatchedName.substr(PatchedName.size() - CCIdx);
2148 // FIXME: Hack to recognize vpcom<comparison code>{ub,uw,ud,uq,b,w,d,q}.
2149 if (PatchedName.startswith("vpcom") &&
2150 (PatchedName.endswith("b") || PatchedName.endswith("w") ||
2151 PatchedName.endswith("d") || PatchedName.endswith("q"))) {
2152 unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1;
2153 unsigned ComparisonCode = StringSwitch<unsigned>(
2154 PatchedName.slice(5, PatchedName.size() - CCIdx))
2164 if (ComparisonCode != ~0U) {
2165 Operands.push_back(X86Operand::CreateToken("vpcom", NameLoc));
2167 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2168 getParser().getContext());
2169 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2171 PatchedName = PatchedName.substr(PatchedName.size() - CCIdx);
2175 Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
2177 // Determine whether this is an instruction prefix.
2179 Name == "lock" || Name == "rep" ||
2180 Name == "repe" || Name == "repz" ||
2181 Name == "repne" || Name == "repnz" ||
2182 Name == "rex64" || Name == "data16";
2184 // This does the actual operand parsing. Don't parse any more if we have a
2185 // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we
2186 // just want to parse the "lock" as the first instruction and the "incl" as
2188 if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) {
2190 // Parse '*' modifier.
2191 if (getLexer().is(AsmToken::Star))
2192 Operands.push_back(X86Operand::CreateToken("*", consumeToken()));
2194 // Read the operands.
2196 if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
2197 Operands.push_back(std::move(Op));
2198 if (!HandleAVX512Operand(Operands, *Operands.back()))
2201 Parser.eatToEndOfStatement();
2204 // check for comma and eat it
2205 if (getLexer().is(AsmToken::Comma))
2211 if (getLexer().isNot(AsmToken::EndOfStatement))
2212 return ErrorAndEatStatement(getLexer().getLoc(),
2213 "unexpected token in argument list");
2216 // Consume the EndOfStatement or the prefix separator Slash
2217 if (getLexer().is(AsmToken::EndOfStatement) ||
2218 (isPrefix && getLexer().is(AsmToken::Slash)))
2221 // This is a terrible hack to handle "out[bwl]? %al, (%dx)" ->
2222 // "outb %al, %dx". Out doesn't take a memory form, but this is a widely
2223 // documented form in various unofficial manuals, so a lot of code uses it.
2224 if ((Name == "outb" || Name == "outw" || Name == "outl" || Name == "out") &&
2225 Operands.size() == 3) {
2226 X86Operand &Op = (X86Operand &)*Operands.back();
2227 if (Op.isMem() && Op.Mem.SegReg == 0 &&
2228 isa<MCConstantExpr>(Op.Mem.Disp) &&
2229 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
2230 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
2231 SMLoc Loc = Op.getEndLoc();
2232 Operands.back() = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
2235 // Same hack for "in[bwl]? (%dx), %al" -> "inb %dx, %al".
2236 if ((Name == "inb" || Name == "inw" || Name == "inl" || Name == "in") &&
2237 Operands.size() == 3) {
2238 X86Operand &Op = (X86Operand &)*Operands[1];
2239 if (Op.isMem() && Op.Mem.SegReg == 0 &&
2240 isa<MCConstantExpr>(Op.Mem.Disp) &&
2241 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
2242 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
2243 SMLoc Loc = Op.getEndLoc();
2244 Operands[1] = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
2248 // Append default arguments to "ins[bwld]"
2249 if (Name.startswith("ins") && Operands.size() == 1 &&
2250 (Name == "insb" || Name == "insw" || Name == "insl" || Name == "insd")) {
2251 AddDefaultSrcDestOperands(Operands,
2252 X86Operand::CreateReg(X86::DX, NameLoc, NameLoc),
2253 DefaultMemDIOperand(NameLoc));
2256 // Append default arguments to "outs[bwld]"
2257 if (Name.startswith("outs") && Operands.size() == 1 &&
2258 (Name == "outsb" || Name == "outsw" || Name == "outsl" ||
2259 Name == "outsd" )) {
2260 AddDefaultSrcDestOperands(Operands,
2261 DefaultMemSIOperand(NameLoc),
2262 X86Operand::CreateReg(X86::DX, NameLoc, NameLoc));
2265 // Transform "lods[bwlq]" into "lods[bwlq] ($SIREG)" for appropriate
2266 // values of $SIREG according to the mode. It would be nice if this
2267 // could be achieved with InstAlias in the tables.
2268 if (Name.startswith("lods") && Operands.size() == 1 &&
2269 (Name == "lods" || Name == "lodsb" || Name == "lodsw" ||
2270 Name == "lodsl" || Name == "lodsd" || Name == "lodsq"))
2271 Operands.push_back(DefaultMemSIOperand(NameLoc));
2273 // Transform "stos[bwlq]" into "stos[bwlq] ($DIREG)" for appropriate
2274 // values of $DIREG according to the mode. It would be nice if this
2275 // could be achieved with InstAlias in the tables.
2276 if (Name.startswith("stos") && Operands.size() == 1 &&
2277 (Name == "stos" || Name == "stosb" || Name == "stosw" ||
2278 Name == "stosl" || Name == "stosd" || Name == "stosq"))
2279 Operands.push_back(DefaultMemDIOperand(NameLoc));
2281 // Transform "scas[bwlq]" into "scas[bwlq] ($DIREG)" for appropriate
2282 // values of $DIREG according to the mode. It would be nice if this
2283 // could be achieved with InstAlias in the tables.
2284 if (Name.startswith("scas") && Operands.size() == 1 &&
2285 (Name == "scas" || Name == "scasb" || Name == "scasw" ||
2286 Name == "scasl" || Name == "scasd" || Name == "scasq"))
2287 Operands.push_back(DefaultMemDIOperand(NameLoc));
2289 // Add default SI and DI operands to "cmps[bwlq]".
2290 if (Name.startswith("cmps") &&
2291 (Name == "cmps" || Name == "cmpsb" || Name == "cmpsw" ||
2292 Name == "cmpsl" || Name == "cmpsd" || Name == "cmpsq")) {
2293 if (Operands.size() == 1) {
2294 AddDefaultSrcDestOperands(Operands,
2295 DefaultMemDIOperand(NameLoc),
2296 DefaultMemSIOperand(NameLoc));
2297 } else if (Operands.size() == 3) {
2298 X86Operand &Op = (X86Operand &)*Operands[1];
2299 X86Operand &Op2 = (X86Operand &)*Operands[2];
2300 if (!doSrcDstMatch(Op, Op2))
2301 return Error(Op.getStartLoc(),
2302 "mismatching source and destination index registers");
2306 // Add default SI and DI operands to "movs[bwlq]".
2307 if ((Name.startswith("movs") &&
2308 (Name == "movs" || Name == "movsb" || Name == "movsw" ||
2309 Name == "movsl" || Name == "movsd" || Name == "movsq")) ||
2310 (Name.startswith("smov") &&
2311 (Name == "smov" || Name == "smovb" || Name == "smovw" ||
2312 Name == "smovl" || Name == "smovd" || Name == "smovq"))) {
2313 if (Operands.size() == 1) {
2314 if (Name == "movsd")
2315 Operands.back() = X86Operand::CreateToken("movsl", NameLoc);
2316 AddDefaultSrcDestOperands(Operands,
2317 DefaultMemSIOperand(NameLoc),
2318 DefaultMemDIOperand(NameLoc));
2319 } else if (Operands.size() == 3) {
2320 X86Operand &Op = (X86Operand &)*Operands[1];
2321 X86Operand &Op2 = (X86Operand &)*Operands[2];
2322 if (!doSrcDstMatch(Op, Op2))
2323 return Error(Op.getStartLoc(),
2324 "mismatching source and destination index registers");
2328 // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>. Canonicalize to
2330 if ((Name.startswith("shr") || Name.startswith("sar") ||
2331 Name.startswith("shl") || Name.startswith("sal") ||
2332 Name.startswith("rcl") || Name.startswith("rcr") ||
2333 Name.startswith("rol") || Name.startswith("ror")) &&
2334 Operands.size() == 3) {
2335 if (isParsingIntelSyntax()) {
2337 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[2]);
2338 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2339 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2340 Operands.pop_back();
2342 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2343 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2344 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2345 Operands.erase(Operands.begin() + 1);
2349 // Transforms "int $3" into "int3" as a size optimization. We can't write an
2350 // instalias with an immediate operand yet.
2351 if (Name == "int" && Operands.size() == 2) {
2352 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2354 if (auto *CE = dyn_cast<MCConstantExpr>(Op1.getImm()))
2355 if (CE->getValue() == 3) {
2356 Operands.erase(Operands.begin() + 1);
2357 static_cast<X86Operand &>(*Operands[0]).setTokenValue("int3");
2364 static bool convertToSExti8(MCInst &Inst, unsigned Opcode, unsigned Reg,
2367 TmpInst.setOpcode(Opcode);
2369 TmpInst.addOperand(MCOperand::createReg(Reg));
2370 TmpInst.addOperand(MCOperand::createReg(Reg));
2371 TmpInst.addOperand(Inst.getOperand(0));
2376 static bool convert16i16to16ri8(MCInst &Inst, unsigned Opcode,
2377 bool isCmp = false) {
2378 if (!Inst.getOperand(0).isImm() ||
2379 !isImmSExti16i8Value(Inst.getOperand(0).getImm()))
2382 return convertToSExti8(Inst, Opcode, X86::AX, isCmp);
2385 static bool convert32i32to32ri8(MCInst &Inst, unsigned Opcode,
2386 bool isCmp = false) {
2387 if (!Inst.getOperand(0).isImm() ||
2388 !isImmSExti32i8Value(Inst.getOperand(0).getImm()))
2391 return convertToSExti8(Inst, Opcode, X86::EAX, isCmp);
2394 static bool convert64i32to64ri8(MCInst &Inst, unsigned Opcode,
2395 bool isCmp = false) {
2396 if (!Inst.getOperand(0).isImm() ||
2397 !isImmSExti64i8Value(Inst.getOperand(0).getImm()))
2400 return convertToSExti8(Inst, Opcode, X86::RAX, isCmp);
2403 bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) {
2404 switch (Inst.getOpcode()) {
2405 default: return false;
2406 case X86::AND16i16: return convert16i16to16ri8(Inst, X86::AND16ri8);
2407 case X86::AND32i32: return convert32i32to32ri8(Inst, X86::AND32ri8);
2408 case X86::AND64i32: return convert64i32to64ri8(Inst, X86::AND64ri8);
2409 case X86::XOR16i16: return convert16i16to16ri8(Inst, X86::XOR16ri8);
2410 case X86::XOR32i32: return convert32i32to32ri8(Inst, X86::XOR32ri8);
2411 case X86::XOR64i32: return convert64i32to64ri8(Inst, X86::XOR64ri8);
2412 case X86::OR16i16: return convert16i16to16ri8(Inst, X86::OR16ri8);
2413 case X86::OR32i32: return convert32i32to32ri8(Inst, X86::OR32ri8);
2414 case X86::OR64i32: return convert64i32to64ri8(Inst, X86::OR64ri8);
2415 case X86::CMP16i16: return convert16i16to16ri8(Inst, X86::CMP16ri8, true);
2416 case X86::CMP32i32: return convert32i32to32ri8(Inst, X86::CMP32ri8, true);
2417 case X86::CMP64i32: return convert64i32to64ri8(Inst, X86::CMP64ri8, true);
2418 case X86::ADD16i16: return convert16i16to16ri8(Inst, X86::ADD16ri8);
2419 case X86::ADD32i32: return convert32i32to32ri8(Inst, X86::ADD32ri8);
2420 case X86::ADD64i32: return convert64i32to64ri8(Inst, X86::ADD64ri8);
2421 case X86::SUB16i16: return convert16i16to16ri8(Inst, X86::SUB16ri8);
2422 case X86::SUB32i32: return convert32i32to32ri8(Inst, X86::SUB32ri8);
2423 case X86::SUB64i32: return convert64i32to64ri8(Inst, X86::SUB64ri8);
2424 case X86::ADC16i16: return convert16i16to16ri8(Inst, X86::ADC16ri8);
2425 case X86::ADC32i32: return convert32i32to32ri8(Inst, X86::ADC32ri8);
2426 case X86::ADC64i32: return convert64i32to64ri8(Inst, X86::ADC64ri8);
2427 case X86::SBB16i16: return convert16i16to16ri8(Inst, X86::SBB16ri8);
2428 case X86::SBB32i32: return convert32i32to32ri8(Inst, X86::SBB32ri8);
2429 case X86::SBB64i32: return convert64i32to64ri8(Inst, X86::SBB64ri8);
2430 case X86::VMOVAPDrr:
2431 case X86::VMOVAPDYrr:
2432 case X86::VMOVAPSrr:
2433 case X86::VMOVAPSYrr:
2434 case X86::VMOVDQArr:
2435 case X86::VMOVDQAYrr:
2436 case X86::VMOVDQUrr:
2437 case X86::VMOVDQUYrr:
2438 case X86::VMOVUPDrr:
2439 case X86::VMOVUPDYrr:
2440 case X86::VMOVUPSrr:
2441 case X86::VMOVUPSYrr: {
2442 if (X86II::isX86_64ExtendedReg(Inst.getOperand(0).getReg()) ||
2443 !X86II::isX86_64ExtendedReg(Inst.getOperand(1).getReg()))
2447 switch (Inst.getOpcode()) {
2448 default: llvm_unreachable("Invalid opcode");
2449 case X86::VMOVAPDrr: NewOpc = X86::VMOVAPDrr_REV; break;
2450 case X86::VMOVAPDYrr: NewOpc = X86::VMOVAPDYrr_REV; break;
2451 case X86::VMOVAPSrr: NewOpc = X86::VMOVAPSrr_REV; break;
2452 case X86::VMOVAPSYrr: NewOpc = X86::VMOVAPSYrr_REV; break;
2453 case X86::VMOVDQArr: NewOpc = X86::VMOVDQArr_REV; break;
2454 case X86::VMOVDQAYrr: NewOpc = X86::VMOVDQAYrr_REV; break;
2455 case X86::VMOVDQUrr: NewOpc = X86::VMOVDQUrr_REV; break;
2456 case X86::VMOVDQUYrr: NewOpc = X86::VMOVDQUYrr_REV; break;
2457 case X86::VMOVUPDrr: NewOpc = X86::VMOVUPDrr_REV; break;
2458 case X86::VMOVUPDYrr: NewOpc = X86::VMOVUPDYrr_REV; break;
2459 case X86::VMOVUPSrr: NewOpc = X86::VMOVUPSrr_REV; break;
2460 case X86::VMOVUPSYrr: NewOpc = X86::VMOVUPSYrr_REV; break;
2462 Inst.setOpcode(NewOpc);
2466 case X86::VMOVSSrr: {
2467 if (X86II::isX86_64ExtendedReg(Inst.getOperand(0).getReg()) ||
2468 !X86II::isX86_64ExtendedReg(Inst.getOperand(2).getReg()))
2471 switch (Inst.getOpcode()) {
2472 default: llvm_unreachable("Invalid opcode");
2473 case X86::VMOVSDrr: NewOpc = X86::VMOVSDrr_REV; break;
2474 case X86::VMOVSSrr: NewOpc = X86::VMOVSSrr_REV; break;
2476 Inst.setOpcode(NewOpc);
2482 static const char *getSubtargetFeatureName(uint64_t Val);
2484 void X86AsmParser::EmitInstruction(MCInst &Inst, OperandVector &Operands,
2486 Instrumentation->InstrumentAndEmitInstruction(Inst, Operands, getContext(),
2490 bool X86AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2491 OperandVector &Operands,
2492 MCStreamer &Out, uint64_t &ErrorInfo,
2493 bool MatchingInlineAsm) {
2494 if (isParsingIntelSyntax())
2495 return MatchAndEmitIntelInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2497 return MatchAndEmitATTInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2501 void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op,
2502 OperandVector &Operands, MCStreamer &Out,
2503 bool MatchingInlineAsm) {
2504 // FIXME: This should be replaced with a real .td file alias mechanism.
2505 // Also, MatchInstructionImpl should actually *do* the EmitInstruction
2507 const char *Repl = StringSwitch<const char *>(Op.getToken())
2508 .Case("finit", "fninit")
2509 .Case("fsave", "fnsave")
2510 .Case("fstcw", "fnstcw")
2511 .Case("fstcww", "fnstcw")
2512 .Case("fstenv", "fnstenv")
2513 .Case("fstsw", "fnstsw")
2514 .Case("fstsww", "fnstsw")
2515 .Case("fclex", "fnclex")
2519 Inst.setOpcode(X86::WAIT);
2521 if (!MatchingInlineAsm)
2522 EmitInstruction(Inst, Operands, Out);
2523 Operands[0] = X86Operand::CreateToken(Repl, IDLoc);
2527 bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
2528 bool MatchingInlineAsm) {
2529 assert(ErrorInfo && "Unknown missing feature!");
2530 ArrayRef<SMRange> EmptyRanges = None;
2531 SmallString<126> Msg;
2532 raw_svector_ostream OS(Msg);
2533 OS << "instruction requires:";
2535 for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
2536 if (ErrorInfo & Mask)
2537 OS << ' ' << getSubtargetFeatureName(ErrorInfo & Mask);
2540 return Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
2543 bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
2544 OperandVector &Operands,
2546 uint64_t &ErrorInfo,
2547 bool MatchingInlineAsm) {
2548 assert(!Operands.empty() && "Unexpect empty operand list!");
2549 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2550 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
2551 ArrayRef<SMRange> EmptyRanges = None;
2553 // First, handle aliases that expand to multiple instructions.
2554 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2556 bool WasOriginallyInvalidOperand = false;
2559 // First, try a direct match.
2560 switch (MatchInstructionImpl(Operands, Inst,
2561 ErrorInfo, MatchingInlineAsm,
2562 isParsingIntelSyntax())) {
2563 default: llvm_unreachable("Unexpected match result!");
2565 // Some instructions need post-processing to, for example, tweak which
2566 // encoding is selected. Loop on it while changes happen so the
2567 // individual transformations can chain off each other.
2568 if (!MatchingInlineAsm)
2569 while (processInstruction(Inst, Operands))
2573 if (!MatchingInlineAsm)
2574 EmitInstruction(Inst, Operands, Out);
2575 Opcode = Inst.getOpcode();
2577 case Match_MissingFeature:
2578 return ErrorMissingFeature(IDLoc, ErrorInfo, MatchingInlineAsm);
2579 case Match_InvalidOperand:
2580 WasOriginallyInvalidOperand = true;
2582 case Match_MnemonicFail:
2586 // FIXME: Ideally, we would only attempt suffix matches for things which are
2587 // valid prefixes, and we could just infer the right unambiguous
2588 // type. However, that requires substantially more matcher support than the
2591 // Change the operand to point to a temporary token.
2592 StringRef Base = Op.getToken();
2593 SmallString<16> Tmp;
2596 Op.setTokenValue(Tmp);
2598 // If this instruction starts with an 'f', then it is a floating point stack
2599 // instruction. These come in up to three forms for 32-bit, 64-bit, and
2600 // 80-bit floating point, which use the suffixes s,l,t respectively.
2602 // Otherwise, we assume that this may be an integer instruction, which comes
2603 // in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively.
2604 const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0";
2606 // Check for the various suffix matches.
2607 uint64_t ErrorInfoIgnore;
2608 uint64_t ErrorInfoMissingFeature = 0; // Init suppresses compiler warnings.
2611 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I) {
2612 Tmp.back() = Suffixes[I];
2613 Match[I] = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
2614 MatchingInlineAsm, isParsingIntelSyntax());
2615 // If this returned as a missing feature failure, remember that.
2616 if (Match[I] == Match_MissingFeature)
2617 ErrorInfoMissingFeature = ErrorInfoIgnore;
2620 // Restore the old token.
2621 Op.setTokenValue(Base);
2623 // If exactly one matched, then we treat that as a successful match (and the
2624 // instruction will already have been filled in correctly, since the failing
2625 // matches won't have modified it).
2626 unsigned NumSuccessfulMatches =
2627 std::count(std::begin(Match), std::end(Match), Match_Success);
2628 if (NumSuccessfulMatches == 1) {
2630 if (!MatchingInlineAsm)
2631 EmitInstruction(Inst, Operands, Out);
2632 Opcode = Inst.getOpcode();
2636 // Otherwise, the match failed, try to produce a decent error message.
2638 // If we had multiple suffix matches, then identify this as an ambiguous
2640 if (NumSuccessfulMatches > 1) {
2642 unsigned NumMatches = 0;
2643 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I)
2644 if (Match[I] == Match_Success)
2645 MatchChars[NumMatches++] = Suffixes[I];
2647 SmallString<126> Msg;
2648 raw_svector_ostream OS(Msg);
2649 OS << "ambiguous instructions require an explicit suffix (could be ";
2650 for (unsigned i = 0; i != NumMatches; ++i) {
2653 if (i + 1 == NumMatches)
2655 OS << "'" << Base << MatchChars[i] << "'";
2658 Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
2662 // Okay, we know that none of the variants matched successfully.
2664 // If all of the instructions reported an invalid mnemonic, then the original
2665 // mnemonic was invalid.
2666 if (std::count(std::begin(Match), std::end(Match), Match_MnemonicFail) == 4) {
2667 if (!WasOriginallyInvalidOperand) {
2668 ArrayRef<SMRange> Ranges =
2669 MatchingInlineAsm ? EmptyRanges : Op.getLocRange();
2670 return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'",
2671 Ranges, MatchingInlineAsm);
2674 // Recover location info for the operand if we know which was the problem.
2675 if (ErrorInfo != ~0ULL) {
2676 if (ErrorInfo >= Operands.size())
2677 return Error(IDLoc, "too few operands for instruction",
2678 EmptyRanges, MatchingInlineAsm);
2680 X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo];
2681 if (Operand.getStartLoc().isValid()) {
2682 SMRange OperandRange = Operand.getLocRange();
2683 return Error(Operand.getStartLoc(), "invalid operand for instruction",
2684 OperandRange, MatchingInlineAsm);
2688 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2692 // If one instruction matched with a missing feature, report this as a
2694 if (std::count(std::begin(Match), std::end(Match),
2695 Match_MissingFeature) == 1) {
2696 ErrorInfo = ErrorInfoMissingFeature;
2697 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
2701 // If one instruction matched with an invalid operand, report this as an
2703 if (std::count(std::begin(Match), std::end(Match),
2704 Match_InvalidOperand) == 1) {
2705 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2709 // If all of these were an outright failure, report it in a useless way.
2710 Error(IDLoc, "unknown use of instruction mnemonic without a size suffix",
2711 EmptyRanges, MatchingInlineAsm);
2715 bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
2716 OperandVector &Operands,
2718 uint64_t &ErrorInfo,
2719 bool MatchingInlineAsm) {
2720 assert(!Operands.empty() && "Unexpect empty operand list!");
2721 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2722 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
2723 StringRef Mnemonic = Op.getToken();
2724 ArrayRef<SMRange> EmptyRanges = None;
2726 // First, handle aliases that expand to multiple instructions.
2727 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2731 // Find one unsized memory operand, if present.
2732 X86Operand *UnsizedMemOp = nullptr;
2733 for (const auto &Op : Operands) {
2734 X86Operand *X86Op = static_cast<X86Operand *>(Op.get());
2735 if (X86Op->isMemUnsized())
2736 UnsizedMemOp = X86Op;
2739 // Allow some instructions to have implicitly pointer-sized operands. This is
2740 // compatible with gas.
2742 static const char *const PtrSizedInstrs[] = {"call", "jmp", "push"};
2743 for (const char *Instr : PtrSizedInstrs) {
2744 if (Mnemonic == Instr) {
2745 UnsizedMemOp->Mem.Size = getPointerWidth();
2751 // If an unsized memory operand is present, try to match with each memory
2752 // operand size. In Intel assembly, the size is not part of the instruction
2754 SmallVector<unsigned, 8> Match;
2755 uint64_t ErrorInfoMissingFeature = 0;
2756 if (UnsizedMemOp && UnsizedMemOp->isMemUnsized()) {
2757 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
2758 for (unsigned Size : MopSizes) {
2759 UnsizedMemOp->Mem.Size = Size;
2760 uint64_t ErrorInfoIgnore;
2761 unsigned LastOpcode = Inst.getOpcode();
2763 MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
2764 MatchingInlineAsm, isParsingIntelSyntax());
2765 if (Match.empty() || LastOpcode != Inst.getOpcode())
2768 // If this returned as a missing feature failure, remember that.
2769 if (Match.back() == Match_MissingFeature)
2770 ErrorInfoMissingFeature = ErrorInfoIgnore;
2773 // Restore the size of the unsized memory operand if we modified it.
2775 UnsizedMemOp->Mem.Size = 0;
2778 // If we haven't matched anything yet, this is not a basic integer or FPU
2779 // operation. There shouldn't be any ambiguity in our mnemonic table, so try
2780 // matching with the unsized operand.
2781 if (Match.empty()) {
2782 Match.push_back(MatchInstructionImpl(Operands, Inst, ErrorInfo,
2784 isParsingIntelSyntax()));
2785 // If this returned as a missing feature failure, remember that.
2786 if (Match.back() == Match_MissingFeature)
2787 ErrorInfoMissingFeature = ErrorInfo;
2790 // Restore the size of the unsized memory operand if we modified it.
2792 UnsizedMemOp->Mem.Size = 0;
2794 // If it's a bad mnemonic, all results will be the same.
2795 if (Match.back() == Match_MnemonicFail) {
2796 ArrayRef<SMRange> Ranges =
2797 MatchingInlineAsm ? EmptyRanges : Op.getLocRange();
2798 return Error(IDLoc, "invalid instruction mnemonic '" + Mnemonic + "'",
2799 Ranges, MatchingInlineAsm);
2802 // If exactly one matched, then we treat that as a successful match (and the
2803 // instruction will already have been filled in correctly, since the failing
2804 // matches won't have modified it).
2805 unsigned NumSuccessfulMatches =
2806 std::count(std::begin(Match), std::end(Match), Match_Success);
2807 if (NumSuccessfulMatches == 1) {
2808 // Some instructions need post-processing to, for example, tweak which
2809 // encoding is selected. Loop on it while changes happen so the individual
2810 // transformations can chain off each other.
2811 if (!MatchingInlineAsm)
2812 while (processInstruction(Inst, Operands))
2815 if (!MatchingInlineAsm)
2816 EmitInstruction(Inst, Operands, Out);
2817 Opcode = Inst.getOpcode();
2819 } else if (NumSuccessfulMatches > 1) {
2820 assert(UnsizedMemOp &&
2821 "multiple matches only possible with unsized memory operands");
2822 ArrayRef<SMRange> Ranges =
2823 MatchingInlineAsm ? EmptyRanges : UnsizedMemOp->getLocRange();
2824 return Error(UnsizedMemOp->getStartLoc(),
2825 "ambiguous operand size for instruction '" + Mnemonic + "\'",
2826 Ranges, MatchingInlineAsm);
2829 // If one instruction matched with a missing feature, report this as a
2831 if (std::count(std::begin(Match), std::end(Match),
2832 Match_MissingFeature) == 1) {
2833 ErrorInfo = ErrorInfoMissingFeature;
2834 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
2838 // If one instruction matched with an invalid operand, report this as an
2840 if (std::count(std::begin(Match), std::end(Match),
2841 Match_InvalidOperand) == 1) {
2842 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2846 // If all of these were an outright failure, report it in a useless way.
2847 return Error(IDLoc, "unknown instruction mnemonic", EmptyRanges,
2851 bool X86AsmParser::OmitRegisterFromClobberLists(unsigned RegNo) {
2852 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo);
2855 bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
2856 MCAsmParser &Parser = getParser();
2857 StringRef IDVal = DirectiveID.getIdentifier();
2858 if (IDVal == ".word")
2859 return ParseDirectiveWord(2, DirectiveID.getLoc());
2860 else if (IDVal.startswith(".code"))
2861 return ParseDirectiveCode(IDVal, DirectiveID.getLoc());
2862 else if (IDVal.startswith(".att_syntax")) {
2863 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2864 if (Parser.getTok().getString() == "prefix")
2866 else if (Parser.getTok().getString() == "noprefix")
2867 return Error(DirectiveID.getLoc(), "'.att_syntax noprefix' is not "
2868 "supported: registers must have a "
2869 "'%' prefix in .att_syntax");
2871 getParser().setAssemblerDialect(0);
2873 } else if (IDVal.startswith(".intel_syntax")) {
2874 getParser().setAssemblerDialect(1);
2875 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2876 if (Parser.getTok().getString() == "noprefix")
2878 else if (Parser.getTok().getString() == "prefix")
2879 return Error(DirectiveID.getLoc(), "'.intel_syntax prefix' is not "
2880 "supported: registers must not have "
2881 "a '%' prefix in .intel_syntax");
2888 /// ParseDirectiveWord
2889 /// ::= .word [ expression (, expression)* ]
2890 bool X86AsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
2891 MCAsmParser &Parser = getParser();
2892 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2894 const MCExpr *Value;
2895 if (getParser().parseExpression(Value))
2898 getParser().getStreamer().EmitValue(Value, Size);
2900 if (getLexer().is(AsmToken::EndOfStatement))
2903 // FIXME: Improve diagnostic.
2904 if (getLexer().isNot(AsmToken::Comma)) {
2905 Error(L, "unexpected token in directive");
2916 /// ParseDirectiveCode
2917 /// ::= .code16 | .code32 | .code64
2918 bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
2919 MCAsmParser &Parser = getParser();
2920 if (IDVal == ".code16") {
2922 if (!is16BitMode()) {
2923 SwitchMode(X86::Mode16Bit);
2924 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
2926 } else if (IDVal == ".code32") {
2928 if (!is32BitMode()) {
2929 SwitchMode(X86::Mode32Bit);
2930 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
2932 } else if (IDVal == ".code64") {
2934 if (!is64BitMode()) {
2935 SwitchMode(X86::Mode64Bit);
2936 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code64);
2939 Error(L, "unknown directive " + IDVal);
2946 // Force static initialization.
2947 extern "C" void LLVMInitializeX86AsmParser() {
2948 RegisterMCAsmParser<X86AsmParser> X(TheX86_32Target);
2949 RegisterMCAsmParser<X86AsmParser> Y(TheX86_64Target);
2952 #define GET_REGISTER_MATCHER
2953 #define GET_MATCHER_IMPLEMENTATION
2954 #define GET_SUBTARGET_FEATURE_NAME
2955 #include "X86GenAsmMatcher.inc"