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]);
2351 if (auto *CE = dyn_cast<MCConstantExpr>(Op1.getImm()))
2352 if (CE->getValue() == 3) {
2353 Operands.erase(Operands.begin() + 1);
2354 static_cast<X86Operand &>(*Operands[0]).setTokenValue("int3");
2361 static bool convertToSExti8(MCInst &Inst, unsigned Opcode, unsigned Reg,
2364 TmpInst.setOpcode(Opcode);
2366 TmpInst.addOperand(MCOperand::createReg(Reg));
2367 TmpInst.addOperand(MCOperand::createReg(Reg));
2368 TmpInst.addOperand(Inst.getOperand(0));
2373 static bool convert16i16to16ri8(MCInst &Inst, unsigned Opcode,
2374 bool isCmp = false) {
2375 if (!Inst.getOperand(0).isImm() ||
2376 !isImmSExti16i8Value(Inst.getOperand(0).getImm()))
2379 return convertToSExti8(Inst, Opcode, X86::AX, isCmp);
2382 static bool convert32i32to32ri8(MCInst &Inst, unsigned Opcode,
2383 bool isCmp = false) {
2384 if (!Inst.getOperand(0).isImm() ||
2385 !isImmSExti32i8Value(Inst.getOperand(0).getImm()))
2388 return convertToSExti8(Inst, Opcode, X86::EAX, isCmp);
2391 static bool convert64i32to64ri8(MCInst &Inst, unsigned Opcode,
2392 bool isCmp = false) {
2393 if (!Inst.getOperand(0).isImm() ||
2394 !isImmSExti64i8Value(Inst.getOperand(0).getImm()))
2397 return convertToSExti8(Inst, Opcode, X86::RAX, isCmp);
2400 bool X86AsmParser::validateInstruction(MCInst &Inst, const OperandVector &Ops) {
2401 switch (Inst.getOpcode()) {
2402 default: return true;
2404 X86Operand &Op = static_cast<X86Operand &>(*Ops[1]);
2405 assert(Op.isImm() && "expected immediate");
2407 if (!Op.getImm()->evaluateAsAbsolute(Res) || Res > 255) {
2408 Error(Op.getStartLoc(), "interrupt vector must be in range [0-255]");
2413 llvm_unreachable("handle the instruction appropriately");
2416 bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) {
2417 switch (Inst.getOpcode()) {
2418 default: return false;
2419 case X86::AND16i16: return convert16i16to16ri8(Inst, X86::AND16ri8);
2420 case X86::AND32i32: return convert32i32to32ri8(Inst, X86::AND32ri8);
2421 case X86::AND64i32: return convert64i32to64ri8(Inst, X86::AND64ri8);
2422 case X86::XOR16i16: return convert16i16to16ri8(Inst, X86::XOR16ri8);
2423 case X86::XOR32i32: return convert32i32to32ri8(Inst, X86::XOR32ri8);
2424 case X86::XOR64i32: return convert64i32to64ri8(Inst, X86::XOR64ri8);
2425 case X86::OR16i16: return convert16i16to16ri8(Inst, X86::OR16ri8);
2426 case X86::OR32i32: return convert32i32to32ri8(Inst, X86::OR32ri8);
2427 case X86::OR64i32: return convert64i32to64ri8(Inst, X86::OR64ri8);
2428 case X86::CMP16i16: return convert16i16to16ri8(Inst, X86::CMP16ri8, true);
2429 case X86::CMP32i32: return convert32i32to32ri8(Inst, X86::CMP32ri8, true);
2430 case X86::CMP64i32: return convert64i32to64ri8(Inst, X86::CMP64ri8, true);
2431 case X86::ADD16i16: return convert16i16to16ri8(Inst, X86::ADD16ri8);
2432 case X86::ADD32i32: return convert32i32to32ri8(Inst, X86::ADD32ri8);
2433 case X86::ADD64i32: return convert64i32to64ri8(Inst, X86::ADD64ri8);
2434 case X86::SUB16i16: return convert16i16to16ri8(Inst, X86::SUB16ri8);
2435 case X86::SUB32i32: return convert32i32to32ri8(Inst, X86::SUB32ri8);
2436 case X86::SUB64i32: return convert64i32to64ri8(Inst, X86::SUB64ri8);
2437 case X86::ADC16i16: return convert16i16to16ri8(Inst, X86::ADC16ri8);
2438 case X86::ADC32i32: return convert32i32to32ri8(Inst, X86::ADC32ri8);
2439 case X86::ADC64i32: return convert64i32to64ri8(Inst, X86::ADC64ri8);
2440 case X86::SBB16i16: return convert16i16to16ri8(Inst, X86::SBB16ri8);
2441 case X86::SBB32i32: return convert32i32to32ri8(Inst, X86::SBB32ri8);
2442 case X86::SBB64i32: return convert64i32to64ri8(Inst, X86::SBB64ri8);
2443 case X86::VMOVAPDrr:
2444 case X86::VMOVAPDYrr:
2445 case X86::VMOVAPSrr:
2446 case X86::VMOVAPSYrr:
2447 case X86::VMOVDQArr:
2448 case X86::VMOVDQAYrr:
2449 case X86::VMOVDQUrr:
2450 case X86::VMOVDQUYrr:
2451 case X86::VMOVUPDrr:
2452 case X86::VMOVUPDYrr:
2453 case X86::VMOVUPSrr:
2454 case X86::VMOVUPSYrr: {
2455 if (X86II::isX86_64ExtendedReg(Inst.getOperand(0).getReg()) ||
2456 !X86II::isX86_64ExtendedReg(Inst.getOperand(1).getReg()))
2460 switch (Inst.getOpcode()) {
2461 default: llvm_unreachable("Invalid opcode");
2462 case X86::VMOVAPDrr: NewOpc = X86::VMOVAPDrr_REV; break;
2463 case X86::VMOVAPDYrr: NewOpc = X86::VMOVAPDYrr_REV; break;
2464 case X86::VMOVAPSrr: NewOpc = X86::VMOVAPSrr_REV; break;
2465 case X86::VMOVAPSYrr: NewOpc = X86::VMOVAPSYrr_REV; break;
2466 case X86::VMOVDQArr: NewOpc = X86::VMOVDQArr_REV; break;
2467 case X86::VMOVDQAYrr: NewOpc = X86::VMOVDQAYrr_REV; break;
2468 case X86::VMOVDQUrr: NewOpc = X86::VMOVDQUrr_REV; break;
2469 case X86::VMOVDQUYrr: NewOpc = X86::VMOVDQUYrr_REV; break;
2470 case X86::VMOVUPDrr: NewOpc = X86::VMOVUPDrr_REV; break;
2471 case X86::VMOVUPDYrr: NewOpc = X86::VMOVUPDYrr_REV; break;
2472 case X86::VMOVUPSrr: NewOpc = X86::VMOVUPSrr_REV; break;
2473 case X86::VMOVUPSYrr: NewOpc = X86::VMOVUPSYrr_REV; break;
2475 Inst.setOpcode(NewOpc);
2479 case X86::VMOVSSrr: {
2480 if (X86II::isX86_64ExtendedReg(Inst.getOperand(0).getReg()) ||
2481 !X86II::isX86_64ExtendedReg(Inst.getOperand(2).getReg()))
2484 switch (Inst.getOpcode()) {
2485 default: llvm_unreachable("Invalid opcode");
2486 case X86::VMOVSDrr: NewOpc = X86::VMOVSDrr_REV; break;
2487 case X86::VMOVSSrr: NewOpc = X86::VMOVSSrr_REV; break;
2489 Inst.setOpcode(NewOpc);
2495 static const char *getSubtargetFeatureName(uint64_t Val);
2497 void X86AsmParser::EmitInstruction(MCInst &Inst, OperandVector &Operands,
2499 Instrumentation->InstrumentAndEmitInstruction(Inst, Operands, getContext(),
2503 bool X86AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2504 OperandVector &Operands,
2505 MCStreamer &Out, uint64_t &ErrorInfo,
2506 bool MatchingInlineAsm) {
2507 if (isParsingIntelSyntax())
2508 return MatchAndEmitIntelInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2510 return MatchAndEmitATTInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2514 void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op,
2515 OperandVector &Operands, MCStreamer &Out,
2516 bool MatchingInlineAsm) {
2517 // FIXME: This should be replaced with a real .td file alias mechanism.
2518 // Also, MatchInstructionImpl should actually *do* the EmitInstruction
2520 const char *Repl = StringSwitch<const char *>(Op.getToken())
2521 .Case("finit", "fninit")
2522 .Case("fsave", "fnsave")
2523 .Case("fstcw", "fnstcw")
2524 .Case("fstcww", "fnstcw")
2525 .Case("fstenv", "fnstenv")
2526 .Case("fstsw", "fnstsw")
2527 .Case("fstsww", "fnstsw")
2528 .Case("fclex", "fnclex")
2532 Inst.setOpcode(X86::WAIT);
2534 if (!MatchingInlineAsm)
2535 EmitInstruction(Inst, Operands, Out);
2536 Operands[0] = X86Operand::CreateToken(Repl, IDLoc);
2540 bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
2541 bool MatchingInlineAsm) {
2542 assert(ErrorInfo && "Unknown missing feature!");
2543 ArrayRef<SMRange> EmptyRanges = None;
2544 SmallString<126> Msg;
2545 raw_svector_ostream OS(Msg);
2546 OS << "instruction requires:";
2548 for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
2549 if (ErrorInfo & Mask)
2550 OS << ' ' << getSubtargetFeatureName(ErrorInfo & Mask);
2553 return Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
2556 bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
2557 OperandVector &Operands,
2559 uint64_t &ErrorInfo,
2560 bool MatchingInlineAsm) {
2561 assert(!Operands.empty() && "Unexpect empty operand list!");
2562 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2563 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
2564 ArrayRef<SMRange> EmptyRanges = None;
2566 // First, handle aliases that expand to multiple instructions.
2567 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2569 bool WasOriginallyInvalidOperand = false;
2572 // First, try a direct match.
2573 switch (MatchInstructionImpl(Operands, Inst,
2574 ErrorInfo, MatchingInlineAsm,
2575 isParsingIntelSyntax())) {
2576 default: llvm_unreachable("Unexpected match result!");
2578 if (!validateInstruction(Inst, Operands))
2581 // Some instructions need post-processing to, for example, tweak which
2582 // encoding is selected. Loop on it while changes happen so the
2583 // individual transformations can chain off each other.
2584 if (!MatchingInlineAsm)
2585 while (processInstruction(Inst, Operands))
2589 if (!MatchingInlineAsm)
2590 EmitInstruction(Inst, Operands, Out);
2591 Opcode = Inst.getOpcode();
2593 case Match_MissingFeature:
2594 return ErrorMissingFeature(IDLoc, ErrorInfo, MatchingInlineAsm);
2595 case Match_InvalidOperand:
2596 WasOriginallyInvalidOperand = true;
2598 case Match_MnemonicFail:
2602 // FIXME: Ideally, we would only attempt suffix matches for things which are
2603 // valid prefixes, and we could just infer the right unambiguous
2604 // type. However, that requires substantially more matcher support than the
2607 // Change the operand to point to a temporary token.
2608 StringRef Base = Op.getToken();
2609 SmallString<16> Tmp;
2612 Op.setTokenValue(Tmp);
2614 // If this instruction starts with an 'f', then it is a floating point stack
2615 // instruction. These come in up to three forms for 32-bit, 64-bit, and
2616 // 80-bit floating point, which use the suffixes s,l,t respectively.
2618 // Otherwise, we assume that this may be an integer instruction, which comes
2619 // in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively.
2620 const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0";
2622 // Check for the various suffix matches.
2623 uint64_t ErrorInfoIgnore;
2624 uint64_t ErrorInfoMissingFeature = 0; // Init suppresses compiler warnings.
2627 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I) {
2628 Tmp.back() = Suffixes[I];
2629 Match[I] = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
2630 MatchingInlineAsm, isParsingIntelSyntax());
2631 // If this returned as a missing feature failure, remember that.
2632 if (Match[I] == Match_MissingFeature)
2633 ErrorInfoMissingFeature = ErrorInfoIgnore;
2636 // Restore the old token.
2637 Op.setTokenValue(Base);
2639 // If exactly one matched, then we treat that as a successful match (and the
2640 // instruction will already have been filled in correctly, since the failing
2641 // matches won't have modified it).
2642 unsigned NumSuccessfulMatches =
2643 std::count(std::begin(Match), std::end(Match), Match_Success);
2644 if (NumSuccessfulMatches == 1) {
2646 if (!MatchingInlineAsm)
2647 EmitInstruction(Inst, Operands, Out);
2648 Opcode = Inst.getOpcode();
2652 // Otherwise, the match failed, try to produce a decent error message.
2654 // If we had multiple suffix matches, then identify this as an ambiguous
2656 if (NumSuccessfulMatches > 1) {
2658 unsigned NumMatches = 0;
2659 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I)
2660 if (Match[I] == Match_Success)
2661 MatchChars[NumMatches++] = Suffixes[I];
2663 SmallString<126> Msg;
2664 raw_svector_ostream OS(Msg);
2665 OS << "ambiguous instructions require an explicit suffix (could be ";
2666 for (unsigned i = 0; i != NumMatches; ++i) {
2669 if (i + 1 == NumMatches)
2671 OS << "'" << Base << MatchChars[i] << "'";
2674 Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
2678 // Okay, we know that none of the variants matched successfully.
2680 // If all of the instructions reported an invalid mnemonic, then the original
2681 // mnemonic was invalid.
2682 if (std::count(std::begin(Match), std::end(Match), Match_MnemonicFail) == 4) {
2683 if (!WasOriginallyInvalidOperand) {
2684 ArrayRef<SMRange> Ranges =
2685 MatchingInlineAsm ? EmptyRanges : Op.getLocRange();
2686 return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'",
2687 Ranges, MatchingInlineAsm);
2690 // Recover location info for the operand if we know which was the problem.
2691 if (ErrorInfo != ~0ULL) {
2692 if (ErrorInfo >= Operands.size())
2693 return Error(IDLoc, "too few operands for instruction",
2694 EmptyRanges, MatchingInlineAsm);
2696 X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo];
2697 if (Operand.getStartLoc().isValid()) {
2698 SMRange OperandRange = Operand.getLocRange();
2699 return Error(Operand.getStartLoc(), "invalid operand for instruction",
2700 OperandRange, MatchingInlineAsm);
2704 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2708 // If one instruction matched with a missing feature, report this as a
2710 if (std::count(std::begin(Match), std::end(Match),
2711 Match_MissingFeature) == 1) {
2712 ErrorInfo = ErrorInfoMissingFeature;
2713 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
2717 // If one instruction matched with an invalid operand, report this as an
2719 if (std::count(std::begin(Match), std::end(Match),
2720 Match_InvalidOperand) == 1) {
2721 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2725 // If all of these were an outright failure, report it in a useless way.
2726 Error(IDLoc, "unknown use of instruction mnemonic without a size suffix",
2727 EmptyRanges, MatchingInlineAsm);
2731 bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
2732 OperandVector &Operands,
2734 uint64_t &ErrorInfo,
2735 bool MatchingInlineAsm) {
2736 assert(!Operands.empty() && "Unexpect empty operand list!");
2737 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2738 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
2739 StringRef Mnemonic = Op.getToken();
2740 ArrayRef<SMRange> EmptyRanges = None;
2742 // First, handle aliases that expand to multiple instructions.
2743 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2747 // Find one unsized memory operand, if present.
2748 X86Operand *UnsizedMemOp = nullptr;
2749 for (const auto &Op : Operands) {
2750 X86Operand *X86Op = static_cast<X86Operand *>(Op.get());
2751 if (X86Op->isMemUnsized())
2752 UnsizedMemOp = X86Op;
2755 // Allow some instructions to have implicitly pointer-sized operands. This is
2756 // compatible with gas.
2758 static const char *const PtrSizedInstrs[] = {"call", "jmp", "push"};
2759 for (const char *Instr : PtrSizedInstrs) {
2760 if (Mnemonic == Instr) {
2761 UnsizedMemOp->Mem.Size = getPointerWidth();
2767 // If an unsized memory operand is present, try to match with each memory
2768 // operand size. In Intel assembly, the size is not part of the instruction
2770 SmallVector<unsigned, 8> Match;
2771 uint64_t ErrorInfoMissingFeature = 0;
2772 if (UnsizedMemOp && UnsizedMemOp->isMemUnsized()) {
2773 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
2774 for (unsigned Size : MopSizes) {
2775 UnsizedMemOp->Mem.Size = Size;
2776 uint64_t ErrorInfoIgnore;
2777 unsigned LastOpcode = Inst.getOpcode();
2779 MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
2780 MatchingInlineAsm, isParsingIntelSyntax());
2781 if (Match.empty() || LastOpcode != Inst.getOpcode())
2784 // If this returned as a missing feature failure, remember that.
2785 if (Match.back() == Match_MissingFeature)
2786 ErrorInfoMissingFeature = ErrorInfoIgnore;
2789 // Restore the size of the unsized memory operand if we modified it.
2791 UnsizedMemOp->Mem.Size = 0;
2794 // If we haven't matched anything yet, this is not a basic integer or FPU
2795 // operation. There shouldn't be any ambiguity in our mnemonic table, so try
2796 // matching with the unsized operand.
2797 if (Match.empty()) {
2798 Match.push_back(MatchInstructionImpl(Operands, Inst, ErrorInfo,
2800 isParsingIntelSyntax()));
2801 // If this returned as a missing feature failure, remember that.
2802 if (Match.back() == Match_MissingFeature)
2803 ErrorInfoMissingFeature = ErrorInfo;
2806 // Restore the size of the unsized memory operand if we modified it.
2808 UnsizedMemOp->Mem.Size = 0;
2810 // If it's a bad mnemonic, all results will be the same.
2811 if (Match.back() == Match_MnemonicFail) {
2812 ArrayRef<SMRange> Ranges =
2813 MatchingInlineAsm ? EmptyRanges : Op.getLocRange();
2814 return Error(IDLoc, "invalid instruction mnemonic '" + Mnemonic + "'",
2815 Ranges, MatchingInlineAsm);
2818 // If exactly one matched, then we treat that as a successful match (and the
2819 // instruction will already have been filled in correctly, since the failing
2820 // matches won't have modified it).
2821 unsigned NumSuccessfulMatches =
2822 std::count(std::begin(Match), std::end(Match), Match_Success);
2823 if (NumSuccessfulMatches == 1) {
2824 if (!validateInstruction(Inst, Operands))
2827 // Some instructions need post-processing to, for example, tweak which
2828 // encoding is selected. Loop on it while changes happen so the individual
2829 // transformations can chain off each other.
2830 if (!MatchingInlineAsm)
2831 while (processInstruction(Inst, Operands))
2834 if (!MatchingInlineAsm)
2835 EmitInstruction(Inst, Operands, Out);
2836 Opcode = Inst.getOpcode();
2838 } else if (NumSuccessfulMatches > 1) {
2839 assert(UnsizedMemOp &&
2840 "multiple matches only possible with unsized memory operands");
2841 ArrayRef<SMRange> Ranges =
2842 MatchingInlineAsm ? EmptyRanges : UnsizedMemOp->getLocRange();
2843 return Error(UnsizedMemOp->getStartLoc(),
2844 "ambiguous operand size for instruction '" + Mnemonic + "\'",
2845 Ranges, MatchingInlineAsm);
2848 // If one instruction matched with a missing feature, report this as a
2850 if (std::count(std::begin(Match), std::end(Match),
2851 Match_MissingFeature) == 1) {
2852 ErrorInfo = ErrorInfoMissingFeature;
2853 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
2857 // If one instruction matched with an invalid operand, report this as an
2859 if (std::count(std::begin(Match), std::end(Match),
2860 Match_InvalidOperand) == 1) {
2861 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2865 // If all of these were an outright failure, report it in a useless way.
2866 return Error(IDLoc, "unknown instruction mnemonic", EmptyRanges,
2870 bool X86AsmParser::OmitRegisterFromClobberLists(unsigned RegNo) {
2871 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo);
2874 bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
2875 MCAsmParser &Parser = getParser();
2876 StringRef IDVal = DirectiveID.getIdentifier();
2877 if (IDVal == ".word")
2878 return ParseDirectiveWord(2, DirectiveID.getLoc());
2879 else if (IDVal.startswith(".code"))
2880 return ParseDirectiveCode(IDVal, DirectiveID.getLoc());
2881 else if (IDVal.startswith(".att_syntax")) {
2882 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2883 if (Parser.getTok().getString() == "prefix")
2885 else if (Parser.getTok().getString() == "noprefix")
2886 return Error(DirectiveID.getLoc(), "'.att_syntax noprefix' is not "
2887 "supported: registers must have a "
2888 "'%' prefix in .att_syntax");
2890 getParser().setAssemblerDialect(0);
2892 } else if (IDVal.startswith(".intel_syntax")) {
2893 getParser().setAssemblerDialect(1);
2894 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2895 if (Parser.getTok().getString() == "noprefix")
2897 else if (Parser.getTok().getString() == "prefix")
2898 return Error(DirectiveID.getLoc(), "'.intel_syntax prefix' is not "
2899 "supported: registers must not have "
2900 "a '%' prefix in .intel_syntax");
2907 /// ParseDirectiveWord
2908 /// ::= .word [ expression (, expression)* ]
2909 bool X86AsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
2910 MCAsmParser &Parser = getParser();
2911 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2913 const MCExpr *Value;
2914 if (getParser().parseExpression(Value))
2917 getParser().getStreamer().EmitValue(Value, Size);
2919 if (getLexer().is(AsmToken::EndOfStatement))
2922 // FIXME: Improve diagnostic.
2923 if (getLexer().isNot(AsmToken::Comma)) {
2924 Error(L, "unexpected token in directive");
2935 /// ParseDirectiveCode
2936 /// ::= .code16 | .code32 | .code64
2937 bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
2938 MCAsmParser &Parser = getParser();
2939 if (IDVal == ".code16") {
2941 if (!is16BitMode()) {
2942 SwitchMode(X86::Mode16Bit);
2943 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
2945 } else if (IDVal == ".code32") {
2947 if (!is32BitMode()) {
2948 SwitchMode(X86::Mode32Bit);
2949 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
2951 } else if (IDVal == ".code64") {
2953 if (!is64BitMode()) {
2954 SwitchMode(X86::Mode64Bit);
2955 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code64);
2958 Error(L, "unknown directive " + IDVal);
2965 // Force static initialization.
2966 extern "C" void LLVMInitializeX86AsmParser() {
2967 RegisterMCAsmParser<X86AsmParser> X(TheX86_32Target);
2968 RegisterMCAsmParser<X86AsmParser> Y(TheX86_64Target);
2971 #define GET_REGISTER_MATCHER
2972 #define GET_MATCHER_IMPLEMENTATION
2973 #define GET_SUBTARGET_FEATURE_NAME
2974 #include "X86GenAsmMatcher.inc"