1 //===-- X86AsmParser.cpp - Parse X86 assembly to MCInst instructions ------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "MCTargetDesc/X86BaseInfo.h"
11 #include "X86AsmInstrumentation.h"
12 #include "X86AsmParserCommon.h"
13 #include "X86Operand.h"
14 #include "X86ISelLowering.h"
15 #include "llvm/ADT/APFloat.h"
16 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/ADT/SmallString.h"
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/ADT/StringSwitch.h"
20 #include "llvm/ADT/Twine.h"
21 #include "llvm/MC/MCContext.h"
22 #include "llvm/MC/MCExpr.h"
23 #include "llvm/MC/MCInst.h"
24 #include "llvm/MC/MCInstrInfo.h"
25 #include "llvm/MC/MCParser/MCAsmLexer.h"
26 #include "llvm/MC/MCParser/MCAsmParser.h"
27 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
28 #include "llvm/MC/MCRegisterInfo.h"
29 #include "llvm/MC/MCStreamer.h"
30 #include "llvm/MC/MCSubtargetInfo.h"
31 #include "llvm/MC/MCSymbol.h"
32 #include "llvm/MC/MCTargetAsmParser.h"
33 #include "llvm/Support/SourceMgr.h"
34 #include "llvm/Support/TargetRegistry.h"
35 #include "llvm/Support/raw_ostream.h"
43 static const char OpPrecedence[] = {
59 class X86AsmParser : public MCTargetAsmParser {
61 const MCInstrInfo &MII;
62 ParseInstructionInfo *InstInfo;
63 std::unique_ptr<X86AsmInstrumentation> Instrumentation;
65 SMLoc consumeToken() {
66 MCAsmParser &Parser = getParser();
67 SMLoc Result = Parser.getTok().getLoc();
72 enum InfixCalculatorTok {
88 class InfixCalculator {
89 typedef std::pair< InfixCalculatorTok, int64_t > ICToken;
90 SmallVector<InfixCalculatorTok, 4> InfixOperatorStack;
91 SmallVector<ICToken, 4> PostfixStack;
94 int64_t popOperand() {
95 assert (!PostfixStack.empty() && "Poped an empty stack!");
96 ICToken Op = PostfixStack.pop_back_val();
97 assert ((Op.first == IC_IMM || Op.first == IC_REGISTER)
98 && "Expected and immediate or register!");
101 void pushOperand(InfixCalculatorTok Op, int64_t Val = 0) {
102 assert ((Op == IC_IMM || Op == IC_REGISTER) &&
103 "Unexpected operand!");
104 PostfixStack.push_back(std::make_pair(Op, Val));
107 void popOperator() { InfixOperatorStack.pop_back(); }
108 void pushOperator(InfixCalculatorTok Op) {
109 // Push the new operator if the stack is empty.
110 if (InfixOperatorStack.empty()) {
111 InfixOperatorStack.push_back(Op);
115 // Push the new operator if it has a higher precedence than the operator
116 // on the top of the stack or the operator on the top of the stack is a
118 unsigned Idx = InfixOperatorStack.size() - 1;
119 InfixCalculatorTok StackOp = InfixOperatorStack[Idx];
120 if (OpPrecedence[Op] > OpPrecedence[StackOp] || StackOp == IC_LPAREN) {
121 InfixOperatorStack.push_back(Op);
125 // The operator on the top of the stack has higher precedence than the
127 unsigned ParenCount = 0;
129 // Nothing to process.
130 if (InfixOperatorStack.empty())
133 Idx = InfixOperatorStack.size() - 1;
134 StackOp = InfixOperatorStack[Idx];
135 if (!(OpPrecedence[StackOp] >= OpPrecedence[Op] || ParenCount))
138 // If we have an even parentheses count and we see a left parentheses,
139 // then stop processing.
140 if (!ParenCount && StackOp == IC_LPAREN)
143 if (StackOp == IC_RPAREN) {
145 InfixOperatorStack.pop_back();
146 } else if (StackOp == IC_LPAREN) {
148 InfixOperatorStack.pop_back();
150 InfixOperatorStack.pop_back();
151 PostfixStack.push_back(std::make_pair(StackOp, 0));
154 // Push the new operator.
155 InfixOperatorStack.push_back(Op);
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;
273 IntelExprStateMachine(int64_t imm, bool stoponlbrac, bool addimmprefix) :
274 State(IES_PLUS), PrevState(IES_ERROR), BaseReg(0), IndexReg(0), TmpReg(0),
275 Scale(1), Imm(imm), Sym(nullptr), StopOnLBrac(stoponlbrac),
276 AddImmPrefix(addimmprefix) { Info.clear(); }
278 unsigned getBaseReg() { return BaseReg; }
279 unsigned getIndexReg() { return IndexReg; }
280 unsigned getScale() { return Scale; }
281 const MCExpr *getSym() { return Sym; }
282 StringRef getSymName() { return SymName; }
283 int64_t getImm() { return Imm + IC.execute(); }
284 bool isValidEndState() {
285 return State == IES_RBRAC || State == IES_INTEGER;
287 bool getStopOnLBrac() { return StopOnLBrac; }
288 bool getAddImmPrefix() { return AddImmPrefix; }
289 bool hadError() { return State == IES_ERROR; }
291 InlineAsmIdentifierInfo &getIdentifierInfo() {
296 IntelExprState CurrState = State;
305 IC.pushOperator(IC_OR);
308 PrevState = CurrState;
311 IntelExprState CurrState = State;
320 IC.pushOperator(IC_XOR);
323 PrevState = CurrState;
326 IntelExprState CurrState = State;
335 IC.pushOperator(IC_AND);
338 PrevState = CurrState;
341 IntelExprState CurrState = State;
350 IC.pushOperator(IC_LSHIFT);
353 PrevState = CurrState;
356 IntelExprState CurrState = State;
365 IC.pushOperator(IC_RSHIFT);
368 PrevState = CurrState;
371 IntelExprState CurrState = State;
380 IC.pushOperator(IC_PLUS);
381 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
382 // If we already have a BaseReg, then assume this is the IndexReg with
387 assert (!IndexReg && "BaseReg/IndexReg already set!");
394 PrevState = CurrState;
397 IntelExprState CurrState = State;
413 // Only push the minus operator if it is not a unary operator.
414 if (!(CurrState == IES_PLUS || CurrState == IES_MINUS ||
415 CurrState == IES_MULTIPLY || CurrState == IES_DIVIDE ||
416 CurrState == IES_LPAREN || CurrState == IES_LBRAC))
417 IC.pushOperator(IC_MINUS);
418 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
419 // If we already have a BaseReg, then assume this is the IndexReg with
424 assert (!IndexReg && "BaseReg/IndexReg already set!");
431 PrevState = CurrState;
434 IntelExprState CurrState = State;
444 PrevState = CurrState;
446 void onRegister(unsigned Reg) {
447 IntelExprState CurrState = State;
454 State = IES_REGISTER;
456 IC.pushOperand(IC_REGISTER);
459 // Index Register - Scale * Register
460 if (PrevState == IES_INTEGER) {
461 assert (!IndexReg && "IndexReg already set!");
462 State = IES_REGISTER;
464 // Get the scale and replace the 'Scale * Register' with '0'.
465 Scale = IC.popOperand();
466 IC.pushOperand(IC_IMM);
473 PrevState = CurrState;
475 void onIdentifierExpr(const MCExpr *SymRef, StringRef SymRefName) {
486 SymName = SymRefName;
487 IC.pushOperand(IC_IMM);
491 bool onInteger(int64_t TmpInt, StringRef &ErrMsg) {
492 IntelExprState CurrState = State;
509 if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
510 // Index Register - Register * Scale
511 assert (!IndexReg && "IndexReg already set!");
514 if(Scale != 1 && Scale != 2 && Scale != 4 && Scale != 8) {
515 ErrMsg = "scale factor in address must be 1, 2, 4 or 8";
518 // Get the scale and replace the 'Register * Scale' with '0'.
520 } else if ((PrevState == IES_PLUS || PrevState == IES_MINUS ||
521 PrevState == IES_OR || PrevState == IES_AND ||
522 PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||
523 PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
524 PrevState == IES_LPAREN || PrevState == IES_LBRAC ||
525 PrevState == IES_NOT || PrevState == IES_XOR) &&
526 CurrState == IES_MINUS) {
527 // Unary minus. No need to pop the minus operand because it was never
529 IC.pushOperand(IC_IMM, -TmpInt); // Push -Imm.
530 } else if ((PrevState == IES_PLUS || PrevState == IES_MINUS ||
531 PrevState == IES_OR || PrevState == IES_AND ||
532 PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||
533 PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
534 PrevState == IES_LPAREN || PrevState == IES_LBRAC ||
535 PrevState == IES_NOT || PrevState == IES_XOR) &&
536 CurrState == IES_NOT) {
537 // Unary not. No need to pop the not operand because it was never
539 IC.pushOperand(IC_IMM, ~TmpInt); // Push ~Imm.
541 IC.pushOperand(IC_IMM, TmpInt);
545 PrevState = CurrState;
557 State = IES_MULTIPLY;
558 IC.pushOperator(IC_MULTIPLY);
571 IC.pushOperator(IC_DIVIDE);
583 IC.pushOperator(IC_PLUS);
588 IntelExprState CurrState = State;
597 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
598 // If we already have a BaseReg, then assume this is the IndexReg with
603 assert (!IndexReg && "BaseReg/IndexReg already set!");
610 PrevState = CurrState;
613 IntelExprState CurrState = State;
629 // FIXME: We don't handle this type of unary minus or not, yet.
630 if ((PrevState == IES_PLUS || PrevState == IES_MINUS ||
631 PrevState == IES_OR || PrevState == IES_AND ||
632 PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||
633 PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
634 PrevState == IES_LPAREN || PrevState == IES_LBRAC ||
635 PrevState == IES_NOT || PrevState == IES_XOR) &&
636 (CurrState == IES_MINUS || CurrState == IES_NOT)) {
641 IC.pushOperator(IC_LPAREN);
644 PrevState = CurrState;
656 IC.pushOperator(IC_RPAREN);
662 bool Error(SMLoc L, const Twine &Msg,
663 ArrayRef<SMRange> Ranges = None,
664 bool MatchingInlineAsm = false) {
665 MCAsmParser &Parser = getParser();
666 if (MatchingInlineAsm) return true;
667 return Parser.Error(L, Msg, Ranges);
670 bool ErrorAndEatStatement(SMLoc L, const Twine &Msg,
671 ArrayRef<SMRange> Ranges = None,
672 bool MatchingInlineAsm = false) {
673 MCAsmParser &Parser = getParser();
674 Parser.eatToEndOfStatement();
675 return Error(L, Msg, Ranges, MatchingInlineAsm);
678 std::nullptr_t ErrorOperand(SMLoc Loc, StringRef Msg) {
683 std::unique_ptr<X86Operand> DefaultMemSIOperand(SMLoc Loc);
684 std::unique_ptr<X86Operand> DefaultMemDIOperand(SMLoc Loc);
685 void AddDefaultSrcDestOperands(
686 OperandVector& Operands, std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
687 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst);
688 std::unique_ptr<X86Operand> ParseOperand();
689 std::unique_ptr<X86Operand> ParseATTOperand();
690 std::unique_ptr<X86Operand> ParseIntelOperand();
691 std::unique_ptr<X86Operand> ParseIntelOffsetOfOperator();
692 bool ParseIntelDotOperator(const MCExpr *Disp, const MCExpr *&NewDisp);
693 std::unique_ptr<X86Operand> ParseIntelOperator(unsigned OpKind);
694 std::unique_ptr<X86Operand>
695 ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start, unsigned Size);
696 std::unique_ptr<X86Operand>
697 ParseIntelMemOperand(int64_t ImmDisp, SMLoc StartLoc, unsigned Size);
698 std::unique_ptr<X86Operand> ParseRoundingModeOp(SMLoc Start, SMLoc End);
699 bool ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End);
700 std::unique_ptr<X86Operand> ParseIntelBracExpression(unsigned SegReg,
704 bool ParseIntelIdentifier(const MCExpr *&Val, StringRef &Identifier,
705 InlineAsmIdentifierInfo &Info,
706 bool IsUnevaluatedOperand, SMLoc &End);
708 std::unique_ptr<X86Operand> ParseMemOperand(unsigned SegReg, SMLoc StartLoc);
710 std::unique_ptr<X86Operand>
711 CreateMemForInlineAsm(unsigned SegReg, const MCExpr *Disp, unsigned BaseReg,
712 unsigned IndexReg, unsigned Scale, SMLoc Start,
713 SMLoc End, unsigned Size, StringRef Identifier,
714 InlineAsmIdentifierInfo &Info);
716 bool ParseDirectiveWord(unsigned Size, SMLoc L);
717 bool ParseDirectiveCode(StringRef IDVal, SMLoc L);
719 bool validateInstruction(MCInst &Inst, const OperandVector &Ops);
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 STI.getFeatureBits()[X86::Mode64Bit];
764 bool is32BitMode() const {
765 // FIXME: Can tablegen auto-generate this?
766 return STI.getFeatureBits()[X86::Mode32Bit];
768 bool is16BitMode() const {
769 // FIXME: Can tablegen auto-generate this?
770 return STI.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(sti), MII(mii), InstInfo(nullptr) {
806 // Initialize the set of available features.
807 setAvailableFeatures(ComputeAvailableFeatures(STI.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->push_back(AsmRewrite(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->push_back(AsmRewrite(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->push_back(AsmRewrite(AOK_Skip, BracLoc, 1));
1114 AsmRewrites->push_back(AsmRewrite(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 (SmallVectorImpl<AsmRewrite>::iterator I = AsmRewrites->begin(),
1126 E = AsmRewrites->end(); I != E; ++I) {
1127 if ((*I).Loc.getPointer() > BracLoc.getPointer())
1129 if ((*I).Kind == AOK_ImmPrefix || (*I).Kind == AOK_Imm) {
1130 assert (!Found && "ImmDisp already rewritten.");
1131 (*I).Kind = AOK_Imm;
1132 (*I).Len = BracLoc.getPointer() - (*I).Loc.getPointer();
1133 (*I).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->push_back(AsmRewrite(AOK_Imm, BracLoc, 0, FinalImmDisp));
1147 // Remove all the ImmPrefix rewrites within the brackets.
1148 for (SmallVectorImpl<AsmRewrite>::iterator I = AsmRewrites->begin(),
1149 E = AsmRewrites->end(); I != E; ++I) {
1150 if ((*I).Loc.getPointer() < StartInBrac.getPointer())
1152 if ((*I).Kind == AOK_ImmPrefix)
1153 (*I).Kind = AOK_Delete;
1155 const char *SymLocPtr = SymName.data();
1156 // Skip everything before the symbol.
1157 if (unsigned Len = SymLocPtr - StartInBrac.getPointer()) {
1158 assert(Len > 0 && "Expected a non-negative length.");
1159 AsmRewrites->push_back(AsmRewrite(AOK_Skip, StartInBrac, Len));
1161 // Skip everything after the symbol.
1162 if (unsigned Len = End.getPointer() - (SymLocPtr + SymName.size())) {
1163 SMLoc Loc = SMLoc::getFromPointer(SymLocPtr + SymName.size());
1164 assert(Len > 0 && "Expected a non-negative length.");
1165 AsmRewrites->push_back(AsmRewrite(AOK_Skip, Loc, Len));
1169 bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
1170 MCAsmParser &Parser = getParser();
1171 const AsmToken &Tok = Parser.getTok();
1175 bool UpdateLocLex = true;
1177 // The period in the dot operator (e.g., [ebx].foo.bar) is parsed as an
1178 // identifier. Don't try an parse it as a register.
1179 if (Tok.getString().startswith("."))
1182 // If we're parsing an immediate expression, we don't expect a '['.
1183 if (SM.getStopOnLBrac() && getLexer().getKind() == AsmToken::LBrac)
1186 AsmToken::TokenKind TK = getLexer().getKind();
1189 if (SM.isValidEndState()) {
1193 return Error(Tok.getLoc(), "unknown token in expression");
1195 case AsmToken::EndOfStatement: {
1199 case AsmToken::String:
1200 case AsmToken::Identifier: {
1201 // This could be a register or a symbolic displacement.
1204 SMLoc IdentLoc = Tok.getLoc();
1205 StringRef Identifier = Tok.getString();
1206 if (TK != AsmToken::String && !ParseRegister(TmpReg, IdentLoc, End)) {
1207 SM.onRegister(TmpReg);
1208 UpdateLocLex = false;
1211 if (!isParsingInlineAsm()) {
1212 if (getParser().parsePrimaryExpr(Val, End))
1213 return Error(Tok.getLoc(), "Unexpected identifier!");
1215 // This is a dot operator, not an adjacent identifier.
1216 if (Identifier.find('.') != StringRef::npos) {
1219 InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
1220 if (ParseIntelIdentifier(Val, Identifier, Info,
1221 /*Unevaluated=*/false, End))
1225 SM.onIdentifierExpr(Val, Identifier);
1226 UpdateLocLex = false;
1229 return Error(Tok.getLoc(), "Unexpected identifier!");
1231 case AsmToken::Integer: {
1233 if (isParsingInlineAsm() && SM.getAddImmPrefix())
1234 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_ImmPrefix,
1236 // Look for 'b' or 'f' following an Integer as a directional label
1237 SMLoc Loc = getTok().getLoc();
1238 int64_t IntVal = getTok().getIntVal();
1239 End = consumeToken();
1240 UpdateLocLex = false;
1241 if (getLexer().getKind() == AsmToken::Identifier) {
1242 StringRef IDVal = getTok().getString();
1243 if (IDVal == "f" || IDVal == "b") {
1245 getContext().getDirectionalLocalSymbol(IntVal, IDVal == "b");
1246 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1248 MCSymbolRefExpr::create(Sym, Variant, getContext());
1249 if (IDVal == "b" && Sym->isUndefined())
1250 return Error(Loc, "invalid reference to undefined symbol");
1251 StringRef Identifier = Sym->getName();
1252 SM.onIdentifierExpr(Val, Identifier);
1253 End = consumeToken();
1255 if (SM.onInteger(IntVal, ErrMsg))
1256 return Error(Loc, ErrMsg);
1259 if (SM.onInteger(IntVal, ErrMsg))
1260 return Error(Loc, ErrMsg);
1264 case AsmToken::Plus: SM.onPlus(); break;
1265 case AsmToken::Minus: SM.onMinus(); break;
1266 case AsmToken::Tilde: SM.onNot(); break;
1267 case AsmToken::Star: SM.onStar(); break;
1268 case AsmToken::Slash: SM.onDivide(); break;
1269 case AsmToken::Pipe: SM.onOr(); break;
1270 case AsmToken::Caret: SM.onXor(); break;
1271 case AsmToken::Amp: SM.onAnd(); break;
1272 case AsmToken::LessLess:
1273 SM.onLShift(); break;
1274 case AsmToken::GreaterGreater:
1275 SM.onRShift(); break;
1276 case AsmToken::LBrac: SM.onLBrac(); break;
1277 case AsmToken::RBrac: SM.onRBrac(); break;
1278 case AsmToken::LParen: SM.onLParen(); break;
1279 case AsmToken::RParen: SM.onRParen(); break;
1282 return Error(Tok.getLoc(), "unknown token in expression");
1284 if (!Done && UpdateLocLex)
1285 End = consumeToken();
1290 std::unique_ptr<X86Operand>
1291 X86AsmParser::ParseIntelBracExpression(unsigned SegReg, SMLoc Start,
1292 int64_t ImmDisp, unsigned Size) {
1293 MCAsmParser &Parser = getParser();
1294 const AsmToken &Tok = Parser.getTok();
1295 SMLoc BracLoc = Tok.getLoc(), End = Tok.getEndLoc();
1296 if (getLexer().isNot(AsmToken::LBrac))
1297 return ErrorOperand(BracLoc, "Expected '[' token!");
1298 Parser.Lex(); // Eat '['
1300 SMLoc StartInBrac = Tok.getLoc();
1301 // Parse [ Symbol + ImmDisp ] and [ BaseReg + Scale*IndexReg + ImmDisp ]. We
1302 // may have already parsed an immediate displacement before the bracketed
1304 IntelExprStateMachine SM(ImmDisp, /*StopOnLBrac=*/false, /*AddImmPrefix=*/true);
1305 if (ParseIntelExpression(SM, End))
1308 const MCExpr *Disp = nullptr;
1309 if (const MCExpr *Sym = SM.getSym()) {
1310 // A symbolic displacement.
1312 if (isParsingInlineAsm())
1313 RewriteIntelBracExpression(InstInfo->AsmRewrites, SM.getSymName(),
1314 ImmDisp, SM.getImm(), BracLoc, StartInBrac,
1318 if (SM.getImm() || !Disp) {
1319 const MCExpr *Imm = MCConstantExpr::create(SM.getImm(), getContext());
1321 Disp = MCBinaryExpr::createAdd(Disp, Imm, getContext());
1323 Disp = Imm; // An immediate displacement only.
1326 // Parse struct field access. Intel requires a dot, but MSVC doesn't. MSVC
1327 // will in fact do global lookup the field name inside all global typedefs,
1328 // but we don't emulate that.
1329 if (Tok.getString().find('.') != StringRef::npos) {
1330 const MCExpr *NewDisp;
1331 if (ParseIntelDotOperator(Disp, NewDisp))
1334 End = Tok.getEndLoc();
1335 Parser.Lex(); // Eat the field.
1339 int BaseReg = SM.getBaseReg();
1340 int IndexReg = SM.getIndexReg();
1341 int Scale = SM.getScale();
1342 if (!isParsingInlineAsm()) {
1344 if (!BaseReg && !IndexReg) {
1346 return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size);
1347 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
1351 if (CheckBaseRegAndIndexReg(BaseReg, IndexReg, ErrMsg)) {
1352 Error(StartInBrac, ErrMsg);
1355 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
1356 IndexReg, Scale, Start, End, Size);
1359 InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
1360 return CreateMemForInlineAsm(SegReg, Disp, BaseReg, IndexReg, Scale, Start,
1361 End, Size, SM.getSymName(), Info);
1364 // Inline assembly may use variable names with namespace alias qualifiers.
1365 bool X86AsmParser::ParseIntelIdentifier(const MCExpr *&Val,
1366 StringRef &Identifier,
1367 InlineAsmIdentifierInfo &Info,
1368 bool IsUnevaluatedOperand, SMLoc &End) {
1369 MCAsmParser &Parser = getParser();
1370 assert(isParsingInlineAsm() && "Expected to be parsing inline assembly.");
1373 StringRef LineBuf(Identifier.data());
1375 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);
1377 const AsmToken &Tok = Parser.getTok();
1378 SMLoc Loc = Tok.getLoc();
1380 // Advance the token stream until the end of the current token is
1381 // after the end of what the frontend claimed.
1382 const char *EndPtr = Tok.getLoc().getPointer() + LineBuf.size();
1384 End = Tok.getEndLoc();
1386 } while (End.getPointer() < EndPtr);
1387 Identifier = LineBuf;
1389 // The frontend should end parsing on an assembler token boundary, unless it
1391 assert((End.getPointer() == EndPtr || !Result) &&
1392 "frontend claimed part of a token?");
1394 // If the identifier lookup was unsuccessful, assume that we are dealing with
1397 StringRef InternalName =
1398 SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(),
1400 assert(InternalName.size() && "We should have an internal name here.");
1401 // Push a rewrite for replacing the identifier name with the internal name.
1402 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Label, Loc,
1407 // Create the symbol reference.
1408 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
1409 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1410 Val = MCSymbolRefExpr::create(Sym, Variant, getParser().getContext());
1414 /// \brief Parse intel style segment override.
1415 std::unique_ptr<X86Operand>
1416 X86AsmParser::ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start,
1418 MCAsmParser &Parser = getParser();
1419 assert(SegReg != 0 && "Tried to parse a segment override without a segment!");
1420 const AsmToken &Tok = Parser.getTok(); // Eat colon.
1421 if (Tok.isNot(AsmToken::Colon))
1422 return ErrorOperand(Tok.getLoc(), "Expected ':' token!");
1423 Parser.Lex(); // Eat ':'
1425 int64_t ImmDisp = 0;
1426 if (getLexer().is(AsmToken::Integer)) {
1427 ImmDisp = Tok.getIntVal();
1428 AsmToken ImmDispToken = Parser.Lex(); // Eat the integer.
1430 if (isParsingInlineAsm())
1431 InstInfo->AsmRewrites->push_back(
1432 AsmRewrite(AOK_ImmPrefix, ImmDispToken.getLoc()));
1434 if (getLexer().isNot(AsmToken::LBrac)) {
1435 // An immediate following a 'segment register', 'colon' token sequence can
1436 // be followed by a bracketed expression. If it isn't we know we have our
1437 // final segment override.
1438 const MCExpr *Disp = MCConstantExpr::create(ImmDisp, getContext());
1439 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp,
1440 /*BaseReg=*/0, /*IndexReg=*/0, /*Scale=*/1,
1441 Start, ImmDispToken.getEndLoc(), Size);
1445 if (getLexer().is(AsmToken::LBrac))
1446 return ParseIntelBracExpression(SegReg, Start, ImmDisp, Size);
1450 if (!isParsingInlineAsm()) {
1451 if (getParser().parsePrimaryExpr(Val, End))
1452 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1454 return X86Operand::CreateMem(getPointerWidth(), Val, Start, End, Size);
1457 InlineAsmIdentifierInfo Info;
1458 StringRef Identifier = Tok.getString();
1459 if (ParseIntelIdentifier(Val, Identifier, Info,
1460 /*Unevaluated=*/false, End))
1462 return CreateMemForInlineAsm(/*SegReg=*/0, Val, /*BaseReg=*/0,/*IndexReg=*/0,
1463 /*Scale=*/1, Start, End, Size, Identifier, Info);
1466 //ParseRoundingModeOp - Parse AVX-512 rounding mode operand
1467 std::unique_ptr<X86Operand>
1468 X86AsmParser::ParseRoundingModeOp(SMLoc Start, SMLoc End) {
1469 MCAsmParser &Parser = getParser();
1470 const AsmToken &Tok = Parser.getTok();
1471 // Eat "{" and mark the current place.
1472 const SMLoc consumedToken = consumeToken();
1473 if (Tok.getIdentifier().startswith("r")){
1474 int rndMode = StringSwitch<int>(Tok.getIdentifier())
1475 .Case("rn", X86::STATIC_ROUNDING::TO_NEAREST_INT)
1476 .Case("rd", X86::STATIC_ROUNDING::TO_NEG_INF)
1477 .Case("ru", X86::STATIC_ROUNDING::TO_POS_INF)
1478 .Case("rz", X86::STATIC_ROUNDING::TO_ZERO)
1481 return ErrorOperand(Tok.getLoc(), "Invalid rounding mode.");
1482 Parser.Lex(); // Eat "r*" of r*-sae
1483 if (!getLexer().is(AsmToken::Minus))
1484 return ErrorOperand(Tok.getLoc(), "Expected - at this point");
1485 Parser.Lex(); // Eat "-"
1486 Parser.Lex(); // Eat the sae
1487 if (!getLexer().is(AsmToken::RCurly))
1488 return ErrorOperand(Tok.getLoc(), "Expected } at this point");
1489 Parser.Lex(); // Eat "}"
1490 const MCExpr *RndModeOp =
1491 MCConstantExpr::create(rndMode, Parser.getContext());
1492 return X86Operand::CreateImm(RndModeOp, Start, End);
1494 if(Tok.getIdentifier().equals("sae")){
1495 Parser.Lex(); // Eat the sae
1496 if (!getLexer().is(AsmToken::RCurly))
1497 return ErrorOperand(Tok.getLoc(), "Expected } at this point");
1498 Parser.Lex(); // Eat "}"
1499 return X86Operand::CreateToken("{sae}", consumedToken);
1501 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1503 /// ParseIntelMemOperand - Parse intel style memory operand.
1504 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelMemOperand(int64_t ImmDisp,
1507 MCAsmParser &Parser = getParser();
1508 const AsmToken &Tok = Parser.getTok();
1511 // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
1512 if (getLexer().is(AsmToken::LBrac))
1513 return ParseIntelBracExpression(/*SegReg=*/0, Start, ImmDisp, Size);
1514 assert(ImmDisp == 0);
1517 if (!isParsingInlineAsm()) {
1518 if (getParser().parsePrimaryExpr(Val, End))
1519 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1521 return X86Operand::CreateMem(getPointerWidth(), Val, Start, End, Size);
1524 InlineAsmIdentifierInfo Info;
1525 StringRef Identifier = Tok.getString();
1526 if (ParseIntelIdentifier(Val, Identifier, Info,
1527 /*Unevaluated=*/false, End))
1530 if (!getLexer().is(AsmToken::LBrac))
1531 return CreateMemForInlineAsm(/*SegReg=*/0, Val, /*BaseReg=*/0, /*IndexReg=*/0,
1532 /*Scale=*/1, Start, End, Size, Identifier, Info);
1534 Parser.Lex(); // Eat '['
1536 // Parse Identifier [ ImmDisp ]
1537 IntelExprStateMachine SM(/*ImmDisp=*/0, /*StopOnLBrac=*/true,
1538 /*AddImmPrefix=*/false);
1539 if (ParseIntelExpression(SM, End))
1543 Error(Start, "cannot use more than one symbol in memory operand");
1546 if (SM.getBaseReg()) {
1547 Error(Start, "cannot use base register with variable reference");
1550 if (SM.getIndexReg()) {
1551 Error(Start, "cannot use index register with variable reference");
1555 const MCExpr *Disp = MCConstantExpr::create(SM.getImm(), getContext());
1556 // BaseReg is non-zero to avoid assertions. In the context of inline asm,
1557 // we're pointing to a local variable in memory, so the base register is
1558 // really the frame or stack pointer.
1559 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
1560 /*BaseReg=*/1, /*IndexReg=*/0, /*Scale=*/1,
1561 Start, End, Size, Identifier, Info.OpDecl);
1564 /// Parse the '.' operator.
1565 bool X86AsmParser::ParseIntelDotOperator(const MCExpr *Disp,
1566 const MCExpr *&NewDisp) {
1567 MCAsmParser &Parser = getParser();
1568 const AsmToken &Tok = Parser.getTok();
1569 int64_t OrigDispVal, DotDispVal;
1571 // FIXME: Handle non-constant expressions.
1572 if (const MCConstantExpr *OrigDisp = dyn_cast<MCConstantExpr>(Disp))
1573 OrigDispVal = OrigDisp->getValue();
1575 return Error(Tok.getLoc(), "Non-constant offsets are not supported!");
1577 // Drop the optional '.'.
1578 StringRef DotDispStr = Tok.getString();
1579 if (DotDispStr.startswith("."))
1580 DotDispStr = DotDispStr.drop_front(1);
1582 // .Imm gets lexed as a real.
1583 if (Tok.is(AsmToken::Real)) {
1585 DotDispStr.getAsInteger(10, DotDisp);
1586 DotDispVal = DotDisp.getZExtValue();
1587 } else if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) {
1589 std::pair<StringRef, StringRef> BaseMember = DotDispStr.split('.');
1590 if (SemaCallback->LookupInlineAsmField(BaseMember.first, BaseMember.second,
1592 return Error(Tok.getLoc(), "Unable to lookup field reference!");
1593 DotDispVal = DotDisp;
1595 return Error(Tok.getLoc(), "Unexpected token type!");
1597 if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) {
1598 SMLoc Loc = SMLoc::getFromPointer(DotDispStr.data());
1599 unsigned Len = DotDispStr.size();
1600 unsigned Val = OrigDispVal + DotDispVal;
1601 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_DotOperator, Loc, Len,
1605 NewDisp = MCConstantExpr::create(OrigDispVal + DotDispVal, getContext());
1609 /// Parse the 'offset' operator. This operator is used to specify the
1610 /// location rather then the content of a variable.
1611 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOffsetOfOperator() {
1612 MCAsmParser &Parser = getParser();
1613 const AsmToken &Tok = Parser.getTok();
1614 SMLoc OffsetOfLoc = Tok.getLoc();
1615 Parser.Lex(); // Eat offset.
1618 InlineAsmIdentifierInfo Info;
1619 SMLoc Start = Tok.getLoc(), End;
1620 StringRef Identifier = Tok.getString();
1621 if (ParseIntelIdentifier(Val, Identifier, Info,
1622 /*Unevaluated=*/false, End))
1625 // Don't emit the offset operator.
1626 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Skip, OffsetOfLoc, 7));
1628 // The offset operator will have an 'r' constraint, thus we need to create
1629 // register operand to ensure proper matching. Just pick a GPR based on
1630 // the size of a pointer.
1632 is64BitMode() ? X86::RBX : (is32BitMode() ? X86::EBX : X86::BX);
1633 return X86Operand::CreateReg(RegNo, Start, End, /*GetAddress=*/true,
1634 OffsetOfLoc, Identifier, Info.OpDecl);
1637 enum IntelOperatorKind {
1643 /// Parse the 'LENGTH', 'TYPE' and 'SIZE' operators. The LENGTH operator
1644 /// returns the number of elements in an array. It returns the value 1 for
1645 /// non-array variables. The SIZE operator returns the size of a C or C++
1646 /// variable. A variable's size is the product of its LENGTH and TYPE. The
1647 /// TYPE operator returns the size of a C or C++ type or variable. If the
1648 /// variable is an array, TYPE returns the size of a single element.
1649 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperator(unsigned OpKind) {
1650 MCAsmParser &Parser = getParser();
1651 const AsmToken &Tok = Parser.getTok();
1652 SMLoc TypeLoc = Tok.getLoc();
1653 Parser.Lex(); // Eat operator.
1655 const MCExpr *Val = nullptr;
1656 InlineAsmIdentifierInfo Info;
1657 SMLoc Start = Tok.getLoc(), End;
1658 StringRef Identifier = Tok.getString();
1659 if (ParseIntelIdentifier(Val, Identifier, Info,
1660 /*Unevaluated=*/true, End))
1664 return ErrorOperand(Start, "unable to lookup expression");
1668 default: llvm_unreachable("Unexpected operand kind!");
1669 case IOK_LENGTH: CVal = Info.Length; break;
1670 case IOK_SIZE: CVal = Info.Size; break;
1671 case IOK_TYPE: CVal = Info.Type; break;
1674 // Rewrite the type operator and the C or C++ type or variable in terms of an
1675 // immediate. E.g. TYPE foo -> $$4
1676 unsigned Len = End.getPointer() - TypeLoc.getPointer();
1677 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Imm, TypeLoc, Len, CVal));
1679 const MCExpr *Imm = MCConstantExpr::create(CVal, getContext());
1680 return X86Operand::CreateImm(Imm, Start, End);
1683 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand() {
1684 MCAsmParser &Parser = getParser();
1685 const AsmToken &Tok = Parser.getTok();
1688 // Offset, length, type and size operators.
1689 if (isParsingInlineAsm()) {
1690 StringRef AsmTokStr = Tok.getString();
1691 if (AsmTokStr == "offset" || AsmTokStr == "OFFSET")
1692 return ParseIntelOffsetOfOperator();
1693 if (AsmTokStr == "length" || AsmTokStr == "LENGTH")
1694 return ParseIntelOperator(IOK_LENGTH);
1695 if (AsmTokStr == "size" || AsmTokStr == "SIZE")
1696 return ParseIntelOperator(IOK_SIZE);
1697 if (AsmTokStr == "type" || AsmTokStr == "TYPE")
1698 return ParseIntelOperator(IOK_TYPE);
1701 unsigned Size = getIntelMemOperandSize(Tok.getString());
1703 Parser.Lex(); // Eat operand size (e.g., byte, word).
1704 if (Tok.getString() != "PTR" && Tok.getString() != "ptr")
1705 return ErrorOperand(Tok.getLoc(), "Expected 'PTR' or 'ptr' token!");
1706 Parser.Lex(); // Eat ptr.
1708 Start = Tok.getLoc();
1711 if (getLexer().is(AsmToken::Integer) || getLexer().is(AsmToken::Minus) ||
1712 getLexer().is(AsmToken::Tilde) || getLexer().is(AsmToken::LParen)) {
1713 AsmToken StartTok = Tok;
1714 IntelExprStateMachine SM(/*Imm=*/0, /*StopOnLBrac=*/true,
1715 /*AddImmPrefix=*/false);
1716 if (ParseIntelExpression(SM, End))
1719 int64_t Imm = SM.getImm();
1720 if (isParsingInlineAsm()) {
1721 unsigned Len = Tok.getLoc().getPointer() - Start.getPointer();
1722 if (StartTok.getString().size() == Len)
1723 // Just add a prefix if this wasn't a complex immediate expression.
1724 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_ImmPrefix, Start));
1726 // Otherwise, rewrite the complex expression as a single immediate.
1727 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Imm, Start, Len, Imm));
1730 if (getLexer().isNot(AsmToken::LBrac)) {
1731 // If a directional label (ie. 1f or 2b) was parsed above from
1732 // ParseIntelExpression() then SM.getSym() was set to a pointer to
1733 // to the MCExpr with the directional local symbol and this is a
1734 // memory operand not an immediate operand.
1736 return X86Operand::CreateMem(getPointerWidth(), SM.getSym(), Start, End,
1739 const MCExpr *ImmExpr = MCConstantExpr::create(Imm, getContext());
1740 return X86Operand::CreateImm(ImmExpr, Start, End);
1743 // Only positive immediates are valid.
1745 return ErrorOperand(Start, "expected a positive immediate displacement "
1746 "before bracketed expr.");
1748 // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
1749 return ParseIntelMemOperand(Imm, Start, Size);
1752 // rounding mode token
1753 if (STI.getFeatureBits()[X86::FeatureAVX512] &&
1754 getLexer().is(AsmToken::LCurly))
1755 return ParseRoundingModeOp(Start, End);
1759 if (!ParseRegister(RegNo, Start, End)) {
1760 // If this is a segment register followed by a ':', then this is the start
1761 // of a segment override, otherwise this is a normal register reference.
1762 if (getLexer().isNot(AsmToken::Colon))
1763 return X86Operand::CreateReg(RegNo, Start, End);
1765 return ParseIntelSegmentOverride(/*SegReg=*/RegNo, Start, Size);
1769 return ParseIntelMemOperand(/*Disp=*/0, Start, Size);
1772 std::unique_ptr<X86Operand> X86AsmParser::ParseATTOperand() {
1773 MCAsmParser &Parser = getParser();
1774 switch (getLexer().getKind()) {
1776 // Parse a memory operand with no segment register.
1777 return ParseMemOperand(0, Parser.getTok().getLoc());
1778 case AsmToken::Percent: {
1779 // Read the register.
1782 if (ParseRegister(RegNo, Start, End)) return nullptr;
1783 if (RegNo == X86::EIZ || RegNo == X86::RIZ) {
1784 Error(Start, "%eiz and %riz can only be used as index registers",
1785 SMRange(Start, End));
1789 // If this is a segment register followed by a ':', then this is the start
1790 // of a memory reference, otherwise this is a normal register reference.
1791 if (getLexer().isNot(AsmToken::Colon))
1792 return X86Operand::CreateReg(RegNo, Start, End);
1794 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo))
1795 return ErrorOperand(Start, "invalid segment register");
1797 getParser().Lex(); // Eat the colon.
1798 return ParseMemOperand(RegNo, Start);
1800 case AsmToken::Dollar: {
1801 // $42 -> immediate.
1802 SMLoc Start = Parser.getTok().getLoc(), End;
1805 if (getParser().parseExpression(Val, End))
1807 return X86Operand::CreateImm(Val, Start, End);
1809 case AsmToken::LCurly:{
1810 SMLoc Start = Parser.getTok().getLoc(), End;
1811 if (STI.getFeatureBits()[X86::FeatureAVX512])
1812 return ParseRoundingModeOp(Start, End);
1813 return ErrorOperand(Start, "unknown token in expression");
1818 bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands,
1819 const MCParsedAsmOperand &Op) {
1820 MCAsmParser &Parser = getParser();
1821 if(STI.getFeatureBits()[X86::FeatureAVX512]) {
1822 if (getLexer().is(AsmToken::LCurly)) {
1823 // Eat "{" and mark the current place.
1824 const SMLoc consumedToken = consumeToken();
1825 // Distinguish {1to<NUM>} from {%k<NUM>}.
1826 if(getLexer().is(AsmToken::Integer)) {
1827 // Parse memory broadcasting ({1to<NUM>}).
1828 if (getLexer().getTok().getIntVal() != 1)
1829 return !ErrorAndEatStatement(getLexer().getLoc(),
1830 "Expected 1to<NUM> at this point");
1831 Parser.Lex(); // Eat "1" of 1to8
1832 if (!getLexer().is(AsmToken::Identifier) ||
1833 !getLexer().getTok().getIdentifier().startswith("to"))
1834 return !ErrorAndEatStatement(getLexer().getLoc(),
1835 "Expected 1to<NUM> at this point");
1836 // Recognize only reasonable suffixes.
1837 const char *BroadcastPrimitive =
1838 StringSwitch<const char*>(getLexer().getTok().getIdentifier())
1839 .Case("to2", "{1to2}")
1840 .Case("to4", "{1to4}")
1841 .Case("to8", "{1to8}")
1842 .Case("to16", "{1to16}")
1844 if (!BroadcastPrimitive)
1845 return !ErrorAndEatStatement(getLexer().getLoc(),
1846 "Invalid memory broadcast primitive.");
1847 Parser.Lex(); // Eat "toN" of 1toN
1848 if (!getLexer().is(AsmToken::RCurly))
1849 return !ErrorAndEatStatement(getLexer().getLoc(),
1850 "Expected } at this point");
1851 Parser.Lex(); // Eat "}"
1852 Operands.push_back(X86Operand::CreateToken(BroadcastPrimitive,
1854 // No AVX512 specific primitives can pass
1855 // after memory broadcasting, so return.
1858 // Parse mask register {%k1}
1859 Operands.push_back(X86Operand::CreateToken("{", consumedToken));
1860 if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
1861 Operands.push_back(std::move(Op));
1862 if (!getLexer().is(AsmToken::RCurly))
1863 return !ErrorAndEatStatement(getLexer().getLoc(),
1864 "Expected } at this point");
1865 Operands.push_back(X86Operand::CreateToken("}", consumeToken()));
1867 // Parse "zeroing non-masked" semantic {z}
1868 if (getLexer().is(AsmToken::LCurly)) {
1869 Operands.push_back(X86Operand::CreateToken("{z}", consumeToken()));
1870 if (!getLexer().is(AsmToken::Identifier) ||
1871 getLexer().getTok().getIdentifier() != "z")
1872 return !ErrorAndEatStatement(getLexer().getLoc(),
1873 "Expected z at this point");
1874 Parser.Lex(); // Eat the z
1875 if (!getLexer().is(AsmToken::RCurly))
1876 return !ErrorAndEatStatement(getLexer().getLoc(),
1877 "Expected } at this point");
1878 Parser.Lex(); // Eat the }
1887 /// ParseMemOperand: segment: disp(basereg, indexreg, scale). The '%ds:' prefix
1888 /// has already been parsed if present.
1889 std::unique_ptr<X86Operand> X86AsmParser::ParseMemOperand(unsigned SegReg,
1892 MCAsmParser &Parser = getParser();
1893 // We have to disambiguate a parenthesized expression "(4+5)" from the start
1894 // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)". The
1895 // only way to do this without lookahead is to eat the '(' and see what is
1897 const MCExpr *Disp = MCConstantExpr::create(0, getParser().getContext());
1898 if (getLexer().isNot(AsmToken::LParen)) {
1900 if (getParser().parseExpression(Disp, ExprEnd)) return nullptr;
1902 // After parsing the base expression we could either have a parenthesized
1903 // memory address or not. If not, return now. If so, eat the (.
1904 if (getLexer().isNot(AsmToken::LParen)) {
1905 // Unless we have a segment register, treat this as an immediate.
1907 return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, ExprEnd);
1908 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
1915 // Okay, we have a '('. We don't know if this is an expression or not, but
1916 // so we have to eat the ( to see beyond it.
1917 SMLoc LParenLoc = Parser.getTok().getLoc();
1918 Parser.Lex(); // Eat the '('.
1920 if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) {
1921 // Nothing to do here, fall into the code below with the '(' part of the
1922 // memory operand consumed.
1926 // It must be an parenthesized expression, parse it now.
1927 if (getParser().parseParenExpression(Disp, ExprEnd))
1930 // After parsing the base expression we could either have a parenthesized
1931 // memory address or not. If not, return now. If so, eat the (.
1932 if (getLexer().isNot(AsmToken::LParen)) {
1933 // Unless we have a segment register, treat this as an immediate.
1935 return X86Operand::CreateMem(getPointerWidth(), Disp, LParenLoc,
1937 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
1946 // If we reached here, then we just ate the ( of the memory operand. Process
1947 // the rest of the memory operand.
1948 unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
1949 SMLoc IndexLoc, BaseLoc;
1951 if (getLexer().is(AsmToken::Percent)) {
1952 SMLoc StartLoc, EndLoc;
1953 BaseLoc = Parser.getTok().getLoc();
1954 if (ParseRegister(BaseReg, StartLoc, EndLoc)) return nullptr;
1955 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) {
1956 Error(StartLoc, "eiz and riz can only be used as index registers",
1957 SMRange(StartLoc, EndLoc));
1962 if (getLexer().is(AsmToken::Comma)) {
1963 Parser.Lex(); // Eat the comma.
1964 IndexLoc = Parser.getTok().getLoc();
1966 // Following the comma we should have either an index register, or a scale
1967 // value. We don't support the later form, but we want to parse it
1970 // Not that even though it would be completely consistent to support syntax
1971 // like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this.
1972 if (getLexer().is(AsmToken::Percent)) {
1974 if (ParseRegister(IndexReg, L, L)) return nullptr;
1976 if (getLexer().isNot(AsmToken::RParen)) {
1977 // Parse the scale amount:
1978 // ::= ',' [scale-expression]
1979 if (getLexer().isNot(AsmToken::Comma)) {
1980 Error(Parser.getTok().getLoc(),
1981 "expected comma in scale expression");
1984 Parser.Lex(); // Eat the comma.
1986 if (getLexer().isNot(AsmToken::RParen)) {
1987 SMLoc Loc = Parser.getTok().getLoc();
1990 if (getParser().parseAbsoluteExpression(ScaleVal)){
1991 Error(Loc, "expected scale expression");
1995 // Validate the scale amount.
1996 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
1998 Error(Loc, "scale factor in 16-bit address must be 1");
2001 if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8){
2002 Error(Loc, "scale factor in address must be 1, 2, 4 or 8");
2005 Scale = (unsigned)ScaleVal;
2008 } else if (getLexer().isNot(AsmToken::RParen)) {
2009 // A scale amount without an index is ignored.
2011 SMLoc Loc = Parser.getTok().getLoc();
2014 if (getParser().parseAbsoluteExpression(Value))
2018 Warning(Loc, "scale factor without index register is ignored");
2023 // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
2024 if (getLexer().isNot(AsmToken::RParen)) {
2025 Error(Parser.getTok().getLoc(), "unexpected token in memory operand");
2028 SMLoc MemEnd = Parser.getTok().getEndLoc();
2029 Parser.Lex(); // Eat the ')'.
2031 // Check for use of invalid 16-bit registers. Only BX/BP/SI/DI are allowed,
2032 // and then only in non-64-bit modes. Except for DX, which is a special case
2033 // because an unofficial form of in/out instructions uses it.
2034 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
2035 (is64BitMode() || (BaseReg != X86::BX && BaseReg != X86::BP &&
2036 BaseReg != X86::SI && BaseReg != X86::DI)) &&
2037 BaseReg != X86::DX) {
2038 Error(BaseLoc, "invalid 16-bit base register");
2042 X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg)) {
2043 Error(IndexLoc, "16-bit memory operand may not include only index register");
2048 if (CheckBaseRegAndIndexReg(BaseReg, IndexReg, ErrMsg)) {
2049 Error(BaseLoc, ErrMsg);
2053 if (SegReg || BaseReg || IndexReg)
2054 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
2055 IndexReg, Scale, MemStart, MemEnd);
2056 return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, MemEnd);
2059 bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2060 SMLoc NameLoc, OperandVector &Operands) {
2061 MCAsmParser &Parser = getParser();
2063 StringRef PatchedName = Name;
2065 // FIXME: Hack to recognize setneb as setne.
2066 if (PatchedName.startswith("set") && PatchedName.endswith("b") &&
2067 PatchedName != "setb" && PatchedName != "setnb")
2068 PatchedName = PatchedName.substr(0, Name.size()-1);
2070 // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}.
2071 if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) &&
2072 (PatchedName.endswith("ss") || PatchedName.endswith("sd") ||
2073 PatchedName.endswith("ps") || PatchedName.endswith("pd"))) {
2074 bool IsVCMP = PatchedName[0] == 'v';
2075 unsigned CCIdx = IsVCMP ? 4 : 3;
2076 unsigned ComparisonCode = StringSwitch<unsigned>(
2077 PatchedName.slice(CCIdx, PatchedName.size() - 2))
2081 .Case("unord", 0x03)
2086 /* AVX only from here */
2087 .Case("eq_uq", 0x08)
2090 .Case("false", 0x0B)
2091 .Case("neq_oq", 0x0C)
2095 .Case("eq_os", 0x10)
2096 .Case("lt_oq", 0x11)
2097 .Case("le_oq", 0x12)
2098 .Case("unord_s", 0x13)
2099 .Case("neq_us", 0x14)
2100 .Case("nlt_uq", 0x15)
2101 .Case("nle_uq", 0x16)
2102 .Case("ord_s", 0x17)
2103 .Case("eq_us", 0x18)
2104 .Case("nge_uq", 0x19)
2105 .Case("ngt_uq", 0x1A)
2106 .Case("false_os", 0x1B)
2107 .Case("neq_os", 0x1C)
2108 .Case("ge_oq", 0x1D)
2109 .Case("gt_oq", 0x1E)
2110 .Case("true_us", 0x1F)
2112 if (ComparisonCode != ~0U && (IsVCMP || ComparisonCode < 8)) {
2114 Operands.push_back(X86Operand::CreateToken(PatchedName.slice(0, CCIdx),
2117 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2118 getParser().getContext());
2119 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2121 PatchedName = PatchedName.substr(PatchedName.size() - 2);
2125 // FIXME: Hack to recognize vpcmp<comparison code>{ub,uw,ud,uq,b,w,d,q}.
2126 if (PatchedName.startswith("vpcmp") &&
2127 (PatchedName.endswith("b") || PatchedName.endswith("w") ||
2128 PatchedName.endswith("d") || PatchedName.endswith("q"))) {
2129 unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1;
2130 unsigned ComparisonCode = StringSwitch<unsigned>(
2131 PatchedName.slice(5, PatchedName.size() - CCIdx))
2132 .Case("eq", 0x0) // Only allowed on unsigned. Checked below.
2135 //.Case("false", 0x3) // Not a documented alias.
2139 //.Case("true", 0x7) // Not a documented alias.
2141 if (ComparisonCode != ~0U && (ComparisonCode != 0 || CCIdx == 2)) {
2142 Operands.push_back(X86Operand::CreateToken("vpcmp", NameLoc));
2144 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2145 getParser().getContext());
2146 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2148 PatchedName = PatchedName.substr(PatchedName.size() - CCIdx);
2152 // FIXME: Hack to recognize vpcom<comparison code>{ub,uw,ud,uq,b,w,d,q}.
2153 if (PatchedName.startswith("vpcom") &&
2154 (PatchedName.endswith("b") || PatchedName.endswith("w") ||
2155 PatchedName.endswith("d") || PatchedName.endswith("q"))) {
2156 unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1;
2157 unsigned ComparisonCode = StringSwitch<unsigned>(
2158 PatchedName.slice(5, PatchedName.size() - CCIdx))
2168 if (ComparisonCode != ~0U) {
2169 Operands.push_back(X86Operand::CreateToken("vpcom", NameLoc));
2171 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2172 getParser().getContext());
2173 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2175 PatchedName = PatchedName.substr(PatchedName.size() - CCIdx);
2179 Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
2181 // Determine whether this is an instruction prefix.
2183 Name == "lock" || Name == "rep" ||
2184 Name == "repe" || Name == "repz" ||
2185 Name == "repne" || Name == "repnz" ||
2186 Name == "rex64" || Name == "data16";
2189 // This does the actual operand parsing. Don't parse any more if we have a
2190 // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we
2191 // just want to parse the "lock" as the first instruction and the "incl" as
2193 if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) {
2195 // Parse '*' modifier.
2196 if (getLexer().is(AsmToken::Star))
2197 Operands.push_back(X86Operand::CreateToken("*", consumeToken()));
2199 // Read the operands.
2201 if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
2202 Operands.push_back(std::move(Op));
2203 if (!HandleAVX512Operand(Operands, *Operands.back()))
2206 Parser.eatToEndOfStatement();
2209 // check for comma and eat it
2210 if (getLexer().is(AsmToken::Comma))
2216 if (getLexer().isNot(AsmToken::EndOfStatement))
2217 return ErrorAndEatStatement(getLexer().getLoc(),
2218 "unexpected token in argument list");
2221 // Consume the EndOfStatement or the prefix separator Slash
2222 if (getLexer().is(AsmToken::EndOfStatement) ||
2223 (isPrefix && getLexer().is(AsmToken::Slash)))
2226 // This is a terrible hack to handle "out[bwl]? %al, (%dx)" ->
2227 // "outb %al, %dx". Out doesn't take a memory form, but this is a widely
2228 // documented form in various unofficial manuals, so a lot of code uses it.
2229 if ((Name == "outb" || Name == "outw" || Name == "outl" || Name == "out") &&
2230 Operands.size() == 3) {
2231 X86Operand &Op = (X86Operand &)*Operands.back();
2232 if (Op.isMem() && Op.Mem.SegReg == 0 &&
2233 isa<MCConstantExpr>(Op.Mem.Disp) &&
2234 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
2235 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
2236 SMLoc Loc = Op.getEndLoc();
2237 Operands.back() = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
2240 // Same hack for "in[bwl]? (%dx), %al" -> "inb %dx, %al".
2241 if ((Name == "inb" || Name == "inw" || Name == "inl" || Name == "in") &&
2242 Operands.size() == 3) {
2243 X86Operand &Op = (X86Operand &)*Operands[1];
2244 if (Op.isMem() && Op.Mem.SegReg == 0 &&
2245 isa<MCConstantExpr>(Op.Mem.Disp) &&
2246 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
2247 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
2248 SMLoc Loc = Op.getEndLoc();
2249 Operands[1] = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
2253 // Append default arguments to "ins[bwld]"
2254 if (Name.startswith("ins") && Operands.size() == 1 &&
2255 (Name == "insb" || Name == "insw" || Name == "insl" || Name == "insd")) {
2256 AddDefaultSrcDestOperands(Operands,
2257 X86Operand::CreateReg(X86::DX, NameLoc, NameLoc),
2258 DefaultMemDIOperand(NameLoc));
2261 // Append default arguments to "outs[bwld]"
2262 if (Name.startswith("outs") && Operands.size() == 1 &&
2263 (Name == "outsb" || Name == "outsw" || Name == "outsl" ||
2264 Name == "outsd" )) {
2265 AddDefaultSrcDestOperands(Operands,
2266 DefaultMemSIOperand(NameLoc),
2267 X86Operand::CreateReg(X86::DX, NameLoc, NameLoc));
2270 // Transform "lods[bwlq]" into "lods[bwlq] ($SIREG)" for appropriate
2271 // values of $SIREG according to the mode. It would be nice if this
2272 // could be achieved with InstAlias in the tables.
2273 if (Name.startswith("lods") && Operands.size() == 1 &&
2274 (Name == "lods" || Name == "lodsb" || Name == "lodsw" ||
2275 Name == "lodsl" || Name == "lodsd" || Name == "lodsq"))
2276 Operands.push_back(DefaultMemSIOperand(NameLoc));
2278 // Transform "stos[bwlq]" into "stos[bwlq] ($DIREG)" for appropriate
2279 // values of $DIREG according to the mode. It would be nice if this
2280 // could be achieved with InstAlias in the tables.
2281 if (Name.startswith("stos") && Operands.size() == 1 &&
2282 (Name == "stos" || Name == "stosb" || Name == "stosw" ||
2283 Name == "stosl" || Name == "stosd" || Name == "stosq"))
2284 Operands.push_back(DefaultMemDIOperand(NameLoc));
2286 // Transform "scas[bwlq]" into "scas[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("scas") && Operands.size() == 1 &&
2290 (Name == "scas" || Name == "scasb" || Name == "scasw" ||
2291 Name == "scasl" || Name == "scasd" || Name == "scasq"))
2292 Operands.push_back(DefaultMemDIOperand(NameLoc));
2294 // Add default SI and DI operands to "cmps[bwlq]".
2295 if (Name.startswith("cmps") &&
2296 (Name == "cmps" || Name == "cmpsb" || Name == "cmpsw" ||
2297 Name == "cmpsl" || Name == "cmpsd" || Name == "cmpsq")) {
2298 if (Operands.size() == 1) {
2299 AddDefaultSrcDestOperands(Operands,
2300 DefaultMemDIOperand(NameLoc),
2301 DefaultMemSIOperand(NameLoc));
2302 } else if (Operands.size() == 3) {
2303 X86Operand &Op = (X86Operand &)*Operands[1];
2304 X86Operand &Op2 = (X86Operand &)*Operands[2];
2305 if (!doSrcDstMatch(Op, Op2))
2306 return Error(Op.getStartLoc(),
2307 "mismatching source and destination index registers");
2311 // Add default SI and DI operands to "movs[bwlq]".
2312 if ((Name.startswith("movs") &&
2313 (Name == "movs" || Name == "movsb" || Name == "movsw" ||
2314 Name == "movsl" || Name == "movsd" || Name == "movsq")) ||
2315 (Name.startswith("smov") &&
2316 (Name == "smov" || Name == "smovb" || Name == "smovw" ||
2317 Name == "smovl" || Name == "smovd" || Name == "smovq"))) {
2318 if (Operands.size() == 1) {
2319 if (Name == "movsd")
2320 Operands.back() = X86Operand::CreateToken("movsl", NameLoc);
2321 AddDefaultSrcDestOperands(Operands,
2322 DefaultMemSIOperand(NameLoc),
2323 DefaultMemDIOperand(NameLoc));
2324 } else if (Operands.size() == 3) {
2325 X86Operand &Op = (X86Operand &)*Operands[1];
2326 X86Operand &Op2 = (X86Operand &)*Operands[2];
2327 if (!doSrcDstMatch(Op, Op2))
2328 return Error(Op.getStartLoc(),
2329 "mismatching source and destination index registers");
2333 // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>. Canonicalize to
2335 if ((Name.startswith("shr") || Name.startswith("sar") ||
2336 Name.startswith("shl") || Name.startswith("sal") ||
2337 Name.startswith("rcl") || Name.startswith("rcr") ||
2338 Name.startswith("rol") || Name.startswith("ror")) &&
2339 Operands.size() == 3) {
2340 if (isParsingIntelSyntax()) {
2342 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[2]);
2343 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2344 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2345 Operands.pop_back();
2347 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2348 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2349 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2350 Operands.erase(Operands.begin() + 1);
2354 // Transforms "int $3" into "int3" as a size optimization. We can't write an
2355 // instalias with an immediate operand yet.
2356 if (Name == "int" && Operands.size() == 2) {
2357 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2359 if (auto *CE = dyn_cast<MCConstantExpr>(Op1.getImm()))
2360 if (CE->getValue() == 3) {
2361 Operands.erase(Operands.begin() + 1);
2362 static_cast<X86Operand &>(*Operands[0]).setTokenValue("int3");
2369 static bool convertToSExti8(MCInst &Inst, unsigned Opcode, unsigned Reg,
2372 TmpInst.setOpcode(Opcode);
2374 TmpInst.addOperand(MCOperand::createReg(Reg));
2375 TmpInst.addOperand(MCOperand::createReg(Reg));
2376 TmpInst.addOperand(Inst.getOperand(0));
2381 static bool convert16i16to16ri8(MCInst &Inst, unsigned Opcode,
2382 bool isCmp = false) {
2383 if (!Inst.getOperand(0).isImm() ||
2384 !isImmSExti16i8Value(Inst.getOperand(0).getImm()))
2387 return convertToSExti8(Inst, Opcode, X86::AX, isCmp);
2390 static bool convert32i32to32ri8(MCInst &Inst, unsigned Opcode,
2391 bool isCmp = false) {
2392 if (!Inst.getOperand(0).isImm() ||
2393 !isImmSExti32i8Value(Inst.getOperand(0).getImm()))
2396 return convertToSExti8(Inst, Opcode, X86::EAX, isCmp);
2399 static bool convert64i32to64ri8(MCInst &Inst, unsigned Opcode,
2400 bool isCmp = false) {
2401 if (!Inst.getOperand(0).isImm() ||
2402 !isImmSExti64i8Value(Inst.getOperand(0).getImm()))
2405 return convertToSExti8(Inst, Opcode, X86::RAX, isCmp);
2408 bool X86AsmParser::validateInstruction(MCInst &Inst, const OperandVector &Ops) {
2409 switch (Inst.getOpcode()) {
2410 default: return true;
2412 X86Operand &Op = static_cast<X86Operand &>(*Ops[1]);
2413 assert(Op.isImm() && "expected immediate");
2415 if (!Op.getImm()->evaluateAsAbsolute(Res) || Res > 255) {
2416 Error(Op.getStartLoc(), "interrupt vector must be in range [0-255]");
2421 llvm_unreachable("handle the instruction appropriately");
2424 bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) {
2425 switch (Inst.getOpcode()) {
2426 default: return false;
2427 case X86::AND16i16: return convert16i16to16ri8(Inst, X86::AND16ri8);
2428 case X86::AND32i32: return convert32i32to32ri8(Inst, X86::AND32ri8);
2429 case X86::AND64i32: return convert64i32to64ri8(Inst, X86::AND64ri8);
2430 case X86::XOR16i16: return convert16i16to16ri8(Inst, X86::XOR16ri8);
2431 case X86::XOR32i32: return convert32i32to32ri8(Inst, X86::XOR32ri8);
2432 case X86::XOR64i32: return convert64i32to64ri8(Inst, X86::XOR64ri8);
2433 case X86::OR16i16: return convert16i16to16ri8(Inst, X86::OR16ri8);
2434 case X86::OR32i32: return convert32i32to32ri8(Inst, X86::OR32ri8);
2435 case X86::OR64i32: return convert64i32to64ri8(Inst, X86::OR64ri8);
2436 case X86::CMP16i16: return convert16i16to16ri8(Inst, X86::CMP16ri8, true);
2437 case X86::CMP32i32: return convert32i32to32ri8(Inst, X86::CMP32ri8, true);
2438 case X86::CMP64i32: return convert64i32to64ri8(Inst, X86::CMP64ri8, true);
2439 case X86::ADD16i16: return convert16i16to16ri8(Inst, X86::ADD16ri8);
2440 case X86::ADD32i32: return convert32i32to32ri8(Inst, X86::ADD32ri8);
2441 case X86::ADD64i32: return convert64i32to64ri8(Inst, X86::ADD64ri8);
2442 case X86::SUB16i16: return convert16i16to16ri8(Inst, X86::SUB16ri8);
2443 case X86::SUB32i32: return convert32i32to32ri8(Inst, X86::SUB32ri8);
2444 case X86::SUB64i32: return convert64i32to64ri8(Inst, X86::SUB64ri8);
2445 case X86::ADC16i16: return convert16i16to16ri8(Inst, X86::ADC16ri8);
2446 case X86::ADC32i32: return convert32i32to32ri8(Inst, X86::ADC32ri8);
2447 case X86::ADC64i32: return convert64i32to64ri8(Inst, X86::ADC64ri8);
2448 case X86::SBB16i16: return convert16i16to16ri8(Inst, X86::SBB16ri8);
2449 case X86::SBB32i32: return convert32i32to32ri8(Inst, X86::SBB32ri8);
2450 case X86::SBB64i32: return convert64i32to64ri8(Inst, X86::SBB64ri8);
2451 case X86::VMOVAPDrr:
2452 case X86::VMOVAPDYrr:
2453 case X86::VMOVAPSrr:
2454 case X86::VMOVAPSYrr:
2455 case X86::VMOVDQArr:
2456 case X86::VMOVDQAYrr:
2457 case X86::VMOVDQUrr:
2458 case X86::VMOVDQUYrr:
2459 case X86::VMOVUPDrr:
2460 case X86::VMOVUPDYrr:
2461 case X86::VMOVUPSrr:
2462 case X86::VMOVUPSYrr: {
2463 if (X86II::isX86_64ExtendedReg(Inst.getOperand(0).getReg()) ||
2464 !X86II::isX86_64ExtendedReg(Inst.getOperand(1).getReg()))
2468 switch (Inst.getOpcode()) {
2469 default: llvm_unreachable("Invalid opcode");
2470 case X86::VMOVAPDrr: NewOpc = X86::VMOVAPDrr_REV; break;
2471 case X86::VMOVAPDYrr: NewOpc = X86::VMOVAPDYrr_REV; break;
2472 case X86::VMOVAPSrr: NewOpc = X86::VMOVAPSrr_REV; break;
2473 case X86::VMOVAPSYrr: NewOpc = X86::VMOVAPSYrr_REV; break;
2474 case X86::VMOVDQArr: NewOpc = X86::VMOVDQArr_REV; break;
2475 case X86::VMOVDQAYrr: NewOpc = X86::VMOVDQAYrr_REV; break;
2476 case X86::VMOVDQUrr: NewOpc = X86::VMOVDQUrr_REV; break;
2477 case X86::VMOVDQUYrr: NewOpc = X86::VMOVDQUYrr_REV; break;
2478 case X86::VMOVUPDrr: NewOpc = X86::VMOVUPDrr_REV; break;
2479 case X86::VMOVUPDYrr: NewOpc = X86::VMOVUPDYrr_REV; break;
2480 case X86::VMOVUPSrr: NewOpc = X86::VMOVUPSrr_REV; break;
2481 case X86::VMOVUPSYrr: NewOpc = X86::VMOVUPSYrr_REV; break;
2483 Inst.setOpcode(NewOpc);
2487 case X86::VMOVSSrr: {
2488 if (X86II::isX86_64ExtendedReg(Inst.getOperand(0).getReg()) ||
2489 !X86II::isX86_64ExtendedReg(Inst.getOperand(2).getReg()))
2492 switch (Inst.getOpcode()) {
2493 default: llvm_unreachable("Invalid opcode");
2494 case X86::VMOVSDrr: NewOpc = X86::VMOVSDrr_REV; break;
2495 case X86::VMOVSSrr: NewOpc = X86::VMOVSSrr_REV; break;
2497 Inst.setOpcode(NewOpc);
2503 static const char *getSubtargetFeatureName(uint64_t Val);
2505 void X86AsmParser::EmitInstruction(MCInst &Inst, OperandVector &Operands,
2507 Instrumentation->InstrumentAndEmitInstruction(Inst, Operands, getContext(),
2511 bool X86AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2512 OperandVector &Operands,
2513 MCStreamer &Out, uint64_t &ErrorInfo,
2514 bool MatchingInlineAsm) {
2515 if (isParsingIntelSyntax())
2516 return MatchAndEmitIntelInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2518 return MatchAndEmitATTInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2522 void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op,
2523 OperandVector &Operands, MCStreamer &Out,
2524 bool MatchingInlineAsm) {
2525 // FIXME: This should be replaced with a real .td file alias mechanism.
2526 // Also, MatchInstructionImpl should actually *do* the EmitInstruction
2528 const char *Repl = StringSwitch<const char *>(Op.getToken())
2529 .Case("finit", "fninit")
2530 .Case("fsave", "fnsave")
2531 .Case("fstcw", "fnstcw")
2532 .Case("fstcww", "fnstcw")
2533 .Case("fstenv", "fnstenv")
2534 .Case("fstsw", "fnstsw")
2535 .Case("fstsww", "fnstsw")
2536 .Case("fclex", "fnclex")
2540 Inst.setOpcode(X86::WAIT);
2542 if (!MatchingInlineAsm)
2543 EmitInstruction(Inst, Operands, Out);
2544 Operands[0] = X86Operand::CreateToken(Repl, IDLoc);
2548 bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
2549 bool MatchingInlineAsm) {
2550 assert(ErrorInfo && "Unknown missing feature!");
2551 ArrayRef<SMRange> EmptyRanges = None;
2552 SmallString<126> Msg;
2553 raw_svector_ostream OS(Msg);
2554 OS << "instruction requires:";
2556 for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
2557 if (ErrorInfo & Mask)
2558 OS << ' ' << getSubtargetFeatureName(ErrorInfo & Mask);
2561 return Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
2564 bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
2565 OperandVector &Operands,
2567 uint64_t &ErrorInfo,
2568 bool MatchingInlineAsm) {
2569 assert(!Operands.empty() && "Unexpect empty operand list!");
2570 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2571 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
2572 ArrayRef<SMRange> EmptyRanges = None;
2574 // First, handle aliases that expand to multiple instructions.
2575 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2577 bool WasOriginallyInvalidOperand = false;
2580 // First, try a direct match.
2581 switch (MatchInstructionImpl(Operands, Inst,
2582 ErrorInfo, MatchingInlineAsm,
2583 isParsingIntelSyntax())) {
2584 default: llvm_unreachable("Unexpected match result!");
2586 if (!validateInstruction(Inst, Operands))
2589 // Some instructions need post-processing to, for example, tweak which
2590 // encoding is selected. Loop on it while changes happen so the
2591 // individual transformations can chain off each other.
2592 if (!MatchingInlineAsm)
2593 while (processInstruction(Inst, Operands))
2597 if (!MatchingInlineAsm)
2598 EmitInstruction(Inst, Operands, Out);
2599 Opcode = Inst.getOpcode();
2601 case Match_MissingFeature:
2602 return ErrorMissingFeature(IDLoc, ErrorInfo, MatchingInlineAsm);
2603 case Match_InvalidOperand:
2604 WasOriginallyInvalidOperand = true;
2606 case Match_MnemonicFail:
2610 // FIXME: Ideally, we would only attempt suffix matches for things which are
2611 // valid prefixes, and we could just infer the right unambiguous
2612 // type. However, that requires substantially more matcher support than the
2615 // Change the operand to point to a temporary token.
2616 StringRef Base = Op.getToken();
2617 SmallString<16> Tmp;
2620 Op.setTokenValue(Tmp);
2622 // If this instruction starts with an 'f', then it is a floating point stack
2623 // instruction. These come in up to three forms for 32-bit, 64-bit, and
2624 // 80-bit floating point, which use the suffixes s,l,t respectively.
2626 // Otherwise, we assume that this may be an integer instruction, which comes
2627 // in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively.
2628 const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0";
2630 // Check for the various suffix matches.
2631 uint64_t ErrorInfoIgnore;
2632 uint64_t ErrorInfoMissingFeature = 0; // Init suppresses compiler warnings.
2635 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I) {
2636 Tmp.back() = Suffixes[I];
2637 Match[I] = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
2638 MatchingInlineAsm, isParsingIntelSyntax());
2639 // If this returned as a missing feature failure, remember that.
2640 if (Match[I] == Match_MissingFeature)
2641 ErrorInfoMissingFeature = ErrorInfoIgnore;
2644 // Restore the old token.
2645 Op.setTokenValue(Base);
2647 // If exactly one matched, then we treat that as a successful match (and the
2648 // instruction will already have been filled in correctly, since the failing
2649 // matches won't have modified it).
2650 unsigned NumSuccessfulMatches =
2651 std::count(std::begin(Match), std::end(Match), Match_Success);
2652 if (NumSuccessfulMatches == 1) {
2654 if (!MatchingInlineAsm)
2655 EmitInstruction(Inst, Operands, Out);
2656 Opcode = Inst.getOpcode();
2660 // Otherwise, the match failed, try to produce a decent error message.
2662 // If we had multiple suffix matches, then identify this as an ambiguous
2664 if (NumSuccessfulMatches > 1) {
2666 unsigned NumMatches = 0;
2667 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I)
2668 if (Match[I] == Match_Success)
2669 MatchChars[NumMatches++] = Suffixes[I];
2671 SmallString<126> Msg;
2672 raw_svector_ostream OS(Msg);
2673 OS << "ambiguous instructions require an explicit suffix (could be ";
2674 for (unsigned i = 0; i != NumMatches; ++i) {
2677 if (i + 1 == NumMatches)
2679 OS << "'" << Base << MatchChars[i] << "'";
2682 Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
2686 // Okay, we know that none of the variants matched successfully.
2688 // If all of the instructions reported an invalid mnemonic, then the original
2689 // mnemonic was invalid.
2690 if (std::count(std::begin(Match), std::end(Match), Match_MnemonicFail) == 4) {
2691 if (!WasOriginallyInvalidOperand) {
2692 ArrayRef<SMRange> Ranges =
2693 MatchingInlineAsm ? EmptyRanges : Op.getLocRange();
2694 return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'",
2695 Ranges, MatchingInlineAsm);
2698 // Recover location info for the operand if we know which was the problem.
2699 if (ErrorInfo != ~0ULL) {
2700 if (ErrorInfo >= Operands.size())
2701 return Error(IDLoc, "too few operands for instruction",
2702 EmptyRanges, MatchingInlineAsm);
2704 X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo];
2705 if (Operand.getStartLoc().isValid()) {
2706 SMRange OperandRange = Operand.getLocRange();
2707 return Error(Operand.getStartLoc(), "invalid operand for instruction",
2708 OperandRange, MatchingInlineAsm);
2712 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2716 // If one instruction matched with a missing feature, report this as a
2718 if (std::count(std::begin(Match), std::end(Match),
2719 Match_MissingFeature) == 1) {
2720 ErrorInfo = ErrorInfoMissingFeature;
2721 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
2725 // If one instruction matched with an invalid operand, report this as an
2727 if (std::count(std::begin(Match), std::end(Match),
2728 Match_InvalidOperand) == 1) {
2729 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2733 // If all of these were an outright failure, report it in a useless way.
2734 Error(IDLoc, "unknown use of instruction mnemonic without a size suffix",
2735 EmptyRanges, MatchingInlineAsm);
2739 bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
2740 OperandVector &Operands,
2742 uint64_t &ErrorInfo,
2743 bool MatchingInlineAsm) {
2744 assert(!Operands.empty() && "Unexpect empty operand list!");
2745 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2746 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
2747 StringRef Mnemonic = Op.getToken();
2748 ArrayRef<SMRange> EmptyRanges = None;
2750 // First, handle aliases that expand to multiple instructions.
2751 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2755 // Find one unsized memory operand, if present.
2756 X86Operand *UnsizedMemOp = nullptr;
2757 for (const auto &Op : Operands) {
2758 X86Operand *X86Op = static_cast<X86Operand *>(Op.get());
2759 if (X86Op->isMemUnsized())
2760 UnsizedMemOp = X86Op;
2763 // Allow some instructions to have implicitly pointer-sized operands. This is
2764 // compatible with gas.
2766 static const char *const PtrSizedInstrs[] = {"call", "jmp", "push"};
2767 for (const char *Instr : PtrSizedInstrs) {
2768 if (Mnemonic == Instr) {
2769 UnsizedMemOp->Mem.Size = getPointerWidth();
2775 // If an unsized memory operand is present, try to match with each memory
2776 // operand size. In Intel assembly, the size is not part of the instruction
2778 SmallVector<unsigned, 8> Match;
2779 uint64_t ErrorInfoMissingFeature = 0;
2780 if (UnsizedMemOp && UnsizedMemOp->isMemUnsized()) {
2781 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
2782 for (unsigned Size : MopSizes) {
2783 UnsizedMemOp->Mem.Size = Size;
2784 uint64_t ErrorInfoIgnore;
2785 unsigned LastOpcode = Inst.getOpcode();
2787 MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
2788 MatchingInlineAsm, isParsingIntelSyntax());
2789 if (Match.empty() || LastOpcode != Inst.getOpcode())
2792 // If this returned as a missing feature failure, remember that.
2793 if (Match.back() == Match_MissingFeature)
2794 ErrorInfoMissingFeature = ErrorInfoIgnore;
2797 // Restore the size of the unsized memory operand if we modified it.
2799 UnsizedMemOp->Mem.Size = 0;
2802 // If we haven't matched anything yet, this is not a basic integer or FPU
2803 // operation. There shouldn't be any ambiguity in our mnemonic table, so try
2804 // matching with the unsized operand.
2805 if (Match.empty()) {
2806 Match.push_back(MatchInstructionImpl(Operands, Inst, ErrorInfo,
2808 isParsingIntelSyntax()));
2809 // If this returned as a missing feature failure, remember that.
2810 if (Match.back() == Match_MissingFeature)
2811 ErrorInfoMissingFeature = ErrorInfo;
2814 // Restore the size of the unsized memory operand if we modified it.
2816 UnsizedMemOp->Mem.Size = 0;
2818 // If it's a bad mnemonic, all results will be the same.
2819 if (Match.back() == Match_MnemonicFail) {
2820 ArrayRef<SMRange> Ranges =
2821 MatchingInlineAsm ? EmptyRanges : Op.getLocRange();
2822 return Error(IDLoc, "invalid instruction mnemonic '" + Mnemonic + "'",
2823 Ranges, MatchingInlineAsm);
2826 // If exactly one matched, then we treat that as a successful match (and the
2827 // instruction will already have been filled in correctly, since the failing
2828 // matches won't have modified it).
2829 unsigned NumSuccessfulMatches =
2830 std::count(std::begin(Match), std::end(Match), Match_Success);
2831 if (NumSuccessfulMatches == 1) {
2832 if (!validateInstruction(Inst, Operands))
2835 // Some instructions need post-processing to, for example, tweak which
2836 // encoding is selected. Loop on it while changes happen so the individual
2837 // transformations can chain off each other.
2838 if (!MatchingInlineAsm)
2839 while (processInstruction(Inst, Operands))
2842 if (!MatchingInlineAsm)
2843 EmitInstruction(Inst, Operands, Out);
2844 Opcode = Inst.getOpcode();
2846 } else if (NumSuccessfulMatches > 1) {
2847 assert(UnsizedMemOp &&
2848 "multiple matches only possible with unsized memory operands");
2849 ArrayRef<SMRange> Ranges =
2850 MatchingInlineAsm ? EmptyRanges : UnsizedMemOp->getLocRange();
2851 return Error(UnsizedMemOp->getStartLoc(),
2852 "ambiguous operand size for instruction '" + Mnemonic + "\'",
2853 Ranges, MatchingInlineAsm);
2856 // If one instruction matched with a missing feature, report this as a
2858 if (std::count(std::begin(Match), std::end(Match),
2859 Match_MissingFeature) == 1) {
2860 ErrorInfo = ErrorInfoMissingFeature;
2861 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
2865 // If one instruction matched with an invalid operand, report this as an
2867 if (std::count(std::begin(Match), std::end(Match),
2868 Match_InvalidOperand) == 1) {
2869 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2873 // If all of these were an outright failure, report it in a useless way.
2874 return Error(IDLoc, "unknown instruction mnemonic", EmptyRanges,
2878 bool X86AsmParser::OmitRegisterFromClobberLists(unsigned RegNo) {
2879 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo);
2882 bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
2883 MCAsmParser &Parser = getParser();
2884 StringRef IDVal = DirectiveID.getIdentifier();
2885 if (IDVal == ".word")
2886 return ParseDirectiveWord(2, DirectiveID.getLoc());
2887 else if (IDVal.startswith(".code"))
2888 return ParseDirectiveCode(IDVal, DirectiveID.getLoc());
2889 else if (IDVal.startswith(".att_syntax")) {
2890 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2891 if (Parser.getTok().getString() == "prefix")
2893 else if (Parser.getTok().getString() == "noprefix")
2894 return Error(DirectiveID.getLoc(), "'.att_syntax noprefix' is not "
2895 "supported: registers must have a "
2896 "'%' prefix in .att_syntax");
2898 getParser().setAssemblerDialect(0);
2900 } else if (IDVal.startswith(".intel_syntax")) {
2901 getParser().setAssemblerDialect(1);
2902 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2903 if (Parser.getTok().getString() == "noprefix")
2905 else if (Parser.getTok().getString() == "prefix")
2906 return Error(DirectiveID.getLoc(), "'.intel_syntax prefix' is not "
2907 "supported: registers must not have "
2908 "a '%' prefix in .intel_syntax");
2915 /// ParseDirectiveWord
2916 /// ::= .word [ expression (, expression)* ]
2917 bool X86AsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
2918 MCAsmParser &Parser = getParser();
2919 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2921 const MCExpr *Value;
2922 if (getParser().parseExpression(Value))
2925 getParser().getStreamer().EmitValue(Value, Size);
2927 if (getLexer().is(AsmToken::EndOfStatement))
2930 // FIXME: Improve diagnostic.
2931 if (getLexer().isNot(AsmToken::Comma)) {
2932 Error(L, "unexpected token in directive");
2943 /// ParseDirectiveCode
2944 /// ::= .code16 | .code32 | .code64
2945 bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
2946 MCAsmParser &Parser = getParser();
2947 if (IDVal == ".code16") {
2949 if (!is16BitMode()) {
2950 SwitchMode(X86::Mode16Bit);
2951 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
2953 } else if (IDVal == ".code32") {
2955 if (!is32BitMode()) {
2956 SwitchMode(X86::Mode32Bit);
2957 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
2959 } else if (IDVal == ".code64") {
2961 if (!is64BitMode()) {
2962 SwitchMode(X86::Mode64Bit);
2963 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code64);
2966 Error(L, "unknown directive " + IDVal);
2973 // Force static initialization.
2974 extern "C" void LLVMInitializeX86AsmParser() {
2975 RegisterMCAsmParser<X86AsmParser> X(TheX86_32Target);
2976 RegisterMCAsmParser<X86AsmParser> Y(TheX86_64Target);
2979 #define GET_REGISTER_MATCHER
2980 #define GET_MATCHER_IMPLEMENTATION
2981 #define GET_SUBTARGET_FEATURE_NAME
2982 #include "X86GenAsmMatcher.inc"