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("XWORD", "xword", 80)
1053 .Cases("TBYTE", "tbyte", 80)
1054 .Cases("XMMWORD", "xmmword", 128)
1055 .Cases("YMMWORD", "ymmword", 256)
1056 .Cases("ZMMWORD", "zmmword", 512)
1057 .Cases("OPAQUE", "opaque", -1U) // needs to be non-zero, but doesn't matter
1062 std::unique_ptr<X86Operand> X86AsmParser::CreateMemForInlineAsm(
1063 unsigned SegReg, const MCExpr *Disp, unsigned BaseReg, unsigned IndexReg,
1064 unsigned Scale, SMLoc Start, SMLoc End, unsigned Size, StringRef Identifier,
1065 InlineAsmIdentifierInfo &Info) {
1066 // If we found a decl other than a VarDecl, then assume it is a FuncDecl or
1067 // some other label reference.
1068 if (isa<MCSymbolRefExpr>(Disp) && Info.OpDecl && !Info.IsVarDecl) {
1069 // Insert an explicit size if the user didn't have one.
1071 Size = getPointerWidth();
1072 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_SizeDirective, Start,
1076 // Create an absolute memory reference in order to match against
1077 // instructions taking a PC relative operand.
1078 return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size,
1079 Identifier, Info.OpDecl);
1082 // We either have a direct symbol reference, or an offset from a symbol. The
1083 // parser always puts the symbol on the LHS, so look there for size
1084 // calculation purposes.
1085 const MCBinaryExpr *BinOp = dyn_cast<MCBinaryExpr>(Disp);
1087 isa<MCSymbolRefExpr>(BinOp ? BinOp->getLHS() : Disp);
1090 Size = Info.Type * 8; // Size is in terms of bits in this context.
1092 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_SizeDirective, Start,
1097 // When parsing inline assembly we set the base register to a non-zero value
1098 // if we don't know the actual value at this time. This is necessary to
1099 // get the matching correct in some cases.
1100 BaseReg = BaseReg ? BaseReg : 1;
1101 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
1102 IndexReg, Scale, Start, End, Size, Identifier,
1107 RewriteIntelBracExpression(SmallVectorImpl<AsmRewrite> *AsmRewrites,
1108 StringRef SymName, int64_t ImmDisp,
1109 int64_t FinalImmDisp, SMLoc &BracLoc,
1110 SMLoc &StartInBrac, SMLoc &End) {
1111 // Remove the '[' and ']' from the IR string.
1112 AsmRewrites->push_back(AsmRewrite(AOK_Skip, BracLoc, 1));
1113 AsmRewrites->push_back(AsmRewrite(AOK_Skip, End, 1));
1115 // If ImmDisp is non-zero, then we parsed a displacement before the
1116 // bracketed expression (i.e., ImmDisp [ BaseReg + Scale*IndexReg + Disp])
1117 // If ImmDisp doesn't match the displacement computed by the state machine
1118 // then we have an additional displacement in the bracketed expression.
1119 if (ImmDisp != FinalImmDisp) {
1121 // We have an immediate displacement before the bracketed expression.
1122 // Adjust this to match the final immediate displacement.
1124 for (SmallVectorImpl<AsmRewrite>::iterator I = AsmRewrites->begin(),
1125 E = AsmRewrites->end(); I != E; ++I) {
1126 if ((*I).Loc.getPointer() > BracLoc.getPointer())
1128 if ((*I).Kind == AOK_ImmPrefix || (*I).Kind == AOK_Imm) {
1129 assert (!Found && "ImmDisp already rewritten.");
1130 (*I).Kind = AOK_Imm;
1131 (*I).Len = BracLoc.getPointer() - (*I).Loc.getPointer();
1132 (*I).Val = FinalImmDisp;
1137 assert (Found && "Unable to rewrite ImmDisp.");
1140 // We have a symbolic and an immediate displacement, but no displacement
1141 // before the bracketed expression. Put the immediate displacement
1142 // before the bracketed expression.
1143 AsmRewrites->push_back(AsmRewrite(AOK_Imm, BracLoc, 0, FinalImmDisp));
1146 // Remove all the ImmPrefix rewrites within the brackets.
1147 for (SmallVectorImpl<AsmRewrite>::iterator I = AsmRewrites->begin(),
1148 E = AsmRewrites->end(); I != E; ++I) {
1149 if ((*I).Loc.getPointer() < StartInBrac.getPointer())
1151 if ((*I).Kind == AOK_ImmPrefix)
1152 (*I).Kind = AOK_Delete;
1154 const char *SymLocPtr = SymName.data();
1155 // Skip everything before the symbol.
1156 if (unsigned Len = SymLocPtr - StartInBrac.getPointer()) {
1157 assert(Len > 0 && "Expected a non-negative length.");
1158 AsmRewrites->push_back(AsmRewrite(AOK_Skip, StartInBrac, Len));
1160 // Skip everything after the symbol.
1161 if (unsigned Len = End.getPointer() - (SymLocPtr + SymName.size())) {
1162 SMLoc Loc = SMLoc::getFromPointer(SymLocPtr + SymName.size());
1163 assert(Len > 0 && "Expected a non-negative length.");
1164 AsmRewrites->push_back(AsmRewrite(AOK_Skip, Loc, Len));
1168 bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
1169 MCAsmParser &Parser = getParser();
1170 const AsmToken &Tok = Parser.getTok();
1174 bool UpdateLocLex = true;
1176 // The period in the dot operator (e.g., [ebx].foo.bar) is parsed as an
1177 // identifier. Don't try an parse it as a register.
1178 if (Tok.getString().startswith("."))
1181 // If we're parsing an immediate expression, we don't expect a '['.
1182 if (SM.getStopOnLBrac() && getLexer().getKind() == AsmToken::LBrac)
1185 AsmToken::TokenKind TK = getLexer().getKind();
1188 if (SM.isValidEndState()) {
1192 return Error(Tok.getLoc(), "unknown token in expression");
1194 case AsmToken::EndOfStatement: {
1198 case AsmToken::String:
1199 case AsmToken::Identifier: {
1200 // This could be a register or a symbolic displacement.
1203 SMLoc IdentLoc = Tok.getLoc();
1204 StringRef Identifier = Tok.getString();
1205 if (TK != AsmToken::String && !ParseRegister(TmpReg, IdentLoc, End)) {
1206 SM.onRegister(TmpReg);
1207 UpdateLocLex = false;
1210 if (!isParsingInlineAsm()) {
1211 if (getParser().parsePrimaryExpr(Val, End))
1212 return Error(Tok.getLoc(), "Unexpected identifier!");
1214 // This is a dot operator, not an adjacent identifier.
1215 if (Identifier.find('.') != StringRef::npos) {
1218 InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
1219 if (ParseIntelIdentifier(Val, Identifier, Info,
1220 /*Unevaluated=*/false, End))
1224 SM.onIdentifierExpr(Val, Identifier);
1225 UpdateLocLex = false;
1228 return Error(Tok.getLoc(), "Unexpected identifier!");
1230 case AsmToken::Integer: {
1232 if (isParsingInlineAsm() && SM.getAddImmPrefix())
1233 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_ImmPrefix,
1235 // Look for 'b' or 'f' following an Integer as a directional label
1236 SMLoc Loc = getTok().getLoc();
1237 int64_t IntVal = getTok().getIntVal();
1238 End = consumeToken();
1239 UpdateLocLex = false;
1240 if (getLexer().getKind() == AsmToken::Identifier) {
1241 StringRef IDVal = getTok().getString();
1242 if (IDVal == "f" || IDVal == "b") {
1244 getContext().getDirectionalLocalSymbol(IntVal, IDVal == "b");
1245 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1247 MCSymbolRefExpr::create(Sym, Variant, getContext());
1248 if (IDVal == "b" && Sym->isUndefined())
1249 return Error(Loc, "invalid reference to undefined symbol");
1250 StringRef Identifier = Sym->getName();
1251 SM.onIdentifierExpr(Val, Identifier);
1252 End = consumeToken();
1254 if (SM.onInteger(IntVal, ErrMsg))
1255 return Error(Loc, ErrMsg);
1258 if (SM.onInteger(IntVal, ErrMsg))
1259 return Error(Loc, ErrMsg);
1263 case AsmToken::Plus: SM.onPlus(); break;
1264 case AsmToken::Minus: SM.onMinus(); break;
1265 case AsmToken::Tilde: SM.onNot(); break;
1266 case AsmToken::Star: SM.onStar(); break;
1267 case AsmToken::Slash: SM.onDivide(); break;
1268 case AsmToken::Pipe: SM.onOr(); break;
1269 case AsmToken::Caret: SM.onXor(); break;
1270 case AsmToken::Amp: SM.onAnd(); break;
1271 case AsmToken::LessLess:
1272 SM.onLShift(); break;
1273 case AsmToken::GreaterGreater:
1274 SM.onRShift(); break;
1275 case AsmToken::LBrac: SM.onLBrac(); break;
1276 case AsmToken::RBrac: SM.onRBrac(); break;
1277 case AsmToken::LParen: SM.onLParen(); break;
1278 case AsmToken::RParen: SM.onRParen(); break;
1281 return Error(Tok.getLoc(), "unknown token in expression");
1283 if (!Done && UpdateLocLex)
1284 End = consumeToken();
1289 std::unique_ptr<X86Operand>
1290 X86AsmParser::ParseIntelBracExpression(unsigned SegReg, SMLoc Start,
1291 int64_t ImmDisp, unsigned Size) {
1292 MCAsmParser &Parser = getParser();
1293 const AsmToken &Tok = Parser.getTok();
1294 SMLoc BracLoc = Tok.getLoc(), End = Tok.getEndLoc();
1295 if (getLexer().isNot(AsmToken::LBrac))
1296 return ErrorOperand(BracLoc, "Expected '[' token!");
1297 Parser.Lex(); // Eat '['
1299 SMLoc StartInBrac = Tok.getLoc();
1300 // Parse [ Symbol + ImmDisp ] and [ BaseReg + Scale*IndexReg + ImmDisp ]. We
1301 // may have already parsed an immediate displacement before the bracketed
1303 IntelExprStateMachine SM(ImmDisp, /*StopOnLBrac=*/false, /*AddImmPrefix=*/true);
1304 if (ParseIntelExpression(SM, End))
1307 const MCExpr *Disp = nullptr;
1308 if (const MCExpr *Sym = SM.getSym()) {
1309 // A symbolic displacement.
1311 if (isParsingInlineAsm())
1312 RewriteIntelBracExpression(InstInfo->AsmRewrites, SM.getSymName(),
1313 ImmDisp, SM.getImm(), BracLoc, StartInBrac,
1317 if (SM.getImm() || !Disp) {
1318 const MCExpr *Imm = MCConstantExpr::create(SM.getImm(), getContext());
1320 Disp = MCBinaryExpr::createAdd(Disp, Imm, getContext());
1322 Disp = Imm; // An immediate displacement only.
1325 // Parse struct field access. Intel requires a dot, but MSVC doesn't. MSVC
1326 // will in fact do global lookup the field name inside all global typedefs,
1327 // but we don't emulate that.
1328 if (Tok.getString().find('.') != StringRef::npos) {
1329 const MCExpr *NewDisp;
1330 if (ParseIntelDotOperator(Disp, NewDisp))
1333 End = Tok.getEndLoc();
1334 Parser.Lex(); // Eat the field.
1338 int BaseReg = SM.getBaseReg();
1339 int IndexReg = SM.getIndexReg();
1340 int Scale = SM.getScale();
1341 if (!isParsingInlineAsm()) {
1343 if (!BaseReg && !IndexReg) {
1345 return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size);
1346 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
1350 if (CheckBaseRegAndIndexReg(BaseReg, IndexReg, ErrMsg)) {
1351 Error(StartInBrac, ErrMsg);
1354 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
1355 IndexReg, Scale, Start, End, Size);
1358 InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
1359 return CreateMemForInlineAsm(SegReg, Disp, BaseReg, IndexReg, Scale, Start,
1360 End, Size, SM.getSymName(), Info);
1363 // Inline assembly may use variable names with namespace alias qualifiers.
1364 bool X86AsmParser::ParseIntelIdentifier(const MCExpr *&Val,
1365 StringRef &Identifier,
1366 InlineAsmIdentifierInfo &Info,
1367 bool IsUnevaluatedOperand, SMLoc &End) {
1368 MCAsmParser &Parser = getParser();
1369 assert (isParsingInlineAsm() && "Expected to be parsing inline assembly.");
1372 StringRef LineBuf(Identifier.data());
1374 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);
1376 const AsmToken &Tok = Parser.getTok();
1377 SMLoc Loc = Tok.getLoc();
1379 // Advance the token stream until the end of the current token is
1380 // after the end of what the frontend claimed.
1381 const char *EndPtr = Tok.getLoc().getPointer() + LineBuf.size();
1383 End = Tok.getEndLoc();
1386 assert(End.getPointer() <= EndPtr && "frontend claimed part of a token?");
1387 if (End.getPointer() == EndPtr) break;
1389 Identifier = LineBuf;
1391 // If the identifier lookup was unsuccessful, assume that we are dealing with
1394 StringRef InternalName =
1395 SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(),
1397 assert(InternalName.size() && "We should have an internal name here.");
1398 // Push a rewrite for replacing the identifier name with the internal name.
1399 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Label, Loc,
1404 // Create the symbol reference.
1405 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
1406 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1407 Val = MCSymbolRefExpr::create(Sym, Variant, getParser().getContext());
1411 /// \brief Parse intel style segment override.
1412 std::unique_ptr<X86Operand>
1413 X86AsmParser::ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start,
1415 MCAsmParser &Parser = getParser();
1416 assert(SegReg != 0 && "Tried to parse a segment override without a segment!");
1417 const AsmToken &Tok = Parser.getTok(); // Eat colon.
1418 if (Tok.isNot(AsmToken::Colon))
1419 return ErrorOperand(Tok.getLoc(), "Expected ':' token!");
1420 Parser.Lex(); // Eat ':'
1422 int64_t ImmDisp = 0;
1423 if (getLexer().is(AsmToken::Integer)) {
1424 ImmDisp = Tok.getIntVal();
1425 AsmToken ImmDispToken = Parser.Lex(); // Eat the integer.
1427 if (isParsingInlineAsm())
1428 InstInfo->AsmRewrites->push_back(
1429 AsmRewrite(AOK_ImmPrefix, ImmDispToken.getLoc()));
1431 if (getLexer().isNot(AsmToken::LBrac)) {
1432 // An immediate following a 'segment register', 'colon' token sequence can
1433 // be followed by a bracketed expression. If it isn't we know we have our
1434 // final segment override.
1435 const MCExpr *Disp = MCConstantExpr::create(ImmDisp, getContext());
1436 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp,
1437 /*BaseReg=*/0, /*IndexReg=*/0, /*Scale=*/1,
1438 Start, ImmDispToken.getEndLoc(), Size);
1442 if (getLexer().is(AsmToken::LBrac))
1443 return ParseIntelBracExpression(SegReg, Start, ImmDisp, Size);
1447 if (!isParsingInlineAsm()) {
1448 if (getParser().parsePrimaryExpr(Val, End))
1449 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1451 return X86Operand::CreateMem(getPointerWidth(), Val, Start, End, Size);
1454 InlineAsmIdentifierInfo Info;
1455 StringRef Identifier = Tok.getString();
1456 if (ParseIntelIdentifier(Val, Identifier, Info,
1457 /*Unevaluated=*/false, End))
1459 return CreateMemForInlineAsm(/*SegReg=*/0, Val, /*BaseReg=*/0,/*IndexReg=*/0,
1460 /*Scale=*/1, Start, End, Size, Identifier, Info);
1463 //ParseRoundingModeOp - Parse AVX-512 rounding mode operand
1464 std::unique_ptr<X86Operand>
1465 X86AsmParser::ParseRoundingModeOp(SMLoc Start, SMLoc End) {
1466 MCAsmParser &Parser = getParser();
1467 const AsmToken &Tok = Parser.getTok();
1468 // Eat "{" and mark the current place.
1469 const SMLoc consumedToken = consumeToken();
1470 if (Tok.getIdentifier().startswith("r")){
1471 int rndMode = StringSwitch<int>(Tok.getIdentifier())
1472 .Case("rn", X86::STATIC_ROUNDING::TO_NEAREST_INT)
1473 .Case("rd", X86::STATIC_ROUNDING::TO_NEG_INF)
1474 .Case("ru", X86::STATIC_ROUNDING::TO_POS_INF)
1475 .Case("rz", X86::STATIC_ROUNDING::TO_ZERO)
1478 return ErrorOperand(Tok.getLoc(), "Invalid rounding mode.");
1479 Parser.Lex(); // Eat "r*" of r*-sae
1480 if (!getLexer().is(AsmToken::Minus))
1481 return ErrorOperand(Tok.getLoc(), "Expected - at this point");
1482 Parser.Lex(); // Eat "-"
1483 Parser.Lex(); // Eat the sae
1484 if (!getLexer().is(AsmToken::RCurly))
1485 return ErrorOperand(Tok.getLoc(), "Expected } at this point");
1486 Parser.Lex(); // Eat "}"
1487 const MCExpr *RndModeOp =
1488 MCConstantExpr::create(rndMode, Parser.getContext());
1489 return X86Operand::CreateImm(RndModeOp, Start, End);
1491 if(Tok.getIdentifier().equals("sae")){
1492 Parser.Lex(); // Eat the sae
1493 if (!getLexer().is(AsmToken::RCurly))
1494 return ErrorOperand(Tok.getLoc(), "Expected } at this point");
1495 Parser.Lex(); // Eat "}"
1496 return X86Operand::CreateToken("{sae}", consumedToken);
1498 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1500 /// ParseIntelMemOperand - Parse intel style memory operand.
1501 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelMemOperand(int64_t ImmDisp,
1504 MCAsmParser &Parser = getParser();
1505 const AsmToken &Tok = Parser.getTok();
1508 // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
1509 if (getLexer().is(AsmToken::LBrac))
1510 return ParseIntelBracExpression(/*SegReg=*/0, Start, ImmDisp, Size);
1511 assert(ImmDisp == 0);
1514 if (!isParsingInlineAsm()) {
1515 if (getParser().parsePrimaryExpr(Val, End))
1516 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1518 return X86Operand::CreateMem(getPointerWidth(), Val, Start, End, Size);
1521 InlineAsmIdentifierInfo Info;
1522 StringRef Identifier = Tok.getString();
1523 if (ParseIntelIdentifier(Val, Identifier, Info,
1524 /*Unevaluated=*/false, End))
1527 if (!getLexer().is(AsmToken::LBrac))
1528 return CreateMemForInlineAsm(/*SegReg=*/0, Val, /*BaseReg=*/0, /*IndexReg=*/0,
1529 /*Scale=*/1, Start, End, Size, Identifier, Info);
1531 Parser.Lex(); // Eat '['
1533 // Parse Identifier [ ImmDisp ]
1534 IntelExprStateMachine SM(/*ImmDisp=*/0, /*StopOnLBrac=*/true,
1535 /*AddImmPrefix=*/false);
1536 if (ParseIntelExpression(SM, End))
1540 Error(Start, "cannot use more than one symbol in memory operand");
1543 if (SM.getBaseReg()) {
1544 Error(Start, "cannot use base register with variable reference");
1547 if (SM.getIndexReg()) {
1548 Error(Start, "cannot use index register with variable reference");
1552 const MCExpr *Disp = MCConstantExpr::create(SM.getImm(), getContext());
1553 // BaseReg is non-zero to avoid assertions. In the context of inline asm,
1554 // we're pointing to a local variable in memory, so the base register is
1555 // really the frame or stack pointer.
1556 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
1557 /*BaseReg=*/1, /*IndexReg=*/0, /*Scale=*/1,
1558 Start, End, Size, Identifier, Info.OpDecl);
1561 /// Parse the '.' operator.
1562 bool X86AsmParser::ParseIntelDotOperator(const MCExpr *Disp,
1563 const MCExpr *&NewDisp) {
1564 MCAsmParser &Parser = getParser();
1565 const AsmToken &Tok = Parser.getTok();
1566 int64_t OrigDispVal, DotDispVal;
1568 // FIXME: Handle non-constant expressions.
1569 if (const MCConstantExpr *OrigDisp = dyn_cast<MCConstantExpr>(Disp))
1570 OrigDispVal = OrigDisp->getValue();
1572 return Error(Tok.getLoc(), "Non-constant offsets are not supported!");
1574 // Drop the optional '.'.
1575 StringRef DotDispStr = Tok.getString();
1576 if (DotDispStr.startswith("."))
1577 DotDispStr = DotDispStr.drop_front(1);
1579 // .Imm gets lexed as a real.
1580 if (Tok.is(AsmToken::Real)) {
1582 DotDispStr.getAsInteger(10, DotDisp);
1583 DotDispVal = DotDisp.getZExtValue();
1584 } else if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) {
1586 std::pair<StringRef, StringRef> BaseMember = DotDispStr.split('.');
1587 if (SemaCallback->LookupInlineAsmField(BaseMember.first, BaseMember.second,
1589 return Error(Tok.getLoc(), "Unable to lookup field reference!");
1590 DotDispVal = DotDisp;
1592 return Error(Tok.getLoc(), "Unexpected token type!");
1594 if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) {
1595 SMLoc Loc = SMLoc::getFromPointer(DotDispStr.data());
1596 unsigned Len = DotDispStr.size();
1597 unsigned Val = OrigDispVal + DotDispVal;
1598 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_DotOperator, Loc, Len,
1602 NewDisp = MCConstantExpr::create(OrigDispVal + DotDispVal, getContext());
1606 /// Parse the 'offset' operator. This operator is used to specify the
1607 /// location rather then the content of a variable.
1608 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOffsetOfOperator() {
1609 MCAsmParser &Parser = getParser();
1610 const AsmToken &Tok = Parser.getTok();
1611 SMLoc OffsetOfLoc = Tok.getLoc();
1612 Parser.Lex(); // Eat offset.
1615 InlineAsmIdentifierInfo Info;
1616 SMLoc Start = Tok.getLoc(), End;
1617 StringRef Identifier = Tok.getString();
1618 if (ParseIntelIdentifier(Val, Identifier, Info,
1619 /*Unevaluated=*/false, End))
1622 // Don't emit the offset operator.
1623 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Skip, OffsetOfLoc, 7));
1625 // The offset operator will have an 'r' constraint, thus we need to create
1626 // register operand to ensure proper matching. Just pick a GPR based on
1627 // the size of a pointer.
1629 is64BitMode() ? X86::RBX : (is32BitMode() ? X86::EBX : X86::BX);
1630 return X86Operand::CreateReg(RegNo, Start, End, /*GetAddress=*/true,
1631 OffsetOfLoc, Identifier, Info.OpDecl);
1634 enum IntelOperatorKind {
1640 /// Parse the 'LENGTH', 'TYPE' and 'SIZE' operators. The LENGTH operator
1641 /// returns the number of elements in an array. It returns the value 1 for
1642 /// non-array variables. The SIZE operator returns the size of a C or C++
1643 /// variable. A variable's size is the product of its LENGTH and TYPE. The
1644 /// TYPE operator returns the size of a C or C++ type or variable. If the
1645 /// variable is an array, TYPE returns the size of a single element.
1646 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperator(unsigned OpKind) {
1647 MCAsmParser &Parser = getParser();
1648 const AsmToken &Tok = Parser.getTok();
1649 SMLoc TypeLoc = Tok.getLoc();
1650 Parser.Lex(); // Eat operator.
1652 const MCExpr *Val = nullptr;
1653 InlineAsmIdentifierInfo Info;
1654 SMLoc Start = Tok.getLoc(), End;
1655 StringRef Identifier = Tok.getString();
1656 if (ParseIntelIdentifier(Val, Identifier, Info,
1657 /*Unevaluated=*/true, End))
1661 return ErrorOperand(Start, "unable to lookup expression");
1665 default: llvm_unreachable("Unexpected operand kind!");
1666 case IOK_LENGTH: CVal = Info.Length; break;
1667 case IOK_SIZE: CVal = Info.Size; break;
1668 case IOK_TYPE: CVal = Info.Type; break;
1671 // Rewrite the type operator and the C or C++ type or variable in terms of an
1672 // immediate. E.g. TYPE foo -> $$4
1673 unsigned Len = End.getPointer() - TypeLoc.getPointer();
1674 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Imm, TypeLoc, Len, CVal));
1676 const MCExpr *Imm = MCConstantExpr::create(CVal, getContext());
1677 return X86Operand::CreateImm(Imm, Start, End);
1680 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand() {
1681 MCAsmParser &Parser = getParser();
1682 const AsmToken &Tok = Parser.getTok();
1685 // Offset, length, type and size operators.
1686 if (isParsingInlineAsm()) {
1687 StringRef AsmTokStr = Tok.getString();
1688 if (AsmTokStr == "offset" || AsmTokStr == "OFFSET")
1689 return ParseIntelOffsetOfOperator();
1690 if (AsmTokStr == "length" || AsmTokStr == "LENGTH")
1691 return ParseIntelOperator(IOK_LENGTH);
1692 if (AsmTokStr == "size" || AsmTokStr == "SIZE")
1693 return ParseIntelOperator(IOK_SIZE);
1694 if (AsmTokStr == "type" || AsmTokStr == "TYPE")
1695 return ParseIntelOperator(IOK_TYPE);
1698 unsigned Size = getIntelMemOperandSize(Tok.getString());
1700 Parser.Lex(); // Eat operand size (e.g., byte, word).
1701 if (Tok.getString() != "PTR" && Tok.getString() != "ptr")
1702 return ErrorOperand(Tok.getLoc(), "Expected 'PTR' or 'ptr' token!");
1703 Parser.Lex(); // Eat ptr.
1705 Start = Tok.getLoc();
1708 if (getLexer().is(AsmToken::Integer) || getLexer().is(AsmToken::Minus) ||
1709 getLexer().is(AsmToken::Tilde) || getLexer().is(AsmToken::LParen)) {
1710 AsmToken StartTok = Tok;
1711 IntelExprStateMachine SM(/*Imm=*/0, /*StopOnLBrac=*/true,
1712 /*AddImmPrefix=*/false);
1713 if (ParseIntelExpression(SM, End))
1716 int64_t Imm = SM.getImm();
1717 if (isParsingInlineAsm()) {
1718 unsigned Len = Tok.getLoc().getPointer() - Start.getPointer();
1719 if (StartTok.getString().size() == Len)
1720 // Just add a prefix if this wasn't a complex immediate expression.
1721 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_ImmPrefix, Start));
1723 // Otherwise, rewrite the complex expression as a single immediate.
1724 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Imm, Start, Len, Imm));
1727 if (getLexer().isNot(AsmToken::LBrac)) {
1728 // If a directional label (ie. 1f or 2b) was parsed above from
1729 // ParseIntelExpression() then SM.getSym() was set to a pointer to
1730 // to the MCExpr with the directional local symbol and this is a
1731 // memory operand not an immediate operand.
1733 return X86Operand::CreateMem(getPointerWidth(), SM.getSym(), Start, End,
1736 const MCExpr *ImmExpr = MCConstantExpr::create(Imm, getContext());
1737 return X86Operand::CreateImm(ImmExpr, Start, End);
1740 // Only positive immediates are valid.
1742 return ErrorOperand(Start, "expected a positive immediate displacement "
1743 "before bracketed expr.");
1745 // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
1746 return ParseIntelMemOperand(Imm, Start, Size);
1749 // rounding mode token
1750 if (STI.getFeatureBits()[X86::FeatureAVX512] &&
1751 getLexer().is(AsmToken::LCurly))
1752 return ParseRoundingModeOp(Start, End);
1756 if (!ParseRegister(RegNo, Start, End)) {
1757 // If this is a segment register followed by a ':', then this is the start
1758 // of a segment override, otherwise this is a normal register reference.
1759 if (getLexer().isNot(AsmToken::Colon))
1760 return X86Operand::CreateReg(RegNo, Start, End);
1762 return ParseIntelSegmentOverride(/*SegReg=*/RegNo, Start, Size);
1766 return ParseIntelMemOperand(/*Disp=*/0, Start, Size);
1769 std::unique_ptr<X86Operand> X86AsmParser::ParseATTOperand() {
1770 MCAsmParser &Parser = getParser();
1771 switch (getLexer().getKind()) {
1773 // Parse a memory operand with no segment register.
1774 return ParseMemOperand(0, Parser.getTok().getLoc());
1775 case AsmToken::Percent: {
1776 // Read the register.
1779 if (ParseRegister(RegNo, Start, End)) return nullptr;
1780 if (RegNo == X86::EIZ || RegNo == X86::RIZ) {
1781 Error(Start, "%eiz and %riz can only be used as index registers",
1782 SMRange(Start, End));
1786 // If this is a segment register followed by a ':', then this is the start
1787 // of a memory reference, otherwise this is a normal register reference.
1788 if (getLexer().isNot(AsmToken::Colon))
1789 return X86Operand::CreateReg(RegNo, Start, End);
1791 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo))
1792 return ErrorOperand(Start, "invalid segment register");
1794 getParser().Lex(); // Eat the colon.
1795 return ParseMemOperand(RegNo, Start);
1797 case AsmToken::Dollar: {
1798 // $42 -> immediate.
1799 SMLoc Start = Parser.getTok().getLoc(), End;
1802 if (getParser().parseExpression(Val, End))
1804 return X86Operand::CreateImm(Val, Start, End);
1806 case AsmToken::LCurly:{
1807 SMLoc Start = Parser.getTok().getLoc(), End;
1808 if (STI.getFeatureBits()[X86::FeatureAVX512])
1809 return ParseRoundingModeOp(Start, End);
1810 return ErrorOperand(Start, "unknown token in expression");
1815 bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands,
1816 const MCParsedAsmOperand &Op) {
1817 MCAsmParser &Parser = getParser();
1818 if(STI.getFeatureBits()[X86::FeatureAVX512]) {
1819 if (getLexer().is(AsmToken::LCurly)) {
1820 // Eat "{" and mark the current place.
1821 const SMLoc consumedToken = consumeToken();
1822 // Distinguish {1to<NUM>} from {%k<NUM>}.
1823 if(getLexer().is(AsmToken::Integer)) {
1824 // Parse memory broadcasting ({1to<NUM>}).
1825 if (getLexer().getTok().getIntVal() != 1)
1826 return !ErrorAndEatStatement(getLexer().getLoc(),
1827 "Expected 1to<NUM> at this point");
1828 Parser.Lex(); // Eat "1" of 1to8
1829 if (!getLexer().is(AsmToken::Identifier) ||
1830 !getLexer().getTok().getIdentifier().startswith("to"))
1831 return !ErrorAndEatStatement(getLexer().getLoc(),
1832 "Expected 1to<NUM> at this point");
1833 // Recognize only reasonable suffixes.
1834 const char *BroadcastPrimitive =
1835 StringSwitch<const char*>(getLexer().getTok().getIdentifier())
1836 .Case("to2", "{1to2}")
1837 .Case("to4", "{1to4}")
1838 .Case("to8", "{1to8}")
1839 .Case("to16", "{1to16}")
1841 if (!BroadcastPrimitive)
1842 return !ErrorAndEatStatement(getLexer().getLoc(),
1843 "Invalid memory broadcast primitive.");
1844 Parser.Lex(); // Eat "toN" of 1toN
1845 if (!getLexer().is(AsmToken::RCurly))
1846 return !ErrorAndEatStatement(getLexer().getLoc(),
1847 "Expected } at this point");
1848 Parser.Lex(); // Eat "}"
1849 Operands.push_back(X86Operand::CreateToken(BroadcastPrimitive,
1851 // No AVX512 specific primitives can pass
1852 // after memory broadcasting, so return.
1855 // Parse mask register {%k1}
1856 Operands.push_back(X86Operand::CreateToken("{", consumedToken));
1857 if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
1858 Operands.push_back(std::move(Op));
1859 if (!getLexer().is(AsmToken::RCurly))
1860 return !ErrorAndEatStatement(getLexer().getLoc(),
1861 "Expected } at this point");
1862 Operands.push_back(X86Operand::CreateToken("}", consumeToken()));
1864 // Parse "zeroing non-masked" semantic {z}
1865 if (getLexer().is(AsmToken::LCurly)) {
1866 Operands.push_back(X86Operand::CreateToken("{z}", consumeToken()));
1867 if (!getLexer().is(AsmToken::Identifier) ||
1868 getLexer().getTok().getIdentifier() != "z")
1869 return !ErrorAndEatStatement(getLexer().getLoc(),
1870 "Expected z at this point");
1871 Parser.Lex(); // Eat the z
1872 if (!getLexer().is(AsmToken::RCurly))
1873 return !ErrorAndEatStatement(getLexer().getLoc(),
1874 "Expected } at this point");
1875 Parser.Lex(); // Eat the }
1884 /// ParseMemOperand: segment: disp(basereg, indexreg, scale). The '%ds:' prefix
1885 /// has already been parsed if present.
1886 std::unique_ptr<X86Operand> X86AsmParser::ParseMemOperand(unsigned SegReg,
1889 MCAsmParser &Parser = getParser();
1890 // We have to disambiguate a parenthesized expression "(4+5)" from the start
1891 // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)". The
1892 // only way to do this without lookahead is to eat the '(' and see what is
1894 const MCExpr *Disp = MCConstantExpr::create(0, getParser().getContext());
1895 if (getLexer().isNot(AsmToken::LParen)) {
1897 if (getParser().parseExpression(Disp, ExprEnd)) return nullptr;
1899 // After parsing the base expression we could either have a parenthesized
1900 // memory address or not. If not, return now. If so, eat the (.
1901 if (getLexer().isNot(AsmToken::LParen)) {
1902 // Unless we have a segment register, treat this as an immediate.
1904 return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, ExprEnd);
1905 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
1912 // Okay, we have a '('. We don't know if this is an expression or not, but
1913 // so we have to eat the ( to see beyond it.
1914 SMLoc LParenLoc = Parser.getTok().getLoc();
1915 Parser.Lex(); // Eat the '('.
1917 if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) {
1918 // Nothing to do here, fall into the code below with the '(' part of the
1919 // memory operand consumed.
1923 // It must be an parenthesized expression, parse it now.
1924 if (getParser().parseParenExpression(Disp, ExprEnd))
1927 // After parsing the base expression we could either have a parenthesized
1928 // memory address or not. If not, return now. If so, eat the (.
1929 if (getLexer().isNot(AsmToken::LParen)) {
1930 // Unless we have a segment register, treat this as an immediate.
1932 return X86Operand::CreateMem(getPointerWidth(), Disp, LParenLoc,
1934 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
1943 // If we reached here, then we just ate the ( of the memory operand. Process
1944 // the rest of the memory operand.
1945 unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
1946 SMLoc IndexLoc, BaseLoc;
1948 if (getLexer().is(AsmToken::Percent)) {
1949 SMLoc StartLoc, EndLoc;
1950 BaseLoc = Parser.getTok().getLoc();
1951 if (ParseRegister(BaseReg, StartLoc, EndLoc)) return nullptr;
1952 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) {
1953 Error(StartLoc, "eiz and riz can only be used as index registers",
1954 SMRange(StartLoc, EndLoc));
1959 if (getLexer().is(AsmToken::Comma)) {
1960 Parser.Lex(); // Eat the comma.
1961 IndexLoc = Parser.getTok().getLoc();
1963 // Following the comma we should have either an index register, or a scale
1964 // value. We don't support the later form, but we want to parse it
1967 // Not that even though it would be completely consistent to support syntax
1968 // like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this.
1969 if (getLexer().is(AsmToken::Percent)) {
1971 if (ParseRegister(IndexReg, L, L)) return nullptr;
1973 if (getLexer().isNot(AsmToken::RParen)) {
1974 // Parse the scale amount:
1975 // ::= ',' [scale-expression]
1976 if (getLexer().isNot(AsmToken::Comma)) {
1977 Error(Parser.getTok().getLoc(),
1978 "expected comma in scale expression");
1981 Parser.Lex(); // Eat the comma.
1983 if (getLexer().isNot(AsmToken::RParen)) {
1984 SMLoc Loc = Parser.getTok().getLoc();
1987 if (getParser().parseAbsoluteExpression(ScaleVal)){
1988 Error(Loc, "expected scale expression");
1992 // Validate the scale amount.
1993 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
1995 Error(Loc, "scale factor in 16-bit address must be 1");
1998 if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8){
1999 Error(Loc, "scale factor in address must be 1, 2, 4 or 8");
2002 Scale = (unsigned)ScaleVal;
2005 } else if (getLexer().isNot(AsmToken::RParen)) {
2006 // A scale amount without an index is ignored.
2008 SMLoc Loc = Parser.getTok().getLoc();
2011 if (getParser().parseAbsoluteExpression(Value))
2015 Warning(Loc, "scale factor without index register is ignored");
2020 // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
2021 if (getLexer().isNot(AsmToken::RParen)) {
2022 Error(Parser.getTok().getLoc(), "unexpected token in memory operand");
2025 SMLoc MemEnd = Parser.getTok().getEndLoc();
2026 Parser.Lex(); // Eat the ')'.
2028 // Check for use of invalid 16-bit registers. Only BX/BP/SI/DI are allowed,
2029 // and then only in non-64-bit modes. Except for DX, which is a special case
2030 // because an unofficial form of in/out instructions uses it.
2031 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
2032 (is64BitMode() || (BaseReg != X86::BX && BaseReg != X86::BP &&
2033 BaseReg != X86::SI && BaseReg != X86::DI)) &&
2034 BaseReg != X86::DX) {
2035 Error(BaseLoc, "invalid 16-bit base register");
2039 X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg)) {
2040 Error(IndexLoc, "16-bit memory operand may not include only index register");
2045 if (CheckBaseRegAndIndexReg(BaseReg, IndexReg, ErrMsg)) {
2046 Error(BaseLoc, ErrMsg);
2050 if (SegReg || BaseReg || IndexReg)
2051 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
2052 IndexReg, Scale, MemStart, MemEnd);
2053 return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, MemEnd);
2056 bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2057 SMLoc NameLoc, OperandVector &Operands) {
2058 MCAsmParser &Parser = getParser();
2060 StringRef PatchedName = Name;
2062 // FIXME: Hack to recognize setneb as setne.
2063 if (PatchedName.startswith("set") && PatchedName.endswith("b") &&
2064 PatchedName != "setb" && PatchedName != "setnb")
2065 PatchedName = PatchedName.substr(0, Name.size()-1);
2067 // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}.
2068 if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) &&
2069 (PatchedName.endswith("ss") || PatchedName.endswith("sd") ||
2070 PatchedName.endswith("ps") || PatchedName.endswith("pd"))) {
2071 bool IsVCMP = PatchedName[0] == 'v';
2072 unsigned CCIdx = IsVCMP ? 4 : 3;
2073 unsigned ComparisonCode = StringSwitch<unsigned>(
2074 PatchedName.slice(CCIdx, PatchedName.size() - 2))
2078 .Case("unord", 0x03)
2083 /* AVX only from here */
2084 .Case("eq_uq", 0x08)
2087 .Case("false", 0x0B)
2088 .Case("neq_oq", 0x0C)
2092 .Case("eq_os", 0x10)
2093 .Case("lt_oq", 0x11)
2094 .Case("le_oq", 0x12)
2095 .Case("unord_s", 0x13)
2096 .Case("neq_us", 0x14)
2097 .Case("nlt_uq", 0x15)
2098 .Case("nle_uq", 0x16)
2099 .Case("ord_s", 0x17)
2100 .Case("eq_us", 0x18)
2101 .Case("nge_uq", 0x19)
2102 .Case("ngt_uq", 0x1A)
2103 .Case("false_os", 0x1B)
2104 .Case("neq_os", 0x1C)
2105 .Case("ge_oq", 0x1D)
2106 .Case("gt_oq", 0x1E)
2107 .Case("true_us", 0x1F)
2109 if (ComparisonCode != ~0U && (IsVCMP || ComparisonCode < 8)) {
2111 Operands.push_back(X86Operand::CreateToken(PatchedName.slice(0, CCIdx),
2114 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2115 getParser().getContext());
2116 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2118 PatchedName = PatchedName.substr(PatchedName.size() - 2);
2122 // FIXME: Hack to recognize vpcmp<comparison code>{ub,uw,ud,uq,b,w,d,q}.
2123 if (PatchedName.startswith("vpcmp") &&
2124 (PatchedName.endswith("b") || PatchedName.endswith("w") ||
2125 PatchedName.endswith("d") || PatchedName.endswith("q"))) {
2126 unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1;
2127 unsigned ComparisonCode = StringSwitch<unsigned>(
2128 PatchedName.slice(5, PatchedName.size() - CCIdx))
2129 .Case("eq", 0x0) // Only allowed on unsigned. Checked below.
2132 //.Case("false", 0x3) // Not a documented alias.
2136 //.Case("true", 0x7) // Not a documented alias.
2138 if (ComparisonCode != ~0U && (ComparisonCode != 0 || CCIdx == 2)) {
2139 Operands.push_back(X86Operand::CreateToken("vpcmp", NameLoc));
2141 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2142 getParser().getContext());
2143 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2145 PatchedName = PatchedName.substr(PatchedName.size() - CCIdx);
2149 // FIXME: Hack to recognize vpcom<comparison code>{ub,uw,ud,uq,b,w,d,q}.
2150 if (PatchedName.startswith("vpcom") &&
2151 (PatchedName.endswith("b") || PatchedName.endswith("w") ||
2152 PatchedName.endswith("d") || PatchedName.endswith("q"))) {
2153 unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1;
2154 unsigned ComparisonCode = StringSwitch<unsigned>(
2155 PatchedName.slice(5, PatchedName.size() - CCIdx))
2165 if (ComparisonCode != ~0U) {
2166 Operands.push_back(X86Operand::CreateToken("vpcom", NameLoc));
2168 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2169 getParser().getContext());
2170 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2172 PatchedName = PatchedName.substr(PatchedName.size() - CCIdx);
2176 Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
2178 // Determine whether this is an instruction prefix.
2180 Name == "lock" || Name == "rep" ||
2181 Name == "repe" || Name == "repz" ||
2182 Name == "repne" || Name == "repnz" ||
2183 Name == "rex64" || Name == "data16";
2186 // This does the actual operand parsing. Don't parse any more if we have a
2187 // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we
2188 // just want to parse the "lock" as the first instruction and the "incl" as
2190 if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) {
2192 // Parse '*' modifier.
2193 if (getLexer().is(AsmToken::Star))
2194 Operands.push_back(X86Operand::CreateToken("*", consumeToken()));
2196 // Read the operands.
2198 if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
2199 Operands.push_back(std::move(Op));
2200 if (!HandleAVX512Operand(Operands, *Operands.back()))
2203 Parser.eatToEndOfStatement();
2206 // check for comma and eat it
2207 if (getLexer().is(AsmToken::Comma))
2213 if (getLexer().isNot(AsmToken::EndOfStatement))
2214 return ErrorAndEatStatement(getLexer().getLoc(),
2215 "unexpected token in argument list");
2218 // Consume the EndOfStatement or the prefix separator Slash
2219 if (getLexer().is(AsmToken::EndOfStatement) ||
2220 (isPrefix && getLexer().is(AsmToken::Slash)))
2223 // This is a terrible hack to handle "out[bwl]? %al, (%dx)" ->
2224 // "outb %al, %dx". Out doesn't take a memory form, but this is a widely
2225 // documented form in various unofficial manuals, so a lot of code uses it.
2226 if ((Name == "outb" || Name == "outw" || Name == "outl" || Name == "out") &&
2227 Operands.size() == 3) {
2228 X86Operand &Op = (X86Operand &)*Operands.back();
2229 if (Op.isMem() && Op.Mem.SegReg == 0 &&
2230 isa<MCConstantExpr>(Op.Mem.Disp) &&
2231 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
2232 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
2233 SMLoc Loc = Op.getEndLoc();
2234 Operands.back() = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
2237 // Same hack for "in[bwl]? (%dx), %al" -> "inb %dx, %al".
2238 if ((Name == "inb" || Name == "inw" || Name == "inl" || Name == "in") &&
2239 Operands.size() == 3) {
2240 X86Operand &Op = (X86Operand &)*Operands[1];
2241 if (Op.isMem() && Op.Mem.SegReg == 0 &&
2242 isa<MCConstantExpr>(Op.Mem.Disp) &&
2243 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
2244 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
2245 SMLoc Loc = Op.getEndLoc();
2246 Operands[1] = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
2250 // Append default arguments to "ins[bwld]"
2251 if (Name.startswith("ins") && Operands.size() == 1 &&
2252 (Name == "insb" || Name == "insw" || Name == "insl" ||
2254 AddDefaultSrcDestOperands(Operands,
2255 X86Operand::CreateReg(X86::DX, NameLoc, NameLoc),
2256 DefaultMemDIOperand(NameLoc));
2259 // Append default arguments to "outs[bwld]"
2260 if (Name.startswith("outs") && Operands.size() == 1 &&
2261 (Name == "outsb" || Name == "outsw" || Name == "outsl" ||
2262 Name == "outsd" )) {
2263 AddDefaultSrcDestOperands(Operands,
2264 DefaultMemSIOperand(NameLoc),
2265 X86Operand::CreateReg(X86::DX, NameLoc, NameLoc));
2268 // Transform "lods[bwlq]" into "lods[bwlq] ($SIREG)" for appropriate
2269 // values of $SIREG according to the mode. It would be nice if this
2270 // could be achieved with InstAlias in the tables.
2271 if (Name.startswith("lods") && Operands.size() == 1 &&
2272 (Name == "lods" || Name == "lodsb" || Name == "lodsw" ||
2273 Name == "lodsl" || Name == "lodsd" || Name == "lodsq"))
2274 Operands.push_back(DefaultMemSIOperand(NameLoc));
2276 // Transform "stos[bwlq]" into "stos[bwlq] ($DIREG)" for appropriate
2277 // values of $DIREG according to the mode. It would be nice if this
2278 // could be achieved with InstAlias in the tables.
2279 if (Name.startswith("stos") && Operands.size() == 1 &&
2280 (Name == "stos" || Name == "stosb" || Name == "stosw" ||
2281 Name == "stosl" || Name == "stosd" || Name == "stosq"))
2282 Operands.push_back(DefaultMemDIOperand(NameLoc));
2284 // Transform "scas[bwlq]" into "scas[bwlq] ($DIREG)" for appropriate
2285 // values of $DIREG according to the mode. It would be nice if this
2286 // could be achieved with InstAlias in the tables.
2287 if (Name.startswith("scas") && Operands.size() == 1 &&
2288 (Name == "scas" || Name == "scasb" || Name == "scasw" ||
2289 Name == "scasl" || Name == "scasd" || Name == "scasq"))
2290 Operands.push_back(DefaultMemDIOperand(NameLoc));
2292 // Add default SI and DI operands to "cmps[bwlq]".
2293 if (Name.startswith("cmps") &&
2294 (Name == "cmps" || Name == "cmpsb" || Name == "cmpsw" ||
2295 Name == "cmpsl" || Name == "cmpsd" || Name == "cmpsq")) {
2296 if (Operands.size() == 1) {
2297 AddDefaultSrcDestOperands(Operands,
2298 DefaultMemDIOperand(NameLoc),
2299 DefaultMemSIOperand(NameLoc));
2300 } else if (Operands.size() == 3) {
2301 X86Operand &Op = (X86Operand &)*Operands[1];
2302 X86Operand &Op2 = (X86Operand &)*Operands[2];
2303 if (!doSrcDstMatch(Op, Op2))
2304 return Error(Op.getStartLoc(),
2305 "mismatching source and destination index registers");
2309 // Add default SI and DI operands to "movs[bwlq]".
2310 if ((Name.startswith("movs") &&
2311 (Name == "movs" || Name == "movsb" || Name == "movsw" ||
2312 Name == "movsl" || Name == "movsd" || Name == "movsq")) ||
2313 (Name.startswith("smov") &&
2314 (Name == "smov" || Name == "smovb" || Name == "smovw" ||
2315 Name == "smovl" || Name == "smovd" || Name == "smovq"))) {
2316 if (Operands.size() == 1) {
2317 if (Name == "movsd")
2318 Operands.back() = X86Operand::CreateToken("movsl", NameLoc);
2319 AddDefaultSrcDestOperands(Operands,
2320 DefaultMemSIOperand(NameLoc),
2321 DefaultMemDIOperand(NameLoc));
2322 } else if (Operands.size() == 3) {
2323 X86Operand &Op = (X86Operand &)*Operands[1];
2324 X86Operand &Op2 = (X86Operand &)*Operands[2];
2325 if (!doSrcDstMatch(Op, Op2))
2326 return Error(Op.getStartLoc(),
2327 "mismatching source and destination index registers");
2331 // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>. Canonicalize to
2333 if ((Name.startswith("shr") || Name.startswith("sar") ||
2334 Name.startswith("shl") || Name.startswith("sal") ||
2335 Name.startswith("rcl") || Name.startswith("rcr") ||
2336 Name.startswith("rol") || Name.startswith("ror")) &&
2337 Operands.size() == 3) {
2338 if (isParsingIntelSyntax()) {
2340 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[2]);
2341 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2342 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2343 Operands.pop_back();
2345 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2346 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2347 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2348 Operands.erase(Operands.begin() + 1);
2352 // Transforms "int $3" into "int3" as a size optimization. We can't write an
2353 // instalias with an immediate operand yet.
2354 if (Name == "int" && Operands.size() == 2) {
2355 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2357 if (auto *CE = dyn_cast<MCConstantExpr>(Op1.getImm()))
2358 if (CE->getValue() == 3) {
2359 Operands.erase(Operands.begin() + 1);
2360 static_cast<X86Operand &>(*Operands[0]).setTokenValue("int3");
2367 static bool convertToSExti8(MCInst &Inst, unsigned Opcode, unsigned Reg,
2370 TmpInst.setOpcode(Opcode);
2372 TmpInst.addOperand(MCOperand::createReg(Reg));
2373 TmpInst.addOperand(MCOperand::createReg(Reg));
2374 TmpInst.addOperand(Inst.getOperand(0));
2379 static bool convert16i16to16ri8(MCInst &Inst, unsigned Opcode,
2380 bool isCmp = false) {
2381 if (!Inst.getOperand(0).isImm() ||
2382 !isImmSExti16i8Value(Inst.getOperand(0).getImm()))
2385 return convertToSExti8(Inst, Opcode, X86::AX, isCmp);
2388 static bool convert32i32to32ri8(MCInst &Inst, unsigned Opcode,
2389 bool isCmp = false) {
2390 if (!Inst.getOperand(0).isImm() ||
2391 !isImmSExti32i8Value(Inst.getOperand(0).getImm()))
2394 return convertToSExti8(Inst, Opcode, X86::EAX, isCmp);
2397 static bool convert64i32to64ri8(MCInst &Inst, unsigned Opcode,
2398 bool isCmp = false) {
2399 if (!Inst.getOperand(0).isImm() ||
2400 !isImmSExti64i8Value(Inst.getOperand(0).getImm()))
2403 return convertToSExti8(Inst, Opcode, X86::RAX, isCmp);
2406 bool X86AsmParser::validateInstruction(MCInst &Inst, const OperandVector &Ops) {
2407 switch (Inst.getOpcode()) {
2408 default: return true;
2410 X86Operand &Op = static_cast<X86Operand &>(*Ops[1]);
2411 assert(Op.isImm() && "expected immediate");
2413 if (!Op.getImm()->evaluateAsAbsolute(Res) || Res > 255) {
2414 Error(Op.getStartLoc(), "interrupt vector must be in range [0-255]");
2419 llvm_unreachable("handle the instruction appropriately");
2422 bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) {
2423 switch (Inst.getOpcode()) {
2424 default: return false;
2425 case X86::AND16i16: return convert16i16to16ri8(Inst, X86::AND16ri8);
2426 case X86::AND32i32: return convert32i32to32ri8(Inst, X86::AND32ri8);
2427 case X86::AND64i32: return convert64i32to64ri8(Inst, X86::AND64ri8);
2428 case X86::XOR16i16: return convert16i16to16ri8(Inst, X86::XOR16ri8);
2429 case X86::XOR32i32: return convert32i32to32ri8(Inst, X86::XOR32ri8);
2430 case X86::XOR64i32: return convert64i32to64ri8(Inst, X86::XOR64ri8);
2431 case X86::OR16i16: return convert16i16to16ri8(Inst, X86::OR16ri8);
2432 case X86::OR32i32: return convert32i32to32ri8(Inst, X86::OR32ri8);
2433 case X86::OR64i32: return convert64i32to64ri8(Inst, X86::OR64ri8);
2434 case X86::CMP16i16: return convert16i16to16ri8(Inst, X86::CMP16ri8, true);
2435 case X86::CMP32i32: return convert32i32to32ri8(Inst, X86::CMP32ri8, true);
2436 case X86::CMP64i32: return convert64i32to64ri8(Inst, X86::CMP64ri8, true);
2437 case X86::ADD16i16: return convert16i16to16ri8(Inst, X86::ADD16ri8);
2438 case X86::ADD32i32: return convert32i32to32ri8(Inst, X86::ADD32ri8);
2439 case X86::ADD64i32: return convert64i32to64ri8(Inst, X86::ADD64ri8);
2440 case X86::SUB16i16: return convert16i16to16ri8(Inst, X86::SUB16ri8);
2441 case X86::SUB32i32: return convert32i32to32ri8(Inst, X86::SUB32ri8);
2442 case X86::SUB64i32: return convert64i32to64ri8(Inst, X86::SUB64ri8);
2443 case X86::ADC16i16: return convert16i16to16ri8(Inst, X86::ADC16ri8);
2444 case X86::ADC32i32: return convert32i32to32ri8(Inst, X86::ADC32ri8);
2445 case X86::ADC64i32: return convert64i32to64ri8(Inst, X86::ADC64ri8);
2446 case X86::SBB16i16: return convert16i16to16ri8(Inst, X86::SBB16ri8);
2447 case X86::SBB32i32: return convert32i32to32ri8(Inst, X86::SBB32ri8);
2448 case X86::SBB64i32: return convert64i32to64ri8(Inst, X86::SBB64ri8);
2449 case X86::VMOVAPDrr:
2450 case X86::VMOVAPDYrr:
2451 case X86::VMOVAPSrr:
2452 case X86::VMOVAPSYrr:
2453 case X86::VMOVDQArr:
2454 case X86::VMOVDQAYrr:
2455 case X86::VMOVDQUrr:
2456 case X86::VMOVDQUYrr:
2457 case X86::VMOVUPDrr:
2458 case X86::VMOVUPDYrr:
2459 case X86::VMOVUPSrr:
2460 case X86::VMOVUPSYrr: {
2461 if (X86II::isX86_64ExtendedReg(Inst.getOperand(0).getReg()) ||
2462 !X86II::isX86_64ExtendedReg(Inst.getOperand(1).getReg()))
2466 switch (Inst.getOpcode()) {
2467 default: llvm_unreachable("Invalid opcode");
2468 case X86::VMOVAPDrr: NewOpc = X86::VMOVAPDrr_REV; break;
2469 case X86::VMOVAPDYrr: NewOpc = X86::VMOVAPDYrr_REV; break;
2470 case X86::VMOVAPSrr: NewOpc = X86::VMOVAPSrr_REV; break;
2471 case X86::VMOVAPSYrr: NewOpc = X86::VMOVAPSYrr_REV; break;
2472 case X86::VMOVDQArr: NewOpc = X86::VMOVDQArr_REV; break;
2473 case X86::VMOVDQAYrr: NewOpc = X86::VMOVDQAYrr_REV; break;
2474 case X86::VMOVDQUrr: NewOpc = X86::VMOVDQUrr_REV; break;
2475 case X86::VMOVDQUYrr: NewOpc = X86::VMOVDQUYrr_REV; break;
2476 case X86::VMOVUPDrr: NewOpc = X86::VMOVUPDrr_REV; break;
2477 case X86::VMOVUPDYrr: NewOpc = X86::VMOVUPDYrr_REV; break;
2478 case X86::VMOVUPSrr: NewOpc = X86::VMOVUPSrr_REV; break;
2479 case X86::VMOVUPSYrr: NewOpc = X86::VMOVUPSYrr_REV; break;
2481 Inst.setOpcode(NewOpc);
2485 case X86::VMOVSSrr: {
2486 if (X86II::isX86_64ExtendedReg(Inst.getOperand(0).getReg()) ||
2487 !X86II::isX86_64ExtendedReg(Inst.getOperand(2).getReg()))
2490 switch (Inst.getOpcode()) {
2491 default: llvm_unreachable("Invalid opcode");
2492 case X86::VMOVSDrr: NewOpc = X86::VMOVSDrr_REV; break;
2493 case X86::VMOVSSrr: NewOpc = X86::VMOVSSrr_REV; break;
2495 Inst.setOpcode(NewOpc);
2501 static const char *getSubtargetFeatureName(uint64_t Val);
2503 void X86AsmParser::EmitInstruction(MCInst &Inst, OperandVector &Operands,
2505 Instrumentation->InstrumentAndEmitInstruction(Inst, Operands, getContext(),
2509 bool X86AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2510 OperandVector &Operands,
2511 MCStreamer &Out, uint64_t &ErrorInfo,
2512 bool MatchingInlineAsm) {
2513 if (isParsingIntelSyntax())
2514 return MatchAndEmitIntelInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2516 return MatchAndEmitATTInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2520 void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op,
2521 OperandVector &Operands, MCStreamer &Out,
2522 bool MatchingInlineAsm) {
2523 // FIXME: This should be replaced with a real .td file alias mechanism.
2524 // Also, MatchInstructionImpl should actually *do* the EmitInstruction
2526 const char *Repl = StringSwitch<const char *>(Op.getToken())
2527 .Case("finit", "fninit")
2528 .Case("fsave", "fnsave")
2529 .Case("fstcw", "fnstcw")
2530 .Case("fstcww", "fnstcw")
2531 .Case("fstenv", "fnstenv")
2532 .Case("fstsw", "fnstsw")
2533 .Case("fstsww", "fnstsw")
2534 .Case("fclex", "fnclex")
2538 Inst.setOpcode(X86::WAIT);
2540 if (!MatchingInlineAsm)
2541 EmitInstruction(Inst, Operands, Out);
2542 Operands[0] = X86Operand::CreateToken(Repl, IDLoc);
2546 bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
2547 bool MatchingInlineAsm) {
2548 assert(ErrorInfo && "Unknown missing feature!");
2549 ArrayRef<SMRange> EmptyRanges = None;
2550 SmallString<126> Msg;
2551 raw_svector_ostream OS(Msg);
2552 OS << "instruction requires:";
2554 for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
2555 if (ErrorInfo & Mask)
2556 OS << ' ' << getSubtargetFeatureName(ErrorInfo & Mask);
2559 return Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
2562 bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
2563 OperandVector &Operands,
2565 uint64_t &ErrorInfo,
2566 bool MatchingInlineAsm) {
2567 assert(!Operands.empty() && "Unexpect empty operand list!");
2568 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2569 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
2570 ArrayRef<SMRange> EmptyRanges = None;
2572 // First, handle aliases that expand to multiple instructions.
2573 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2575 bool WasOriginallyInvalidOperand = false;
2578 // First, try a direct match.
2579 switch (MatchInstructionImpl(Operands, Inst,
2580 ErrorInfo, MatchingInlineAsm,
2581 isParsingIntelSyntax())) {
2582 default: llvm_unreachable("Unexpected match result!");
2584 if (!validateInstruction(Inst, Operands))
2587 // Some instructions need post-processing to, for example, tweak which
2588 // encoding is selected. Loop on it while changes happen so the
2589 // individual transformations can chain off each other.
2590 if (!MatchingInlineAsm)
2591 while (processInstruction(Inst, Operands))
2595 if (!MatchingInlineAsm)
2596 EmitInstruction(Inst, Operands, Out);
2597 Opcode = Inst.getOpcode();
2599 case Match_MissingFeature:
2600 return ErrorMissingFeature(IDLoc, ErrorInfo, MatchingInlineAsm);
2601 case Match_InvalidOperand:
2602 WasOriginallyInvalidOperand = true;
2604 case Match_MnemonicFail:
2608 // FIXME: Ideally, we would only attempt suffix matches for things which are
2609 // valid prefixes, and we could just infer the right unambiguous
2610 // type. However, that requires substantially more matcher support than the
2613 // Change the operand to point to a temporary token.
2614 StringRef Base = Op.getToken();
2615 SmallString<16> Tmp;
2618 Op.setTokenValue(Tmp);
2620 // If this instruction starts with an 'f', then it is a floating point stack
2621 // instruction. These come in up to three forms for 32-bit, 64-bit, and
2622 // 80-bit floating point, which use the suffixes s,l,t respectively.
2624 // Otherwise, we assume that this may be an integer instruction, which comes
2625 // in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively.
2626 const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0";
2628 // Check for the various suffix matches.
2629 uint64_t ErrorInfoIgnore;
2630 uint64_t ErrorInfoMissingFeature = 0; // Init suppresses compiler warnings.
2633 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I) {
2634 Tmp.back() = Suffixes[I];
2635 Match[I] = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
2636 MatchingInlineAsm, isParsingIntelSyntax());
2637 // If this returned as a missing feature failure, remember that.
2638 if (Match[I] == Match_MissingFeature)
2639 ErrorInfoMissingFeature = ErrorInfoIgnore;
2642 // Restore the old token.
2643 Op.setTokenValue(Base);
2645 // If exactly one matched, then we treat that as a successful match (and the
2646 // instruction will already have been filled in correctly, since the failing
2647 // matches won't have modified it).
2648 unsigned NumSuccessfulMatches =
2649 std::count(std::begin(Match), std::end(Match), Match_Success);
2650 if (NumSuccessfulMatches == 1) {
2652 if (!MatchingInlineAsm)
2653 EmitInstruction(Inst, Operands, Out);
2654 Opcode = Inst.getOpcode();
2658 // Otherwise, the match failed, try to produce a decent error message.
2660 // If we had multiple suffix matches, then identify this as an ambiguous
2662 if (NumSuccessfulMatches > 1) {
2664 unsigned NumMatches = 0;
2665 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I)
2666 if (Match[I] == Match_Success)
2667 MatchChars[NumMatches++] = Suffixes[I];
2669 SmallString<126> Msg;
2670 raw_svector_ostream OS(Msg);
2671 OS << "ambiguous instructions require an explicit suffix (could be ";
2672 for (unsigned i = 0; i != NumMatches; ++i) {
2675 if (i + 1 == NumMatches)
2677 OS << "'" << Base << MatchChars[i] << "'";
2680 Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
2684 // Okay, we know that none of the variants matched successfully.
2686 // If all of the instructions reported an invalid mnemonic, then the original
2687 // mnemonic was invalid.
2688 if (std::count(std::begin(Match), std::end(Match), Match_MnemonicFail) == 4) {
2689 if (!WasOriginallyInvalidOperand) {
2690 ArrayRef<SMRange> Ranges =
2691 MatchingInlineAsm ? EmptyRanges : Op.getLocRange();
2692 return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'",
2693 Ranges, MatchingInlineAsm);
2696 // Recover location info for the operand if we know which was the problem.
2697 if (ErrorInfo != ~0ULL) {
2698 if (ErrorInfo >= Operands.size())
2699 return Error(IDLoc, "too few operands for instruction",
2700 EmptyRanges, MatchingInlineAsm);
2702 X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo];
2703 if (Operand.getStartLoc().isValid()) {
2704 SMRange OperandRange = Operand.getLocRange();
2705 return Error(Operand.getStartLoc(), "invalid operand for instruction",
2706 OperandRange, MatchingInlineAsm);
2710 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2714 // If one instruction matched with a missing feature, report this as a
2716 if (std::count(std::begin(Match), std::end(Match),
2717 Match_MissingFeature) == 1) {
2718 ErrorInfo = ErrorInfoMissingFeature;
2719 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
2723 // If one instruction matched with an invalid operand, report this as an
2725 if (std::count(std::begin(Match), std::end(Match),
2726 Match_InvalidOperand) == 1) {
2727 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2731 // If all of these were an outright failure, report it in a useless way.
2732 Error(IDLoc, "unknown use of instruction mnemonic without a size suffix",
2733 EmptyRanges, MatchingInlineAsm);
2737 bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
2738 OperandVector &Operands,
2740 uint64_t &ErrorInfo,
2741 bool MatchingInlineAsm) {
2742 assert(!Operands.empty() && "Unexpect empty operand list!");
2743 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2744 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
2745 StringRef Mnemonic = Op.getToken();
2746 ArrayRef<SMRange> EmptyRanges = None;
2748 // First, handle aliases that expand to multiple instructions.
2749 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2753 // Find one unsized memory operand, if present.
2754 X86Operand *UnsizedMemOp = nullptr;
2755 for (const auto &Op : Operands) {
2756 X86Operand *X86Op = static_cast<X86Operand *>(Op.get());
2757 if (X86Op->isMemUnsized())
2758 UnsizedMemOp = X86Op;
2761 // Allow some instructions to have implicitly pointer-sized operands. This is
2762 // compatible with gas.
2764 static const char *const PtrSizedInstrs[] = {"call", "jmp", "push"};
2765 for (const char *Instr : PtrSizedInstrs) {
2766 if (Mnemonic == Instr) {
2767 UnsizedMemOp->Mem.Size = getPointerWidth();
2773 // If an unsized memory operand is present, try to match with each memory
2774 // operand size. In Intel assembly, the size is not part of the instruction
2776 SmallVector<unsigned, 8> Match;
2777 uint64_t ErrorInfoMissingFeature = 0;
2778 if (UnsizedMemOp && UnsizedMemOp->isMemUnsized()) {
2779 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
2780 for (unsigned Size : MopSizes) {
2781 UnsizedMemOp->Mem.Size = Size;
2782 uint64_t ErrorInfoIgnore;
2783 unsigned LastOpcode = Inst.getOpcode();
2785 MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
2786 MatchingInlineAsm, isParsingIntelSyntax());
2787 if (Match.empty() || LastOpcode != Inst.getOpcode())
2790 // If this returned as a missing feature failure, remember that.
2791 if (Match.back() == Match_MissingFeature)
2792 ErrorInfoMissingFeature = ErrorInfoIgnore;
2795 // Restore the size of the unsized memory operand if we modified it.
2797 UnsizedMemOp->Mem.Size = 0;
2800 // If we haven't matched anything yet, this is not a basic integer or FPU
2801 // operation. There shouldn't be any ambiguity in our mnemonic table, so try
2802 // matching with the unsized operand.
2803 if (Match.empty()) {
2804 Match.push_back(MatchInstructionImpl(Operands, Inst, ErrorInfo,
2806 isParsingIntelSyntax()));
2807 // If this returned as a missing feature failure, remember that.
2808 if (Match.back() == Match_MissingFeature)
2809 ErrorInfoMissingFeature = ErrorInfo;
2812 // Restore the size of the unsized memory operand if we modified it.
2814 UnsizedMemOp->Mem.Size = 0;
2816 // If it's a bad mnemonic, all results will be the same.
2817 if (Match.back() == Match_MnemonicFail) {
2818 ArrayRef<SMRange> Ranges =
2819 MatchingInlineAsm ? EmptyRanges : Op.getLocRange();
2820 return Error(IDLoc, "invalid instruction mnemonic '" + Mnemonic + "'",
2821 Ranges, MatchingInlineAsm);
2824 // If exactly one matched, then we treat that as a successful match (and the
2825 // instruction will already have been filled in correctly, since the failing
2826 // matches won't have modified it).
2827 unsigned NumSuccessfulMatches =
2828 std::count(std::begin(Match), std::end(Match), Match_Success);
2829 if (NumSuccessfulMatches == 1) {
2830 if (!validateInstruction(Inst, Operands))
2833 // Some instructions need post-processing to, for example, tweak which
2834 // encoding is selected. Loop on it while changes happen so the individual
2835 // transformations can chain off each other.
2836 if (!MatchingInlineAsm)
2837 while (processInstruction(Inst, Operands))
2840 if (!MatchingInlineAsm)
2841 EmitInstruction(Inst, Operands, Out);
2842 Opcode = Inst.getOpcode();
2844 } else if (NumSuccessfulMatches > 1) {
2845 assert(UnsizedMemOp &&
2846 "multiple matches only possible with unsized memory operands");
2847 ArrayRef<SMRange> Ranges =
2848 MatchingInlineAsm ? EmptyRanges : UnsizedMemOp->getLocRange();
2849 return Error(UnsizedMemOp->getStartLoc(),
2850 "ambiguous operand size for instruction '" + Mnemonic + "\'",
2851 Ranges, MatchingInlineAsm);
2854 // If one instruction matched with a missing feature, report this as a
2856 if (std::count(std::begin(Match), std::end(Match),
2857 Match_MissingFeature) == 1) {
2858 ErrorInfo = ErrorInfoMissingFeature;
2859 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
2863 // If one instruction matched with an invalid operand, report this as an
2865 if (std::count(std::begin(Match), std::end(Match),
2866 Match_InvalidOperand) == 1) {
2867 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2871 // If all of these were an outright failure, report it in a useless way.
2872 return Error(IDLoc, "unknown instruction mnemonic", EmptyRanges,
2876 bool X86AsmParser::OmitRegisterFromClobberLists(unsigned RegNo) {
2877 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo);
2880 bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
2881 MCAsmParser &Parser = getParser();
2882 StringRef IDVal = DirectiveID.getIdentifier();
2883 if (IDVal == ".word")
2884 return ParseDirectiveWord(2, DirectiveID.getLoc());
2885 else if (IDVal.startswith(".code"))
2886 return ParseDirectiveCode(IDVal, DirectiveID.getLoc());
2887 else if (IDVal.startswith(".att_syntax")) {
2888 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2889 if (Parser.getTok().getString() == "prefix")
2891 else if (Parser.getTok().getString() == "noprefix")
2892 return Error(DirectiveID.getLoc(), "'.att_syntax noprefix' is not "
2893 "supported: registers must have a "
2894 "'%' prefix in .att_syntax");
2896 getParser().setAssemblerDialect(0);
2898 } else if (IDVal.startswith(".intel_syntax")) {
2899 getParser().setAssemblerDialect(1);
2900 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2901 if (Parser.getTok().getString() == "noprefix")
2903 else if (Parser.getTok().getString() == "prefix")
2904 return Error(DirectiveID.getLoc(), "'.intel_syntax prefix' is not "
2905 "supported: registers must not have "
2906 "a '%' prefix in .intel_syntax");
2913 /// ParseDirectiveWord
2914 /// ::= .word [ expression (, expression)* ]
2915 bool X86AsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
2916 MCAsmParser &Parser = getParser();
2917 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2919 const MCExpr *Value;
2920 if (getParser().parseExpression(Value))
2923 getParser().getStreamer().EmitValue(Value, Size);
2925 if (getLexer().is(AsmToken::EndOfStatement))
2928 // FIXME: Improve diagnostic.
2929 if (getLexer().isNot(AsmToken::Comma)) {
2930 Error(L, "unexpected token in directive");
2941 /// ParseDirectiveCode
2942 /// ::= .code16 | .code32 | .code64
2943 bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
2944 MCAsmParser &Parser = getParser();
2945 if (IDVal == ".code16") {
2947 if (!is16BitMode()) {
2948 SwitchMode(X86::Mode16Bit);
2949 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
2951 } else if (IDVal == ".code32") {
2953 if (!is32BitMode()) {
2954 SwitchMode(X86::Mode32Bit);
2955 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
2957 } else if (IDVal == ".code64") {
2959 if (!is64BitMode()) {
2960 SwitchMode(X86::Mode64Bit);
2961 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code64);
2964 Error(L, "unknown directive " + IDVal);
2971 // Force static initialization.
2972 extern "C" void LLVMInitializeX86AsmParser() {
2973 RegisterMCAsmParser<X86AsmParser> X(TheX86_32Target);
2974 RegisterMCAsmParser<X86AsmParser> Y(TheX86_64Target);
2977 #define GET_REGISTER_MATCHER
2978 #define GET_MATCHER_IMPLEMENTATION
2979 #define GET_SUBTARGET_FEATURE_NAME
2980 #include "X86GenAsmMatcher.inc"