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();
823 std::unique_ptr<X86Operand> ParseATTOperand();
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 MemStart);
840 bool ParseIntelMemoryOperandSize(unsigned &Size);
841 std::unique_ptr<X86Operand>
842 CreateMemForInlineAsm(unsigned SegReg, const MCExpr *Disp, unsigned BaseReg,
843 unsigned IndexReg, unsigned Scale, SMLoc Start,
844 SMLoc End, unsigned Size, StringRef Identifier,
845 const InlineAsmIdentifierInfo &Info);
847 bool parseDirectiveEven(SMLoc L);
848 bool ParseDirectiveCode(StringRef IDVal, SMLoc L);
850 /// CodeView FPO data directives.
851 bool parseDirectiveFPOProc(SMLoc L);
852 bool parseDirectiveFPOSetFrame(SMLoc L);
853 bool parseDirectiveFPOPushReg(SMLoc L);
854 bool parseDirectiveFPOStackAlloc(SMLoc L);
855 bool parseDirectiveFPOEndPrologue(SMLoc L);
856 bool parseDirectiveFPOEndProc(SMLoc L);
857 bool parseDirectiveFPOData(SMLoc L);
859 bool validateInstruction(MCInst &Inst, const OperandVector &Ops);
860 bool processInstruction(MCInst &Inst, const OperandVector &Ops);
862 /// Wrapper around MCStreamer::EmitInstruction(). Possibly adds
863 /// instrumentation around Inst.
864 void EmitInstruction(MCInst &Inst, OperandVector &Operands, MCStreamer &Out);
866 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
867 OperandVector &Operands, MCStreamer &Out,
869 bool MatchingInlineAsm) override;
871 void MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op, OperandVector &Operands,
872 MCStreamer &Out, bool MatchingInlineAsm);
874 bool ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
875 bool MatchingInlineAsm);
877 bool MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
878 OperandVector &Operands, MCStreamer &Out,
880 bool MatchingInlineAsm);
882 bool MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
883 OperandVector &Operands, MCStreamer &Out,
885 bool MatchingInlineAsm);
887 bool OmitRegisterFromClobberLists(unsigned RegNo) override;
889 /// Parses AVX512 specific operand primitives: masked registers ({%k<NUM>}, {z})
890 /// and memory broadcasting ({1to<NUM>}) primitives, updating Operands vector if required.
891 /// return false if no parsing errors occurred, true otherwise.
892 bool HandleAVX512Operand(OperandVector &Operands,
893 const MCParsedAsmOperand &Op);
895 bool ParseZ(std::unique_ptr<X86Operand> &Z, const SMLoc &StartLoc);
897 bool is64BitMode() const {
898 // FIXME: Can tablegen auto-generate this?
899 return getSTI().getFeatureBits()[X86::Mode64Bit];
901 bool is32BitMode() const {
902 // FIXME: Can tablegen auto-generate this?
903 return getSTI().getFeatureBits()[X86::Mode32Bit];
905 bool is16BitMode() const {
906 // FIXME: Can tablegen auto-generate this?
907 return getSTI().getFeatureBits()[X86::Mode16Bit];
909 void SwitchMode(unsigned mode) {
910 MCSubtargetInfo &STI = copySTI();
911 FeatureBitset AllModes({X86::Mode64Bit, X86::Mode32Bit, X86::Mode16Bit});
912 FeatureBitset OldMode = STI.getFeatureBits() & AllModes;
913 uint64_t FB = ComputeAvailableFeatures(
914 STI.ToggleFeature(OldMode.flip(mode)));
915 setAvailableFeatures(FB);
917 assert(FeatureBitset({mode}) == (STI.getFeatureBits() & AllModes));
920 unsigned getPointerWidth() {
921 if (is16BitMode()) return 16;
922 if (is32BitMode()) return 32;
923 if (is64BitMode()) return 64;
924 llvm_unreachable("invalid mode");
927 bool isParsingIntelSyntax() {
928 return getParser().getAssemblerDialect();
931 /// @name Auto-generated Matcher Functions
934 #define GET_ASSEMBLER_HEADER
935 #include "X86GenAsmMatcher.inc"
941 X86AsmParser(const MCSubtargetInfo &sti, MCAsmParser &Parser,
942 const MCInstrInfo &mii, const MCTargetOptions &Options)
943 : MCTargetAsmParser(Options, sti, mii), InstInfo(nullptr),
946 Parser.addAliasForDirective(".word", ".2byte");
948 // Initialize the set of available features.
949 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
950 Instrumentation.reset(
951 CreateX86AsmInstrumentation(Options, Parser.getContext(), STI));
954 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
956 void SetFrameRegister(unsigned RegNo) override;
958 bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) override;
960 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
961 SMLoc NameLoc, OperandVector &Operands) override;
963 bool ParseDirective(AsmToken DirectiveID) override;
965 } // end anonymous namespace
967 /// @name Auto-generated Match Functions
970 static unsigned MatchRegisterName(StringRef Name);
974 static bool CheckBaseRegAndIndexRegAndScale(unsigned BaseReg, unsigned IndexReg,
975 unsigned Scale, bool Is64BitMode,
977 // If we have both a base register and an index register make sure they are
978 // both 64-bit or 32-bit registers.
979 // To support VSIB, IndexReg can be 128-bit or 256-bit registers.
982 !(BaseReg == X86::RIP || BaseReg == X86::EIP ||
983 X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) ||
984 X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg) ||
985 X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg))) {
986 ErrMsg = "invalid base+index expression";
991 !(IndexReg == X86::EIZ || IndexReg == X86::RIZ ||
992 X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
993 X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg) ||
994 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg) ||
995 X86MCRegisterClasses[X86::VR128XRegClassID].contains(IndexReg) ||
996 X86MCRegisterClasses[X86::VR256XRegClassID].contains(IndexReg) ||
997 X86MCRegisterClasses[X86::VR512RegClassID].contains(IndexReg))) {
998 ErrMsg = "invalid base+index expression";
1002 if (((BaseReg == X86::RIP || BaseReg == X86::EIP) && IndexReg != 0) ||
1003 IndexReg == X86::EIP || IndexReg == X86::RIP ||
1004 IndexReg == X86::ESP || IndexReg == X86::RSP) {
1005 ErrMsg = "invalid base+index expression";
1009 // Check for use of invalid 16-bit registers. Only BX/BP/SI/DI are allowed,
1010 // and then only in non-64-bit modes.
1011 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
1012 (Is64BitMode || (BaseReg != X86::BX && BaseReg != X86::BP &&
1013 BaseReg != X86::SI && BaseReg != X86::DI)) &&
1014 BaseReg != X86::DX) {
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() {
1336 if (isParsingIntelSyntax())
1337 return ParseIntelOperand();
1338 return ParseATTOperand();
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() {
1936 MCAsmParser &Parser = getParser();
1937 switch (getLexer().getKind()) {
1939 // Parse a memory operand with no segment register.
1940 return ParseMemOperand(0, Parser.getTok().getLoc());
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);
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,
2094 MCAsmParser &Parser = getParser();
2095 // We have to disambiguate a parenthesized expression "(4+5)" from the start
2096 // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)". The
2097 // only way to do this without lookahead is to eat the '(' and see what is
2099 const MCExpr *Disp = MCConstantExpr::create(0, getParser().getContext());
2100 if (getLexer().isNot(AsmToken::LParen)) {
2102 if (getParser().parseExpression(Disp, ExprEnd)) return nullptr;
2103 // Disp may be a variable, handle register values.
2104 if (auto *RE = dyn_cast<X86MCExpr>(Disp))
2105 return X86Operand::CreateReg(RE->getRegNo(), MemStart, ExprEnd);
2107 // After parsing the base expression we could either have a parenthesized
2108 // memory address or not. If not, return now. If so, eat the (.
2109 if (getLexer().isNot(AsmToken::LParen)) {
2110 // Unless we have a segment register, treat this as an immediate.
2112 return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, ExprEnd);
2113 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
2120 // Okay, we have a '('. We don't know if this is an expression or not, but
2121 // so we have to eat the ( to see beyond it.
2122 SMLoc LParenLoc = Parser.getTok().getLoc();
2123 Parser.Lex(); // Eat the '('.
2125 if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) {
2126 // Nothing to do here, fall into the code below with the '(' part of the
2127 // memory operand consumed.
2130 getLexer().UnLex(AsmToken(AsmToken::LParen, "("));
2132 // It must be either an parenthesized expression, or an expression that
2133 // begins from a parenthesized expression, parse it now. Example: (1+2) or
2135 if (getParser().parseExpression(Disp, ExprEnd))
2138 // After parsing the base expression we could either have a parenthesized
2139 // memory address or not. If not, return now. If so, eat the (.
2140 if (getLexer().isNot(AsmToken::LParen)) {
2141 // Unless we have a segment register, treat this as an immediate.
2143 return X86Operand::CreateMem(getPointerWidth(), Disp, LParenLoc,
2145 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
2154 // If we reached here, then we just ate the ( of the memory operand. Process
2155 // the rest of the memory operand.
2156 unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
2157 SMLoc IndexLoc, BaseLoc;
2159 if (getLexer().is(AsmToken::Percent)) {
2160 SMLoc StartLoc, EndLoc;
2161 BaseLoc = Parser.getTok().getLoc();
2162 if (ParseRegister(BaseReg, StartLoc, EndLoc)) return nullptr;
2163 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) {
2164 Error(StartLoc, "eiz and riz can only be used as index registers",
2165 SMRange(StartLoc, EndLoc));
2170 if (getLexer().is(AsmToken::Comma)) {
2171 Parser.Lex(); // Eat the comma.
2172 IndexLoc = Parser.getTok().getLoc();
2174 // Following the comma we should have either an index register, or a scale
2175 // value. We don't support the later form, but we want to parse it
2178 // Not that even though it would be completely consistent to support syntax
2179 // like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this.
2180 if (getLexer().is(AsmToken::Percent)) {
2182 if (ParseRegister(IndexReg, L, L))
2184 if (BaseReg == X86::RIP) {
2185 Error(IndexLoc, "%rip as base register can not have an index register");
2188 if (IndexReg == X86::RIP) {
2189 Error(IndexLoc, "%rip is not allowed as an index register");
2193 if (getLexer().isNot(AsmToken::RParen)) {
2194 // Parse the scale amount:
2195 // ::= ',' [scale-expression]
2196 if (parseToken(AsmToken::Comma, "expected comma in scale expression"))
2199 if (getLexer().isNot(AsmToken::RParen)) {
2200 SMLoc Loc = Parser.getTok().getLoc();
2203 if (getParser().parseAbsoluteExpression(ScaleVal)){
2204 Error(Loc, "expected scale expression");
2208 // Validate the scale amount.
2209 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
2211 Error(Loc, "scale factor in 16-bit address must be 1");
2214 if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 &&
2216 Error(Loc, "scale factor in address must be 1, 2, 4 or 8");
2219 Scale = (unsigned)ScaleVal;
2222 } else if (getLexer().isNot(AsmToken::RParen)) {
2223 // A scale amount without an index is ignored.
2225 SMLoc Loc = Parser.getTok().getLoc();
2228 if (getParser().parseAbsoluteExpression(Value))
2232 Warning(Loc, "scale factor without index register is ignored");
2237 // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
2238 SMLoc MemEnd = Parser.getTok().getEndLoc();
2239 if (parseToken(AsmToken::RParen, "unexpected token in memory operand"))
2242 // This is a terrible hack to handle "out[s]?[bwl]? %al, (%dx)" ->
2243 // "outb %al, %dx". Out doesn't take a memory form, but this is a widely
2244 // documented form in various unofficial manuals, so a lot of code uses it.
2245 if (BaseReg == X86::DX && IndexReg == 0 && Scale == 1 &&
2246 SegReg == 0 && isa<MCConstantExpr>(Disp) &&
2247 cast<MCConstantExpr>(Disp)->getValue() == 0)
2248 return X86Operand::CreateDXReg(BaseLoc, BaseLoc);
2251 if (CheckBaseRegAndIndexRegAndScale(BaseReg, IndexReg, Scale, is64BitMode(),
2253 Error(BaseLoc, ErrMsg);
2257 if (SegReg || BaseReg || IndexReg)
2258 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
2259 IndexReg, Scale, MemStart, MemEnd);
2260 return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, MemEnd);
2263 // Parse either a standard primary expression or a register.
2264 bool X86AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
2265 MCAsmParser &Parser = getParser();
2266 if (Parser.parsePrimaryExpr(Res, EndLoc)) {
2267 SMLoc StartLoc = Parser.getTok().getLoc();
2268 // Normal Expression parse fails, check if it could be a register.
2271 getTok().is(AsmToken::Percent) ||
2272 (isParsingIntelSyntax() && getTok().is(AsmToken::Identifier));
2273 if (!TryRegParse || ParseRegister(RegNo, StartLoc, EndLoc))
2275 // Clear previous parse error and return correct expression.
2276 Parser.clearPendingErrors();
2277 Res = X86MCExpr::create(RegNo, Parser.getContext());
2284 bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2285 SMLoc NameLoc, OperandVector &Operands) {
2286 MCAsmParser &Parser = getParser();
2288 StringRef PatchedName = Name;
2290 if ((Name.equals("jmp") || Name.equals("jc") || Name.equals("jz")) &&
2291 isParsingIntelSyntax() && isParsingInlineAsm()) {
2292 StringRef NextTok = Parser.getTok().getString();
2293 if (NextTok == "short") {
2295 NameLoc.getFromPointer(NameLoc.getPointer() + Name.size());
2296 // Eat the short keyword
2298 // MS ignores the short keyword, it determines the jmp type based
2299 // on the distance of the label
2300 InstInfo->AsmRewrites->emplace_back(AOK_Skip, NameEndLoc,
2301 NextTok.size() + 1);
2305 // FIXME: Hack to recognize setneb as setne.
2306 if (PatchedName.startswith("set") && PatchedName.endswith("b") &&
2307 PatchedName != "setb" && PatchedName != "setnb")
2308 PatchedName = PatchedName.substr(0, Name.size()-1);
2310 // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}.
2311 if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) &&
2312 (PatchedName.endswith("ss") || PatchedName.endswith("sd") ||
2313 PatchedName.endswith("ps") || PatchedName.endswith("pd"))) {
2314 bool IsVCMP = PatchedName[0] == 'v';
2315 unsigned CCIdx = IsVCMP ? 4 : 3;
2316 unsigned ComparisonCode = StringSwitch<unsigned>(
2317 PatchedName.slice(CCIdx, PatchedName.size() - 2))
2319 .Case("eq_oq", 0x00)
2321 .Case("lt_os", 0x01)
2323 .Case("le_os", 0x02)
2324 .Case("unord", 0x03)
2325 .Case("unord_q", 0x03)
2327 .Case("neq_uq", 0x04)
2329 .Case("nlt_us", 0x05)
2331 .Case("nle_us", 0x06)
2333 .Case("ord_q", 0x07)
2334 /* AVX only from here */
2335 .Case("eq_uq", 0x08)
2337 .Case("nge_us", 0x09)
2339 .Case("ngt_us", 0x0A)
2340 .Case("false", 0x0B)
2341 .Case("false_oq", 0x0B)
2342 .Case("neq_oq", 0x0C)
2344 .Case("ge_os", 0x0D)
2346 .Case("gt_os", 0x0E)
2348 .Case("true_uq", 0x0F)
2349 .Case("eq_os", 0x10)
2350 .Case("lt_oq", 0x11)
2351 .Case("le_oq", 0x12)
2352 .Case("unord_s", 0x13)
2353 .Case("neq_us", 0x14)
2354 .Case("nlt_uq", 0x15)
2355 .Case("nle_uq", 0x16)
2356 .Case("ord_s", 0x17)
2357 .Case("eq_us", 0x18)
2358 .Case("nge_uq", 0x19)
2359 .Case("ngt_uq", 0x1A)
2360 .Case("false_os", 0x1B)
2361 .Case("neq_os", 0x1C)
2362 .Case("ge_oq", 0x1D)
2363 .Case("gt_oq", 0x1E)
2364 .Case("true_us", 0x1F)
2366 if (ComparisonCode != ~0U && (IsVCMP || ComparisonCode < 8)) {
2368 Operands.push_back(X86Operand::CreateToken(PatchedName.slice(0, CCIdx),
2371 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2372 getParser().getContext());
2373 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2375 PatchedName = PatchedName.substr(PatchedName.size() - 2);
2379 // FIXME: Hack to recognize vpcmp<comparison code>{ub,uw,ud,uq,b,w,d,q}.
2380 if (PatchedName.startswith("vpcmp") &&
2381 (PatchedName.endswith("b") || PatchedName.endswith("w") ||
2382 PatchedName.endswith("d") || PatchedName.endswith("q"))) {
2383 unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1;
2384 unsigned ComparisonCode = StringSwitch<unsigned>(
2385 PatchedName.slice(5, PatchedName.size() - CCIdx))
2386 .Case("eq", 0x0) // Only allowed on unsigned. Checked below.
2389 //.Case("false", 0x3) // Not a documented alias.
2393 //.Case("true", 0x7) // Not a documented alias.
2395 if (ComparisonCode != ~0U && (ComparisonCode != 0 || CCIdx == 2)) {
2396 Operands.push_back(X86Operand::CreateToken("vpcmp", NameLoc));
2398 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2399 getParser().getContext());
2400 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2402 PatchedName = PatchedName.substr(PatchedName.size() - CCIdx);
2406 // FIXME: Hack to recognize vpcom<comparison code>{ub,uw,ud,uq,b,w,d,q}.
2407 if (PatchedName.startswith("vpcom") &&
2408 (PatchedName.endswith("b") || PatchedName.endswith("w") ||
2409 PatchedName.endswith("d") || PatchedName.endswith("q"))) {
2410 unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1;
2411 unsigned ComparisonCode = StringSwitch<unsigned>(
2412 PatchedName.slice(5, PatchedName.size() - CCIdx))
2422 if (ComparisonCode != ~0U) {
2423 Operands.push_back(X86Operand::CreateToken("vpcom", NameLoc));
2425 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2426 getParser().getContext());
2427 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2429 PatchedName = PatchedName.substr(PatchedName.size() - CCIdx);
2434 // Determine whether this is an instruction prefix.
2436 // Enhance prefixes integrity robustness. for example, following forms
2437 // are currently tolerated:
2438 // repz repnz <insn> ; GAS errors for the use of two similar prefixes
2439 // lock addq %rax, %rbx ; Destination operand must be of memory type
2440 // xacquire <insn> ; xacquire must be accompanied by 'lock'
2441 bool isPrefix = StringSwitch<bool>(Name)
2442 .Cases("rex64", "data32", "data16", true)
2443 .Cases("xacquire", "xrelease", true)
2444 .Cases("acquire", "release", isParsingIntelSyntax())
2447 auto isLockRepeatNtPrefix = [](StringRef N) {
2448 return StringSwitch<bool>(N)
2449 .Cases("lock", "rep", "repe", "repz", "repne", "repnz", "notrack", true)
2453 bool CurlyAsEndOfStatement = false;
2455 unsigned Flags = X86::IP_NO_PREFIX;
2456 while (isLockRepeatNtPrefix(Name.lower())) {
2458 StringSwitch<unsigned>(Name)
2459 .Cases("lock", "lock", X86::IP_HAS_LOCK)
2460 .Cases("rep", "repe", "repz", X86::IP_HAS_REPEAT)
2461 .Cases("repne", "repnz", X86::IP_HAS_REPEAT_NE)
2462 .Cases("notrack", "notrack", X86::IP_HAS_NOTRACK)
2463 .Default(X86::IP_NO_PREFIX); // Invalid prefix (impossible)
2465 if (getLexer().is(AsmToken::EndOfStatement)) {
2466 // We don't have real instr with the given prefix
2467 // let's use the prefix as the instr.
2468 // TODO: there could be several prefixes one after another
2469 Flags = X86::IP_NO_PREFIX;
2472 Name = Parser.getTok().getString();
2473 Parser.Lex(); // eat the prefix
2474 // Hack: we could have something like "rep # some comment" or
2475 // "lock; cmpxchg16b $1" or "lock\0A\09incl" or "lock/incl"
2476 while (Name.startswith(";") || Name.startswith("\n") ||
2477 Name.startswith("#") || Name.startswith("\t") ||
2478 Name.startswith("/")) {
2479 Name = Parser.getTok().getString();
2480 Parser.Lex(); // go to next prefix or instr
2487 // Hacks to handle 'data16' and 'data32'
2488 if (PatchedName == "data16" && is16BitMode()) {
2489 return Error(NameLoc, "redundant data16 prefix");
2491 if (PatchedName == "data32") {
2493 return Error(NameLoc, "redundant data32 prefix");
2495 return Error(NameLoc, "'data32' is not supported in 64-bit mode");
2496 // Hack to 'data16' for the table lookup.
2497 PatchedName = "data16";
2500 Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
2502 // This does the actual operand parsing. Don't parse any more if we have a
2503 // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we
2504 // just want to parse the "lock" as the first instruction and the "incl" as
2506 if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) {
2507 // Parse '*' modifier.
2508 if (getLexer().is(AsmToken::Star))
2509 Operands.push_back(X86Operand::CreateToken("*", consumeToken()));
2511 // Read the operands.
2513 if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
2514 Operands.push_back(std::move(Op));
2515 if (HandleAVX512Operand(Operands, *Operands.back()))
2520 // check for comma and eat it
2521 if (getLexer().is(AsmToken::Comma))
2527 // In MS inline asm curly braces mark the beginning/end of a block,
2528 // therefore they should be interepreted as end of statement
2529 CurlyAsEndOfStatement =
2530 isParsingIntelSyntax() && isParsingInlineAsm() &&
2531 (getLexer().is(AsmToken::LCurly) || getLexer().is(AsmToken::RCurly));
2532 if (getLexer().isNot(AsmToken::EndOfStatement) && !CurlyAsEndOfStatement)
2533 return TokError("unexpected token in argument list");
2536 // Consume the EndOfStatement or the prefix separator Slash
2537 if (getLexer().is(AsmToken::EndOfStatement) ||
2538 (isPrefix && getLexer().is(AsmToken::Slash)))
2540 else if (CurlyAsEndOfStatement)
2541 // Add an actual EndOfStatement before the curly brace
2542 Info.AsmRewrites->emplace_back(AOK_EndOfStatement,
2543 getLexer().getTok().getLoc(), 0);
2545 // This is for gas compatibility and cannot be done in td.
2546 // Adding "p" for some floating point with no argument.
2547 // For example: fsub --> fsubp
2549 Name == "fsub" || Name == "fdiv" || Name == "fsubr" || Name == "fdivr";
2550 if (IsFp && Operands.size() == 1) {
2551 const char *Repl = StringSwitch<const char *>(Name)
2552 .Case("fsub", "fsubp")
2553 .Case("fdiv", "fdivp")
2554 .Case("fsubr", "fsubrp")
2555 .Case("fdivr", "fdivrp");
2556 static_cast<X86Operand &>(*Operands[0]).setTokenValue(Repl);
2559 // Moving a 32 or 16 bit value into a segment register has the same
2560 // behavior. Modify such instructions to always take shorter form.
2561 if ((Name == "mov" || Name == "movw" || Name == "movl") &&
2562 (Operands.size() == 3)) {
2563 X86Operand &Op1 = (X86Operand &)*Operands[1];
2564 X86Operand &Op2 = (X86Operand &)*Operands[2];
2565 SMLoc Loc = Op1.getEndLoc();
2566 if (Op1.isReg() && Op2.isReg() &&
2567 X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(
2569 (X86MCRegisterClasses[X86::GR16RegClassID].contains(Op1.getReg()) ||
2570 X86MCRegisterClasses[X86::GR32RegClassID].contains(Op1.getReg()))) {
2571 // Change instruction name to match new instruction.
2572 if (Name != "mov" && Name[3] == (is16BitMode() ? 'l' : 'w')) {
2573 Name = is16BitMode() ? "movw" : "movl";
2574 Operands[0] = X86Operand::CreateToken(Name, NameLoc);
2576 // Select the correct equivalent 16-/32-bit source register.
2578 getX86SubSuperRegisterOrZero(Op1.getReg(), is16BitMode() ? 16 : 32);
2579 Operands[1] = X86Operand::CreateReg(Reg, Loc, Loc);
2583 // This is a terrible hack to handle "out[s]?[bwl]? %al, (%dx)" ->
2584 // "outb %al, %dx". Out doesn't take a memory form, but this is a widely
2585 // documented form in various unofficial manuals, so a lot of code uses it.
2586 if ((Name == "outb" || Name == "outsb" || Name == "outw" || Name == "outsw" ||
2587 Name == "outl" || Name == "outsl" || Name == "out" || Name == "outs") &&
2588 Operands.size() == 3) {
2589 X86Operand &Op = (X86Operand &)*Operands.back();
2591 Operands.back() = X86Operand::CreateReg(X86::DX, Op.getStartLoc(),
2594 // Same hack for "in[s]?[bwl]? (%dx), %al" -> "inb %dx, %al".
2595 if ((Name == "inb" || Name == "insb" || Name == "inw" || Name == "insw" ||
2596 Name == "inl" || Name == "insl" || Name == "in" || Name == "ins") &&
2597 Operands.size() == 3) {
2598 X86Operand &Op = (X86Operand &)*Operands[1];
2600 Operands[1] = X86Operand::CreateReg(X86::DX, Op.getStartLoc(),
2604 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 2> TmpOperands;
2605 bool HadVerifyError = false;
2607 // Append default arguments to "ins[bwld]"
2608 if (Name.startswith("ins") &&
2609 (Operands.size() == 1 || Operands.size() == 3) &&
2610 (Name == "insb" || Name == "insw" || Name == "insl" || Name == "insd" ||
2613 AddDefaultSrcDestOperands(TmpOperands,
2614 X86Operand::CreateReg(X86::DX, NameLoc, NameLoc),
2615 DefaultMemDIOperand(NameLoc));
2616 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2619 // Append default arguments to "outs[bwld]"
2620 if (Name.startswith("outs") &&
2621 (Operands.size() == 1 || Operands.size() == 3) &&
2622 (Name == "outsb" || Name == "outsw" || Name == "outsl" ||
2623 Name == "outsd" || Name == "outs")) {
2624 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
2625 X86Operand::CreateReg(X86::DX, NameLoc, NameLoc));
2626 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2629 // Transform "lods[bwlq]" into "lods[bwlq] ($SIREG)" for appropriate
2630 // values of $SIREG according to the mode. It would be nice if this
2631 // could be achieved with InstAlias in the tables.
2632 if (Name.startswith("lods") &&
2633 (Operands.size() == 1 || Operands.size() == 2) &&
2634 (Name == "lods" || Name == "lodsb" || Name == "lodsw" ||
2635 Name == "lodsl" || Name == "lodsd" || Name == "lodsq")) {
2636 TmpOperands.push_back(DefaultMemSIOperand(NameLoc));
2637 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2640 // Transform "stos[bwlq]" into "stos[bwlq] ($DIREG)" for appropriate
2641 // values of $DIREG according to the mode. It would be nice if this
2642 // could be achieved with InstAlias in the tables.
2643 if (Name.startswith("stos") &&
2644 (Operands.size() == 1 || Operands.size() == 2) &&
2645 (Name == "stos" || Name == "stosb" || Name == "stosw" ||
2646 Name == "stosl" || Name == "stosd" || Name == "stosq")) {
2647 TmpOperands.push_back(DefaultMemDIOperand(NameLoc));
2648 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2651 // Transform "scas[bwlq]" into "scas[bwlq] ($DIREG)" for appropriate
2652 // values of $DIREG according to the mode. It would be nice if this
2653 // could be achieved with InstAlias in the tables.
2654 if (Name.startswith("scas") &&
2655 (Operands.size() == 1 || Operands.size() == 2) &&
2656 (Name == "scas" || Name == "scasb" || Name == "scasw" ||
2657 Name == "scasl" || Name == "scasd" || Name == "scasq")) {
2658 TmpOperands.push_back(DefaultMemDIOperand(NameLoc));
2659 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2662 // Add default SI and DI operands to "cmps[bwlq]".
2663 if (Name.startswith("cmps") &&
2664 (Operands.size() == 1 || Operands.size() == 3) &&
2665 (Name == "cmps" || Name == "cmpsb" || Name == "cmpsw" ||
2666 Name == "cmpsl" || Name == "cmpsd" || Name == "cmpsq")) {
2667 AddDefaultSrcDestOperands(TmpOperands, DefaultMemDIOperand(NameLoc),
2668 DefaultMemSIOperand(NameLoc));
2669 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2672 // Add default SI and DI operands to "movs[bwlq]".
2673 if (((Name.startswith("movs") &&
2674 (Name == "movs" || Name == "movsb" || Name == "movsw" ||
2675 Name == "movsl" || Name == "movsd" || Name == "movsq")) ||
2676 (Name.startswith("smov") &&
2677 (Name == "smov" || Name == "smovb" || Name == "smovw" ||
2678 Name == "smovl" || Name == "smovd" || Name == "smovq"))) &&
2679 (Operands.size() == 1 || Operands.size() == 3)) {
2680 if (Name == "movsd" && Operands.size() == 1 && !isParsingIntelSyntax())
2681 Operands.back() = X86Operand::CreateToken("movsl", NameLoc);
2682 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
2683 DefaultMemDIOperand(NameLoc));
2684 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2687 // Check if we encountered an error for one the string insturctions
2688 if (HadVerifyError) {
2689 return HadVerifyError;
2692 // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>. Canonicalize to
2694 if ((Name.startswith("shr") || Name.startswith("sar") ||
2695 Name.startswith("shl") || Name.startswith("sal") ||
2696 Name.startswith("rcl") || Name.startswith("rcr") ||
2697 Name.startswith("rol") || Name.startswith("ror")) &&
2698 Operands.size() == 3) {
2699 if (isParsingIntelSyntax()) {
2701 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[2]);
2702 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2703 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2704 Operands.pop_back();
2706 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2707 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2708 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2709 Operands.erase(Operands.begin() + 1);
2713 // Transforms "int $3" into "int3" as a size optimization. We can't write an
2714 // instalias with an immediate operand yet.
2715 if (Name == "int" && Operands.size() == 2) {
2716 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2718 if (auto *CE = dyn_cast<MCConstantExpr>(Op1.getImm()))
2719 if (CE->getValue() == 3) {
2720 Operands.erase(Operands.begin() + 1);
2721 static_cast<X86Operand &>(*Operands[0]).setTokenValue("int3");
2725 // Transforms "xlat mem8" into "xlatb"
2726 if ((Name == "xlat" || Name == "xlatb") && Operands.size() == 2) {
2727 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2729 Warning(Op1.getStartLoc(), "memory operand is only for determining the "
2730 "size, (R|E)BX will be used for the location");
2731 Operands.pop_back();
2732 static_cast<X86Operand &>(*Operands[0]).setTokenValue("xlatb");
2737 Operands.push_back(X86Operand::CreatePrefix(Flags, NameLoc, NameLoc));
2741 bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) {
2745 bool X86AsmParser::validateInstruction(MCInst &Inst, const OperandVector &Ops) {
2746 const MCRegisterInfo *MRI = getContext().getRegisterInfo();
2748 switch (Inst.getOpcode()) {
2749 case X86::VGATHERDPDYrm:
2750 case X86::VGATHERDPDrm:
2751 case X86::VGATHERDPSYrm:
2752 case X86::VGATHERDPSrm:
2753 case X86::VGATHERQPDYrm:
2754 case X86::VGATHERQPDrm:
2755 case X86::VGATHERQPSYrm:
2756 case X86::VGATHERQPSrm:
2757 case X86::VPGATHERDDYrm:
2758 case X86::VPGATHERDDrm:
2759 case X86::VPGATHERDQYrm:
2760 case X86::VPGATHERDQrm:
2761 case X86::VPGATHERQDYrm:
2762 case X86::VPGATHERQDrm:
2763 case X86::VPGATHERQQYrm:
2764 case X86::VPGATHERQQrm: {
2765 unsigned Dest = MRI->getEncodingValue(Inst.getOperand(0).getReg());
2766 unsigned Mask = MRI->getEncodingValue(Inst.getOperand(1).getReg());
2768 MRI->getEncodingValue(Inst.getOperand(3 + X86::AddrIndexReg).getReg());
2769 if (Dest == Mask || Dest == Index || Mask == Index)
2770 return Warning(Ops[0]->getStartLoc(), "mask, index, and destination "
2771 "registers should be distinct");
2774 case X86::VGATHERDPDZ128rm:
2775 case X86::VGATHERDPDZ256rm:
2776 case X86::VGATHERDPDZrm:
2777 case X86::VGATHERDPSZ128rm:
2778 case X86::VGATHERDPSZ256rm:
2779 case X86::VGATHERDPSZrm:
2780 case X86::VGATHERQPDZ128rm:
2781 case X86::VGATHERQPDZ256rm:
2782 case X86::VGATHERQPDZrm:
2783 case X86::VGATHERQPSZ128rm:
2784 case X86::VGATHERQPSZ256rm:
2785 case X86::VGATHERQPSZrm:
2786 case X86::VPGATHERDDZ128rm:
2787 case X86::VPGATHERDDZ256rm:
2788 case X86::VPGATHERDDZrm:
2789 case X86::VPGATHERDQZ128rm:
2790 case X86::VPGATHERDQZ256rm:
2791 case X86::VPGATHERDQZrm:
2792 case X86::VPGATHERQDZ128rm:
2793 case X86::VPGATHERQDZ256rm:
2794 case X86::VPGATHERQDZrm:
2795 case X86::VPGATHERQQZ128rm:
2796 case X86::VPGATHERQQZ256rm:
2797 case X86::VPGATHERQQZrm: {
2798 unsigned Dest = MRI->getEncodingValue(Inst.getOperand(0).getReg());
2800 MRI->getEncodingValue(Inst.getOperand(4 + X86::AddrIndexReg).getReg());
2802 return Warning(Ops[0]->getStartLoc(), "index and destination registers "
2803 "should be distinct");
2806 case X86::V4FMADDPSrm:
2807 case X86::V4FMADDPSrmk:
2808 case X86::V4FMADDPSrmkz:
2809 case X86::V4FMADDSSrm:
2810 case X86::V4FMADDSSrmk:
2811 case X86::V4FMADDSSrmkz:
2812 case X86::V4FNMADDPSrm:
2813 case X86::V4FNMADDPSrmk:
2814 case X86::V4FNMADDPSrmkz:
2815 case X86::V4FNMADDSSrm:
2816 case X86::V4FNMADDSSrmk:
2817 case X86::V4FNMADDSSrmkz:
2818 case X86::VP4DPWSSDSrm:
2819 case X86::VP4DPWSSDSrmk:
2820 case X86::VP4DPWSSDSrmkz:
2821 case X86::VP4DPWSSDrm:
2822 case X86::VP4DPWSSDrmk:
2823 case X86::VP4DPWSSDrmkz: {
2824 unsigned Src2 = Inst.getOperand(Inst.getNumOperands() -
2825 X86::AddrNumOperands - 1).getReg();
2826 unsigned Src2Enc = MRI->getEncodingValue(Src2);
2827 if (Src2Enc % 4 != 0) {
2828 StringRef RegName = X86IntelInstPrinter::getRegisterName(Src2);
2829 unsigned GroupStart = (Src2Enc / 4) * 4;
2830 unsigned GroupEnd = GroupStart + 3;
2831 return Warning(Ops[0]->getStartLoc(),
2832 "source register '" + RegName + "' implicitly denotes '" +
2833 RegName.take_front(3) + Twine(GroupStart) + "' to '" +
2834 RegName.take_front(3) + Twine(GroupEnd) +
2844 static const char *getSubtargetFeatureName(uint64_t Val);
2846 void X86AsmParser::EmitInstruction(MCInst &Inst, OperandVector &Operands,
2848 Instrumentation->InstrumentAndEmitInstruction(
2849 Inst, Operands, getContext(), MII, Out,
2850 getParser().shouldPrintSchedInfo());
2853 bool X86AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2854 OperandVector &Operands,
2855 MCStreamer &Out, uint64_t &ErrorInfo,
2856 bool MatchingInlineAsm) {
2857 if (isParsingIntelSyntax())
2858 return MatchAndEmitIntelInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2860 return MatchAndEmitATTInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2864 void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op,
2865 OperandVector &Operands, MCStreamer &Out,
2866 bool MatchingInlineAsm) {
2867 // FIXME: This should be replaced with a real .td file alias mechanism.
2868 // Also, MatchInstructionImpl should actually *do* the EmitInstruction
2870 const char *Repl = StringSwitch<const char *>(Op.getToken())
2871 .Case("finit", "fninit")
2872 .Case("fsave", "fnsave")
2873 .Case("fstcw", "fnstcw")
2874 .Case("fstcww", "fnstcw")
2875 .Case("fstenv", "fnstenv")
2876 .Case("fstsw", "fnstsw")
2877 .Case("fstsww", "fnstsw")
2878 .Case("fclex", "fnclex")
2882 Inst.setOpcode(X86::WAIT);
2884 if (!MatchingInlineAsm)
2885 EmitInstruction(Inst, Operands, Out);
2886 Operands[0] = X86Operand::CreateToken(Repl, IDLoc);
2890 bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
2891 bool MatchingInlineAsm) {
2892 assert(ErrorInfo && "Unknown missing feature!");
2893 SmallString<126> Msg;
2894 raw_svector_ostream OS(Msg);
2895 OS << "instruction requires:";
2897 for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
2898 if (ErrorInfo & Mask)
2899 OS << ' ' << getSubtargetFeatureName(ErrorInfo & Mask);
2902 return Error(IDLoc, OS.str(), SMRange(), MatchingInlineAsm);
2905 static unsigned getPrefixes(OperandVector &Operands) {
2906 unsigned Result = 0;
2907 X86Operand &Prefix = static_cast<X86Operand &>(*Operands.back());
2908 if (Prefix.isPrefix()) {
2909 Result = Prefix.getPrefix();
2910 Operands.pop_back();
2915 bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
2916 OperandVector &Operands,
2918 uint64_t &ErrorInfo,
2919 bool MatchingInlineAsm) {
2920 assert(!Operands.empty() && "Unexpect empty operand list!");
2921 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2922 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
2923 SMRange EmptyRange = None;
2925 // First, handle aliases that expand to multiple instructions.
2926 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2928 bool WasOriginallyInvalidOperand = false;
2929 unsigned Prefixes = getPrefixes(Operands);
2934 Inst.setFlags(Prefixes);
2936 // First, try a direct match.
2937 switch (MatchInstruction(Operands, Inst, ErrorInfo, MatchingInlineAsm,
2938 isParsingIntelSyntax())) {
2939 default: llvm_unreachable("Unexpected match result!");
2941 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
2943 // Some instructions need post-processing to, for example, tweak which
2944 // encoding is selected. Loop on it while changes happen so the
2945 // individual transformations can chain off each other.
2946 if (!MatchingInlineAsm)
2947 while (processInstruction(Inst, Operands))
2951 if (!MatchingInlineAsm)
2952 EmitInstruction(Inst, Operands, Out);
2953 Opcode = Inst.getOpcode();
2955 case Match_MissingFeature:
2956 return ErrorMissingFeature(IDLoc, ErrorInfo, MatchingInlineAsm);
2957 case Match_InvalidOperand:
2958 WasOriginallyInvalidOperand = true;
2960 case Match_MnemonicFail:
2964 // FIXME: Ideally, we would only attempt suffix matches for things which are
2965 // valid prefixes, and we could just infer the right unambiguous
2966 // type. However, that requires substantially more matcher support than the
2969 // Change the operand to point to a temporary token.
2970 StringRef Base = Op.getToken();
2971 SmallString<16> Tmp;
2974 Op.setTokenValue(Tmp);
2976 // If this instruction starts with an 'f', then it is a floating point stack
2977 // instruction. These come in up to three forms for 32-bit, 64-bit, and
2978 // 80-bit floating point, which use the suffixes s,l,t respectively.
2980 // Otherwise, we assume that this may be an integer instruction, which comes
2981 // in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively.
2982 const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0";
2984 // Check for the various suffix matches.
2985 uint64_t ErrorInfoIgnore;
2986 uint64_t ErrorInfoMissingFeature = 0; // Init suppresses compiler warnings.
2989 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I) {
2990 Tmp.back() = Suffixes[I];
2991 Match[I] = MatchInstruction(Operands, Inst, ErrorInfoIgnore,
2992 MatchingInlineAsm, isParsingIntelSyntax());
2993 // If this returned as a missing feature failure, remember that.
2994 if (Match[I] == Match_MissingFeature)
2995 ErrorInfoMissingFeature = ErrorInfoIgnore;
2998 // Restore the old token.
2999 Op.setTokenValue(Base);
3001 // If exactly one matched, then we treat that as a successful match (and the
3002 // instruction will already have been filled in correctly, since the failing
3003 // matches won't have modified it).
3004 unsigned NumSuccessfulMatches =
3005 std::count(std::begin(Match), std::end(Match), Match_Success);
3006 if (NumSuccessfulMatches == 1) {
3008 if (!MatchingInlineAsm)
3009 EmitInstruction(Inst, Operands, Out);
3010 Opcode = Inst.getOpcode();
3014 // Otherwise, the match failed, try to produce a decent error message.
3016 // If we had multiple suffix matches, then identify this as an ambiguous
3018 if (NumSuccessfulMatches > 1) {
3020 unsigned NumMatches = 0;
3021 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I)
3022 if (Match[I] == Match_Success)
3023 MatchChars[NumMatches++] = Suffixes[I];
3025 SmallString<126> Msg;
3026 raw_svector_ostream OS(Msg);
3027 OS << "ambiguous instructions require an explicit suffix (could be ";
3028 for (unsigned i = 0; i != NumMatches; ++i) {
3031 if (i + 1 == NumMatches)
3033 OS << "'" << Base << MatchChars[i] << "'";
3036 Error(IDLoc, OS.str(), EmptyRange, MatchingInlineAsm);
3040 // Okay, we know that none of the variants matched successfully.
3042 // If all of the instructions reported an invalid mnemonic, then the original
3043 // mnemonic was invalid.
3044 if (std::count(std::begin(Match), std::end(Match), Match_MnemonicFail) == 4) {
3045 if (!WasOriginallyInvalidOperand) {
3046 return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'",
3047 Op.getLocRange(), MatchingInlineAsm);
3050 // Recover location info for the operand if we know which was the problem.
3051 if (ErrorInfo != ~0ULL) {
3052 if (ErrorInfo >= Operands.size())
3053 return Error(IDLoc, "too few operands for instruction", EmptyRange,
3056 X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo];
3057 if (Operand.getStartLoc().isValid()) {
3058 SMRange OperandRange = Operand.getLocRange();
3059 return Error(Operand.getStartLoc(), "invalid operand for instruction",
3060 OperandRange, MatchingInlineAsm);
3064 return Error(IDLoc, "invalid operand for instruction", EmptyRange,
3068 // If one instruction matched with a missing feature, report this as a
3070 if (std::count(std::begin(Match), std::end(Match),
3071 Match_MissingFeature) == 1) {
3072 ErrorInfo = ErrorInfoMissingFeature;
3073 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
3077 // If one instruction matched with an invalid operand, report this as an
3079 if (std::count(std::begin(Match), std::end(Match),
3080 Match_InvalidOperand) == 1) {
3081 return Error(IDLoc, "invalid operand for instruction", EmptyRange,
3085 // If all of these were an outright failure, report it in a useless way.
3086 Error(IDLoc, "unknown use of instruction mnemonic without a size suffix",
3087 EmptyRange, MatchingInlineAsm);
3091 bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
3092 OperandVector &Operands,
3094 uint64_t &ErrorInfo,
3095 bool MatchingInlineAsm) {
3096 assert(!Operands.empty() && "Unexpect empty operand list!");
3097 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
3098 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
3099 StringRef Mnemonic = Op.getToken();
3100 SMRange EmptyRange = None;
3101 StringRef Base = Op.getToken();
3102 unsigned Prefixes = getPrefixes(Operands);
3104 // First, handle aliases that expand to multiple instructions.
3105 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
3110 Inst.setFlags(Prefixes);
3112 // Find one unsized memory operand, if present.
3113 X86Operand *UnsizedMemOp = nullptr;
3114 for (const auto &Op : Operands) {
3115 X86Operand *X86Op = static_cast<X86Operand *>(Op.get());
3116 if (X86Op->isMemUnsized()) {
3117 UnsizedMemOp = X86Op;
3118 // Have we found an unqualified memory operand,
3119 // break. IA allows only one memory operand.
3124 // Allow some instructions to have implicitly pointer-sized operands. This is
3125 // compatible with gas.
3127 static const char *const PtrSizedInstrs[] = {"call", "jmp", "push"};
3128 for (const char *Instr : PtrSizedInstrs) {
3129 if (Mnemonic == Instr) {
3130 UnsizedMemOp->Mem.Size = getPointerWidth();
3136 SmallVector<unsigned, 8> Match;
3137 uint64_t ErrorInfoMissingFeature = 0;
3139 // If unsized push has immediate operand we should default the default pointer
3140 // size for the size.
3141 if (Mnemonic == "push" && Operands.size() == 2) {
3142 auto *X86Op = static_cast<X86Operand *>(Operands[1].get());
3143 if (X86Op->isImm()) {
3144 // If it's not a constant fall through and let remainder take care of it.
3145 const auto *CE = dyn_cast<MCConstantExpr>(X86Op->getImm());
3146 unsigned Size = getPointerWidth();
3148 (isIntN(Size, CE->getValue()) || isUIntN(Size, CE->getValue()))) {
3149 SmallString<16> Tmp;
3151 Tmp += (is64BitMode())
3153 : (is32BitMode()) ? "l" : (is16BitMode()) ? "w" : " ";
3154 Op.setTokenValue(Tmp);
3155 // Do match in ATT mode to allow explicit suffix usage.
3156 Match.push_back(MatchInstruction(Operands, Inst, ErrorInfo,
3158 false /*isParsingIntelSyntax()*/));
3159 Op.setTokenValue(Base);
3164 // If an unsized memory operand is present, try to match with each memory
3165 // operand size. In Intel assembly, the size is not part of the instruction
3167 if (UnsizedMemOp && UnsizedMemOp->isMemUnsized()) {
3168 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
3169 for (unsigned Size : MopSizes) {
3170 UnsizedMemOp->Mem.Size = Size;
3171 uint64_t ErrorInfoIgnore;
3172 unsigned LastOpcode = Inst.getOpcode();
3173 unsigned M = MatchInstruction(Operands, Inst, ErrorInfoIgnore,
3174 MatchingInlineAsm, isParsingIntelSyntax());
3175 if (Match.empty() || LastOpcode != Inst.getOpcode())
3178 // If this returned as a missing feature failure, remember that.
3179 if (Match.back() == Match_MissingFeature)
3180 ErrorInfoMissingFeature = ErrorInfoIgnore;
3183 // Restore the size of the unsized memory operand if we modified it.
3184 UnsizedMemOp->Mem.Size = 0;
3187 // If we haven't matched anything yet, this is not a basic integer or FPU
3188 // operation. There shouldn't be any ambiguity in our mnemonic table, so try
3189 // matching with the unsized operand.
3190 if (Match.empty()) {
3191 Match.push_back(MatchInstruction(
3192 Operands, Inst, ErrorInfo, MatchingInlineAsm, isParsingIntelSyntax()));
3193 // If this returned as a missing feature failure, remember that.
3194 if (Match.back() == Match_MissingFeature)
3195 ErrorInfoMissingFeature = ErrorInfo;
3198 // Restore the size of the unsized memory operand if we modified it.
3200 UnsizedMemOp->Mem.Size = 0;
3202 // If it's a bad mnemonic, all results will be the same.
3203 if (Match.back() == Match_MnemonicFail) {
3204 return Error(IDLoc, "invalid instruction mnemonic '" + Mnemonic + "'",
3205 Op.getLocRange(), MatchingInlineAsm);
3208 unsigned NumSuccessfulMatches =
3209 std::count(std::begin(Match), std::end(Match), Match_Success);
3211 // If matching was ambiguous and we had size information from the frontend,
3212 // try again with that. This handles cases like "movxz eax, m8/m16".
3213 if (UnsizedMemOp && NumSuccessfulMatches > 1 &&
3214 UnsizedMemOp->getMemFrontendSize()) {
3215 UnsizedMemOp->Mem.Size = UnsizedMemOp->getMemFrontendSize();
3216 unsigned M = MatchInstruction(
3217 Operands, Inst, ErrorInfo, MatchingInlineAsm, isParsingIntelSyntax());
3218 if (M == Match_Success)
3219 NumSuccessfulMatches = 1;
3221 // Add a rewrite that encodes the size information we used from the
3223 InstInfo->AsmRewrites->emplace_back(
3224 AOK_SizeDirective, UnsizedMemOp->getStartLoc(),
3225 /*Len=*/0, UnsizedMemOp->getMemFrontendSize());
3228 // If exactly one matched, then we treat that as a successful match (and the
3229 // instruction will already have been filled in correctly, since the failing
3230 // matches won't have modified it).
3231 if (NumSuccessfulMatches == 1) {
3232 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
3234 // Some instructions need post-processing to, for example, tweak which
3235 // encoding is selected. Loop on it while changes happen so the individual
3236 // transformations can chain off each other.
3237 if (!MatchingInlineAsm)
3238 while (processInstruction(Inst, Operands))
3241 if (!MatchingInlineAsm)
3242 EmitInstruction(Inst, Operands, Out);
3243 Opcode = Inst.getOpcode();
3245 } else if (NumSuccessfulMatches > 1) {
3246 assert(UnsizedMemOp &&
3247 "multiple matches only possible with unsized memory operands");
3248 return Error(UnsizedMemOp->getStartLoc(),
3249 "ambiguous operand size for instruction '" + Mnemonic + "\'",
3250 UnsizedMemOp->getLocRange());
3253 // If one instruction matched with a missing feature, report this as a
3255 if (std::count(std::begin(Match), std::end(Match),
3256 Match_MissingFeature) == 1) {
3257 ErrorInfo = ErrorInfoMissingFeature;
3258 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
3262 // If one instruction matched with an invalid operand, report this as an
3264 if (std::count(std::begin(Match), std::end(Match),
3265 Match_InvalidOperand) == 1) {
3266 return Error(IDLoc, "invalid operand for instruction", EmptyRange,
3270 // If all of these were an outright failure, report it in a useless way.
3271 return Error(IDLoc, "unknown instruction mnemonic", EmptyRange,
3275 bool X86AsmParser::OmitRegisterFromClobberLists(unsigned RegNo) {
3276 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo);
3279 bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
3280 MCAsmParser &Parser = getParser();
3281 StringRef IDVal = DirectiveID.getIdentifier();
3282 if (IDVal.startswith(".code"))
3283 return ParseDirectiveCode(IDVal, DirectiveID.getLoc());
3284 else if (IDVal.startswith(".att_syntax")) {
3285 getParser().setParsingInlineAsm(false);
3286 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3287 if (Parser.getTok().getString() == "prefix")
3289 else if (Parser.getTok().getString() == "noprefix")
3290 return Error(DirectiveID.getLoc(), "'.att_syntax noprefix' is not "
3291 "supported: registers must have a "
3292 "'%' prefix in .att_syntax");
3294 getParser().setAssemblerDialect(0);
3296 } else if (IDVal.startswith(".intel_syntax")) {
3297 getParser().setAssemblerDialect(1);
3298 getParser().setParsingInlineAsm(true);
3299 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3300 if (Parser.getTok().getString() == "noprefix")
3302 else if (Parser.getTok().getString() == "prefix")
3303 return Error(DirectiveID.getLoc(), "'.intel_syntax prefix' is not "
3304 "supported: registers must not have "
3305 "a '%' prefix in .intel_syntax");
3308 } else if (IDVal == ".even")
3309 return parseDirectiveEven(DirectiveID.getLoc());
3310 else if (IDVal == ".cv_fpo_proc")
3311 return parseDirectiveFPOProc(DirectiveID.getLoc());
3312 else if (IDVal == ".cv_fpo_setframe")
3313 return parseDirectiveFPOSetFrame(DirectiveID.getLoc());
3314 else if (IDVal == ".cv_fpo_pushreg")
3315 return parseDirectiveFPOPushReg(DirectiveID.getLoc());
3316 else if (IDVal == ".cv_fpo_stackalloc")
3317 return parseDirectiveFPOStackAlloc(DirectiveID.getLoc());
3318 else if (IDVal == ".cv_fpo_endprologue")
3319 return parseDirectiveFPOEndPrologue(DirectiveID.getLoc());
3320 else if (IDVal == ".cv_fpo_endproc")
3321 return parseDirectiveFPOEndProc(DirectiveID.getLoc());
3326 /// parseDirectiveEven
3328 bool X86AsmParser::parseDirectiveEven(SMLoc L) {
3329 if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive"))
3332 const MCSection *Section = getStreamer().getCurrentSectionOnly();
3334 getStreamer().InitSections(false);
3335 Section = getStreamer().getCurrentSectionOnly();
3337 if (Section->UseCodeAlign())
3338 getStreamer().EmitCodeAlignment(2, 0);
3340 getStreamer().EmitValueToAlignment(2, 0, 1, 0);
3344 /// ParseDirectiveCode
3345 /// ::= .code16 | .code32 | .code64
3346 bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
3347 MCAsmParser &Parser = getParser();
3349 if (IDVal == ".code16") {
3351 if (!is16BitMode()) {
3352 SwitchMode(X86::Mode16Bit);
3353 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
3355 } else if (IDVal == ".code16gcc") {
3356 // .code16gcc parses as if in 32-bit mode, but emits code in 16-bit mode.
3359 if (!is16BitMode()) {
3360 SwitchMode(X86::Mode16Bit);
3361 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
3363 } else if (IDVal == ".code32") {
3365 if (!is32BitMode()) {
3366 SwitchMode(X86::Mode32Bit);
3367 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
3369 } else if (IDVal == ".code64") {
3371 if (!is64BitMode()) {
3372 SwitchMode(X86::Mode64Bit);
3373 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code64);
3376 Error(L, "unknown directive " + IDVal);
3384 bool X86AsmParser::parseDirectiveFPOProc(SMLoc L) {
3385 MCAsmParser &Parser = getParser();
3388 if (Parser.parseIdentifier(ProcName))
3389 return Parser.TokError("expected symbol name");
3390 if (Parser.parseIntToken(ParamsSize, "expected parameter byte count"))
3392 if (!isUIntN(32, ParamsSize))
3393 return Parser.TokError("parameters size out of range");
3394 if (Parser.parseEOL("unexpected tokens"))
3395 return addErrorSuffix(" in '.cv_fpo_proc' directive");
3396 MCSymbol *ProcSym = getContext().getOrCreateSymbol(ProcName);
3397 return getTargetStreamer().emitFPOProc(ProcSym, ParamsSize, L);
3400 // .cv_fpo_setframe ebp
3401 bool X86AsmParser::parseDirectiveFPOSetFrame(SMLoc L) {
3402 MCAsmParser &Parser = getParser();
3405 if (ParseRegister(Reg, DummyLoc, DummyLoc) ||
3406 Parser.parseEOL("unexpected tokens"))
3407 return addErrorSuffix(" in '.cv_fpo_setframe' directive");
3408 return getTargetStreamer().emitFPOSetFrame(Reg, L);
3411 // .cv_fpo_pushreg ebx
3412 bool X86AsmParser::parseDirectiveFPOPushReg(SMLoc L) {
3413 MCAsmParser &Parser = getParser();
3416 if (ParseRegister(Reg, DummyLoc, DummyLoc) ||
3417 Parser.parseEOL("unexpected tokens"))
3418 return addErrorSuffix(" in '.cv_fpo_pushreg' directive");
3419 return getTargetStreamer().emitFPOPushReg(Reg, L);
3422 // .cv_fpo_stackalloc 20
3423 bool X86AsmParser::parseDirectiveFPOStackAlloc(SMLoc L) {
3424 MCAsmParser &Parser = getParser();
3426 if (Parser.parseIntToken(Offset, "expected offset") ||
3427 Parser.parseEOL("unexpected tokens"))
3428 return addErrorSuffix(" in '.cv_fpo_stackalloc' directive");
3429 return getTargetStreamer().emitFPOStackAlloc(Offset, L);
3432 // .cv_fpo_endprologue
3433 bool X86AsmParser::parseDirectiveFPOEndPrologue(SMLoc L) {
3434 MCAsmParser &Parser = getParser();
3435 if (Parser.parseEOL("unexpected tokens"))
3436 return addErrorSuffix(" in '.cv_fpo_endprologue' directive");
3437 return getTargetStreamer().emitFPOEndPrologue(L);
3441 bool X86AsmParser::parseDirectiveFPOEndProc(SMLoc L) {
3442 MCAsmParser &Parser = getParser();
3443 if (Parser.parseEOL("unexpected tokens"))
3444 return addErrorSuffix(" in '.cv_fpo_endproc' directive");
3445 return getTargetStreamer().emitFPOEndProc(L);
3448 // Force static initialization.
3449 extern "C" void LLVMInitializeX86AsmParser() {
3450 RegisterMCAsmParser<X86AsmParser> X(getTheX86_32Target());
3451 RegisterMCAsmParser<X86AsmParser> Y(getTheX86_64Target());
3454 #define GET_REGISTER_MATCHER
3455 #define GET_MATCHER_IMPLEMENTATION
3456 #define GET_SUBTARGET_FEATURE_NAME
3457 #include "X86GenAsmMatcher.inc"