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)
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();
1387 assert(End.getPointer() <= EndPtr && "frontend claimed part of a token?");
1388 if (End.getPointer() == EndPtr) break;
1390 Identifier = LineBuf;
1392 // If the identifier lookup was unsuccessful, assume that we are dealing with
1395 StringRef InternalName =
1396 SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(),
1398 assert(InternalName.size() && "We should have an internal name here.");
1399 // Push a rewrite for replacing the identifier name with the internal name.
1400 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Label, Loc,
1405 // Create the symbol reference.
1406 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
1407 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1408 Val = MCSymbolRefExpr::create(Sym, Variant, getParser().getContext());
1412 /// \brief Parse intel style segment override.
1413 std::unique_ptr<X86Operand>
1414 X86AsmParser::ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start,
1416 MCAsmParser &Parser = getParser();
1417 assert(SegReg != 0 && "Tried to parse a segment override without a segment!");
1418 const AsmToken &Tok = Parser.getTok(); // Eat colon.
1419 if (Tok.isNot(AsmToken::Colon))
1420 return ErrorOperand(Tok.getLoc(), "Expected ':' token!");
1421 Parser.Lex(); // Eat ':'
1423 int64_t ImmDisp = 0;
1424 if (getLexer().is(AsmToken::Integer)) {
1425 ImmDisp = Tok.getIntVal();
1426 AsmToken ImmDispToken = Parser.Lex(); // Eat the integer.
1428 if (isParsingInlineAsm())
1429 InstInfo->AsmRewrites->push_back(
1430 AsmRewrite(AOK_ImmPrefix, ImmDispToken.getLoc()));
1432 if (getLexer().isNot(AsmToken::LBrac)) {
1433 // An immediate following a 'segment register', 'colon' token sequence can
1434 // be followed by a bracketed expression. If it isn't we know we have our
1435 // final segment override.
1436 const MCExpr *Disp = MCConstantExpr::create(ImmDisp, getContext());
1437 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp,
1438 /*BaseReg=*/0, /*IndexReg=*/0, /*Scale=*/1,
1439 Start, ImmDispToken.getEndLoc(), Size);
1443 if (getLexer().is(AsmToken::LBrac))
1444 return ParseIntelBracExpression(SegReg, Start, ImmDisp, Size);
1448 if (!isParsingInlineAsm()) {
1449 if (getParser().parsePrimaryExpr(Val, End))
1450 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1452 return X86Operand::CreateMem(getPointerWidth(), Val, Start, End, Size);
1455 InlineAsmIdentifierInfo Info;
1456 StringRef Identifier = Tok.getString();
1457 if (ParseIntelIdentifier(Val, Identifier, Info,
1458 /*Unevaluated=*/false, End))
1460 return CreateMemForInlineAsm(/*SegReg=*/0, Val, /*BaseReg=*/0,/*IndexReg=*/0,
1461 /*Scale=*/1, Start, End, Size, Identifier, Info);
1464 //ParseRoundingModeOp - Parse AVX-512 rounding mode operand
1465 std::unique_ptr<X86Operand>
1466 X86AsmParser::ParseRoundingModeOp(SMLoc Start, SMLoc End) {
1467 MCAsmParser &Parser = getParser();
1468 const AsmToken &Tok = Parser.getTok();
1469 // Eat "{" and mark the current place.
1470 const SMLoc consumedToken = consumeToken();
1471 if (Tok.getIdentifier().startswith("r")){
1472 int rndMode = StringSwitch<int>(Tok.getIdentifier())
1473 .Case("rn", X86::STATIC_ROUNDING::TO_NEAREST_INT)
1474 .Case("rd", X86::STATIC_ROUNDING::TO_NEG_INF)
1475 .Case("ru", X86::STATIC_ROUNDING::TO_POS_INF)
1476 .Case("rz", X86::STATIC_ROUNDING::TO_ZERO)
1479 return ErrorOperand(Tok.getLoc(), "Invalid rounding mode.");
1480 Parser.Lex(); // Eat "r*" of r*-sae
1481 if (!getLexer().is(AsmToken::Minus))
1482 return ErrorOperand(Tok.getLoc(), "Expected - at this point");
1483 Parser.Lex(); // Eat "-"
1484 Parser.Lex(); // Eat the sae
1485 if (!getLexer().is(AsmToken::RCurly))
1486 return ErrorOperand(Tok.getLoc(), "Expected } at this point");
1487 Parser.Lex(); // Eat "}"
1488 const MCExpr *RndModeOp =
1489 MCConstantExpr::create(rndMode, Parser.getContext());
1490 return X86Operand::CreateImm(RndModeOp, Start, End);
1492 if(Tok.getIdentifier().equals("sae")){
1493 Parser.Lex(); // Eat the sae
1494 if (!getLexer().is(AsmToken::RCurly))
1495 return ErrorOperand(Tok.getLoc(), "Expected } at this point");
1496 Parser.Lex(); // Eat "}"
1497 return X86Operand::CreateToken("{sae}", consumedToken);
1499 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1501 /// ParseIntelMemOperand - Parse intel style memory operand.
1502 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelMemOperand(int64_t ImmDisp,
1505 MCAsmParser &Parser = getParser();
1506 const AsmToken &Tok = Parser.getTok();
1509 // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
1510 if (getLexer().is(AsmToken::LBrac))
1511 return ParseIntelBracExpression(/*SegReg=*/0, Start, ImmDisp, Size);
1512 assert(ImmDisp == 0);
1515 if (!isParsingInlineAsm()) {
1516 if (getParser().parsePrimaryExpr(Val, End))
1517 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1519 return X86Operand::CreateMem(getPointerWidth(), Val, Start, End, Size);
1522 InlineAsmIdentifierInfo Info;
1523 StringRef Identifier = Tok.getString();
1524 if (ParseIntelIdentifier(Val, Identifier, Info,
1525 /*Unevaluated=*/false, End))
1528 if (!getLexer().is(AsmToken::LBrac))
1529 return CreateMemForInlineAsm(/*SegReg=*/0, Val, /*BaseReg=*/0, /*IndexReg=*/0,
1530 /*Scale=*/1, Start, End, Size, Identifier, Info);
1532 Parser.Lex(); // Eat '['
1534 // Parse Identifier [ ImmDisp ]
1535 IntelExprStateMachine SM(/*ImmDisp=*/0, /*StopOnLBrac=*/true,
1536 /*AddImmPrefix=*/false);
1537 if (ParseIntelExpression(SM, End))
1541 Error(Start, "cannot use more than one symbol in memory operand");
1544 if (SM.getBaseReg()) {
1545 Error(Start, "cannot use base register with variable reference");
1548 if (SM.getIndexReg()) {
1549 Error(Start, "cannot use index register with variable reference");
1553 const MCExpr *Disp = MCConstantExpr::create(SM.getImm(), getContext());
1554 // BaseReg is non-zero to avoid assertions. In the context of inline asm,
1555 // we're pointing to a local variable in memory, so the base register is
1556 // really the frame or stack pointer.
1557 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
1558 /*BaseReg=*/1, /*IndexReg=*/0, /*Scale=*/1,
1559 Start, End, Size, Identifier, Info.OpDecl);
1562 /// Parse the '.' operator.
1563 bool X86AsmParser::ParseIntelDotOperator(const MCExpr *Disp,
1564 const MCExpr *&NewDisp) {
1565 MCAsmParser &Parser = getParser();
1566 const AsmToken &Tok = Parser.getTok();
1567 int64_t OrigDispVal, DotDispVal;
1569 // FIXME: Handle non-constant expressions.
1570 if (const MCConstantExpr *OrigDisp = dyn_cast<MCConstantExpr>(Disp))
1571 OrigDispVal = OrigDisp->getValue();
1573 return Error(Tok.getLoc(), "Non-constant offsets are not supported!");
1575 // Drop the optional '.'.
1576 StringRef DotDispStr = Tok.getString();
1577 if (DotDispStr.startswith("."))
1578 DotDispStr = DotDispStr.drop_front(1);
1580 // .Imm gets lexed as a real.
1581 if (Tok.is(AsmToken::Real)) {
1583 DotDispStr.getAsInteger(10, DotDisp);
1584 DotDispVal = DotDisp.getZExtValue();
1585 } else if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) {
1587 std::pair<StringRef, StringRef> BaseMember = DotDispStr.split('.');
1588 if (SemaCallback->LookupInlineAsmField(BaseMember.first, BaseMember.second,
1590 return Error(Tok.getLoc(), "Unable to lookup field reference!");
1591 DotDispVal = DotDisp;
1593 return Error(Tok.getLoc(), "Unexpected token type!");
1595 if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) {
1596 SMLoc Loc = SMLoc::getFromPointer(DotDispStr.data());
1597 unsigned Len = DotDispStr.size();
1598 unsigned Val = OrigDispVal + DotDispVal;
1599 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_DotOperator, Loc, Len,
1603 NewDisp = MCConstantExpr::create(OrigDispVal + DotDispVal, getContext());
1607 /// Parse the 'offset' operator. This operator is used to specify the
1608 /// location rather then the content of a variable.
1609 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOffsetOfOperator() {
1610 MCAsmParser &Parser = getParser();
1611 const AsmToken &Tok = Parser.getTok();
1612 SMLoc OffsetOfLoc = Tok.getLoc();
1613 Parser.Lex(); // Eat offset.
1616 InlineAsmIdentifierInfo Info;
1617 SMLoc Start = Tok.getLoc(), End;
1618 StringRef Identifier = Tok.getString();
1619 if (ParseIntelIdentifier(Val, Identifier, Info,
1620 /*Unevaluated=*/false, End))
1623 // Don't emit the offset operator.
1624 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Skip, OffsetOfLoc, 7));
1626 // The offset operator will have an 'r' constraint, thus we need to create
1627 // register operand to ensure proper matching. Just pick a GPR based on
1628 // the size of a pointer.
1630 is64BitMode() ? X86::RBX : (is32BitMode() ? X86::EBX : X86::BX);
1631 return X86Operand::CreateReg(RegNo, Start, End, /*GetAddress=*/true,
1632 OffsetOfLoc, Identifier, Info.OpDecl);
1635 enum IntelOperatorKind {
1641 /// Parse the 'LENGTH', 'TYPE' and 'SIZE' operators. The LENGTH operator
1642 /// returns the number of elements in an array. It returns the value 1 for
1643 /// non-array variables. The SIZE operator returns the size of a C or C++
1644 /// variable. A variable's size is the product of its LENGTH and TYPE. The
1645 /// TYPE operator returns the size of a C or C++ type or variable. If the
1646 /// variable is an array, TYPE returns the size of a single element.
1647 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperator(unsigned OpKind) {
1648 MCAsmParser &Parser = getParser();
1649 const AsmToken &Tok = Parser.getTok();
1650 SMLoc TypeLoc = Tok.getLoc();
1651 Parser.Lex(); // Eat operator.
1653 const MCExpr *Val = nullptr;
1654 InlineAsmIdentifierInfo Info;
1655 SMLoc Start = Tok.getLoc(), End;
1656 StringRef Identifier = Tok.getString();
1657 if (ParseIntelIdentifier(Val, Identifier, Info,
1658 /*Unevaluated=*/true, End))
1662 return ErrorOperand(Start, "unable to lookup expression");
1666 default: llvm_unreachable("Unexpected operand kind!");
1667 case IOK_LENGTH: CVal = Info.Length; break;
1668 case IOK_SIZE: CVal = Info.Size; break;
1669 case IOK_TYPE: CVal = Info.Type; break;
1672 // Rewrite the type operator and the C or C++ type or variable in terms of an
1673 // immediate. E.g. TYPE foo -> $$4
1674 unsigned Len = End.getPointer() - TypeLoc.getPointer();
1675 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Imm, TypeLoc, Len, CVal));
1677 const MCExpr *Imm = MCConstantExpr::create(CVal, getContext());
1678 return X86Operand::CreateImm(Imm, Start, End);
1681 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand() {
1682 MCAsmParser &Parser = getParser();
1683 const AsmToken &Tok = Parser.getTok();
1686 // Offset, length, type and size operators.
1687 if (isParsingInlineAsm()) {
1688 StringRef AsmTokStr = Tok.getString();
1689 if (AsmTokStr == "offset" || AsmTokStr == "OFFSET")
1690 return ParseIntelOffsetOfOperator();
1691 if (AsmTokStr == "length" || AsmTokStr == "LENGTH")
1692 return ParseIntelOperator(IOK_LENGTH);
1693 if (AsmTokStr == "size" || AsmTokStr == "SIZE")
1694 return ParseIntelOperator(IOK_SIZE);
1695 if (AsmTokStr == "type" || AsmTokStr == "TYPE")
1696 return ParseIntelOperator(IOK_TYPE);
1699 unsigned Size = getIntelMemOperandSize(Tok.getString());
1701 Parser.Lex(); // Eat operand size (e.g., byte, word).
1702 if (Tok.getString() != "PTR" && Tok.getString() != "ptr")
1703 return ErrorOperand(Tok.getLoc(), "Expected 'PTR' or 'ptr' token!");
1704 Parser.Lex(); // Eat ptr.
1706 Start = Tok.getLoc();
1709 if (getLexer().is(AsmToken::Integer) || getLexer().is(AsmToken::Minus) ||
1710 getLexer().is(AsmToken::Tilde) || getLexer().is(AsmToken::LParen)) {
1711 AsmToken StartTok = Tok;
1712 IntelExprStateMachine SM(/*Imm=*/0, /*StopOnLBrac=*/true,
1713 /*AddImmPrefix=*/false);
1714 if (ParseIntelExpression(SM, End))
1717 int64_t Imm = SM.getImm();
1718 if (isParsingInlineAsm()) {
1719 unsigned Len = Tok.getLoc().getPointer() - Start.getPointer();
1720 if (StartTok.getString().size() == Len)
1721 // Just add a prefix if this wasn't a complex immediate expression.
1722 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_ImmPrefix, Start));
1724 // Otherwise, rewrite the complex expression as a single immediate.
1725 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Imm, Start, Len, Imm));
1728 if (getLexer().isNot(AsmToken::LBrac)) {
1729 // If a directional label (ie. 1f or 2b) was parsed above from
1730 // ParseIntelExpression() then SM.getSym() was set to a pointer to
1731 // to the MCExpr with the directional local symbol and this is a
1732 // memory operand not an immediate operand.
1734 return X86Operand::CreateMem(getPointerWidth(), SM.getSym(), Start, End,
1737 const MCExpr *ImmExpr = MCConstantExpr::create(Imm, getContext());
1738 return X86Operand::CreateImm(ImmExpr, Start, End);
1741 // Only positive immediates are valid.
1743 return ErrorOperand(Start, "expected a positive immediate displacement "
1744 "before bracketed expr.");
1746 // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
1747 return ParseIntelMemOperand(Imm, Start, Size);
1750 // rounding mode token
1751 if (STI.getFeatureBits()[X86::FeatureAVX512] &&
1752 getLexer().is(AsmToken::LCurly))
1753 return ParseRoundingModeOp(Start, End);
1757 if (!ParseRegister(RegNo, Start, End)) {
1758 // If this is a segment register followed by a ':', then this is the start
1759 // of a segment override, otherwise this is a normal register reference.
1760 if (getLexer().isNot(AsmToken::Colon))
1761 return X86Operand::CreateReg(RegNo, Start, End);
1763 return ParseIntelSegmentOverride(/*SegReg=*/RegNo, Start, Size);
1767 return ParseIntelMemOperand(/*Disp=*/0, Start, Size);
1770 std::unique_ptr<X86Operand> X86AsmParser::ParseATTOperand() {
1771 MCAsmParser &Parser = getParser();
1772 switch (getLexer().getKind()) {
1774 // Parse a memory operand with no segment register.
1775 return ParseMemOperand(0, Parser.getTok().getLoc());
1776 case AsmToken::Percent: {
1777 // Read the register.
1780 if (ParseRegister(RegNo, Start, End)) return nullptr;
1781 if (RegNo == X86::EIZ || RegNo == X86::RIZ) {
1782 Error(Start, "%eiz and %riz can only be used as index registers",
1783 SMRange(Start, End));
1787 // If this is a segment register followed by a ':', then this is the start
1788 // of a memory reference, otherwise this is a normal register reference.
1789 if (getLexer().isNot(AsmToken::Colon))
1790 return X86Operand::CreateReg(RegNo, Start, End);
1792 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo))
1793 return ErrorOperand(Start, "invalid segment register");
1795 getParser().Lex(); // Eat the colon.
1796 return ParseMemOperand(RegNo, Start);
1798 case AsmToken::Dollar: {
1799 // $42 -> immediate.
1800 SMLoc Start = Parser.getTok().getLoc(), End;
1803 if (getParser().parseExpression(Val, End))
1805 return X86Operand::CreateImm(Val, Start, End);
1807 case AsmToken::LCurly:{
1808 SMLoc Start = Parser.getTok().getLoc(), End;
1809 if (STI.getFeatureBits()[X86::FeatureAVX512])
1810 return ParseRoundingModeOp(Start, End);
1811 return ErrorOperand(Start, "unknown token in expression");
1816 bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands,
1817 const MCParsedAsmOperand &Op) {
1818 MCAsmParser &Parser = getParser();
1819 if(STI.getFeatureBits()[X86::FeatureAVX512]) {
1820 if (getLexer().is(AsmToken::LCurly)) {
1821 // Eat "{" and mark the current place.
1822 const SMLoc consumedToken = consumeToken();
1823 // Distinguish {1to<NUM>} from {%k<NUM>}.
1824 if(getLexer().is(AsmToken::Integer)) {
1825 // Parse memory broadcasting ({1to<NUM>}).
1826 if (getLexer().getTok().getIntVal() != 1)
1827 return !ErrorAndEatStatement(getLexer().getLoc(),
1828 "Expected 1to<NUM> at this point");
1829 Parser.Lex(); // Eat "1" of 1to8
1830 if (!getLexer().is(AsmToken::Identifier) ||
1831 !getLexer().getTok().getIdentifier().startswith("to"))
1832 return !ErrorAndEatStatement(getLexer().getLoc(),
1833 "Expected 1to<NUM> at this point");
1834 // Recognize only reasonable suffixes.
1835 const char *BroadcastPrimitive =
1836 StringSwitch<const char*>(getLexer().getTok().getIdentifier())
1837 .Case("to2", "{1to2}")
1838 .Case("to4", "{1to4}")
1839 .Case("to8", "{1to8}")
1840 .Case("to16", "{1to16}")
1842 if (!BroadcastPrimitive)
1843 return !ErrorAndEatStatement(getLexer().getLoc(),
1844 "Invalid memory broadcast primitive.");
1845 Parser.Lex(); // Eat "toN" of 1toN
1846 if (!getLexer().is(AsmToken::RCurly))
1847 return !ErrorAndEatStatement(getLexer().getLoc(),
1848 "Expected } at this point");
1849 Parser.Lex(); // Eat "}"
1850 Operands.push_back(X86Operand::CreateToken(BroadcastPrimitive,
1852 // No AVX512 specific primitives can pass
1853 // after memory broadcasting, so return.
1856 // Parse mask register {%k1}
1857 Operands.push_back(X86Operand::CreateToken("{", consumedToken));
1858 if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
1859 Operands.push_back(std::move(Op));
1860 if (!getLexer().is(AsmToken::RCurly))
1861 return !ErrorAndEatStatement(getLexer().getLoc(),
1862 "Expected } at this point");
1863 Operands.push_back(X86Operand::CreateToken("}", consumeToken()));
1865 // Parse "zeroing non-masked" semantic {z}
1866 if (getLexer().is(AsmToken::LCurly)) {
1867 Operands.push_back(X86Operand::CreateToken("{z}", consumeToken()));
1868 if (!getLexer().is(AsmToken::Identifier) ||
1869 getLexer().getTok().getIdentifier() != "z")
1870 return !ErrorAndEatStatement(getLexer().getLoc(),
1871 "Expected z at this point");
1872 Parser.Lex(); // Eat the z
1873 if (!getLexer().is(AsmToken::RCurly))
1874 return !ErrorAndEatStatement(getLexer().getLoc(),
1875 "Expected } at this point");
1876 Parser.Lex(); // Eat the }
1885 /// ParseMemOperand: segment: disp(basereg, indexreg, scale). The '%ds:' prefix
1886 /// has already been parsed if present.
1887 std::unique_ptr<X86Operand> X86AsmParser::ParseMemOperand(unsigned SegReg,
1890 MCAsmParser &Parser = getParser();
1891 // We have to disambiguate a parenthesized expression "(4+5)" from the start
1892 // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)". The
1893 // only way to do this without lookahead is to eat the '(' and see what is
1895 const MCExpr *Disp = MCConstantExpr::create(0, getParser().getContext());
1896 if (getLexer().isNot(AsmToken::LParen)) {
1898 if (getParser().parseExpression(Disp, ExprEnd)) return nullptr;
1900 // After parsing the base expression we could either have a parenthesized
1901 // memory address or not. If not, return now. If so, eat the (.
1902 if (getLexer().isNot(AsmToken::LParen)) {
1903 // Unless we have a segment register, treat this as an immediate.
1905 return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, ExprEnd);
1906 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
1913 // Okay, we have a '('. We don't know if this is an expression or not, but
1914 // so we have to eat the ( to see beyond it.
1915 SMLoc LParenLoc = Parser.getTok().getLoc();
1916 Parser.Lex(); // Eat the '('.
1918 if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) {
1919 // Nothing to do here, fall into the code below with the '(' part of the
1920 // memory operand consumed.
1924 // It must be an parenthesized expression, parse it now.
1925 if (getParser().parseParenExpression(Disp, ExprEnd))
1928 // After parsing the base expression we could either have a parenthesized
1929 // memory address or not. If not, return now. If so, eat the (.
1930 if (getLexer().isNot(AsmToken::LParen)) {
1931 // Unless we have a segment register, treat this as an immediate.
1933 return X86Operand::CreateMem(getPointerWidth(), Disp, LParenLoc,
1935 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
1944 // If we reached here, then we just ate the ( of the memory operand. Process
1945 // the rest of the memory operand.
1946 unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
1947 SMLoc IndexLoc, BaseLoc;
1949 if (getLexer().is(AsmToken::Percent)) {
1950 SMLoc StartLoc, EndLoc;
1951 BaseLoc = Parser.getTok().getLoc();
1952 if (ParseRegister(BaseReg, StartLoc, EndLoc)) return nullptr;
1953 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) {
1954 Error(StartLoc, "eiz and riz can only be used as index registers",
1955 SMRange(StartLoc, EndLoc));
1960 if (getLexer().is(AsmToken::Comma)) {
1961 Parser.Lex(); // Eat the comma.
1962 IndexLoc = Parser.getTok().getLoc();
1964 // Following the comma we should have either an index register, or a scale
1965 // value. We don't support the later form, but we want to parse it
1968 // Not that even though it would be completely consistent to support syntax
1969 // like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this.
1970 if (getLexer().is(AsmToken::Percent)) {
1972 if (ParseRegister(IndexReg, L, L)) return nullptr;
1974 if (getLexer().isNot(AsmToken::RParen)) {
1975 // Parse the scale amount:
1976 // ::= ',' [scale-expression]
1977 if (getLexer().isNot(AsmToken::Comma)) {
1978 Error(Parser.getTok().getLoc(),
1979 "expected comma in scale expression");
1982 Parser.Lex(); // Eat the comma.
1984 if (getLexer().isNot(AsmToken::RParen)) {
1985 SMLoc Loc = Parser.getTok().getLoc();
1988 if (getParser().parseAbsoluteExpression(ScaleVal)){
1989 Error(Loc, "expected scale expression");
1993 // Validate the scale amount.
1994 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
1996 Error(Loc, "scale factor in 16-bit address must be 1");
1999 if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8){
2000 Error(Loc, "scale factor in address must be 1, 2, 4 or 8");
2003 Scale = (unsigned)ScaleVal;
2006 } else if (getLexer().isNot(AsmToken::RParen)) {
2007 // A scale amount without an index is ignored.
2009 SMLoc Loc = Parser.getTok().getLoc();
2012 if (getParser().parseAbsoluteExpression(Value))
2016 Warning(Loc, "scale factor without index register is ignored");
2021 // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
2022 if (getLexer().isNot(AsmToken::RParen)) {
2023 Error(Parser.getTok().getLoc(), "unexpected token in memory operand");
2026 SMLoc MemEnd = Parser.getTok().getEndLoc();
2027 Parser.Lex(); // Eat the ')'.
2029 // Check for use of invalid 16-bit registers. Only BX/BP/SI/DI are allowed,
2030 // and then only in non-64-bit modes. Except for DX, which is a special case
2031 // because an unofficial form of in/out instructions uses it.
2032 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
2033 (is64BitMode() || (BaseReg != X86::BX && BaseReg != X86::BP &&
2034 BaseReg != X86::SI && BaseReg != X86::DI)) &&
2035 BaseReg != X86::DX) {
2036 Error(BaseLoc, "invalid 16-bit base register");
2040 X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg)) {
2041 Error(IndexLoc, "16-bit memory operand may not include only index register");
2046 if (CheckBaseRegAndIndexReg(BaseReg, IndexReg, ErrMsg)) {
2047 Error(BaseLoc, ErrMsg);
2051 if (SegReg || BaseReg || IndexReg)
2052 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
2053 IndexReg, Scale, MemStart, MemEnd);
2054 return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, MemEnd);
2057 bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2058 SMLoc NameLoc, OperandVector &Operands) {
2059 MCAsmParser &Parser = getParser();
2061 StringRef PatchedName = Name;
2063 // FIXME: Hack to recognize setneb as setne.
2064 if (PatchedName.startswith("set") && PatchedName.endswith("b") &&
2065 PatchedName != "setb" && PatchedName != "setnb")
2066 PatchedName = PatchedName.substr(0, Name.size()-1);
2068 // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}.
2069 if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) &&
2070 (PatchedName.endswith("ss") || PatchedName.endswith("sd") ||
2071 PatchedName.endswith("ps") || PatchedName.endswith("pd"))) {
2072 bool IsVCMP = PatchedName[0] == 'v';
2073 unsigned CCIdx = IsVCMP ? 4 : 3;
2074 unsigned ComparisonCode = StringSwitch<unsigned>(
2075 PatchedName.slice(CCIdx, PatchedName.size() - 2))
2079 .Case("unord", 0x03)
2084 /* AVX only from here */
2085 .Case("eq_uq", 0x08)
2088 .Case("false", 0x0B)
2089 .Case("neq_oq", 0x0C)
2093 .Case("eq_os", 0x10)
2094 .Case("lt_oq", 0x11)
2095 .Case("le_oq", 0x12)
2096 .Case("unord_s", 0x13)
2097 .Case("neq_us", 0x14)
2098 .Case("nlt_uq", 0x15)
2099 .Case("nle_uq", 0x16)
2100 .Case("ord_s", 0x17)
2101 .Case("eq_us", 0x18)
2102 .Case("nge_uq", 0x19)
2103 .Case("ngt_uq", 0x1A)
2104 .Case("false_os", 0x1B)
2105 .Case("neq_os", 0x1C)
2106 .Case("ge_oq", 0x1D)
2107 .Case("gt_oq", 0x1E)
2108 .Case("true_us", 0x1F)
2110 if (ComparisonCode != ~0U && (IsVCMP || ComparisonCode < 8)) {
2112 Operands.push_back(X86Operand::CreateToken(PatchedName.slice(0, CCIdx),
2115 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2116 getParser().getContext());
2117 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2119 PatchedName = PatchedName.substr(PatchedName.size() - 2);
2123 // FIXME: Hack to recognize vpcmp<comparison code>{ub,uw,ud,uq,b,w,d,q}.
2124 if (PatchedName.startswith("vpcmp") &&
2125 (PatchedName.endswith("b") || PatchedName.endswith("w") ||
2126 PatchedName.endswith("d") || PatchedName.endswith("q"))) {
2127 unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1;
2128 unsigned ComparisonCode = StringSwitch<unsigned>(
2129 PatchedName.slice(5, PatchedName.size() - CCIdx))
2130 .Case("eq", 0x0) // Only allowed on unsigned. Checked below.
2133 //.Case("false", 0x3) // Not a documented alias.
2137 //.Case("true", 0x7) // Not a documented alias.
2139 if (ComparisonCode != ~0U && (ComparisonCode != 0 || CCIdx == 2)) {
2140 Operands.push_back(X86Operand::CreateToken("vpcmp", NameLoc));
2142 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2143 getParser().getContext());
2144 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2146 PatchedName = PatchedName.substr(PatchedName.size() - CCIdx);
2150 // FIXME: Hack to recognize vpcom<comparison code>{ub,uw,ud,uq,b,w,d,q}.
2151 if (PatchedName.startswith("vpcom") &&
2152 (PatchedName.endswith("b") || PatchedName.endswith("w") ||
2153 PatchedName.endswith("d") || PatchedName.endswith("q"))) {
2154 unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1;
2155 unsigned ComparisonCode = StringSwitch<unsigned>(
2156 PatchedName.slice(5, PatchedName.size() - CCIdx))
2166 if (ComparisonCode != ~0U) {
2167 Operands.push_back(X86Operand::CreateToken("vpcom", NameLoc));
2169 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2170 getParser().getContext());
2171 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2173 PatchedName = PatchedName.substr(PatchedName.size() - CCIdx);
2177 Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
2179 // Determine whether this is an instruction prefix.
2181 Name == "lock" || Name == "rep" ||
2182 Name == "repe" || Name == "repz" ||
2183 Name == "repne" || Name == "repnz" ||
2184 Name == "rex64" || Name == "data16";
2187 // This does the actual operand parsing. Don't parse any more if we have a
2188 // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we
2189 // just want to parse the "lock" as the first instruction and the "incl" as
2191 if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) {
2193 // Parse '*' modifier.
2194 if (getLexer().is(AsmToken::Star))
2195 Operands.push_back(X86Operand::CreateToken("*", consumeToken()));
2197 // Read the operands.
2199 if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
2200 Operands.push_back(std::move(Op));
2201 if (!HandleAVX512Operand(Operands, *Operands.back()))
2204 Parser.eatToEndOfStatement();
2207 // check for comma and eat it
2208 if (getLexer().is(AsmToken::Comma))
2214 if (getLexer().isNot(AsmToken::EndOfStatement))
2215 return ErrorAndEatStatement(getLexer().getLoc(),
2216 "unexpected token in argument list");
2219 // Consume the EndOfStatement or the prefix separator Slash
2220 if (getLexer().is(AsmToken::EndOfStatement) ||
2221 (isPrefix && getLexer().is(AsmToken::Slash)))
2224 // This is a terrible hack to handle "out[bwl]? %al, (%dx)" ->
2225 // "outb %al, %dx". Out doesn't take a memory form, but this is a widely
2226 // documented form in various unofficial manuals, so a lot of code uses it.
2227 if ((Name == "outb" || Name == "outw" || Name == "outl" || Name == "out") &&
2228 Operands.size() == 3) {
2229 X86Operand &Op = (X86Operand &)*Operands.back();
2230 if (Op.isMem() && Op.Mem.SegReg == 0 &&
2231 isa<MCConstantExpr>(Op.Mem.Disp) &&
2232 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
2233 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
2234 SMLoc Loc = Op.getEndLoc();
2235 Operands.back() = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
2238 // Same hack for "in[bwl]? (%dx), %al" -> "inb %dx, %al".
2239 if ((Name == "inb" || Name == "inw" || Name == "inl" || Name == "in") &&
2240 Operands.size() == 3) {
2241 X86Operand &Op = (X86Operand &)*Operands[1];
2242 if (Op.isMem() && Op.Mem.SegReg == 0 &&
2243 isa<MCConstantExpr>(Op.Mem.Disp) &&
2244 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
2245 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
2246 SMLoc Loc = Op.getEndLoc();
2247 Operands[1] = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
2251 // Append default arguments to "ins[bwld]"
2252 if (Name.startswith("ins") && Operands.size() == 1 &&
2253 (Name == "insb" || Name == "insw" || Name == "insl" ||
2255 AddDefaultSrcDestOperands(Operands,
2256 X86Operand::CreateReg(X86::DX, NameLoc, NameLoc),
2257 DefaultMemDIOperand(NameLoc));
2260 // Append default arguments to "outs[bwld]"
2261 if (Name.startswith("outs") && Operands.size() == 1 &&
2262 (Name == "outsb" || Name == "outsw" || Name == "outsl" ||
2263 Name == "outsd" )) {
2264 AddDefaultSrcDestOperands(Operands,
2265 DefaultMemSIOperand(NameLoc),
2266 X86Operand::CreateReg(X86::DX, NameLoc, NameLoc));
2269 // Transform "lods[bwlq]" into "lods[bwlq] ($SIREG)" for appropriate
2270 // values of $SIREG according to the mode. It would be nice if this
2271 // could be achieved with InstAlias in the tables.
2272 if (Name.startswith("lods") && Operands.size() == 1 &&
2273 (Name == "lods" || Name == "lodsb" || Name == "lodsw" ||
2274 Name == "lodsl" || Name == "lodsd" || Name == "lodsq"))
2275 Operands.push_back(DefaultMemSIOperand(NameLoc));
2277 // Transform "stos[bwlq]" into "stos[bwlq] ($DIREG)" for appropriate
2278 // values of $DIREG according to the mode. It would be nice if this
2279 // could be achieved with InstAlias in the tables.
2280 if (Name.startswith("stos") && Operands.size() == 1 &&
2281 (Name == "stos" || Name == "stosb" || Name == "stosw" ||
2282 Name == "stosl" || Name == "stosd" || Name == "stosq"))
2283 Operands.push_back(DefaultMemDIOperand(NameLoc));
2285 // Transform "scas[bwlq]" into "scas[bwlq] ($DIREG)" for appropriate
2286 // values of $DIREG according to the mode. It would be nice if this
2287 // could be achieved with InstAlias in the tables.
2288 if (Name.startswith("scas") && Operands.size() == 1 &&
2289 (Name == "scas" || Name == "scasb" || Name == "scasw" ||
2290 Name == "scasl" || Name == "scasd" || Name == "scasq"))
2291 Operands.push_back(DefaultMemDIOperand(NameLoc));
2293 // Add default SI and DI operands to "cmps[bwlq]".
2294 if (Name.startswith("cmps") &&
2295 (Name == "cmps" || Name == "cmpsb" || Name == "cmpsw" ||
2296 Name == "cmpsl" || Name == "cmpsd" || Name == "cmpsq")) {
2297 if (Operands.size() == 1) {
2298 AddDefaultSrcDestOperands(Operands,
2299 DefaultMemDIOperand(NameLoc),
2300 DefaultMemSIOperand(NameLoc));
2301 } else if (Operands.size() == 3) {
2302 X86Operand &Op = (X86Operand &)*Operands[1];
2303 X86Operand &Op2 = (X86Operand &)*Operands[2];
2304 if (!doSrcDstMatch(Op, Op2))
2305 return Error(Op.getStartLoc(),
2306 "mismatching source and destination index registers");
2310 // Add default SI and DI operands to "movs[bwlq]".
2311 if ((Name.startswith("movs") &&
2312 (Name == "movs" || Name == "movsb" || Name == "movsw" ||
2313 Name == "movsl" || Name == "movsd" || Name == "movsq")) ||
2314 (Name.startswith("smov") &&
2315 (Name == "smov" || Name == "smovb" || Name == "smovw" ||
2316 Name == "smovl" || Name == "smovd" || Name == "smovq"))) {
2317 if (Operands.size() == 1) {
2318 if (Name == "movsd")
2319 Operands.back() = X86Operand::CreateToken("movsl", NameLoc);
2320 AddDefaultSrcDestOperands(Operands,
2321 DefaultMemSIOperand(NameLoc),
2322 DefaultMemDIOperand(NameLoc));
2323 } else if (Operands.size() == 3) {
2324 X86Operand &Op = (X86Operand &)*Operands[1];
2325 X86Operand &Op2 = (X86Operand &)*Operands[2];
2326 if (!doSrcDstMatch(Op, Op2))
2327 return Error(Op.getStartLoc(),
2328 "mismatching source and destination index registers");
2332 // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>. Canonicalize to
2334 if ((Name.startswith("shr") || Name.startswith("sar") ||
2335 Name.startswith("shl") || Name.startswith("sal") ||
2336 Name.startswith("rcl") || Name.startswith("rcr") ||
2337 Name.startswith("rol") || Name.startswith("ror")) &&
2338 Operands.size() == 3) {
2339 if (isParsingIntelSyntax()) {
2341 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[2]);
2342 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2343 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2344 Operands.pop_back();
2346 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2347 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2348 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2349 Operands.erase(Operands.begin() + 1);
2353 // Transforms "int $3" into "int3" as a size optimization. We can't write an
2354 // instalias with an immediate operand yet.
2355 if (Name == "int" && Operands.size() == 2) {
2356 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2358 if (auto *CE = dyn_cast<MCConstantExpr>(Op1.getImm()))
2359 if (CE->getValue() == 3) {
2360 Operands.erase(Operands.begin() + 1);
2361 static_cast<X86Operand &>(*Operands[0]).setTokenValue("int3");
2368 static bool convertToSExti8(MCInst &Inst, unsigned Opcode, unsigned Reg,
2371 TmpInst.setOpcode(Opcode);
2373 TmpInst.addOperand(MCOperand::createReg(Reg));
2374 TmpInst.addOperand(MCOperand::createReg(Reg));
2375 TmpInst.addOperand(Inst.getOperand(0));
2380 static bool convert16i16to16ri8(MCInst &Inst, unsigned Opcode,
2381 bool isCmp = false) {
2382 if (!Inst.getOperand(0).isImm() ||
2383 !isImmSExti16i8Value(Inst.getOperand(0).getImm()))
2386 return convertToSExti8(Inst, Opcode, X86::AX, isCmp);
2389 static bool convert32i32to32ri8(MCInst &Inst, unsigned Opcode,
2390 bool isCmp = false) {
2391 if (!Inst.getOperand(0).isImm() ||
2392 !isImmSExti32i8Value(Inst.getOperand(0).getImm()))
2395 return convertToSExti8(Inst, Opcode, X86::EAX, isCmp);
2398 static bool convert64i32to64ri8(MCInst &Inst, unsigned Opcode,
2399 bool isCmp = false) {
2400 if (!Inst.getOperand(0).isImm() ||
2401 !isImmSExti64i8Value(Inst.getOperand(0).getImm()))
2404 return convertToSExti8(Inst, Opcode, X86::RAX, isCmp);
2407 bool X86AsmParser::validateInstruction(MCInst &Inst, const OperandVector &Ops) {
2408 switch (Inst.getOpcode()) {
2409 default: return true;
2411 X86Operand &Op = static_cast<X86Operand &>(*Ops[1]);
2412 assert(Op.isImm() && "expected immediate");
2414 if (!Op.getImm()->evaluateAsAbsolute(Res) || Res > 255) {
2415 Error(Op.getStartLoc(), "interrupt vector must be in range [0-255]");
2420 llvm_unreachable("handle the instruction appropriately");
2423 bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) {
2424 switch (Inst.getOpcode()) {
2425 default: return false;
2426 case X86::AND16i16: return convert16i16to16ri8(Inst, X86::AND16ri8);
2427 case X86::AND32i32: return convert32i32to32ri8(Inst, X86::AND32ri8);
2428 case X86::AND64i32: return convert64i32to64ri8(Inst, X86::AND64ri8);
2429 case X86::XOR16i16: return convert16i16to16ri8(Inst, X86::XOR16ri8);
2430 case X86::XOR32i32: return convert32i32to32ri8(Inst, X86::XOR32ri8);
2431 case X86::XOR64i32: return convert64i32to64ri8(Inst, X86::XOR64ri8);
2432 case X86::OR16i16: return convert16i16to16ri8(Inst, X86::OR16ri8);
2433 case X86::OR32i32: return convert32i32to32ri8(Inst, X86::OR32ri8);
2434 case X86::OR64i32: return convert64i32to64ri8(Inst, X86::OR64ri8);
2435 case X86::CMP16i16: return convert16i16to16ri8(Inst, X86::CMP16ri8, true);
2436 case X86::CMP32i32: return convert32i32to32ri8(Inst, X86::CMP32ri8, true);
2437 case X86::CMP64i32: return convert64i32to64ri8(Inst, X86::CMP64ri8, true);
2438 case X86::ADD16i16: return convert16i16to16ri8(Inst, X86::ADD16ri8);
2439 case X86::ADD32i32: return convert32i32to32ri8(Inst, X86::ADD32ri8);
2440 case X86::ADD64i32: return convert64i32to64ri8(Inst, X86::ADD64ri8);
2441 case X86::SUB16i16: return convert16i16to16ri8(Inst, X86::SUB16ri8);
2442 case X86::SUB32i32: return convert32i32to32ri8(Inst, X86::SUB32ri8);
2443 case X86::SUB64i32: return convert64i32to64ri8(Inst, X86::SUB64ri8);
2444 case X86::ADC16i16: return convert16i16to16ri8(Inst, X86::ADC16ri8);
2445 case X86::ADC32i32: return convert32i32to32ri8(Inst, X86::ADC32ri8);
2446 case X86::ADC64i32: return convert64i32to64ri8(Inst, X86::ADC64ri8);
2447 case X86::SBB16i16: return convert16i16to16ri8(Inst, X86::SBB16ri8);
2448 case X86::SBB32i32: return convert32i32to32ri8(Inst, X86::SBB32ri8);
2449 case X86::SBB64i32: return convert64i32to64ri8(Inst, X86::SBB64ri8);
2450 case X86::VMOVAPDrr:
2451 case X86::VMOVAPDYrr:
2452 case X86::VMOVAPSrr:
2453 case X86::VMOVAPSYrr:
2454 case X86::VMOVDQArr:
2455 case X86::VMOVDQAYrr:
2456 case X86::VMOVDQUrr:
2457 case X86::VMOVDQUYrr:
2458 case X86::VMOVUPDrr:
2459 case X86::VMOVUPDYrr:
2460 case X86::VMOVUPSrr:
2461 case X86::VMOVUPSYrr: {
2462 if (X86II::isX86_64ExtendedReg(Inst.getOperand(0).getReg()) ||
2463 !X86II::isX86_64ExtendedReg(Inst.getOperand(1).getReg()))
2467 switch (Inst.getOpcode()) {
2468 default: llvm_unreachable("Invalid opcode");
2469 case X86::VMOVAPDrr: NewOpc = X86::VMOVAPDrr_REV; break;
2470 case X86::VMOVAPDYrr: NewOpc = X86::VMOVAPDYrr_REV; break;
2471 case X86::VMOVAPSrr: NewOpc = X86::VMOVAPSrr_REV; break;
2472 case X86::VMOVAPSYrr: NewOpc = X86::VMOVAPSYrr_REV; break;
2473 case X86::VMOVDQArr: NewOpc = X86::VMOVDQArr_REV; break;
2474 case X86::VMOVDQAYrr: NewOpc = X86::VMOVDQAYrr_REV; break;
2475 case X86::VMOVDQUrr: NewOpc = X86::VMOVDQUrr_REV; break;
2476 case X86::VMOVDQUYrr: NewOpc = X86::VMOVDQUYrr_REV; break;
2477 case X86::VMOVUPDrr: NewOpc = X86::VMOVUPDrr_REV; break;
2478 case X86::VMOVUPDYrr: NewOpc = X86::VMOVUPDYrr_REV; break;
2479 case X86::VMOVUPSrr: NewOpc = X86::VMOVUPSrr_REV; break;
2480 case X86::VMOVUPSYrr: NewOpc = X86::VMOVUPSYrr_REV; break;
2482 Inst.setOpcode(NewOpc);
2486 case X86::VMOVSSrr: {
2487 if (X86II::isX86_64ExtendedReg(Inst.getOperand(0).getReg()) ||
2488 !X86II::isX86_64ExtendedReg(Inst.getOperand(2).getReg()))
2491 switch (Inst.getOpcode()) {
2492 default: llvm_unreachable("Invalid opcode");
2493 case X86::VMOVSDrr: NewOpc = X86::VMOVSDrr_REV; break;
2494 case X86::VMOVSSrr: NewOpc = X86::VMOVSSrr_REV; break;
2496 Inst.setOpcode(NewOpc);
2502 static const char *getSubtargetFeatureName(uint64_t Val);
2504 void X86AsmParser::EmitInstruction(MCInst &Inst, OperandVector &Operands,
2506 Instrumentation->InstrumentAndEmitInstruction(Inst, Operands, getContext(),
2510 bool X86AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2511 OperandVector &Operands,
2512 MCStreamer &Out, uint64_t &ErrorInfo,
2513 bool MatchingInlineAsm) {
2514 if (isParsingIntelSyntax())
2515 return MatchAndEmitIntelInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2517 return MatchAndEmitATTInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2521 void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op,
2522 OperandVector &Operands, MCStreamer &Out,
2523 bool MatchingInlineAsm) {
2524 // FIXME: This should be replaced with a real .td file alias mechanism.
2525 // Also, MatchInstructionImpl should actually *do* the EmitInstruction
2527 const char *Repl = StringSwitch<const char *>(Op.getToken())
2528 .Case("finit", "fninit")
2529 .Case("fsave", "fnsave")
2530 .Case("fstcw", "fnstcw")
2531 .Case("fstcww", "fnstcw")
2532 .Case("fstenv", "fnstenv")
2533 .Case("fstsw", "fnstsw")
2534 .Case("fstsww", "fnstsw")
2535 .Case("fclex", "fnclex")
2539 Inst.setOpcode(X86::WAIT);
2541 if (!MatchingInlineAsm)
2542 EmitInstruction(Inst, Operands, Out);
2543 Operands[0] = X86Operand::CreateToken(Repl, IDLoc);
2547 bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
2548 bool MatchingInlineAsm) {
2549 assert(ErrorInfo && "Unknown missing feature!");
2550 ArrayRef<SMRange> EmptyRanges = None;
2551 SmallString<126> Msg;
2552 raw_svector_ostream OS(Msg);
2553 OS << "instruction requires:";
2555 for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
2556 if (ErrorInfo & Mask)
2557 OS << ' ' << getSubtargetFeatureName(ErrorInfo & Mask);
2560 return Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
2563 bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
2564 OperandVector &Operands,
2566 uint64_t &ErrorInfo,
2567 bool MatchingInlineAsm) {
2568 assert(!Operands.empty() && "Unexpect empty operand list!");
2569 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2570 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
2571 ArrayRef<SMRange> EmptyRanges = None;
2573 // First, handle aliases that expand to multiple instructions.
2574 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2576 bool WasOriginallyInvalidOperand = false;
2579 // First, try a direct match.
2580 switch (MatchInstructionImpl(Operands, Inst,
2581 ErrorInfo, MatchingInlineAsm,
2582 isParsingIntelSyntax())) {
2583 default: llvm_unreachable("Unexpected match result!");
2585 if (!validateInstruction(Inst, Operands))
2588 // Some instructions need post-processing to, for example, tweak which
2589 // encoding is selected. Loop on it while changes happen so the
2590 // individual transformations can chain off each other.
2591 if (!MatchingInlineAsm)
2592 while (processInstruction(Inst, Operands))
2596 if (!MatchingInlineAsm)
2597 EmitInstruction(Inst, Operands, Out);
2598 Opcode = Inst.getOpcode();
2600 case Match_MissingFeature:
2601 return ErrorMissingFeature(IDLoc, ErrorInfo, MatchingInlineAsm);
2602 case Match_InvalidOperand:
2603 WasOriginallyInvalidOperand = true;
2605 case Match_MnemonicFail:
2609 // FIXME: Ideally, we would only attempt suffix matches for things which are
2610 // valid prefixes, and we could just infer the right unambiguous
2611 // type. However, that requires substantially more matcher support than the
2614 // Change the operand to point to a temporary token.
2615 StringRef Base = Op.getToken();
2616 SmallString<16> Tmp;
2619 Op.setTokenValue(Tmp);
2621 // If this instruction starts with an 'f', then it is a floating point stack
2622 // instruction. These come in up to three forms for 32-bit, 64-bit, and
2623 // 80-bit floating point, which use the suffixes s,l,t respectively.
2625 // Otherwise, we assume that this may be an integer instruction, which comes
2626 // in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively.
2627 const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0";
2629 // Check for the various suffix matches.
2630 uint64_t ErrorInfoIgnore;
2631 uint64_t ErrorInfoMissingFeature = 0; // Init suppresses compiler warnings.
2634 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I) {
2635 Tmp.back() = Suffixes[I];
2636 Match[I] = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
2637 MatchingInlineAsm, isParsingIntelSyntax());
2638 // If this returned as a missing feature failure, remember that.
2639 if (Match[I] == Match_MissingFeature)
2640 ErrorInfoMissingFeature = ErrorInfoIgnore;
2643 // Restore the old token.
2644 Op.setTokenValue(Base);
2646 // If exactly one matched, then we treat that as a successful match (and the
2647 // instruction will already have been filled in correctly, since the failing
2648 // matches won't have modified it).
2649 unsigned NumSuccessfulMatches =
2650 std::count(std::begin(Match), std::end(Match), Match_Success);
2651 if (NumSuccessfulMatches == 1) {
2653 if (!MatchingInlineAsm)
2654 EmitInstruction(Inst, Operands, Out);
2655 Opcode = Inst.getOpcode();
2659 // Otherwise, the match failed, try to produce a decent error message.
2661 // If we had multiple suffix matches, then identify this as an ambiguous
2663 if (NumSuccessfulMatches > 1) {
2665 unsigned NumMatches = 0;
2666 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I)
2667 if (Match[I] == Match_Success)
2668 MatchChars[NumMatches++] = Suffixes[I];
2670 SmallString<126> Msg;
2671 raw_svector_ostream OS(Msg);
2672 OS << "ambiguous instructions require an explicit suffix (could be ";
2673 for (unsigned i = 0; i != NumMatches; ++i) {
2676 if (i + 1 == NumMatches)
2678 OS << "'" << Base << MatchChars[i] << "'";
2681 Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
2685 // Okay, we know that none of the variants matched successfully.
2687 // If all of the instructions reported an invalid mnemonic, then the original
2688 // mnemonic was invalid.
2689 if (std::count(std::begin(Match), std::end(Match), Match_MnemonicFail) == 4) {
2690 if (!WasOriginallyInvalidOperand) {
2691 ArrayRef<SMRange> Ranges =
2692 MatchingInlineAsm ? EmptyRanges : Op.getLocRange();
2693 return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'",
2694 Ranges, MatchingInlineAsm);
2697 // Recover location info for the operand if we know which was the problem.
2698 if (ErrorInfo != ~0ULL) {
2699 if (ErrorInfo >= Operands.size())
2700 return Error(IDLoc, "too few operands for instruction",
2701 EmptyRanges, MatchingInlineAsm);
2703 X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo];
2704 if (Operand.getStartLoc().isValid()) {
2705 SMRange OperandRange = Operand.getLocRange();
2706 return Error(Operand.getStartLoc(), "invalid operand for instruction",
2707 OperandRange, MatchingInlineAsm);
2711 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2715 // If one instruction matched with a missing feature, report this as a
2717 if (std::count(std::begin(Match), std::end(Match),
2718 Match_MissingFeature) == 1) {
2719 ErrorInfo = ErrorInfoMissingFeature;
2720 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
2724 // If one instruction matched with an invalid operand, report this as an
2726 if (std::count(std::begin(Match), std::end(Match),
2727 Match_InvalidOperand) == 1) {
2728 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2732 // If all of these were an outright failure, report it in a useless way.
2733 Error(IDLoc, "unknown use of instruction mnemonic without a size suffix",
2734 EmptyRanges, MatchingInlineAsm);
2738 bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
2739 OperandVector &Operands,
2741 uint64_t &ErrorInfo,
2742 bool MatchingInlineAsm) {
2743 assert(!Operands.empty() && "Unexpect empty operand list!");
2744 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2745 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
2746 StringRef Mnemonic = Op.getToken();
2747 ArrayRef<SMRange> EmptyRanges = None;
2749 // First, handle aliases that expand to multiple instructions.
2750 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2754 // Find one unsized memory operand, if present.
2755 X86Operand *UnsizedMemOp = nullptr;
2756 for (const auto &Op : Operands) {
2757 X86Operand *X86Op = static_cast<X86Operand *>(Op.get());
2758 if (X86Op->isMemUnsized())
2759 UnsizedMemOp = X86Op;
2762 // Allow some instructions to have implicitly pointer-sized operands. This is
2763 // compatible with gas.
2765 static const char *const PtrSizedInstrs[] = {"call", "jmp", "push"};
2766 for (const char *Instr : PtrSizedInstrs) {
2767 if (Mnemonic == Instr) {
2768 UnsizedMemOp->Mem.Size = getPointerWidth();
2774 // If an unsized memory operand is present, try to match with each memory
2775 // operand size. In Intel assembly, the size is not part of the instruction
2777 SmallVector<unsigned, 8> Match;
2778 uint64_t ErrorInfoMissingFeature = 0;
2779 if (UnsizedMemOp && UnsizedMemOp->isMemUnsized()) {
2780 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
2781 for (unsigned Size : MopSizes) {
2782 UnsizedMemOp->Mem.Size = Size;
2783 uint64_t ErrorInfoIgnore;
2784 unsigned LastOpcode = Inst.getOpcode();
2786 MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
2787 MatchingInlineAsm, isParsingIntelSyntax());
2788 if (Match.empty() || LastOpcode != Inst.getOpcode())
2791 // If this returned as a missing feature failure, remember that.
2792 if (Match.back() == Match_MissingFeature)
2793 ErrorInfoMissingFeature = ErrorInfoIgnore;
2796 // Restore the size of the unsized memory operand if we modified it.
2798 UnsizedMemOp->Mem.Size = 0;
2801 // If we haven't matched anything yet, this is not a basic integer or FPU
2802 // operation. There shouldn't be any ambiguity in our mnemonic table, so try
2803 // matching with the unsized operand.
2804 if (Match.empty()) {
2805 Match.push_back(MatchInstructionImpl(Operands, Inst, ErrorInfo,
2807 isParsingIntelSyntax()));
2808 // If this returned as a missing feature failure, remember that.
2809 if (Match.back() == Match_MissingFeature)
2810 ErrorInfoMissingFeature = ErrorInfo;
2813 // Restore the size of the unsized memory operand if we modified it.
2815 UnsizedMemOp->Mem.Size = 0;
2817 // If it's a bad mnemonic, all results will be the same.
2818 if (Match.back() == Match_MnemonicFail) {
2819 ArrayRef<SMRange> Ranges =
2820 MatchingInlineAsm ? EmptyRanges : Op.getLocRange();
2821 return Error(IDLoc, "invalid instruction mnemonic '" + Mnemonic + "'",
2822 Ranges, MatchingInlineAsm);
2825 // If exactly one matched, then we treat that as a successful match (and the
2826 // instruction will already have been filled in correctly, since the failing
2827 // matches won't have modified it).
2828 unsigned NumSuccessfulMatches =
2829 std::count(std::begin(Match), std::end(Match), Match_Success);
2830 if (NumSuccessfulMatches == 1) {
2831 if (!validateInstruction(Inst, Operands))
2834 // Some instructions need post-processing to, for example, tweak which
2835 // encoding is selected. Loop on it while changes happen so the individual
2836 // transformations can chain off each other.
2837 if (!MatchingInlineAsm)
2838 while (processInstruction(Inst, Operands))
2841 if (!MatchingInlineAsm)
2842 EmitInstruction(Inst, Operands, Out);
2843 Opcode = Inst.getOpcode();
2845 } else if (NumSuccessfulMatches > 1) {
2846 assert(UnsizedMemOp &&
2847 "multiple matches only possible with unsized memory operands");
2848 ArrayRef<SMRange> Ranges =
2849 MatchingInlineAsm ? EmptyRanges : UnsizedMemOp->getLocRange();
2850 return Error(UnsizedMemOp->getStartLoc(),
2851 "ambiguous operand size for instruction '" + Mnemonic + "\'",
2852 Ranges, MatchingInlineAsm);
2855 // If one instruction matched with a missing feature, report this as a
2857 if (std::count(std::begin(Match), std::end(Match),
2858 Match_MissingFeature) == 1) {
2859 ErrorInfo = ErrorInfoMissingFeature;
2860 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
2864 // If one instruction matched with an invalid operand, report this as an
2866 if (std::count(std::begin(Match), std::end(Match),
2867 Match_InvalidOperand) == 1) {
2868 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2872 // If all of these were an outright failure, report it in a useless way.
2873 return Error(IDLoc, "unknown instruction mnemonic", EmptyRanges,
2877 bool X86AsmParser::OmitRegisterFromClobberLists(unsigned RegNo) {
2878 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo);
2881 bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
2882 MCAsmParser &Parser = getParser();
2883 StringRef IDVal = DirectiveID.getIdentifier();
2884 if (IDVal == ".word")
2885 return ParseDirectiveWord(2, DirectiveID.getLoc());
2886 else if (IDVal.startswith(".code"))
2887 return ParseDirectiveCode(IDVal, DirectiveID.getLoc());
2888 else if (IDVal.startswith(".att_syntax")) {
2889 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2890 if (Parser.getTok().getString() == "prefix")
2892 else if (Parser.getTok().getString() == "noprefix")
2893 return Error(DirectiveID.getLoc(), "'.att_syntax noprefix' is not "
2894 "supported: registers must have a "
2895 "'%' prefix in .att_syntax");
2897 getParser().setAssemblerDialect(0);
2899 } else if (IDVal.startswith(".intel_syntax")) {
2900 getParser().setAssemblerDialect(1);
2901 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2902 if (Parser.getTok().getString() == "noprefix")
2904 else if (Parser.getTok().getString() == "prefix")
2905 return Error(DirectiveID.getLoc(), "'.intel_syntax prefix' is not "
2906 "supported: registers must not have "
2907 "a '%' prefix in .intel_syntax");
2914 /// ParseDirectiveWord
2915 /// ::= .word [ expression (, expression)* ]
2916 bool X86AsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
2917 MCAsmParser &Parser = getParser();
2918 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2920 const MCExpr *Value;
2921 if (getParser().parseExpression(Value))
2924 getParser().getStreamer().EmitValue(Value, Size);
2926 if (getLexer().is(AsmToken::EndOfStatement))
2929 // FIXME: Improve diagnostic.
2930 if (getLexer().isNot(AsmToken::Comma)) {
2931 Error(L, "unexpected token in directive");
2942 /// ParseDirectiveCode
2943 /// ::= .code16 | .code32 | .code64
2944 bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
2945 MCAsmParser &Parser = getParser();
2946 if (IDVal == ".code16") {
2948 if (!is16BitMode()) {
2949 SwitchMode(X86::Mode16Bit);
2950 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
2952 } else if (IDVal == ".code32") {
2954 if (!is32BitMode()) {
2955 SwitchMode(X86::Mode32Bit);
2956 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
2958 } else if (IDVal == ".code64") {
2960 if (!is64BitMode()) {
2961 SwitchMode(X86::Mode64Bit);
2962 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code64);
2965 Error(L, "unknown directive " + IDVal);
2972 // Force static initialization.
2973 extern "C" void LLVMInitializeX86AsmParser() {
2974 RegisterMCAsmParser<X86AsmParser> X(TheX86_32Target);
2975 RegisterMCAsmParser<X86AsmParser> Y(TheX86_64Target);
2978 #define GET_REGISTER_MATCHER
2979 #define GET_MATCHER_IMPLEMENTATION
2980 #define GET_SUBTARGET_FEATURE_NAME
2981 #include "X86GenAsmMatcher.inc"