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);
158 // Push any remaining operators onto the postfix stack.
159 while (!InfixOperatorStack.empty()) {
160 InfixCalculatorTok StackOp = InfixOperatorStack.pop_back_val();
161 if (StackOp != IC_LPAREN && StackOp != IC_RPAREN)
162 PostfixStack.push_back(std::make_pair(StackOp, 0));
165 if (PostfixStack.empty())
168 SmallVector<ICToken, 16> OperandStack;
169 for (unsigned i = 0, e = PostfixStack.size(); i != e; ++i) {
170 ICToken Op = PostfixStack[i];
171 if (Op.first == IC_IMM || Op.first == IC_REGISTER) {
172 OperandStack.push_back(Op);
174 assert (OperandStack.size() > 1 && "Too few operands.");
176 ICToken Op2 = OperandStack.pop_back_val();
177 ICToken Op1 = OperandStack.pop_back_val();
180 report_fatal_error("Unexpected operator!");
183 Val = Op1.second + Op2.second;
184 OperandStack.push_back(std::make_pair(IC_IMM, Val));
187 Val = Op1.second - Op2.second;
188 OperandStack.push_back(std::make_pair(IC_IMM, Val));
191 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
192 "Multiply operation with an immediate and a register!");
193 Val = Op1.second * Op2.second;
194 OperandStack.push_back(std::make_pair(IC_IMM, Val));
197 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
198 "Divide operation with an immediate and a register!");
199 assert (Op2.second != 0 && "Division by zero!");
200 Val = Op1.second / Op2.second;
201 OperandStack.push_back(std::make_pair(IC_IMM, Val));
204 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
205 "Or operation with an immediate and a register!");
206 Val = Op1.second | Op2.second;
207 OperandStack.push_back(std::make_pair(IC_IMM, Val));
210 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
211 "Xor operation with an immediate and a register!");
212 Val = Op1.second ^ Op2.second;
213 OperandStack.push_back(std::make_pair(IC_IMM, Val));
216 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
217 "And operation with an immediate and a register!");
218 Val = Op1.second & Op2.second;
219 OperandStack.push_back(std::make_pair(IC_IMM, Val));
222 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
223 "Left shift operation with an immediate and a register!");
224 Val = Op1.second << Op2.second;
225 OperandStack.push_back(std::make_pair(IC_IMM, Val));
228 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
229 "Right shift operation with an immediate and a register!");
230 Val = Op1.second >> Op2.second;
231 OperandStack.push_back(std::make_pair(IC_IMM, Val));
236 assert (OperandStack.size() == 1 && "Expected a single result.");
237 return OperandStack.pop_back_val().second;
241 enum IntelExprState {
262 class IntelExprStateMachine {
263 IntelExprState State, PrevState;
264 unsigned BaseReg, IndexReg, TmpReg, Scale;
268 bool StopOnLBrac, AddImmPrefix;
270 InlineAsmIdentifierInfo Info;
272 IntelExprStateMachine(int64_t imm, bool stoponlbrac, bool addimmprefix) :
273 State(IES_PLUS), PrevState(IES_ERROR), BaseReg(0), IndexReg(0), TmpReg(0),
274 Scale(1), Imm(imm), Sym(nullptr), StopOnLBrac(stoponlbrac),
275 AddImmPrefix(addimmprefix) { Info.clear(); }
277 unsigned getBaseReg() { return BaseReg; }
278 unsigned getIndexReg() { return IndexReg; }
279 unsigned getScale() { return Scale; }
280 const MCExpr *getSym() { return Sym; }
281 StringRef getSymName() { return SymName; }
282 int64_t getImm() { return Imm + IC.execute(); }
283 bool isValidEndState() {
284 return State == IES_RBRAC || State == IES_INTEGER;
286 bool getStopOnLBrac() { return StopOnLBrac; }
287 bool getAddImmPrefix() { return AddImmPrefix; }
288 bool hadError() { return State == IES_ERROR; }
290 InlineAsmIdentifierInfo &getIdentifierInfo() {
295 IntelExprState CurrState = State;
304 IC.pushOperator(IC_OR);
307 PrevState = CurrState;
310 IntelExprState CurrState = State;
319 IC.pushOperator(IC_XOR);
322 PrevState = CurrState;
325 IntelExprState CurrState = State;
334 IC.pushOperator(IC_AND);
337 PrevState = CurrState;
340 IntelExprState CurrState = State;
349 IC.pushOperator(IC_LSHIFT);
352 PrevState = CurrState;
355 IntelExprState CurrState = State;
364 IC.pushOperator(IC_RSHIFT);
367 PrevState = CurrState;
370 IntelExprState CurrState = State;
379 IC.pushOperator(IC_PLUS);
380 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
381 // If we already have a BaseReg, then assume this is the IndexReg with
386 assert (!IndexReg && "BaseReg/IndexReg already set!");
393 PrevState = CurrState;
396 IntelExprState CurrState = State;
412 // Only push the minus operator if it is not a unary operator.
413 if (!(CurrState == IES_PLUS || CurrState == IES_MINUS ||
414 CurrState == IES_MULTIPLY || CurrState == IES_DIVIDE ||
415 CurrState == IES_LPAREN || CurrState == IES_LBRAC))
416 IC.pushOperator(IC_MINUS);
417 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
418 // If we already have a BaseReg, then assume this is the IndexReg with
423 assert (!IndexReg && "BaseReg/IndexReg already set!");
430 PrevState = CurrState;
433 IntelExprState CurrState = State;
443 PrevState = CurrState;
445 void onRegister(unsigned Reg) {
446 IntelExprState CurrState = State;
453 State = IES_REGISTER;
455 IC.pushOperand(IC_REGISTER);
458 // Index Register - Scale * Register
459 if (PrevState == IES_INTEGER) {
460 assert (!IndexReg && "IndexReg already set!");
461 State = IES_REGISTER;
463 // Get the scale and replace the 'Scale * Register' with '0'.
464 Scale = IC.popOperand();
465 IC.pushOperand(IC_IMM);
472 PrevState = CurrState;
474 void onIdentifierExpr(const MCExpr *SymRef, StringRef SymRefName) {
485 SymName = SymRefName;
486 IC.pushOperand(IC_IMM);
490 bool onInteger(int64_t TmpInt, StringRef &ErrMsg) {
491 IntelExprState CurrState = State;
508 if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
509 // Index Register - Register * Scale
510 assert (!IndexReg && "IndexReg already set!");
513 if(Scale != 1 && Scale != 2 && Scale != 4 && Scale != 8) {
514 ErrMsg = "scale factor in address must be 1, 2, 4 or 8";
517 // Get the scale and replace the 'Register * Scale' with '0'.
519 } else if ((PrevState == IES_PLUS || PrevState == IES_MINUS ||
520 PrevState == IES_OR || PrevState == IES_AND ||
521 PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||
522 PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
523 PrevState == IES_LPAREN || PrevState == IES_LBRAC ||
524 PrevState == IES_NOT || PrevState == IES_XOR) &&
525 CurrState == IES_MINUS) {
526 // Unary minus. No need to pop the minus operand because it was never
528 IC.pushOperand(IC_IMM, -TmpInt); // Push -Imm.
529 } else if ((PrevState == IES_PLUS || PrevState == IES_MINUS ||
530 PrevState == IES_OR || PrevState == IES_AND ||
531 PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||
532 PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
533 PrevState == IES_LPAREN || PrevState == IES_LBRAC ||
534 PrevState == IES_NOT || PrevState == IES_XOR) &&
535 CurrState == IES_NOT) {
536 // Unary not. No need to pop the not operand because it was never
538 IC.pushOperand(IC_IMM, ~TmpInt); // Push ~Imm.
540 IC.pushOperand(IC_IMM, TmpInt);
544 PrevState = CurrState;
556 State = IES_MULTIPLY;
557 IC.pushOperator(IC_MULTIPLY);
570 IC.pushOperator(IC_DIVIDE);
582 IC.pushOperator(IC_PLUS);
587 IntelExprState CurrState = State;
596 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
597 // If we already have a BaseReg, then assume this is the IndexReg with
602 assert (!IndexReg && "BaseReg/IndexReg already set!");
609 PrevState = CurrState;
612 IntelExprState CurrState = State;
628 // FIXME: We don't handle this type of unary minus or not, yet.
629 if ((PrevState == IES_PLUS || PrevState == IES_MINUS ||
630 PrevState == IES_OR || PrevState == IES_AND ||
631 PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||
632 PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
633 PrevState == IES_LPAREN || PrevState == IES_LBRAC ||
634 PrevState == IES_NOT || PrevState == IES_XOR) &&
635 (CurrState == IES_MINUS || CurrState == IES_NOT)) {
640 IC.pushOperator(IC_LPAREN);
643 PrevState = CurrState;
655 IC.pushOperator(IC_RPAREN);
661 bool Error(SMLoc L, const Twine &Msg,
662 ArrayRef<SMRange> Ranges = None,
663 bool MatchingInlineAsm = false) {
664 MCAsmParser &Parser = getParser();
665 if (MatchingInlineAsm) return true;
666 return Parser.Error(L, Msg, Ranges);
669 bool ErrorAndEatStatement(SMLoc L, const Twine &Msg,
670 ArrayRef<SMRange> Ranges = None,
671 bool MatchingInlineAsm = false) {
672 MCAsmParser &Parser = getParser();
673 Parser.eatToEndOfStatement();
674 return Error(L, Msg, Ranges, MatchingInlineAsm);
677 std::nullptr_t ErrorOperand(SMLoc Loc, StringRef Msg) {
682 std::unique_ptr<X86Operand> DefaultMemSIOperand(SMLoc Loc);
683 std::unique_ptr<X86Operand> DefaultMemDIOperand(SMLoc Loc);
684 void AddDefaultSrcDestOperands(
685 OperandVector& Operands, std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
686 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst);
687 std::unique_ptr<X86Operand> ParseOperand();
688 std::unique_ptr<X86Operand> ParseATTOperand();
689 std::unique_ptr<X86Operand> ParseIntelOperand();
690 std::unique_ptr<X86Operand> ParseIntelOffsetOfOperator();
691 bool ParseIntelDotOperator(const MCExpr *Disp, const MCExpr *&NewDisp);
692 std::unique_ptr<X86Operand> ParseIntelOperator(unsigned OpKind);
693 std::unique_ptr<X86Operand>
694 ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start, unsigned Size);
695 std::unique_ptr<X86Operand>
696 ParseIntelMemOperand(int64_t ImmDisp, SMLoc StartLoc, unsigned Size);
697 std::unique_ptr<X86Operand> ParseRoundingModeOp(SMLoc Start, SMLoc End);
698 bool ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End);
699 std::unique_ptr<X86Operand> ParseIntelBracExpression(unsigned SegReg,
703 bool ParseIntelIdentifier(const MCExpr *&Val, StringRef &Identifier,
704 InlineAsmIdentifierInfo &Info,
705 bool IsUnevaluatedOperand, SMLoc &End);
707 std::unique_ptr<X86Operand> ParseMemOperand(unsigned SegReg, SMLoc StartLoc);
709 std::unique_ptr<X86Operand>
710 CreateMemForInlineAsm(unsigned SegReg, const MCExpr *Disp, unsigned BaseReg,
711 unsigned IndexReg, unsigned Scale, SMLoc Start,
712 SMLoc End, unsigned Size, StringRef Identifier,
713 InlineAsmIdentifierInfo &Info);
715 bool ParseDirectiveWord(unsigned Size, SMLoc L);
716 bool ParseDirectiveCode(StringRef IDVal, SMLoc L);
718 bool validateInstruction(MCInst &Inst, const OperandVector &Ops);
719 bool processInstruction(MCInst &Inst, const OperandVector &Ops);
721 /// Wrapper around MCStreamer::EmitInstruction(). Possibly adds
722 /// instrumentation around Inst.
723 void EmitInstruction(MCInst &Inst, OperandVector &Operands, MCStreamer &Out);
725 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
726 OperandVector &Operands, MCStreamer &Out,
728 bool MatchingInlineAsm) override;
730 void MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op, OperandVector &Operands,
731 MCStreamer &Out, bool MatchingInlineAsm);
733 bool ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
734 bool MatchingInlineAsm);
736 bool MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
737 OperandVector &Operands, MCStreamer &Out,
739 bool MatchingInlineAsm);
741 bool MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
742 OperandVector &Operands, MCStreamer &Out,
744 bool MatchingInlineAsm);
746 bool OmitRegisterFromClobberLists(unsigned RegNo) override;
748 /// doSrcDstMatch - Returns true if operands are matching in their
749 /// word size (%si and %di, %esi and %edi, etc.). Order depends on
750 /// the parsing mode (Intel vs. AT&T).
751 bool doSrcDstMatch(X86Operand &Op1, X86Operand &Op2);
753 /// Parses AVX512 specific operand primitives: masked registers ({%k<NUM>}, {z})
754 /// and memory broadcasting ({1to<NUM>}) primitives, updating Operands vector if required.
755 /// \return \c true if no parsing errors occurred, \c false otherwise.
756 bool HandleAVX512Operand(OperandVector &Operands,
757 const MCParsedAsmOperand &Op);
759 bool is64BitMode() const {
760 // FIXME: Can tablegen auto-generate this?
761 return STI.getFeatureBits()[X86::Mode64Bit];
763 bool is32BitMode() const {
764 // FIXME: Can tablegen auto-generate this?
765 return STI.getFeatureBits()[X86::Mode32Bit];
767 bool is16BitMode() const {
768 // FIXME: Can tablegen auto-generate this?
769 return STI.getFeatureBits()[X86::Mode16Bit];
771 void SwitchMode(unsigned mode) {
772 FeatureBitset AllModes({X86::Mode64Bit, X86::Mode32Bit, X86::Mode16Bit});
773 FeatureBitset OldMode = STI.getFeatureBits() & AllModes;
774 unsigned FB = ComputeAvailableFeatures(
775 STI.ToggleFeature(OldMode.flip(mode)));
776 setAvailableFeatures(FB);
778 assert(FeatureBitset({mode}) == (STI.getFeatureBits() & AllModes));
781 unsigned getPointerWidth() {
782 if (is16BitMode()) return 16;
783 if (is32BitMode()) return 32;
784 if (is64BitMode()) return 64;
785 llvm_unreachable("invalid mode");
788 bool isParsingIntelSyntax() {
789 return getParser().getAssemblerDialect();
792 /// @name Auto-generated Matcher Functions
795 #define GET_ASSEMBLER_HEADER
796 #include "X86GenAsmMatcher.inc"
801 X86AsmParser(MCSubtargetInfo &sti, MCAsmParser &Parser,
802 const MCInstrInfo &mii, const MCTargetOptions &Options)
803 : MCTargetAsmParser(), STI(sti), MII(mii), InstInfo(nullptr) {
805 // Initialize the set of available features.
806 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
807 Instrumentation.reset(
808 CreateX86AsmInstrumentation(Options, Parser.getContext(), STI));
811 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
813 void SetFrameRegister(unsigned RegNo) override;
815 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
816 SMLoc NameLoc, OperandVector &Operands) override;
818 bool ParseDirective(AsmToken DirectiveID) override;
820 } // end anonymous namespace
822 /// @name Auto-generated Match Functions
825 static unsigned MatchRegisterName(StringRef Name);
829 static bool CheckBaseRegAndIndexReg(unsigned BaseReg, unsigned IndexReg,
831 // If we have both a base register and an index register make sure they are
832 // both 64-bit or 32-bit registers.
833 // To support VSIB, IndexReg can be 128-bit or 256-bit registers.
834 if (BaseReg != 0 && IndexReg != 0) {
835 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) &&
836 (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
837 X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg)) &&
838 IndexReg != X86::RIZ) {
839 ErrMsg = "base register is 64-bit, but index register is not";
842 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg) &&
843 (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
844 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) &&
845 IndexReg != X86::EIZ){
846 ErrMsg = "base register is 32-bit, but index register is not";
849 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg)) {
850 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg) ||
851 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) {
852 ErrMsg = "base register is 16-bit, but index register is not";
855 if (((BaseReg == X86::BX || BaseReg == X86::BP) &&
856 IndexReg != X86::SI && IndexReg != X86::DI) ||
857 ((BaseReg == X86::SI || BaseReg == X86::DI) &&
858 IndexReg != X86::BX && IndexReg != X86::BP)) {
859 ErrMsg = "invalid 16-bit base/index register combination";
867 bool X86AsmParser::doSrcDstMatch(X86Operand &Op1, X86Operand &Op2)
869 // Return true and let a normal complaint about bogus operands happen.
870 if (!Op1.isMem() || !Op2.isMem())
873 // Actually these might be the other way round if Intel syntax is
874 // being used. It doesn't matter.
875 unsigned diReg = Op1.Mem.BaseReg;
876 unsigned siReg = Op2.Mem.BaseReg;
878 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(siReg))
879 return X86MCRegisterClasses[X86::GR16RegClassID].contains(diReg);
880 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(siReg))
881 return X86MCRegisterClasses[X86::GR32RegClassID].contains(diReg);
882 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(siReg))
883 return X86MCRegisterClasses[X86::GR64RegClassID].contains(diReg);
884 // Again, return true and let another error happen.
888 bool X86AsmParser::ParseRegister(unsigned &RegNo,
889 SMLoc &StartLoc, SMLoc &EndLoc) {
890 MCAsmParser &Parser = getParser();
892 const AsmToken &PercentTok = Parser.getTok();
893 StartLoc = PercentTok.getLoc();
895 // If we encounter a %, ignore it. This code handles registers with and
896 // without the prefix, unprefixed registers can occur in cfi directives.
897 if (!isParsingIntelSyntax() && PercentTok.is(AsmToken::Percent))
898 Parser.Lex(); // Eat percent token.
900 const AsmToken &Tok = Parser.getTok();
901 EndLoc = Tok.getEndLoc();
903 if (Tok.isNot(AsmToken::Identifier)) {
904 if (isParsingIntelSyntax()) return true;
905 return Error(StartLoc, "invalid register name",
906 SMRange(StartLoc, EndLoc));
909 RegNo = MatchRegisterName(Tok.getString());
911 // If the match failed, try the register name as lowercase.
913 RegNo = MatchRegisterName(Tok.getString().lower());
915 if (!is64BitMode()) {
916 // FIXME: This should be done using Requires<Not64BitMode> and
917 // Requires<In64BitMode> so "eiz" usage in 64-bit instructions can be also
919 // FIXME: Check AH, CH, DH, BH cannot be used in an instruction requiring a
921 if (RegNo == X86::RIZ ||
922 X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo) ||
923 X86II::isX86_64NonExtLowByteReg(RegNo) ||
924 X86II::isX86_64ExtendedReg(RegNo))
925 return Error(StartLoc, "register %"
926 + Tok.getString() + " is only available in 64-bit mode",
927 SMRange(StartLoc, EndLoc));
930 // Parse "%st" as "%st(0)" and "%st(1)", which is multiple tokens.
931 if (RegNo == 0 && (Tok.getString() == "st" || Tok.getString() == "ST")) {
933 Parser.Lex(); // Eat 'st'
935 // Check to see if we have '(4)' after %st.
936 if (getLexer().isNot(AsmToken::LParen))
941 const AsmToken &IntTok = Parser.getTok();
942 if (IntTok.isNot(AsmToken::Integer))
943 return Error(IntTok.getLoc(), "expected stack index");
944 switch (IntTok.getIntVal()) {
945 case 0: RegNo = X86::ST0; break;
946 case 1: RegNo = X86::ST1; break;
947 case 2: RegNo = X86::ST2; break;
948 case 3: RegNo = X86::ST3; break;
949 case 4: RegNo = X86::ST4; break;
950 case 5: RegNo = X86::ST5; break;
951 case 6: RegNo = X86::ST6; break;
952 case 7: RegNo = X86::ST7; break;
953 default: return Error(IntTok.getLoc(), "invalid stack index");
956 if (getParser().Lex().isNot(AsmToken::RParen))
957 return Error(Parser.getTok().getLoc(), "expected ')'");
959 EndLoc = Parser.getTok().getEndLoc();
960 Parser.Lex(); // Eat ')'
964 EndLoc = Parser.getTok().getEndLoc();
966 // If this is "db[0-7]", match it as an alias
968 if (RegNo == 0 && Tok.getString().size() == 3 &&
969 Tok.getString().startswith("db")) {
970 switch (Tok.getString()[2]) {
971 case '0': RegNo = X86::DR0; break;
972 case '1': RegNo = X86::DR1; break;
973 case '2': RegNo = X86::DR2; break;
974 case '3': RegNo = X86::DR3; break;
975 case '4': RegNo = X86::DR4; break;
976 case '5': RegNo = X86::DR5; break;
977 case '6': RegNo = X86::DR6; break;
978 case '7': RegNo = X86::DR7; break;
982 EndLoc = Parser.getTok().getEndLoc();
983 Parser.Lex(); // Eat it.
989 if (isParsingIntelSyntax()) return true;
990 return Error(StartLoc, "invalid register name",
991 SMRange(StartLoc, EndLoc));
994 Parser.Lex(); // Eat identifier token.
998 void X86AsmParser::SetFrameRegister(unsigned RegNo) {
999 Instrumentation->SetInitialFrameRegister(RegNo);
1002 std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(SMLoc Loc) {
1004 is64BitMode() ? X86::RSI : (is32BitMode() ? X86::ESI : X86::SI);
1005 const MCExpr *Disp = MCConstantExpr::create(0, getContext());
1006 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
1007 /*BaseReg=*/basereg, /*IndexReg=*/0, /*Scale=*/1,
1011 std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand(SMLoc Loc) {
1013 is64BitMode() ? X86::RDI : (is32BitMode() ? X86::EDI : X86::DI);
1014 const MCExpr *Disp = MCConstantExpr::create(0, getContext());
1015 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
1016 /*BaseReg=*/basereg, /*IndexReg=*/0, /*Scale=*/1,
1020 void X86AsmParser::AddDefaultSrcDestOperands(
1021 OperandVector& Operands, std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
1022 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst) {
1023 if (isParsingIntelSyntax()) {
1024 Operands.push_back(std::move(Dst));
1025 Operands.push_back(std::move(Src));
1028 Operands.push_back(std::move(Src));
1029 Operands.push_back(std::move(Dst));
1033 std::unique_ptr<X86Operand> X86AsmParser::ParseOperand() {
1034 if (isParsingIntelSyntax())
1035 return ParseIntelOperand();
1036 return ParseATTOperand();
1039 /// getIntelMemOperandSize - Return intel memory operand size.
1040 static unsigned getIntelMemOperandSize(StringRef OpStr) {
1041 unsigned Size = StringSwitch<unsigned>(OpStr)
1042 .Cases("BYTE", "byte", 8)
1043 .Cases("WORD", "word", 16)
1044 .Cases("DWORD", "dword", 32)
1045 .Cases("QWORD", "qword", 64)
1046 .Cases("XWORD", "xword", 80)
1047 .Cases("TBYTE", "tbyte", 80)
1048 .Cases("XMMWORD", "xmmword", 128)
1049 .Cases("YMMWORD", "ymmword", 256)
1050 .Cases("ZMMWORD", "zmmword", 512)
1051 .Cases("OPAQUE", "opaque", -1U) // needs to be non-zero, but doesn't matter
1056 std::unique_ptr<X86Operand> X86AsmParser::CreateMemForInlineAsm(
1057 unsigned SegReg, const MCExpr *Disp, unsigned BaseReg, unsigned IndexReg,
1058 unsigned Scale, SMLoc Start, SMLoc End, unsigned Size, StringRef Identifier,
1059 InlineAsmIdentifierInfo &Info) {
1060 // If we found a decl other than a VarDecl, then assume it is a FuncDecl or
1061 // some other label reference.
1062 if (isa<MCSymbolRefExpr>(Disp) && Info.OpDecl && !Info.IsVarDecl) {
1063 // Insert an explicit size if the user didn't have one.
1065 Size = getPointerWidth();
1066 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_SizeDirective, Start,
1070 // Create an absolute memory reference in order to match against
1071 // instructions taking a PC relative operand.
1072 return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size,
1073 Identifier, Info.OpDecl);
1076 // We either have a direct symbol reference, or an offset from a symbol. The
1077 // parser always puts the symbol on the LHS, so look there for size
1078 // calculation purposes.
1079 const MCBinaryExpr *BinOp = dyn_cast<MCBinaryExpr>(Disp);
1081 isa<MCSymbolRefExpr>(BinOp ? BinOp->getLHS() : Disp);
1084 Size = Info.Type * 8; // Size is in terms of bits in this context.
1086 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_SizeDirective, Start,
1091 // When parsing inline assembly we set the base register to a non-zero value
1092 // if we don't know the actual value at this time. This is necessary to
1093 // get the matching correct in some cases.
1094 BaseReg = BaseReg ? BaseReg : 1;
1095 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
1096 IndexReg, Scale, Start, End, Size, Identifier,
1101 RewriteIntelBracExpression(SmallVectorImpl<AsmRewrite> *AsmRewrites,
1102 StringRef SymName, int64_t ImmDisp,
1103 int64_t FinalImmDisp, SMLoc &BracLoc,
1104 SMLoc &StartInBrac, SMLoc &End) {
1105 // Remove the '[' and ']' from the IR string.
1106 AsmRewrites->push_back(AsmRewrite(AOK_Skip, BracLoc, 1));
1107 AsmRewrites->push_back(AsmRewrite(AOK_Skip, End, 1));
1109 // If ImmDisp is non-zero, then we parsed a displacement before the
1110 // bracketed expression (i.e., ImmDisp [ BaseReg + Scale*IndexReg + Disp])
1111 // If ImmDisp doesn't match the displacement computed by the state machine
1112 // then we have an additional displacement in the bracketed expression.
1113 if (ImmDisp != FinalImmDisp) {
1115 // We have an immediate displacement before the bracketed expression.
1116 // Adjust this to match the final immediate displacement.
1118 for (SmallVectorImpl<AsmRewrite>::iterator I = AsmRewrites->begin(),
1119 E = AsmRewrites->end(); I != E; ++I) {
1120 if ((*I).Loc.getPointer() > BracLoc.getPointer())
1122 if ((*I).Kind == AOK_ImmPrefix || (*I).Kind == AOK_Imm) {
1123 assert (!Found && "ImmDisp already rewritten.");
1124 (*I).Kind = AOK_Imm;
1125 (*I).Len = BracLoc.getPointer() - (*I).Loc.getPointer();
1126 (*I).Val = FinalImmDisp;
1131 assert (Found && "Unable to rewrite ImmDisp.");
1134 // We have a symbolic and an immediate displacement, but no displacement
1135 // before the bracketed expression. Put the immediate displacement
1136 // before the bracketed expression.
1137 AsmRewrites->push_back(AsmRewrite(AOK_Imm, BracLoc, 0, FinalImmDisp));
1140 // Remove all the ImmPrefix rewrites within the brackets.
1141 for (SmallVectorImpl<AsmRewrite>::iterator I = AsmRewrites->begin(),
1142 E = AsmRewrites->end(); I != E; ++I) {
1143 if ((*I).Loc.getPointer() < StartInBrac.getPointer())
1145 if ((*I).Kind == AOK_ImmPrefix)
1146 (*I).Kind = AOK_Delete;
1148 const char *SymLocPtr = SymName.data();
1149 // Skip everything before the symbol.
1150 if (unsigned Len = SymLocPtr - StartInBrac.getPointer()) {
1151 assert(Len > 0 && "Expected a non-negative length.");
1152 AsmRewrites->push_back(AsmRewrite(AOK_Skip, StartInBrac, Len));
1154 // Skip everything after the symbol.
1155 if (unsigned Len = End.getPointer() - (SymLocPtr + SymName.size())) {
1156 SMLoc Loc = SMLoc::getFromPointer(SymLocPtr + SymName.size());
1157 assert(Len > 0 && "Expected a non-negative length.");
1158 AsmRewrites->push_back(AsmRewrite(AOK_Skip, Loc, Len));
1162 bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
1163 MCAsmParser &Parser = getParser();
1164 const AsmToken &Tok = Parser.getTok();
1168 bool UpdateLocLex = true;
1170 // The period in the dot operator (e.g., [ebx].foo.bar) is parsed as an
1171 // identifier. Don't try an parse it as a register.
1172 if (Tok.getString().startswith("."))
1175 // If we're parsing an immediate expression, we don't expect a '['.
1176 if (SM.getStopOnLBrac() && getLexer().getKind() == AsmToken::LBrac)
1179 AsmToken::TokenKind TK = getLexer().getKind();
1182 if (SM.isValidEndState()) {
1186 return Error(Tok.getLoc(), "unknown token in expression");
1188 case AsmToken::EndOfStatement: {
1192 case AsmToken::String:
1193 case AsmToken::Identifier: {
1194 // This could be a register or a symbolic displacement.
1197 SMLoc IdentLoc = Tok.getLoc();
1198 StringRef Identifier = Tok.getString();
1199 if (TK != AsmToken::String && !ParseRegister(TmpReg, IdentLoc, End)) {
1200 SM.onRegister(TmpReg);
1201 UpdateLocLex = false;
1204 if (!isParsingInlineAsm()) {
1205 if (getParser().parsePrimaryExpr(Val, End))
1206 return Error(Tok.getLoc(), "Unexpected identifier!");
1208 // This is a dot operator, not an adjacent identifier.
1209 if (Identifier.find('.') != StringRef::npos) {
1212 InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
1213 if (ParseIntelIdentifier(Val, Identifier, Info,
1214 /*Unevaluated=*/false, End))
1218 SM.onIdentifierExpr(Val, Identifier);
1219 UpdateLocLex = false;
1222 return Error(Tok.getLoc(), "Unexpected identifier!");
1224 case AsmToken::Integer: {
1226 if (isParsingInlineAsm() && SM.getAddImmPrefix())
1227 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_ImmPrefix,
1229 // Look for 'b' or 'f' following an Integer as a directional label
1230 SMLoc Loc = getTok().getLoc();
1231 int64_t IntVal = getTok().getIntVal();
1232 End = consumeToken();
1233 UpdateLocLex = false;
1234 if (getLexer().getKind() == AsmToken::Identifier) {
1235 StringRef IDVal = getTok().getString();
1236 if (IDVal == "f" || IDVal == "b") {
1238 getContext().getDirectionalLocalSymbol(IntVal, IDVal == "b");
1239 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1241 MCSymbolRefExpr::create(Sym, Variant, getContext());
1242 if (IDVal == "b" && Sym->isUndefined())
1243 return Error(Loc, "invalid reference to undefined symbol");
1244 StringRef Identifier = Sym->getName();
1245 SM.onIdentifierExpr(Val, Identifier);
1246 End = consumeToken();
1248 if (SM.onInteger(IntVal, ErrMsg))
1249 return Error(Loc, ErrMsg);
1252 if (SM.onInteger(IntVal, ErrMsg))
1253 return Error(Loc, ErrMsg);
1257 case AsmToken::Plus: SM.onPlus(); break;
1258 case AsmToken::Minus: SM.onMinus(); break;
1259 case AsmToken::Tilde: SM.onNot(); break;
1260 case AsmToken::Star: SM.onStar(); break;
1261 case AsmToken::Slash: SM.onDivide(); break;
1262 case AsmToken::Pipe: SM.onOr(); break;
1263 case AsmToken::Caret: SM.onXor(); break;
1264 case AsmToken::Amp: SM.onAnd(); break;
1265 case AsmToken::LessLess:
1266 SM.onLShift(); break;
1267 case AsmToken::GreaterGreater:
1268 SM.onRShift(); break;
1269 case AsmToken::LBrac: SM.onLBrac(); break;
1270 case AsmToken::RBrac: SM.onRBrac(); break;
1271 case AsmToken::LParen: SM.onLParen(); break;
1272 case AsmToken::RParen: SM.onRParen(); break;
1275 return Error(Tok.getLoc(), "unknown token in expression");
1277 if (!Done && UpdateLocLex)
1278 End = consumeToken();
1283 std::unique_ptr<X86Operand>
1284 X86AsmParser::ParseIntelBracExpression(unsigned SegReg, SMLoc Start,
1285 int64_t ImmDisp, unsigned Size) {
1286 MCAsmParser &Parser = getParser();
1287 const AsmToken &Tok = Parser.getTok();
1288 SMLoc BracLoc = Tok.getLoc(), End = Tok.getEndLoc();
1289 if (getLexer().isNot(AsmToken::LBrac))
1290 return ErrorOperand(BracLoc, "Expected '[' token!");
1291 Parser.Lex(); // Eat '['
1293 SMLoc StartInBrac = Tok.getLoc();
1294 // Parse [ Symbol + ImmDisp ] and [ BaseReg + Scale*IndexReg + ImmDisp ]. We
1295 // may have already parsed an immediate displacement before the bracketed
1297 IntelExprStateMachine SM(ImmDisp, /*StopOnLBrac=*/false, /*AddImmPrefix=*/true);
1298 if (ParseIntelExpression(SM, End))
1301 const MCExpr *Disp = nullptr;
1302 if (const MCExpr *Sym = SM.getSym()) {
1303 // A symbolic displacement.
1305 if (isParsingInlineAsm())
1306 RewriteIntelBracExpression(InstInfo->AsmRewrites, SM.getSymName(),
1307 ImmDisp, SM.getImm(), BracLoc, StartInBrac,
1311 if (SM.getImm() || !Disp) {
1312 const MCExpr *Imm = MCConstantExpr::create(SM.getImm(), getContext());
1314 Disp = MCBinaryExpr::createAdd(Disp, Imm, getContext());
1316 Disp = Imm; // An immediate displacement only.
1319 // Parse struct field access. Intel requires a dot, but MSVC doesn't. MSVC
1320 // will in fact do global lookup the field name inside all global typedefs,
1321 // but we don't emulate that.
1322 if (Tok.getString().find('.') != StringRef::npos) {
1323 const MCExpr *NewDisp;
1324 if (ParseIntelDotOperator(Disp, NewDisp))
1327 End = Tok.getEndLoc();
1328 Parser.Lex(); // Eat the field.
1332 int BaseReg = SM.getBaseReg();
1333 int IndexReg = SM.getIndexReg();
1334 int Scale = SM.getScale();
1335 if (!isParsingInlineAsm()) {
1337 if (!BaseReg && !IndexReg) {
1339 return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size);
1340 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
1344 if (CheckBaseRegAndIndexReg(BaseReg, IndexReg, ErrMsg)) {
1345 Error(StartInBrac, ErrMsg);
1348 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
1349 IndexReg, Scale, Start, End, Size);
1352 InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
1353 return CreateMemForInlineAsm(SegReg, Disp, BaseReg, IndexReg, Scale, Start,
1354 End, Size, SM.getSymName(), Info);
1357 // Inline assembly may use variable names with namespace alias qualifiers.
1358 bool X86AsmParser::ParseIntelIdentifier(const MCExpr *&Val,
1359 StringRef &Identifier,
1360 InlineAsmIdentifierInfo &Info,
1361 bool IsUnevaluatedOperand, SMLoc &End) {
1362 MCAsmParser &Parser = getParser();
1363 assert (isParsingInlineAsm() && "Expected to be parsing inline assembly.");
1366 StringRef LineBuf(Identifier.data());
1368 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);
1370 const AsmToken &Tok = Parser.getTok();
1371 SMLoc Loc = Tok.getLoc();
1373 // Advance the token stream until the end of the current token is
1374 // after the end of what the frontend claimed.
1375 const char *EndPtr = Tok.getLoc().getPointer() + LineBuf.size();
1377 End = Tok.getEndLoc();
1380 assert(End.getPointer() <= EndPtr && "frontend claimed part of a token?");
1381 if (End.getPointer() == EndPtr) break;
1383 Identifier = LineBuf;
1385 // If the identifier lookup was unsuccessful, assume that we are dealing with
1388 StringRef InternalName =
1389 SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(),
1391 assert(InternalName.size() && "We should have an internal name here.");
1392 // Push a rewrite for replacing the identifier name with the internal name.
1393 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Label, Loc,
1398 // Create the symbol reference.
1399 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
1400 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1401 Val = MCSymbolRefExpr::create(Sym, Variant, getParser().getContext());
1405 /// \brief Parse intel style segment override.
1406 std::unique_ptr<X86Operand>
1407 X86AsmParser::ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start,
1409 MCAsmParser &Parser = getParser();
1410 assert(SegReg != 0 && "Tried to parse a segment override without a segment!");
1411 const AsmToken &Tok = Parser.getTok(); // Eat colon.
1412 if (Tok.isNot(AsmToken::Colon))
1413 return ErrorOperand(Tok.getLoc(), "Expected ':' token!");
1414 Parser.Lex(); // Eat ':'
1416 int64_t ImmDisp = 0;
1417 if (getLexer().is(AsmToken::Integer)) {
1418 ImmDisp = Tok.getIntVal();
1419 AsmToken ImmDispToken = Parser.Lex(); // Eat the integer.
1421 if (isParsingInlineAsm())
1422 InstInfo->AsmRewrites->push_back(
1423 AsmRewrite(AOK_ImmPrefix, ImmDispToken.getLoc()));
1425 if (getLexer().isNot(AsmToken::LBrac)) {
1426 // An immediate following a 'segment register', 'colon' token sequence can
1427 // be followed by a bracketed expression. If it isn't we know we have our
1428 // final segment override.
1429 const MCExpr *Disp = MCConstantExpr::create(ImmDisp, getContext());
1430 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp,
1431 /*BaseReg=*/0, /*IndexReg=*/0, /*Scale=*/1,
1432 Start, ImmDispToken.getEndLoc(), Size);
1436 if (getLexer().is(AsmToken::LBrac))
1437 return ParseIntelBracExpression(SegReg, Start, ImmDisp, Size);
1441 if (!isParsingInlineAsm()) {
1442 if (getParser().parsePrimaryExpr(Val, End))
1443 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1445 return X86Operand::CreateMem(getPointerWidth(), Val, Start, End, Size);
1448 InlineAsmIdentifierInfo Info;
1449 StringRef Identifier = Tok.getString();
1450 if (ParseIntelIdentifier(Val, Identifier, Info,
1451 /*Unevaluated=*/false, End))
1453 return CreateMemForInlineAsm(/*SegReg=*/0, Val, /*BaseReg=*/0,/*IndexReg=*/0,
1454 /*Scale=*/1, Start, End, Size, Identifier, Info);
1457 //ParseRoundingModeOp - Parse AVX-512 rounding mode operand
1458 std::unique_ptr<X86Operand>
1459 X86AsmParser::ParseRoundingModeOp(SMLoc Start, SMLoc End) {
1460 MCAsmParser &Parser = getParser();
1461 const AsmToken &Tok = Parser.getTok();
1462 // Eat "{" and mark the current place.
1463 const SMLoc consumedToken = consumeToken();
1464 if (Tok.getIdentifier().startswith("r")){
1465 int rndMode = StringSwitch<int>(Tok.getIdentifier())
1466 .Case("rn", X86::STATIC_ROUNDING::TO_NEAREST_INT)
1467 .Case("rd", X86::STATIC_ROUNDING::TO_NEG_INF)
1468 .Case("ru", X86::STATIC_ROUNDING::TO_POS_INF)
1469 .Case("rz", X86::STATIC_ROUNDING::TO_ZERO)
1472 return ErrorOperand(Tok.getLoc(), "Invalid rounding mode.");
1473 Parser.Lex(); // Eat "r*" of r*-sae
1474 if (!getLexer().is(AsmToken::Minus))
1475 return ErrorOperand(Tok.getLoc(), "Expected - at this point");
1476 Parser.Lex(); // Eat "-"
1477 Parser.Lex(); // Eat the sae
1478 if (!getLexer().is(AsmToken::RCurly))
1479 return ErrorOperand(Tok.getLoc(), "Expected } at this point");
1480 Parser.Lex(); // Eat "}"
1481 const MCExpr *RndModeOp =
1482 MCConstantExpr::create(rndMode, Parser.getContext());
1483 return X86Operand::CreateImm(RndModeOp, Start, End);
1485 if(Tok.getIdentifier().equals("sae")){
1486 Parser.Lex(); // Eat the sae
1487 if (!getLexer().is(AsmToken::RCurly))
1488 return ErrorOperand(Tok.getLoc(), "Expected } at this point");
1489 Parser.Lex(); // Eat "}"
1490 return X86Operand::CreateToken("{sae}", consumedToken);
1492 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1494 /// ParseIntelMemOperand - Parse intel style memory operand.
1495 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelMemOperand(int64_t ImmDisp,
1498 MCAsmParser &Parser = getParser();
1499 const AsmToken &Tok = Parser.getTok();
1502 // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
1503 if (getLexer().is(AsmToken::LBrac))
1504 return ParseIntelBracExpression(/*SegReg=*/0, Start, ImmDisp, Size);
1505 assert(ImmDisp == 0);
1508 if (!isParsingInlineAsm()) {
1509 if (getParser().parsePrimaryExpr(Val, End))
1510 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1512 return X86Operand::CreateMem(getPointerWidth(), Val, Start, End, Size);
1515 InlineAsmIdentifierInfo Info;
1516 StringRef Identifier = Tok.getString();
1517 if (ParseIntelIdentifier(Val, Identifier, Info,
1518 /*Unevaluated=*/false, End))
1521 if (!getLexer().is(AsmToken::LBrac))
1522 return CreateMemForInlineAsm(/*SegReg=*/0, Val, /*BaseReg=*/0, /*IndexReg=*/0,
1523 /*Scale=*/1, Start, End, Size, Identifier, Info);
1525 Parser.Lex(); // Eat '['
1527 // Parse Identifier [ ImmDisp ]
1528 IntelExprStateMachine SM(/*ImmDisp=*/0, /*StopOnLBrac=*/true,
1529 /*AddImmPrefix=*/false);
1530 if (ParseIntelExpression(SM, End))
1534 Error(Start, "cannot use more than one symbol in memory operand");
1537 if (SM.getBaseReg()) {
1538 Error(Start, "cannot use base register with variable reference");
1541 if (SM.getIndexReg()) {
1542 Error(Start, "cannot use index register with variable reference");
1546 const MCExpr *Disp = MCConstantExpr::create(SM.getImm(), getContext());
1547 // BaseReg is non-zero to avoid assertions. In the context of inline asm,
1548 // we're pointing to a local variable in memory, so the base register is
1549 // really the frame or stack pointer.
1550 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
1551 /*BaseReg=*/1, /*IndexReg=*/0, /*Scale=*/1,
1552 Start, End, Size, Identifier, Info.OpDecl);
1555 /// Parse the '.' operator.
1556 bool X86AsmParser::ParseIntelDotOperator(const MCExpr *Disp,
1557 const MCExpr *&NewDisp) {
1558 MCAsmParser &Parser = getParser();
1559 const AsmToken &Tok = Parser.getTok();
1560 int64_t OrigDispVal, DotDispVal;
1562 // FIXME: Handle non-constant expressions.
1563 if (const MCConstantExpr *OrigDisp = dyn_cast<MCConstantExpr>(Disp))
1564 OrigDispVal = OrigDisp->getValue();
1566 return Error(Tok.getLoc(), "Non-constant offsets are not supported!");
1568 // Drop the optional '.'.
1569 StringRef DotDispStr = Tok.getString();
1570 if (DotDispStr.startswith("."))
1571 DotDispStr = DotDispStr.drop_front(1);
1573 // .Imm gets lexed as a real.
1574 if (Tok.is(AsmToken::Real)) {
1576 DotDispStr.getAsInteger(10, DotDisp);
1577 DotDispVal = DotDisp.getZExtValue();
1578 } else if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) {
1580 std::pair<StringRef, StringRef> BaseMember = DotDispStr.split('.');
1581 if (SemaCallback->LookupInlineAsmField(BaseMember.first, BaseMember.second,
1583 return Error(Tok.getLoc(), "Unable to lookup field reference!");
1584 DotDispVal = DotDisp;
1586 return Error(Tok.getLoc(), "Unexpected token type!");
1588 if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) {
1589 SMLoc Loc = SMLoc::getFromPointer(DotDispStr.data());
1590 unsigned Len = DotDispStr.size();
1591 unsigned Val = OrigDispVal + DotDispVal;
1592 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_DotOperator, Loc, Len,
1596 NewDisp = MCConstantExpr::create(OrigDispVal + DotDispVal, getContext());
1600 /// Parse the 'offset' operator. This operator is used to specify the
1601 /// location rather then the content of a variable.
1602 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOffsetOfOperator() {
1603 MCAsmParser &Parser = getParser();
1604 const AsmToken &Tok = Parser.getTok();
1605 SMLoc OffsetOfLoc = Tok.getLoc();
1606 Parser.Lex(); // Eat offset.
1609 InlineAsmIdentifierInfo Info;
1610 SMLoc Start = Tok.getLoc(), End;
1611 StringRef Identifier = Tok.getString();
1612 if (ParseIntelIdentifier(Val, Identifier, Info,
1613 /*Unevaluated=*/false, End))
1616 // Don't emit the offset operator.
1617 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Skip, OffsetOfLoc, 7));
1619 // The offset operator will have an 'r' constraint, thus we need to create
1620 // register operand to ensure proper matching. Just pick a GPR based on
1621 // the size of a pointer.
1623 is64BitMode() ? X86::RBX : (is32BitMode() ? X86::EBX : X86::BX);
1624 return X86Operand::CreateReg(RegNo, Start, End, /*GetAddress=*/true,
1625 OffsetOfLoc, Identifier, Info.OpDecl);
1628 enum IntelOperatorKind {
1634 /// Parse the 'LENGTH', 'TYPE' and 'SIZE' operators. The LENGTH operator
1635 /// returns the number of elements in an array. It returns the value 1 for
1636 /// non-array variables. The SIZE operator returns the size of a C or C++
1637 /// variable. A variable's size is the product of its LENGTH and TYPE. The
1638 /// TYPE operator returns the size of a C or C++ type or variable. If the
1639 /// variable is an array, TYPE returns the size of a single element.
1640 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperator(unsigned OpKind) {
1641 MCAsmParser &Parser = getParser();
1642 const AsmToken &Tok = Parser.getTok();
1643 SMLoc TypeLoc = Tok.getLoc();
1644 Parser.Lex(); // Eat operator.
1646 const MCExpr *Val = nullptr;
1647 InlineAsmIdentifierInfo Info;
1648 SMLoc Start = Tok.getLoc(), End;
1649 StringRef Identifier = Tok.getString();
1650 if (ParseIntelIdentifier(Val, Identifier, Info,
1651 /*Unevaluated=*/true, End))
1655 return ErrorOperand(Start, "unable to lookup expression");
1659 default: llvm_unreachable("Unexpected operand kind!");
1660 case IOK_LENGTH: CVal = Info.Length; break;
1661 case IOK_SIZE: CVal = Info.Size; break;
1662 case IOK_TYPE: CVal = Info.Type; break;
1665 // Rewrite the type operator and the C or C++ type or variable in terms of an
1666 // immediate. E.g. TYPE foo -> $$4
1667 unsigned Len = End.getPointer() - TypeLoc.getPointer();
1668 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Imm, TypeLoc, Len, CVal));
1670 const MCExpr *Imm = MCConstantExpr::create(CVal, getContext());
1671 return X86Operand::CreateImm(Imm, Start, End);
1674 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand() {
1675 MCAsmParser &Parser = getParser();
1676 const AsmToken &Tok = Parser.getTok();
1679 // Offset, length, type and size operators.
1680 if (isParsingInlineAsm()) {
1681 StringRef AsmTokStr = Tok.getString();
1682 if (AsmTokStr == "offset" || AsmTokStr == "OFFSET")
1683 return ParseIntelOffsetOfOperator();
1684 if (AsmTokStr == "length" || AsmTokStr == "LENGTH")
1685 return ParseIntelOperator(IOK_LENGTH);
1686 if (AsmTokStr == "size" || AsmTokStr == "SIZE")
1687 return ParseIntelOperator(IOK_SIZE);
1688 if (AsmTokStr == "type" || AsmTokStr == "TYPE")
1689 return ParseIntelOperator(IOK_TYPE);
1692 unsigned Size = getIntelMemOperandSize(Tok.getString());
1694 Parser.Lex(); // Eat operand size (e.g., byte, word).
1695 if (Tok.getString() != "PTR" && Tok.getString() != "ptr")
1696 return ErrorOperand(Tok.getLoc(), "Expected 'PTR' or 'ptr' token!");
1697 Parser.Lex(); // Eat ptr.
1699 Start = Tok.getLoc();
1702 if (getLexer().is(AsmToken::Integer) || getLexer().is(AsmToken::Minus) ||
1703 getLexer().is(AsmToken::Tilde) || getLexer().is(AsmToken::LParen)) {
1704 AsmToken StartTok = Tok;
1705 IntelExprStateMachine SM(/*Imm=*/0, /*StopOnLBrac=*/true,
1706 /*AddImmPrefix=*/false);
1707 if (ParseIntelExpression(SM, End))
1710 int64_t Imm = SM.getImm();
1711 if (isParsingInlineAsm()) {
1712 unsigned Len = Tok.getLoc().getPointer() - Start.getPointer();
1713 if (StartTok.getString().size() == Len)
1714 // Just add a prefix if this wasn't a complex immediate expression.
1715 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_ImmPrefix, Start));
1717 // Otherwise, rewrite the complex expression as a single immediate.
1718 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Imm, Start, Len, Imm));
1721 if (getLexer().isNot(AsmToken::LBrac)) {
1722 // If a directional label (ie. 1f or 2b) was parsed above from
1723 // ParseIntelExpression() then SM.getSym() was set to a pointer to
1724 // to the MCExpr with the directional local symbol and this is a
1725 // memory operand not an immediate operand.
1727 return X86Operand::CreateMem(getPointerWidth(), SM.getSym(), Start, End,
1730 const MCExpr *ImmExpr = MCConstantExpr::create(Imm, getContext());
1731 return X86Operand::CreateImm(ImmExpr, Start, End);
1734 // Only positive immediates are valid.
1736 return ErrorOperand(Start, "expected a positive immediate displacement "
1737 "before bracketed expr.");
1739 // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
1740 return ParseIntelMemOperand(Imm, Start, Size);
1743 // rounding mode token
1744 if (STI.getFeatureBits()[X86::FeatureAVX512] &&
1745 getLexer().is(AsmToken::LCurly))
1746 return ParseRoundingModeOp(Start, End);
1750 if (!ParseRegister(RegNo, Start, End)) {
1751 // If this is a segment register followed by a ':', then this is the start
1752 // of a segment override, otherwise this is a normal register reference.
1753 if (getLexer().isNot(AsmToken::Colon))
1754 return X86Operand::CreateReg(RegNo, Start, End);
1756 return ParseIntelSegmentOverride(/*SegReg=*/RegNo, Start, Size);
1760 return ParseIntelMemOperand(/*Disp=*/0, Start, Size);
1763 std::unique_ptr<X86Operand> X86AsmParser::ParseATTOperand() {
1764 MCAsmParser &Parser = getParser();
1765 switch (getLexer().getKind()) {
1767 // Parse a memory operand with no segment register.
1768 return ParseMemOperand(0, Parser.getTok().getLoc());
1769 case AsmToken::Percent: {
1770 // Read the register.
1773 if (ParseRegister(RegNo, Start, End)) return nullptr;
1774 if (RegNo == X86::EIZ || RegNo == X86::RIZ) {
1775 Error(Start, "%eiz and %riz can only be used as index registers",
1776 SMRange(Start, End));
1780 // If this is a segment register followed by a ':', then this is the start
1781 // of a memory reference, otherwise this is a normal register reference.
1782 if (getLexer().isNot(AsmToken::Colon))
1783 return X86Operand::CreateReg(RegNo, Start, End);
1785 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo))
1786 return ErrorOperand(Start, "invalid segment register");
1788 getParser().Lex(); // Eat the colon.
1789 return ParseMemOperand(RegNo, Start);
1791 case AsmToken::Dollar: {
1792 // $42 -> immediate.
1793 SMLoc Start = Parser.getTok().getLoc(), End;
1796 if (getParser().parseExpression(Val, End))
1798 return X86Operand::CreateImm(Val, Start, End);
1800 case AsmToken::LCurly:{
1801 SMLoc Start = Parser.getTok().getLoc(), End;
1802 if (STI.getFeatureBits()[X86::FeatureAVX512])
1803 return ParseRoundingModeOp(Start, End);
1804 return ErrorOperand(Start, "unknown token in expression");
1809 bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands,
1810 const MCParsedAsmOperand &Op) {
1811 MCAsmParser &Parser = getParser();
1812 if(STI.getFeatureBits()[X86::FeatureAVX512]) {
1813 if (getLexer().is(AsmToken::LCurly)) {
1814 // Eat "{" and mark the current place.
1815 const SMLoc consumedToken = consumeToken();
1816 // Distinguish {1to<NUM>} from {%k<NUM>}.
1817 if(getLexer().is(AsmToken::Integer)) {
1818 // Parse memory broadcasting ({1to<NUM>}).
1819 if (getLexer().getTok().getIntVal() != 1)
1820 return !ErrorAndEatStatement(getLexer().getLoc(),
1821 "Expected 1to<NUM> at this point");
1822 Parser.Lex(); // Eat "1" of 1to8
1823 if (!getLexer().is(AsmToken::Identifier) ||
1824 !getLexer().getTok().getIdentifier().startswith("to"))
1825 return !ErrorAndEatStatement(getLexer().getLoc(),
1826 "Expected 1to<NUM> at this point");
1827 // Recognize only reasonable suffixes.
1828 const char *BroadcastPrimitive =
1829 StringSwitch<const char*>(getLexer().getTok().getIdentifier())
1830 .Case("to2", "{1to2}")
1831 .Case("to4", "{1to4}")
1832 .Case("to8", "{1to8}")
1833 .Case("to16", "{1to16}")
1835 if (!BroadcastPrimitive)
1836 return !ErrorAndEatStatement(getLexer().getLoc(),
1837 "Invalid memory broadcast primitive.");
1838 Parser.Lex(); // Eat "toN" of 1toN
1839 if (!getLexer().is(AsmToken::RCurly))
1840 return !ErrorAndEatStatement(getLexer().getLoc(),
1841 "Expected } at this point");
1842 Parser.Lex(); // Eat "}"
1843 Operands.push_back(X86Operand::CreateToken(BroadcastPrimitive,
1845 // No AVX512 specific primitives can pass
1846 // after memory broadcasting, so return.
1849 // Parse mask register {%k1}
1850 Operands.push_back(X86Operand::CreateToken("{", consumedToken));
1851 if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
1852 Operands.push_back(std::move(Op));
1853 if (!getLexer().is(AsmToken::RCurly))
1854 return !ErrorAndEatStatement(getLexer().getLoc(),
1855 "Expected } at this point");
1856 Operands.push_back(X86Operand::CreateToken("}", consumeToken()));
1858 // Parse "zeroing non-masked" semantic {z}
1859 if (getLexer().is(AsmToken::LCurly)) {
1860 Operands.push_back(X86Operand::CreateToken("{z}", consumeToken()));
1861 if (!getLexer().is(AsmToken::Identifier) ||
1862 getLexer().getTok().getIdentifier() != "z")
1863 return !ErrorAndEatStatement(getLexer().getLoc(),
1864 "Expected z at this point");
1865 Parser.Lex(); // Eat the z
1866 if (!getLexer().is(AsmToken::RCurly))
1867 return !ErrorAndEatStatement(getLexer().getLoc(),
1868 "Expected } at this point");
1869 Parser.Lex(); // Eat the }
1878 /// ParseMemOperand: segment: disp(basereg, indexreg, scale). The '%ds:' prefix
1879 /// has already been parsed if present.
1880 std::unique_ptr<X86Operand> X86AsmParser::ParseMemOperand(unsigned SegReg,
1883 MCAsmParser &Parser = getParser();
1884 // We have to disambiguate a parenthesized expression "(4+5)" from the start
1885 // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)". The
1886 // only way to do this without lookahead is to eat the '(' and see what is
1888 const MCExpr *Disp = MCConstantExpr::create(0, getParser().getContext());
1889 if (getLexer().isNot(AsmToken::LParen)) {
1891 if (getParser().parseExpression(Disp, ExprEnd)) return nullptr;
1893 // After parsing the base expression we could either have a parenthesized
1894 // memory address or not. If not, return now. If so, eat the (.
1895 if (getLexer().isNot(AsmToken::LParen)) {
1896 // Unless we have a segment register, treat this as an immediate.
1898 return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, ExprEnd);
1899 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
1906 // Okay, we have a '('. We don't know if this is an expression or not, but
1907 // so we have to eat the ( to see beyond it.
1908 SMLoc LParenLoc = Parser.getTok().getLoc();
1909 Parser.Lex(); // Eat the '('.
1911 if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) {
1912 // Nothing to do here, fall into the code below with the '(' part of the
1913 // memory operand consumed.
1917 // It must be an parenthesized expression, parse it now.
1918 if (getParser().parseParenExpression(Disp, ExprEnd))
1921 // After parsing the base expression we could either have a parenthesized
1922 // memory address or not. If not, return now. If so, eat the (.
1923 if (getLexer().isNot(AsmToken::LParen)) {
1924 // Unless we have a segment register, treat this as an immediate.
1926 return X86Operand::CreateMem(getPointerWidth(), Disp, LParenLoc,
1928 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
1937 // If we reached here, then we just ate the ( of the memory operand. Process
1938 // the rest of the memory operand.
1939 unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
1940 SMLoc IndexLoc, BaseLoc;
1942 if (getLexer().is(AsmToken::Percent)) {
1943 SMLoc StartLoc, EndLoc;
1944 BaseLoc = Parser.getTok().getLoc();
1945 if (ParseRegister(BaseReg, StartLoc, EndLoc)) return nullptr;
1946 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) {
1947 Error(StartLoc, "eiz and riz can only be used as index registers",
1948 SMRange(StartLoc, EndLoc));
1953 if (getLexer().is(AsmToken::Comma)) {
1954 Parser.Lex(); // Eat the comma.
1955 IndexLoc = Parser.getTok().getLoc();
1957 // Following the comma we should have either an index register, or a scale
1958 // value. We don't support the later form, but we want to parse it
1961 // Not that even though it would be completely consistent to support syntax
1962 // like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this.
1963 if (getLexer().is(AsmToken::Percent)) {
1965 if (ParseRegister(IndexReg, L, L)) return nullptr;
1967 if (getLexer().isNot(AsmToken::RParen)) {
1968 // Parse the scale amount:
1969 // ::= ',' [scale-expression]
1970 if (getLexer().isNot(AsmToken::Comma)) {
1971 Error(Parser.getTok().getLoc(),
1972 "expected comma in scale expression");
1975 Parser.Lex(); // Eat the comma.
1977 if (getLexer().isNot(AsmToken::RParen)) {
1978 SMLoc Loc = Parser.getTok().getLoc();
1981 if (getParser().parseAbsoluteExpression(ScaleVal)){
1982 Error(Loc, "expected scale expression");
1986 // Validate the scale amount.
1987 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
1989 Error(Loc, "scale factor in 16-bit address must be 1");
1992 if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8){
1993 Error(Loc, "scale factor in address must be 1, 2, 4 or 8");
1996 Scale = (unsigned)ScaleVal;
1999 } else if (getLexer().isNot(AsmToken::RParen)) {
2000 // A scale amount without an index is ignored.
2002 SMLoc Loc = Parser.getTok().getLoc();
2005 if (getParser().parseAbsoluteExpression(Value))
2009 Warning(Loc, "scale factor without index register is ignored");
2014 // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
2015 if (getLexer().isNot(AsmToken::RParen)) {
2016 Error(Parser.getTok().getLoc(), "unexpected token in memory operand");
2019 SMLoc MemEnd = Parser.getTok().getEndLoc();
2020 Parser.Lex(); // Eat the ')'.
2022 // Check for use of invalid 16-bit registers. Only BX/BP/SI/DI are allowed,
2023 // and then only in non-64-bit modes. Except for DX, which is a special case
2024 // because an unofficial form of in/out instructions uses it.
2025 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
2026 (is64BitMode() || (BaseReg != X86::BX && BaseReg != X86::BP &&
2027 BaseReg != X86::SI && BaseReg != X86::DI)) &&
2028 BaseReg != X86::DX) {
2029 Error(BaseLoc, "invalid 16-bit base register");
2033 X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg)) {
2034 Error(IndexLoc, "16-bit memory operand may not include only index register");
2039 if (CheckBaseRegAndIndexReg(BaseReg, IndexReg, ErrMsg)) {
2040 Error(BaseLoc, ErrMsg);
2044 if (SegReg || BaseReg || IndexReg)
2045 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
2046 IndexReg, Scale, MemStart, MemEnd);
2047 return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, MemEnd);
2050 bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2051 SMLoc NameLoc, OperandVector &Operands) {
2052 MCAsmParser &Parser = getParser();
2054 StringRef PatchedName = Name;
2056 // FIXME: Hack to recognize setneb as setne.
2057 if (PatchedName.startswith("set") && PatchedName.endswith("b") &&
2058 PatchedName != "setb" && PatchedName != "setnb")
2059 PatchedName = PatchedName.substr(0, Name.size()-1);
2061 // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}.
2062 if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) &&
2063 (PatchedName.endswith("ss") || PatchedName.endswith("sd") ||
2064 PatchedName.endswith("ps") || PatchedName.endswith("pd"))) {
2065 bool IsVCMP = PatchedName[0] == 'v';
2066 unsigned CCIdx = IsVCMP ? 4 : 3;
2067 unsigned ComparisonCode = StringSwitch<unsigned>(
2068 PatchedName.slice(CCIdx, PatchedName.size() - 2))
2072 .Case("unord", 0x03)
2077 /* AVX only from here */
2078 .Case("eq_uq", 0x08)
2081 .Case("false", 0x0B)
2082 .Case("neq_oq", 0x0C)
2086 .Case("eq_os", 0x10)
2087 .Case("lt_oq", 0x11)
2088 .Case("le_oq", 0x12)
2089 .Case("unord_s", 0x13)
2090 .Case("neq_us", 0x14)
2091 .Case("nlt_uq", 0x15)
2092 .Case("nle_uq", 0x16)
2093 .Case("ord_s", 0x17)
2094 .Case("eq_us", 0x18)
2095 .Case("nge_uq", 0x19)
2096 .Case("ngt_uq", 0x1A)
2097 .Case("false_os", 0x1B)
2098 .Case("neq_os", 0x1C)
2099 .Case("ge_oq", 0x1D)
2100 .Case("gt_oq", 0x1E)
2101 .Case("true_us", 0x1F)
2103 if (ComparisonCode != ~0U && (IsVCMP || ComparisonCode < 8)) {
2105 Operands.push_back(X86Operand::CreateToken(PatchedName.slice(0, CCIdx),
2108 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2109 getParser().getContext());
2110 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2112 PatchedName = PatchedName.substr(PatchedName.size() - 2);
2116 // FIXME: Hack to recognize vpcmp<comparison code>{ub,uw,ud,uq,b,w,d,q}.
2117 if (PatchedName.startswith("vpcmp") &&
2118 (PatchedName.endswith("b") || PatchedName.endswith("w") ||
2119 PatchedName.endswith("d") || PatchedName.endswith("q"))) {
2120 unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1;
2121 unsigned ComparisonCode = StringSwitch<unsigned>(
2122 PatchedName.slice(5, PatchedName.size() - CCIdx))
2123 .Case("eq", 0x0) // Only allowed on unsigned. Checked below.
2126 //.Case("false", 0x3) // Not a documented alias.
2130 //.Case("true", 0x7) // Not a documented alias.
2132 if (ComparisonCode != ~0U && (ComparisonCode != 0 || CCIdx == 2)) {
2133 Operands.push_back(X86Operand::CreateToken("vpcmp", NameLoc));
2135 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2136 getParser().getContext());
2137 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2139 PatchedName = PatchedName.substr(PatchedName.size() - CCIdx);
2143 // FIXME: Hack to recognize vpcom<comparison code>{ub,uw,ud,uq,b,w,d,q}.
2144 if (PatchedName.startswith("vpcom") &&
2145 (PatchedName.endswith("b") || PatchedName.endswith("w") ||
2146 PatchedName.endswith("d") || PatchedName.endswith("q"))) {
2147 unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1;
2148 unsigned ComparisonCode = StringSwitch<unsigned>(
2149 PatchedName.slice(5, PatchedName.size() - CCIdx))
2159 if (ComparisonCode != ~0U) {
2160 Operands.push_back(X86Operand::CreateToken("vpcom", NameLoc));
2162 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2163 getParser().getContext());
2164 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2166 PatchedName = PatchedName.substr(PatchedName.size() - CCIdx);
2170 Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
2172 // Determine whether this is an instruction prefix.
2174 Name == "lock" || Name == "rep" ||
2175 Name == "repe" || Name == "repz" ||
2176 Name == "repne" || Name == "repnz" ||
2177 Name == "rex64" || Name == "data16";
2180 // This does the actual operand parsing. Don't parse any more if we have a
2181 // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we
2182 // just want to parse the "lock" as the first instruction and the "incl" as
2184 if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) {
2186 // Parse '*' modifier.
2187 if (getLexer().is(AsmToken::Star))
2188 Operands.push_back(X86Operand::CreateToken("*", consumeToken()));
2190 // Read the operands.
2192 if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
2193 Operands.push_back(std::move(Op));
2194 if (!HandleAVX512Operand(Operands, *Operands.back()))
2197 Parser.eatToEndOfStatement();
2200 // check for comma and eat it
2201 if (getLexer().is(AsmToken::Comma))
2207 if (getLexer().isNot(AsmToken::EndOfStatement))
2208 return ErrorAndEatStatement(getLexer().getLoc(),
2209 "unexpected token in argument list");
2212 // Consume the EndOfStatement or the prefix separator Slash
2213 if (getLexer().is(AsmToken::EndOfStatement) ||
2214 (isPrefix && getLexer().is(AsmToken::Slash)))
2217 // This is a terrible hack to handle "out[bwl]? %al, (%dx)" ->
2218 // "outb %al, %dx". Out doesn't take a memory form, but this is a widely
2219 // documented form in various unofficial manuals, so a lot of code uses it.
2220 if ((Name == "outb" || Name == "outw" || Name == "outl" || Name == "out") &&
2221 Operands.size() == 3) {
2222 X86Operand &Op = (X86Operand &)*Operands.back();
2223 if (Op.isMem() && Op.Mem.SegReg == 0 &&
2224 isa<MCConstantExpr>(Op.Mem.Disp) &&
2225 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
2226 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
2227 SMLoc Loc = Op.getEndLoc();
2228 Operands.back() = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
2231 // Same hack for "in[bwl]? (%dx), %al" -> "inb %dx, %al".
2232 if ((Name == "inb" || Name == "inw" || Name == "inl" || Name == "in") &&
2233 Operands.size() == 3) {
2234 X86Operand &Op = (X86Operand &)*Operands[1];
2235 if (Op.isMem() && Op.Mem.SegReg == 0 &&
2236 isa<MCConstantExpr>(Op.Mem.Disp) &&
2237 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
2238 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
2239 SMLoc Loc = Op.getEndLoc();
2240 Operands[1] = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
2244 // Append default arguments to "ins[bwld]"
2245 if (Name.startswith("ins") && Operands.size() == 1 &&
2246 (Name == "insb" || Name == "insw" || Name == "insl" ||
2248 AddDefaultSrcDestOperands(Operands,
2249 X86Operand::CreateReg(X86::DX, NameLoc, NameLoc),
2250 DefaultMemDIOperand(NameLoc));
2253 // Append default arguments to "outs[bwld]"
2254 if (Name.startswith("outs") && Operands.size() == 1 &&
2255 (Name == "outsb" || Name == "outsw" || Name == "outsl" ||
2256 Name == "outsd" )) {
2257 AddDefaultSrcDestOperands(Operands,
2258 DefaultMemSIOperand(NameLoc),
2259 X86Operand::CreateReg(X86::DX, NameLoc, NameLoc));
2262 // Transform "lods[bwlq]" into "lods[bwlq] ($SIREG)" for appropriate
2263 // values of $SIREG according to the mode. It would be nice if this
2264 // could be achieved with InstAlias in the tables.
2265 if (Name.startswith("lods") && Operands.size() == 1 &&
2266 (Name == "lods" || Name == "lodsb" || Name == "lodsw" ||
2267 Name == "lodsl" || Name == "lodsd" || Name == "lodsq"))
2268 Operands.push_back(DefaultMemSIOperand(NameLoc));
2270 // Transform "stos[bwlq]" into "stos[bwlq] ($DIREG)" for appropriate
2271 // values of $DIREG according to the mode. It would be nice if this
2272 // could be achieved with InstAlias in the tables.
2273 if (Name.startswith("stos") && Operands.size() == 1 &&
2274 (Name == "stos" || Name == "stosb" || Name == "stosw" ||
2275 Name == "stosl" || Name == "stosd" || Name == "stosq"))
2276 Operands.push_back(DefaultMemDIOperand(NameLoc));
2278 // Transform "scas[bwlq]" into "scas[bwlq] ($DIREG)" for appropriate
2279 // values of $DIREG according to the mode. It would be nice if this
2280 // could be achieved with InstAlias in the tables.
2281 if (Name.startswith("scas") && Operands.size() == 1 &&
2282 (Name == "scas" || Name == "scasb" || Name == "scasw" ||
2283 Name == "scasl" || Name == "scasd" || Name == "scasq"))
2284 Operands.push_back(DefaultMemDIOperand(NameLoc));
2286 // Add default SI and DI operands to "cmps[bwlq]".
2287 if (Name.startswith("cmps") &&
2288 (Name == "cmps" || Name == "cmpsb" || Name == "cmpsw" ||
2289 Name == "cmpsl" || Name == "cmpsd" || Name == "cmpsq")) {
2290 if (Operands.size() == 1) {
2291 AddDefaultSrcDestOperands(Operands,
2292 DefaultMemDIOperand(NameLoc),
2293 DefaultMemSIOperand(NameLoc));
2294 } else if (Operands.size() == 3) {
2295 X86Operand &Op = (X86Operand &)*Operands[1];
2296 X86Operand &Op2 = (X86Operand &)*Operands[2];
2297 if (!doSrcDstMatch(Op, Op2))
2298 return Error(Op.getStartLoc(),
2299 "mismatching source and destination index registers");
2303 // Add default SI and DI operands to "movs[bwlq]".
2304 if ((Name.startswith("movs") &&
2305 (Name == "movs" || Name == "movsb" || Name == "movsw" ||
2306 Name == "movsl" || Name == "movsd" || Name == "movsq")) ||
2307 (Name.startswith("smov") &&
2308 (Name == "smov" || Name == "smovb" || Name == "smovw" ||
2309 Name == "smovl" || Name == "smovd" || Name == "smovq"))) {
2310 if (Operands.size() == 1) {
2311 if (Name == "movsd")
2312 Operands.back() = X86Operand::CreateToken("movsl", NameLoc);
2313 AddDefaultSrcDestOperands(Operands,
2314 DefaultMemSIOperand(NameLoc),
2315 DefaultMemDIOperand(NameLoc));
2316 } else if (Operands.size() == 3) {
2317 X86Operand &Op = (X86Operand &)*Operands[1];
2318 X86Operand &Op2 = (X86Operand &)*Operands[2];
2319 if (!doSrcDstMatch(Op, Op2))
2320 return Error(Op.getStartLoc(),
2321 "mismatching source and destination index registers");
2325 // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>. Canonicalize to
2327 if ((Name.startswith("shr") || Name.startswith("sar") ||
2328 Name.startswith("shl") || Name.startswith("sal") ||
2329 Name.startswith("rcl") || Name.startswith("rcr") ||
2330 Name.startswith("rol") || Name.startswith("ror")) &&
2331 Operands.size() == 3) {
2332 if (isParsingIntelSyntax()) {
2334 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[2]);
2335 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2336 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2337 Operands.pop_back();
2339 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2340 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2341 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2342 Operands.erase(Operands.begin() + 1);
2346 // Transforms "int $3" into "int3" as a size optimization. We can't write an
2347 // instalias with an immediate operand yet.
2348 if (Name == "int" && Operands.size() == 2) {
2349 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2350 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2351 cast<MCConstantExpr>(Op1.getImm())->getValue() == 3) {
2352 Operands.erase(Operands.begin() + 1);
2353 static_cast<X86Operand &>(*Operands[0]).setTokenValue("int3");
2360 static bool convertToSExti8(MCInst &Inst, unsigned Opcode, unsigned Reg,
2363 TmpInst.setOpcode(Opcode);
2365 TmpInst.addOperand(MCOperand::createReg(Reg));
2366 TmpInst.addOperand(MCOperand::createReg(Reg));
2367 TmpInst.addOperand(Inst.getOperand(0));
2372 static bool convert16i16to16ri8(MCInst &Inst, unsigned Opcode,
2373 bool isCmp = false) {
2374 if (!Inst.getOperand(0).isImm() ||
2375 !isImmSExti16i8Value(Inst.getOperand(0).getImm()))
2378 return convertToSExti8(Inst, Opcode, X86::AX, isCmp);
2381 static bool convert32i32to32ri8(MCInst &Inst, unsigned Opcode,
2382 bool isCmp = false) {
2383 if (!Inst.getOperand(0).isImm() ||
2384 !isImmSExti32i8Value(Inst.getOperand(0).getImm()))
2387 return convertToSExti8(Inst, Opcode, X86::EAX, isCmp);
2390 static bool convert64i32to64ri8(MCInst &Inst, unsigned Opcode,
2391 bool isCmp = false) {
2392 if (!Inst.getOperand(0).isImm() ||
2393 !isImmSExti64i8Value(Inst.getOperand(0).getImm()))
2396 return convertToSExti8(Inst, Opcode, X86::RAX, isCmp);
2399 bool X86AsmParser::validateInstruction(MCInst &Inst, const OperandVector &Ops) {
2400 switch (Inst.getOpcode()) {
2401 default: return true;
2403 X86Operand &Op = static_cast<X86Operand &>(*Ops[1]);
2404 assert(Op.isImm() && "expected immediate");
2406 if (!Op.getImm()->evaluateAsAbsolute(Res) || Res > 255) {
2407 Error(Op.getStartLoc(), "interrupt vector must be in range [0-255]");
2412 llvm_unreachable("handle the instruction appropriately");
2415 bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) {
2416 switch (Inst.getOpcode()) {
2417 default: return false;
2418 case X86::AND16i16: return convert16i16to16ri8(Inst, X86::AND16ri8);
2419 case X86::AND32i32: return convert32i32to32ri8(Inst, X86::AND32ri8);
2420 case X86::AND64i32: return convert64i32to64ri8(Inst, X86::AND64ri8);
2421 case X86::XOR16i16: return convert16i16to16ri8(Inst, X86::XOR16ri8);
2422 case X86::XOR32i32: return convert32i32to32ri8(Inst, X86::XOR32ri8);
2423 case X86::XOR64i32: return convert64i32to64ri8(Inst, X86::XOR64ri8);
2424 case X86::OR16i16: return convert16i16to16ri8(Inst, X86::OR16ri8);
2425 case X86::OR32i32: return convert32i32to32ri8(Inst, X86::OR32ri8);
2426 case X86::OR64i32: return convert64i32to64ri8(Inst, X86::OR64ri8);
2427 case X86::CMP16i16: return convert16i16to16ri8(Inst, X86::CMP16ri8, true);
2428 case X86::CMP32i32: return convert32i32to32ri8(Inst, X86::CMP32ri8, true);
2429 case X86::CMP64i32: return convert64i32to64ri8(Inst, X86::CMP64ri8, true);
2430 case X86::ADD16i16: return convert16i16to16ri8(Inst, X86::ADD16ri8);
2431 case X86::ADD32i32: return convert32i32to32ri8(Inst, X86::ADD32ri8);
2432 case X86::ADD64i32: return convert64i32to64ri8(Inst, X86::ADD64ri8);
2433 case X86::SUB16i16: return convert16i16to16ri8(Inst, X86::SUB16ri8);
2434 case X86::SUB32i32: return convert32i32to32ri8(Inst, X86::SUB32ri8);
2435 case X86::SUB64i32: return convert64i32to64ri8(Inst, X86::SUB64ri8);
2436 case X86::ADC16i16: return convert16i16to16ri8(Inst, X86::ADC16ri8);
2437 case X86::ADC32i32: return convert32i32to32ri8(Inst, X86::ADC32ri8);
2438 case X86::ADC64i32: return convert64i32to64ri8(Inst, X86::ADC64ri8);
2439 case X86::SBB16i16: return convert16i16to16ri8(Inst, X86::SBB16ri8);
2440 case X86::SBB32i32: return convert32i32to32ri8(Inst, X86::SBB32ri8);
2441 case X86::SBB64i32: return convert64i32to64ri8(Inst, X86::SBB64ri8);
2442 case X86::VMOVAPDrr:
2443 case X86::VMOVAPDYrr:
2444 case X86::VMOVAPSrr:
2445 case X86::VMOVAPSYrr:
2446 case X86::VMOVDQArr:
2447 case X86::VMOVDQAYrr:
2448 case X86::VMOVDQUrr:
2449 case X86::VMOVDQUYrr:
2450 case X86::VMOVUPDrr:
2451 case X86::VMOVUPDYrr:
2452 case X86::VMOVUPSrr:
2453 case X86::VMOVUPSYrr: {
2454 if (X86II::isX86_64ExtendedReg(Inst.getOperand(0).getReg()) ||
2455 !X86II::isX86_64ExtendedReg(Inst.getOperand(1).getReg()))
2459 switch (Inst.getOpcode()) {
2460 default: llvm_unreachable("Invalid opcode");
2461 case X86::VMOVAPDrr: NewOpc = X86::VMOVAPDrr_REV; break;
2462 case X86::VMOVAPDYrr: NewOpc = X86::VMOVAPDYrr_REV; break;
2463 case X86::VMOVAPSrr: NewOpc = X86::VMOVAPSrr_REV; break;
2464 case X86::VMOVAPSYrr: NewOpc = X86::VMOVAPSYrr_REV; break;
2465 case X86::VMOVDQArr: NewOpc = X86::VMOVDQArr_REV; break;
2466 case X86::VMOVDQAYrr: NewOpc = X86::VMOVDQAYrr_REV; break;
2467 case X86::VMOVDQUrr: NewOpc = X86::VMOVDQUrr_REV; break;
2468 case X86::VMOVDQUYrr: NewOpc = X86::VMOVDQUYrr_REV; break;
2469 case X86::VMOVUPDrr: NewOpc = X86::VMOVUPDrr_REV; break;
2470 case X86::VMOVUPDYrr: NewOpc = X86::VMOVUPDYrr_REV; break;
2471 case X86::VMOVUPSrr: NewOpc = X86::VMOVUPSrr_REV; break;
2472 case X86::VMOVUPSYrr: NewOpc = X86::VMOVUPSYrr_REV; break;
2474 Inst.setOpcode(NewOpc);
2478 case X86::VMOVSSrr: {
2479 if (X86II::isX86_64ExtendedReg(Inst.getOperand(0).getReg()) ||
2480 !X86II::isX86_64ExtendedReg(Inst.getOperand(2).getReg()))
2483 switch (Inst.getOpcode()) {
2484 default: llvm_unreachable("Invalid opcode");
2485 case X86::VMOVSDrr: NewOpc = X86::VMOVSDrr_REV; break;
2486 case X86::VMOVSSrr: NewOpc = X86::VMOVSSrr_REV; break;
2488 Inst.setOpcode(NewOpc);
2494 static const char *getSubtargetFeatureName(uint64_t Val);
2496 void X86AsmParser::EmitInstruction(MCInst &Inst, OperandVector &Operands,
2498 Instrumentation->InstrumentAndEmitInstruction(Inst, Operands, getContext(),
2502 bool X86AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2503 OperandVector &Operands,
2504 MCStreamer &Out, uint64_t &ErrorInfo,
2505 bool MatchingInlineAsm) {
2506 if (isParsingIntelSyntax())
2507 return MatchAndEmitIntelInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2509 return MatchAndEmitATTInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2513 void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op,
2514 OperandVector &Operands, MCStreamer &Out,
2515 bool MatchingInlineAsm) {
2516 // FIXME: This should be replaced with a real .td file alias mechanism.
2517 // Also, MatchInstructionImpl should actually *do* the EmitInstruction
2519 const char *Repl = StringSwitch<const char *>(Op.getToken())
2520 .Case("finit", "fninit")
2521 .Case("fsave", "fnsave")
2522 .Case("fstcw", "fnstcw")
2523 .Case("fstcww", "fnstcw")
2524 .Case("fstenv", "fnstenv")
2525 .Case("fstsw", "fnstsw")
2526 .Case("fstsww", "fnstsw")
2527 .Case("fclex", "fnclex")
2531 Inst.setOpcode(X86::WAIT);
2533 if (!MatchingInlineAsm)
2534 EmitInstruction(Inst, Operands, Out);
2535 Operands[0] = X86Operand::CreateToken(Repl, IDLoc);
2539 bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
2540 bool MatchingInlineAsm) {
2541 assert(ErrorInfo && "Unknown missing feature!");
2542 ArrayRef<SMRange> EmptyRanges = None;
2543 SmallString<126> Msg;
2544 raw_svector_ostream OS(Msg);
2545 OS << "instruction requires:";
2547 for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
2548 if (ErrorInfo & Mask)
2549 OS << ' ' << getSubtargetFeatureName(ErrorInfo & Mask);
2552 return Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
2555 bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
2556 OperandVector &Operands,
2558 uint64_t &ErrorInfo,
2559 bool MatchingInlineAsm) {
2560 assert(!Operands.empty() && "Unexpect empty operand list!");
2561 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2562 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
2563 ArrayRef<SMRange> EmptyRanges = None;
2565 // First, handle aliases that expand to multiple instructions.
2566 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2568 bool WasOriginallyInvalidOperand = false;
2571 // First, try a direct match.
2572 switch (MatchInstructionImpl(Operands, Inst,
2573 ErrorInfo, MatchingInlineAsm,
2574 isParsingIntelSyntax())) {
2575 default: llvm_unreachable("Unexpected match result!");
2577 if (!validateInstruction(Inst, Operands))
2580 // Some instructions need post-processing to, for example, tweak which
2581 // encoding is selected. Loop on it while changes happen so the
2582 // individual transformations can chain off each other.
2583 if (!MatchingInlineAsm)
2584 while (processInstruction(Inst, Operands))
2588 if (!MatchingInlineAsm)
2589 EmitInstruction(Inst, Operands, Out);
2590 Opcode = Inst.getOpcode();
2592 case Match_MissingFeature:
2593 return ErrorMissingFeature(IDLoc, ErrorInfo, MatchingInlineAsm);
2594 case Match_InvalidOperand:
2595 WasOriginallyInvalidOperand = true;
2597 case Match_MnemonicFail:
2601 // FIXME: Ideally, we would only attempt suffix matches for things which are
2602 // valid prefixes, and we could just infer the right unambiguous
2603 // type. However, that requires substantially more matcher support than the
2606 // Change the operand to point to a temporary token.
2607 StringRef Base = Op.getToken();
2608 SmallString<16> Tmp;
2611 Op.setTokenValue(Tmp);
2613 // If this instruction starts with an 'f', then it is a floating point stack
2614 // instruction. These come in up to three forms for 32-bit, 64-bit, and
2615 // 80-bit floating point, which use the suffixes s,l,t respectively.
2617 // Otherwise, we assume that this may be an integer instruction, which comes
2618 // in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively.
2619 const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0";
2621 // Check for the various suffix matches.
2622 uint64_t ErrorInfoIgnore;
2623 uint64_t ErrorInfoMissingFeature = 0; // Init suppresses compiler warnings.
2626 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I) {
2627 Tmp.back() = Suffixes[I];
2628 Match[I] = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
2629 MatchingInlineAsm, isParsingIntelSyntax());
2630 // If this returned as a missing feature failure, remember that.
2631 if (Match[I] == Match_MissingFeature)
2632 ErrorInfoMissingFeature = ErrorInfoIgnore;
2635 // Restore the old token.
2636 Op.setTokenValue(Base);
2638 // If exactly one matched, then we treat that as a successful match (and the
2639 // instruction will already have been filled in correctly, since the failing
2640 // matches won't have modified it).
2641 unsigned NumSuccessfulMatches =
2642 std::count(std::begin(Match), std::end(Match), Match_Success);
2643 if (NumSuccessfulMatches == 1) {
2645 if (!MatchingInlineAsm)
2646 EmitInstruction(Inst, Operands, Out);
2647 Opcode = Inst.getOpcode();
2651 // Otherwise, the match failed, try to produce a decent error message.
2653 // If we had multiple suffix matches, then identify this as an ambiguous
2655 if (NumSuccessfulMatches > 1) {
2657 unsigned NumMatches = 0;
2658 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I)
2659 if (Match[I] == Match_Success)
2660 MatchChars[NumMatches++] = Suffixes[I];
2662 SmallString<126> Msg;
2663 raw_svector_ostream OS(Msg);
2664 OS << "ambiguous instructions require an explicit suffix (could be ";
2665 for (unsigned i = 0; i != NumMatches; ++i) {
2668 if (i + 1 == NumMatches)
2670 OS << "'" << Base << MatchChars[i] << "'";
2673 Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
2677 // Okay, we know that none of the variants matched successfully.
2679 // If all of the instructions reported an invalid mnemonic, then the original
2680 // mnemonic was invalid.
2681 if (std::count(std::begin(Match), std::end(Match), Match_MnemonicFail) == 4) {
2682 if (!WasOriginallyInvalidOperand) {
2683 ArrayRef<SMRange> Ranges =
2684 MatchingInlineAsm ? EmptyRanges : Op.getLocRange();
2685 return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'",
2686 Ranges, MatchingInlineAsm);
2689 // Recover location info for the operand if we know which was the problem.
2690 if (ErrorInfo != ~0ULL) {
2691 if (ErrorInfo >= Operands.size())
2692 return Error(IDLoc, "too few operands for instruction",
2693 EmptyRanges, MatchingInlineAsm);
2695 X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo];
2696 if (Operand.getStartLoc().isValid()) {
2697 SMRange OperandRange = Operand.getLocRange();
2698 return Error(Operand.getStartLoc(), "invalid operand for instruction",
2699 OperandRange, MatchingInlineAsm);
2703 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2707 // If one instruction matched with a missing feature, report this as a
2709 if (std::count(std::begin(Match), std::end(Match),
2710 Match_MissingFeature) == 1) {
2711 ErrorInfo = ErrorInfoMissingFeature;
2712 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
2716 // If one instruction matched with an invalid operand, report this as an
2718 if (std::count(std::begin(Match), std::end(Match),
2719 Match_InvalidOperand) == 1) {
2720 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2724 // If all of these were an outright failure, report it in a useless way.
2725 Error(IDLoc, "unknown use of instruction mnemonic without a size suffix",
2726 EmptyRanges, MatchingInlineAsm);
2730 bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
2731 OperandVector &Operands,
2733 uint64_t &ErrorInfo,
2734 bool MatchingInlineAsm) {
2735 assert(!Operands.empty() && "Unexpect empty operand list!");
2736 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2737 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
2738 StringRef Mnemonic = Op.getToken();
2739 ArrayRef<SMRange> EmptyRanges = None;
2741 // First, handle aliases that expand to multiple instructions.
2742 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2746 // Find one unsized memory operand, if present.
2747 X86Operand *UnsizedMemOp = nullptr;
2748 for (const auto &Op : Operands) {
2749 X86Operand *X86Op = static_cast<X86Operand *>(Op.get());
2750 if (X86Op->isMemUnsized())
2751 UnsizedMemOp = X86Op;
2754 // Allow some instructions to have implicitly pointer-sized operands. This is
2755 // compatible with gas.
2757 static const char *const PtrSizedInstrs[] = {"call", "jmp", "push"};
2758 for (const char *Instr : PtrSizedInstrs) {
2759 if (Mnemonic == Instr) {
2760 UnsizedMemOp->Mem.Size = getPointerWidth();
2766 // If an unsized memory operand is present, try to match with each memory
2767 // operand size. In Intel assembly, the size is not part of the instruction
2769 SmallVector<unsigned, 8> Match;
2770 uint64_t ErrorInfoMissingFeature = 0;
2771 if (UnsizedMemOp && UnsizedMemOp->isMemUnsized()) {
2772 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
2773 for (unsigned Size : MopSizes) {
2774 UnsizedMemOp->Mem.Size = Size;
2775 uint64_t ErrorInfoIgnore;
2776 unsigned LastOpcode = Inst.getOpcode();
2778 MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
2779 MatchingInlineAsm, isParsingIntelSyntax());
2780 if (Match.empty() || LastOpcode != Inst.getOpcode())
2783 // If this returned as a missing feature failure, remember that.
2784 if (Match.back() == Match_MissingFeature)
2785 ErrorInfoMissingFeature = ErrorInfoIgnore;
2788 // Restore the size of the unsized memory operand if we modified it.
2790 UnsizedMemOp->Mem.Size = 0;
2793 // If we haven't matched anything yet, this is not a basic integer or FPU
2794 // operation. There shouldn't be any ambiguity in our mnemonic table, so try
2795 // matching with the unsized operand.
2796 if (Match.empty()) {
2797 Match.push_back(MatchInstructionImpl(Operands, Inst, ErrorInfo,
2799 isParsingIntelSyntax()));
2800 // If this returned as a missing feature failure, remember that.
2801 if (Match.back() == Match_MissingFeature)
2802 ErrorInfoMissingFeature = ErrorInfo;
2805 // Restore the size of the unsized memory operand if we modified it.
2807 UnsizedMemOp->Mem.Size = 0;
2809 // If it's a bad mnemonic, all results will be the same.
2810 if (Match.back() == Match_MnemonicFail) {
2811 ArrayRef<SMRange> Ranges =
2812 MatchingInlineAsm ? EmptyRanges : Op.getLocRange();
2813 return Error(IDLoc, "invalid instruction mnemonic '" + Mnemonic + "'",
2814 Ranges, MatchingInlineAsm);
2817 // If exactly one matched, then we treat that as a successful match (and the
2818 // instruction will already have been filled in correctly, since the failing
2819 // matches won't have modified it).
2820 unsigned NumSuccessfulMatches =
2821 std::count(std::begin(Match), std::end(Match), Match_Success);
2822 if (NumSuccessfulMatches == 1) {
2823 if (!validateInstruction(Inst, Operands))
2826 // Some instructions need post-processing to, for example, tweak which
2827 // encoding is selected. Loop on it while changes happen so the individual
2828 // transformations can chain off each other.
2829 if (!MatchingInlineAsm)
2830 while (processInstruction(Inst, Operands))
2833 if (!MatchingInlineAsm)
2834 EmitInstruction(Inst, Operands, Out);
2835 Opcode = Inst.getOpcode();
2837 } else if (NumSuccessfulMatches > 1) {
2838 assert(UnsizedMemOp &&
2839 "multiple matches only possible with unsized memory operands");
2840 ArrayRef<SMRange> Ranges =
2841 MatchingInlineAsm ? EmptyRanges : UnsizedMemOp->getLocRange();
2842 return Error(UnsizedMemOp->getStartLoc(),
2843 "ambiguous operand size for instruction '" + Mnemonic + "\'",
2844 Ranges, MatchingInlineAsm);
2847 // If one instruction matched with a missing feature, report this as a
2849 if (std::count(std::begin(Match), std::end(Match),
2850 Match_MissingFeature) == 1) {
2851 ErrorInfo = ErrorInfoMissingFeature;
2852 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
2856 // If one instruction matched with an invalid operand, report this as an
2858 if (std::count(std::begin(Match), std::end(Match),
2859 Match_InvalidOperand) == 1) {
2860 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2864 // If all of these were an outright failure, report it in a useless way.
2865 return Error(IDLoc, "unknown instruction mnemonic", EmptyRanges,
2869 bool X86AsmParser::OmitRegisterFromClobberLists(unsigned RegNo) {
2870 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo);
2873 bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
2874 MCAsmParser &Parser = getParser();
2875 StringRef IDVal = DirectiveID.getIdentifier();
2876 if (IDVal == ".word")
2877 return ParseDirectiveWord(2, DirectiveID.getLoc());
2878 else if (IDVal.startswith(".code"))
2879 return ParseDirectiveCode(IDVal, DirectiveID.getLoc());
2880 else if (IDVal.startswith(".att_syntax")) {
2881 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2882 if (Parser.getTok().getString() == "prefix")
2884 else if (Parser.getTok().getString() == "noprefix")
2885 return Error(DirectiveID.getLoc(), "'.att_syntax noprefix' is not "
2886 "supported: registers must have a "
2887 "'%' prefix in .att_syntax");
2889 getParser().setAssemblerDialect(0);
2891 } else if (IDVal.startswith(".intel_syntax")) {
2892 getParser().setAssemblerDialect(1);
2893 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2894 if (Parser.getTok().getString() == "noprefix")
2896 else if (Parser.getTok().getString() == "prefix")
2897 return Error(DirectiveID.getLoc(), "'.intel_syntax prefix' is not "
2898 "supported: registers must not have "
2899 "a '%' prefix in .intel_syntax");
2906 /// ParseDirectiveWord
2907 /// ::= .word [ expression (, expression)* ]
2908 bool X86AsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
2909 MCAsmParser &Parser = getParser();
2910 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2912 const MCExpr *Value;
2913 if (getParser().parseExpression(Value))
2916 getParser().getStreamer().EmitValue(Value, Size);
2918 if (getLexer().is(AsmToken::EndOfStatement))
2921 // FIXME: Improve diagnostic.
2922 if (getLexer().isNot(AsmToken::Comma)) {
2923 Error(L, "unexpected token in directive");
2934 /// ParseDirectiveCode
2935 /// ::= .code16 | .code32 | .code64
2936 bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
2937 MCAsmParser &Parser = getParser();
2938 if (IDVal == ".code16") {
2940 if (!is16BitMode()) {
2941 SwitchMode(X86::Mode16Bit);
2942 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
2944 } else if (IDVal == ".code32") {
2946 if (!is32BitMode()) {
2947 SwitchMode(X86::Mode32Bit);
2948 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
2950 } else if (IDVal == ".code64") {
2952 if (!is64BitMode()) {
2953 SwitchMode(X86::Mode64Bit);
2954 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code64);
2957 Error(L, "unknown directive " + IDVal);
2964 // Force static initialization.
2965 extern "C" void LLVMInitializeX86AsmParser() {
2966 RegisterMCAsmParser<X86AsmParser> X(TheX86_32Target);
2967 RegisterMCAsmParser<X86AsmParser> Y(TheX86_64Target);
2970 #define GET_REGISTER_MATCHER
2971 #define GET_MATCHER_IMPLEMENTATION
2972 #define GET_SUBTARGET_FEATURE_NAME
2973 #include "X86GenAsmMatcher.inc"