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 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 void SetFrameRegister(unsigned RegNo) override;
793 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
794 SMLoc NameLoc, OperandVector &Operands) override;
796 bool ParseDirective(AsmToken DirectiveID) override;
798 } // end anonymous namespace
800 /// @name Auto-generated Match Functions
803 static unsigned MatchRegisterName(StringRef Name);
807 static bool CheckBaseRegAndIndexReg(unsigned BaseReg, unsigned IndexReg,
809 // If we have both a base register and an index register make sure they are
810 // both 64-bit or 32-bit registers.
811 // To support VSIB, IndexReg can be 128-bit or 256-bit registers.
812 if (BaseReg != 0 && IndexReg != 0) {
813 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) &&
814 (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
815 X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg)) &&
816 IndexReg != X86::RIZ) {
817 ErrMsg = "base register is 64-bit, but index register is not";
820 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg) &&
821 (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
822 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) &&
823 IndexReg != X86::EIZ){
824 ErrMsg = "base register is 32-bit, but index register is not";
827 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg)) {
828 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg) ||
829 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) {
830 ErrMsg = "base register is 16-bit, but index register is not";
833 if (((BaseReg == X86::BX || BaseReg == X86::BP) &&
834 IndexReg != X86::SI && IndexReg != X86::DI) ||
835 ((BaseReg == X86::SI || BaseReg == X86::DI) &&
836 IndexReg != X86::BX && IndexReg != X86::BP)) {
837 ErrMsg = "invalid 16-bit base/index register combination";
845 bool X86AsmParser::doSrcDstMatch(X86Operand &Op1, X86Operand &Op2)
847 // Return true and let a normal complaint about bogus operands happen.
848 if (!Op1.isMem() || !Op2.isMem())
851 // Actually these might be the other way round if Intel syntax is
852 // being used. It doesn't matter.
853 unsigned diReg = Op1.Mem.BaseReg;
854 unsigned siReg = Op2.Mem.BaseReg;
856 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(siReg))
857 return X86MCRegisterClasses[X86::GR16RegClassID].contains(diReg);
858 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(siReg))
859 return X86MCRegisterClasses[X86::GR32RegClassID].contains(diReg);
860 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(siReg))
861 return X86MCRegisterClasses[X86::GR64RegClassID].contains(diReg);
862 // Again, return true and let another error happen.
866 bool X86AsmParser::ParseRegister(unsigned &RegNo,
867 SMLoc &StartLoc, SMLoc &EndLoc) {
869 const AsmToken &PercentTok = Parser.getTok();
870 StartLoc = PercentTok.getLoc();
872 // If we encounter a %, ignore it. This code handles registers with and
873 // without the prefix, unprefixed registers can occur in cfi directives.
874 if (!isParsingIntelSyntax() && PercentTok.is(AsmToken::Percent))
875 Parser.Lex(); // Eat percent token.
877 const AsmToken &Tok = Parser.getTok();
878 EndLoc = Tok.getEndLoc();
880 if (Tok.isNot(AsmToken::Identifier)) {
881 if (isParsingIntelSyntax()) return true;
882 return Error(StartLoc, "invalid register name",
883 SMRange(StartLoc, EndLoc));
886 RegNo = MatchRegisterName(Tok.getString());
888 // If the match failed, try the register name as lowercase.
890 RegNo = MatchRegisterName(Tok.getString().lower());
892 if (!is64BitMode()) {
893 // FIXME: This should be done using Requires<Not64BitMode> and
894 // Requires<In64BitMode> so "eiz" usage in 64-bit instructions can be also
896 // FIXME: Check AH, CH, DH, BH cannot be used in an instruction requiring a
898 if (RegNo == X86::RIZ ||
899 X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo) ||
900 X86II::isX86_64NonExtLowByteReg(RegNo) ||
901 X86II::isX86_64ExtendedReg(RegNo))
902 return Error(StartLoc, "register %"
903 + Tok.getString() + " is only available in 64-bit mode",
904 SMRange(StartLoc, EndLoc));
907 // Parse "%st" as "%st(0)" and "%st(1)", which is multiple tokens.
908 if (RegNo == 0 && (Tok.getString() == "st" || Tok.getString() == "ST")) {
910 Parser.Lex(); // Eat 'st'
912 // Check to see if we have '(4)' after %st.
913 if (getLexer().isNot(AsmToken::LParen))
918 const AsmToken &IntTok = Parser.getTok();
919 if (IntTok.isNot(AsmToken::Integer))
920 return Error(IntTok.getLoc(), "expected stack index");
921 switch (IntTok.getIntVal()) {
922 case 0: RegNo = X86::ST0; break;
923 case 1: RegNo = X86::ST1; break;
924 case 2: RegNo = X86::ST2; break;
925 case 3: RegNo = X86::ST3; break;
926 case 4: RegNo = X86::ST4; break;
927 case 5: RegNo = X86::ST5; break;
928 case 6: RegNo = X86::ST6; break;
929 case 7: RegNo = X86::ST7; break;
930 default: return Error(IntTok.getLoc(), "invalid stack index");
933 if (getParser().Lex().isNot(AsmToken::RParen))
934 return Error(Parser.getTok().getLoc(), "expected ')'");
936 EndLoc = Parser.getTok().getEndLoc();
937 Parser.Lex(); // Eat ')'
941 EndLoc = Parser.getTok().getEndLoc();
943 // If this is "db[0-7]", match it as an alias
945 if (RegNo == 0 && Tok.getString().size() == 3 &&
946 Tok.getString().startswith("db")) {
947 switch (Tok.getString()[2]) {
948 case '0': RegNo = X86::DR0; break;
949 case '1': RegNo = X86::DR1; break;
950 case '2': RegNo = X86::DR2; break;
951 case '3': RegNo = X86::DR3; break;
952 case '4': RegNo = X86::DR4; break;
953 case '5': RegNo = X86::DR5; break;
954 case '6': RegNo = X86::DR6; break;
955 case '7': RegNo = X86::DR7; break;
959 EndLoc = Parser.getTok().getEndLoc();
960 Parser.Lex(); // Eat it.
966 if (isParsingIntelSyntax()) return true;
967 return Error(StartLoc, "invalid register name",
968 SMRange(StartLoc, EndLoc));
971 Parser.Lex(); // Eat identifier token.
975 void X86AsmParser::SetFrameRegister(unsigned RegNo) {
976 Instrumentation->SetFrameRegister(RegNo);
979 std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(SMLoc Loc) {
981 is64BitMode() ? X86::RSI : (is32BitMode() ? X86::ESI : X86::SI);
982 const MCExpr *Disp = MCConstantExpr::Create(0, getContext());
983 return X86Operand::CreateMem(/*SegReg=*/0, Disp, /*BaseReg=*/basereg,
984 /*IndexReg=*/0, /*Scale=*/1, Loc, Loc, 0);
987 std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand(SMLoc Loc) {
989 is64BitMode() ? X86::RDI : (is32BitMode() ? X86::EDI : X86::DI);
990 const MCExpr *Disp = MCConstantExpr::Create(0, getContext());
991 return X86Operand::CreateMem(/*SegReg=*/0, Disp, /*BaseReg=*/basereg,
992 /*IndexReg=*/0, /*Scale=*/1, Loc, Loc, 0);
995 std::unique_ptr<X86Operand> X86AsmParser::ParseOperand() {
996 if (isParsingIntelSyntax())
997 return ParseIntelOperand();
998 return ParseATTOperand();
1001 /// getIntelMemOperandSize - Return intel memory operand size.
1002 static unsigned getIntelMemOperandSize(StringRef OpStr) {
1003 unsigned Size = StringSwitch<unsigned>(OpStr)
1004 .Cases("BYTE", "byte", 8)
1005 .Cases("WORD", "word", 16)
1006 .Cases("DWORD", "dword", 32)
1007 .Cases("QWORD", "qword", 64)
1008 .Cases("XWORD", "xword", 80)
1009 .Cases("XMMWORD", "xmmword", 128)
1010 .Cases("YMMWORD", "ymmword", 256)
1011 .Cases("ZMMWORD", "zmmword", 512)
1012 .Cases("OPAQUE", "opaque", -1U) // needs to be non-zero, but doesn't matter
1017 std::unique_ptr<X86Operand> X86AsmParser::CreateMemForInlineAsm(
1018 unsigned SegReg, const MCExpr *Disp, unsigned BaseReg, unsigned IndexReg,
1019 unsigned Scale, SMLoc Start, SMLoc End, unsigned Size, StringRef Identifier,
1020 InlineAsmIdentifierInfo &Info) {
1021 // If we found a decl other than a VarDecl, then assume it is a FuncDecl or
1022 // some other label reference.
1023 if (isa<MCSymbolRefExpr>(Disp) && Info.OpDecl && !Info.IsVarDecl) {
1024 // Insert an explicit size if the user didn't have one.
1026 Size = getPointerWidth();
1027 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_SizeDirective, Start,
1031 // Create an absolute memory reference in order to match against
1032 // instructions taking a PC relative operand.
1033 return X86Operand::CreateMem(Disp, Start, End, Size, Identifier,
1037 // We either have a direct symbol reference, or an offset from a symbol. The
1038 // parser always puts the symbol on the LHS, so look there for size
1039 // calculation purposes.
1040 const MCBinaryExpr *BinOp = dyn_cast<MCBinaryExpr>(Disp);
1042 isa<MCSymbolRefExpr>(BinOp ? BinOp->getLHS() : Disp);
1045 Size = Info.Type * 8; // Size is in terms of bits in this context.
1047 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_SizeDirective, Start,
1052 // When parsing inline assembly we set the base register to a non-zero value
1053 // if we don't know the actual value at this time. This is necessary to
1054 // get the matching correct in some cases.
1055 BaseReg = BaseReg ? BaseReg : 1;
1056 return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale, Start,
1057 End, Size, Identifier, Info.OpDecl);
1061 RewriteIntelBracExpression(SmallVectorImpl<AsmRewrite> *AsmRewrites,
1062 StringRef SymName, int64_t ImmDisp,
1063 int64_t FinalImmDisp, SMLoc &BracLoc,
1064 SMLoc &StartInBrac, SMLoc &End) {
1065 // Remove the '[' and ']' from the IR string.
1066 AsmRewrites->push_back(AsmRewrite(AOK_Skip, BracLoc, 1));
1067 AsmRewrites->push_back(AsmRewrite(AOK_Skip, End, 1));
1069 // If ImmDisp is non-zero, then we parsed a displacement before the
1070 // bracketed expression (i.e., ImmDisp [ BaseReg + Scale*IndexReg + Disp])
1071 // If ImmDisp doesn't match the displacement computed by the state machine
1072 // then we have an additional displacement in the bracketed expression.
1073 if (ImmDisp != FinalImmDisp) {
1075 // We have an immediate displacement before the bracketed expression.
1076 // Adjust this to match the final immediate displacement.
1078 for (SmallVectorImpl<AsmRewrite>::iterator I = AsmRewrites->begin(),
1079 E = AsmRewrites->end(); I != E; ++I) {
1080 if ((*I).Loc.getPointer() > BracLoc.getPointer())
1082 if ((*I).Kind == AOK_ImmPrefix || (*I).Kind == AOK_Imm) {
1083 assert (!Found && "ImmDisp already rewritten.");
1084 (*I).Kind = AOK_Imm;
1085 (*I).Len = BracLoc.getPointer() - (*I).Loc.getPointer();
1086 (*I).Val = FinalImmDisp;
1091 assert (Found && "Unable to rewrite ImmDisp.");
1094 // We have a symbolic and an immediate displacement, but no displacement
1095 // before the bracketed expression. Put the immediate displacement
1096 // before the bracketed expression.
1097 AsmRewrites->push_back(AsmRewrite(AOK_Imm, BracLoc, 0, FinalImmDisp));
1100 // Remove all the ImmPrefix rewrites within the brackets.
1101 for (SmallVectorImpl<AsmRewrite>::iterator I = AsmRewrites->begin(),
1102 E = AsmRewrites->end(); I != E; ++I) {
1103 if ((*I).Loc.getPointer() < StartInBrac.getPointer())
1105 if ((*I).Kind == AOK_ImmPrefix)
1106 (*I).Kind = AOK_Delete;
1108 const char *SymLocPtr = SymName.data();
1109 // Skip everything before the symbol.
1110 if (unsigned Len = SymLocPtr - StartInBrac.getPointer()) {
1111 assert(Len > 0 && "Expected a non-negative length.");
1112 AsmRewrites->push_back(AsmRewrite(AOK_Skip, StartInBrac, Len));
1114 // Skip everything after the symbol.
1115 if (unsigned Len = End.getPointer() - (SymLocPtr + SymName.size())) {
1116 SMLoc Loc = SMLoc::getFromPointer(SymLocPtr + SymName.size());
1117 assert(Len > 0 && "Expected a non-negative length.");
1118 AsmRewrites->push_back(AsmRewrite(AOK_Skip, Loc, Len));
1122 bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
1123 const AsmToken &Tok = Parser.getTok();
1127 bool UpdateLocLex = true;
1129 // The period in the dot operator (e.g., [ebx].foo.bar) is parsed as an
1130 // identifier. Don't try an parse it as a register.
1131 if (Tok.getString().startswith("."))
1134 // If we're parsing an immediate expression, we don't expect a '['.
1135 if (SM.getStopOnLBrac() && getLexer().getKind() == AsmToken::LBrac)
1138 AsmToken::TokenKind TK = getLexer().getKind();
1141 if (SM.isValidEndState()) {
1145 return Error(Tok.getLoc(), "unknown token in expression");
1147 case AsmToken::EndOfStatement: {
1151 case AsmToken::String:
1152 case AsmToken::Identifier: {
1153 // This could be a register or a symbolic displacement.
1156 SMLoc IdentLoc = Tok.getLoc();
1157 StringRef Identifier = Tok.getString();
1158 if (TK != AsmToken::String && !ParseRegister(TmpReg, IdentLoc, End)) {
1159 SM.onRegister(TmpReg);
1160 UpdateLocLex = false;
1163 if (!isParsingInlineAsm()) {
1164 if (getParser().parsePrimaryExpr(Val, End))
1165 return Error(Tok.getLoc(), "Unexpected identifier!");
1167 // This is a dot operator, not an adjacent identifier.
1168 if (Identifier.find('.') != StringRef::npos) {
1171 InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
1172 if (ParseIntelIdentifier(Val, Identifier, Info,
1173 /*Unevaluated=*/false, End))
1177 SM.onIdentifierExpr(Val, Identifier);
1178 UpdateLocLex = false;
1181 return Error(Tok.getLoc(), "Unexpected identifier!");
1183 case AsmToken::Integer: {
1185 if (isParsingInlineAsm() && SM.getAddImmPrefix())
1186 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_ImmPrefix,
1188 // Look for 'b' or 'f' following an Integer as a directional label
1189 SMLoc Loc = getTok().getLoc();
1190 int64_t IntVal = getTok().getIntVal();
1191 End = consumeToken();
1192 UpdateLocLex = false;
1193 if (getLexer().getKind() == AsmToken::Identifier) {
1194 StringRef IDVal = getTok().getString();
1195 if (IDVal == "f" || IDVal == "b") {
1197 getContext().GetDirectionalLocalSymbol(IntVal, IDVal == "b");
1198 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1200 MCSymbolRefExpr::Create(Sym, Variant, getContext());
1201 if (IDVal == "b" && Sym->isUndefined())
1202 return Error(Loc, "invalid reference to undefined symbol");
1203 StringRef Identifier = Sym->getName();
1204 SM.onIdentifierExpr(Val, Identifier);
1205 End = consumeToken();
1207 if (SM.onInteger(IntVal, ErrMsg))
1208 return Error(Loc, ErrMsg);
1211 if (SM.onInteger(IntVal, ErrMsg))
1212 return Error(Loc, ErrMsg);
1216 case AsmToken::Plus: SM.onPlus(); break;
1217 case AsmToken::Minus: SM.onMinus(); break;
1218 case AsmToken::Tilde: SM.onNot(); break;
1219 case AsmToken::Star: SM.onStar(); break;
1220 case AsmToken::Slash: SM.onDivide(); break;
1221 case AsmToken::Pipe: SM.onOr(); break;
1222 case AsmToken::Amp: SM.onAnd(); break;
1223 case AsmToken::LessLess:
1224 SM.onLShift(); break;
1225 case AsmToken::GreaterGreater:
1226 SM.onRShift(); break;
1227 case AsmToken::LBrac: SM.onLBrac(); break;
1228 case AsmToken::RBrac: SM.onRBrac(); break;
1229 case AsmToken::LParen: SM.onLParen(); break;
1230 case AsmToken::RParen: SM.onRParen(); break;
1233 return Error(Tok.getLoc(), "unknown token in expression");
1235 if (!Done && UpdateLocLex)
1236 End = consumeToken();
1241 std::unique_ptr<X86Operand>
1242 X86AsmParser::ParseIntelBracExpression(unsigned SegReg, SMLoc Start,
1243 int64_t ImmDisp, unsigned Size) {
1244 const AsmToken &Tok = Parser.getTok();
1245 SMLoc BracLoc = Tok.getLoc(), End = Tok.getEndLoc();
1246 if (getLexer().isNot(AsmToken::LBrac))
1247 return ErrorOperand(BracLoc, "Expected '[' token!");
1248 Parser.Lex(); // Eat '['
1250 SMLoc StartInBrac = Tok.getLoc();
1251 // Parse [ Symbol + ImmDisp ] and [ BaseReg + Scale*IndexReg + ImmDisp ]. We
1252 // may have already parsed an immediate displacement before the bracketed
1254 IntelExprStateMachine SM(ImmDisp, /*StopOnLBrac=*/false, /*AddImmPrefix=*/true);
1255 if (ParseIntelExpression(SM, End))
1258 const MCExpr *Disp = nullptr;
1259 if (const MCExpr *Sym = SM.getSym()) {
1260 // A symbolic displacement.
1262 if (isParsingInlineAsm())
1263 RewriteIntelBracExpression(InstInfo->AsmRewrites, SM.getSymName(),
1264 ImmDisp, SM.getImm(), BracLoc, StartInBrac,
1268 if (SM.getImm() || !Disp) {
1269 const MCExpr *Imm = MCConstantExpr::Create(SM.getImm(), getContext());
1271 Disp = MCBinaryExpr::CreateAdd(Disp, Imm, getContext());
1273 Disp = Imm; // An immediate displacement only.
1276 // Parse struct field access. Intel requires a dot, but MSVC doesn't. MSVC
1277 // will in fact do global lookup the field name inside all global typedefs,
1278 // but we don't emulate that.
1279 if (Tok.getString().find('.') != StringRef::npos) {
1280 const MCExpr *NewDisp;
1281 if (ParseIntelDotOperator(Disp, NewDisp))
1284 End = Tok.getEndLoc();
1285 Parser.Lex(); // Eat the field.
1289 int BaseReg = SM.getBaseReg();
1290 int IndexReg = SM.getIndexReg();
1291 int Scale = SM.getScale();
1292 if (!isParsingInlineAsm()) {
1294 if (!BaseReg && !IndexReg) {
1296 return X86Operand::CreateMem(Disp, Start, End, Size);
1298 return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, Start, End, Size);
1301 if (CheckBaseRegAndIndexReg(BaseReg, IndexReg, ErrMsg)) {
1302 Error(StartInBrac, ErrMsg);
1305 return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale, Start,
1309 InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
1310 return CreateMemForInlineAsm(SegReg, Disp, BaseReg, IndexReg, Scale, Start,
1311 End, Size, SM.getSymName(), Info);
1314 // Inline assembly may use variable names with namespace alias qualifiers.
1315 bool X86AsmParser::ParseIntelIdentifier(const MCExpr *&Val,
1316 StringRef &Identifier,
1317 InlineAsmIdentifierInfo &Info,
1318 bool IsUnevaluatedOperand, SMLoc &End) {
1319 assert (isParsingInlineAsm() && "Expected to be parsing inline assembly.");
1322 StringRef LineBuf(Identifier.data());
1324 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);
1326 const AsmToken &Tok = Parser.getTok();
1327 SMLoc Loc = Tok.getLoc();
1329 // Advance the token stream until the end of the current token is
1330 // after the end of what the frontend claimed.
1331 const char *EndPtr = Tok.getLoc().getPointer() + LineBuf.size();
1333 End = Tok.getEndLoc();
1336 assert(End.getPointer() <= EndPtr && "frontend claimed part of a token?");
1337 if (End.getPointer() == EndPtr) break;
1339 Identifier = LineBuf;
1341 // If the identifier lookup was unsuccessful, assume that we are dealing with
1344 StringRef InternalName =
1345 SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(),
1347 assert(InternalName.size() && "We should have an internal name here.");
1348 // Push a rewrite for replacing the identifier name with the internal name.
1349 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Label, Loc,
1354 // Create the symbol reference.
1355 MCSymbol *Sym = getContext().GetOrCreateSymbol(Identifier);
1356 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1357 Val = MCSymbolRefExpr::Create(Sym, Variant, getParser().getContext());
1361 /// \brief Parse intel style segment override.
1362 std::unique_ptr<X86Operand>
1363 X86AsmParser::ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start,
1365 assert(SegReg != 0 && "Tried to parse a segment override without a segment!");
1366 const AsmToken &Tok = Parser.getTok(); // Eat colon.
1367 if (Tok.isNot(AsmToken::Colon))
1368 return ErrorOperand(Tok.getLoc(), "Expected ':' token!");
1369 Parser.Lex(); // Eat ':'
1371 int64_t ImmDisp = 0;
1372 if (getLexer().is(AsmToken::Integer)) {
1373 ImmDisp = Tok.getIntVal();
1374 AsmToken ImmDispToken = Parser.Lex(); // Eat the integer.
1376 if (isParsingInlineAsm())
1377 InstInfo->AsmRewrites->push_back(
1378 AsmRewrite(AOK_ImmPrefix, ImmDispToken.getLoc()));
1380 if (getLexer().isNot(AsmToken::LBrac)) {
1381 // An immediate following a 'segment register', 'colon' token sequence can
1382 // be followed by a bracketed expression. If it isn't we know we have our
1383 // final segment override.
1384 const MCExpr *Disp = MCConstantExpr::Create(ImmDisp, getContext());
1385 return X86Operand::CreateMem(SegReg, Disp, /*BaseReg=*/0, /*IndexReg=*/0,
1386 /*Scale=*/1, Start, ImmDispToken.getEndLoc(),
1391 if (getLexer().is(AsmToken::LBrac))
1392 return ParseIntelBracExpression(SegReg, Start, ImmDisp, Size);
1396 if (!isParsingInlineAsm()) {
1397 if (getParser().parsePrimaryExpr(Val, End))
1398 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1400 return X86Operand::CreateMem(Val, Start, End, Size);
1403 InlineAsmIdentifierInfo Info;
1404 StringRef Identifier = Tok.getString();
1405 if (ParseIntelIdentifier(Val, Identifier, Info,
1406 /*Unevaluated=*/false, End))
1408 return CreateMemForInlineAsm(/*SegReg=*/0, Val, /*BaseReg=*/0,/*IndexReg=*/0,
1409 /*Scale=*/1, Start, End, Size, Identifier, Info);
1412 /// ParseIntelMemOperand - Parse intel style memory operand.
1413 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelMemOperand(int64_t ImmDisp,
1416 const AsmToken &Tok = Parser.getTok();
1419 // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
1420 if (getLexer().is(AsmToken::LBrac))
1421 return ParseIntelBracExpression(/*SegReg=*/0, Start, ImmDisp, Size);
1422 assert(ImmDisp == 0);
1425 if (!isParsingInlineAsm()) {
1426 if (getParser().parsePrimaryExpr(Val, End))
1427 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1429 return X86Operand::CreateMem(Val, Start, End, Size);
1432 InlineAsmIdentifierInfo Info;
1433 StringRef Identifier = Tok.getString();
1434 if (ParseIntelIdentifier(Val, Identifier, Info,
1435 /*Unevaluated=*/false, End))
1438 if (!getLexer().is(AsmToken::LBrac))
1439 return CreateMemForInlineAsm(/*SegReg=*/0, Val, /*BaseReg=*/0, /*IndexReg=*/0,
1440 /*Scale=*/1, Start, End, Size, Identifier, Info);
1442 Parser.Lex(); // Eat '['
1444 // Parse Identifier [ ImmDisp ]
1445 IntelExprStateMachine SM(/*ImmDisp=*/0, /*StopOnLBrac=*/true,
1446 /*AddImmPrefix=*/false);
1447 if (ParseIntelExpression(SM, End))
1451 Error(Start, "cannot use more than one symbol in memory operand");
1454 if (SM.getBaseReg()) {
1455 Error(Start, "cannot use base register with variable reference");
1458 if (SM.getIndexReg()) {
1459 Error(Start, "cannot use index register with variable reference");
1463 const MCExpr *Disp = MCConstantExpr::Create(SM.getImm(), getContext());
1464 // BaseReg is non-zero to avoid assertions. In the context of inline asm,
1465 // we're pointing to a local variable in memory, so the base register is
1466 // really the frame or stack pointer.
1467 return X86Operand::CreateMem(/*SegReg=*/0, Disp, /*BaseReg=*/1, /*IndexReg=*/0,
1468 /*Scale=*/1, Start, End, Size, Identifier,
1472 /// Parse the '.' operator.
1473 bool X86AsmParser::ParseIntelDotOperator(const MCExpr *Disp,
1474 const MCExpr *&NewDisp) {
1475 const AsmToken &Tok = Parser.getTok();
1476 int64_t OrigDispVal, DotDispVal;
1478 // FIXME: Handle non-constant expressions.
1479 if (const MCConstantExpr *OrigDisp = dyn_cast<MCConstantExpr>(Disp))
1480 OrigDispVal = OrigDisp->getValue();
1482 return Error(Tok.getLoc(), "Non-constant offsets are not supported!");
1484 // Drop the optional '.'.
1485 StringRef DotDispStr = Tok.getString();
1486 if (DotDispStr.startswith("."))
1487 DotDispStr = DotDispStr.drop_front(1);
1489 // .Imm gets lexed as a real.
1490 if (Tok.is(AsmToken::Real)) {
1492 DotDispStr.getAsInteger(10, DotDisp);
1493 DotDispVal = DotDisp.getZExtValue();
1494 } else if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) {
1496 std::pair<StringRef, StringRef> BaseMember = DotDispStr.split('.');
1497 if (SemaCallback->LookupInlineAsmField(BaseMember.first, BaseMember.second,
1499 return Error(Tok.getLoc(), "Unable to lookup field reference!");
1500 DotDispVal = DotDisp;
1502 return Error(Tok.getLoc(), "Unexpected token type!");
1504 if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) {
1505 SMLoc Loc = SMLoc::getFromPointer(DotDispStr.data());
1506 unsigned Len = DotDispStr.size();
1507 unsigned Val = OrigDispVal + DotDispVal;
1508 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_DotOperator, Loc, Len,
1512 NewDisp = MCConstantExpr::Create(OrigDispVal + DotDispVal, getContext());
1516 /// Parse the 'offset' operator. This operator is used to specify the
1517 /// location rather then the content of a variable.
1518 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOffsetOfOperator() {
1519 const AsmToken &Tok = Parser.getTok();
1520 SMLoc OffsetOfLoc = Tok.getLoc();
1521 Parser.Lex(); // Eat offset.
1524 InlineAsmIdentifierInfo Info;
1525 SMLoc Start = Tok.getLoc(), End;
1526 StringRef Identifier = Tok.getString();
1527 if (ParseIntelIdentifier(Val, Identifier, Info,
1528 /*Unevaluated=*/false, End))
1531 // Don't emit the offset operator.
1532 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Skip, OffsetOfLoc, 7));
1534 // The offset operator will have an 'r' constraint, thus we need to create
1535 // register operand to ensure proper matching. Just pick a GPR based on
1536 // the size of a pointer.
1538 is64BitMode() ? X86::RBX : (is32BitMode() ? X86::EBX : X86::BX);
1539 return X86Operand::CreateReg(RegNo, Start, End, /*GetAddress=*/true,
1540 OffsetOfLoc, Identifier, Info.OpDecl);
1543 enum IntelOperatorKind {
1549 /// Parse the 'LENGTH', 'TYPE' and 'SIZE' operators. The LENGTH operator
1550 /// returns the number of elements in an array. It returns the value 1 for
1551 /// non-array variables. The SIZE operator returns the size of a C or C++
1552 /// variable. A variable's size is the product of its LENGTH and TYPE. The
1553 /// TYPE operator returns the size of a C or C++ type or variable. If the
1554 /// variable is an array, TYPE returns the size of a single element.
1555 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperator(unsigned OpKind) {
1556 const AsmToken &Tok = Parser.getTok();
1557 SMLoc TypeLoc = Tok.getLoc();
1558 Parser.Lex(); // Eat operator.
1560 const MCExpr *Val = nullptr;
1561 InlineAsmIdentifierInfo Info;
1562 SMLoc Start = Tok.getLoc(), End;
1563 StringRef Identifier = Tok.getString();
1564 if (ParseIntelIdentifier(Val, Identifier, Info,
1565 /*Unevaluated=*/true, End))
1569 return ErrorOperand(Start, "unable to lookup expression");
1573 default: llvm_unreachable("Unexpected operand kind!");
1574 case IOK_LENGTH: CVal = Info.Length; break;
1575 case IOK_SIZE: CVal = Info.Size; break;
1576 case IOK_TYPE: CVal = Info.Type; break;
1579 // Rewrite the type operator and the C or C++ type or variable in terms of an
1580 // immediate. E.g. TYPE foo -> $$4
1581 unsigned Len = End.getPointer() - TypeLoc.getPointer();
1582 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Imm, TypeLoc, Len, CVal));
1584 const MCExpr *Imm = MCConstantExpr::Create(CVal, getContext());
1585 return X86Operand::CreateImm(Imm, Start, End);
1588 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand() {
1589 const AsmToken &Tok = Parser.getTok();
1592 // Offset, length, type and size operators.
1593 if (isParsingInlineAsm()) {
1594 StringRef AsmTokStr = Tok.getString();
1595 if (AsmTokStr == "offset" || AsmTokStr == "OFFSET")
1596 return ParseIntelOffsetOfOperator();
1597 if (AsmTokStr == "length" || AsmTokStr == "LENGTH")
1598 return ParseIntelOperator(IOK_LENGTH);
1599 if (AsmTokStr == "size" || AsmTokStr == "SIZE")
1600 return ParseIntelOperator(IOK_SIZE);
1601 if (AsmTokStr == "type" || AsmTokStr == "TYPE")
1602 return ParseIntelOperator(IOK_TYPE);
1605 unsigned Size = getIntelMemOperandSize(Tok.getString());
1607 Parser.Lex(); // Eat operand size (e.g., byte, word).
1608 if (Tok.getString() != "PTR" && Tok.getString() != "ptr")
1609 return ErrorOperand(Tok.getLoc(), "Expected 'PTR' or 'ptr' token!");
1610 Parser.Lex(); // Eat ptr.
1612 Start = Tok.getLoc();
1615 if (getLexer().is(AsmToken::Integer) || getLexer().is(AsmToken::Minus) ||
1616 getLexer().is(AsmToken::Tilde) || getLexer().is(AsmToken::LParen)) {
1617 AsmToken StartTok = Tok;
1618 IntelExprStateMachine SM(/*Imm=*/0, /*StopOnLBrac=*/true,
1619 /*AddImmPrefix=*/false);
1620 if (ParseIntelExpression(SM, End))
1623 int64_t Imm = SM.getImm();
1624 if (isParsingInlineAsm()) {
1625 unsigned Len = Tok.getLoc().getPointer() - Start.getPointer();
1626 if (StartTok.getString().size() == Len)
1627 // Just add a prefix if this wasn't a complex immediate expression.
1628 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_ImmPrefix, Start));
1630 // Otherwise, rewrite the complex expression as a single immediate.
1631 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Imm, Start, Len, Imm));
1634 if (getLexer().isNot(AsmToken::LBrac)) {
1635 // If a directional label (ie. 1f or 2b) was parsed above from
1636 // ParseIntelExpression() then SM.getSym() was set to a pointer to
1637 // to the MCExpr with the directional local symbol and this is a
1638 // memory operand not an immediate operand.
1640 return X86Operand::CreateMem(SM.getSym(), Start, End, Size);
1642 const MCExpr *ImmExpr = MCConstantExpr::Create(Imm, getContext());
1643 return X86Operand::CreateImm(ImmExpr, Start, End);
1646 // Only positive immediates are valid.
1648 return ErrorOperand(Start, "expected a positive immediate displacement "
1649 "before bracketed expr.");
1651 // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
1652 return ParseIntelMemOperand(Imm, Start, Size);
1657 if (!ParseRegister(RegNo, Start, End)) {
1658 // If this is a segment register followed by a ':', then this is the start
1659 // of a segment override, otherwise this is a normal register reference.
1660 if (getLexer().isNot(AsmToken::Colon))
1661 return X86Operand::CreateReg(RegNo, Start, End);
1663 return ParseIntelSegmentOverride(/*SegReg=*/RegNo, Start, Size);
1667 return ParseIntelMemOperand(/*Disp=*/0, Start, Size);
1670 std::unique_ptr<X86Operand> X86AsmParser::ParseATTOperand() {
1671 switch (getLexer().getKind()) {
1673 // Parse a memory operand with no segment register.
1674 return ParseMemOperand(0, Parser.getTok().getLoc());
1675 case AsmToken::Percent: {
1676 // Read the register.
1679 if (ParseRegister(RegNo, Start, End)) return nullptr;
1680 if (RegNo == X86::EIZ || RegNo == X86::RIZ) {
1681 Error(Start, "%eiz and %riz can only be used as index registers",
1682 SMRange(Start, End));
1686 // If this is a segment register followed by a ':', then this is the start
1687 // of a memory reference, otherwise this is a normal register reference.
1688 if (getLexer().isNot(AsmToken::Colon))
1689 return X86Operand::CreateReg(RegNo, Start, End);
1691 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo))
1692 return ErrorOperand(Start, "invalid segment register");
1694 getParser().Lex(); // Eat the colon.
1695 return ParseMemOperand(RegNo, Start);
1697 case AsmToken::Dollar: {
1698 // $42 -> immediate.
1699 SMLoc Start = Parser.getTok().getLoc(), End;
1702 if (getParser().parseExpression(Val, End))
1704 return X86Operand::CreateImm(Val, Start, End);
1709 bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands,
1710 const MCParsedAsmOperand &Op) {
1711 if(STI.getFeatureBits() & X86::FeatureAVX512) {
1712 if (getLexer().is(AsmToken::LCurly)) {
1713 // Eat "{" and mark the current place.
1714 const SMLoc consumedToken = consumeToken();
1715 // Distinguish {1to<NUM>} from {%k<NUM>}.
1716 if(getLexer().is(AsmToken::Integer)) {
1717 // Parse memory broadcasting ({1to<NUM>}).
1718 if (getLexer().getTok().getIntVal() != 1)
1719 return !ErrorAndEatStatement(getLexer().getLoc(),
1720 "Expected 1to<NUM> at this point");
1721 Parser.Lex(); // Eat "1" of 1to8
1722 if (!getLexer().is(AsmToken::Identifier) ||
1723 !getLexer().getTok().getIdentifier().startswith("to"))
1724 return !ErrorAndEatStatement(getLexer().getLoc(),
1725 "Expected 1to<NUM> at this point");
1726 // Recognize only reasonable suffixes.
1727 const char *BroadcastPrimitive =
1728 StringSwitch<const char*>(getLexer().getTok().getIdentifier())
1729 .Case("to2", "{1to2}")
1730 .Case("to4", "{1to4}")
1731 .Case("to8", "{1to8}")
1732 .Case("to16", "{1to16}")
1734 if (!BroadcastPrimitive)
1735 return !ErrorAndEatStatement(getLexer().getLoc(),
1736 "Invalid memory broadcast primitive.");
1737 Parser.Lex(); // Eat "toN" of 1toN
1738 if (!getLexer().is(AsmToken::RCurly))
1739 return !ErrorAndEatStatement(getLexer().getLoc(),
1740 "Expected } at this point");
1741 Parser.Lex(); // Eat "}"
1742 Operands.push_back(X86Operand::CreateToken(BroadcastPrimitive,
1744 // No AVX512 specific primitives can pass
1745 // after memory broadcasting, so return.
1748 // Parse mask register {%k1}
1749 Operands.push_back(X86Operand::CreateToken("{", consumedToken));
1750 if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
1751 Operands.push_back(std::move(Op));
1752 if (!getLexer().is(AsmToken::RCurly))
1753 return !ErrorAndEatStatement(getLexer().getLoc(),
1754 "Expected } at this point");
1755 Operands.push_back(X86Operand::CreateToken("}", consumeToken()));
1757 // Parse "zeroing non-masked" semantic {z}
1758 if (getLexer().is(AsmToken::LCurly)) {
1759 Operands.push_back(X86Operand::CreateToken("{z}", consumeToken()));
1760 if (!getLexer().is(AsmToken::Identifier) ||
1761 getLexer().getTok().getIdentifier() != "z")
1762 return !ErrorAndEatStatement(getLexer().getLoc(),
1763 "Expected z at this point");
1764 Parser.Lex(); // Eat the z
1765 if (!getLexer().is(AsmToken::RCurly))
1766 return !ErrorAndEatStatement(getLexer().getLoc(),
1767 "Expected } at this point");
1768 Parser.Lex(); // Eat the }
1777 /// ParseMemOperand: segment: disp(basereg, indexreg, scale). The '%ds:' prefix
1778 /// has already been parsed if present.
1779 std::unique_ptr<X86Operand> X86AsmParser::ParseMemOperand(unsigned SegReg,
1782 // We have to disambiguate a parenthesized expression "(4+5)" from the start
1783 // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)". The
1784 // only way to do this without lookahead is to eat the '(' and see what is
1786 const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext());
1787 if (getLexer().isNot(AsmToken::LParen)) {
1789 if (getParser().parseExpression(Disp, ExprEnd)) return nullptr;
1791 // After parsing the base expression we could either have a parenthesized
1792 // memory address or not. If not, return now. If so, eat the (.
1793 if (getLexer().isNot(AsmToken::LParen)) {
1794 // Unless we have a segment register, treat this as an immediate.
1796 return X86Operand::CreateMem(Disp, MemStart, ExprEnd);
1797 return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd);
1803 // Okay, we have a '('. We don't know if this is an expression or not, but
1804 // so we have to eat the ( to see beyond it.
1805 SMLoc LParenLoc = Parser.getTok().getLoc();
1806 Parser.Lex(); // Eat the '('.
1808 if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) {
1809 // Nothing to do here, fall into the code below with the '(' part of the
1810 // memory operand consumed.
1814 // It must be an parenthesized expression, parse it now.
1815 if (getParser().parseParenExpression(Disp, ExprEnd))
1818 // After parsing the base expression we could either have a parenthesized
1819 // memory address or not. If not, return now. If so, eat the (.
1820 if (getLexer().isNot(AsmToken::LParen)) {
1821 // Unless we have a segment register, treat this as an immediate.
1823 return X86Operand::CreateMem(Disp, LParenLoc, ExprEnd);
1824 return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd);
1832 // If we reached here, then we just ate the ( of the memory operand. Process
1833 // the rest of the memory operand.
1834 unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
1835 SMLoc IndexLoc, BaseLoc;
1837 if (getLexer().is(AsmToken::Percent)) {
1838 SMLoc StartLoc, EndLoc;
1839 BaseLoc = Parser.getTok().getLoc();
1840 if (ParseRegister(BaseReg, StartLoc, EndLoc)) return nullptr;
1841 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) {
1842 Error(StartLoc, "eiz and riz can only be used as index registers",
1843 SMRange(StartLoc, EndLoc));
1848 if (getLexer().is(AsmToken::Comma)) {
1849 Parser.Lex(); // Eat the comma.
1850 IndexLoc = Parser.getTok().getLoc();
1852 // Following the comma we should have either an index register, or a scale
1853 // value. We don't support the later form, but we want to parse it
1856 // Not that even though it would be completely consistent to support syntax
1857 // like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this.
1858 if (getLexer().is(AsmToken::Percent)) {
1860 if (ParseRegister(IndexReg, L, L)) return nullptr;
1862 if (getLexer().isNot(AsmToken::RParen)) {
1863 // Parse the scale amount:
1864 // ::= ',' [scale-expression]
1865 if (getLexer().isNot(AsmToken::Comma)) {
1866 Error(Parser.getTok().getLoc(),
1867 "expected comma in scale expression");
1870 Parser.Lex(); // Eat the comma.
1872 if (getLexer().isNot(AsmToken::RParen)) {
1873 SMLoc Loc = Parser.getTok().getLoc();
1876 if (getParser().parseAbsoluteExpression(ScaleVal)){
1877 Error(Loc, "expected scale expression");
1881 // Validate the scale amount.
1882 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
1884 Error(Loc, "scale factor in 16-bit address must be 1");
1887 if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8){
1888 Error(Loc, "scale factor in address must be 1, 2, 4 or 8");
1891 Scale = (unsigned)ScaleVal;
1894 } else if (getLexer().isNot(AsmToken::RParen)) {
1895 // A scale amount without an index is ignored.
1897 SMLoc Loc = Parser.getTok().getLoc();
1900 if (getParser().parseAbsoluteExpression(Value))
1904 Warning(Loc, "scale factor without index register is ignored");
1909 // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
1910 if (getLexer().isNot(AsmToken::RParen)) {
1911 Error(Parser.getTok().getLoc(), "unexpected token in memory operand");
1914 SMLoc MemEnd = Parser.getTok().getEndLoc();
1915 Parser.Lex(); // Eat the ')'.
1917 // Check for use of invalid 16-bit registers. Only BX/BP/SI/DI are allowed,
1918 // and then only in non-64-bit modes. Except for DX, which is a special case
1919 // because an unofficial form of in/out instructions uses it.
1920 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
1921 (is64BitMode() || (BaseReg != X86::BX && BaseReg != X86::BP &&
1922 BaseReg != X86::SI && BaseReg != X86::DI)) &&
1923 BaseReg != X86::DX) {
1924 Error(BaseLoc, "invalid 16-bit base register");
1928 X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg)) {
1929 Error(IndexLoc, "16-bit memory operand may not include only index register");
1934 if (CheckBaseRegAndIndexReg(BaseReg, IndexReg, ErrMsg)) {
1935 Error(BaseLoc, ErrMsg);
1939 if (SegReg || BaseReg || IndexReg)
1940 return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale,
1942 return X86Operand::CreateMem(Disp, MemStart, MemEnd);
1945 bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
1946 SMLoc NameLoc, OperandVector &Operands) {
1948 StringRef PatchedName = Name;
1950 // FIXME: Hack to recognize setneb as setne.
1951 if (PatchedName.startswith("set") && PatchedName.endswith("b") &&
1952 PatchedName != "setb" && PatchedName != "setnb")
1953 PatchedName = PatchedName.substr(0, Name.size()-1);
1955 // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}.
1956 const MCExpr *ExtraImmOp = nullptr;
1957 if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) &&
1958 (PatchedName.endswith("ss") || PatchedName.endswith("sd") ||
1959 PatchedName.endswith("ps") || PatchedName.endswith("pd"))) {
1960 bool IsVCMP = PatchedName[0] == 'v';
1961 unsigned SSECCIdx = IsVCMP ? 4 : 3;
1962 unsigned SSEComparisonCode = StringSwitch<unsigned>(
1963 PatchedName.slice(SSECCIdx, PatchedName.size() - 2))
1967 .Case("unord", 0x03)
1972 /* AVX only from here */
1973 .Case("eq_uq", 0x08)
1976 .Case("false", 0x0B)
1977 .Case("neq_oq", 0x0C)
1981 .Case("eq_os", 0x10)
1982 .Case("lt_oq", 0x11)
1983 .Case("le_oq", 0x12)
1984 .Case("unord_s", 0x13)
1985 .Case("neq_us", 0x14)
1986 .Case("nlt_uq", 0x15)
1987 .Case("nle_uq", 0x16)
1988 .Case("ord_s", 0x17)
1989 .Case("eq_us", 0x18)
1990 .Case("nge_uq", 0x19)
1991 .Case("ngt_uq", 0x1A)
1992 .Case("false_os", 0x1B)
1993 .Case("neq_os", 0x1C)
1994 .Case("ge_oq", 0x1D)
1995 .Case("gt_oq", 0x1E)
1996 .Case("true_us", 0x1F)
1998 if (SSEComparisonCode != ~0U && (IsVCMP || SSEComparisonCode < 8)) {
1999 ExtraImmOp = MCConstantExpr::Create(SSEComparisonCode,
2000 getParser().getContext());
2001 if (PatchedName.endswith("ss")) {
2002 PatchedName = IsVCMP ? "vcmpss" : "cmpss";
2003 } else if (PatchedName.endswith("sd")) {
2004 PatchedName = IsVCMP ? "vcmpsd" : "cmpsd";
2005 } else if (PatchedName.endswith("ps")) {
2006 PatchedName = IsVCMP ? "vcmpps" : "cmpps";
2008 assert(PatchedName.endswith("pd") && "Unexpected mnemonic!");
2009 PatchedName = IsVCMP ? "vcmppd" : "cmppd";
2014 Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
2016 if (ExtraImmOp && !isParsingIntelSyntax())
2017 Operands.push_back(X86Operand::CreateImm(ExtraImmOp, NameLoc, NameLoc));
2019 // Determine whether this is an instruction prefix.
2021 Name == "lock" || Name == "rep" ||
2022 Name == "repe" || Name == "repz" ||
2023 Name == "repne" || Name == "repnz" ||
2024 Name == "rex64" || Name == "data16";
2027 // This does the actual operand parsing. Don't parse any more if we have a
2028 // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we
2029 // just want to parse the "lock" as the first instruction and the "incl" as
2031 if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) {
2033 // Parse '*' modifier.
2034 if (getLexer().is(AsmToken::Star))
2035 Operands.push_back(X86Operand::CreateToken("*", consumeToken()));
2037 // Read the operands.
2039 if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
2040 Operands.push_back(std::move(Op));
2041 if (!HandleAVX512Operand(Operands, *Operands.back()))
2044 Parser.eatToEndOfStatement();
2047 // check for comma and eat it
2048 if (getLexer().is(AsmToken::Comma))
2054 if (getLexer().isNot(AsmToken::EndOfStatement))
2055 return ErrorAndEatStatement(getLexer().getLoc(),
2056 "unexpected token in argument list");
2059 // Consume the EndOfStatement or the prefix separator Slash
2060 if (getLexer().is(AsmToken::EndOfStatement) ||
2061 (isPrefix && getLexer().is(AsmToken::Slash)))
2064 if (ExtraImmOp && isParsingIntelSyntax())
2065 Operands.push_back(X86Operand::CreateImm(ExtraImmOp, NameLoc, NameLoc));
2067 // This is a terrible hack to handle "out[bwl]? %al, (%dx)" ->
2068 // "outb %al, %dx". Out doesn't take a memory form, but this is a widely
2069 // documented form in various unofficial manuals, so a lot of code uses it.
2070 if ((Name == "outb" || Name == "outw" || Name == "outl" || Name == "out") &&
2071 Operands.size() == 3) {
2072 X86Operand &Op = (X86Operand &)*Operands.back();
2073 if (Op.isMem() && Op.Mem.SegReg == 0 &&
2074 isa<MCConstantExpr>(Op.Mem.Disp) &&
2075 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
2076 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
2077 SMLoc Loc = Op.getEndLoc();
2078 Operands.back() = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
2081 // Same hack for "in[bwl]? (%dx), %al" -> "inb %dx, %al".
2082 if ((Name == "inb" || Name == "inw" || Name == "inl" || Name == "in") &&
2083 Operands.size() == 3) {
2084 X86Operand &Op = (X86Operand &)*Operands[1];
2085 if (Op.isMem() && Op.Mem.SegReg == 0 &&
2086 isa<MCConstantExpr>(Op.Mem.Disp) &&
2087 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
2088 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
2089 SMLoc Loc = Op.getEndLoc();
2090 Operands[1] = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
2094 // Append default arguments to "ins[bwld]"
2095 if (Name.startswith("ins") && Operands.size() == 1 &&
2096 (Name == "insb" || Name == "insw" || Name == "insl" ||
2098 if (isParsingIntelSyntax()) {
2099 Operands.push_back(X86Operand::CreateReg(X86::DX, NameLoc, NameLoc));
2100 Operands.push_back(DefaultMemDIOperand(NameLoc));
2102 Operands.push_back(X86Operand::CreateReg(X86::DX, NameLoc, NameLoc));
2103 Operands.push_back(DefaultMemDIOperand(NameLoc));
2107 // Append default arguments to "outs[bwld]"
2108 if (Name.startswith("outs") && Operands.size() == 1 &&
2109 (Name == "outsb" || Name == "outsw" || Name == "outsl" ||
2110 Name == "outsd" )) {
2111 if (isParsingIntelSyntax()) {
2112 Operands.push_back(DefaultMemSIOperand(NameLoc));
2113 Operands.push_back(X86Operand::CreateReg(X86::DX, NameLoc, NameLoc));
2115 Operands.push_back(DefaultMemSIOperand(NameLoc));
2116 Operands.push_back(X86Operand::CreateReg(X86::DX, NameLoc, NameLoc));
2120 // Transform "lods[bwlq]" into "lods[bwlq] ($SIREG)" for appropriate
2121 // values of $SIREG according to the mode. It would be nice if this
2122 // could be achieved with InstAlias in the tables.
2123 if (Name.startswith("lods") && Operands.size() == 1 &&
2124 (Name == "lods" || Name == "lodsb" || Name == "lodsw" ||
2125 Name == "lodsl" || Name == "lodsd" || Name == "lodsq"))
2126 Operands.push_back(DefaultMemSIOperand(NameLoc));
2128 // Transform "stos[bwlq]" into "stos[bwlq] ($DIREG)" for appropriate
2129 // values of $DIREG according to the mode. It would be nice if this
2130 // could be achieved with InstAlias in the tables.
2131 if (Name.startswith("stos") && Operands.size() == 1 &&
2132 (Name == "stos" || Name == "stosb" || Name == "stosw" ||
2133 Name == "stosl" || Name == "stosd" || Name == "stosq"))
2134 Operands.push_back(DefaultMemDIOperand(NameLoc));
2136 // Transform "scas[bwlq]" into "scas[bwlq] ($DIREG)" for appropriate
2137 // values of $DIREG according to the mode. It would be nice if this
2138 // could be achieved with InstAlias in the tables.
2139 if (Name.startswith("scas") && Operands.size() == 1 &&
2140 (Name == "scas" || Name == "scasb" || Name == "scasw" ||
2141 Name == "scasl" || Name == "scasd" || Name == "scasq"))
2142 Operands.push_back(DefaultMemDIOperand(NameLoc));
2144 // Add default SI and DI operands to "cmps[bwlq]".
2145 if (Name.startswith("cmps") &&
2146 (Name == "cmps" || Name == "cmpsb" || Name == "cmpsw" ||
2147 Name == "cmpsl" || Name == "cmpsd" || Name == "cmpsq")) {
2148 if (Operands.size() == 1) {
2149 if (isParsingIntelSyntax()) {
2150 Operands.push_back(DefaultMemSIOperand(NameLoc));
2151 Operands.push_back(DefaultMemDIOperand(NameLoc));
2153 Operands.push_back(DefaultMemDIOperand(NameLoc));
2154 Operands.push_back(DefaultMemSIOperand(NameLoc));
2156 } else if (Operands.size() == 3) {
2157 X86Operand &Op = (X86Operand &)*Operands[1];
2158 X86Operand &Op2 = (X86Operand &)*Operands[2];
2159 if (!doSrcDstMatch(Op, Op2))
2160 return Error(Op.getStartLoc(),
2161 "mismatching source and destination index registers");
2165 // Add default SI and DI operands to "movs[bwlq]".
2166 if ((Name.startswith("movs") &&
2167 (Name == "movs" || Name == "movsb" || Name == "movsw" ||
2168 Name == "movsl" || Name == "movsd" || Name == "movsq")) ||
2169 (Name.startswith("smov") &&
2170 (Name == "smov" || Name == "smovb" || Name == "smovw" ||
2171 Name == "smovl" || Name == "smovd" || Name == "smovq"))) {
2172 if (Operands.size() == 1) {
2173 if (Name == "movsd")
2174 Operands.back() = X86Operand::CreateToken("movsl", NameLoc);
2175 if (isParsingIntelSyntax()) {
2176 Operands.push_back(DefaultMemDIOperand(NameLoc));
2177 Operands.push_back(DefaultMemSIOperand(NameLoc));
2179 Operands.push_back(DefaultMemSIOperand(NameLoc));
2180 Operands.push_back(DefaultMemDIOperand(NameLoc));
2182 } else if (Operands.size() == 3) {
2183 X86Operand &Op = (X86Operand &)*Operands[1];
2184 X86Operand &Op2 = (X86Operand &)*Operands[2];
2185 if (!doSrcDstMatch(Op, Op2))
2186 return Error(Op.getStartLoc(),
2187 "mismatching source and destination index registers");
2191 // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>. Canonicalize to
2193 if ((Name.startswith("shr") || Name.startswith("sar") ||
2194 Name.startswith("shl") || Name.startswith("sal") ||
2195 Name.startswith("rcl") || Name.startswith("rcr") ||
2196 Name.startswith("rol") || Name.startswith("ror")) &&
2197 Operands.size() == 3) {
2198 if (isParsingIntelSyntax()) {
2200 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[2]);
2201 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2202 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2203 Operands.pop_back();
2205 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2206 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2207 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2208 Operands.erase(Operands.begin() + 1);
2212 // Transforms "int $3" into "int3" as a size optimization. We can't write an
2213 // instalias with an immediate operand yet.
2214 if (Name == "int" && Operands.size() == 2) {
2215 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2216 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2217 cast<MCConstantExpr>(Op1.getImm())->getValue() == 3) {
2218 Operands.erase(Operands.begin() + 1);
2219 static_cast<X86Operand &>(*Operands[0]).setTokenValue("int3");
2226 static bool convertToSExti8(MCInst &Inst, unsigned Opcode, unsigned Reg,
2229 TmpInst.setOpcode(Opcode);
2231 TmpInst.addOperand(MCOperand::CreateReg(Reg));
2232 TmpInst.addOperand(MCOperand::CreateReg(Reg));
2233 TmpInst.addOperand(Inst.getOperand(0));
2238 static bool convert16i16to16ri8(MCInst &Inst, unsigned Opcode,
2239 bool isCmp = false) {
2240 if (!Inst.getOperand(0).isImm() ||
2241 !isImmSExti16i8Value(Inst.getOperand(0).getImm()))
2244 return convertToSExti8(Inst, Opcode, X86::AX, isCmp);
2247 static bool convert32i32to32ri8(MCInst &Inst, unsigned Opcode,
2248 bool isCmp = false) {
2249 if (!Inst.getOperand(0).isImm() ||
2250 !isImmSExti32i8Value(Inst.getOperand(0).getImm()))
2253 return convertToSExti8(Inst, Opcode, X86::EAX, isCmp);
2256 static bool convert64i32to64ri8(MCInst &Inst, unsigned Opcode,
2257 bool isCmp = false) {
2258 if (!Inst.getOperand(0).isImm() ||
2259 !isImmSExti64i8Value(Inst.getOperand(0).getImm()))
2262 return convertToSExti8(Inst, Opcode, X86::RAX, isCmp);
2265 bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) {
2266 switch (Inst.getOpcode()) {
2267 default: return false;
2268 case X86::AND16i16: return convert16i16to16ri8(Inst, X86::AND16ri8);
2269 case X86::AND32i32: return convert32i32to32ri8(Inst, X86::AND32ri8);
2270 case X86::AND64i32: return convert64i32to64ri8(Inst, X86::AND64ri8);
2271 case X86::XOR16i16: return convert16i16to16ri8(Inst, X86::XOR16ri8);
2272 case X86::XOR32i32: return convert32i32to32ri8(Inst, X86::XOR32ri8);
2273 case X86::XOR64i32: return convert64i32to64ri8(Inst, X86::XOR64ri8);
2274 case X86::OR16i16: return convert16i16to16ri8(Inst, X86::OR16ri8);
2275 case X86::OR32i32: return convert32i32to32ri8(Inst, X86::OR32ri8);
2276 case X86::OR64i32: return convert64i32to64ri8(Inst, X86::OR64ri8);
2277 case X86::CMP16i16: return convert16i16to16ri8(Inst, X86::CMP16ri8, true);
2278 case X86::CMP32i32: return convert32i32to32ri8(Inst, X86::CMP32ri8, true);
2279 case X86::CMP64i32: return convert64i32to64ri8(Inst, X86::CMP64ri8, true);
2280 case X86::ADD16i16: return convert16i16to16ri8(Inst, X86::ADD16ri8);
2281 case X86::ADD32i32: return convert32i32to32ri8(Inst, X86::ADD32ri8);
2282 case X86::ADD64i32: return convert64i32to64ri8(Inst, X86::ADD64ri8);
2283 case X86::SUB16i16: return convert16i16to16ri8(Inst, X86::SUB16ri8);
2284 case X86::SUB32i32: return convert32i32to32ri8(Inst, X86::SUB32ri8);
2285 case X86::SUB64i32: return convert64i32to64ri8(Inst, X86::SUB64ri8);
2286 case X86::ADC16i16: return convert16i16to16ri8(Inst, X86::ADC16ri8);
2287 case X86::ADC32i32: return convert32i32to32ri8(Inst, X86::ADC32ri8);
2288 case X86::ADC64i32: return convert64i32to64ri8(Inst, X86::ADC64ri8);
2289 case X86::SBB16i16: return convert16i16to16ri8(Inst, X86::SBB16ri8);
2290 case X86::SBB32i32: return convert32i32to32ri8(Inst, X86::SBB32ri8);
2291 case X86::SBB64i32: return convert64i32to64ri8(Inst, X86::SBB64ri8);
2292 case X86::VMOVAPDrr:
2293 case X86::VMOVAPDYrr:
2294 case X86::VMOVAPSrr:
2295 case X86::VMOVAPSYrr:
2296 case X86::VMOVDQArr:
2297 case X86::VMOVDQAYrr:
2298 case X86::VMOVDQUrr:
2299 case X86::VMOVDQUYrr:
2300 case X86::VMOVUPDrr:
2301 case X86::VMOVUPDYrr:
2302 case X86::VMOVUPSrr:
2303 case X86::VMOVUPSYrr: {
2304 if (X86II::isX86_64ExtendedReg(Inst.getOperand(0).getReg()) ||
2305 !X86II::isX86_64ExtendedReg(Inst.getOperand(1).getReg()))
2309 switch (Inst.getOpcode()) {
2310 default: llvm_unreachable("Invalid opcode");
2311 case X86::VMOVAPDrr: NewOpc = X86::VMOVAPDrr_REV; break;
2312 case X86::VMOVAPDYrr: NewOpc = X86::VMOVAPDYrr_REV; break;
2313 case X86::VMOVAPSrr: NewOpc = X86::VMOVAPSrr_REV; break;
2314 case X86::VMOVAPSYrr: NewOpc = X86::VMOVAPSYrr_REV; break;
2315 case X86::VMOVDQArr: NewOpc = X86::VMOVDQArr_REV; break;
2316 case X86::VMOVDQAYrr: NewOpc = X86::VMOVDQAYrr_REV; break;
2317 case X86::VMOVDQUrr: NewOpc = X86::VMOVDQUrr_REV; break;
2318 case X86::VMOVDQUYrr: NewOpc = X86::VMOVDQUYrr_REV; break;
2319 case X86::VMOVUPDrr: NewOpc = X86::VMOVUPDrr_REV; break;
2320 case X86::VMOVUPDYrr: NewOpc = X86::VMOVUPDYrr_REV; break;
2321 case X86::VMOVUPSrr: NewOpc = X86::VMOVUPSrr_REV; break;
2322 case X86::VMOVUPSYrr: NewOpc = X86::VMOVUPSYrr_REV; break;
2324 Inst.setOpcode(NewOpc);
2328 case X86::VMOVSSrr: {
2329 if (X86II::isX86_64ExtendedReg(Inst.getOperand(0).getReg()) ||
2330 !X86II::isX86_64ExtendedReg(Inst.getOperand(2).getReg()))
2333 switch (Inst.getOpcode()) {
2334 default: llvm_unreachable("Invalid opcode");
2335 case X86::VMOVSDrr: NewOpc = X86::VMOVSDrr_REV; break;
2336 case X86::VMOVSSrr: NewOpc = X86::VMOVSSrr_REV; break;
2338 Inst.setOpcode(NewOpc);
2344 static const char *getSubtargetFeatureName(uint64_t Val);
2346 void X86AsmParser::EmitInstruction(MCInst &Inst, OperandVector &Operands,
2348 Instrumentation->InstrumentAndEmitInstruction(Inst, Operands, getContext(),
2352 bool X86AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2353 OperandVector &Operands,
2354 MCStreamer &Out, uint64_t &ErrorInfo,
2355 bool MatchingInlineAsm) {
2356 if (isParsingIntelSyntax())
2357 return MatchAndEmitIntelInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2359 return MatchAndEmitATTInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2363 void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op,
2364 OperandVector &Operands, MCStreamer &Out,
2365 bool MatchingInlineAsm) {
2366 // FIXME: This should be replaced with a real .td file alias mechanism.
2367 // Also, MatchInstructionImpl should actually *do* the EmitInstruction
2369 const char *Repl = StringSwitch<const char *>(Op.getToken())
2370 .Case("finit", "fninit")
2371 .Case("fsave", "fnsave")
2372 .Case("fstcw", "fnstcw")
2373 .Case("fstcww", "fnstcw")
2374 .Case("fstenv", "fnstenv")
2375 .Case("fstsw", "fnstsw")
2376 .Case("fstsww", "fnstsw")
2377 .Case("fclex", "fnclex")
2381 Inst.setOpcode(X86::WAIT);
2383 if (!MatchingInlineAsm)
2384 EmitInstruction(Inst, Operands, Out);
2385 Operands[0] = X86Operand::CreateToken(Repl, IDLoc);
2389 bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
2390 bool MatchingInlineAsm) {
2391 assert(ErrorInfo && "Unknown missing feature!");
2392 ArrayRef<SMRange> EmptyRanges = None;
2393 SmallString<126> Msg;
2394 raw_svector_ostream OS(Msg);
2395 OS << "instruction requires:";
2397 for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
2398 if (ErrorInfo & Mask)
2399 OS << ' ' << getSubtargetFeatureName(ErrorInfo & Mask);
2402 return Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
2405 bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
2406 OperandVector &Operands,
2408 uint64_t &ErrorInfo,
2409 bool MatchingInlineAsm) {
2410 assert(!Operands.empty() && "Unexpect empty operand list!");
2411 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2412 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
2413 ArrayRef<SMRange> EmptyRanges = None;
2415 // First, handle aliases that expand to multiple instructions.
2416 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2418 bool WasOriginallyInvalidOperand = false;
2421 // First, try a direct match.
2422 switch (MatchInstructionImpl(Operands, Inst,
2423 ErrorInfo, MatchingInlineAsm,
2424 isParsingIntelSyntax())) {
2427 // Some instructions need post-processing to, for example, tweak which
2428 // encoding is selected. Loop on it while changes happen so the
2429 // individual transformations can chain off each other.
2430 if (!MatchingInlineAsm)
2431 while (processInstruction(Inst, Operands))
2435 if (!MatchingInlineAsm)
2436 EmitInstruction(Inst, Operands, Out);
2437 Opcode = Inst.getOpcode();
2439 case Match_MissingFeature:
2440 return ErrorMissingFeature(IDLoc, ErrorInfo, MatchingInlineAsm);
2441 case Match_InvalidOperand:
2442 WasOriginallyInvalidOperand = true;
2444 case Match_MnemonicFail:
2448 // FIXME: Ideally, we would only attempt suffix matches for things which are
2449 // valid prefixes, and we could just infer the right unambiguous
2450 // type. However, that requires substantially more matcher support than the
2453 // Change the operand to point to a temporary token.
2454 StringRef Base = Op.getToken();
2455 SmallString<16> Tmp;
2458 Op.setTokenValue(Tmp.str());
2460 // If this instruction starts with an 'f', then it is a floating point stack
2461 // instruction. These come in up to three forms for 32-bit, 64-bit, and
2462 // 80-bit floating point, which use the suffixes s,l,t respectively.
2464 // Otherwise, we assume that this may be an integer instruction, which comes
2465 // in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively.
2466 const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0";
2468 // Check for the various suffix matches.
2469 uint64_t ErrorInfoIgnore;
2470 uint64_t ErrorInfoMissingFeature = 0; // Init suppresses compiler warnings.
2473 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I) {
2474 Tmp.back() = Suffixes[I];
2475 Match[I] = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
2476 MatchingInlineAsm, isParsingIntelSyntax());
2477 // If this returned as a missing feature failure, remember that.
2478 if (Match[I] == Match_MissingFeature)
2479 ErrorInfoMissingFeature = ErrorInfoIgnore;
2482 // Restore the old token.
2483 Op.setTokenValue(Base);
2485 // If exactly one matched, then we treat that as a successful match (and the
2486 // instruction will already have been filled in correctly, since the failing
2487 // matches won't have modified it).
2488 unsigned NumSuccessfulMatches =
2489 std::count(std::begin(Match), std::end(Match), Match_Success);
2490 if (NumSuccessfulMatches == 1) {
2492 if (!MatchingInlineAsm)
2493 EmitInstruction(Inst, Operands, Out);
2494 Opcode = Inst.getOpcode();
2498 // Otherwise, the match failed, try to produce a decent error message.
2500 // If we had multiple suffix matches, then identify this as an ambiguous
2502 if (NumSuccessfulMatches > 1) {
2504 unsigned NumMatches = 0;
2505 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I)
2506 if (Match[I] == Match_Success)
2507 MatchChars[NumMatches++] = Suffixes[I];
2509 SmallString<126> Msg;
2510 raw_svector_ostream OS(Msg);
2511 OS << "ambiguous instructions require an explicit suffix (could be ";
2512 for (unsigned i = 0; i != NumMatches; ++i) {
2515 if (i + 1 == NumMatches)
2517 OS << "'" << Base << MatchChars[i] << "'";
2520 Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
2524 // Okay, we know that none of the variants matched successfully.
2526 // If all of the instructions reported an invalid mnemonic, then the original
2527 // mnemonic was invalid.
2528 if (std::count(std::begin(Match), std::end(Match), Match_MnemonicFail) == 4) {
2529 if (!WasOriginallyInvalidOperand) {
2530 ArrayRef<SMRange> Ranges =
2531 MatchingInlineAsm ? EmptyRanges : Op.getLocRange();
2532 return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'",
2533 Ranges, MatchingInlineAsm);
2536 // Recover location info for the operand if we know which was the problem.
2537 if (ErrorInfo != ~0ULL) {
2538 if (ErrorInfo >= Operands.size())
2539 return Error(IDLoc, "too few operands for instruction",
2540 EmptyRanges, MatchingInlineAsm);
2542 X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo];
2543 if (Operand.getStartLoc().isValid()) {
2544 SMRange OperandRange = Operand.getLocRange();
2545 return Error(Operand.getStartLoc(), "invalid operand for instruction",
2546 OperandRange, MatchingInlineAsm);
2550 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2554 // If one instruction matched with a missing feature, report this as a
2556 if (std::count(std::begin(Match), std::end(Match),
2557 Match_MissingFeature) == 1) {
2558 ErrorInfo = ErrorInfoMissingFeature;
2559 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
2563 // If one instruction matched with an invalid operand, report this as an
2565 if (std::count(std::begin(Match), std::end(Match),
2566 Match_InvalidOperand) == 1) {
2567 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2571 // If all of these were an outright failure, report it in a useless way.
2572 Error(IDLoc, "unknown use of instruction mnemonic without a size suffix",
2573 EmptyRanges, MatchingInlineAsm);
2577 bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
2578 OperandVector &Operands,
2580 uint64_t &ErrorInfo,
2581 bool MatchingInlineAsm) {
2582 assert(!Operands.empty() && "Unexpect empty operand list!");
2583 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2584 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
2585 StringRef Mnemonic = Op.getToken();
2586 ArrayRef<SMRange> EmptyRanges = None;
2588 // First, handle aliases that expand to multiple instructions.
2589 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2593 // Find one unsized memory operand, if present.
2594 X86Operand *UnsizedMemOp = nullptr;
2595 for (const auto &Op : Operands) {
2596 X86Operand *X86Op = static_cast<X86Operand *>(Op.get());
2597 if (X86Op->isMemUnsized())
2598 UnsizedMemOp = X86Op;
2601 // Allow some instructions to have implicitly pointer-sized operands. This is
2602 // compatible with gas.
2604 static const char *const PtrSizedInstrs[] = {"call", "jmp", "push"};
2605 for (const char *Instr : PtrSizedInstrs) {
2606 if (Mnemonic == Instr) {
2607 UnsizedMemOp->Mem.Size = getPointerSize();
2613 // If an unsized memory operand is present, try to match with each memory
2614 // operand size. In Intel assembly, the size is not part of the instruction
2616 SmallVector<unsigned, 8> Match;
2617 uint64_t ErrorInfoMissingFeature = 0;
2618 if (UnsizedMemOp && UnsizedMemOp->isMemUnsized()) {
2619 static const unsigned MopSizes[] = {8, 16, 32, 64, 80};
2620 for (unsigned Size : MopSizes) {
2621 UnsizedMemOp->Mem.Size = Size;
2622 uint64_t ErrorInfoIgnore;
2623 unsigned LastOpcode = Inst.getOpcode();
2625 MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
2626 MatchingInlineAsm, isParsingIntelSyntax());
2627 if (Match.empty() || LastOpcode != Inst.getOpcode())
2630 // If this returned as a missing feature failure, remember that.
2631 if (Match.back() == Match_MissingFeature)
2632 ErrorInfoMissingFeature = ErrorInfoIgnore;
2635 // Restore the size of the unsized memory operand if we modified it.
2637 UnsizedMemOp->Mem.Size = 0;
2640 // If we haven't matched anything yet, this is not a basic integer or FPU
2641 // operation. There shouldn't be any ambiguity in our mneumonic table, so try
2642 // matching with the unsized operand.
2643 if (Match.empty()) {
2644 Match.push_back(MatchInstructionImpl(Operands, Inst, ErrorInfo,
2646 isParsingIntelSyntax()));
2647 // If this returned as a missing feature failure, remember that.
2648 if (Match.back() == Match_MissingFeature)
2649 ErrorInfoMissingFeature = ErrorInfo;
2652 // Restore the size of the unsized memory operand if we modified it.
2654 UnsizedMemOp->Mem.Size = 0;
2656 // If it's a bad mnemonic, all results will be the same.
2657 if (Match.back() == Match_MnemonicFail) {
2658 ArrayRef<SMRange> Ranges =
2659 MatchingInlineAsm ? EmptyRanges : Op.getLocRange();
2660 return Error(IDLoc, "invalid instruction mnemonic '" + Mnemonic + "'",
2661 Ranges, MatchingInlineAsm);
2664 // If exactly one matched, then we treat that as a successful match (and the
2665 // instruction will already have been filled in correctly, since the failing
2666 // matches won't have modified it).
2667 unsigned NumSuccessfulMatches =
2668 std::count(std::begin(Match), std::end(Match), Match_Success);
2669 if (NumSuccessfulMatches == 1) {
2670 // Some instructions need post-processing to, for example, tweak which
2671 // encoding is selected. Loop on it while changes happen so the individual
2672 // transformations can chain off each other.
2673 if (!MatchingInlineAsm)
2674 while (processInstruction(Inst, Operands))
2677 if (!MatchingInlineAsm)
2678 EmitInstruction(Inst, Operands, Out);
2679 Opcode = Inst.getOpcode();
2681 } else if (NumSuccessfulMatches > 1) {
2682 assert(UnsizedMemOp &&
2683 "multiple matches only possible with unsized memory operands");
2684 ArrayRef<SMRange> Ranges =
2685 MatchingInlineAsm ? EmptyRanges : UnsizedMemOp->getLocRange();
2686 return Error(UnsizedMemOp->getStartLoc(),
2687 "ambiguous operand size for instruction '" + Mnemonic + "\'",
2688 Ranges, MatchingInlineAsm);
2691 // If one instruction matched with a missing feature, report this as a
2693 if (std::count(std::begin(Match), std::end(Match),
2694 Match_MissingFeature) == 1) {
2695 ErrorInfo = ErrorInfoMissingFeature;
2696 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
2700 // If one instruction matched with an invalid operand, report this as an
2702 if (std::count(std::begin(Match), std::end(Match),
2703 Match_InvalidOperand) == 1) {
2704 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2708 // If all of these were an outright failure, report it in a useless way.
2709 return Error(IDLoc, "unknown instruction mnemonic", EmptyRanges,
2713 bool X86AsmParser::OmitRegisterFromClobberLists(unsigned RegNo) {
2714 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo);
2717 bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
2718 StringRef IDVal = DirectiveID.getIdentifier();
2719 if (IDVal == ".word")
2720 return ParseDirectiveWord(2, DirectiveID.getLoc());
2721 else if (IDVal.startswith(".code"))
2722 return ParseDirectiveCode(IDVal, DirectiveID.getLoc());
2723 else if (IDVal.startswith(".att_syntax")) {
2724 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2725 if (Parser.getTok().getString() == "prefix")
2727 else if (Parser.getTok().getString() == "noprefix")
2728 return Error(DirectiveID.getLoc(), "'.att_syntax noprefix' is not "
2729 "supported: registers must have a "
2730 "'%' prefix in .att_syntax");
2732 getParser().setAssemblerDialect(0);
2734 } else if (IDVal.startswith(".intel_syntax")) {
2735 getParser().setAssemblerDialect(1);
2736 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2737 if (Parser.getTok().getString() == "noprefix")
2739 else if (Parser.getTok().getString() == "prefix")
2740 return Error(DirectiveID.getLoc(), "'.intel_syntax prefix' is not "
2741 "supported: registers must not have "
2742 "a '%' prefix in .intel_syntax");
2749 /// ParseDirectiveWord
2750 /// ::= .word [ expression (, expression)* ]
2751 bool X86AsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
2752 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2754 const MCExpr *Value;
2755 if (getParser().parseExpression(Value))
2758 getParser().getStreamer().EmitValue(Value, Size);
2760 if (getLexer().is(AsmToken::EndOfStatement))
2763 // FIXME: Improve diagnostic.
2764 if (getLexer().isNot(AsmToken::Comma)) {
2765 Error(L, "unexpected token in directive");
2776 /// ParseDirectiveCode
2777 /// ::= .code16 | .code32 | .code64
2778 bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
2779 if (IDVal == ".code16") {
2781 if (!is16BitMode()) {
2782 SwitchMode(X86::Mode16Bit);
2783 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
2785 } else if (IDVal == ".code32") {
2787 if (!is32BitMode()) {
2788 SwitchMode(X86::Mode32Bit);
2789 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
2791 } else if (IDVal == ".code64") {
2793 if (!is64BitMode()) {
2794 SwitchMode(X86::Mode64Bit);
2795 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code64);
2798 Error(L, "unknown directive " + IDVal);
2805 // Force static initialization.
2806 extern "C" void LLVMInitializeX86AsmParser() {
2807 RegisterMCAsmParser<X86AsmParser> X(TheX86_32Target);
2808 RegisterMCAsmParser<X86AsmParser> Y(TheX86_64Target);
2811 #define GET_REGISTER_MATCHER
2812 #define GET_MATCHER_IMPLEMENTATION
2813 #define GET_SUBTARGET_FEATURE_NAME
2814 #include "X86GenAsmMatcher.inc"