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 "InstPrinter/X86IntelInstPrinter.h"
11 #include "MCTargetDesc/X86BaseInfo.h"
12 #include "MCTargetDesc/X86MCExpr.h"
13 #include "MCTargetDesc/X86TargetStreamer.h"
14 #include "X86AsmInstrumentation.h"
15 #include "X86AsmParserCommon.h"
16 #include "X86Operand.h"
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/ADT/SmallString.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/ADT/StringSwitch.h"
21 #include "llvm/ADT/Twine.h"
22 #include "llvm/MC/MCContext.h"
23 #include "llvm/MC/MCExpr.h"
24 #include "llvm/MC/MCInst.h"
25 #include "llvm/MC/MCInstrInfo.h"
26 #include "llvm/MC/MCParser/MCAsmLexer.h"
27 #include "llvm/MC/MCParser/MCAsmParser.h"
28 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
29 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
30 #include "llvm/MC/MCRegisterInfo.h"
31 #include "llvm/MC/MCSection.h"
32 #include "llvm/MC/MCStreamer.h"
33 #include "llvm/MC/MCSubtargetInfo.h"
34 #include "llvm/MC/MCSymbol.h"
35 #include "llvm/Support/SourceMgr.h"
36 #include "llvm/Support/TargetRegistry.h"
37 #include "llvm/Support/raw_ostream.h"
43 static bool checkScale(unsigned Scale, StringRef &ErrMsg) {
44 if (Scale != 1 && Scale != 2 && Scale != 4 && Scale != 8) {
45 ErrMsg = "scale factor in address must be 1, 2, 4 or 8";
53 static const char OpPrecedence[] = {
72 class X86AsmParser : public MCTargetAsmParser {
73 ParseInstructionInfo *InstInfo;
74 std::unique_ptr<X86AsmInstrumentation> Instrumentation;
78 SMLoc consumeToken() {
79 MCAsmParser &Parser = getParser();
80 SMLoc Result = Parser.getTok().getLoc();
85 X86TargetStreamer &getTargetStreamer() {
86 assert(getParser().getStreamer().getTargetStreamer() &&
87 "do not have a target streamer");
88 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
89 return static_cast<X86TargetStreamer &>(TS);
92 unsigned MatchInstruction(const OperandVector &Operands, MCInst &Inst,
93 uint64_t &ErrorInfo, bool matchingInlineAsm,
94 unsigned VariantID = 0) {
95 // In Code16GCC mode, match as 32-bit.
97 SwitchMode(X86::Mode32Bit);
98 unsigned rv = MatchInstructionImpl(Operands, Inst, ErrorInfo,
99 matchingInlineAsm, VariantID);
101 SwitchMode(X86::Mode16Bit);
105 enum InfixCalculatorTok {
124 enum IntelOperatorKind {
132 class InfixCalculator {
133 typedef std::pair< InfixCalculatorTok, int64_t > ICToken;
134 SmallVector<InfixCalculatorTok, 4> InfixOperatorStack;
135 SmallVector<ICToken, 4> PostfixStack;
137 bool isUnaryOperator(const InfixCalculatorTok Op) {
138 return Op == IC_NEG || Op == IC_NOT;
142 int64_t popOperand() {
143 assert (!PostfixStack.empty() && "Poped an empty stack!");
144 ICToken Op = PostfixStack.pop_back_val();
145 if (!(Op.first == IC_IMM || Op.first == IC_REGISTER))
146 return -1; // The invalid Scale value will be caught later by checkScale
149 void pushOperand(InfixCalculatorTok Op, int64_t Val = 0) {
150 assert ((Op == IC_IMM || Op == IC_REGISTER) &&
151 "Unexpected operand!");
152 PostfixStack.push_back(std::make_pair(Op, Val));
155 void popOperator() { InfixOperatorStack.pop_back(); }
156 void pushOperator(InfixCalculatorTok Op) {
157 // Push the new operator if the stack is empty.
158 if (InfixOperatorStack.empty()) {
159 InfixOperatorStack.push_back(Op);
163 // Push the new operator if it has a higher precedence than the operator
164 // on the top of the stack or the operator on the top of the stack is a
166 unsigned Idx = InfixOperatorStack.size() - 1;
167 InfixCalculatorTok StackOp = InfixOperatorStack[Idx];
168 if (OpPrecedence[Op] > OpPrecedence[StackOp] || StackOp == IC_LPAREN) {
169 InfixOperatorStack.push_back(Op);
173 // The operator on the top of the stack has higher precedence than the
175 unsigned ParenCount = 0;
177 // Nothing to process.
178 if (InfixOperatorStack.empty())
181 Idx = InfixOperatorStack.size() - 1;
182 StackOp = InfixOperatorStack[Idx];
183 if (!(OpPrecedence[StackOp] >= OpPrecedence[Op] || ParenCount))
186 // If we have an even parentheses count and we see a left parentheses,
187 // then stop processing.
188 if (!ParenCount && StackOp == IC_LPAREN)
191 if (StackOp == IC_RPAREN) {
193 InfixOperatorStack.pop_back();
194 } else if (StackOp == IC_LPAREN) {
196 InfixOperatorStack.pop_back();
198 InfixOperatorStack.pop_back();
199 PostfixStack.push_back(std::make_pair(StackOp, 0));
202 // Push the new operator.
203 InfixOperatorStack.push_back(Op);
207 // Push any remaining operators onto the postfix stack.
208 while (!InfixOperatorStack.empty()) {
209 InfixCalculatorTok StackOp = InfixOperatorStack.pop_back_val();
210 if (StackOp != IC_LPAREN && StackOp != IC_RPAREN)
211 PostfixStack.push_back(std::make_pair(StackOp, 0));
214 if (PostfixStack.empty())
217 SmallVector<ICToken, 16> OperandStack;
218 for (unsigned i = 0, e = PostfixStack.size(); i != e; ++i) {
219 ICToken Op = PostfixStack[i];
220 if (Op.first == IC_IMM || Op.first == IC_REGISTER) {
221 OperandStack.push_back(Op);
222 } else if (isUnaryOperator(Op.first)) {
223 assert (OperandStack.size() > 0 && "Too few operands.");
224 ICToken Operand = OperandStack.pop_back_val();
225 assert (Operand.first == IC_IMM &&
226 "Unary operation with a register!");
229 report_fatal_error("Unexpected operator!");
232 OperandStack.push_back(std::make_pair(IC_IMM, -Operand.second));
235 OperandStack.push_back(std::make_pair(IC_IMM, ~Operand.second));
239 assert (OperandStack.size() > 1 && "Too few operands.");
241 ICToken Op2 = OperandStack.pop_back_val();
242 ICToken Op1 = OperandStack.pop_back_val();
245 report_fatal_error("Unexpected operator!");
248 Val = Op1.second + Op2.second;
249 OperandStack.push_back(std::make_pair(IC_IMM, Val));
252 Val = Op1.second - Op2.second;
253 OperandStack.push_back(std::make_pair(IC_IMM, Val));
256 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
257 "Multiply operation with an immediate and a register!");
258 Val = Op1.second * Op2.second;
259 OperandStack.push_back(std::make_pair(IC_IMM, Val));
262 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
263 "Divide operation with an immediate and a register!");
264 assert (Op2.second != 0 && "Division by zero!");
265 Val = Op1.second / Op2.second;
266 OperandStack.push_back(std::make_pair(IC_IMM, Val));
269 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
270 "Modulo operation with an immediate and a register!");
271 Val = Op1.second % Op2.second;
272 OperandStack.push_back(std::make_pair(IC_IMM, Val));
275 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
276 "Or operation with an immediate and a register!");
277 Val = Op1.second | Op2.second;
278 OperandStack.push_back(std::make_pair(IC_IMM, Val));
281 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
282 "Xor operation with an immediate and a register!");
283 Val = Op1.second ^ Op2.second;
284 OperandStack.push_back(std::make_pair(IC_IMM, Val));
287 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
288 "And operation with an immediate and a register!");
289 Val = Op1.second & Op2.second;
290 OperandStack.push_back(std::make_pair(IC_IMM, Val));
293 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
294 "Left shift operation with an immediate and a register!");
295 Val = Op1.second << Op2.second;
296 OperandStack.push_back(std::make_pair(IC_IMM, Val));
299 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
300 "Right shift operation with an immediate and a register!");
301 Val = Op1.second >> Op2.second;
302 OperandStack.push_back(std::make_pair(IC_IMM, Val));
307 assert (OperandStack.size() == 1 && "Expected a single result.");
308 return OperandStack.pop_back_val().second;
312 enum IntelExprState {
335 class IntelExprStateMachine {
336 IntelExprState State, PrevState;
337 unsigned BaseReg, IndexReg, TmpReg, Scale;
342 InlineAsmIdentifierInfo Info;
347 IntelExprStateMachine()
348 : State(IES_INIT), PrevState(IES_ERROR), BaseReg(0), IndexReg(0),
349 TmpReg(0), Scale(0), Imm(0), Sym(nullptr), BracCount(0),
352 void addImm(int64_t imm) { Imm += imm; }
353 short getBracCount() { return BracCount; }
354 bool isMemExpr() { return MemExpr; }
355 unsigned getBaseReg() { return BaseReg; }
356 unsigned getIndexReg() { return IndexReg; }
357 unsigned getScale() { return Scale; }
358 const MCExpr *getSym() { return Sym; }
359 StringRef getSymName() { return SymName; }
360 int64_t getImm() { return Imm + IC.execute(); }
361 bool isValidEndState() {
362 return State == IES_RBRAC || State == IES_INTEGER;
364 bool hadError() { return State == IES_ERROR; }
365 InlineAsmIdentifierInfo &getIdentifierInfo() { return Info; }
368 IntelExprState CurrState = State;
377 IC.pushOperator(IC_OR);
380 PrevState = CurrState;
383 IntelExprState CurrState = State;
392 IC.pushOperator(IC_XOR);
395 PrevState = CurrState;
398 IntelExprState CurrState = State;
407 IC.pushOperator(IC_AND);
410 PrevState = CurrState;
413 IntelExprState CurrState = State;
422 IC.pushOperator(IC_LSHIFT);
425 PrevState = CurrState;
428 IntelExprState CurrState = State;
437 IC.pushOperator(IC_RSHIFT);
440 PrevState = CurrState;
442 bool onPlus(StringRef &ErrMsg) {
443 IntelExprState CurrState = State;
452 IC.pushOperator(IC_PLUS);
453 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
454 // If we already have a BaseReg, then assume this is the IndexReg with
455 // no explicit scale.
460 ErrMsg = "BaseReg/IndexReg already set!";
469 PrevState = CurrState;
472 bool onMinus(StringRef &ErrMsg) {
473 IntelExprState CurrState = State;
496 // push minus operator if it is not a negate operator
497 if (CurrState == IES_REGISTER || CurrState == IES_RPAREN ||
498 CurrState == IES_INTEGER || CurrState == IES_RBRAC)
499 IC.pushOperator(IC_MINUS);
500 else if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
501 // We have negate operator for Scale: it's illegal
502 ErrMsg = "Scale can't be negative";
505 IC.pushOperator(IC_NEG);
506 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
507 // If we already have a BaseReg, then assume this is the IndexReg with
508 // no explicit scale.
513 ErrMsg = "BaseReg/IndexReg already set!";
522 PrevState = CurrState;
526 IntelExprState CurrState = State;
546 IC.pushOperator(IC_NOT);
549 PrevState = CurrState;
552 bool onRegister(unsigned Reg, StringRef &ErrMsg) {
553 IntelExprState CurrState = State;
561 State = IES_REGISTER;
563 IC.pushOperand(IC_REGISTER);
566 // Index Register - Scale * Register
567 if (PrevState == IES_INTEGER) {
569 ErrMsg = "BaseReg/IndexReg already set!";
572 State = IES_REGISTER;
574 // Get the scale and replace the 'Scale * Register' with '0'.
575 Scale = IC.popOperand();
576 if (checkScale(Scale, ErrMsg))
578 IC.pushOperand(IC_IMM);
585 PrevState = CurrState;
588 bool onIdentifierExpr(const MCExpr *SymRef, StringRef SymRefName,
589 const InlineAsmIdentifierInfo &IDInfo,
590 bool ParsingInlineAsm, StringRef &ErrMsg) {
591 // InlineAsm: Treat an enum value as an integer
592 if (ParsingInlineAsm)
593 if (IDInfo.isKind(InlineAsmIdentifierInfo::IK_EnumVal))
594 return onInteger(IDInfo.Enum.EnumVal, ErrMsg);
595 // Treat a symbolic constant like an integer
596 if (auto *CE = dyn_cast<MCConstantExpr>(SymRef))
597 return onInteger(CE->getValue(), ErrMsg);
599 bool HasSymbol = Sym != nullptr;
612 SymName = SymRefName;
613 IC.pushOperand(IC_IMM);
614 if (ParsingInlineAsm)
619 ErrMsg = "cannot use more than one symbol in memory operand";
622 bool onInteger(int64_t TmpInt, StringRef &ErrMsg) {
623 IntelExprState CurrState = State;
643 if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
644 // Index Register - Register * Scale
646 ErrMsg = "BaseReg/IndexReg already set!";
651 if (checkScale(Scale, ErrMsg))
653 // Get the scale and replace the 'Register * Scale' with '0'.
656 IC.pushOperand(IC_IMM, TmpInt);
660 PrevState = CurrState;
672 State = IES_MULTIPLY;
673 IC.pushOperator(IC_MULTIPLY);
686 IC.pushOperator(IC_DIVIDE);
699 IC.pushOperator(IC_MOD);
715 IC.pushOperator(IC_PLUS);
718 assert(!BracCount && "BracCount should be zero on parsing's start");
727 IntelExprState CurrState = State;
735 if (BracCount-- != 1)
738 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
739 // If we already have a BaseReg, then assume this is the IndexReg with
740 // no explicit scale.
744 assert (!IndexReg && "BaseReg/IndexReg already set!");
751 PrevState = CurrState;
755 IntelExprState CurrState = State;
775 IC.pushOperator(IC_LPAREN);
778 PrevState = CurrState;
790 IC.pushOperator(IC_RPAREN);
796 bool Error(SMLoc L, const Twine &Msg, SMRange Range = None,
797 bool MatchingInlineAsm = false) {
798 MCAsmParser &Parser = getParser();
799 if (MatchingInlineAsm) {
800 if (!getLexer().isAtStartOfStatement())
801 Parser.eatToEndOfStatement();
804 return Parser.Error(L, Msg, Range);
807 std::nullptr_t ErrorOperand(SMLoc Loc, StringRef Msg) {
812 std::unique_ptr<X86Operand> DefaultMemSIOperand(SMLoc Loc);
813 std::unique_ptr<X86Operand> DefaultMemDIOperand(SMLoc Loc);
814 bool IsSIReg(unsigned Reg);
815 unsigned GetSIDIForRegClass(unsigned RegClassID, unsigned Reg, bool IsSIReg);
817 AddDefaultSrcDestOperands(OperandVector &Operands,
818 std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
819 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst);
820 bool VerifyAndAdjustOperands(OperandVector &OrigOperands,
821 OperandVector &FinalOperands);
822 std::unique_ptr<X86Operand> ParseOperand(StringRef Mnemonic);
823 std::unique_ptr<X86Operand> ParseATTOperand(StringRef Mnemonic);
824 std::unique_ptr<X86Operand> ParseIntelOperand();
825 std::unique_ptr<X86Operand> ParseIntelOffsetOfOperator();
826 bool ParseIntelDotOperator(IntelExprStateMachine &SM, SMLoc &End);
827 unsigned IdentifyIntelInlineAsmOperator(StringRef Name);
828 unsigned ParseIntelInlineAsmOperator(unsigned OpKind);
829 std::unique_ptr<X86Operand> ParseRoundingModeOp(SMLoc Start);
830 bool ParseIntelNamedOperator(StringRef Name, IntelExprStateMachine &SM);
831 void RewriteIntelExpression(IntelExprStateMachine &SM, SMLoc Start,
833 bool ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End);
834 bool ParseIntelInlineAsmIdentifier(const MCExpr *&Val, StringRef &Identifier,
835 InlineAsmIdentifierInfo &Info,
836 bool IsUnevaluatedOperand, SMLoc &End);
838 std::unique_ptr<X86Operand> ParseMemOperand(unsigned SegReg, SMLoc StartLoc,
841 bool ParseIntelMemoryOperandSize(unsigned &Size);
842 std::unique_ptr<X86Operand>
843 CreateMemForInlineAsm(unsigned SegReg, const MCExpr *Disp, unsigned BaseReg,
844 unsigned IndexReg, unsigned Scale, SMLoc Start,
845 SMLoc End, unsigned Size, StringRef Identifier,
846 const InlineAsmIdentifierInfo &Info);
848 bool parseDirectiveEven(SMLoc L);
849 bool ParseDirectiveCode(StringRef IDVal, SMLoc L);
851 /// CodeView FPO data directives.
852 bool parseDirectiveFPOProc(SMLoc L);
853 bool parseDirectiveFPOSetFrame(SMLoc L);
854 bool parseDirectiveFPOPushReg(SMLoc L);
855 bool parseDirectiveFPOStackAlloc(SMLoc L);
856 bool parseDirectiveFPOEndPrologue(SMLoc L);
857 bool parseDirectiveFPOEndProc(SMLoc L);
858 bool parseDirectiveFPOData(SMLoc L);
860 bool validateInstruction(MCInst &Inst, const OperandVector &Ops);
861 bool processInstruction(MCInst &Inst, const OperandVector &Ops);
863 /// Wrapper around MCStreamer::EmitInstruction(). Possibly adds
864 /// instrumentation around Inst.
865 void EmitInstruction(MCInst &Inst, OperandVector &Operands, MCStreamer &Out);
867 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
868 OperandVector &Operands, MCStreamer &Out,
870 bool MatchingInlineAsm) override;
872 void MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op, OperandVector &Operands,
873 MCStreamer &Out, bool MatchingInlineAsm);
875 bool ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
876 bool MatchingInlineAsm);
878 bool MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
879 OperandVector &Operands, MCStreamer &Out,
881 bool MatchingInlineAsm);
883 bool MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
884 OperandVector &Operands, MCStreamer &Out,
886 bool MatchingInlineAsm);
888 bool OmitRegisterFromClobberLists(unsigned RegNo) override;
890 /// Parses AVX512 specific operand primitives: masked registers ({%k<NUM>}, {z})
891 /// and memory broadcasting ({1to<NUM>}) primitives, updating Operands vector if required.
892 /// return false if no parsing errors occurred, true otherwise.
893 bool HandleAVX512Operand(OperandVector &Operands,
894 const MCParsedAsmOperand &Op);
896 bool ParseZ(std::unique_ptr<X86Operand> &Z, const SMLoc &StartLoc);
898 bool is64BitMode() const {
899 // FIXME: Can tablegen auto-generate this?
900 return getSTI().getFeatureBits()[X86::Mode64Bit];
902 bool is32BitMode() const {
903 // FIXME: Can tablegen auto-generate this?
904 return getSTI().getFeatureBits()[X86::Mode32Bit];
906 bool is16BitMode() const {
907 // FIXME: Can tablegen auto-generate this?
908 return getSTI().getFeatureBits()[X86::Mode16Bit];
910 void SwitchMode(unsigned mode) {
911 MCSubtargetInfo &STI = copySTI();
912 FeatureBitset AllModes({X86::Mode64Bit, X86::Mode32Bit, X86::Mode16Bit});
913 FeatureBitset OldMode = STI.getFeatureBits() & AllModes;
914 uint64_t FB = ComputeAvailableFeatures(
915 STI.ToggleFeature(OldMode.flip(mode)));
916 setAvailableFeatures(FB);
918 assert(FeatureBitset({mode}) == (STI.getFeatureBits() & AllModes));
921 unsigned getPointerWidth() {
922 if (is16BitMode()) return 16;
923 if (is32BitMode()) return 32;
924 if (is64BitMode()) return 64;
925 llvm_unreachable("invalid mode");
928 bool isParsingIntelSyntax() {
929 return getParser().getAssemblerDialect();
932 /// @name Auto-generated Matcher Functions
935 #define GET_ASSEMBLER_HEADER
936 #include "X86GenAsmMatcher.inc"
942 X86AsmParser(const MCSubtargetInfo &sti, MCAsmParser &Parser,
943 const MCInstrInfo &mii, const MCTargetOptions &Options)
944 : MCTargetAsmParser(Options, sti, mii), InstInfo(nullptr),
947 Parser.addAliasForDirective(".word", ".2byte");
949 // Initialize the set of available features.
950 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
951 Instrumentation.reset(
952 CreateX86AsmInstrumentation(Options, Parser.getContext(), STI));
955 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
957 void SetFrameRegister(unsigned RegNo) override;
959 bool parseAssignmentExpression(const MCExpr *&Res, SMLoc &EndLoc) override;
961 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
962 SMLoc NameLoc, OperandVector &Operands) override;
964 bool ParseDirective(AsmToken DirectiveID) override;
966 } // end anonymous namespace
968 /// @name Auto-generated Match Functions
971 static unsigned MatchRegisterName(StringRef Name);
975 static bool CheckBaseRegAndIndexRegAndScale(unsigned BaseReg, unsigned IndexReg,
976 unsigned Scale, bool Is64BitMode,
978 // If we have both a base register and an index register make sure they are
979 // both 64-bit or 32-bit registers.
980 // To support VSIB, IndexReg can be 128-bit or 256-bit registers.
983 !(BaseReg == X86::RIP || BaseReg == X86::EIP ||
984 X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) ||
985 X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg) ||
986 X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg))) {
987 ErrMsg = "invalid base+index expression";
992 !(IndexReg == X86::EIZ || IndexReg == X86::RIZ ||
993 X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
994 X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg) ||
995 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg) ||
996 X86MCRegisterClasses[X86::VR128XRegClassID].contains(IndexReg) ||
997 X86MCRegisterClasses[X86::VR256XRegClassID].contains(IndexReg) ||
998 X86MCRegisterClasses[X86::VR512RegClassID].contains(IndexReg))) {
999 ErrMsg = "invalid base+index expression";
1003 if (((BaseReg == X86::RIP || BaseReg == X86::EIP) && IndexReg != 0) ||
1004 IndexReg == X86::EIP || IndexReg == X86::RIP ||
1005 IndexReg == X86::ESP || IndexReg == X86::RSP) {
1006 ErrMsg = "invalid base+index expression";
1010 // Check for use of invalid 16-bit registers. Only BX/BP/SI/DI are allowed,
1011 // and then only in non-64-bit modes.
1012 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
1013 (Is64BitMode || (BaseReg != X86::BX && BaseReg != X86::BP &&
1014 BaseReg != X86::SI && BaseReg != X86::DI))) {
1015 ErrMsg = "invalid 16-bit base register";
1020 X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg)) {
1021 ErrMsg = "16-bit memory operand may not include only index register";
1025 if (BaseReg != 0 && IndexReg != 0) {
1026 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) &&
1027 (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
1028 X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg) ||
1029 IndexReg == X86::EIZ)) {
1030 ErrMsg = "base register is 64-bit, but index register is not";
1033 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg) &&
1034 (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
1035 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg) ||
1036 IndexReg == X86::RIZ)) {
1037 ErrMsg = "base register is 32-bit, but index register is not";
1040 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg)) {
1041 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg) ||
1042 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) {
1043 ErrMsg = "base register is 16-bit, but index register is not";
1046 if ((BaseReg != X86::BX && BaseReg != X86::BP) ||
1047 (IndexReg != X86::SI && IndexReg != X86::DI)) {
1048 ErrMsg = "invalid 16-bit base/index register combination";
1054 // RIP/EIP-relative addressing is only supported in 64-bit mode.
1055 if (!Is64BitMode && BaseReg != 0 &&
1056 (BaseReg == X86::RIP || BaseReg == X86::EIP)) {
1057 ErrMsg = "RIP-relative addressing requires 64-bit mode";
1061 return checkScale(Scale, ErrMsg);
1064 bool X86AsmParser::ParseRegister(unsigned &RegNo,
1065 SMLoc &StartLoc, SMLoc &EndLoc) {
1066 MCAsmParser &Parser = getParser();
1068 const AsmToken &PercentTok = Parser.getTok();
1069 StartLoc = PercentTok.getLoc();
1071 // If we encounter a %, ignore it. This code handles registers with and
1072 // without the prefix, unprefixed registers can occur in cfi directives.
1073 if (!isParsingIntelSyntax() && PercentTok.is(AsmToken::Percent))
1074 Parser.Lex(); // Eat percent token.
1076 const AsmToken &Tok = Parser.getTok();
1077 EndLoc = Tok.getEndLoc();
1079 if (Tok.isNot(AsmToken::Identifier)) {
1080 if (isParsingIntelSyntax()) return true;
1081 return Error(StartLoc, "invalid register name",
1082 SMRange(StartLoc, EndLoc));
1085 RegNo = MatchRegisterName(Tok.getString());
1087 // If the match failed, try the register name as lowercase.
1089 RegNo = MatchRegisterName(Tok.getString().lower());
1091 // The "flags" register cannot be referenced directly.
1092 // Treat it as an identifier instead.
1093 if (isParsingInlineAsm() && isParsingIntelSyntax() && RegNo == X86::EFLAGS)
1096 if (!is64BitMode()) {
1097 // FIXME: This should be done using Requires<Not64BitMode> and
1098 // Requires<In64BitMode> so "eiz" usage in 64-bit instructions can be also
1100 // FIXME: Check AH, CH, DH, BH cannot be used in an instruction requiring a
1102 if (RegNo == X86::RIZ || RegNo == X86::RIP || RegNo == X86::EIP ||
1103 X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo) ||
1104 X86II::isX86_64NonExtLowByteReg(RegNo) ||
1105 X86II::isX86_64ExtendedReg(RegNo))
1106 return Error(StartLoc, "register %"
1107 + Tok.getString() + " is only available in 64-bit mode",
1108 SMRange(StartLoc, EndLoc));
1111 // Parse "%st" as "%st(0)" and "%st(1)", which is multiple tokens.
1112 if (RegNo == 0 && (Tok.getString() == "st" || Tok.getString() == "ST")) {
1114 Parser.Lex(); // Eat 'st'
1116 // Check to see if we have '(4)' after %st.
1117 if (getLexer().isNot(AsmToken::LParen))
1122 const AsmToken &IntTok = Parser.getTok();
1123 if (IntTok.isNot(AsmToken::Integer))
1124 return Error(IntTok.getLoc(), "expected stack index");
1125 switch (IntTok.getIntVal()) {
1126 case 0: RegNo = X86::ST0; break;
1127 case 1: RegNo = X86::ST1; break;
1128 case 2: RegNo = X86::ST2; break;
1129 case 3: RegNo = X86::ST3; break;
1130 case 4: RegNo = X86::ST4; break;
1131 case 5: RegNo = X86::ST5; break;
1132 case 6: RegNo = X86::ST6; break;
1133 case 7: RegNo = X86::ST7; break;
1134 default: return Error(IntTok.getLoc(), "invalid stack index");
1137 if (getParser().Lex().isNot(AsmToken::RParen))
1138 return Error(Parser.getTok().getLoc(), "expected ')'");
1140 EndLoc = Parser.getTok().getEndLoc();
1141 Parser.Lex(); // Eat ')'
1145 EndLoc = Parser.getTok().getEndLoc();
1147 // If this is "db[0-15]", match it as an alias
1149 if (RegNo == 0 && Tok.getString().startswith("db")) {
1150 if (Tok.getString().size() == 3) {
1151 switch (Tok.getString()[2]) {
1152 case '0': RegNo = X86::DR0; break;
1153 case '1': RegNo = X86::DR1; break;
1154 case '2': RegNo = X86::DR2; break;
1155 case '3': RegNo = X86::DR3; break;
1156 case '4': RegNo = X86::DR4; break;
1157 case '5': RegNo = X86::DR5; break;
1158 case '6': RegNo = X86::DR6; break;
1159 case '7': RegNo = X86::DR7; break;
1160 case '8': RegNo = X86::DR8; break;
1161 case '9': RegNo = X86::DR9; break;
1163 } else if (Tok.getString().size() == 4 && Tok.getString()[2] == '1') {
1164 switch (Tok.getString()[3]) {
1165 case '0': RegNo = X86::DR10; break;
1166 case '1': RegNo = X86::DR11; break;
1167 case '2': RegNo = X86::DR12; break;
1168 case '3': RegNo = X86::DR13; break;
1169 case '4': RegNo = X86::DR14; break;
1170 case '5': RegNo = X86::DR15; break;
1175 EndLoc = Parser.getTok().getEndLoc();
1176 Parser.Lex(); // Eat it.
1182 if (isParsingIntelSyntax()) return true;
1183 return Error(StartLoc, "invalid register name",
1184 SMRange(StartLoc, EndLoc));
1187 Parser.Lex(); // Eat identifier token.
1191 void X86AsmParser::SetFrameRegister(unsigned RegNo) {
1192 Instrumentation->SetInitialFrameRegister(RegNo);
1195 std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(SMLoc Loc) {
1196 bool Parse32 = is32BitMode() || Code16GCC;
1197 unsigned Basereg = is64BitMode() ? X86::RSI : (Parse32 ? X86::ESI : X86::SI);
1198 const MCExpr *Disp = MCConstantExpr::create(0, getContext());
1199 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
1200 /*BaseReg=*/Basereg, /*IndexReg=*/0, /*Scale=*/1,
1204 std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand(SMLoc Loc) {
1205 bool Parse32 = is32BitMode() || Code16GCC;
1206 unsigned Basereg = is64BitMode() ? X86::RDI : (Parse32 ? X86::EDI : X86::DI);
1207 const MCExpr *Disp = MCConstantExpr::create(0, getContext());
1208 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
1209 /*BaseReg=*/Basereg, /*IndexReg=*/0, /*Scale=*/1,
1213 bool X86AsmParser::IsSIReg(unsigned Reg) {
1215 default: llvm_unreachable("Only (R|E)SI and (R|E)DI are expected!");
1227 unsigned X86AsmParser::GetSIDIForRegClass(unsigned RegClassID, unsigned Reg,
1229 switch (RegClassID) {
1230 default: llvm_unreachable("Unexpected register class");
1231 case X86::GR64RegClassID:
1232 return IsSIReg ? X86::RSI : X86::RDI;
1233 case X86::GR32RegClassID:
1234 return IsSIReg ? X86::ESI : X86::EDI;
1235 case X86::GR16RegClassID:
1236 return IsSIReg ? X86::SI : X86::DI;
1240 void X86AsmParser::AddDefaultSrcDestOperands(
1241 OperandVector& Operands, std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
1242 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst) {
1243 if (isParsingIntelSyntax()) {
1244 Operands.push_back(std::move(Dst));
1245 Operands.push_back(std::move(Src));
1248 Operands.push_back(std::move(Src));
1249 Operands.push_back(std::move(Dst));
1253 bool X86AsmParser::VerifyAndAdjustOperands(OperandVector &OrigOperands,
1254 OperandVector &FinalOperands) {
1256 if (OrigOperands.size() > 1) {
1257 // Check if sizes match, OrigOperands also contains the instruction name
1258 assert(OrigOperands.size() == FinalOperands.size() + 1 &&
1259 "Operand size mismatch");
1261 SmallVector<std::pair<SMLoc, std::string>, 2> Warnings;
1262 // Verify types match
1263 int RegClassID = -1;
1264 for (unsigned int i = 0; i < FinalOperands.size(); ++i) {
1265 X86Operand &OrigOp = static_cast<X86Operand &>(*OrigOperands[i + 1]);
1266 X86Operand &FinalOp = static_cast<X86Operand &>(*FinalOperands[i]);
1268 if (FinalOp.isReg() &&
1269 (!OrigOp.isReg() || FinalOp.getReg() != OrigOp.getReg()))
1270 // Return false and let a normal complaint about bogus operands happen
1273 if (FinalOp.isMem()) {
1275 if (!OrigOp.isMem())
1276 // Return false and let a normal complaint about bogus operands happen
1279 unsigned OrigReg = OrigOp.Mem.BaseReg;
1280 unsigned FinalReg = FinalOp.Mem.BaseReg;
1282 // If we've already encounterd a register class, make sure all register
1283 // bases are of the same register class
1284 if (RegClassID != -1 &&
1285 !X86MCRegisterClasses[RegClassID].contains(OrigReg)) {
1286 return Error(OrigOp.getStartLoc(),
1287 "mismatching source and destination index registers");
1290 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(OrigReg))
1291 RegClassID = X86::GR64RegClassID;
1292 else if (X86MCRegisterClasses[X86::GR32RegClassID].contains(OrigReg))
1293 RegClassID = X86::GR32RegClassID;
1294 else if (X86MCRegisterClasses[X86::GR16RegClassID].contains(OrigReg))
1295 RegClassID = X86::GR16RegClassID;
1297 // Unexpected register class type
1298 // Return false and let a normal complaint about bogus operands happen
1301 bool IsSI = IsSIReg(FinalReg);
1302 FinalReg = GetSIDIForRegClass(RegClassID, FinalReg, IsSI);
1304 if (FinalReg != OrigReg) {
1305 std::string RegName = IsSI ? "ES:(R|E)SI" : "ES:(R|E)DI";
1306 Warnings.push_back(std::make_pair(
1307 OrigOp.getStartLoc(),
1308 "memory operand is only for determining the size, " + RegName +
1309 " will be used for the location"));
1312 FinalOp.Mem.Size = OrigOp.Mem.Size;
1313 FinalOp.Mem.SegReg = OrigOp.Mem.SegReg;
1314 FinalOp.Mem.BaseReg = FinalReg;
1318 // Produce warnings only if all the operands passed the adjustment - prevent
1319 // legal cases like "movsd (%rax), %xmm0" mistakenly produce warnings
1320 for (auto &WarningMsg : Warnings) {
1321 Warning(WarningMsg.first, WarningMsg.second);
1324 // Remove old operands
1325 for (unsigned int i = 0; i < FinalOperands.size(); ++i)
1326 OrigOperands.pop_back();
1328 // OrigOperands.append(FinalOperands.begin(), FinalOperands.end());
1329 for (unsigned int i = 0; i < FinalOperands.size(); ++i)
1330 OrigOperands.push_back(std::move(FinalOperands[i]));
1335 std::unique_ptr<X86Operand> X86AsmParser::ParseOperand(StringRef Mnemonic) {
1336 if (isParsingIntelSyntax())
1337 return ParseIntelOperand();
1338 return ParseATTOperand(Mnemonic);
1341 std::unique_ptr<X86Operand> X86AsmParser::CreateMemForInlineAsm(
1342 unsigned SegReg, const MCExpr *Disp, unsigned BaseReg, unsigned IndexReg,
1343 unsigned Scale, SMLoc Start, SMLoc End, unsigned Size, StringRef Identifier,
1344 const InlineAsmIdentifierInfo &Info) {
1345 // If we found a decl other than a VarDecl, then assume it is a FuncDecl or
1346 // some other label reference.
1347 if (Info.isKind(InlineAsmIdentifierInfo::IK_Label)) {
1348 // Insert an explicit size if the user didn't have one.
1350 Size = getPointerWidth();
1351 InstInfo->AsmRewrites->emplace_back(AOK_SizeDirective, Start,
1354 // Create an absolute memory reference in order to match against
1355 // instructions taking a PC relative operand.
1356 return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size,
1357 Identifier, Info.Label.Decl);
1359 // We either have a direct symbol reference, or an offset from a symbol. The
1360 // parser always puts the symbol on the LHS, so look there for size
1361 // calculation purposes.
1362 unsigned FrontendSize = 0;
1363 void *Decl = nullptr;
1364 bool IsGlobalLV = false;
1365 if (Info.isKind(InlineAsmIdentifierInfo::IK_Var)) {
1366 // Size is in terms of bits in this context.
1367 FrontendSize = Info.Var.Type * 8;
1368 Decl = Info.Var.Decl;
1369 IsGlobalLV = Info.Var.IsGlobalLV;
1371 // It is widely common for MS InlineAsm to use a global variable and one/two
1372 // registers in a mmory expression, and though unaccessible via rip/eip.
1373 if (IsGlobalLV && (BaseReg || IndexReg)) {
1374 return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End);
1375 // Otherwise, we set the base register to a non-zero value
1376 // if we don't know the actual value at this time. This is necessary to
1377 // get the matching correct in some cases.
1379 BaseReg = BaseReg ? BaseReg : 1;
1380 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
1381 IndexReg, Scale, Start, End, Size, Identifier,
1382 Decl, FrontendSize);
1386 // Some binary bitwise operators have a named synonymous
1387 // Query a candidate string for being such a named operator
1388 // and if so - invoke the appropriate handler
1389 bool X86AsmParser::ParseIntelNamedOperator(StringRef Name, IntelExprStateMachine &SM) {
1390 // A named operator should be either lower or upper case, but not a mix
1391 if (Name.compare(Name.lower()) && Name.compare(Name.upper()))
1393 if (Name.equals_lower("not"))
1395 else if (Name.equals_lower("or"))
1397 else if (Name.equals_lower("shl"))
1399 else if (Name.equals_lower("shr"))
1401 else if (Name.equals_lower("xor"))
1403 else if (Name.equals_lower("and"))
1405 else if (Name.equals_lower("mod"))
1412 bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
1413 MCAsmParser &Parser = getParser();
1414 const AsmToken &Tok = Parser.getTok();
1417 AsmToken::TokenKind PrevTK = AsmToken::Error;
1420 bool UpdateLocLex = true;
1421 AsmToken::TokenKind TK = getLexer().getKind();
1425 if ((Done = SM.isValidEndState()))
1427 return Error(Tok.getLoc(), "unknown token in expression");
1428 case AsmToken::EndOfStatement:
1431 case AsmToken::Real:
1432 // DotOperator: [ebx].0
1433 UpdateLocLex = false;
1434 if (ParseIntelDotOperator(SM, End))
1438 case AsmToken::String:
1439 case AsmToken::Identifier: {
1440 SMLoc IdentLoc = Tok.getLoc();
1441 StringRef Identifier = Tok.getString();
1442 UpdateLocLex = false;
1445 if (Tok.is(AsmToken::Identifier) && !ParseRegister(Reg, IdentLoc, End)) {
1446 if (SM.onRegister(Reg, ErrMsg))
1447 return Error(Tok.getLoc(), ErrMsg);
1450 // Operator synonymous ("not", "or" etc.)
1451 if ((UpdateLocLex = ParseIntelNamedOperator(Identifier, SM)))
1453 // Symbol reference, when parsing assembly content
1454 InlineAsmIdentifierInfo Info;
1456 if (!isParsingInlineAsm()) {
1457 if (getParser().parsePrimaryExpr(Val, End)) {
1458 return Error(Tok.getLoc(), "Unexpected identifier!");
1459 } else if (SM.onIdentifierExpr(Val, Identifier, Info, false, ErrMsg)) {
1460 return Error(IdentLoc, ErrMsg);
1464 // MS InlineAsm operators (TYPE/LENGTH/SIZE)
1465 if (unsigned OpKind = IdentifyIntelInlineAsmOperator(Identifier)) {
1466 if (OpKind == IOK_OFFSET)
1467 return Error(IdentLoc, "Dealing OFFSET operator as part of"
1468 "a compound immediate expression is yet to be supported");
1469 if (int64_t Val = ParseIntelInlineAsmOperator(OpKind)) {
1470 if (SM.onInteger(Val, ErrMsg))
1471 return Error(IdentLoc, ErrMsg);
1476 // MS Dot Operator expression
1477 if (Identifier.count('.') && PrevTK == AsmToken::RBrac) {
1478 if (ParseIntelDotOperator(SM, End))
1482 // MS InlineAsm identifier
1483 // Call parseIdentifier() to combine @ with the identifier behind it.
1484 if (TK == AsmToken::At && Parser.parseIdentifier(Identifier))
1485 return Error(IdentLoc, "expected identifier");
1486 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info, false, End))
1488 else if (SM.onIdentifierExpr(Val, Identifier, Info, true, ErrMsg))
1489 return Error(IdentLoc, ErrMsg);
1492 case AsmToken::Integer: {
1493 // Look for 'b' or 'f' following an Integer as a directional label
1494 SMLoc Loc = getTok().getLoc();
1495 int64_t IntVal = getTok().getIntVal();
1496 End = consumeToken();
1497 UpdateLocLex = false;
1498 if (getLexer().getKind() == AsmToken::Identifier) {
1499 StringRef IDVal = getTok().getString();
1500 if (IDVal == "f" || IDVal == "b") {
1502 getContext().getDirectionalLocalSymbol(IntVal, IDVal == "b");
1503 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1505 MCSymbolRefExpr::create(Sym, Variant, getContext());
1506 if (IDVal == "b" && Sym->isUndefined())
1507 return Error(Loc, "invalid reference to undefined symbol");
1508 StringRef Identifier = Sym->getName();
1509 InlineAsmIdentifierInfo Info;
1510 if (SM.onIdentifierExpr(Val, Identifier, Info,
1511 isParsingInlineAsm(), ErrMsg))
1512 return Error(Loc, ErrMsg);
1513 End = consumeToken();
1515 if (SM.onInteger(IntVal, ErrMsg))
1516 return Error(Loc, ErrMsg);
1519 if (SM.onInteger(IntVal, ErrMsg))
1520 return Error(Loc, ErrMsg);
1524 case AsmToken::Plus:
1525 if (SM.onPlus(ErrMsg))
1526 return Error(getTok().getLoc(), ErrMsg);
1528 case AsmToken::Minus:
1529 if (SM.onMinus(ErrMsg))
1530 return Error(getTok().getLoc(), ErrMsg);
1532 case AsmToken::Tilde: SM.onNot(); break;
1533 case AsmToken::Star: SM.onStar(); break;
1534 case AsmToken::Slash: SM.onDivide(); break;
1535 case AsmToken::Percent: SM.onMod(); break;
1536 case AsmToken::Pipe: SM.onOr(); break;
1537 case AsmToken::Caret: SM.onXor(); break;
1538 case AsmToken::Amp: SM.onAnd(); break;
1539 case AsmToken::LessLess:
1540 SM.onLShift(); break;
1541 case AsmToken::GreaterGreater:
1542 SM.onRShift(); break;
1543 case AsmToken::LBrac:
1545 return Error(Tok.getLoc(), "unexpected bracket encountered");
1547 case AsmToken::RBrac:
1549 return Error(Tok.getLoc(), "unexpected bracket encountered");
1551 case AsmToken::LParen: SM.onLParen(); break;
1552 case AsmToken::RParen: SM.onRParen(); break;
1555 return Error(Tok.getLoc(), "unknown token in expression");
1557 if (!Done && UpdateLocLex)
1558 End = consumeToken();
1565 void X86AsmParser::RewriteIntelExpression(IntelExprStateMachine &SM,
1566 SMLoc Start, SMLoc End) {
1568 unsigned ExprLen = End.getPointer() - Start.getPointer();
1569 // Skip everything before a symbol displacement (if we have one)
1571 StringRef SymName = SM.getSymName();
1572 if (unsigned Len = SymName.data() - Start.getPointer())
1573 InstInfo->AsmRewrites->emplace_back(AOK_Skip, Start, Len);
1574 Loc = SMLoc::getFromPointer(SymName.data() + SymName.size());
1575 ExprLen = End.getPointer() - (SymName.data() + SymName.size());
1576 // If we have only a symbol than there's no need for complex rewrite,
1577 // simply skip everything after it
1578 if (!(SM.getBaseReg() || SM.getIndexReg() || SM.getImm())) {
1580 InstInfo->AsmRewrites->emplace_back(AOK_Skip, Loc, ExprLen);
1584 // Build an Intel Expression rewrite
1585 StringRef BaseRegStr;
1586 StringRef IndexRegStr;
1587 if (SM.getBaseReg())
1588 BaseRegStr = X86IntelInstPrinter::getRegisterName(SM.getBaseReg());
1589 if (SM.getIndexReg())
1590 IndexRegStr = X86IntelInstPrinter::getRegisterName(SM.getIndexReg());
1592 IntelExpr Expr(BaseRegStr, IndexRegStr, SM.getScale(), SM.getImm(), SM.isMemExpr());
1593 InstInfo->AsmRewrites->emplace_back(Loc, ExprLen, Expr);
1596 // Inline assembly may use variable names with namespace alias qualifiers.
1597 bool X86AsmParser::ParseIntelInlineAsmIdentifier(const MCExpr *&Val,
1598 StringRef &Identifier,
1599 InlineAsmIdentifierInfo &Info,
1600 bool IsUnevaluatedOperand,
1602 MCAsmParser &Parser = getParser();
1603 assert(isParsingInlineAsm() && "Expected to be parsing inline assembly.");
1606 StringRef LineBuf(Identifier.data());
1607 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);
1609 const AsmToken &Tok = Parser.getTok();
1610 SMLoc Loc = Tok.getLoc();
1612 // Advance the token stream until the end of the current token is
1613 // after the end of what the frontend claimed.
1614 const char *EndPtr = Tok.getLoc().getPointer() + LineBuf.size();
1616 End = Tok.getEndLoc();
1618 } while (End.getPointer() < EndPtr);
1619 Identifier = LineBuf;
1621 // The frontend should end parsing on an assembler token boundary, unless it
1623 assert((End.getPointer() == EndPtr ||
1624 Info.isKind(InlineAsmIdentifierInfo::IK_Invalid)) &&
1625 "frontend claimed part of a token?");
1627 // If the identifier lookup was unsuccessful, assume that we are dealing with
1629 if (Info.isKind(InlineAsmIdentifierInfo::IK_Invalid)) {
1630 StringRef InternalName =
1631 SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(),
1633 assert(InternalName.size() && "We should have an internal name here.");
1634 // Push a rewrite for replacing the identifier name with the internal name.
1635 InstInfo->AsmRewrites->emplace_back(AOK_Label, Loc, Identifier.size(),
1637 } else if (Info.isKind(InlineAsmIdentifierInfo::IK_EnumVal))
1639 // Create the symbol reference.
1640 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
1641 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1642 Val = MCSymbolRefExpr::create(Sym, Variant, getParser().getContext());
1646 //ParseRoundingModeOp - Parse AVX-512 rounding mode operand
1647 std::unique_ptr<X86Operand>
1648 X86AsmParser::ParseRoundingModeOp(SMLoc Start) {
1649 MCAsmParser &Parser = getParser();
1650 const AsmToken &Tok = Parser.getTok();
1651 // Eat "{" and mark the current place.
1652 const SMLoc consumedToken = consumeToken();
1653 if (Tok.getIdentifier().startswith("r")){
1654 int rndMode = StringSwitch<int>(Tok.getIdentifier())
1655 .Case("rn", X86::STATIC_ROUNDING::TO_NEAREST_INT)
1656 .Case("rd", X86::STATIC_ROUNDING::TO_NEG_INF)
1657 .Case("ru", X86::STATIC_ROUNDING::TO_POS_INF)
1658 .Case("rz", X86::STATIC_ROUNDING::TO_ZERO)
1661 return ErrorOperand(Tok.getLoc(), "Invalid rounding mode.");
1662 Parser.Lex(); // Eat "r*" of r*-sae
1663 if (!getLexer().is(AsmToken::Minus))
1664 return ErrorOperand(Tok.getLoc(), "Expected - at this point");
1665 Parser.Lex(); // Eat "-"
1666 Parser.Lex(); // Eat the sae
1667 if (!getLexer().is(AsmToken::RCurly))
1668 return ErrorOperand(Tok.getLoc(), "Expected } at this point");
1669 SMLoc End = Tok.getEndLoc();
1670 Parser.Lex(); // Eat "}"
1671 const MCExpr *RndModeOp =
1672 MCConstantExpr::create(rndMode, Parser.getContext());
1673 return X86Operand::CreateImm(RndModeOp, Start, End);
1675 if(Tok.getIdentifier().equals("sae")){
1676 Parser.Lex(); // Eat the sae
1677 if (!getLexer().is(AsmToken::RCurly))
1678 return ErrorOperand(Tok.getLoc(), "Expected } at this point");
1679 Parser.Lex(); // Eat "}"
1680 return X86Operand::CreateToken("{sae}", consumedToken);
1682 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1685 /// Parse the '.' operator.
1686 bool X86AsmParser::ParseIntelDotOperator(IntelExprStateMachine &SM, SMLoc &End) {
1687 const AsmToken &Tok = getTok();
1690 // Drop the optional '.'.
1691 StringRef DotDispStr = Tok.getString();
1692 if (DotDispStr.startswith("."))
1693 DotDispStr = DotDispStr.drop_front(1);
1695 // .Imm gets lexed as a real.
1696 if (Tok.is(AsmToken::Real)) {
1698 DotDispStr.getAsInteger(10, DotDisp);
1699 Offset = DotDisp.getZExtValue();
1700 } else if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) {
1701 std::pair<StringRef, StringRef> BaseMember = DotDispStr.split('.');
1702 if (SemaCallback->LookupInlineAsmField(BaseMember.first, BaseMember.second,
1704 return Error(Tok.getLoc(), "Unable to lookup field reference!");
1706 return Error(Tok.getLoc(), "Unexpected token type!");
1708 // Eat the DotExpression and update End
1709 End = SMLoc::getFromPointer(DotDispStr.data());
1710 const char *DotExprEndLoc = DotDispStr.data() + DotDispStr.size();
1711 while (Tok.getLoc().getPointer() < DotExprEndLoc)
1717 /// Parse the 'offset' operator. This operator is used to specify the
1718 /// location rather then the content of a variable.
1719 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOffsetOfOperator() {
1720 MCAsmParser &Parser = getParser();
1721 const AsmToken &Tok = Parser.getTok();
1722 SMLoc OffsetOfLoc = Tok.getLoc();
1723 Parser.Lex(); // Eat offset.
1726 InlineAsmIdentifierInfo Info;
1727 SMLoc Start = Tok.getLoc(), End;
1728 StringRef Identifier = Tok.getString();
1729 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
1730 /*Unevaluated=*/false, End))
1733 void *Decl = nullptr;
1734 // FIXME: MS evaluates "offset <Constant>" to the underlying integral
1735 if (Info.isKind(InlineAsmIdentifierInfo::IK_EnumVal))
1736 return ErrorOperand(Start, "offset operator cannot yet handle constants");
1737 else if (Info.isKind(InlineAsmIdentifierInfo::IK_Var))
1738 Decl = Info.Var.Decl;
1739 // Don't emit the offset operator.
1740 InstInfo->AsmRewrites->emplace_back(AOK_Skip, OffsetOfLoc, 7);
1742 // The offset operator will have an 'r' constraint, thus we need to create
1743 // register operand to ensure proper matching. Just pick a GPR based on
1744 // the size of a pointer.
1745 bool Parse32 = is32BitMode() || Code16GCC;
1746 unsigned RegNo = is64BitMode() ? X86::RBX : (Parse32 ? X86::EBX : X86::BX);
1748 return X86Operand::CreateReg(RegNo, Start, End, /*GetAddress=*/true,
1749 OffsetOfLoc, Identifier, Decl);
1752 // Query a candidate string for being an Intel assembly operator
1753 // Report back its kind, or IOK_INVALID if does not evaluated as a known one
1754 unsigned X86AsmParser::IdentifyIntelInlineAsmOperator(StringRef Name) {
1755 return StringSwitch<unsigned>(Name)
1756 .Cases("TYPE","type",IOK_TYPE)
1757 .Cases("SIZE","size",IOK_SIZE)
1758 .Cases("LENGTH","length",IOK_LENGTH)
1759 .Cases("OFFSET","offset",IOK_OFFSET)
1760 .Default(IOK_INVALID);
1763 /// Parse the 'LENGTH', 'TYPE' and 'SIZE' operators. The LENGTH operator
1764 /// returns the number of elements in an array. It returns the value 1 for
1765 /// non-array variables. The SIZE operator returns the size of a C or C++
1766 /// variable. A variable's size is the product of its LENGTH and TYPE. The
1767 /// TYPE operator returns the size of a C or C++ type or variable. If the
1768 /// variable is an array, TYPE returns the size of a single element.
1769 unsigned X86AsmParser::ParseIntelInlineAsmOperator(unsigned OpKind) {
1770 MCAsmParser &Parser = getParser();
1771 const AsmToken &Tok = Parser.getTok();
1772 Parser.Lex(); // Eat operator.
1774 const MCExpr *Val = nullptr;
1775 InlineAsmIdentifierInfo Info;
1776 SMLoc Start = Tok.getLoc(), End;
1777 StringRef Identifier = Tok.getString();
1778 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
1779 /*Unevaluated=*/true, End))
1782 if (!Info.isKind(InlineAsmIdentifierInfo::IK_Var)) {
1783 Error(Start, "unable to lookup expression");
1789 default: llvm_unreachable("Unexpected operand kind!");
1790 case IOK_LENGTH: CVal = Info.Var.Length; break;
1791 case IOK_SIZE: CVal = Info.Var.Size; break;
1792 case IOK_TYPE: CVal = Info.Var.Type; break;
1798 bool X86AsmParser::ParseIntelMemoryOperandSize(unsigned &Size) {
1799 Size = StringSwitch<unsigned>(getTok().getString())
1800 .Cases("BYTE", "byte", 8)
1801 .Cases("WORD", "word", 16)
1802 .Cases("DWORD", "dword", 32)
1803 .Cases("FLOAT", "float", 32)
1804 .Cases("LONG", "long", 32)
1805 .Cases("FWORD", "fword", 48)
1806 .Cases("DOUBLE", "double", 64)
1807 .Cases("QWORD", "qword", 64)
1808 .Cases("MMWORD","mmword", 64)
1809 .Cases("XWORD", "xword", 80)
1810 .Cases("TBYTE", "tbyte", 80)
1811 .Cases("XMMWORD", "xmmword", 128)
1812 .Cases("YMMWORD", "ymmword", 256)
1813 .Cases("ZMMWORD", "zmmword", 512)
1816 const AsmToken &Tok = Lex(); // Eat operand size (e.g., byte, word).
1817 if (!(Tok.getString().equals("PTR") || Tok.getString().equals("ptr")))
1818 return Error(Tok.getLoc(), "Expected 'PTR' or 'ptr' token!");
1824 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand() {
1825 MCAsmParser &Parser = getParser();
1826 const AsmToken &Tok = Parser.getTok();
1829 // FIXME: Offset operator
1830 // Should be handled as part of immediate expression, as other operators
1831 // Currently, only supported as a stand-alone operand
1832 if (isParsingInlineAsm())
1833 if (IdentifyIntelInlineAsmOperator(Tok.getString()) == IOK_OFFSET)
1834 return ParseIntelOffsetOfOperator();
1836 // Parse optional Size directive.
1838 if (ParseIntelMemoryOperandSize(Size))
1840 bool PtrInOperand = bool(Size);
1842 Start = Tok.getLoc();
1844 // Rounding mode operand.
1845 if (getLexer().is(AsmToken::LCurly))
1846 return ParseRoundingModeOp(Start);
1848 // Register operand.
1850 if (Tok.is(AsmToken::Identifier) && !ParseRegister(RegNo, Start, End)) {
1851 if (RegNo == X86::RIP)
1852 return ErrorOperand(Start, "rip can only be used as a base register");
1853 // A Register followed by ':' is considered a segment override
1854 if (Tok.isNot(AsmToken::Colon))
1855 return !PtrInOperand ? X86Operand::CreateReg(RegNo, Start, End) :
1856 ErrorOperand(Start, "expected memory operand after 'ptr', "
1857 "found register operand instead");
1858 // An alleged segment override. check if we have a valid segment register
1859 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo))
1860 return ErrorOperand(Start, "invalid segment register");
1861 // Eat ':' and update Start location
1862 Start = Lex().getLoc();
1865 // Immediates and Memory
1866 IntelExprStateMachine SM;
1867 if (ParseIntelExpression(SM, End))
1870 if (isParsingInlineAsm())
1871 RewriteIntelExpression(SM, Start, Tok.getLoc());
1873 int64_t Imm = SM.getImm();
1874 const MCExpr *Disp = SM.getSym();
1875 const MCExpr *ImmDisp = MCConstantExpr::create(Imm, getContext());
1877 Disp = MCBinaryExpr::createAdd(Disp, ImmDisp, getContext());
1881 // RegNo != 0 specifies a valid segment register,
1882 // and we are parsing a segment override
1883 if (!SM.isMemExpr() && !RegNo)
1884 return X86Operand::CreateImm(Disp, Start, End);
1887 unsigned BaseReg = SM.getBaseReg();
1888 unsigned IndexReg = SM.getIndexReg();
1889 unsigned Scale = SM.getScale();
1891 if (Scale == 0 && BaseReg != X86::ESP && BaseReg != X86::RSP &&
1892 (IndexReg == X86::ESP || IndexReg == X86::RSP))
1893 std::swap(BaseReg, IndexReg);
1895 // If BaseReg is a vector register and IndexReg is not, swap them unless
1896 // Scale was specified in which case it would be an error.
1898 !(X86MCRegisterClasses[X86::VR128XRegClassID].contains(IndexReg) ||
1899 X86MCRegisterClasses[X86::VR256XRegClassID].contains(IndexReg) ||
1900 X86MCRegisterClasses[X86::VR512RegClassID].contains(IndexReg)) &&
1901 (X86MCRegisterClasses[X86::VR128XRegClassID].contains(BaseReg) ||
1902 X86MCRegisterClasses[X86::VR256XRegClassID].contains(BaseReg) ||
1903 X86MCRegisterClasses[X86::VR512RegClassID].contains(BaseReg)))
1904 std::swap(BaseReg, IndexReg);
1907 X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg))
1908 return ErrorOperand(Start, "16-bit addresses cannot have a scale");
1910 // If there was no explicit scale specified, change it to 1.
1914 // If this is a 16-bit addressing mode with the base and index in the wrong
1915 // order, swap them so CheckBaseRegAndIndexRegAndScale doesn't fail. It is
1916 // shared with att syntax where order matters.
1917 if ((BaseReg == X86::SI || BaseReg == X86::DI) &&
1918 (IndexReg == X86::BX || IndexReg == X86::BP))
1919 std::swap(BaseReg, IndexReg);
1921 if ((BaseReg || IndexReg) &&
1922 CheckBaseRegAndIndexRegAndScale(BaseReg, IndexReg, Scale, is64BitMode(),
1924 return ErrorOperand(Start, ErrMsg);
1925 if (isParsingInlineAsm())
1926 return CreateMemForInlineAsm(RegNo, Disp, BaseReg, IndexReg,
1927 Scale, Start, End, Size, SM.getSymName(),
1928 SM.getIdentifierInfo());
1929 if (!(BaseReg || IndexReg || RegNo))
1930 return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size);
1931 return X86Operand::CreateMem(getPointerWidth(), RegNo, Disp,
1932 BaseReg, IndexReg, Scale, Start, End, Size);
1935 std::unique_ptr<X86Operand> X86AsmParser::ParseATTOperand(StringRef Mnemonic) {
1936 MCAsmParser &Parser = getParser();
1937 switch (getLexer().getKind()) {
1939 // Parse a memory operand with no segment register.
1940 return ParseMemOperand(0, Parser.getTok().getLoc(), Mnemonic);
1941 case AsmToken::Percent: {
1942 // Read the register.
1945 if (ParseRegister(RegNo, Start, End)) return nullptr;
1946 if (RegNo == X86::EIZ || RegNo == X86::RIZ) {
1947 Error(Start, "%eiz and %riz can only be used as index registers",
1948 SMRange(Start, End));
1951 if (RegNo == X86::RIP) {
1952 Error(Start, "%rip can only be used as a base register",
1953 SMRange(Start, End));
1957 // If this is a segment register followed by a ':', then this is the start
1958 // of a memory reference, otherwise this is a normal register reference.
1959 if (getLexer().isNot(AsmToken::Colon))
1960 return X86Operand::CreateReg(RegNo, Start, End);
1962 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo))
1963 return ErrorOperand(Start, "invalid segment register");
1965 getParser().Lex(); // Eat the colon.
1966 return ParseMemOperand(RegNo, Start, Mnemonic);
1968 case AsmToken::Dollar: {
1969 // $42 -> immediate.
1970 SMLoc Start = Parser.getTok().getLoc(), End;
1973 if (getParser().parseExpression(Val, End))
1975 return X86Operand::CreateImm(Val, Start, End);
1977 case AsmToken::LCurly:{
1978 SMLoc Start = Parser.getTok().getLoc();
1979 return ParseRoundingModeOp(Start);
1984 // true on failure, false otherwise
1985 // If no {z} mark was found - Parser doesn't advance
1986 bool X86AsmParser::ParseZ(std::unique_ptr<X86Operand> &Z,
1987 const SMLoc &StartLoc) {
1988 MCAsmParser &Parser = getParser();
1989 // Assuming we are just pass the '{' mark, quering the next token
1990 // Searched for {z}, but none was found. Return false, as no parsing error was
1992 if (!(getLexer().is(AsmToken::Identifier) &&
1993 (getLexer().getTok().getIdentifier() == "z")))
1995 Parser.Lex(); // Eat z
1996 // Query and eat the '}' mark
1997 if (!getLexer().is(AsmToken::RCurly))
1998 return Error(getLexer().getLoc(), "Expected } at this point");
1999 Parser.Lex(); // Eat '}'
2000 // Assign Z with the {z} mark opernad
2001 Z = X86Operand::CreateToken("{z}", StartLoc);
2005 // true on failure, false otherwise
2006 bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands,
2007 const MCParsedAsmOperand &Op) {
2008 MCAsmParser &Parser = getParser();
2009 if (getLexer().is(AsmToken::LCurly)) {
2010 // Eat "{" and mark the current place.
2011 const SMLoc consumedToken = consumeToken();
2012 // Distinguish {1to<NUM>} from {%k<NUM>}.
2013 if(getLexer().is(AsmToken::Integer)) {
2014 // Parse memory broadcasting ({1to<NUM>}).
2015 if (getLexer().getTok().getIntVal() != 1)
2016 return TokError("Expected 1to<NUM> at this point");
2017 Parser.Lex(); // Eat "1" of 1to8
2018 if (!getLexer().is(AsmToken::Identifier) ||
2019 !getLexer().getTok().getIdentifier().startswith("to"))
2020 return TokError("Expected 1to<NUM> at this point");
2021 // Recognize only reasonable suffixes.
2022 const char *BroadcastPrimitive =
2023 StringSwitch<const char*>(getLexer().getTok().getIdentifier())
2024 .Case("to2", "{1to2}")
2025 .Case("to4", "{1to4}")
2026 .Case("to8", "{1to8}")
2027 .Case("to16", "{1to16}")
2029 if (!BroadcastPrimitive)
2030 return TokError("Invalid memory broadcast primitive.");
2031 Parser.Lex(); // Eat "toN" of 1toN
2032 if (!getLexer().is(AsmToken::RCurly))
2033 return TokError("Expected } at this point");
2034 Parser.Lex(); // Eat "}"
2035 Operands.push_back(X86Operand::CreateToken(BroadcastPrimitive,
2037 // No AVX512 specific primitives can pass
2038 // after memory broadcasting, so return.
2041 // Parse either {k}{z}, {z}{k}, {k} or {z}
2042 // last one have no meaning, but GCC accepts it
2043 // Currently, we're just pass a '{' mark
2044 std::unique_ptr<X86Operand> Z;
2045 if (ParseZ(Z, consumedToken))
2047 // Reaching here means that parsing of the allegadly '{z}' mark yielded
2049 // Query for the need of further parsing for a {%k<NUM>} mark
2050 if (!Z || getLexer().is(AsmToken::LCurly)) {
2051 SMLoc StartLoc = Z ? consumeToken() : consumedToken;
2052 // Parse an op-mask register mark ({%k<NUM>}), which is now to be
2056 if (!ParseRegister(RegNo, RegLoc, StartLoc) &&
2057 X86MCRegisterClasses[X86::VK1RegClassID].contains(RegNo)) {
2058 if (RegNo == X86::K0)
2059 return Error(RegLoc, "Register k0 can't be used as write mask");
2060 if (!getLexer().is(AsmToken::RCurly))
2061 return Error(getLexer().getLoc(), "Expected } at this point");
2062 Operands.push_back(X86Operand::CreateToken("{", StartLoc));
2064 X86Operand::CreateReg(RegNo, StartLoc, StartLoc));
2065 Operands.push_back(X86Operand::CreateToken("}", consumeToken()));
2067 return Error(getLexer().getLoc(),
2068 "Expected an op-mask register at this point");
2069 // {%k<NUM>} mark is found, inquire for {z}
2070 if (getLexer().is(AsmToken::LCurly) && !Z) {
2071 // Have we've found a parsing error, or found no (expected) {z} mark
2072 // - report an error
2073 if (ParseZ(Z, consumeToken()) || !Z)
2074 return Error(getLexer().getLoc(),
2075 "Expected a {z} mark at this point");
2078 // '{z}' on its own is meaningless, hence should be ignored.
2079 // on the contrary - have it been accompanied by a K register,
2082 Operands.push_back(std::move(Z));
2089 /// ParseMemOperand: segment: disp(basereg, indexreg, scale). The '%ds:' prefix
2090 /// has already been parsed if present.
2091 std::unique_ptr<X86Operand> X86AsmParser::ParseMemOperand(unsigned SegReg,
2093 StringRef Mnemonic) {
2095 MCAsmParser &Parser = getParser();
2096 // We have to disambiguate a parenthesized expression "(4+5)" from the start
2097 // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)". The
2098 // only way to do this without lookahead is to eat the '(' and see what is
2100 const MCExpr *Disp = MCConstantExpr::create(0, getParser().getContext());
2101 if (getLexer().isNot(AsmToken::LParen)) {
2103 if (getParser().parseExpression(Disp, ExprEnd)) return nullptr;
2104 // Disp may be a variable, handle register values.
2105 if (auto *RE = dyn_cast<X86MCExpr>(Disp))
2106 return X86Operand::CreateReg(RE->getRegNo(), MemStart, ExprEnd);
2108 // After parsing the base expression we could either have a parenthesized
2109 // memory address or not. If not, return now. If so, eat the (.
2110 if (getLexer().isNot(AsmToken::LParen)) {
2111 // Unless we have a segment register, treat this as an immediate.
2113 return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, ExprEnd);
2114 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
2121 // Okay, we have a '('. We don't know if this is an expression or not, but
2122 // so we have to eat the ( to see beyond it.
2123 SMLoc LParenLoc = Parser.getTok().getLoc();
2124 Parser.Lex(); // Eat the '('.
2126 if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) {
2127 // Nothing to do here, fall into the code below with the '(' part of the
2128 // memory operand consumed.
2131 getLexer().UnLex(AsmToken(AsmToken::LParen, "("));
2133 // It must be either an parenthesized expression, or an expression that
2134 // begins from a parenthesized expression, parse it now. Example: (1+2) or
2136 if (getParser().parseExpression(Disp, ExprEnd))
2139 // After parsing the base expression we could either have a parenthesized
2140 // memory address or not. If not, return now. If so, eat the (.
2141 if (getLexer().isNot(AsmToken::LParen)) {
2142 // Unless we have a segment register, treat this as an immediate.
2144 return X86Operand::CreateMem(getPointerWidth(), Disp, LParenLoc,
2146 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
2155 // If we reached here, then we just ate the ( of the memory operand. Process
2156 // the rest of the memory operand.
2157 unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
2158 SMLoc IndexLoc, BaseLoc;
2160 if (getLexer().is(AsmToken::Percent)) {
2161 SMLoc StartLoc, EndLoc;
2162 BaseLoc = Parser.getTok().getLoc();
2163 if (ParseRegister(BaseReg, StartLoc, EndLoc)) return nullptr;
2164 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) {
2165 Error(StartLoc, "eiz and riz can only be used as index registers",
2166 SMRange(StartLoc, EndLoc));
2171 if (getLexer().is(AsmToken::Comma)) {
2172 Parser.Lex(); // Eat the comma.
2173 IndexLoc = Parser.getTok().getLoc();
2175 // Following the comma we should have either an index register, or a scale
2176 // value. We don't support the later form, but we want to parse it
2179 // Not that even though it would be completely consistent to support syntax
2180 // like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this.
2181 if (getLexer().is(AsmToken::Percent)) {
2183 if (ParseRegister(IndexReg, L, L))
2185 if (BaseReg == X86::RIP) {
2186 Error(IndexLoc, "%rip as base register can not have an index register");
2189 if (IndexReg == X86::RIP) {
2190 Error(IndexLoc, "%rip is not allowed as an index register");
2194 if (getLexer().isNot(AsmToken::RParen)) {
2195 // Parse the scale amount:
2196 // ::= ',' [scale-expression]
2197 if (parseToken(AsmToken::Comma, "expected comma in scale expression"))
2200 if (getLexer().isNot(AsmToken::RParen)) {
2201 SMLoc Loc = Parser.getTok().getLoc();
2204 if (getParser().parseAbsoluteExpression(ScaleVal)){
2205 Error(Loc, "expected scale expression");
2209 // Validate the scale amount.
2210 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
2212 Error(Loc, "scale factor in 16-bit address must be 1");
2215 if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 &&
2217 Error(Loc, "scale factor in address must be 1, 2, 4 or 8");
2220 Scale = (unsigned)ScaleVal;
2223 } else if (getLexer().isNot(AsmToken::RParen)) {
2224 // A scale amount without an index is ignored.
2226 SMLoc Loc = Parser.getTok().getLoc();
2229 if (getParser().parseAbsoluteExpression(Value))
2233 Warning(Loc, "scale factor without index register is ignored");
2238 // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
2239 SMLoc MemEnd = Parser.getTok().getEndLoc();
2240 if (parseToken(AsmToken::RParen, "unexpected token in memory operand"))
2243 // This is a terrible hack to handle "out[s]?[bwl]? %al, (%dx)" ->
2244 // "outb %al, %dx". Out doesn't take a memory form, but this is a widely
2245 // documented form in various unofficial manuals, so a lot of code uses it.
2246 if (BaseReg == X86::DX && IndexReg == 0 && Scale == 1 &&
2247 SegReg == 0 && isa<MCConstantExpr>(Disp) &&
2248 cast<MCConstantExpr>(Disp)->getValue() == 0 &&
2249 (Mnemonic == "outb" || Mnemonic == "outsb" ||
2250 Mnemonic == "outw" || Mnemonic == "outsw" ||
2251 Mnemonic == "outl" || Mnemonic == "outsl" ||
2252 Mnemonic == "out" || Mnemonic == "outs" ||
2253 Mnemonic == "inb" || Mnemonic == "insb" ||
2254 Mnemonic == "inw" || Mnemonic == "insw" ||
2255 Mnemonic == "inl" || Mnemonic == "insl" ||
2256 Mnemonic == "in" || Mnemonic == "ins"))
2257 return X86Operand::CreateReg(BaseReg, BaseLoc, BaseLoc);
2260 if (CheckBaseRegAndIndexRegAndScale(BaseReg, IndexReg, Scale, is64BitMode(),
2262 Error(BaseLoc, ErrMsg);
2266 if (SegReg || BaseReg || IndexReg)
2267 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
2268 IndexReg, Scale, MemStart, MemEnd);
2269 return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, MemEnd);
2272 // Parse either a standard expression or a register.
2273 bool X86AsmParser::parseAssignmentExpression(const MCExpr *&Res,
2275 MCAsmParser &Parser = getParser();
2276 if (Parser.parseExpression(Res, EndLoc)) {
2277 SMLoc StartLoc = Parser.getTok().getLoc();
2278 // Normal Expression parse fails, check if it could be a register.
2280 if (Parser.getTargetParser().ParseRegister(RegNo, StartLoc, EndLoc))
2282 // Clear previous parse error and return correct expression.
2283 Parser.clearPendingErrors();
2284 Res = X86MCExpr::create(RegNo, Parser.getContext());
2291 bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2292 SMLoc NameLoc, OperandVector &Operands) {
2293 MCAsmParser &Parser = getParser();
2295 StringRef PatchedName = Name;
2297 if ((Name.equals("jmp") || Name.equals("jc") || Name.equals("jz")) &&
2298 isParsingIntelSyntax() && isParsingInlineAsm()) {
2299 StringRef NextTok = Parser.getTok().getString();
2300 if (NextTok == "short") {
2302 NameLoc.getFromPointer(NameLoc.getPointer() + Name.size());
2303 // Eat the short keyword
2305 // MS ignores the short keyword, it determines the jmp type based
2306 // on the distance of the label
2307 InstInfo->AsmRewrites->emplace_back(AOK_Skip, NameEndLoc,
2308 NextTok.size() + 1);
2312 // FIXME: Hack to recognize setneb as setne.
2313 if (PatchedName.startswith("set") && PatchedName.endswith("b") &&
2314 PatchedName != "setb" && PatchedName != "setnb")
2315 PatchedName = PatchedName.substr(0, Name.size()-1);
2317 // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}.
2318 if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) &&
2319 (PatchedName.endswith("ss") || PatchedName.endswith("sd") ||
2320 PatchedName.endswith("ps") || PatchedName.endswith("pd"))) {
2321 bool IsVCMP = PatchedName[0] == 'v';
2322 unsigned CCIdx = IsVCMP ? 4 : 3;
2323 unsigned ComparisonCode = StringSwitch<unsigned>(
2324 PatchedName.slice(CCIdx, PatchedName.size() - 2))
2326 .Case("eq_oq", 0x00)
2328 .Case("lt_os", 0x01)
2330 .Case("le_os", 0x02)
2331 .Case("unord", 0x03)
2332 .Case("unord_q", 0x03)
2334 .Case("neq_uq", 0x04)
2336 .Case("nlt_us", 0x05)
2338 .Case("nle_us", 0x06)
2340 .Case("ord_q", 0x07)
2341 /* AVX only from here */
2342 .Case("eq_uq", 0x08)
2344 .Case("nge_us", 0x09)
2346 .Case("ngt_us", 0x0A)
2347 .Case("false", 0x0B)
2348 .Case("false_oq", 0x0B)
2349 .Case("neq_oq", 0x0C)
2351 .Case("ge_os", 0x0D)
2353 .Case("gt_os", 0x0E)
2355 .Case("true_uq", 0x0F)
2356 .Case("eq_os", 0x10)
2357 .Case("lt_oq", 0x11)
2358 .Case("le_oq", 0x12)
2359 .Case("unord_s", 0x13)
2360 .Case("neq_us", 0x14)
2361 .Case("nlt_uq", 0x15)
2362 .Case("nle_uq", 0x16)
2363 .Case("ord_s", 0x17)
2364 .Case("eq_us", 0x18)
2365 .Case("nge_uq", 0x19)
2366 .Case("ngt_uq", 0x1A)
2367 .Case("false_os", 0x1B)
2368 .Case("neq_os", 0x1C)
2369 .Case("ge_oq", 0x1D)
2370 .Case("gt_oq", 0x1E)
2371 .Case("true_us", 0x1F)
2373 if (ComparisonCode != ~0U && (IsVCMP || ComparisonCode < 8)) {
2375 Operands.push_back(X86Operand::CreateToken(PatchedName.slice(0, CCIdx),
2378 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2379 getParser().getContext());
2380 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2382 PatchedName = PatchedName.substr(PatchedName.size() - 2);
2386 // FIXME: Hack to recognize vpcmp<comparison code>{ub,uw,ud,uq,b,w,d,q}.
2387 if (PatchedName.startswith("vpcmp") &&
2388 (PatchedName.endswith("b") || PatchedName.endswith("w") ||
2389 PatchedName.endswith("d") || PatchedName.endswith("q"))) {
2390 unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1;
2391 unsigned ComparisonCode = StringSwitch<unsigned>(
2392 PatchedName.slice(5, PatchedName.size() - CCIdx))
2393 .Case("eq", 0x0) // Only allowed on unsigned. Checked below.
2396 //.Case("false", 0x3) // Not a documented alias.
2400 //.Case("true", 0x7) // Not a documented alias.
2402 if (ComparisonCode != ~0U && (ComparisonCode != 0 || CCIdx == 2)) {
2403 Operands.push_back(X86Operand::CreateToken("vpcmp", NameLoc));
2405 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2406 getParser().getContext());
2407 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2409 PatchedName = PatchedName.substr(PatchedName.size() - CCIdx);
2413 // FIXME: Hack to recognize vpcom<comparison code>{ub,uw,ud,uq,b,w,d,q}.
2414 if (PatchedName.startswith("vpcom") &&
2415 (PatchedName.endswith("b") || PatchedName.endswith("w") ||
2416 PatchedName.endswith("d") || PatchedName.endswith("q"))) {
2417 unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1;
2418 unsigned ComparisonCode = StringSwitch<unsigned>(
2419 PatchedName.slice(5, PatchedName.size() - CCIdx))
2429 if (ComparisonCode != ~0U) {
2430 Operands.push_back(X86Operand::CreateToken("vpcom", NameLoc));
2432 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2433 getParser().getContext());
2434 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2436 PatchedName = PatchedName.substr(PatchedName.size() - CCIdx);
2441 // Determine whether this is an instruction prefix.
2443 // Enhance prefixes integrity robustness. for example, following forms
2444 // are currently tolerated:
2445 // repz repnz <insn> ; GAS errors for the use of two similar prefixes
2446 // lock addq %rax, %rbx ; Destination operand must be of memory type
2447 // xacquire <insn> ; xacquire must be accompanied by 'lock'
2448 bool isPrefix = StringSwitch<bool>(Name)
2449 .Cases("rex64", "data32", "data16", true)
2450 .Cases("xacquire", "xrelease", true)
2451 .Cases("acquire", "release", isParsingIntelSyntax())
2454 auto isLockRepeatNtPrefix = [](StringRef N) {
2455 return StringSwitch<bool>(N)
2456 .Cases("lock", "rep", "repe", "repz", "repne", "repnz", "notrack", true)
2460 bool CurlyAsEndOfStatement = false;
2462 unsigned Flags = X86::IP_NO_PREFIX;
2463 while (isLockRepeatNtPrefix(Name.lower())) {
2465 StringSwitch<unsigned>(Name)
2466 .Cases("lock", "lock", X86::IP_HAS_LOCK)
2467 .Cases("rep", "repe", "repz", X86::IP_HAS_REPEAT)
2468 .Cases("repne", "repnz", X86::IP_HAS_REPEAT_NE)
2469 .Cases("notrack", "notrack", X86::IP_HAS_NOTRACK)
2470 .Default(X86::IP_NO_PREFIX); // Invalid prefix (impossible)
2472 if (getLexer().is(AsmToken::EndOfStatement)) {
2473 // We don't have real instr with the given prefix
2474 // let's use the prefix as the instr.
2475 // TODO: there could be several prefixes one after another
2476 Flags = X86::IP_NO_PREFIX;
2479 Name = Parser.getTok().getString();
2480 Parser.Lex(); // eat the prefix
2481 // Hack: we could have something like "rep # some comment" or
2482 // "lock; cmpxchg16b $1" or "lock\0A\09incl" or "lock/incl"
2483 while (Name.startswith(";") || Name.startswith("\n") ||
2484 Name.startswith("#") || Name.startswith("\t") ||
2485 Name.startswith("/")) {
2486 Name = Parser.getTok().getString();
2487 Parser.Lex(); // go to next prefix or instr
2494 // Hacks to handle 'data16' and 'data32'
2495 if (PatchedName == "data16" && is16BitMode()) {
2496 return Error(NameLoc, "redundant data16 prefix");
2498 if (PatchedName == "data32") {
2500 return Error(NameLoc, "redundant data32 prefix");
2502 return Error(NameLoc, "'data32' is not supported in 64-bit mode");
2503 // Hack to 'data16' for the table lookup.
2504 PatchedName = "data16";
2507 Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
2509 // This does the actual operand parsing. Don't parse any more if we have a
2510 // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we
2511 // just want to parse the "lock" as the first instruction and the "incl" as
2513 if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) {
2514 // Parse '*' modifier.
2515 if (getLexer().is(AsmToken::Star))
2516 Operands.push_back(X86Operand::CreateToken("*", consumeToken()));
2518 // Read the operands.
2520 if (std::unique_ptr<X86Operand> Op = ParseOperand(Name)) {
2521 Operands.push_back(std::move(Op));
2522 if (HandleAVX512Operand(Operands, *Operands.back()))
2527 // check for comma and eat it
2528 if (getLexer().is(AsmToken::Comma))
2534 // In MS inline asm curly braces mark the beginning/end of a block,
2535 // therefore they should be interepreted as end of statement
2536 CurlyAsEndOfStatement =
2537 isParsingIntelSyntax() && isParsingInlineAsm() &&
2538 (getLexer().is(AsmToken::LCurly) || getLexer().is(AsmToken::RCurly));
2539 if (getLexer().isNot(AsmToken::EndOfStatement) && !CurlyAsEndOfStatement)
2540 return TokError("unexpected token in argument list");
2543 // Consume the EndOfStatement or the prefix separator Slash
2544 if (getLexer().is(AsmToken::EndOfStatement) ||
2545 (isPrefix && getLexer().is(AsmToken::Slash)))
2547 else if (CurlyAsEndOfStatement)
2548 // Add an actual EndOfStatement before the curly brace
2549 Info.AsmRewrites->emplace_back(AOK_EndOfStatement,
2550 getLexer().getTok().getLoc(), 0);
2552 // This is for gas compatibility and cannot be done in td.
2553 // Adding "p" for some floating point with no argument.
2554 // For example: fsub --> fsubp
2556 Name == "fsub" || Name == "fdiv" || Name == "fsubr" || Name == "fdivr";
2557 if (IsFp && Operands.size() == 1) {
2558 const char *Repl = StringSwitch<const char *>(Name)
2559 .Case("fsub", "fsubp")
2560 .Case("fdiv", "fdivp")
2561 .Case("fsubr", "fsubrp")
2562 .Case("fdivr", "fdivrp");
2563 static_cast<X86Operand &>(*Operands[0]).setTokenValue(Repl);
2566 // Moving a 32 or 16 bit value into a segment register has the same
2567 // behavior. Modify such instructions to always take shorter form.
2568 if ((Name == "mov" || Name == "movw" || Name == "movl") &&
2569 (Operands.size() == 3)) {
2570 X86Operand &Op1 = (X86Operand &)*Operands[1];
2571 X86Operand &Op2 = (X86Operand &)*Operands[2];
2572 SMLoc Loc = Op1.getEndLoc();
2573 if (Op1.isReg() && Op2.isReg() &&
2574 X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(
2576 (X86MCRegisterClasses[X86::GR16RegClassID].contains(Op1.getReg()) ||
2577 X86MCRegisterClasses[X86::GR32RegClassID].contains(Op1.getReg()))) {
2578 // Change instruction name to match new instruction.
2579 if (Name != "mov" && Name[3] == (is16BitMode() ? 'l' : 'w')) {
2580 Name = is16BitMode() ? "movw" : "movl";
2581 Operands[0] = X86Operand::CreateToken(Name, NameLoc);
2583 // Select the correct equivalent 16-/32-bit source register.
2585 getX86SubSuperRegisterOrZero(Op1.getReg(), is16BitMode() ? 16 : 32);
2586 Operands[1] = X86Operand::CreateReg(Reg, Loc, Loc);
2590 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 2> TmpOperands;
2591 bool HadVerifyError = false;
2593 // Append default arguments to "ins[bwld]"
2594 if (Name.startswith("ins") &&
2595 (Operands.size() == 1 || Operands.size() == 3) &&
2596 (Name == "insb" || Name == "insw" || Name == "insl" || Name == "insd" ||
2599 AddDefaultSrcDestOperands(TmpOperands,
2600 X86Operand::CreateReg(X86::DX, NameLoc, NameLoc),
2601 DefaultMemDIOperand(NameLoc));
2602 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2605 // Append default arguments to "outs[bwld]"
2606 if (Name.startswith("outs") &&
2607 (Operands.size() == 1 || Operands.size() == 3) &&
2608 (Name == "outsb" || Name == "outsw" || Name == "outsl" ||
2609 Name == "outsd" || Name == "outs")) {
2610 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
2611 X86Operand::CreateReg(X86::DX, NameLoc, NameLoc));
2612 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2615 // Transform "lods[bwlq]" into "lods[bwlq] ($SIREG)" for appropriate
2616 // values of $SIREG according to the mode. It would be nice if this
2617 // could be achieved with InstAlias in the tables.
2618 if (Name.startswith("lods") &&
2619 (Operands.size() == 1 || Operands.size() == 2) &&
2620 (Name == "lods" || Name == "lodsb" || Name == "lodsw" ||
2621 Name == "lodsl" || Name == "lodsd" || Name == "lodsq")) {
2622 TmpOperands.push_back(DefaultMemSIOperand(NameLoc));
2623 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2626 // Transform "stos[bwlq]" into "stos[bwlq] ($DIREG)" for appropriate
2627 // values of $DIREG according to the mode. It would be nice if this
2628 // could be achieved with InstAlias in the tables.
2629 if (Name.startswith("stos") &&
2630 (Operands.size() == 1 || Operands.size() == 2) &&
2631 (Name == "stos" || Name == "stosb" || Name == "stosw" ||
2632 Name == "stosl" || Name == "stosd" || Name == "stosq")) {
2633 TmpOperands.push_back(DefaultMemDIOperand(NameLoc));
2634 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2637 // Transform "scas[bwlq]" into "scas[bwlq] ($DIREG)" for appropriate
2638 // values of $DIREG according to the mode. It would be nice if this
2639 // could be achieved with InstAlias in the tables.
2640 if (Name.startswith("scas") &&
2641 (Operands.size() == 1 || Operands.size() == 2) &&
2642 (Name == "scas" || Name == "scasb" || Name == "scasw" ||
2643 Name == "scasl" || Name == "scasd" || Name == "scasq")) {
2644 TmpOperands.push_back(DefaultMemDIOperand(NameLoc));
2645 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2648 // Add default SI and DI operands to "cmps[bwlq]".
2649 if (Name.startswith("cmps") &&
2650 (Operands.size() == 1 || Operands.size() == 3) &&
2651 (Name == "cmps" || Name == "cmpsb" || Name == "cmpsw" ||
2652 Name == "cmpsl" || Name == "cmpsd" || Name == "cmpsq")) {
2653 AddDefaultSrcDestOperands(TmpOperands, DefaultMemDIOperand(NameLoc),
2654 DefaultMemSIOperand(NameLoc));
2655 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2658 // Add default SI and DI operands to "movs[bwlq]".
2659 if (((Name.startswith("movs") &&
2660 (Name == "movs" || Name == "movsb" || Name == "movsw" ||
2661 Name == "movsl" || Name == "movsd" || Name == "movsq")) ||
2662 (Name.startswith("smov") &&
2663 (Name == "smov" || Name == "smovb" || Name == "smovw" ||
2664 Name == "smovl" || Name == "smovd" || Name == "smovq"))) &&
2665 (Operands.size() == 1 || Operands.size() == 3)) {
2666 if (Name == "movsd" && Operands.size() == 1 && !isParsingIntelSyntax())
2667 Operands.back() = X86Operand::CreateToken("movsl", NameLoc);
2668 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
2669 DefaultMemDIOperand(NameLoc));
2670 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2673 // Check if we encountered an error for one the string insturctions
2674 if (HadVerifyError) {
2675 return HadVerifyError;
2678 // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>. Canonicalize to
2680 if ((Name.startswith("shr") || Name.startswith("sar") ||
2681 Name.startswith("shl") || Name.startswith("sal") ||
2682 Name.startswith("rcl") || Name.startswith("rcr") ||
2683 Name.startswith("rol") || Name.startswith("ror")) &&
2684 Operands.size() == 3) {
2685 if (isParsingIntelSyntax()) {
2687 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[2]);
2688 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2689 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2690 Operands.pop_back();
2692 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2693 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2694 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2695 Operands.erase(Operands.begin() + 1);
2699 // Transforms "int $3" into "int3" as a size optimization. We can't write an
2700 // instalias with an immediate operand yet.
2701 if (Name == "int" && Operands.size() == 2) {
2702 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2704 if (auto *CE = dyn_cast<MCConstantExpr>(Op1.getImm()))
2705 if (CE->getValue() == 3) {
2706 Operands.erase(Operands.begin() + 1);
2707 static_cast<X86Operand &>(*Operands[0]).setTokenValue("int3");
2711 // Transforms "xlat mem8" into "xlatb"
2712 if ((Name == "xlat" || Name == "xlatb") && Operands.size() == 2) {
2713 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2715 Warning(Op1.getStartLoc(), "memory operand is only for determining the "
2716 "size, (R|E)BX will be used for the location");
2717 Operands.pop_back();
2718 static_cast<X86Operand &>(*Operands[0]).setTokenValue("xlatb");
2723 Operands.push_back(X86Operand::CreatePrefix(Flags, NameLoc, NameLoc));
2727 bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) {
2731 bool X86AsmParser::validateInstruction(MCInst &Inst, const OperandVector &Ops) {
2732 const MCRegisterInfo *MRI = getContext().getRegisterInfo();
2734 switch (Inst.getOpcode()) {
2735 case X86::VGATHERDPDYrm:
2736 case X86::VGATHERDPDrm:
2737 case X86::VGATHERDPSYrm:
2738 case X86::VGATHERDPSrm:
2739 case X86::VGATHERQPDYrm:
2740 case X86::VGATHERQPDrm:
2741 case X86::VGATHERQPSYrm:
2742 case X86::VGATHERQPSrm:
2743 case X86::VPGATHERDDYrm:
2744 case X86::VPGATHERDDrm:
2745 case X86::VPGATHERDQYrm:
2746 case X86::VPGATHERDQrm:
2747 case X86::VPGATHERQDYrm:
2748 case X86::VPGATHERQDrm:
2749 case X86::VPGATHERQQYrm:
2750 case X86::VPGATHERQQrm: {
2751 unsigned Dest = MRI->getEncodingValue(Inst.getOperand(0).getReg());
2752 unsigned Mask = MRI->getEncodingValue(Inst.getOperand(1).getReg());
2754 MRI->getEncodingValue(Inst.getOperand(3 + X86::AddrIndexReg).getReg());
2755 if (Dest == Mask || Dest == Index || Mask == Index)
2756 return Warning(Ops[0]->getStartLoc(), "mask, index, and destination "
2757 "registers should be distinct");
2760 case X86::VGATHERDPDZ128rm:
2761 case X86::VGATHERDPDZ256rm:
2762 case X86::VGATHERDPDZrm:
2763 case X86::VGATHERDPSZ128rm:
2764 case X86::VGATHERDPSZ256rm:
2765 case X86::VGATHERDPSZrm:
2766 case X86::VGATHERQPDZ128rm:
2767 case X86::VGATHERQPDZ256rm:
2768 case X86::VGATHERQPDZrm:
2769 case X86::VGATHERQPSZ128rm:
2770 case X86::VGATHERQPSZ256rm:
2771 case X86::VGATHERQPSZrm:
2772 case X86::VPGATHERDDZ128rm:
2773 case X86::VPGATHERDDZ256rm:
2774 case X86::VPGATHERDDZrm:
2775 case X86::VPGATHERDQZ128rm:
2776 case X86::VPGATHERDQZ256rm:
2777 case X86::VPGATHERDQZrm:
2778 case X86::VPGATHERQDZ128rm:
2779 case X86::VPGATHERQDZ256rm:
2780 case X86::VPGATHERQDZrm:
2781 case X86::VPGATHERQQZ128rm:
2782 case X86::VPGATHERQQZ256rm:
2783 case X86::VPGATHERQQZrm: {
2784 unsigned Dest = MRI->getEncodingValue(Inst.getOperand(0).getReg());
2786 MRI->getEncodingValue(Inst.getOperand(4 + X86::AddrIndexReg).getReg());
2788 return Warning(Ops[0]->getStartLoc(), "index and destination registers "
2789 "should be distinct");
2792 case X86::V4FMADDPSrm:
2793 case X86::V4FMADDPSrmk:
2794 case X86::V4FMADDPSrmkz:
2795 case X86::V4FMADDSSrm:
2796 case X86::V4FMADDSSrmk:
2797 case X86::V4FMADDSSrmkz:
2798 case X86::V4FNMADDPSrm:
2799 case X86::V4FNMADDPSrmk:
2800 case X86::V4FNMADDPSrmkz:
2801 case X86::V4FNMADDSSrm:
2802 case X86::V4FNMADDSSrmk:
2803 case X86::V4FNMADDSSrmkz:
2804 case X86::VP4DPWSSDSrm:
2805 case X86::VP4DPWSSDSrmk:
2806 case X86::VP4DPWSSDSrmkz:
2807 case X86::VP4DPWSSDrm:
2808 case X86::VP4DPWSSDrmk:
2809 case X86::VP4DPWSSDrmkz: {
2810 unsigned Src2 = Inst.getOperand(Inst.getNumOperands() -
2811 X86::AddrNumOperands - 1).getReg();
2812 unsigned Src2Enc = MRI->getEncodingValue(Src2);
2813 if (Src2Enc % 4 != 0) {
2814 StringRef RegName = X86IntelInstPrinter::getRegisterName(Src2);
2815 unsigned GroupStart = (Src2Enc / 4) * 4;
2816 unsigned GroupEnd = GroupStart + 3;
2817 return Warning(Ops[0]->getStartLoc(),
2818 "source register '" + RegName + "' implicitly denotes '" +
2819 RegName.take_front(3) + Twine(GroupStart) + "' to '" +
2820 RegName.take_front(3) + Twine(GroupEnd) +
2830 static const char *getSubtargetFeatureName(uint64_t Val);
2832 void X86AsmParser::EmitInstruction(MCInst &Inst, OperandVector &Operands,
2834 Instrumentation->InstrumentAndEmitInstruction(
2835 Inst, Operands, getContext(), MII, Out,
2836 getParser().shouldPrintSchedInfo());
2839 bool X86AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2840 OperandVector &Operands,
2841 MCStreamer &Out, uint64_t &ErrorInfo,
2842 bool MatchingInlineAsm) {
2843 if (isParsingIntelSyntax())
2844 return MatchAndEmitIntelInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2846 return MatchAndEmitATTInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2850 void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op,
2851 OperandVector &Operands, MCStreamer &Out,
2852 bool MatchingInlineAsm) {
2853 // FIXME: This should be replaced with a real .td file alias mechanism.
2854 // Also, MatchInstructionImpl should actually *do* the EmitInstruction
2856 const char *Repl = StringSwitch<const char *>(Op.getToken())
2857 .Case("finit", "fninit")
2858 .Case("fsave", "fnsave")
2859 .Case("fstcw", "fnstcw")
2860 .Case("fstcww", "fnstcw")
2861 .Case("fstenv", "fnstenv")
2862 .Case("fstsw", "fnstsw")
2863 .Case("fstsww", "fnstsw")
2864 .Case("fclex", "fnclex")
2868 Inst.setOpcode(X86::WAIT);
2870 if (!MatchingInlineAsm)
2871 EmitInstruction(Inst, Operands, Out);
2872 Operands[0] = X86Operand::CreateToken(Repl, IDLoc);
2876 bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
2877 bool MatchingInlineAsm) {
2878 assert(ErrorInfo && "Unknown missing feature!");
2879 SmallString<126> Msg;
2880 raw_svector_ostream OS(Msg);
2881 OS << "instruction requires:";
2883 for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
2884 if (ErrorInfo & Mask)
2885 OS << ' ' << getSubtargetFeatureName(ErrorInfo & Mask);
2888 return Error(IDLoc, OS.str(), SMRange(), MatchingInlineAsm);
2891 static unsigned getPrefixes(OperandVector &Operands) {
2892 unsigned Result = 0;
2893 X86Operand &Prefix = static_cast<X86Operand &>(*Operands.back());
2894 if (Prefix.isPrefix()) {
2895 Result = Prefix.getPrefix();
2896 Operands.pop_back();
2901 bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
2902 OperandVector &Operands,
2904 uint64_t &ErrorInfo,
2905 bool MatchingInlineAsm) {
2906 assert(!Operands.empty() && "Unexpect empty operand list!");
2907 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2908 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
2909 SMRange EmptyRange = None;
2911 // First, handle aliases that expand to multiple instructions.
2912 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2914 bool WasOriginallyInvalidOperand = false;
2915 unsigned Prefixes = getPrefixes(Operands);
2920 Inst.setFlags(Prefixes);
2922 // First, try a direct match.
2923 switch (MatchInstruction(Operands, Inst, ErrorInfo, MatchingInlineAsm,
2924 isParsingIntelSyntax())) {
2925 default: llvm_unreachable("Unexpected match result!");
2927 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
2929 // Some instructions need post-processing to, for example, tweak which
2930 // encoding is selected. Loop on it while changes happen so the
2931 // individual transformations can chain off each other.
2932 if (!MatchingInlineAsm)
2933 while (processInstruction(Inst, Operands))
2937 if (!MatchingInlineAsm)
2938 EmitInstruction(Inst, Operands, Out);
2939 Opcode = Inst.getOpcode();
2941 case Match_MissingFeature:
2942 return ErrorMissingFeature(IDLoc, ErrorInfo, MatchingInlineAsm);
2943 case Match_InvalidOperand:
2944 WasOriginallyInvalidOperand = true;
2946 case Match_MnemonicFail:
2950 // FIXME: Ideally, we would only attempt suffix matches for things which are
2951 // valid prefixes, and we could just infer the right unambiguous
2952 // type. However, that requires substantially more matcher support than the
2955 // Change the operand to point to a temporary token.
2956 StringRef Base = Op.getToken();
2957 SmallString<16> Tmp;
2960 Op.setTokenValue(Tmp);
2962 // If this instruction starts with an 'f', then it is a floating point stack
2963 // instruction. These come in up to three forms for 32-bit, 64-bit, and
2964 // 80-bit floating point, which use the suffixes s,l,t respectively.
2966 // Otherwise, we assume that this may be an integer instruction, which comes
2967 // in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively.
2968 const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0";
2970 // Check for the various suffix matches.
2971 uint64_t ErrorInfoIgnore;
2972 uint64_t ErrorInfoMissingFeature = 0; // Init suppresses compiler warnings.
2975 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I) {
2976 Tmp.back() = Suffixes[I];
2977 Match[I] = MatchInstruction(Operands, Inst, ErrorInfoIgnore,
2978 MatchingInlineAsm, isParsingIntelSyntax());
2979 // If this returned as a missing feature failure, remember that.
2980 if (Match[I] == Match_MissingFeature)
2981 ErrorInfoMissingFeature = ErrorInfoIgnore;
2984 // Restore the old token.
2985 Op.setTokenValue(Base);
2987 // If exactly one matched, then we treat that as a successful match (and the
2988 // instruction will already have been filled in correctly, since the failing
2989 // matches won't have modified it).
2990 unsigned NumSuccessfulMatches =
2991 std::count(std::begin(Match), std::end(Match), Match_Success);
2992 if (NumSuccessfulMatches == 1) {
2994 if (!MatchingInlineAsm)
2995 EmitInstruction(Inst, Operands, Out);
2996 Opcode = Inst.getOpcode();
3000 // Otherwise, the match failed, try to produce a decent error message.
3002 // If we had multiple suffix matches, then identify this as an ambiguous
3004 if (NumSuccessfulMatches > 1) {
3006 unsigned NumMatches = 0;
3007 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I)
3008 if (Match[I] == Match_Success)
3009 MatchChars[NumMatches++] = Suffixes[I];
3011 SmallString<126> Msg;
3012 raw_svector_ostream OS(Msg);
3013 OS << "ambiguous instructions require an explicit suffix (could be ";
3014 for (unsigned i = 0; i != NumMatches; ++i) {
3017 if (i + 1 == NumMatches)
3019 OS << "'" << Base << MatchChars[i] << "'";
3022 Error(IDLoc, OS.str(), EmptyRange, MatchingInlineAsm);
3026 // Okay, we know that none of the variants matched successfully.
3028 // If all of the instructions reported an invalid mnemonic, then the original
3029 // mnemonic was invalid.
3030 if (std::count(std::begin(Match), std::end(Match), Match_MnemonicFail) == 4) {
3031 if (!WasOriginallyInvalidOperand) {
3032 return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'",
3033 Op.getLocRange(), MatchingInlineAsm);
3036 // Recover location info for the operand if we know which was the problem.
3037 if (ErrorInfo != ~0ULL) {
3038 if (ErrorInfo >= Operands.size())
3039 return Error(IDLoc, "too few operands for instruction", EmptyRange,
3042 X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo];
3043 if (Operand.getStartLoc().isValid()) {
3044 SMRange OperandRange = Operand.getLocRange();
3045 return Error(Operand.getStartLoc(), "invalid operand for instruction",
3046 OperandRange, MatchingInlineAsm);
3050 return Error(IDLoc, "invalid operand for instruction", EmptyRange,
3054 // If one instruction matched with a missing feature, report this as a
3056 if (std::count(std::begin(Match), std::end(Match),
3057 Match_MissingFeature) == 1) {
3058 ErrorInfo = ErrorInfoMissingFeature;
3059 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
3063 // If one instruction matched with an invalid operand, report this as an
3065 if (std::count(std::begin(Match), std::end(Match),
3066 Match_InvalidOperand) == 1) {
3067 return Error(IDLoc, "invalid operand for instruction", EmptyRange,
3071 // If all of these were an outright failure, report it in a useless way.
3072 Error(IDLoc, "unknown use of instruction mnemonic without a size suffix",
3073 EmptyRange, MatchingInlineAsm);
3077 bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
3078 OperandVector &Operands,
3080 uint64_t &ErrorInfo,
3081 bool MatchingInlineAsm) {
3082 assert(!Operands.empty() && "Unexpect empty operand list!");
3083 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
3084 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
3085 StringRef Mnemonic = Op.getToken();
3086 SMRange EmptyRange = None;
3087 StringRef Base = Op.getToken();
3088 unsigned Prefixes = getPrefixes(Operands);
3090 // First, handle aliases that expand to multiple instructions.
3091 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
3096 Inst.setFlags(Prefixes);
3098 // Find one unsized memory operand, if present.
3099 X86Operand *UnsizedMemOp = nullptr;
3100 for (const auto &Op : Operands) {
3101 X86Operand *X86Op = static_cast<X86Operand *>(Op.get());
3102 if (X86Op->isMemUnsized()) {
3103 UnsizedMemOp = X86Op;
3104 // Have we found an unqualified memory operand,
3105 // break. IA allows only one memory operand.
3110 // Allow some instructions to have implicitly pointer-sized operands. This is
3111 // compatible with gas.
3113 static const char *const PtrSizedInstrs[] = {"call", "jmp", "push"};
3114 for (const char *Instr : PtrSizedInstrs) {
3115 if (Mnemonic == Instr) {
3116 UnsizedMemOp->Mem.Size = getPointerWidth();
3122 SmallVector<unsigned, 8> Match;
3123 uint64_t ErrorInfoMissingFeature = 0;
3125 // If unsized push has immediate operand we should default the default pointer
3126 // size for the size.
3127 if (Mnemonic == "push" && Operands.size() == 2) {
3128 auto *X86Op = static_cast<X86Operand *>(Operands[1].get());
3129 if (X86Op->isImm()) {
3130 // If it's not a constant fall through and let remainder take care of it.
3131 const auto *CE = dyn_cast<MCConstantExpr>(X86Op->getImm());
3132 unsigned Size = getPointerWidth();
3134 (isIntN(Size, CE->getValue()) || isUIntN(Size, CE->getValue()))) {
3135 SmallString<16> Tmp;
3137 Tmp += (is64BitMode())
3139 : (is32BitMode()) ? "l" : (is16BitMode()) ? "w" : " ";
3140 Op.setTokenValue(Tmp);
3141 // Do match in ATT mode to allow explicit suffix usage.
3142 Match.push_back(MatchInstruction(Operands, Inst, ErrorInfo,
3144 false /*isParsingIntelSyntax()*/));
3145 Op.setTokenValue(Base);
3150 // If an unsized memory operand is present, try to match with each memory
3151 // operand size. In Intel assembly, the size is not part of the instruction
3153 if (UnsizedMemOp && UnsizedMemOp->isMemUnsized()) {
3154 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
3155 for (unsigned Size : MopSizes) {
3156 UnsizedMemOp->Mem.Size = Size;
3157 uint64_t ErrorInfoIgnore;
3158 unsigned LastOpcode = Inst.getOpcode();
3159 unsigned M = MatchInstruction(Operands, Inst, ErrorInfoIgnore,
3160 MatchingInlineAsm, isParsingIntelSyntax());
3161 if (Match.empty() || LastOpcode != Inst.getOpcode())
3164 // If this returned as a missing feature failure, remember that.
3165 if (Match.back() == Match_MissingFeature)
3166 ErrorInfoMissingFeature = ErrorInfoIgnore;
3169 // Restore the size of the unsized memory operand if we modified it.
3170 UnsizedMemOp->Mem.Size = 0;
3173 // If we haven't matched anything yet, this is not a basic integer or FPU
3174 // operation. There shouldn't be any ambiguity in our mnemonic table, so try
3175 // matching with the unsized operand.
3176 if (Match.empty()) {
3177 Match.push_back(MatchInstruction(
3178 Operands, Inst, ErrorInfo, MatchingInlineAsm, isParsingIntelSyntax()));
3179 // If this returned as a missing feature failure, remember that.
3180 if (Match.back() == Match_MissingFeature)
3181 ErrorInfoMissingFeature = ErrorInfo;
3184 // Restore the size of the unsized memory operand if we modified it.
3186 UnsizedMemOp->Mem.Size = 0;
3188 // If it's a bad mnemonic, all results will be the same.
3189 if (Match.back() == Match_MnemonicFail) {
3190 return Error(IDLoc, "invalid instruction mnemonic '" + Mnemonic + "'",
3191 Op.getLocRange(), MatchingInlineAsm);
3194 unsigned NumSuccessfulMatches =
3195 std::count(std::begin(Match), std::end(Match), Match_Success);
3197 // If matching was ambiguous and we had size information from the frontend,
3198 // try again with that. This handles cases like "movxz eax, m8/m16".
3199 if (UnsizedMemOp && NumSuccessfulMatches > 1 &&
3200 UnsizedMemOp->getMemFrontendSize()) {
3201 UnsizedMemOp->Mem.Size = UnsizedMemOp->getMemFrontendSize();
3202 unsigned M = MatchInstruction(
3203 Operands, Inst, ErrorInfo, MatchingInlineAsm, isParsingIntelSyntax());
3204 if (M == Match_Success)
3205 NumSuccessfulMatches = 1;
3207 // Add a rewrite that encodes the size information we used from the
3209 InstInfo->AsmRewrites->emplace_back(
3210 AOK_SizeDirective, UnsizedMemOp->getStartLoc(),
3211 /*Len=*/0, UnsizedMemOp->getMemFrontendSize());
3214 // If exactly one matched, then we treat that as a successful match (and the
3215 // instruction will already have been filled in correctly, since the failing
3216 // matches won't have modified it).
3217 if (NumSuccessfulMatches == 1) {
3218 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
3220 // Some instructions need post-processing to, for example, tweak which
3221 // encoding is selected. Loop on it while changes happen so the individual
3222 // transformations can chain off each other.
3223 if (!MatchingInlineAsm)
3224 while (processInstruction(Inst, Operands))
3227 if (!MatchingInlineAsm)
3228 EmitInstruction(Inst, Operands, Out);
3229 Opcode = Inst.getOpcode();
3231 } else if (NumSuccessfulMatches > 1) {
3232 assert(UnsizedMemOp &&
3233 "multiple matches only possible with unsized memory operands");
3234 return Error(UnsizedMemOp->getStartLoc(),
3235 "ambiguous operand size for instruction '" + Mnemonic + "\'",
3236 UnsizedMemOp->getLocRange());
3239 // If one instruction matched with a missing feature, report this as a
3241 if (std::count(std::begin(Match), std::end(Match),
3242 Match_MissingFeature) == 1) {
3243 ErrorInfo = ErrorInfoMissingFeature;
3244 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
3248 // If one instruction matched with an invalid operand, report this as an
3250 if (std::count(std::begin(Match), std::end(Match),
3251 Match_InvalidOperand) == 1) {
3252 return Error(IDLoc, "invalid operand for instruction", EmptyRange,
3256 // If all of these were an outright failure, report it in a useless way.
3257 return Error(IDLoc, "unknown instruction mnemonic", EmptyRange,
3261 bool X86AsmParser::OmitRegisterFromClobberLists(unsigned RegNo) {
3262 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo);
3265 bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
3266 MCAsmParser &Parser = getParser();
3267 StringRef IDVal = DirectiveID.getIdentifier();
3268 if (IDVal.startswith(".code"))
3269 return ParseDirectiveCode(IDVal, DirectiveID.getLoc());
3270 else if (IDVal.startswith(".att_syntax")) {
3271 getParser().setParsingInlineAsm(false);
3272 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3273 if (Parser.getTok().getString() == "prefix")
3275 else if (Parser.getTok().getString() == "noprefix")
3276 return Error(DirectiveID.getLoc(), "'.att_syntax noprefix' is not "
3277 "supported: registers must have a "
3278 "'%' prefix in .att_syntax");
3280 getParser().setAssemblerDialect(0);
3282 } else if (IDVal.startswith(".intel_syntax")) {
3283 getParser().setAssemblerDialect(1);
3284 getParser().setParsingInlineAsm(true);
3285 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3286 if (Parser.getTok().getString() == "noprefix")
3288 else if (Parser.getTok().getString() == "prefix")
3289 return Error(DirectiveID.getLoc(), "'.intel_syntax prefix' is not "
3290 "supported: registers must not have "
3291 "a '%' prefix in .intel_syntax");
3294 } else if (IDVal == ".even")
3295 return parseDirectiveEven(DirectiveID.getLoc());
3296 else if (IDVal == ".cv_fpo_proc")
3297 return parseDirectiveFPOProc(DirectiveID.getLoc());
3298 else if (IDVal == ".cv_fpo_setframe")
3299 return parseDirectiveFPOSetFrame(DirectiveID.getLoc());
3300 else if (IDVal == ".cv_fpo_pushreg")
3301 return parseDirectiveFPOPushReg(DirectiveID.getLoc());
3302 else if (IDVal == ".cv_fpo_stackalloc")
3303 return parseDirectiveFPOStackAlloc(DirectiveID.getLoc());
3304 else if (IDVal == ".cv_fpo_endprologue")
3305 return parseDirectiveFPOEndPrologue(DirectiveID.getLoc());
3306 else if (IDVal == ".cv_fpo_endproc")
3307 return parseDirectiveFPOEndProc(DirectiveID.getLoc());
3312 /// parseDirectiveEven
3314 bool X86AsmParser::parseDirectiveEven(SMLoc L) {
3315 if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive"))
3318 const MCSection *Section = getStreamer().getCurrentSectionOnly();
3320 getStreamer().InitSections(false);
3321 Section = getStreamer().getCurrentSectionOnly();
3323 if (Section->UseCodeAlign())
3324 getStreamer().EmitCodeAlignment(2, 0);
3326 getStreamer().EmitValueToAlignment(2, 0, 1, 0);
3330 /// ParseDirectiveCode
3331 /// ::= .code16 | .code32 | .code64
3332 bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
3333 MCAsmParser &Parser = getParser();
3335 if (IDVal == ".code16") {
3337 if (!is16BitMode()) {
3338 SwitchMode(X86::Mode16Bit);
3339 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
3341 } else if (IDVal == ".code16gcc") {
3342 // .code16gcc parses as if in 32-bit mode, but emits code in 16-bit mode.
3345 if (!is16BitMode()) {
3346 SwitchMode(X86::Mode16Bit);
3347 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
3349 } else if (IDVal == ".code32") {
3351 if (!is32BitMode()) {
3352 SwitchMode(X86::Mode32Bit);
3353 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
3355 } else if (IDVal == ".code64") {
3357 if (!is64BitMode()) {
3358 SwitchMode(X86::Mode64Bit);
3359 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code64);
3362 Error(L, "unknown directive " + IDVal);
3370 bool X86AsmParser::parseDirectiveFPOProc(SMLoc L) {
3371 MCAsmParser &Parser = getParser();
3374 if (Parser.parseIdentifier(ProcName))
3375 return Parser.TokError("expected symbol name");
3376 if (Parser.parseIntToken(ParamsSize, "expected parameter byte count"))
3378 if (!isUIntN(32, ParamsSize))
3379 return Parser.TokError("parameters size out of range");
3380 if (Parser.parseEOL("unexpected tokens"))
3381 return addErrorSuffix(" in '.cv_fpo_proc' directive");
3382 MCSymbol *ProcSym = getContext().getOrCreateSymbol(ProcName);
3383 return getTargetStreamer().emitFPOProc(ProcSym, ParamsSize, L);
3386 // .cv_fpo_setframe ebp
3387 bool X86AsmParser::parseDirectiveFPOSetFrame(SMLoc L) {
3388 MCAsmParser &Parser = getParser();
3391 if (ParseRegister(Reg, DummyLoc, DummyLoc) ||
3392 Parser.parseEOL("unexpected tokens"))
3393 return addErrorSuffix(" in '.cv_fpo_setframe' directive");
3394 return getTargetStreamer().emitFPOSetFrame(Reg, L);
3397 // .cv_fpo_pushreg ebx
3398 bool X86AsmParser::parseDirectiveFPOPushReg(SMLoc L) {
3399 MCAsmParser &Parser = getParser();
3402 if (ParseRegister(Reg, DummyLoc, DummyLoc) ||
3403 Parser.parseEOL("unexpected tokens"))
3404 return addErrorSuffix(" in '.cv_fpo_pushreg' directive");
3405 return getTargetStreamer().emitFPOPushReg(Reg, L);
3408 // .cv_fpo_stackalloc 20
3409 bool X86AsmParser::parseDirectiveFPOStackAlloc(SMLoc L) {
3410 MCAsmParser &Parser = getParser();
3412 if (Parser.parseIntToken(Offset, "expected offset") ||
3413 Parser.parseEOL("unexpected tokens"))
3414 return addErrorSuffix(" in '.cv_fpo_stackalloc' directive");
3415 return getTargetStreamer().emitFPOStackAlloc(Offset, L);
3418 // .cv_fpo_endprologue
3419 bool X86AsmParser::parseDirectiveFPOEndPrologue(SMLoc L) {
3420 MCAsmParser &Parser = getParser();
3421 if (Parser.parseEOL("unexpected tokens"))
3422 return addErrorSuffix(" in '.cv_fpo_endprologue' directive");
3423 return getTargetStreamer().emitFPOEndPrologue(L);
3427 bool X86AsmParser::parseDirectiveFPOEndProc(SMLoc L) {
3428 MCAsmParser &Parser = getParser();
3429 if (Parser.parseEOL("unexpected tokens"))
3430 return addErrorSuffix(" in '.cv_fpo_endproc' directive");
3431 return getTargetStreamer().emitFPOEndProc(L);
3434 // Force static initialization.
3435 extern "C" void LLVMInitializeX86AsmParser() {
3436 RegisterMCAsmParser<X86AsmParser> X(getTheX86_32Target());
3437 RegisterMCAsmParser<X86AsmParser> Y(getTheX86_64Target());
3440 #define GET_REGISTER_MATCHER
3441 #define GET_MATCHER_IMPLEMENTATION
3442 #define GET_SUBTARGET_FEATURE_NAME
3443 #include "X86GenAsmMatcher.inc"