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 "llvm/ADT/APFloat.h"
15 #include "llvm/ADT/STLExtras.h"
16 #include "llvm/ADT/SmallString.h"
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/ADT/StringSwitch.h"
19 #include "llvm/ADT/Twine.h"
20 #include "llvm/MC/MCContext.h"
21 #include "llvm/MC/MCExpr.h"
22 #include "llvm/MC/MCInst.h"
23 #include "llvm/MC/MCInstrInfo.h"
24 #include "llvm/MC/MCParser/MCAsmLexer.h"
25 #include "llvm/MC/MCParser/MCAsmParser.h"
26 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
27 #include "llvm/MC/MCRegisterInfo.h"
28 #include "llvm/MC/MCStreamer.h"
29 #include "llvm/MC/MCSubtargetInfo.h"
30 #include "llvm/MC/MCSymbol.h"
31 #include "llvm/MC/MCTargetAsmParser.h"
32 #include "llvm/Support/SourceMgr.h"
33 #include "llvm/Support/TargetRegistry.h"
34 #include "llvm/Support/raw_ostream.h"
42 static const char OpPrecedence[] = {
57 class X86AsmParser : public MCTargetAsmParser {
60 const MCInstrInfo &MII;
61 ParseInstructionInfo *InstInfo;
62 std::unique_ptr<X86AsmInstrumentation> Instrumentation;
64 SMLoc consumeToken() {
65 SMLoc Result = Parser.getTok().getLoc();
70 enum InfixCalculatorTok {
85 class InfixCalculator {
86 typedef std::pair< InfixCalculatorTok, int64_t > ICToken;
87 SmallVector<InfixCalculatorTok, 4> InfixOperatorStack;
88 SmallVector<ICToken, 4> PostfixStack;
91 int64_t popOperand() {
92 assert (!PostfixStack.empty() && "Poped an empty stack!");
93 ICToken Op = PostfixStack.pop_back_val();
94 assert ((Op.first == IC_IMM || Op.first == IC_REGISTER)
95 && "Expected and immediate or register!");
98 void pushOperand(InfixCalculatorTok Op, int64_t Val = 0) {
99 assert ((Op == IC_IMM || Op == IC_REGISTER) &&
100 "Unexpected operand!");
101 PostfixStack.push_back(std::make_pair(Op, Val));
104 void popOperator() { InfixOperatorStack.pop_back(); }
105 void pushOperator(InfixCalculatorTok Op) {
106 // Push the new operator if the stack is empty.
107 if (InfixOperatorStack.empty()) {
108 InfixOperatorStack.push_back(Op);
112 // Push the new operator if it has a higher precedence than the operator
113 // on the top of the stack or the operator on the top of the stack is a
115 unsigned Idx = InfixOperatorStack.size() - 1;
116 InfixCalculatorTok StackOp = InfixOperatorStack[Idx];
117 if (OpPrecedence[Op] > OpPrecedence[StackOp] || StackOp == IC_LPAREN) {
118 InfixOperatorStack.push_back(Op);
122 // The operator on the top of the stack has higher precedence than the
124 unsigned ParenCount = 0;
126 // Nothing to process.
127 if (InfixOperatorStack.empty())
130 Idx = InfixOperatorStack.size() - 1;
131 StackOp = InfixOperatorStack[Idx];
132 if (!(OpPrecedence[StackOp] >= OpPrecedence[Op] || ParenCount))
135 // If we have an even parentheses count and we see a left parentheses,
136 // then stop processing.
137 if (!ParenCount && StackOp == IC_LPAREN)
140 if (StackOp == IC_RPAREN) {
142 InfixOperatorStack.pop_back();
143 } else if (StackOp == IC_LPAREN) {
145 InfixOperatorStack.pop_back();
147 InfixOperatorStack.pop_back();
148 PostfixStack.push_back(std::make_pair(StackOp, 0));
151 // Push the new operator.
152 InfixOperatorStack.push_back(Op);
155 // Push any remaining operators onto the postfix stack.
156 while (!InfixOperatorStack.empty()) {
157 InfixCalculatorTok StackOp = InfixOperatorStack.pop_back_val();
158 if (StackOp != IC_LPAREN && StackOp != IC_RPAREN)
159 PostfixStack.push_back(std::make_pair(StackOp, 0));
162 if (PostfixStack.empty())
165 SmallVector<ICToken, 16> OperandStack;
166 for (unsigned i = 0, e = PostfixStack.size(); i != e; ++i) {
167 ICToken Op = PostfixStack[i];
168 if (Op.first == IC_IMM || Op.first == IC_REGISTER) {
169 OperandStack.push_back(Op);
171 assert (OperandStack.size() > 1 && "Too few operands.");
173 ICToken Op2 = OperandStack.pop_back_val();
174 ICToken Op1 = OperandStack.pop_back_val();
177 report_fatal_error("Unexpected operator!");
180 Val = Op1.second + Op2.second;
181 OperandStack.push_back(std::make_pair(IC_IMM, Val));
184 Val = Op1.second - Op2.second;
185 OperandStack.push_back(std::make_pair(IC_IMM, Val));
188 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
189 "Multiply operation with an immediate and a register!");
190 Val = Op1.second * Op2.second;
191 OperandStack.push_back(std::make_pair(IC_IMM, Val));
194 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
195 "Divide operation with an immediate and a register!");
196 assert (Op2.second != 0 && "Division by zero!");
197 Val = Op1.second / Op2.second;
198 OperandStack.push_back(std::make_pair(IC_IMM, Val));
201 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
202 "Or operation with an immediate and a register!");
203 Val = Op1.second | Op2.second;
204 OperandStack.push_back(std::make_pair(IC_IMM, Val));
207 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
208 "And operation with an immediate and a register!");
209 Val = Op1.second & Op2.second;
210 OperandStack.push_back(std::make_pair(IC_IMM, Val));
213 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
214 "Left shift operation with an immediate and a register!");
215 Val = Op1.second << Op2.second;
216 OperandStack.push_back(std::make_pair(IC_IMM, Val));
219 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
220 "Right shift operation with an immediate and a register!");
221 Val = Op1.second >> Op2.second;
222 OperandStack.push_back(std::make_pair(IC_IMM, Val));
227 assert (OperandStack.size() == 1 && "Expected a single result.");
228 return OperandStack.pop_back_val().second;
232 enum IntelExprState {
252 class IntelExprStateMachine {
253 IntelExprState State, PrevState;
254 unsigned BaseReg, IndexReg, TmpReg, Scale;
258 bool StopOnLBrac, AddImmPrefix;
260 InlineAsmIdentifierInfo Info;
262 IntelExprStateMachine(int64_t imm, bool stoponlbrac, bool addimmprefix) :
263 State(IES_PLUS), PrevState(IES_ERROR), BaseReg(0), IndexReg(0), TmpReg(0),
264 Scale(1), Imm(imm), Sym(nullptr), StopOnLBrac(stoponlbrac),
265 AddImmPrefix(addimmprefix) { Info.clear(); }
267 unsigned getBaseReg() { return BaseReg; }
268 unsigned getIndexReg() { return IndexReg; }
269 unsigned getScale() { return Scale; }
270 const MCExpr *getSym() { return Sym; }
271 StringRef getSymName() { return SymName; }
272 int64_t getImm() { return Imm + IC.execute(); }
273 bool isValidEndState() {
274 return State == IES_RBRAC || State == IES_INTEGER;
276 bool getStopOnLBrac() { return StopOnLBrac; }
277 bool getAddImmPrefix() { return AddImmPrefix; }
278 bool hadError() { return State == IES_ERROR; }
280 InlineAsmIdentifierInfo &getIdentifierInfo() {
285 IntelExprState CurrState = State;
294 IC.pushOperator(IC_OR);
297 PrevState = CurrState;
300 IntelExprState CurrState = State;
309 IC.pushOperator(IC_AND);
312 PrevState = CurrState;
315 IntelExprState CurrState = State;
324 IC.pushOperator(IC_LSHIFT);
327 PrevState = CurrState;
330 IntelExprState CurrState = State;
339 IC.pushOperator(IC_RSHIFT);
342 PrevState = CurrState;
345 IntelExprState CurrState = State;
354 IC.pushOperator(IC_PLUS);
355 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
356 // If we already have a BaseReg, then assume this is the IndexReg with
361 assert (!IndexReg && "BaseReg/IndexReg already set!");
368 PrevState = CurrState;
371 IntelExprState CurrState = State;
387 // Only push the minus operator if it is not a unary operator.
388 if (!(CurrState == IES_PLUS || CurrState == IES_MINUS ||
389 CurrState == IES_MULTIPLY || CurrState == IES_DIVIDE ||
390 CurrState == IES_LPAREN || CurrState == IES_LBRAC))
391 IC.pushOperator(IC_MINUS);
392 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
393 // If we already have a BaseReg, then assume this is the IndexReg with
398 assert (!IndexReg && "BaseReg/IndexReg already set!");
405 PrevState = CurrState;
408 IntelExprState CurrState = State;
418 PrevState = CurrState;
420 void onRegister(unsigned Reg) {
421 IntelExprState CurrState = State;
428 State = IES_REGISTER;
430 IC.pushOperand(IC_REGISTER);
433 // Index Register - Scale * Register
434 if (PrevState == IES_INTEGER) {
435 assert (!IndexReg && "IndexReg already set!");
436 State = IES_REGISTER;
438 // Get the scale and replace the 'Scale * Register' with '0'.
439 Scale = IC.popOperand();
440 IC.pushOperand(IC_IMM);
447 PrevState = CurrState;
449 void onIdentifierExpr(const MCExpr *SymRef, StringRef SymRefName) {
460 SymName = SymRefName;
461 IC.pushOperand(IC_IMM);
465 bool onInteger(int64_t TmpInt, StringRef &ErrMsg) {
466 IntelExprState CurrState = State;
482 if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
483 // Index Register - Register * Scale
484 assert (!IndexReg && "IndexReg already set!");
487 if(Scale != 1 && Scale != 2 && Scale != 4 && Scale != 8) {
488 ErrMsg = "scale factor in address must be 1, 2, 4 or 8";
491 // Get the scale and replace the 'Register * Scale' with '0'.
493 } else if ((PrevState == IES_PLUS || PrevState == IES_MINUS ||
494 PrevState == IES_OR || PrevState == IES_AND ||
495 PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||
496 PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
497 PrevState == IES_LPAREN || PrevState == IES_LBRAC ||
498 PrevState == IES_NOT) &&
499 CurrState == IES_MINUS) {
500 // Unary minus. No need to pop the minus operand because it was never
502 IC.pushOperand(IC_IMM, -TmpInt); // Push -Imm.
503 } else if ((PrevState == IES_PLUS || PrevState == IES_MINUS ||
504 PrevState == IES_OR || PrevState == IES_AND ||
505 PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||
506 PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
507 PrevState == IES_LPAREN || PrevState == IES_LBRAC ||
508 PrevState == IES_NOT) &&
509 CurrState == IES_NOT) {
510 // Unary not. No need to pop the not operand because it was never
512 IC.pushOperand(IC_IMM, ~TmpInt); // Push ~Imm.
514 IC.pushOperand(IC_IMM, TmpInt);
518 PrevState = CurrState;
530 State = IES_MULTIPLY;
531 IC.pushOperator(IC_MULTIPLY);
544 IC.pushOperator(IC_DIVIDE);
556 IC.pushOperator(IC_PLUS);
561 IntelExprState CurrState = State;
570 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
571 // If we already have a BaseReg, then assume this is the IndexReg with
576 assert (!IndexReg && "BaseReg/IndexReg already set!");
583 PrevState = CurrState;
586 IntelExprState CurrState = State;
601 // FIXME: We don't handle this type of unary minus or not, yet.
602 if ((PrevState == IES_PLUS || PrevState == IES_MINUS ||
603 PrevState == IES_OR || PrevState == IES_AND ||
604 PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||
605 PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
606 PrevState == IES_LPAREN || PrevState == IES_LBRAC ||
607 PrevState == IES_NOT) &&
608 (CurrState == IES_MINUS || CurrState == IES_NOT)) {
613 IC.pushOperator(IC_LPAREN);
616 PrevState = CurrState;
628 IC.pushOperator(IC_RPAREN);
634 MCAsmParser &getParser() const { return Parser; }
636 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
638 bool Error(SMLoc L, const Twine &Msg,
639 ArrayRef<SMRange> Ranges = None,
640 bool MatchingInlineAsm = false) {
641 if (MatchingInlineAsm) return true;
642 return Parser.Error(L, Msg, Ranges);
645 bool ErrorAndEatStatement(SMLoc L, const Twine &Msg,
646 ArrayRef<SMRange> Ranges = None,
647 bool MatchingInlineAsm = false) {
648 Parser.eatToEndOfStatement();
649 return Error(L, Msg, Ranges, MatchingInlineAsm);
652 std::nullptr_t ErrorOperand(SMLoc Loc, StringRef Msg) {
657 std::unique_ptr<X86Operand> DefaultMemSIOperand(SMLoc Loc);
658 std::unique_ptr<X86Operand> DefaultMemDIOperand(SMLoc Loc);
659 std::unique_ptr<X86Operand> ParseOperand();
660 std::unique_ptr<X86Operand> ParseATTOperand();
661 std::unique_ptr<X86Operand> ParseIntelOperand();
662 std::unique_ptr<X86Operand> ParseIntelOffsetOfOperator();
663 bool ParseIntelDotOperator(const MCExpr *Disp, const MCExpr *&NewDisp);
664 std::unique_ptr<X86Operand> ParseIntelOperator(unsigned OpKind);
665 std::unique_ptr<X86Operand>
666 ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start, unsigned Size);
667 std::unique_ptr<X86Operand>
668 ParseIntelMemOperand(int64_t ImmDisp, SMLoc StartLoc, unsigned Size);
669 bool ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End);
670 std::unique_ptr<X86Operand> ParseIntelBracExpression(unsigned SegReg,
674 bool ParseIntelIdentifier(const MCExpr *&Val, StringRef &Identifier,
675 InlineAsmIdentifierInfo &Info,
676 bool IsUnevaluatedOperand, SMLoc &End);
678 std::unique_ptr<X86Operand> ParseMemOperand(unsigned SegReg, SMLoc StartLoc);
680 std::unique_ptr<X86Operand>
681 CreateMemForInlineAsm(unsigned SegReg, const MCExpr *Disp, unsigned BaseReg,
682 unsigned IndexReg, unsigned Scale, SMLoc Start,
683 SMLoc End, unsigned Size, StringRef Identifier,
684 InlineAsmIdentifierInfo &Info);
686 bool ParseDirectiveWord(unsigned Size, SMLoc L);
687 bool ParseDirectiveCode(StringRef IDVal, SMLoc L);
689 bool processInstruction(MCInst &Inst, const OperandVector &Ops);
691 /// Wrapper around MCStreamer::EmitInstruction(). Possibly adds
692 /// instrumentation around Inst.
693 void EmitInstruction(MCInst &Inst, OperandVector &Operands, MCStreamer &Out);
695 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
696 OperandVector &Operands, MCStreamer &Out,
698 bool MatchingInlineAsm) override;
700 void MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op, OperandVector &Operands,
701 MCStreamer &Out, bool MatchingInlineAsm);
703 bool ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
704 bool MatchingInlineAsm);
706 bool MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
707 OperandVector &Operands, MCStreamer &Out,
709 bool MatchingInlineAsm);
711 bool MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
712 OperandVector &Operands, MCStreamer &Out,
714 bool MatchingInlineAsm);
716 unsigned getPointerSize() {
717 if (is16BitMode()) return 16;
718 if (is32BitMode()) return 32;
719 if (is64BitMode()) return 64;
720 llvm_unreachable("invalid mode");
723 virtual bool OmitRegisterFromClobberLists(unsigned RegNo) override;
725 /// doSrcDstMatch - Returns true if operands are matching in their
726 /// word size (%si and %di, %esi and %edi, etc.). Order depends on
727 /// the parsing mode (Intel vs. AT&T).
728 bool doSrcDstMatch(X86Operand &Op1, X86Operand &Op2);
730 /// Parses AVX512 specific operand primitives: masked registers ({%k<NUM>}, {z})
731 /// and memory broadcasting ({1to<NUM>}) primitives, updating Operands vector if required.
732 /// \return \c true if no parsing errors occurred, \c false otherwise.
733 bool HandleAVX512Operand(OperandVector &Operands,
734 const MCParsedAsmOperand &Op);
736 bool is64BitMode() const {
737 // FIXME: Can tablegen auto-generate this?
738 return (STI.getFeatureBits() & X86::Mode64Bit) != 0;
740 bool is32BitMode() const {
741 // FIXME: Can tablegen auto-generate this?
742 return (STI.getFeatureBits() & X86::Mode32Bit) != 0;
744 bool is16BitMode() const {
745 // FIXME: Can tablegen auto-generate this?
746 return (STI.getFeatureBits() & X86::Mode16Bit) != 0;
748 void SwitchMode(uint64_t mode) {
749 uint64_t oldMode = STI.getFeatureBits() &
750 (X86::Mode64Bit | X86::Mode32Bit | X86::Mode16Bit);
751 unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(oldMode | mode));
752 setAvailableFeatures(FB);
753 assert(mode == (STI.getFeatureBits() &
754 (X86::Mode64Bit | X86::Mode32Bit | X86::Mode16Bit)));
757 unsigned getPointerWidth() {
758 if (is16BitMode()) return 16;
759 if (is32BitMode()) return 32;
760 if (is64BitMode()) return 64;
761 llvm_unreachable("invalid mode");
764 bool isParsingIntelSyntax() {
765 return getParser().getAssemblerDialect();
768 /// @name Auto-generated Matcher Functions
771 #define GET_ASSEMBLER_HEADER
772 #include "X86GenAsmMatcher.inc"
777 X86AsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
778 const MCInstrInfo &mii,
779 const MCTargetOptions &Options)
780 : MCTargetAsmParser(), STI(sti), Parser(parser), MII(mii),
783 // Initialize the set of available features.
784 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
785 Instrumentation.reset(
786 CreateX86AsmInstrumentation(Options, Parser.getContext(), STI));
789 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
791 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
792 SMLoc NameLoc, OperandVector &Operands) override;
794 bool ParseDirective(AsmToken DirectiveID) override;
796 } // end anonymous namespace
798 /// @name Auto-generated Match Functions
801 static unsigned MatchRegisterName(StringRef Name);
805 static bool CheckBaseRegAndIndexReg(unsigned BaseReg, unsigned IndexReg,
807 // If we have both a base register and an index register make sure they are
808 // both 64-bit or 32-bit registers.
809 // To support VSIB, IndexReg can be 128-bit or 256-bit registers.
810 if (BaseReg != 0 && IndexReg != 0) {
811 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) &&
812 (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
813 X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg)) &&
814 IndexReg != X86::RIZ) {
815 ErrMsg = "base register is 64-bit, but index register is not";
818 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg) &&
819 (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
820 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) &&
821 IndexReg != X86::EIZ){
822 ErrMsg = "base register is 32-bit, but index register is not";
825 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg)) {
826 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg) ||
827 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) {
828 ErrMsg = "base register is 16-bit, but index register is not";
831 if (((BaseReg == X86::BX || BaseReg == X86::BP) &&
832 IndexReg != X86::SI && IndexReg != X86::DI) ||
833 ((BaseReg == X86::SI || BaseReg == X86::DI) &&
834 IndexReg != X86::BX && IndexReg != X86::BP)) {
835 ErrMsg = "invalid 16-bit base/index register combination";
843 bool X86AsmParser::doSrcDstMatch(X86Operand &Op1, X86Operand &Op2)
845 // Return true and let a normal complaint about bogus operands happen.
846 if (!Op1.isMem() || !Op2.isMem())
849 // Actually these might be the other way round if Intel syntax is
850 // being used. It doesn't matter.
851 unsigned diReg = Op1.Mem.BaseReg;
852 unsigned siReg = Op2.Mem.BaseReg;
854 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(siReg))
855 return X86MCRegisterClasses[X86::GR16RegClassID].contains(diReg);
856 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(siReg))
857 return X86MCRegisterClasses[X86::GR32RegClassID].contains(diReg);
858 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(siReg))
859 return X86MCRegisterClasses[X86::GR64RegClassID].contains(diReg);
860 // Again, return true and let another error happen.
864 bool X86AsmParser::ParseRegister(unsigned &RegNo,
865 SMLoc &StartLoc, SMLoc &EndLoc) {
867 const AsmToken &PercentTok = Parser.getTok();
868 StartLoc = PercentTok.getLoc();
870 // If we encounter a %, ignore it. This code handles registers with and
871 // without the prefix, unprefixed registers can occur in cfi directives.
872 if (!isParsingIntelSyntax() && PercentTok.is(AsmToken::Percent))
873 Parser.Lex(); // Eat percent token.
875 const AsmToken &Tok = Parser.getTok();
876 EndLoc = Tok.getEndLoc();
878 if (Tok.isNot(AsmToken::Identifier)) {
879 if (isParsingIntelSyntax()) return true;
880 return Error(StartLoc, "invalid register name",
881 SMRange(StartLoc, EndLoc));
884 RegNo = MatchRegisterName(Tok.getString());
886 // If the match failed, try the register name as lowercase.
888 RegNo = MatchRegisterName(Tok.getString().lower());
890 if (!is64BitMode()) {
891 // FIXME: This should be done using Requires<Not64BitMode> and
892 // Requires<In64BitMode> so "eiz" usage in 64-bit instructions can be also
894 // FIXME: Check AH, CH, DH, BH cannot be used in an instruction requiring a
896 if (RegNo == X86::RIZ ||
897 X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo) ||
898 X86II::isX86_64NonExtLowByteReg(RegNo) ||
899 X86II::isX86_64ExtendedReg(RegNo))
900 return Error(StartLoc, "register %"
901 + Tok.getString() + " is only available in 64-bit mode",
902 SMRange(StartLoc, EndLoc));
905 // Parse "%st" as "%st(0)" and "%st(1)", which is multiple tokens.
906 if (RegNo == 0 && (Tok.getString() == "st" || Tok.getString() == "ST")) {
908 Parser.Lex(); // Eat 'st'
910 // Check to see if we have '(4)' after %st.
911 if (getLexer().isNot(AsmToken::LParen))
916 const AsmToken &IntTok = Parser.getTok();
917 if (IntTok.isNot(AsmToken::Integer))
918 return Error(IntTok.getLoc(), "expected stack index");
919 switch (IntTok.getIntVal()) {
920 case 0: RegNo = X86::ST0; break;
921 case 1: RegNo = X86::ST1; break;
922 case 2: RegNo = X86::ST2; break;
923 case 3: RegNo = X86::ST3; break;
924 case 4: RegNo = X86::ST4; break;
925 case 5: RegNo = X86::ST5; break;
926 case 6: RegNo = X86::ST6; break;
927 case 7: RegNo = X86::ST7; break;
928 default: return Error(IntTok.getLoc(), "invalid stack index");
931 if (getParser().Lex().isNot(AsmToken::RParen))
932 return Error(Parser.getTok().getLoc(), "expected ')'");
934 EndLoc = Parser.getTok().getEndLoc();
935 Parser.Lex(); // Eat ')'
939 EndLoc = Parser.getTok().getEndLoc();
941 // If this is "db[0-7]", match it as an alias
943 if (RegNo == 0 && Tok.getString().size() == 3 &&
944 Tok.getString().startswith("db")) {
945 switch (Tok.getString()[2]) {
946 case '0': RegNo = X86::DR0; break;
947 case '1': RegNo = X86::DR1; break;
948 case '2': RegNo = X86::DR2; break;
949 case '3': RegNo = X86::DR3; break;
950 case '4': RegNo = X86::DR4; break;
951 case '5': RegNo = X86::DR5; break;
952 case '6': RegNo = X86::DR6; break;
953 case '7': RegNo = X86::DR7; break;
957 EndLoc = Parser.getTok().getEndLoc();
958 Parser.Lex(); // Eat it.
964 if (isParsingIntelSyntax()) return true;
965 return Error(StartLoc, "invalid register name",
966 SMRange(StartLoc, EndLoc));
969 Parser.Lex(); // Eat identifier token.
973 std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(SMLoc Loc) {
975 is64BitMode() ? X86::RSI : (is32BitMode() ? X86::ESI : X86::SI);
976 const MCExpr *Disp = MCConstantExpr::Create(0, getContext());
977 return X86Operand::CreateMem(/*SegReg=*/0, Disp, /*BaseReg=*/basereg,
978 /*IndexReg=*/0, /*Scale=*/1, Loc, Loc, 0);
981 std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand(SMLoc Loc) {
983 is64BitMode() ? X86::RDI : (is32BitMode() ? X86::EDI : X86::DI);
984 const MCExpr *Disp = MCConstantExpr::Create(0, getContext());
985 return X86Operand::CreateMem(/*SegReg=*/0, Disp, /*BaseReg=*/basereg,
986 /*IndexReg=*/0, /*Scale=*/1, Loc, Loc, 0);
989 std::unique_ptr<X86Operand> X86AsmParser::ParseOperand() {
990 if (isParsingIntelSyntax())
991 return ParseIntelOperand();
992 return ParseATTOperand();
995 /// getIntelMemOperandSize - Return intel memory operand size.
996 static unsigned getIntelMemOperandSize(StringRef OpStr) {
997 unsigned Size = StringSwitch<unsigned>(OpStr)
998 .Cases("BYTE", "byte", 8)
999 .Cases("WORD", "word", 16)
1000 .Cases("DWORD", "dword", 32)
1001 .Cases("QWORD", "qword", 64)
1002 .Cases("XWORD", "xword", 80)
1003 .Cases("XMMWORD", "xmmword", 128)
1004 .Cases("YMMWORD", "ymmword", 256)
1005 .Cases("ZMMWORD", "zmmword", 512)
1006 .Cases("OPAQUE", "opaque", -1U) // needs to be non-zero, but doesn't matter
1011 std::unique_ptr<X86Operand> X86AsmParser::CreateMemForInlineAsm(
1012 unsigned SegReg, const MCExpr *Disp, unsigned BaseReg, unsigned IndexReg,
1013 unsigned Scale, SMLoc Start, SMLoc End, unsigned Size, StringRef Identifier,
1014 InlineAsmIdentifierInfo &Info) {
1015 // If we found a decl other than a VarDecl, then assume it is a FuncDecl or
1016 // some other label reference.
1017 if (isa<MCSymbolRefExpr>(Disp) && Info.OpDecl && !Info.IsVarDecl) {
1018 // Insert an explicit size if the user didn't have one.
1020 Size = getPointerWidth();
1021 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_SizeDirective, Start,
1025 // Create an absolute memory reference in order to match against
1026 // instructions taking a PC relative operand.
1027 return X86Operand::CreateMem(Disp, Start, End, Size, Identifier,
1031 // We either have a direct symbol reference, or an offset from a symbol. The
1032 // parser always puts the symbol on the LHS, so look there for size
1033 // calculation purposes.
1034 const MCBinaryExpr *BinOp = dyn_cast<MCBinaryExpr>(Disp);
1036 isa<MCSymbolRefExpr>(BinOp ? BinOp->getLHS() : Disp);
1039 Size = Info.Type * 8; // Size is in terms of bits in this context.
1041 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_SizeDirective, Start,
1046 // When parsing inline assembly we set the base register to a non-zero value
1047 // if we don't know the actual value at this time. This is necessary to
1048 // get the matching correct in some cases.
1049 BaseReg = BaseReg ? BaseReg : 1;
1050 return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale, Start,
1051 End, Size, Identifier, Info.OpDecl);
1055 RewriteIntelBracExpression(SmallVectorImpl<AsmRewrite> *AsmRewrites,
1056 StringRef SymName, int64_t ImmDisp,
1057 int64_t FinalImmDisp, SMLoc &BracLoc,
1058 SMLoc &StartInBrac, SMLoc &End) {
1059 // Remove the '[' and ']' from the IR string.
1060 AsmRewrites->push_back(AsmRewrite(AOK_Skip, BracLoc, 1));
1061 AsmRewrites->push_back(AsmRewrite(AOK_Skip, End, 1));
1063 // If ImmDisp is non-zero, then we parsed a displacement before the
1064 // bracketed expression (i.e., ImmDisp [ BaseReg + Scale*IndexReg + Disp])
1065 // If ImmDisp doesn't match the displacement computed by the state machine
1066 // then we have an additional displacement in the bracketed expression.
1067 if (ImmDisp != FinalImmDisp) {
1069 // We have an immediate displacement before the bracketed expression.
1070 // Adjust this to match the final immediate displacement.
1072 for (SmallVectorImpl<AsmRewrite>::iterator I = AsmRewrites->begin(),
1073 E = AsmRewrites->end(); I != E; ++I) {
1074 if ((*I).Loc.getPointer() > BracLoc.getPointer())
1076 if ((*I).Kind == AOK_ImmPrefix || (*I).Kind == AOK_Imm) {
1077 assert (!Found && "ImmDisp already rewritten.");
1078 (*I).Kind = AOK_Imm;
1079 (*I).Len = BracLoc.getPointer() - (*I).Loc.getPointer();
1080 (*I).Val = FinalImmDisp;
1085 assert (Found && "Unable to rewrite ImmDisp.");
1088 // We have a symbolic and an immediate displacement, but no displacement
1089 // before the bracketed expression. Put the immediate displacement
1090 // before the bracketed expression.
1091 AsmRewrites->push_back(AsmRewrite(AOK_Imm, BracLoc, 0, FinalImmDisp));
1094 // Remove all the ImmPrefix rewrites within the brackets.
1095 for (SmallVectorImpl<AsmRewrite>::iterator I = AsmRewrites->begin(),
1096 E = AsmRewrites->end(); I != E; ++I) {
1097 if ((*I).Loc.getPointer() < StartInBrac.getPointer())
1099 if ((*I).Kind == AOK_ImmPrefix)
1100 (*I).Kind = AOK_Delete;
1102 const char *SymLocPtr = SymName.data();
1103 // Skip everything before the symbol.
1104 if (unsigned Len = SymLocPtr - StartInBrac.getPointer()) {
1105 assert(Len > 0 && "Expected a non-negative length.");
1106 AsmRewrites->push_back(AsmRewrite(AOK_Skip, StartInBrac, Len));
1108 // Skip everything after the symbol.
1109 if (unsigned Len = End.getPointer() - (SymLocPtr + SymName.size())) {
1110 SMLoc Loc = SMLoc::getFromPointer(SymLocPtr + SymName.size());
1111 assert(Len > 0 && "Expected a non-negative length.");
1112 AsmRewrites->push_back(AsmRewrite(AOK_Skip, Loc, Len));
1116 bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
1117 const AsmToken &Tok = Parser.getTok();
1121 bool UpdateLocLex = true;
1123 // The period in the dot operator (e.g., [ebx].foo.bar) is parsed as an
1124 // identifier. Don't try an parse it as a register.
1125 if (Tok.getString().startswith("."))
1128 // If we're parsing an immediate expression, we don't expect a '['.
1129 if (SM.getStopOnLBrac() && getLexer().getKind() == AsmToken::LBrac)
1132 AsmToken::TokenKind TK = getLexer().getKind();
1135 if (SM.isValidEndState()) {
1139 return Error(Tok.getLoc(), "unknown token in expression");
1141 case AsmToken::EndOfStatement: {
1145 case AsmToken::String:
1146 case AsmToken::Identifier: {
1147 // This could be a register or a symbolic displacement.
1150 SMLoc IdentLoc = Tok.getLoc();
1151 StringRef Identifier = Tok.getString();
1152 if (TK != AsmToken::String && !ParseRegister(TmpReg, IdentLoc, End)) {
1153 SM.onRegister(TmpReg);
1154 UpdateLocLex = false;
1157 if (!isParsingInlineAsm()) {
1158 if (getParser().parsePrimaryExpr(Val, End))
1159 return Error(Tok.getLoc(), "Unexpected identifier!");
1161 // This is a dot operator, not an adjacent identifier.
1162 if (Identifier.find('.') != StringRef::npos) {
1165 InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
1166 if (ParseIntelIdentifier(Val, Identifier, Info,
1167 /*Unevaluated=*/false, End))
1171 SM.onIdentifierExpr(Val, Identifier);
1172 UpdateLocLex = false;
1175 return Error(Tok.getLoc(), "Unexpected identifier!");
1177 case AsmToken::Integer: {
1179 if (isParsingInlineAsm() && SM.getAddImmPrefix())
1180 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_ImmPrefix,
1182 // Look for 'b' or 'f' following an Integer as a directional label
1183 SMLoc Loc = getTok().getLoc();
1184 int64_t IntVal = getTok().getIntVal();
1185 End = consumeToken();
1186 UpdateLocLex = false;
1187 if (getLexer().getKind() == AsmToken::Identifier) {
1188 StringRef IDVal = getTok().getString();
1189 if (IDVal == "f" || IDVal == "b") {
1191 getContext().GetDirectionalLocalSymbol(IntVal, IDVal == "b");
1192 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1194 MCSymbolRefExpr::Create(Sym, Variant, getContext());
1195 if (IDVal == "b" && Sym->isUndefined())
1196 return Error(Loc, "invalid reference to undefined symbol");
1197 StringRef Identifier = Sym->getName();
1198 SM.onIdentifierExpr(Val, Identifier);
1199 End = consumeToken();
1201 if (SM.onInteger(IntVal, ErrMsg))
1202 return Error(Loc, ErrMsg);
1205 if (SM.onInteger(IntVal, ErrMsg))
1206 return Error(Loc, ErrMsg);
1210 case AsmToken::Plus: SM.onPlus(); break;
1211 case AsmToken::Minus: SM.onMinus(); break;
1212 case AsmToken::Tilde: SM.onNot(); break;
1213 case AsmToken::Star: SM.onStar(); break;
1214 case AsmToken::Slash: SM.onDivide(); break;
1215 case AsmToken::Pipe: SM.onOr(); break;
1216 case AsmToken::Amp: SM.onAnd(); break;
1217 case AsmToken::LessLess:
1218 SM.onLShift(); break;
1219 case AsmToken::GreaterGreater:
1220 SM.onRShift(); break;
1221 case AsmToken::LBrac: SM.onLBrac(); break;
1222 case AsmToken::RBrac: SM.onRBrac(); break;
1223 case AsmToken::LParen: SM.onLParen(); break;
1224 case AsmToken::RParen: SM.onRParen(); break;
1227 return Error(Tok.getLoc(), "unknown token in expression");
1229 if (!Done && UpdateLocLex)
1230 End = consumeToken();
1235 std::unique_ptr<X86Operand>
1236 X86AsmParser::ParseIntelBracExpression(unsigned SegReg, SMLoc Start,
1237 int64_t ImmDisp, unsigned Size) {
1238 const AsmToken &Tok = Parser.getTok();
1239 SMLoc BracLoc = Tok.getLoc(), End = Tok.getEndLoc();
1240 if (getLexer().isNot(AsmToken::LBrac))
1241 return ErrorOperand(BracLoc, "Expected '[' token!");
1242 Parser.Lex(); // Eat '['
1244 SMLoc StartInBrac = Tok.getLoc();
1245 // Parse [ Symbol + ImmDisp ] and [ BaseReg + Scale*IndexReg + ImmDisp ]. We
1246 // may have already parsed an immediate displacement before the bracketed
1248 IntelExprStateMachine SM(ImmDisp, /*StopOnLBrac=*/false, /*AddImmPrefix=*/true);
1249 if (ParseIntelExpression(SM, End))
1252 const MCExpr *Disp = nullptr;
1253 if (const MCExpr *Sym = SM.getSym()) {
1254 // A symbolic displacement.
1256 if (isParsingInlineAsm())
1257 RewriteIntelBracExpression(InstInfo->AsmRewrites, SM.getSymName(),
1258 ImmDisp, SM.getImm(), BracLoc, StartInBrac,
1262 if (SM.getImm() || !Disp) {
1263 const MCExpr *Imm = MCConstantExpr::Create(SM.getImm(), getContext());
1265 Disp = MCBinaryExpr::CreateAdd(Disp, Imm, getContext());
1267 Disp = Imm; // An immediate displacement only.
1270 // Parse struct field access. Intel requires a dot, but MSVC doesn't. MSVC
1271 // will in fact do global lookup the field name inside all global typedefs,
1272 // but we don't emulate that.
1273 if (Tok.getString().find('.') != StringRef::npos) {
1274 const MCExpr *NewDisp;
1275 if (ParseIntelDotOperator(Disp, NewDisp))
1278 End = Tok.getEndLoc();
1279 Parser.Lex(); // Eat the field.
1283 int BaseReg = SM.getBaseReg();
1284 int IndexReg = SM.getIndexReg();
1285 int Scale = SM.getScale();
1286 if (!isParsingInlineAsm()) {
1288 if (!BaseReg && !IndexReg) {
1290 return X86Operand::CreateMem(Disp, Start, End, Size);
1292 return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, Start, End, Size);
1295 if (CheckBaseRegAndIndexReg(BaseReg, IndexReg, ErrMsg)) {
1296 Error(StartInBrac, ErrMsg);
1299 return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale, Start,
1303 InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
1304 return CreateMemForInlineAsm(SegReg, Disp, BaseReg, IndexReg, Scale, Start,
1305 End, Size, SM.getSymName(), Info);
1308 // Inline assembly may use variable names with namespace alias qualifiers.
1309 bool X86AsmParser::ParseIntelIdentifier(const MCExpr *&Val,
1310 StringRef &Identifier,
1311 InlineAsmIdentifierInfo &Info,
1312 bool IsUnevaluatedOperand, SMLoc &End) {
1313 assert (isParsingInlineAsm() && "Expected to be parsing inline assembly.");
1316 StringRef LineBuf(Identifier.data());
1317 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);
1319 const AsmToken &Tok = Parser.getTok();
1321 // Advance the token stream until the end of the current token is
1322 // after the end of what the frontend claimed.
1323 const char *EndPtr = Tok.getLoc().getPointer() + LineBuf.size();
1325 End = Tok.getEndLoc();
1328 assert(End.getPointer() <= EndPtr && "frontend claimed part of a token?");
1329 if (End.getPointer() == EndPtr) break;
1332 // Create the symbol reference.
1333 Identifier = LineBuf;
1334 MCSymbol *Sym = getContext().GetOrCreateSymbol(Identifier);
1335 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1336 Val = MCSymbolRefExpr::Create(Sym, Variant, getParser().getContext());
1340 /// \brief Parse intel style segment override.
1341 std::unique_ptr<X86Operand>
1342 X86AsmParser::ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start,
1344 assert(SegReg != 0 && "Tried to parse a segment override without a segment!");
1345 const AsmToken &Tok = Parser.getTok(); // Eat colon.
1346 if (Tok.isNot(AsmToken::Colon))
1347 return ErrorOperand(Tok.getLoc(), "Expected ':' token!");
1348 Parser.Lex(); // Eat ':'
1350 int64_t ImmDisp = 0;
1351 if (getLexer().is(AsmToken::Integer)) {
1352 ImmDisp = Tok.getIntVal();
1353 AsmToken ImmDispToken = Parser.Lex(); // Eat the integer.
1355 if (isParsingInlineAsm())
1356 InstInfo->AsmRewrites->push_back(
1357 AsmRewrite(AOK_ImmPrefix, ImmDispToken.getLoc()));
1359 if (getLexer().isNot(AsmToken::LBrac)) {
1360 // An immediate following a 'segment register', 'colon' token sequence can
1361 // be followed by a bracketed expression. If it isn't we know we have our
1362 // final segment override.
1363 const MCExpr *Disp = MCConstantExpr::Create(ImmDisp, getContext());
1364 return X86Operand::CreateMem(SegReg, Disp, /*BaseReg=*/0, /*IndexReg=*/0,
1365 /*Scale=*/1, Start, ImmDispToken.getEndLoc(),
1370 if (getLexer().is(AsmToken::LBrac))
1371 return ParseIntelBracExpression(SegReg, Start, ImmDisp, Size);
1375 if (!isParsingInlineAsm()) {
1376 if (getParser().parsePrimaryExpr(Val, End))
1377 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1379 return X86Operand::CreateMem(Val, Start, End, Size);
1382 InlineAsmIdentifierInfo Info;
1383 StringRef Identifier = Tok.getString();
1384 if (ParseIntelIdentifier(Val, Identifier, Info,
1385 /*Unevaluated=*/false, End))
1387 return CreateMemForInlineAsm(/*SegReg=*/0, Val, /*BaseReg=*/0,/*IndexReg=*/0,
1388 /*Scale=*/1, Start, End, Size, Identifier, Info);
1391 /// ParseIntelMemOperand - Parse intel style memory operand.
1392 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelMemOperand(int64_t ImmDisp,
1395 const AsmToken &Tok = Parser.getTok();
1398 // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
1399 if (getLexer().is(AsmToken::LBrac))
1400 return ParseIntelBracExpression(/*SegReg=*/0, Start, ImmDisp, Size);
1401 assert(ImmDisp == 0);
1404 if (!isParsingInlineAsm()) {
1405 if (getParser().parsePrimaryExpr(Val, End))
1406 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1408 return X86Operand::CreateMem(Val, Start, End, Size);
1411 InlineAsmIdentifierInfo Info;
1412 StringRef Identifier = Tok.getString();
1413 if (ParseIntelIdentifier(Val, Identifier, Info,
1414 /*Unevaluated=*/false, End))
1417 if (!getLexer().is(AsmToken::LBrac))
1418 return CreateMemForInlineAsm(/*SegReg=*/0, Val, /*BaseReg=*/0, /*IndexReg=*/0,
1419 /*Scale=*/1, Start, End, Size, Identifier, Info);
1421 Parser.Lex(); // Eat '['
1423 // Parse Identifier [ ImmDisp ]
1424 IntelExprStateMachine SM(/*ImmDisp=*/0, /*StopOnLBrac=*/true,
1425 /*AddImmPrefix=*/false);
1426 if (ParseIntelExpression(SM, End))
1430 Error(Start, "cannot use more than one symbol in memory operand");
1433 if (SM.getBaseReg()) {
1434 Error(Start, "cannot use base register with variable reference");
1437 if (SM.getIndexReg()) {
1438 Error(Start, "cannot use index register with variable reference");
1442 const MCExpr *Disp = MCConstantExpr::Create(SM.getImm(), getContext());
1443 // BaseReg is non-zero to avoid assertions. In the context of inline asm,
1444 // we're pointing to a local variable in memory, so the base register is
1445 // really the frame or stack pointer.
1446 return X86Operand::CreateMem(/*SegReg=*/0, Disp, /*BaseReg=*/1, /*IndexReg=*/0,
1447 /*Scale=*/1, Start, End, Size, Identifier,
1451 /// Parse the '.' operator.
1452 bool X86AsmParser::ParseIntelDotOperator(const MCExpr *Disp,
1453 const MCExpr *&NewDisp) {
1454 const AsmToken &Tok = Parser.getTok();
1455 int64_t OrigDispVal, DotDispVal;
1457 // FIXME: Handle non-constant expressions.
1458 if (const MCConstantExpr *OrigDisp = dyn_cast<MCConstantExpr>(Disp))
1459 OrigDispVal = OrigDisp->getValue();
1461 return Error(Tok.getLoc(), "Non-constant offsets are not supported!");
1463 // Drop the optional '.'.
1464 StringRef DotDispStr = Tok.getString();
1465 if (DotDispStr.startswith("."))
1466 DotDispStr = DotDispStr.drop_front(1);
1468 // .Imm gets lexed as a real.
1469 if (Tok.is(AsmToken::Real)) {
1471 DotDispStr.getAsInteger(10, DotDisp);
1472 DotDispVal = DotDisp.getZExtValue();
1473 } else if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) {
1475 std::pair<StringRef, StringRef> BaseMember = DotDispStr.split('.');
1476 if (SemaCallback->LookupInlineAsmField(BaseMember.first, BaseMember.second,
1478 return Error(Tok.getLoc(), "Unable to lookup field reference!");
1479 DotDispVal = DotDisp;
1481 return Error(Tok.getLoc(), "Unexpected token type!");
1483 if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) {
1484 SMLoc Loc = SMLoc::getFromPointer(DotDispStr.data());
1485 unsigned Len = DotDispStr.size();
1486 unsigned Val = OrigDispVal + DotDispVal;
1487 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_DotOperator, Loc, Len,
1491 NewDisp = MCConstantExpr::Create(OrigDispVal + DotDispVal, getContext());
1495 /// Parse the 'offset' operator. This operator is used to specify the
1496 /// location rather then the content of a variable.
1497 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOffsetOfOperator() {
1498 const AsmToken &Tok = Parser.getTok();
1499 SMLoc OffsetOfLoc = Tok.getLoc();
1500 Parser.Lex(); // Eat offset.
1503 InlineAsmIdentifierInfo Info;
1504 SMLoc Start = Tok.getLoc(), End;
1505 StringRef Identifier = Tok.getString();
1506 if (ParseIntelIdentifier(Val, Identifier, Info,
1507 /*Unevaluated=*/false, End))
1510 // Don't emit the offset operator.
1511 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Skip, OffsetOfLoc, 7));
1513 // The offset operator will have an 'r' constraint, thus we need to create
1514 // register operand to ensure proper matching. Just pick a GPR based on
1515 // the size of a pointer.
1517 is64BitMode() ? X86::RBX : (is32BitMode() ? X86::EBX : X86::BX);
1518 return X86Operand::CreateReg(RegNo, Start, End, /*GetAddress=*/true,
1519 OffsetOfLoc, Identifier, Info.OpDecl);
1522 enum IntelOperatorKind {
1528 /// Parse the 'LENGTH', 'TYPE' and 'SIZE' operators. The LENGTH operator
1529 /// returns the number of elements in an array. It returns the value 1 for
1530 /// non-array variables. The SIZE operator returns the size of a C or C++
1531 /// variable. A variable's size is the product of its LENGTH and TYPE. The
1532 /// TYPE operator returns the size of a C or C++ type or variable. If the
1533 /// variable is an array, TYPE returns the size of a single element.
1534 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperator(unsigned OpKind) {
1535 const AsmToken &Tok = Parser.getTok();
1536 SMLoc TypeLoc = Tok.getLoc();
1537 Parser.Lex(); // Eat operator.
1539 const MCExpr *Val = nullptr;
1540 InlineAsmIdentifierInfo Info;
1541 SMLoc Start = Tok.getLoc(), End;
1542 StringRef Identifier = Tok.getString();
1543 if (ParseIntelIdentifier(Val, Identifier, Info,
1544 /*Unevaluated=*/true, End))
1548 return ErrorOperand(Start, "unable to lookup expression");
1552 default: llvm_unreachable("Unexpected operand kind!");
1553 case IOK_LENGTH: CVal = Info.Length; break;
1554 case IOK_SIZE: CVal = Info.Size; break;
1555 case IOK_TYPE: CVal = Info.Type; break;
1558 // Rewrite the type operator and the C or C++ type or variable in terms of an
1559 // immediate. E.g. TYPE foo -> $$4
1560 unsigned Len = End.getPointer() - TypeLoc.getPointer();
1561 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Imm, TypeLoc, Len, CVal));
1563 const MCExpr *Imm = MCConstantExpr::Create(CVal, getContext());
1564 return X86Operand::CreateImm(Imm, Start, End);
1567 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand() {
1568 const AsmToken &Tok = Parser.getTok();
1571 // Offset, length, type and size operators.
1572 if (isParsingInlineAsm()) {
1573 StringRef AsmTokStr = Tok.getString();
1574 if (AsmTokStr == "offset" || AsmTokStr == "OFFSET")
1575 return ParseIntelOffsetOfOperator();
1576 if (AsmTokStr == "length" || AsmTokStr == "LENGTH")
1577 return ParseIntelOperator(IOK_LENGTH);
1578 if (AsmTokStr == "size" || AsmTokStr == "SIZE")
1579 return ParseIntelOperator(IOK_SIZE);
1580 if (AsmTokStr == "type" || AsmTokStr == "TYPE")
1581 return ParseIntelOperator(IOK_TYPE);
1584 unsigned Size = getIntelMemOperandSize(Tok.getString());
1586 Parser.Lex(); // Eat operand size (e.g., byte, word).
1587 if (Tok.getString() != "PTR" && Tok.getString() != "ptr")
1588 return ErrorOperand(Tok.getLoc(), "Expected 'PTR' or 'ptr' token!");
1589 Parser.Lex(); // Eat ptr.
1591 Start = Tok.getLoc();
1594 if (getLexer().is(AsmToken::Integer) || getLexer().is(AsmToken::Minus) ||
1595 getLexer().is(AsmToken::Tilde) || getLexer().is(AsmToken::LParen)) {
1596 AsmToken StartTok = Tok;
1597 IntelExprStateMachine SM(/*Imm=*/0, /*StopOnLBrac=*/true,
1598 /*AddImmPrefix=*/false);
1599 if (ParseIntelExpression(SM, End))
1602 int64_t Imm = SM.getImm();
1603 if (isParsingInlineAsm()) {
1604 unsigned Len = Tok.getLoc().getPointer() - Start.getPointer();
1605 if (StartTok.getString().size() == Len)
1606 // Just add a prefix if this wasn't a complex immediate expression.
1607 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_ImmPrefix, Start));
1609 // Otherwise, rewrite the complex expression as a single immediate.
1610 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Imm, Start, Len, Imm));
1613 if (getLexer().isNot(AsmToken::LBrac)) {
1614 // If a directional label (ie. 1f or 2b) was parsed above from
1615 // ParseIntelExpression() then SM.getSym() was set to a pointer to
1616 // to the MCExpr with the directional local symbol and this is a
1617 // memory operand not an immediate operand.
1619 return X86Operand::CreateMem(SM.getSym(), Start, End, Size);
1621 const MCExpr *ImmExpr = MCConstantExpr::Create(Imm, getContext());
1622 return X86Operand::CreateImm(ImmExpr, Start, End);
1625 // Only positive immediates are valid.
1627 return ErrorOperand(Start, "expected a positive immediate displacement "
1628 "before bracketed expr.");
1630 // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
1631 return ParseIntelMemOperand(Imm, Start, Size);
1636 if (!ParseRegister(RegNo, Start, End)) {
1637 // If this is a segment register followed by a ':', then this is the start
1638 // of a segment override, otherwise this is a normal register reference.
1639 if (getLexer().isNot(AsmToken::Colon))
1640 return X86Operand::CreateReg(RegNo, Start, End);
1642 return ParseIntelSegmentOverride(/*SegReg=*/RegNo, Start, Size);
1646 return ParseIntelMemOperand(/*Disp=*/0, Start, Size);
1649 std::unique_ptr<X86Operand> X86AsmParser::ParseATTOperand() {
1650 switch (getLexer().getKind()) {
1652 // Parse a memory operand with no segment register.
1653 return ParseMemOperand(0, Parser.getTok().getLoc());
1654 case AsmToken::Percent: {
1655 // Read the register.
1658 if (ParseRegister(RegNo, Start, End)) return nullptr;
1659 if (RegNo == X86::EIZ || RegNo == X86::RIZ) {
1660 Error(Start, "%eiz and %riz can only be used as index registers",
1661 SMRange(Start, End));
1665 // If this is a segment register followed by a ':', then this is the start
1666 // of a memory reference, otherwise this is a normal register reference.
1667 if (getLexer().isNot(AsmToken::Colon))
1668 return X86Operand::CreateReg(RegNo, Start, End);
1670 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo))
1671 return ErrorOperand(Start, "invalid segment register");
1673 getParser().Lex(); // Eat the colon.
1674 return ParseMemOperand(RegNo, Start);
1676 case AsmToken::Dollar: {
1677 // $42 -> immediate.
1678 SMLoc Start = Parser.getTok().getLoc(), End;
1681 if (getParser().parseExpression(Val, End))
1683 return X86Operand::CreateImm(Val, Start, End);
1688 bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands,
1689 const MCParsedAsmOperand &Op) {
1690 if(STI.getFeatureBits() & X86::FeatureAVX512) {
1691 if (getLexer().is(AsmToken::LCurly)) {
1692 // Eat "{" and mark the current place.
1693 const SMLoc consumedToken = consumeToken();
1694 // Distinguish {1to<NUM>} from {%k<NUM>}.
1695 if(getLexer().is(AsmToken::Integer)) {
1696 // Parse memory broadcasting ({1to<NUM>}).
1697 if (getLexer().getTok().getIntVal() != 1)
1698 return !ErrorAndEatStatement(getLexer().getLoc(),
1699 "Expected 1to<NUM> at this point");
1700 Parser.Lex(); // Eat "1" of 1to8
1701 if (!getLexer().is(AsmToken::Identifier) ||
1702 !getLexer().getTok().getIdentifier().startswith("to"))
1703 return !ErrorAndEatStatement(getLexer().getLoc(),
1704 "Expected 1to<NUM> at this point");
1705 // Recognize only reasonable suffixes.
1706 const char *BroadcastPrimitive =
1707 StringSwitch<const char*>(getLexer().getTok().getIdentifier())
1708 .Case("to2", "{1to2}")
1709 .Case("to4", "{1to4}")
1710 .Case("to8", "{1to8}")
1711 .Case("to16", "{1to16}")
1713 if (!BroadcastPrimitive)
1714 return !ErrorAndEatStatement(getLexer().getLoc(),
1715 "Invalid memory broadcast primitive.");
1716 Parser.Lex(); // Eat "toN" of 1toN
1717 if (!getLexer().is(AsmToken::RCurly))
1718 return !ErrorAndEatStatement(getLexer().getLoc(),
1719 "Expected } at this point");
1720 Parser.Lex(); // Eat "}"
1721 Operands.push_back(X86Operand::CreateToken(BroadcastPrimitive,
1723 // No AVX512 specific primitives can pass
1724 // after memory broadcasting, so return.
1727 // Parse mask register {%k1}
1728 Operands.push_back(X86Operand::CreateToken("{", consumedToken));
1729 if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
1730 Operands.push_back(std::move(Op));
1731 if (!getLexer().is(AsmToken::RCurly))
1732 return !ErrorAndEatStatement(getLexer().getLoc(),
1733 "Expected } at this point");
1734 Operands.push_back(X86Operand::CreateToken("}", consumeToken()));
1736 // Parse "zeroing non-masked" semantic {z}
1737 if (getLexer().is(AsmToken::LCurly)) {
1738 Operands.push_back(X86Operand::CreateToken("{z}", consumeToken()));
1739 if (!getLexer().is(AsmToken::Identifier) ||
1740 getLexer().getTok().getIdentifier() != "z")
1741 return !ErrorAndEatStatement(getLexer().getLoc(),
1742 "Expected z at this point");
1743 Parser.Lex(); // Eat the z
1744 if (!getLexer().is(AsmToken::RCurly))
1745 return !ErrorAndEatStatement(getLexer().getLoc(),
1746 "Expected } at this point");
1747 Parser.Lex(); // Eat the }
1756 /// ParseMemOperand: segment: disp(basereg, indexreg, scale). The '%ds:' prefix
1757 /// has already been parsed if present.
1758 std::unique_ptr<X86Operand> X86AsmParser::ParseMemOperand(unsigned SegReg,
1761 // We have to disambiguate a parenthesized expression "(4+5)" from the start
1762 // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)". The
1763 // only way to do this without lookahead is to eat the '(' and see what is
1765 const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext());
1766 if (getLexer().isNot(AsmToken::LParen)) {
1768 if (getParser().parseExpression(Disp, ExprEnd)) return nullptr;
1770 // After parsing the base expression we could either have a parenthesized
1771 // memory address or not. If not, return now. If so, eat the (.
1772 if (getLexer().isNot(AsmToken::LParen)) {
1773 // Unless we have a segment register, treat this as an immediate.
1775 return X86Operand::CreateMem(Disp, MemStart, ExprEnd);
1776 return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd);
1782 // Okay, we have a '('. We don't know if this is an expression or not, but
1783 // so we have to eat the ( to see beyond it.
1784 SMLoc LParenLoc = Parser.getTok().getLoc();
1785 Parser.Lex(); // Eat the '('.
1787 if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) {
1788 // Nothing to do here, fall into the code below with the '(' part of the
1789 // memory operand consumed.
1793 // It must be an parenthesized expression, parse it now.
1794 if (getParser().parseParenExpression(Disp, ExprEnd))
1797 // After parsing the base expression we could either have a parenthesized
1798 // memory address or not. If not, return now. If so, eat the (.
1799 if (getLexer().isNot(AsmToken::LParen)) {
1800 // Unless we have a segment register, treat this as an immediate.
1802 return X86Operand::CreateMem(Disp, LParenLoc, ExprEnd);
1803 return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd);
1811 // If we reached here, then we just ate the ( of the memory operand. Process
1812 // the rest of the memory operand.
1813 unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
1814 SMLoc IndexLoc, BaseLoc;
1816 if (getLexer().is(AsmToken::Percent)) {
1817 SMLoc StartLoc, EndLoc;
1818 BaseLoc = Parser.getTok().getLoc();
1819 if (ParseRegister(BaseReg, StartLoc, EndLoc)) return nullptr;
1820 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) {
1821 Error(StartLoc, "eiz and riz can only be used as index registers",
1822 SMRange(StartLoc, EndLoc));
1827 if (getLexer().is(AsmToken::Comma)) {
1828 Parser.Lex(); // Eat the comma.
1829 IndexLoc = Parser.getTok().getLoc();
1831 // Following the comma we should have either an index register, or a scale
1832 // value. We don't support the later form, but we want to parse it
1835 // Not that even though it would be completely consistent to support syntax
1836 // like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this.
1837 if (getLexer().is(AsmToken::Percent)) {
1839 if (ParseRegister(IndexReg, L, L)) return nullptr;
1841 if (getLexer().isNot(AsmToken::RParen)) {
1842 // Parse the scale amount:
1843 // ::= ',' [scale-expression]
1844 if (getLexer().isNot(AsmToken::Comma)) {
1845 Error(Parser.getTok().getLoc(),
1846 "expected comma in scale expression");
1849 Parser.Lex(); // Eat the comma.
1851 if (getLexer().isNot(AsmToken::RParen)) {
1852 SMLoc Loc = Parser.getTok().getLoc();
1855 if (getParser().parseAbsoluteExpression(ScaleVal)){
1856 Error(Loc, "expected scale expression");
1860 // Validate the scale amount.
1861 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
1863 Error(Loc, "scale factor in 16-bit address must be 1");
1866 if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8){
1867 Error(Loc, "scale factor in address must be 1, 2, 4 or 8");
1870 Scale = (unsigned)ScaleVal;
1873 } else if (getLexer().isNot(AsmToken::RParen)) {
1874 // A scale amount without an index is ignored.
1876 SMLoc Loc = Parser.getTok().getLoc();
1879 if (getParser().parseAbsoluteExpression(Value))
1883 Warning(Loc, "scale factor without index register is ignored");
1888 // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
1889 if (getLexer().isNot(AsmToken::RParen)) {
1890 Error(Parser.getTok().getLoc(), "unexpected token in memory operand");
1893 SMLoc MemEnd = Parser.getTok().getEndLoc();
1894 Parser.Lex(); // Eat the ')'.
1896 // Check for use of invalid 16-bit registers. Only BX/BP/SI/DI are allowed,
1897 // and then only in non-64-bit modes. Except for DX, which is a special case
1898 // because an unofficial form of in/out instructions uses it.
1899 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
1900 (is64BitMode() || (BaseReg != X86::BX && BaseReg != X86::BP &&
1901 BaseReg != X86::SI && BaseReg != X86::DI)) &&
1902 BaseReg != X86::DX) {
1903 Error(BaseLoc, "invalid 16-bit base register");
1907 X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg)) {
1908 Error(IndexLoc, "16-bit memory operand may not include only index register");
1913 if (CheckBaseRegAndIndexReg(BaseReg, IndexReg, ErrMsg)) {
1914 Error(BaseLoc, ErrMsg);
1918 if (SegReg || BaseReg || IndexReg)
1919 return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale,
1921 return X86Operand::CreateMem(Disp, MemStart, MemEnd);
1924 bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
1925 SMLoc NameLoc, OperandVector &Operands) {
1927 StringRef PatchedName = Name;
1929 // FIXME: Hack to recognize setneb as setne.
1930 if (PatchedName.startswith("set") && PatchedName.endswith("b") &&
1931 PatchedName != "setb" && PatchedName != "setnb")
1932 PatchedName = PatchedName.substr(0, Name.size()-1);
1934 // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}.
1935 const MCExpr *ExtraImmOp = nullptr;
1936 if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) &&
1937 (PatchedName.endswith("ss") || PatchedName.endswith("sd") ||
1938 PatchedName.endswith("ps") || PatchedName.endswith("pd"))) {
1939 bool IsVCMP = PatchedName[0] == 'v';
1940 unsigned SSECCIdx = IsVCMP ? 4 : 3;
1941 unsigned SSEComparisonCode = StringSwitch<unsigned>(
1942 PatchedName.slice(SSECCIdx, PatchedName.size() - 2))
1946 .Case("unord", 0x03)
1951 /* AVX only from here */
1952 .Case("eq_uq", 0x08)
1955 .Case("false", 0x0B)
1956 .Case("neq_oq", 0x0C)
1960 .Case("eq_os", 0x10)
1961 .Case("lt_oq", 0x11)
1962 .Case("le_oq", 0x12)
1963 .Case("unord_s", 0x13)
1964 .Case("neq_us", 0x14)
1965 .Case("nlt_uq", 0x15)
1966 .Case("nle_uq", 0x16)
1967 .Case("ord_s", 0x17)
1968 .Case("eq_us", 0x18)
1969 .Case("nge_uq", 0x19)
1970 .Case("ngt_uq", 0x1A)
1971 .Case("false_os", 0x1B)
1972 .Case("neq_os", 0x1C)
1973 .Case("ge_oq", 0x1D)
1974 .Case("gt_oq", 0x1E)
1975 .Case("true_us", 0x1F)
1977 if (SSEComparisonCode != ~0U && (IsVCMP || SSEComparisonCode < 8)) {
1978 ExtraImmOp = MCConstantExpr::Create(SSEComparisonCode,
1979 getParser().getContext());
1980 if (PatchedName.endswith("ss")) {
1981 PatchedName = IsVCMP ? "vcmpss" : "cmpss";
1982 } else if (PatchedName.endswith("sd")) {
1983 PatchedName = IsVCMP ? "vcmpsd" : "cmpsd";
1984 } else if (PatchedName.endswith("ps")) {
1985 PatchedName = IsVCMP ? "vcmpps" : "cmpps";
1987 assert(PatchedName.endswith("pd") && "Unexpected mnemonic!");
1988 PatchedName = IsVCMP ? "vcmppd" : "cmppd";
1993 Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
1995 if (ExtraImmOp && !isParsingIntelSyntax())
1996 Operands.push_back(X86Operand::CreateImm(ExtraImmOp, NameLoc, NameLoc));
1998 // Determine whether this is an instruction prefix.
2000 Name == "lock" || Name == "rep" ||
2001 Name == "repe" || Name == "repz" ||
2002 Name == "repne" || Name == "repnz" ||
2003 Name == "rex64" || Name == "data16";
2006 // This does the actual operand parsing. Don't parse any more if we have a
2007 // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we
2008 // just want to parse the "lock" as the first instruction and the "incl" as
2010 if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) {
2012 // Parse '*' modifier.
2013 if (getLexer().is(AsmToken::Star))
2014 Operands.push_back(X86Operand::CreateToken("*", consumeToken()));
2016 // Read the operands.
2018 if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
2019 Operands.push_back(std::move(Op));
2020 if (!HandleAVX512Operand(Operands, *Operands.back()))
2023 Parser.eatToEndOfStatement();
2026 // check for comma and eat it
2027 if (getLexer().is(AsmToken::Comma))
2033 if (getLexer().isNot(AsmToken::EndOfStatement))
2034 return ErrorAndEatStatement(getLexer().getLoc(),
2035 "unexpected token in argument list");
2038 // Consume the EndOfStatement or the prefix separator Slash
2039 if (getLexer().is(AsmToken::EndOfStatement) ||
2040 (isPrefix && getLexer().is(AsmToken::Slash)))
2043 if (ExtraImmOp && isParsingIntelSyntax())
2044 Operands.push_back(X86Operand::CreateImm(ExtraImmOp, NameLoc, NameLoc));
2046 // This is a terrible hack to handle "out[bwl]? %al, (%dx)" ->
2047 // "outb %al, %dx". Out doesn't take a memory form, but this is a widely
2048 // documented form in various unofficial manuals, so a lot of code uses it.
2049 if ((Name == "outb" || Name == "outw" || Name == "outl" || Name == "out") &&
2050 Operands.size() == 3) {
2051 X86Operand &Op = (X86Operand &)*Operands.back();
2052 if (Op.isMem() && Op.Mem.SegReg == 0 &&
2053 isa<MCConstantExpr>(Op.Mem.Disp) &&
2054 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
2055 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
2056 SMLoc Loc = Op.getEndLoc();
2057 Operands.back() = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
2060 // Same hack for "in[bwl]? (%dx), %al" -> "inb %dx, %al".
2061 if ((Name == "inb" || Name == "inw" || Name == "inl" || Name == "in") &&
2062 Operands.size() == 3) {
2063 X86Operand &Op = (X86Operand &)*Operands[1];
2064 if (Op.isMem() && Op.Mem.SegReg == 0 &&
2065 isa<MCConstantExpr>(Op.Mem.Disp) &&
2066 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
2067 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
2068 SMLoc Loc = Op.getEndLoc();
2069 Operands[1] = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
2073 // Append default arguments to "ins[bwld]"
2074 if (Name.startswith("ins") && Operands.size() == 1 &&
2075 (Name == "insb" || Name == "insw" || Name == "insl" ||
2077 if (isParsingIntelSyntax()) {
2078 Operands.push_back(X86Operand::CreateReg(X86::DX, NameLoc, NameLoc));
2079 Operands.push_back(DefaultMemDIOperand(NameLoc));
2081 Operands.push_back(X86Operand::CreateReg(X86::DX, NameLoc, NameLoc));
2082 Operands.push_back(DefaultMemDIOperand(NameLoc));
2086 // Append default arguments to "outs[bwld]"
2087 if (Name.startswith("outs") && Operands.size() == 1 &&
2088 (Name == "outsb" || Name == "outsw" || Name == "outsl" ||
2089 Name == "outsd" )) {
2090 if (isParsingIntelSyntax()) {
2091 Operands.push_back(DefaultMemSIOperand(NameLoc));
2092 Operands.push_back(X86Operand::CreateReg(X86::DX, NameLoc, NameLoc));
2094 Operands.push_back(DefaultMemSIOperand(NameLoc));
2095 Operands.push_back(X86Operand::CreateReg(X86::DX, NameLoc, NameLoc));
2099 // Transform "lods[bwlq]" into "lods[bwlq] ($SIREG)" for appropriate
2100 // values of $SIREG according to the mode. It would be nice if this
2101 // could be achieved with InstAlias in the tables.
2102 if (Name.startswith("lods") && Operands.size() == 1 &&
2103 (Name == "lods" || Name == "lodsb" || Name == "lodsw" ||
2104 Name == "lodsl" || Name == "lodsd" || Name == "lodsq"))
2105 Operands.push_back(DefaultMemSIOperand(NameLoc));
2107 // Transform "stos[bwlq]" into "stos[bwlq] ($DIREG)" for appropriate
2108 // values of $DIREG according to the mode. It would be nice if this
2109 // could be achieved with InstAlias in the tables.
2110 if (Name.startswith("stos") && Operands.size() == 1 &&
2111 (Name == "stos" || Name == "stosb" || Name == "stosw" ||
2112 Name == "stosl" || Name == "stosd" || Name == "stosq"))
2113 Operands.push_back(DefaultMemDIOperand(NameLoc));
2115 // Transform "scas[bwlq]" into "scas[bwlq] ($DIREG)" for appropriate
2116 // values of $DIREG according to the mode. It would be nice if this
2117 // could be achieved with InstAlias in the tables.
2118 if (Name.startswith("scas") && Operands.size() == 1 &&
2119 (Name == "scas" || Name == "scasb" || Name == "scasw" ||
2120 Name == "scasl" || Name == "scasd" || Name == "scasq"))
2121 Operands.push_back(DefaultMemDIOperand(NameLoc));
2123 // Add default SI and DI operands to "cmps[bwlq]".
2124 if (Name.startswith("cmps") &&
2125 (Name == "cmps" || Name == "cmpsb" || Name == "cmpsw" ||
2126 Name == "cmpsl" || Name == "cmpsd" || Name == "cmpsq")) {
2127 if (Operands.size() == 1) {
2128 if (isParsingIntelSyntax()) {
2129 Operands.push_back(DefaultMemSIOperand(NameLoc));
2130 Operands.push_back(DefaultMemDIOperand(NameLoc));
2132 Operands.push_back(DefaultMemDIOperand(NameLoc));
2133 Operands.push_back(DefaultMemSIOperand(NameLoc));
2135 } else if (Operands.size() == 3) {
2136 X86Operand &Op = (X86Operand &)*Operands[1];
2137 X86Operand &Op2 = (X86Operand &)*Operands[2];
2138 if (!doSrcDstMatch(Op, Op2))
2139 return Error(Op.getStartLoc(),
2140 "mismatching source and destination index registers");
2144 // Add default SI and DI operands to "movs[bwlq]".
2145 if ((Name.startswith("movs") &&
2146 (Name == "movs" || Name == "movsb" || Name == "movsw" ||
2147 Name == "movsl" || Name == "movsd" || Name == "movsq")) ||
2148 (Name.startswith("smov") &&
2149 (Name == "smov" || Name == "smovb" || Name == "smovw" ||
2150 Name == "smovl" || Name == "smovd" || Name == "smovq"))) {
2151 if (Operands.size() == 1) {
2152 if (Name == "movsd")
2153 Operands.back() = X86Operand::CreateToken("movsl", NameLoc);
2154 if (isParsingIntelSyntax()) {
2155 Operands.push_back(DefaultMemDIOperand(NameLoc));
2156 Operands.push_back(DefaultMemSIOperand(NameLoc));
2158 Operands.push_back(DefaultMemSIOperand(NameLoc));
2159 Operands.push_back(DefaultMemDIOperand(NameLoc));
2161 } else if (Operands.size() == 3) {
2162 X86Operand &Op = (X86Operand &)*Operands[1];
2163 X86Operand &Op2 = (X86Operand &)*Operands[2];
2164 if (!doSrcDstMatch(Op, Op2))
2165 return Error(Op.getStartLoc(),
2166 "mismatching source and destination index registers");
2170 // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>. Canonicalize to
2172 if ((Name.startswith("shr") || Name.startswith("sar") ||
2173 Name.startswith("shl") || Name.startswith("sal") ||
2174 Name.startswith("rcl") || Name.startswith("rcr") ||
2175 Name.startswith("rol") || Name.startswith("ror")) &&
2176 Operands.size() == 3) {
2177 if (isParsingIntelSyntax()) {
2179 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[2]);
2180 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2181 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2182 Operands.pop_back();
2184 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2185 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2186 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2187 Operands.erase(Operands.begin() + 1);
2191 // Transforms "int $3" into "int3" as a size optimization. We can't write an
2192 // instalias with an immediate operand yet.
2193 if (Name == "int" && Operands.size() == 2) {
2194 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2195 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2196 cast<MCConstantExpr>(Op1.getImm())->getValue() == 3) {
2197 Operands.erase(Operands.begin() + 1);
2198 static_cast<X86Operand &>(*Operands[0]).setTokenValue("int3");
2205 static bool convertToSExti8(MCInst &Inst, unsigned Opcode, unsigned Reg,
2208 TmpInst.setOpcode(Opcode);
2210 TmpInst.addOperand(MCOperand::CreateReg(Reg));
2211 TmpInst.addOperand(MCOperand::CreateReg(Reg));
2212 TmpInst.addOperand(Inst.getOperand(0));
2217 static bool convert16i16to16ri8(MCInst &Inst, unsigned Opcode,
2218 bool isCmp = false) {
2219 if (!Inst.getOperand(0).isImm() ||
2220 !isImmSExti16i8Value(Inst.getOperand(0).getImm()))
2223 return convertToSExti8(Inst, Opcode, X86::AX, isCmp);
2226 static bool convert32i32to32ri8(MCInst &Inst, unsigned Opcode,
2227 bool isCmp = false) {
2228 if (!Inst.getOperand(0).isImm() ||
2229 !isImmSExti32i8Value(Inst.getOperand(0).getImm()))
2232 return convertToSExti8(Inst, Opcode, X86::EAX, isCmp);
2235 static bool convert64i32to64ri8(MCInst &Inst, unsigned Opcode,
2236 bool isCmp = false) {
2237 if (!Inst.getOperand(0).isImm() ||
2238 !isImmSExti64i8Value(Inst.getOperand(0).getImm()))
2241 return convertToSExti8(Inst, Opcode, X86::RAX, isCmp);
2244 bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) {
2245 switch (Inst.getOpcode()) {
2246 default: return false;
2247 case X86::AND16i16: return convert16i16to16ri8(Inst, X86::AND16ri8);
2248 case X86::AND32i32: return convert32i32to32ri8(Inst, X86::AND32ri8);
2249 case X86::AND64i32: return convert64i32to64ri8(Inst, X86::AND64ri8);
2250 case X86::XOR16i16: return convert16i16to16ri8(Inst, X86::XOR16ri8);
2251 case X86::XOR32i32: return convert32i32to32ri8(Inst, X86::XOR32ri8);
2252 case X86::XOR64i32: return convert64i32to64ri8(Inst, X86::XOR64ri8);
2253 case X86::OR16i16: return convert16i16to16ri8(Inst, X86::OR16ri8);
2254 case X86::OR32i32: return convert32i32to32ri8(Inst, X86::OR32ri8);
2255 case X86::OR64i32: return convert64i32to64ri8(Inst, X86::OR64ri8);
2256 case X86::CMP16i16: return convert16i16to16ri8(Inst, X86::CMP16ri8, true);
2257 case X86::CMP32i32: return convert32i32to32ri8(Inst, X86::CMP32ri8, true);
2258 case X86::CMP64i32: return convert64i32to64ri8(Inst, X86::CMP64ri8, true);
2259 case X86::ADD16i16: return convert16i16to16ri8(Inst, X86::ADD16ri8);
2260 case X86::ADD32i32: return convert32i32to32ri8(Inst, X86::ADD32ri8);
2261 case X86::ADD64i32: return convert64i32to64ri8(Inst, X86::ADD64ri8);
2262 case X86::SUB16i16: return convert16i16to16ri8(Inst, X86::SUB16ri8);
2263 case X86::SUB32i32: return convert32i32to32ri8(Inst, X86::SUB32ri8);
2264 case X86::SUB64i32: return convert64i32to64ri8(Inst, X86::SUB64ri8);
2265 case X86::ADC16i16: return convert16i16to16ri8(Inst, X86::ADC16ri8);
2266 case X86::ADC32i32: return convert32i32to32ri8(Inst, X86::ADC32ri8);
2267 case X86::ADC64i32: return convert64i32to64ri8(Inst, X86::ADC64ri8);
2268 case X86::SBB16i16: return convert16i16to16ri8(Inst, X86::SBB16ri8);
2269 case X86::SBB32i32: return convert32i32to32ri8(Inst, X86::SBB32ri8);
2270 case X86::SBB64i32: return convert64i32to64ri8(Inst, X86::SBB64ri8);
2271 case X86::VMOVAPDrr:
2272 case X86::VMOVAPDYrr:
2273 case X86::VMOVAPSrr:
2274 case X86::VMOVAPSYrr:
2275 case X86::VMOVDQArr:
2276 case X86::VMOVDQAYrr:
2277 case X86::VMOVDQUrr:
2278 case X86::VMOVDQUYrr:
2279 case X86::VMOVUPDrr:
2280 case X86::VMOVUPDYrr:
2281 case X86::VMOVUPSrr:
2282 case X86::VMOVUPSYrr: {
2283 if (X86II::isX86_64ExtendedReg(Inst.getOperand(0).getReg()) ||
2284 !X86II::isX86_64ExtendedReg(Inst.getOperand(1).getReg()))
2288 switch (Inst.getOpcode()) {
2289 default: llvm_unreachable("Invalid opcode");
2290 case X86::VMOVAPDrr: NewOpc = X86::VMOVAPDrr_REV; break;
2291 case X86::VMOVAPDYrr: NewOpc = X86::VMOVAPDYrr_REV; break;
2292 case X86::VMOVAPSrr: NewOpc = X86::VMOVAPSrr_REV; break;
2293 case X86::VMOVAPSYrr: NewOpc = X86::VMOVAPSYrr_REV; break;
2294 case X86::VMOVDQArr: NewOpc = X86::VMOVDQArr_REV; break;
2295 case X86::VMOVDQAYrr: NewOpc = X86::VMOVDQAYrr_REV; break;
2296 case X86::VMOVDQUrr: NewOpc = X86::VMOVDQUrr_REV; break;
2297 case X86::VMOVDQUYrr: NewOpc = X86::VMOVDQUYrr_REV; break;
2298 case X86::VMOVUPDrr: NewOpc = X86::VMOVUPDrr_REV; break;
2299 case X86::VMOVUPDYrr: NewOpc = X86::VMOVUPDYrr_REV; break;
2300 case X86::VMOVUPSrr: NewOpc = X86::VMOVUPSrr_REV; break;
2301 case X86::VMOVUPSYrr: NewOpc = X86::VMOVUPSYrr_REV; break;
2303 Inst.setOpcode(NewOpc);
2307 case X86::VMOVSSrr: {
2308 if (X86II::isX86_64ExtendedReg(Inst.getOperand(0).getReg()) ||
2309 !X86II::isX86_64ExtendedReg(Inst.getOperand(2).getReg()))
2312 switch (Inst.getOpcode()) {
2313 default: llvm_unreachable("Invalid opcode");
2314 case X86::VMOVSDrr: NewOpc = X86::VMOVSDrr_REV; break;
2315 case X86::VMOVSSrr: NewOpc = X86::VMOVSSrr_REV; break;
2317 Inst.setOpcode(NewOpc);
2323 static const char *getSubtargetFeatureName(uint64_t Val);
2325 void X86AsmParser::EmitInstruction(MCInst &Inst, OperandVector &Operands,
2327 Instrumentation->InstrumentAndEmitInstruction(Inst, Operands, getContext(),
2331 bool X86AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2332 OperandVector &Operands,
2333 MCStreamer &Out, uint64_t &ErrorInfo,
2334 bool MatchingInlineAsm) {
2335 if (isParsingIntelSyntax())
2336 return MatchAndEmitIntelInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2338 return MatchAndEmitATTInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2342 void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op,
2343 OperandVector &Operands, MCStreamer &Out,
2344 bool MatchingInlineAsm) {
2345 // FIXME: This should be replaced with a real .td file alias mechanism.
2346 // Also, MatchInstructionImpl should actually *do* the EmitInstruction
2348 const char *Repl = StringSwitch<const char *>(Op.getToken())
2349 .Case("finit", "fninit")
2350 .Case("fsave", "fnsave")
2351 .Case("fstcw", "fnstcw")
2352 .Case("fstcww", "fnstcw")
2353 .Case("fstenv", "fnstenv")
2354 .Case("fstsw", "fnstsw")
2355 .Case("fstsww", "fnstsw")
2356 .Case("fclex", "fnclex")
2360 Inst.setOpcode(X86::WAIT);
2362 if (!MatchingInlineAsm)
2363 EmitInstruction(Inst, Operands, Out);
2364 Operands[0] = X86Operand::CreateToken(Repl, IDLoc);
2368 bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
2369 bool MatchingInlineAsm) {
2370 assert(ErrorInfo && "Unknown missing feature!");
2371 ArrayRef<SMRange> EmptyRanges = None;
2372 SmallString<126> Msg;
2373 raw_svector_ostream OS(Msg);
2374 OS << "instruction requires:";
2376 for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
2377 if (ErrorInfo & Mask)
2378 OS << ' ' << getSubtargetFeatureName(ErrorInfo & Mask);
2381 return Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
2384 bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
2385 OperandVector &Operands,
2387 uint64_t &ErrorInfo,
2388 bool MatchingInlineAsm) {
2389 assert(!Operands.empty() && "Unexpect empty operand list!");
2390 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2391 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
2392 ArrayRef<SMRange> EmptyRanges = None;
2394 // First, handle aliases that expand to multiple instructions.
2395 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2397 bool WasOriginallyInvalidOperand = false;
2400 // First, try a direct match.
2401 switch (MatchInstructionImpl(Operands, Inst,
2402 ErrorInfo, MatchingInlineAsm,
2403 isParsingIntelSyntax())) {
2406 // Some instructions need post-processing to, for example, tweak which
2407 // encoding is selected. Loop on it while changes happen so the
2408 // individual transformations can chain off each other.
2409 if (!MatchingInlineAsm)
2410 while (processInstruction(Inst, Operands))
2414 if (!MatchingInlineAsm)
2415 EmitInstruction(Inst, Operands, Out);
2416 Opcode = Inst.getOpcode();
2418 case Match_MissingFeature:
2419 return ErrorMissingFeature(IDLoc, ErrorInfo, MatchingInlineAsm);
2420 case Match_InvalidOperand:
2421 WasOriginallyInvalidOperand = true;
2423 case Match_MnemonicFail:
2427 // FIXME: Ideally, we would only attempt suffix matches for things which are
2428 // valid prefixes, and we could just infer the right unambiguous
2429 // type. However, that requires substantially more matcher support than the
2432 // Change the operand to point to a temporary token.
2433 StringRef Base = Op.getToken();
2434 SmallString<16> Tmp;
2437 Op.setTokenValue(Tmp.str());
2439 // If this instruction starts with an 'f', then it is a floating point stack
2440 // instruction. These come in up to three forms for 32-bit, 64-bit, and
2441 // 80-bit floating point, which use the suffixes s,l,t respectively.
2443 // Otherwise, we assume that this may be an integer instruction, which comes
2444 // in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively.
2445 const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0";
2447 // Check for the various suffix matches.
2448 uint64_t ErrorInfoIgnore;
2449 uint64_t ErrorInfoMissingFeature = 0; // Init suppresses compiler warnings.
2452 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I) {
2453 Tmp.back() = Suffixes[I];
2454 Match[I] = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
2455 MatchingInlineAsm, isParsingIntelSyntax());
2456 // If this returned as a missing feature failure, remember that.
2457 if (Match[I] == Match_MissingFeature)
2458 ErrorInfoMissingFeature = ErrorInfoIgnore;
2461 // Restore the old token.
2462 Op.setTokenValue(Base);
2464 // If exactly one matched, then we treat that as a successful match (and the
2465 // instruction will already have been filled in correctly, since the failing
2466 // matches won't have modified it).
2467 unsigned NumSuccessfulMatches =
2468 std::count(std::begin(Match), std::end(Match), Match_Success);
2469 if (NumSuccessfulMatches == 1) {
2471 if (!MatchingInlineAsm)
2472 EmitInstruction(Inst, Operands, Out);
2473 Opcode = Inst.getOpcode();
2477 // Otherwise, the match failed, try to produce a decent error message.
2479 // If we had multiple suffix matches, then identify this as an ambiguous
2481 if (NumSuccessfulMatches > 1) {
2483 unsigned NumMatches = 0;
2484 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I)
2485 if (Match[I] == Match_Success)
2486 MatchChars[NumMatches++] = Suffixes[I];
2488 SmallString<126> Msg;
2489 raw_svector_ostream OS(Msg);
2490 OS << "ambiguous instructions require an explicit suffix (could be ";
2491 for (unsigned i = 0; i != NumMatches; ++i) {
2494 if (i + 1 == NumMatches)
2496 OS << "'" << Base << MatchChars[i] << "'";
2499 Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
2503 // Okay, we know that none of the variants matched successfully.
2505 // If all of the instructions reported an invalid mnemonic, then the original
2506 // mnemonic was invalid.
2507 if (std::count(std::begin(Match), std::end(Match), Match_MnemonicFail) == 4) {
2508 if (!WasOriginallyInvalidOperand) {
2509 ArrayRef<SMRange> Ranges =
2510 MatchingInlineAsm ? EmptyRanges : Op.getLocRange();
2511 return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'",
2512 Ranges, MatchingInlineAsm);
2515 // Recover location info for the operand if we know which was the problem.
2516 if (ErrorInfo != ~0ULL) {
2517 if (ErrorInfo >= Operands.size())
2518 return Error(IDLoc, "too few operands for instruction",
2519 EmptyRanges, MatchingInlineAsm);
2521 X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo];
2522 if (Operand.getStartLoc().isValid()) {
2523 SMRange OperandRange = Operand.getLocRange();
2524 return Error(Operand.getStartLoc(), "invalid operand for instruction",
2525 OperandRange, MatchingInlineAsm);
2529 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2533 // If one instruction matched with a missing feature, report this as a
2535 if (std::count(std::begin(Match), std::end(Match),
2536 Match_MissingFeature) == 1) {
2537 ErrorInfo = ErrorInfoMissingFeature;
2538 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
2542 // If one instruction matched with an invalid operand, report this as an
2544 if (std::count(std::begin(Match), std::end(Match),
2545 Match_InvalidOperand) == 1) {
2546 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2550 // If all of these were an outright failure, report it in a useless way.
2551 Error(IDLoc, "unknown use of instruction mnemonic without a size suffix",
2552 EmptyRanges, MatchingInlineAsm);
2556 bool X86AsmParser::MatchAndEmitIntelInstruction(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 StringRef Mnemonic = Op.getToken();
2565 ArrayRef<SMRange> EmptyRanges = None;
2567 // First, handle aliases that expand to multiple instructions.
2568 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2572 // Find one unsized memory operand, if present.
2573 X86Operand *UnsizedMemOp = nullptr;
2574 for (const auto &Op : Operands) {
2575 X86Operand *X86Op = static_cast<X86Operand *>(Op.get());
2576 // FIXME: Remove this exception for absolute memory references. Currently it
2577 // allows us to assemble 'call foo', because foo is represented as a memory
2579 if (X86Op->isMemUnsized() && !X86Op->isAbsMem())
2580 UnsizedMemOp = X86Op;
2583 // Allow some instructions to have implicitly pointer-sized operands. This is
2584 // compatible with gas.
2586 static const char *const PtrSizedInstrs[] = {"call", "jmp", "push"};
2587 for (const char *Instr : PtrSizedInstrs) {
2588 if (Mnemonic == Instr) {
2589 UnsizedMemOp->Mem.Size = getPointerSize();
2595 // If an unsized memory operand is present, try to match with each memory
2596 // operand size. In Intel assembly, the size is not part of the instruction
2598 SmallVector<unsigned, 8> Match;
2599 uint64_t ErrorInfoMissingFeature = 0;
2600 if (UnsizedMemOp && UnsizedMemOp->isMemUnsized()) {
2601 static const unsigned MopSizes[] = {8, 16, 32, 64, 80};
2602 for (unsigned Size : MopSizes) {
2603 UnsizedMemOp->Mem.Size = Size;
2604 uint64_t ErrorInfoIgnore;
2605 Match.push_back(MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
2607 isParsingIntelSyntax()));
2608 // If this returned as a missing feature failure, remember that.
2609 if (Match.back() == Match_MissingFeature)
2610 ErrorInfoMissingFeature = ErrorInfoIgnore;
2613 Match.push_back(MatchInstructionImpl(Operands, Inst, ErrorInfo,
2615 isParsingIntelSyntax()));
2616 // If this returned as a missing feature failure, remember that.
2617 if (Match.back() == Match_MissingFeature)
2618 ErrorInfoMissingFeature = ErrorInfo;
2621 // Restore the size of the unsized memory operand if we modified it.
2623 UnsizedMemOp->Mem.Size = 0;
2625 // If it's a bad mnemonic, all results will be the same.
2626 if (Match.back() == Match_MnemonicFail) {
2627 ArrayRef<SMRange> Ranges =
2628 MatchingInlineAsm ? EmptyRanges : Op.getLocRange();
2629 return Error(IDLoc, "invalid instruction mnemonic '" + Mnemonic + "'",
2630 Ranges, MatchingInlineAsm);
2633 // If exactly one matched, then we treat that as a successful match (and the
2634 // instruction will already have been filled in correctly, since the failing
2635 // matches won't have modified it).
2636 unsigned NumSuccessfulMatches =
2637 std::count(std::begin(Match), std::end(Match), Match_Success);
2638 if (NumSuccessfulMatches == 1) {
2639 // Some instructions need post-processing to, for example, tweak which
2640 // encoding is selected. Loop on it while changes happen so the individual
2641 // transformations can chain off each other.
2642 if (!MatchingInlineAsm)
2643 while (processInstruction(Inst, Operands))
2646 if (!MatchingInlineAsm)
2647 EmitInstruction(Inst, Operands, Out);
2648 Opcode = Inst.getOpcode();
2650 } else if (NumSuccessfulMatches > 1) {
2651 assert(UnsizedMemOp &&
2652 "multiple matches only possible with unsized memory operands");
2653 ArrayRef<SMRange> Ranges =
2654 MatchingInlineAsm ? EmptyRanges : UnsizedMemOp->getLocRange();
2655 return Error(UnsizedMemOp->getStartLoc(),
2656 "ambiguous operand size for instruction '" + Mnemonic + "\'",
2657 Ranges, MatchingInlineAsm);
2660 // If one instruction matched with a missing feature, report this as a
2662 if (std::count(std::begin(Match), std::end(Match),
2663 Match_MissingFeature) == 1) {
2664 ErrorInfo = ErrorInfoMissingFeature;
2665 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
2669 // If one instruction matched with an invalid operand, report this as an
2671 if (std::count(std::begin(Match), std::end(Match),
2672 Match_InvalidOperand) == 1) {
2673 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2677 // If all of these were an outright failure, report it in a useless way.
2678 return Error(IDLoc, "unknown instruction mnemonic", EmptyRanges,
2682 bool X86AsmParser::OmitRegisterFromClobberLists(unsigned RegNo) {
2683 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo);
2686 bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
2687 StringRef IDVal = DirectiveID.getIdentifier();
2688 if (IDVal == ".word")
2689 return ParseDirectiveWord(2, DirectiveID.getLoc());
2690 else if (IDVal.startswith(".code"))
2691 return ParseDirectiveCode(IDVal, DirectiveID.getLoc());
2692 else if (IDVal.startswith(".att_syntax")) {
2693 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2694 if (Parser.getTok().getString() == "prefix")
2696 else if (Parser.getTok().getString() == "noprefix")
2697 return Error(DirectiveID.getLoc(), "'.att_syntax noprefix' is not "
2698 "supported: registers must have a "
2699 "'%' prefix in .att_syntax");
2701 getParser().setAssemblerDialect(0);
2703 } else if (IDVal.startswith(".intel_syntax")) {
2704 getParser().setAssemblerDialect(1);
2705 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2706 if (Parser.getTok().getString() == "noprefix")
2708 else if (Parser.getTok().getString() == "prefix")
2709 return Error(DirectiveID.getLoc(), "'.intel_syntax prefix' is not "
2710 "supported: registers must not have "
2711 "a '%' prefix in .intel_syntax");
2718 /// ParseDirectiveWord
2719 /// ::= .word [ expression (, expression)* ]
2720 bool X86AsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
2721 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2723 const MCExpr *Value;
2724 if (getParser().parseExpression(Value))
2727 getParser().getStreamer().EmitValue(Value, Size);
2729 if (getLexer().is(AsmToken::EndOfStatement))
2732 // FIXME: Improve diagnostic.
2733 if (getLexer().isNot(AsmToken::Comma)) {
2734 Error(L, "unexpected token in directive");
2745 /// ParseDirectiveCode
2746 /// ::= .code16 | .code32 | .code64
2747 bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
2748 if (IDVal == ".code16") {
2750 if (!is16BitMode()) {
2751 SwitchMode(X86::Mode16Bit);
2752 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
2754 } else if (IDVal == ".code32") {
2756 if (!is32BitMode()) {
2757 SwitchMode(X86::Mode32Bit);
2758 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
2760 } else if (IDVal == ".code64") {
2762 if (!is64BitMode()) {
2763 SwitchMode(X86::Mode64Bit);
2764 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code64);
2767 Error(L, "unknown directive " + IDVal);
2774 // Force static initialization.
2775 extern "C" void LLVMInitializeX86AsmParser() {
2776 RegisterMCAsmParser<X86AsmParser> X(TheX86_32Target);
2777 RegisterMCAsmParser<X86AsmParser> Y(TheX86_64Target);
2780 #define GET_REGISTER_MATCHER
2781 #define GET_MATCHER_IMPLEMENTATION
2782 #define GET_SUBTARGET_FEATURE_NAME
2783 #include "X86GenAsmMatcher.inc"