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" ||
2257 AddDefaultSrcDestOperands(Operands,
2258 X86Operand::CreateReg(X86::DX, NameLoc, NameLoc),
2259 DefaultMemDIOperand(NameLoc));
2262 // Append default arguments to "outs[bwld]"
2263 if (Name.startswith("outs") && Operands.size() == 1 &&
2264 (Name == "outsb" || Name == "outsw" || Name == "outsl" ||
2265 Name == "outsd" )) {
2266 AddDefaultSrcDestOperands(Operands,
2267 DefaultMemSIOperand(NameLoc),
2268 X86Operand::CreateReg(X86::DX, NameLoc, NameLoc));
2271 // Transform "lods[bwlq]" into "lods[bwlq] ($SIREG)" for appropriate
2272 // values of $SIREG according to the mode. It would be nice if this
2273 // could be achieved with InstAlias in the tables.
2274 if (Name.startswith("lods") && Operands.size() == 1 &&
2275 (Name == "lods" || Name == "lodsb" || Name == "lodsw" ||
2276 Name == "lodsl" || Name == "lodsd" || Name == "lodsq"))
2277 Operands.push_back(DefaultMemSIOperand(NameLoc));
2279 // Transform "stos[bwlq]" into "stos[bwlq] ($DIREG)" for appropriate
2280 // values of $DIREG according to the mode. It would be nice if this
2281 // could be achieved with InstAlias in the tables.
2282 if (Name.startswith("stos") && Operands.size() == 1 &&
2283 (Name == "stos" || Name == "stosb" || Name == "stosw" ||
2284 Name == "stosl" || Name == "stosd" || Name == "stosq"))
2285 Operands.push_back(DefaultMemDIOperand(NameLoc));
2287 // Transform "scas[bwlq]" into "scas[bwlq] ($DIREG)" for appropriate
2288 // values of $DIREG according to the mode. It would be nice if this
2289 // could be achieved with InstAlias in the tables.
2290 if (Name.startswith("scas") && Operands.size() == 1 &&
2291 (Name == "scas" || Name == "scasb" || Name == "scasw" ||
2292 Name == "scasl" || Name == "scasd" || Name == "scasq"))
2293 Operands.push_back(DefaultMemDIOperand(NameLoc));
2295 // Add default SI and DI operands to "cmps[bwlq]".
2296 if (Name.startswith("cmps") &&
2297 (Name == "cmps" || Name == "cmpsb" || Name == "cmpsw" ||
2298 Name == "cmpsl" || Name == "cmpsd" || Name == "cmpsq")) {
2299 if (Operands.size() == 1) {
2300 AddDefaultSrcDestOperands(Operands,
2301 DefaultMemDIOperand(NameLoc),
2302 DefaultMemSIOperand(NameLoc));
2303 } else if (Operands.size() == 3) {
2304 X86Operand &Op = (X86Operand &)*Operands[1];
2305 X86Operand &Op2 = (X86Operand &)*Operands[2];
2306 if (!doSrcDstMatch(Op, Op2))
2307 return Error(Op.getStartLoc(),
2308 "mismatching source and destination index registers");
2312 // Add default SI and DI operands to "movs[bwlq]".
2313 if ((Name.startswith("movs") &&
2314 (Name == "movs" || Name == "movsb" || Name == "movsw" ||
2315 Name == "movsl" || Name == "movsd" || Name == "movsq")) ||
2316 (Name.startswith("smov") &&
2317 (Name == "smov" || Name == "smovb" || Name == "smovw" ||
2318 Name == "smovl" || Name == "smovd" || Name == "smovq"))) {
2319 if (Operands.size() == 1) {
2320 if (Name == "movsd")
2321 Operands.back() = X86Operand::CreateToken("movsl", NameLoc);
2322 AddDefaultSrcDestOperands(Operands,
2323 DefaultMemSIOperand(NameLoc),
2324 DefaultMemDIOperand(NameLoc));
2325 } else if (Operands.size() == 3) {
2326 X86Operand &Op = (X86Operand &)*Operands[1];
2327 X86Operand &Op2 = (X86Operand &)*Operands[2];
2328 if (!doSrcDstMatch(Op, Op2))
2329 return Error(Op.getStartLoc(),
2330 "mismatching source and destination index registers");
2334 // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>. Canonicalize to
2336 if ((Name.startswith("shr") || Name.startswith("sar") ||
2337 Name.startswith("shl") || Name.startswith("sal") ||
2338 Name.startswith("rcl") || Name.startswith("rcr") ||
2339 Name.startswith("rol") || Name.startswith("ror")) &&
2340 Operands.size() == 3) {
2341 if (isParsingIntelSyntax()) {
2343 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[2]);
2344 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2345 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2346 Operands.pop_back();
2348 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2349 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2350 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2351 Operands.erase(Operands.begin() + 1);
2355 // Transforms "int $3" into "int3" as a size optimization. We can't write an
2356 // instalias with an immediate operand yet.
2357 if (Name == "int" && Operands.size() == 2) {
2358 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2360 if (auto *CE = dyn_cast<MCConstantExpr>(Op1.getImm()))
2361 if (CE->getValue() == 3) {
2362 Operands.erase(Operands.begin() + 1);
2363 static_cast<X86Operand &>(*Operands[0]).setTokenValue("int3");
2370 static bool convertToSExti8(MCInst &Inst, unsigned Opcode, unsigned Reg,
2373 TmpInst.setOpcode(Opcode);
2375 TmpInst.addOperand(MCOperand::createReg(Reg));
2376 TmpInst.addOperand(MCOperand::createReg(Reg));
2377 TmpInst.addOperand(Inst.getOperand(0));
2382 static bool convert16i16to16ri8(MCInst &Inst, unsigned Opcode,
2383 bool isCmp = false) {
2384 if (!Inst.getOperand(0).isImm() ||
2385 !isImmSExti16i8Value(Inst.getOperand(0).getImm()))
2388 return convertToSExti8(Inst, Opcode, X86::AX, isCmp);
2391 static bool convert32i32to32ri8(MCInst &Inst, unsigned Opcode,
2392 bool isCmp = false) {
2393 if (!Inst.getOperand(0).isImm() ||
2394 !isImmSExti32i8Value(Inst.getOperand(0).getImm()))
2397 return convertToSExti8(Inst, Opcode, X86::EAX, isCmp);
2400 static bool convert64i32to64ri8(MCInst &Inst, unsigned Opcode,
2401 bool isCmp = false) {
2402 if (!Inst.getOperand(0).isImm() ||
2403 !isImmSExti64i8Value(Inst.getOperand(0).getImm()))
2406 return convertToSExti8(Inst, Opcode, X86::RAX, isCmp);
2409 bool X86AsmParser::validateInstruction(MCInst &Inst, const OperandVector &Ops) {
2410 switch (Inst.getOpcode()) {
2411 default: return true;
2413 X86Operand &Op = static_cast<X86Operand &>(*Ops[1]);
2414 assert(Op.isImm() && "expected immediate");
2416 if (!Op.getImm()->evaluateAsAbsolute(Res) || Res > 255) {
2417 Error(Op.getStartLoc(), "interrupt vector must be in range [0-255]");
2422 llvm_unreachable("handle the instruction appropriately");
2425 bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) {
2426 switch (Inst.getOpcode()) {
2427 default: return false;
2428 case X86::AND16i16: return convert16i16to16ri8(Inst, X86::AND16ri8);
2429 case X86::AND32i32: return convert32i32to32ri8(Inst, X86::AND32ri8);
2430 case X86::AND64i32: return convert64i32to64ri8(Inst, X86::AND64ri8);
2431 case X86::XOR16i16: return convert16i16to16ri8(Inst, X86::XOR16ri8);
2432 case X86::XOR32i32: return convert32i32to32ri8(Inst, X86::XOR32ri8);
2433 case X86::XOR64i32: return convert64i32to64ri8(Inst, X86::XOR64ri8);
2434 case X86::OR16i16: return convert16i16to16ri8(Inst, X86::OR16ri8);
2435 case X86::OR32i32: return convert32i32to32ri8(Inst, X86::OR32ri8);
2436 case X86::OR64i32: return convert64i32to64ri8(Inst, X86::OR64ri8);
2437 case X86::CMP16i16: return convert16i16to16ri8(Inst, X86::CMP16ri8, true);
2438 case X86::CMP32i32: return convert32i32to32ri8(Inst, X86::CMP32ri8, true);
2439 case X86::CMP64i32: return convert64i32to64ri8(Inst, X86::CMP64ri8, true);
2440 case X86::ADD16i16: return convert16i16to16ri8(Inst, X86::ADD16ri8);
2441 case X86::ADD32i32: return convert32i32to32ri8(Inst, X86::ADD32ri8);
2442 case X86::ADD64i32: return convert64i32to64ri8(Inst, X86::ADD64ri8);
2443 case X86::SUB16i16: return convert16i16to16ri8(Inst, X86::SUB16ri8);
2444 case X86::SUB32i32: return convert32i32to32ri8(Inst, X86::SUB32ri8);
2445 case X86::SUB64i32: return convert64i32to64ri8(Inst, X86::SUB64ri8);
2446 case X86::ADC16i16: return convert16i16to16ri8(Inst, X86::ADC16ri8);
2447 case X86::ADC32i32: return convert32i32to32ri8(Inst, X86::ADC32ri8);
2448 case X86::ADC64i32: return convert64i32to64ri8(Inst, X86::ADC64ri8);
2449 case X86::SBB16i16: return convert16i16to16ri8(Inst, X86::SBB16ri8);
2450 case X86::SBB32i32: return convert32i32to32ri8(Inst, X86::SBB32ri8);
2451 case X86::SBB64i32: return convert64i32to64ri8(Inst, X86::SBB64ri8);
2452 case X86::VMOVAPDrr:
2453 case X86::VMOVAPDYrr:
2454 case X86::VMOVAPSrr:
2455 case X86::VMOVAPSYrr:
2456 case X86::VMOVDQArr:
2457 case X86::VMOVDQAYrr:
2458 case X86::VMOVDQUrr:
2459 case X86::VMOVDQUYrr:
2460 case X86::VMOVUPDrr:
2461 case X86::VMOVUPDYrr:
2462 case X86::VMOVUPSrr:
2463 case X86::VMOVUPSYrr: {
2464 if (X86II::isX86_64ExtendedReg(Inst.getOperand(0).getReg()) ||
2465 !X86II::isX86_64ExtendedReg(Inst.getOperand(1).getReg()))
2469 switch (Inst.getOpcode()) {
2470 default: llvm_unreachable("Invalid opcode");
2471 case X86::VMOVAPDrr: NewOpc = X86::VMOVAPDrr_REV; break;
2472 case X86::VMOVAPDYrr: NewOpc = X86::VMOVAPDYrr_REV; break;
2473 case X86::VMOVAPSrr: NewOpc = X86::VMOVAPSrr_REV; break;
2474 case X86::VMOVAPSYrr: NewOpc = X86::VMOVAPSYrr_REV; break;
2475 case X86::VMOVDQArr: NewOpc = X86::VMOVDQArr_REV; break;
2476 case X86::VMOVDQAYrr: NewOpc = X86::VMOVDQAYrr_REV; break;
2477 case X86::VMOVDQUrr: NewOpc = X86::VMOVDQUrr_REV; break;
2478 case X86::VMOVDQUYrr: NewOpc = X86::VMOVDQUYrr_REV; break;
2479 case X86::VMOVUPDrr: NewOpc = X86::VMOVUPDrr_REV; break;
2480 case X86::VMOVUPDYrr: NewOpc = X86::VMOVUPDYrr_REV; break;
2481 case X86::VMOVUPSrr: NewOpc = X86::VMOVUPSrr_REV; break;
2482 case X86::VMOVUPSYrr: NewOpc = X86::VMOVUPSYrr_REV; break;
2484 Inst.setOpcode(NewOpc);
2488 case X86::VMOVSSrr: {
2489 if (X86II::isX86_64ExtendedReg(Inst.getOperand(0).getReg()) ||
2490 !X86II::isX86_64ExtendedReg(Inst.getOperand(2).getReg()))
2493 switch (Inst.getOpcode()) {
2494 default: llvm_unreachable("Invalid opcode");
2495 case X86::VMOVSDrr: NewOpc = X86::VMOVSDrr_REV; break;
2496 case X86::VMOVSSrr: NewOpc = X86::VMOVSSrr_REV; break;
2498 Inst.setOpcode(NewOpc);
2504 static const char *getSubtargetFeatureName(uint64_t Val);
2506 void X86AsmParser::EmitInstruction(MCInst &Inst, OperandVector &Operands,
2508 Instrumentation->InstrumentAndEmitInstruction(Inst, Operands, getContext(),
2512 bool X86AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2513 OperandVector &Operands,
2514 MCStreamer &Out, uint64_t &ErrorInfo,
2515 bool MatchingInlineAsm) {
2516 if (isParsingIntelSyntax())
2517 return MatchAndEmitIntelInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2519 return MatchAndEmitATTInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2523 void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op,
2524 OperandVector &Operands, MCStreamer &Out,
2525 bool MatchingInlineAsm) {
2526 // FIXME: This should be replaced with a real .td file alias mechanism.
2527 // Also, MatchInstructionImpl should actually *do* the EmitInstruction
2529 const char *Repl = StringSwitch<const char *>(Op.getToken())
2530 .Case("finit", "fninit")
2531 .Case("fsave", "fnsave")
2532 .Case("fstcw", "fnstcw")
2533 .Case("fstcww", "fnstcw")
2534 .Case("fstenv", "fnstenv")
2535 .Case("fstsw", "fnstsw")
2536 .Case("fstsww", "fnstsw")
2537 .Case("fclex", "fnclex")
2541 Inst.setOpcode(X86::WAIT);
2543 if (!MatchingInlineAsm)
2544 EmitInstruction(Inst, Operands, Out);
2545 Operands[0] = X86Operand::CreateToken(Repl, IDLoc);
2549 bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
2550 bool MatchingInlineAsm) {
2551 assert(ErrorInfo && "Unknown missing feature!");
2552 ArrayRef<SMRange> EmptyRanges = None;
2553 SmallString<126> Msg;
2554 raw_svector_ostream OS(Msg);
2555 OS << "instruction requires:";
2557 for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
2558 if (ErrorInfo & Mask)
2559 OS << ' ' << getSubtargetFeatureName(ErrorInfo & Mask);
2562 return Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
2565 bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
2566 OperandVector &Operands,
2568 uint64_t &ErrorInfo,
2569 bool MatchingInlineAsm) {
2570 assert(!Operands.empty() && "Unexpect empty operand list!");
2571 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2572 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
2573 ArrayRef<SMRange> EmptyRanges = None;
2575 // First, handle aliases that expand to multiple instructions.
2576 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2578 bool WasOriginallyInvalidOperand = false;
2581 // First, try a direct match.
2582 switch (MatchInstructionImpl(Operands, Inst,
2583 ErrorInfo, MatchingInlineAsm,
2584 isParsingIntelSyntax())) {
2585 default: llvm_unreachable("Unexpected match result!");
2587 if (!validateInstruction(Inst, Operands))
2590 // Some instructions need post-processing to, for example, tweak which
2591 // encoding is selected. Loop on it while changes happen so the
2592 // individual transformations can chain off each other.
2593 if (!MatchingInlineAsm)
2594 while (processInstruction(Inst, Operands))
2598 if (!MatchingInlineAsm)
2599 EmitInstruction(Inst, Operands, Out);
2600 Opcode = Inst.getOpcode();
2602 case Match_MissingFeature:
2603 return ErrorMissingFeature(IDLoc, ErrorInfo, MatchingInlineAsm);
2604 case Match_InvalidOperand:
2605 WasOriginallyInvalidOperand = true;
2607 case Match_MnemonicFail:
2611 // FIXME: Ideally, we would only attempt suffix matches for things which are
2612 // valid prefixes, and we could just infer the right unambiguous
2613 // type. However, that requires substantially more matcher support than the
2616 // Change the operand to point to a temporary token.
2617 StringRef Base = Op.getToken();
2618 SmallString<16> Tmp;
2621 Op.setTokenValue(Tmp);
2623 // If this instruction starts with an 'f', then it is a floating point stack
2624 // instruction. These come in up to three forms for 32-bit, 64-bit, and
2625 // 80-bit floating point, which use the suffixes s,l,t respectively.
2627 // Otherwise, we assume that this may be an integer instruction, which comes
2628 // in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively.
2629 const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0";
2631 // Check for the various suffix matches.
2632 uint64_t ErrorInfoIgnore;
2633 uint64_t ErrorInfoMissingFeature = 0; // Init suppresses compiler warnings.
2636 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I) {
2637 Tmp.back() = Suffixes[I];
2638 Match[I] = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
2639 MatchingInlineAsm, isParsingIntelSyntax());
2640 // If this returned as a missing feature failure, remember that.
2641 if (Match[I] == Match_MissingFeature)
2642 ErrorInfoMissingFeature = ErrorInfoIgnore;
2645 // Restore the old token.
2646 Op.setTokenValue(Base);
2648 // If exactly one matched, then we treat that as a successful match (and the
2649 // instruction will already have been filled in correctly, since the failing
2650 // matches won't have modified it).
2651 unsigned NumSuccessfulMatches =
2652 std::count(std::begin(Match), std::end(Match), Match_Success);
2653 if (NumSuccessfulMatches == 1) {
2655 if (!MatchingInlineAsm)
2656 EmitInstruction(Inst, Operands, Out);
2657 Opcode = Inst.getOpcode();
2661 // Otherwise, the match failed, try to produce a decent error message.
2663 // If we had multiple suffix matches, then identify this as an ambiguous
2665 if (NumSuccessfulMatches > 1) {
2667 unsigned NumMatches = 0;
2668 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I)
2669 if (Match[I] == Match_Success)
2670 MatchChars[NumMatches++] = Suffixes[I];
2672 SmallString<126> Msg;
2673 raw_svector_ostream OS(Msg);
2674 OS << "ambiguous instructions require an explicit suffix (could be ";
2675 for (unsigned i = 0; i != NumMatches; ++i) {
2678 if (i + 1 == NumMatches)
2680 OS << "'" << Base << MatchChars[i] << "'";
2683 Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
2687 // Okay, we know that none of the variants matched successfully.
2689 // If all of the instructions reported an invalid mnemonic, then the original
2690 // mnemonic was invalid.
2691 if (std::count(std::begin(Match), std::end(Match), Match_MnemonicFail) == 4) {
2692 if (!WasOriginallyInvalidOperand) {
2693 ArrayRef<SMRange> Ranges =
2694 MatchingInlineAsm ? EmptyRanges : Op.getLocRange();
2695 return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'",
2696 Ranges, MatchingInlineAsm);
2699 // Recover location info for the operand if we know which was the problem.
2700 if (ErrorInfo != ~0ULL) {
2701 if (ErrorInfo >= Operands.size())
2702 return Error(IDLoc, "too few operands for instruction",
2703 EmptyRanges, MatchingInlineAsm);
2705 X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo];
2706 if (Operand.getStartLoc().isValid()) {
2707 SMRange OperandRange = Operand.getLocRange();
2708 return Error(Operand.getStartLoc(), "invalid operand for instruction",
2709 OperandRange, MatchingInlineAsm);
2713 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2717 // If one instruction matched with a missing feature, report this as a
2719 if (std::count(std::begin(Match), std::end(Match),
2720 Match_MissingFeature) == 1) {
2721 ErrorInfo = ErrorInfoMissingFeature;
2722 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
2726 // If one instruction matched with an invalid operand, report this as an
2728 if (std::count(std::begin(Match), std::end(Match),
2729 Match_InvalidOperand) == 1) {
2730 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2734 // If all of these were an outright failure, report it in a useless way.
2735 Error(IDLoc, "unknown use of instruction mnemonic without a size suffix",
2736 EmptyRanges, MatchingInlineAsm);
2740 bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
2741 OperandVector &Operands,
2743 uint64_t &ErrorInfo,
2744 bool MatchingInlineAsm) {
2745 assert(!Operands.empty() && "Unexpect empty operand list!");
2746 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2747 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
2748 StringRef Mnemonic = Op.getToken();
2749 ArrayRef<SMRange> EmptyRanges = None;
2751 // First, handle aliases that expand to multiple instructions.
2752 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2756 // Find one unsized memory operand, if present.
2757 X86Operand *UnsizedMemOp = nullptr;
2758 for (const auto &Op : Operands) {
2759 X86Operand *X86Op = static_cast<X86Operand *>(Op.get());
2760 if (X86Op->isMemUnsized())
2761 UnsizedMemOp = X86Op;
2764 // Allow some instructions to have implicitly pointer-sized operands. This is
2765 // compatible with gas.
2767 static const char *const PtrSizedInstrs[] = {"call", "jmp", "push"};
2768 for (const char *Instr : PtrSizedInstrs) {
2769 if (Mnemonic == Instr) {
2770 UnsizedMemOp->Mem.Size = getPointerWidth();
2776 // If an unsized memory operand is present, try to match with each memory
2777 // operand size. In Intel assembly, the size is not part of the instruction
2779 SmallVector<unsigned, 8> Match;
2780 uint64_t ErrorInfoMissingFeature = 0;
2781 if (UnsizedMemOp && UnsizedMemOp->isMemUnsized()) {
2782 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
2783 for (unsigned Size : MopSizes) {
2784 UnsizedMemOp->Mem.Size = Size;
2785 uint64_t ErrorInfoIgnore;
2786 unsigned LastOpcode = Inst.getOpcode();
2788 MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
2789 MatchingInlineAsm, isParsingIntelSyntax());
2790 if (Match.empty() || LastOpcode != Inst.getOpcode())
2793 // If this returned as a missing feature failure, remember that.
2794 if (Match.back() == Match_MissingFeature)
2795 ErrorInfoMissingFeature = ErrorInfoIgnore;
2798 // Restore the size of the unsized memory operand if we modified it.
2800 UnsizedMemOp->Mem.Size = 0;
2803 // If we haven't matched anything yet, this is not a basic integer or FPU
2804 // operation. There shouldn't be any ambiguity in our mnemonic table, so try
2805 // matching with the unsized operand.
2806 if (Match.empty()) {
2807 Match.push_back(MatchInstructionImpl(Operands, Inst, ErrorInfo,
2809 isParsingIntelSyntax()));
2810 // If this returned as a missing feature failure, remember that.
2811 if (Match.back() == Match_MissingFeature)
2812 ErrorInfoMissingFeature = ErrorInfo;
2815 // Restore the size of the unsized memory operand if we modified it.
2817 UnsizedMemOp->Mem.Size = 0;
2819 // If it's a bad mnemonic, all results will be the same.
2820 if (Match.back() == Match_MnemonicFail) {
2821 ArrayRef<SMRange> Ranges =
2822 MatchingInlineAsm ? EmptyRanges : Op.getLocRange();
2823 return Error(IDLoc, "invalid instruction mnemonic '" + Mnemonic + "'",
2824 Ranges, MatchingInlineAsm);
2827 // If exactly one matched, then we treat that as a successful match (and the
2828 // instruction will already have been filled in correctly, since the failing
2829 // matches won't have modified it).
2830 unsigned NumSuccessfulMatches =
2831 std::count(std::begin(Match), std::end(Match), Match_Success);
2832 if (NumSuccessfulMatches == 1) {
2833 if (!validateInstruction(Inst, Operands))
2836 // Some instructions need post-processing to, for example, tweak which
2837 // encoding is selected. Loop on it while changes happen so the individual
2838 // transformations can chain off each other.
2839 if (!MatchingInlineAsm)
2840 while (processInstruction(Inst, Operands))
2843 if (!MatchingInlineAsm)
2844 EmitInstruction(Inst, Operands, Out);
2845 Opcode = Inst.getOpcode();
2847 } else if (NumSuccessfulMatches > 1) {
2848 assert(UnsizedMemOp &&
2849 "multiple matches only possible with unsized memory operands");
2850 ArrayRef<SMRange> Ranges =
2851 MatchingInlineAsm ? EmptyRanges : UnsizedMemOp->getLocRange();
2852 return Error(UnsizedMemOp->getStartLoc(),
2853 "ambiguous operand size for instruction '" + Mnemonic + "\'",
2854 Ranges, MatchingInlineAsm);
2857 // If one instruction matched with a missing feature, report this as a
2859 if (std::count(std::begin(Match), std::end(Match),
2860 Match_MissingFeature) == 1) {
2861 ErrorInfo = ErrorInfoMissingFeature;
2862 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
2866 // If one instruction matched with an invalid operand, report this as an
2868 if (std::count(std::begin(Match), std::end(Match),
2869 Match_InvalidOperand) == 1) {
2870 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2874 // If all of these were an outright failure, report it in a useless way.
2875 return Error(IDLoc, "unknown instruction mnemonic", EmptyRanges,
2879 bool X86AsmParser::OmitRegisterFromClobberLists(unsigned RegNo) {
2880 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo);
2883 bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
2884 MCAsmParser &Parser = getParser();
2885 StringRef IDVal = DirectiveID.getIdentifier();
2886 if (IDVal == ".word")
2887 return ParseDirectiveWord(2, DirectiveID.getLoc());
2888 else if (IDVal.startswith(".code"))
2889 return ParseDirectiveCode(IDVal, DirectiveID.getLoc());
2890 else if (IDVal.startswith(".att_syntax")) {
2891 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2892 if (Parser.getTok().getString() == "prefix")
2894 else if (Parser.getTok().getString() == "noprefix")
2895 return Error(DirectiveID.getLoc(), "'.att_syntax noprefix' is not "
2896 "supported: registers must have a "
2897 "'%' prefix in .att_syntax");
2899 getParser().setAssemblerDialect(0);
2901 } else if (IDVal.startswith(".intel_syntax")) {
2902 getParser().setAssemblerDialect(1);
2903 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2904 if (Parser.getTok().getString() == "noprefix")
2906 else if (Parser.getTok().getString() == "prefix")
2907 return Error(DirectiveID.getLoc(), "'.intel_syntax prefix' is not "
2908 "supported: registers must not have "
2909 "a '%' prefix in .intel_syntax");
2916 /// ParseDirectiveWord
2917 /// ::= .word [ expression (, expression)* ]
2918 bool X86AsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
2919 MCAsmParser &Parser = getParser();
2920 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2922 const MCExpr *Value;
2923 if (getParser().parseExpression(Value))
2926 getParser().getStreamer().EmitValue(Value, Size);
2928 if (getLexer().is(AsmToken::EndOfStatement))
2931 // FIXME: Improve diagnostic.
2932 if (getLexer().isNot(AsmToken::Comma)) {
2933 Error(L, "unexpected token in directive");
2944 /// ParseDirectiveCode
2945 /// ::= .code16 | .code32 | .code64
2946 bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
2947 MCAsmParser &Parser = getParser();
2948 if (IDVal == ".code16") {
2950 if (!is16BitMode()) {
2951 SwitchMode(X86::Mode16Bit);
2952 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
2954 } else if (IDVal == ".code32") {
2956 if (!is32BitMode()) {
2957 SwitchMode(X86::Mode32Bit);
2958 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
2960 } else if (IDVal == ".code64") {
2962 if (!is64BitMode()) {
2963 SwitchMode(X86::Mode64Bit);
2964 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code64);
2967 Error(L, "unknown directive " + IDVal);
2974 // Force static initialization.
2975 extern "C" void LLVMInitializeX86AsmParser() {
2976 RegisterMCAsmParser<X86AsmParser> X(TheX86_32Target);
2977 RegisterMCAsmParser<X86AsmParser> Y(TheX86_64Target);
2980 #define GET_REGISTER_MATCHER
2981 #define GET_MATCHER_IMPLEMENTATION
2982 #define GET_SUBTARGET_FEATURE_NAME
2983 #include "X86GenAsmMatcher.inc"