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/X86TargetStreamer.h"
13 #include "X86AsmInstrumentation.h"
14 #include "X86AsmParserCommon.h"
15 #include "X86Operand.h"
16 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/ADT/SmallString.h"
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/ADT/StringSwitch.h"
20 #include "llvm/ADT/Twine.h"
21 #include "llvm/MC/MCContext.h"
22 #include "llvm/MC/MCExpr.h"
23 #include "llvm/MC/MCInst.h"
24 #include "llvm/MC/MCInstrInfo.h"
25 #include "llvm/MC/MCParser/MCAsmLexer.h"
26 #include "llvm/MC/MCParser/MCAsmParser.h"
27 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
28 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
29 #include "llvm/MC/MCRegisterInfo.h"
30 #include "llvm/MC/MCSection.h"
31 #include "llvm/MC/MCStreamer.h"
32 #include "llvm/MC/MCSubtargetInfo.h"
33 #include "llvm/MC/MCSymbol.h"
34 #include "llvm/Support/SourceMgr.h"
35 #include "llvm/Support/TargetRegistry.h"
36 #include "llvm/Support/raw_ostream.h"
42 static bool checkScale(unsigned Scale, StringRef &ErrMsg) {
43 if (Scale != 1 && Scale != 2 && Scale != 4 && Scale != 8) {
44 ErrMsg = "scale factor in address must be 1, 2, 4 or 8";
52 static const char OpPrecedence[] = {
71 class X86AsmParser : public MCTargetAsmParser {
72 ParseInstructionInfo *InstInfo;
73 std::unique_ptr<X86AsmInstrumentation> Instrumentation;
77 SMLoc consumeToken() {
78 MCAsmParser &Parser = getParser();
79 SMLoc Result = Parser.getTok().getLoc();
84 X86TargetStreamer &getTargetStreamer() {
85 assert(getParser().getStreamer().getTargetStreamer() &&
86 "do not have a target streamer");
87 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
88 return static_cast<X86TargetStreamer &>(TS);
91 unsigned MatchInstruction(const OperandVector &Operands, MCInst &Inst,
92 uint64_t &ErrorInfo, bool matchingInlineAsm,
93 unsigned VariantID = 0) {
94 // In Code16GCC mode, match as 32-bit.
96 SwitchMode(X86::Mode32Bit);
97 unsigned rv = MatchInstructionImpl(Operands, Inst, ErrorInfo,
98 matchingInlineAsm, VariantID);
100 SwitchMode(X86::Mode16Bit);
104 enum InfixCalculatorTok {
123 enum IntelOperatorKind {
131 class InfixCalculator {
132 typedef std::pair< InfixCalculatorTok, int64_t > ICToken;
133 SmallVector<InfixCalculatorTok, 4> InfixOperatorStack;
134 SmallVector<ICToken, 4> PostfixStack;
136 bool isUnaryOperator(const InfixCalculatorTok Op) {
137 return Op == IC_NEG || Op == IC_NOT;
141 int64_t popOperand() {
142 assert (!PostfixStack.empty() && "Poped an empty stack!");
143 ICToken Op = PostfixStack.pop_back_val();
144 if (!(Op.first == IC_IMM || Op.first == IC_REGISTER))
145 return -1; // The invalid Scale value will be caught later by checkScale
148 void pushOperand(InfixCalculatorTok Op, int64_t Val = 0) {
149 assert ((Op == IC_IMM || Op == IC_REGISTER) &&
150 "Unexpected operand!");
151 PostfixStack.push_back(std::make_pair(Op, Val));
154 void popOperator() { InfixOperatorStack.pop_back(); }
155 void pushOperator(InfixCalculatorTok Op) {
156 // Push the new operator if the stack is empty.
157 if (InfixOperatorStack.empty()) {
158 InfixOperatorStack.push_back(Op);
162 // Push the new operator if it has a higher precedence than the operator
163 // on the top of the stack or the operator on the top of the stack is a
165 unsigned Idx = InfixOperatorStack.size() - 1;
166 InfixCalculatorTok StackOp = InfixOperatorStack[Idx];
167 if (OpPrecedence[Op] > OpPrecedence[StackOp] || StackOp == IC_LPAREN) {
168 InfixOperatorStack.push_back(Op);
172 // The operator on the top of the stack has higher precedence than the
174 unsigned ParenCount = 0;
176 // Nothing to process.
177 if (InfixOperatorStack.empty())
180 Idx = InfixOperatorStack.size() - 1;
181 StackOp = InfixOperatorStack[Idx];
182 if (!(OpPrecedence[StackOp] >= OpPrecedence[Op] || ParenCount))
185 // If we have an even parentheses count and we see a left parentheses,
186 // then stop processing.
187 if (!ParenCount && StackOp == IC_LPAREN)
190 if (StackOp == IC_RPAREN) {
192 InfixOperatorStack.pop_back();
193 } else if (StackOp == IC_LPAREN) {
195 InfixOperatorStack.pop_back();
197 InfixOperatorStack.pop_back();
198 PostfixStack.push_back(std::make_pair(StackOp, 0));
201 // Push the new operator.
202 InfixOperatorStack.push_back(Op);
206 // Push any remaining operators onto the postfix stack.
207 while (!InfixOperatorStack.empty()) {
208 InfixCalculatorTok StackOp = InfixOperatorStack.pop_back_val();
209 if (StackOp != IC_LPAREN && StackOp != IC_RPAREN)
210 PostfixStack.push_back(std::make_pair(StackOp, 0));
213 if (PostfixStack.empty())
216 SmallVector<ICToken, 16> OperandStack;
217 for (unsigned i = 0, e = PostfixStack.size(); i != e; ++i) {
218 ICToken Op = PostfixStack[i];
219 if (Op.first == IC_IMM || Op.first == IC_REGISTER) {
220 OperandStack.push_back(Op);
221 } else if (isUnaryOperator(Op.first)) {
222 assert (OperandStack.size() > 0 && "Too few operands.");
223 ICToken Operand = OperandStack.pop_back_val();
224 assert (Operand.first == IC_IMM &&
225 "Unary operation with a register!");
228 report_fatal_error("Unexpected operator!");
231 OperandStack.push_back(std::make_pair(IC_IMM, -Operand.second));
234 OperandStack.push_back(std::make_pair(IC_IMM, ~Operand.second));
238 assert (OperandStack.size() > 1 && "Too few operands.");
240 ICToken Op2 = OperandStack.pop_back_val();
241 ICToken Op1 = OperandStack.pop_back_val();
244 report_fatal_error("Unexpected operator!");
247 Val = Op1.second + Op2.second;
248 OperandStack.push_back(std::make_pair(IC_IMM, Val));
251 Val = Op1.second - Op2.second;
252 OperandStack.push_back(std::make_pair(IC_IMM, Val));
255 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
256 "Multiply operation with an immediate and a register!");
257 Val = Op1.second * Op2.second;
258 OperandStack.push_back(std::make_pair(IC_IMM, Val));
261 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
262 "Divide operation with an immediate and a register!");
263 assert (Op2.second != 0 && "Division by zero!");
264 Val = Op1.second / Op2.second;
265 OperandStack.push_back(std::make_pair(IC_IMM, Val));
268 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
269 "Modulo operation with an immediate and a register!");
270 Val = Op1.second % Op2.second;
271 OperandStack.push_back(std::make_pair(IC_IMM, Val));
274 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
275 "Or operation with an immediate and a register!");
276 Val = Op1.second | Op2.second;
277 OperandStack.push_back(std::make_pair(IC_IMM, Val));
280 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
281 "Xor operation with an immediate and a register!");
282 Val = Op1.second ^ Op2.second;
283 OperandStack.push_back(std::make_pair(IC_IMM, Val));
286 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
287 "And operation with an immediate and a register!");
288 Val = Op1.second & Op2.second;
289 OperandStack.push_back(std::make_pair(IC_IMM, Val));
292 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
293 "Left shift operation with an immediate and a register!");
294 Val = Op1.second << Op2.second;
295 OperandStack.push_back(std::make_pair(IC_IMM, Val));
298 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
299 "Right shift operation with an immediate and a register!");
300 Val = Op1.second >> Op2.second;
301 OperandStack.push_back(std::make_pair(IC_IMM, Val));
306 assert (OperandStack.size() == 1 && "Expected a single result.");
307 return OperandStack.pop_back_val().second;
311 enum IntelExprState {
334 class IntelExprStateMachine {
335 IntelExprState State, PrevState;
336 unsigned BaseReg, IndexReg, TmpReg, Scale;
341 InlineAsmIdentifierInfo Info;
346 IntelExprStateMachine()
347 : State(IES_INIT), PrevState(IES_ERROR), BaseReg(0), IndexReg(0),
348 TmpReg(0), Scale(1), Imm(0), Sym(nullptr), BracCount(0),
351 void addImm(int64_t imm) { Imm += imm; }
352 short getBracCount() { return BracCount; }
353 bool isMemExpr() { return MemExpr; }
354 unsigned getBaseReg() { return BaseReg; }
355 unsigned getIndexReg() { return IndexReg; }
356 unsigned getScale() { return Scale; }
357 const MCExpr *getSym() { return Sym; }
358 StringRef getSymName() { return SymName; }
359 int64_t getImm() { return Imm + IC.execute(); }
360 bool isValidEndState() {
361 return State == IES_RBRAC || State == IES_INTEGER;
363 bool hadError() { return State == IES_ERROR; }
364 InlineAsmIdentifierInfo &getIdentifierInfo() { return Info; }
367 IntelExprState CurrState = State;
376 IC.pushOperator(IC_OR);
379 PrevState = CurrState;
382 IntelExprState CurrState = State;
391 IC.pushOperator(IC_XOR);
394 PrevState = CurrState;
397 IntelExprState CurrState = State;
406 IC.pushOperator(IC_AND);
409 PrevState = CurrState;
412 IntelExprState CurrState = State;
421 IC.pushOperator(IC_LSHIFT);
424 PrevState = CurrState;
427 IntelExprState CurrState = State;
436 IC.pushOperator(IC_RSHIFT);
439 PrevState = CurrState;
441 bool onPlus(StringRef &ErrMsg) {
442 IntelExprState CurrState = State;
451 IC.pushOperator(IC_PLUS);
452 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
453 // If we already have a BaseReg, then assume this is the IndexReg with
459 ErrMsg = "BaseReg/IndexReg already set!";
468 PrevState = CurrState;
471 bool onMinus(StringRef &ErrMsg) {
472 IntelExprState CurrState = State;
495 // push minus operator if it is not a negate operator
496 if (CurrState == IES_REGISTER || CurrState == IES_RPAREN ||
497 CurrState == IES_INTEGER || CurrState == IES_RBRAC)
498 IC.pushOperator(IC_MINUS);
499 else if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
500 // We have negate operator for Scale: it's illegal
501 ErrMsg = "Scale can't be negative";
504 IC.pushOperator(IC_NEG);
505 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
506 // If we already have a BaseReg, then assume this is the IndexReg with
512 ErrMsg = "BaseReg/IndexReg already set!";
521 PrevState = CurrState;
525 IntelExprState CurrState = State;
545 IC.pushOperator(IC_NOT);
548 PrevState = CurrState;
551 bool onRegister(unsigned Reg, StringRef &ErrMsg) {
552 IntelExprState CurrState = State;
560 State = IES_REGISTER;
562 IC.pushOperand(IC_REGISTER);
565 // Index Register - Scale * Register
566 if (PrevState == IES_INTEGER) {
568 ErrMsg = "BaseReg/IndexReg already set!";
571 State = IES_REGISTER;
573 // Get the scale and replace the 'Scale * Register' with '0'.
574 Scale = IC.popOperand();
575 if (checkScale(Scale, ErrMsg))
577 IC.pushOperand(IC_IMM);
584 PrevState = CurrState;
587 bool onIdentifierExpr(const MCExpr *SymRef, StringRef SymRefName,
588 const InlineAsmIdentifierInfo &IDInfo,
589 bool ParsingInlineAsm, StringRef &ErrMsg) {
590 // InlineAsm: Treat an enum value as an integer
591 if (ParsingInlineAsm)
592 if (IDInfo.isKind(InlineAsmIdentifierInfo::IK_EnumVal))
593 return onInteger(IDInfo.Enum.EnumVal, ErrMsg);
594 // Treat a symbolic constant like an integer
595 if (auto *CE = dyn_cast<MCConstantExpr>(SymRef))
596 return onInteger(CE->getValue(), ErrMsg);
598 bool HasSymbol = Sym != nullptr;
611 SymName = SymRefName;
612 IC.pushOperand(IC_IMM);
613 if (ParsingInlineAsm)
618 ErrMsg = "cannot use more than one symbol in memory operand";
621 bool onInteger(int64_t TmpInt, StringRef &ErrMsg) {
622 IntelExprState CurrState = State;
642 if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
643 // Index Register - Register * Scale
645 ErrMsg = "BaseReg/IndexReg already set!";
650 if (checkScale(Scale, ErrMsg))
652 // Get the scale and replace the 'Register * Scale' with '0'.
655 IC.pushOperand(IC_IMM, TmpInt);
659 PrevState = CurrState;
671 State = IES_MULTIPLY;
672 IC.pushOperator(IC_MULTIPLY);
685 IC.pushOperator(IC_DIVIDE);
698 IC.pushOperator(IC_MOD);
714 IC.pushOperator(IC_PLUS);
717 assert(!BracCount && "BracCount should be zero on parsing's start");
726 IntelExprState CurrState = State;
734 if (BracCount-- != 1)
737 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
738 // If we already have a BaseReg, then assume this is the IndexReg with
743 assert (!IndexReg && "BaseReg/IndexReg already set!");
750 PrevState = CurrState;
754 IntelExprState CurrState = State;
774 IC.pushOperator(IC_LPAREN);
777 PrevState = CurrState;
789 IC.pushOperator(IC_RPAREN);
795 bool Error(SMLoc L, const Twine &Msg, SMRange Range = None,
796 bool MatchingInlineAsm = false) {
797 MCAsmParser &Parser = getParser();
798 if (MatchingInlineAsm) {
799 if (!getLexer().isAtStartOfStatement())
800 Parser.eatToEndOfStatement();
803 return Parser.Error(L, Msg, Range);
806 std::nullptr_t ErrorOperand(SMLoc Loc, StringRef Msg) {
811 std::unique_ptr<X86Operand> DefaultMemSIOperand(SMLoc Loc);
812 std::unique_ptr<X86Operand> DefaultMemDIOperand(SMLoc Loc);
813 bool IsSIReg(unsigned Reg);
814 unsigned GetSIDIForRegClass(unsigned RegClassID, unsigned Reg, bool IsSIReg);
816 AddDefaultSrcDestOperands(OperandVector &Operands,
817 std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
818 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst);
819 bool VerifyAndAdjustOperands(OperandVector &OrigOperands,
820 OperandVector &FinalOperands);
821 std::unique_ptr<X86Operand> ParseOperand();
822 std::unique_ptr<X86Operand> ParseATTOperand();
823 std::unique_ptr<X86Operand> ParseIntelOperand();
824 std::unique_ptr<X86Operand> ParseIntelOffsetOfOperator();
825 bool ParseIntelDotOperator(IntelExprStateMachine &SM, SMLoc &End);
826 unsigned IdentifyIntelInlineAsmOperator(StringRef Name);
827 unsigned ParseIntelInlineAsmOperator(unsigned OpKind);
828 std::unique_ptr<X86Operand> ParseRoundingModeOp(SMLoc Start, SMLoc End);
829 bool ParseIntelNamedOperator(StringRef Name, IntelExprStateMachine &SM);
830 void RewriteIntelExpression(IntelExprStateMachine &SM, SMLoc Start,
832 bool ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End);
833 bool ParseIntelInlineAsmIdentifier(const MCExpr *&Val, StringRef &Identifier,
834 InlineAsmIdentifierInfo &Info,
835 bool IsUnevaluatedOperand, SMLoc &End);
837 std::unique_ptr<X86Operand> ParseMemOperand(unsigned SegReg, SMLoc StartLoc);
839 bool ParseIntelMemoryOperandSize(unsigned &Size);
840 std::unique_ptr<X86Operand>
841 CreateMemForInlineAsm(unsigned SegReg, const MCExpr *Disp, unsigned BaseReg,
842 unsigned IndexReg, unsigned Scale, SMLoc Start,
843 SMLoc End, unsigned Size, StringRef Identifier,
844 const InlineAsmIdentifierInfo &Info);
846 bool parseDirectiveEven(SMLoc L);
847 bool ParseDirectiveWord(unsigned Size, 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 // Initialize the set of available features.
947 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
948 Instrumentation.reset(
949 CreateX86AsmInstrumentation(Options, Parser.getContext(), STI));
952 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
954 void SetFrameRegister(unsigned RegNo) override;
956 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
957 SMLoc NameLoc, OperandVector &Operands) override;
959 bool ParseDirective(AsmToken DirectiveID) override;
961 } // end anonymous namespace
963 /// @name Auto-generated Match Functions
966 static unsigned MatchRegisterName(StringRef Name);
970 static bool CheckBaseRegAndIndexRegAndScale(unsigned BaseReg, unsigned IndexReg,
971 unsigned Scale, StringRef &ErrMsg) {
972 // If we have both a base register and an index register make sure they are
973 // both 64-bit or 32-bit registers.
974 // To support VSIB, IndexReg can be 128-bit or 256-bit registers.
976 if ((BaseReg == X86::RIP && IndexReg != 0) || (IndexReg == X86::RIP)) {
977 ErrMsg = "invalid base+index expression";
980 if (BaseReg != 0 && IndexReg != 0) {
981 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) &&
982 (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
983 X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg)) &&
984 IndexReg != X86::RIZ) {
985 ErrMsg = "base register is 64-bit, but index register is not";
988 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg) &&
989 (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
990 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) &&
991 IndexReg != X86::EIZ){
992 ErrMsg = "base register is 32-bit, but index register is not";
995 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg)) {
996 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg) ||
997 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) {
998 ErrMsg = "base register is 16-bit, but index register is not";
1001 if (((BaseReg == X86::BX || BaseReg == X86::BP) &&
1002 IndexReg != X86::SI && IndexReg != X86::DI) ||
1003 ((BaseReg == X86::SI || BaseReg == X86::DI) &&
1004 IndexReg != X86::BX && IndexReg != X86::BP)) {
1005 ErrMsg = "invalid 16-bit base/index register combination";
1010 return checkScale(Scale, ErrMsg);
1013 bool X86AsmParser::ParseRegister(unsigned &RegNo,
1014 SMLoc &StartLoc, SMLoc &EndLoc) {
1015 MCAsmParser &Parser = getParser();
1017 const AsmToken &PercentTok = Parser.getTok();
1018 StartLoc = PercentTok.getLoc();
1020 // If we encounter a %, ignore it. This code handles registers with and
1021 // without the prefix, unprefixed registers can occur in cfi directives.
1022 if (!isParsingIntelSyntax() && PercentTok.is(AsmToken::Percent))
1023 Parser.Lex(); // Eat percent token.
1025 const AsmToken &Tok = Parser.getTok();
1026 EndLoc = Tok.getEndLoc();
1028 if (Tok.isNot(AsmToken::Identifier)) {
1029 if (isParsingIntelSyntax()) return true;
1030 return Error(StartLoc, "invalid register name",
1031 SMRange(StartLoc, EndLoc));
1034 RegNo = MatchRegisterName(Tok.getString());
1036 // If the match failed, try the register name as lowercase.
1038 RegNo = MatchRegisterName(Tok.getString().lower());
1040 // The "flags" register cannot be referenced directly.
1041 // Treat it as an identifier instead.
1042 if (isParsingInlineAsm() && isParsingIntelSyntax() && RegNo == X86::EFLAGS)
1045 if (!is64BitMode()) {
1046 // FIXME: This should be done using Requires<Not64BitMode> and
1047 // Requires<In64BitMode> so "eiz" usage in 64-bit instructions can be also
1049 // FIXME: Check AH, CH, DH, BH cannot be used in an instruction requiring a
1051 if (RegNo == X86::RIZ ||
1052 X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo) ||
1053 X86II::isX86_64NonExtLowByteReg(RegNo) ||
1054 X86II::isX86_64ExtendedReg(RegNo))
1055 return Error(StartLoc, "register %"
1056 + Tok.getString() + " is only available in 64-bit mode",
1057 SMRange(StartLoc, EndLoc));
1058 } else if (!getSTI().getFeatureBits()[X86::FeatureAVX512]) {
1059 if (X86II::is32ExtendedReg(RegNo))
1060 return Error(StartLoc, "register %"
1061 + Tok.getString() + " is only available with AVX512",
1062 SMRange(StartLoc, EndLoc));
1065 // Parse "%st" as "%st(0)" and "%st(1)", which is multiple tokens.
1066 if (RegNo == 0 && (Tok.getString() == "st" || Tok.getString() == "ST")) {
1068 Parser.Lex(); // Eat 'st'
1070 // Check to see if we have '(4)' after %st.
1071 if (getLexer().isNot(AsmToken::LParen))
1076 const AsmToken &IntTok = Parser.getTok();
1077 if (IntTok.isNot(AsmToken::Integer))
1078 return Error(IntTok.getLoc(), "expected stack index");
1079 switch (IntTok.getIntVal()) {
1080 case 0: RegNo = X86::ST0; break;
1081 case 1: RegNo = X86::ST1; break;
1082 case 2: RegNo = X86::ST2; break;
1083 case 3: RegNo = X86::ST3; break;
1084 case 4: RegNo = X86::ST4; break;
1085 case 5: RegNo = X86::ST5; break;
1086 case 6: RegNo = X86::ST6; break;
1087 case 7: RegNo = X86::ST7; break;
1088 default: return Error(IntTok.getLoc(), "invalid stack index");
1091 if (getParser().Lex().isNot(AsmToken::RParen))
1092 return Error(Parser.getTok().getLoc(), "expected ')'");
1094 EndLoc = Parser.getTok().getEndLoc();
1095 Parser.Lex(); // Eat ')'
1099 EndLoc = Parser.getTok().getEndLoc();
1101 // If this is "db[0-15]", match it as an alias
1103 if (RegNo == 0 && Tok.getString().startswith("db")) {
1104 if (Tok.getString().size() == 3) {
1105 switch (Tok.getString()[2]) {
1106 case '0': RegNo = X86::DR0; break;
1107 case '1': RegNo = X86::DR1; break;
1108 case '2': RegNo = X86::DR2; break;
1109 case '3': RegNo = X86::DR3; break;
1110 case '4': RegNo = X86::DR4; break;
1111 case '5': RegNo = X86::DR5; break;
1112 case '6': RegNo = X86::DR6; break;
1113 case '7': RegNo = X86::DR7; break;
1114 case '8': RegNo = X86::DR8; break;
1115 case '9': RegNo = X86::DR9; break;
1117 } else if (Tok.getString().size() == 4 && Tok.getString()[2] == '1') {
1118 switch (Tok.getString()[3]) {
1119 case '0': RegNo = X86::DR10; break;
1120 case '1': RegNo = X86::DR11; break;
1121 case '2': RegNo = X86::DR12; break;
1122 case '3': RegNo = X86::DR13; break;
1123 case '4': RegNo = X86::DR14; break;
1124 case '5': RegNo = X86::DR15; break;
1129 EndLoc = Parser.getTok().getEndLoc();
1130 Parser.Lex(); // Eat it.
1136 if (isParsingIntelSyntax()) return true;
1137 return Error(StartLoc, "invalid register name",
1138 SMRange(StartLoc, EndLoc));
1141 Parser.Lex(); // Eat identifier token.
1145 void X86AsmParser::SetFrameRegister(unsigned RegNo) {
1146 Instrumentation->SetInitialFrameRegister(RegNo);
1149 std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(SMLoc Loc) {
1150 bool Parse32 = is32BitMode() || Code16GCC;
1151 unsigned Basereg = is64BitMode() ? X86::RSI : (Parse32 ? X86::ESI : X86::SI);
1152 const MCExpr *Disp = MCConstantExpr::create(0, getContext());
1153 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
1154 /*BaseReg=*/Basereg, /*IndexReg=*/0, /*Scale=*/1,
1158 std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand(SMLoc Loc) {
1159 bool Parse32 = is32BitMode() || Code16GCC;
1160 unsigned Basereg = is64BitMode() ? X86::RDI : (Parse32 ? X86::EDI : X86::DI);
1161 const MCExpr *Disp = MCConstantExpr::create(0, getContext());
1162 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
1163 /*BaseReg=*/Basereg, /*IndexReg=*/0, /*Scale=*/1,
1167 bool X86AsmParser::IsSIReg(unsigned Reg) {
1169 default: llvm_unreachable("Only (R|E)SI and (R|E)DI are expected!");
1181 unsigned X86AsmParser::GetSIDIForRegClass(unsigned RegClassID, unsigned Reg,
1183 switch (RegClassID) {
1184 default: llvm_unreachable("Unexpected register class");
1185 case X86::GR64RegClassID:
1186 return IsSIReg ? X86::RSI : X86::RDI;
1187 case X86::GR32RegClassID:
1188 return IsSIReg ? X86::ESI : X86::EDI;
1189 case X86::GR16RegClassID:
1190 return IsSIReg ? X86::SI : X86::DI;
1194 void X86AsmParser::AddDefaultSrcDestOperands(
1195 OperandVector& Operands, std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
1196 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst) {
1197 if (isParsingIntelSyntax()) {
1198 Operands.push_back(std::move(Dst));
1199 Operands.push_back(std::move(Src));
1202 Operands.push_back(std::move(Src));
1203 Operands.push_back(std::move(Dst));
1207 bool X86AsmParser::VerifyAndAdjustOperands(OperandVector &OrigOperands,
1208 OperandVector &FinalOperands) {
1210 if (OrigOperands.size() > 1) {
1211 // Check if sizes match, OrigOperands also contains the instruction name
1212 assert(OrigOperands.size() == FinalOperands.size() + 1 &&
1213 "Operand size mismatch");
1215 SmallVector<std::pair<SMLoc, std::string>, 2> Warnings;
1216 // Verify types match
1217 int RegClassID = -1;
1218 for (unsigned int i = 0; i < FinalOperands.size(); ++i) {
1219 X86Operand &OrigOp = static_cast<X86Operand &>(*OrigOperands[i + 1]);
1220 X86Operand &FinalOp = static_cast<X86Operand &>(*FinalOperands[i]);
1222 if (FinalOp.isReg() &&
1223 (!OrigOp.isReg() || FinalOp.getReg() != OrigOp.getReg()))
1224 // Return false and let a normal complaint about bogus operands happen
1227 if (FinalOp.isMem()) {
1229 if (!OrigOp.isMem())
1230 // Return false and let a normal complaint about bogus operands happen
1233 unsigned OrigReg = OrigOp.Mem.BaseReg;
1234 unsigned FinalReg = FinalOp.Mem.BaseReg;
1236 // If we've already encounterd a register class, make sure all register
1237 // bases are of the same register class
1238 if (RegClassID != -1 &&
1239 !X86MCRegisterClasses[RegClassID].contains(OrigReg)) {
1240 return Error(OrigOp.getStartLoc(),
1241 "mismatching source and destination index registers");
1244 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(OrigReg))
1245 RegClassID = X86::GR64RegClassID;
1246 else if (X86MCRegisterClasses[X86::GR32RegClassID].contains(OrigReg))
1247 RegClassID = X86::GR32RegClassID;
1248 else if (X86MCRegisterClasses[X86::GR16RegClassID].contains(OrigReg))
1249 RegClassID = X86::GR16RegClassID;
1251 // Unexpected register class type
1252 // Return false and let a normal complaint about bogus operands happen
1255 bool IsSI = IsSIReg(FinalReg);
1256 FinalReg = GetSIDIForRegClass(RegClassID, FinalReg, IsSI);
1258 if (FinalReg != OrigReg) {
1259 std::string RegName = IsSI ? "ES:(R|E)SI" : "ES:(R|E)DI";
1260 Warnings.push_back(std::make_pair(
1261 OrigOp.getStartLoc(),
1262 "memory operand is only for determining the size, " + RegName +
1263 " will be used for the location"));
1266 FinalOp.Mem.Size = OrigOp.Mem.Size;
1267 FinalOp.Mem.SegReg = OrigOp.Mem.SegReg;
1268 FinalOp.Mem.BaseReg = FinalReg;
1272 // Produce warnings only if all the operands passed the adjustment - prevent
1273 // legal cases like "movsd (%rax), %xmm0" mistakenly produce warnings
1274 for (auto &WarningMsg : Warnings) {
1275 Warning(WarningMsg.first, WarningMsg.second);
1278 // Remove old operands
1279 for (unsigned int i = 0; i < FinalOperands.size(); ++i)
1280 OrigOperands.pop_back();
1282 // OrigOperands.append(FinalOperands.begin(), FinalOperands.end());
1283 for (unsigned int i = 0; i < FinalOperands.size(); ++i)
1284 OrigOperands.push_back(std::move(FinalOperands[i]));
1289 std::unique_ptr<X86Operand> X86AsmParser::ParseOperand() {
1290 if (isParsingIntelSyntax())
1291 return ParseIntelOperand();
1292 return ParseATTOperand();
1295 std::unique_ptr<X86Operand> X86AsmParser::CreateMemForInlineAsm(
1296 unsigned SegReg, const MCExpr *Disp, unsigned BaseReg, unsigned IndexReg,
1297 unsigned Scale, SMLoc Start, SMLoc End, unsigned Size, StringRef Identifier,
1298 const InlineAsmIdentifierInfo &Info) {
1299 // If we found a decl other than a VarDecl, then assume it is a FuncDecl or
1300 // some other label reference.
1301 if (Info.isKind(InlineAsmIdentifierInfo::IK_Label)) {
1302 // Insert an explicit size if the user didn't have one.
1304 Size = getPointerWidth();
1305 InstInfo->AsmRewrites->emplace_back(AOK_SizeDirective, Start,
1308 // Create an absolute memory reference in order to match against
1309 // instructions taking a PC relative operand.
1310 return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size,
1311 Identifier, Info.Label.Decl);
1313 // We either have a direct symbol reference, or an offset from a symbol. The
1314 // parser always puts the symbol on the LHS, so look there for size
1315 // calculation purposes.
1316 unsigned FrontendSize = 0;
1317 void *Decl = nullptr;
1318 bool IsGlobalLV = false;
1319 if (Info.isKind(InlineAsmIdentifierInfo::IK_Var)) {
1320 // Size is in terms of bits in this context.
1321 FrontendSize = Info.Var.Type * 8;
1322 Decl = Info.Var.Decl;
1323 IsGlobalLV = Info.Var.IsGlobalLV;
1325 // It is widely common for MS InlineAsm to use a global variable and one/two
1326 // registers in a mmory expression, and though unaccessible via rip/eip.
1327 if (IsGlobalLV && (BaseReg || IndexReg)) {
1328 return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End);
1329 // Otherwise, we set the base register to a non-zero value
1330 // if we don't know the actual value at this time. This is necessary to
1331 // get the matching correct in some cases.
1333 BaseReg = BaseReg ? BaseReg : 1;
1334 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
1335 IndexReg, Scale, Start, End, Size, Identifier,
1336 Decl, FrontendSize);
1340 // Some binary bitwise operators have a named synonymous
1341 // Query a candidate string for being such a named operator
1342 // and if so - invoke the appropriate handler
1343 bool X86AsmParser::ParseIntelNamedOperator(StringRef Name, IntelExprStateMachine &SM) {
1344 // A named operator should be either lower or upper case, but not a mix
1345 if (Name.compare(Name.lower()) && Name.compare(Name.upper()))
1347 if (Name.equals_lower("not"))
1349 else if (Name.equals_lower("or"))
1351 else if (Name.equals_lower("shl"))
1353 else if (Name.equals_lower("shr"))
1355 else if (Name.equals_lower("xor"))
1357 else if (Name.equals_lower("and"))
1359 else if (Name.equals_lower("mod"))
1366 bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
1367 MCAsmParser &Parser = getParser();
1368 const AsmToken &Tok = Parser.getTok();
1371 AsmToken::TokenKind PrevTK = AsmToken::Error;
1374 bool UpdateLocLex = true;
1375 AsmToken::TokenKind TK = getLexer().getKind();
1379 if ((Done = SM.isValidEndState()))
1381 return Error(Tok.getLoc(), "unknown token in expression");
1382 case AsmToken::EndOfStatement:
1385 case AsmToken::Real:
1386 // DotOperator: [ebx].0
1387 UpdateLocLex = false;
1388 if (ParseIntelDotOperator(SM, End))
1391 case AsmToken::String:
1392 case AsmToken::Identifier: {
1393 SMLoc IdentLoc = Tok.getLoc();
1394 StringRef Identifier = Tok.getString();
1395 UpdateLocLex = false;
1398 if (Tok.isNot(AsmToken::String) && !ParseRegister(Reg, IdentLoc, End)) {
1399 if (SM.onRegister(Reg, ErrMsg))
1400 return Error(Tok.getLoc(), ErrMsg);
1403 // Operator synonymous ("not", "or" etc.)
1404 if ((UpdateLocLex = ParseIntelNamedOperator(Identifier, SM)))
1406 // Symbol reference, when parsing assembly content
1407 InlineAsmIdentifierInfo Info;
1409 if (!isParsingInlineAsm()) {
1410 if (getParser().parsePrimaryExpr(Val, End)) {
1411 return Error(Tok.getLoc(), "Unexpected identifier!");
1412 } else if (SM.onIdentifierExpr(Val, Identifier, Info, false, ErrMsg)) {
1413 return Error(IdentLoc, ErrMsg);
1417 // MS InlineAsm operators (TYPE/LENGTH/SIZE)
1418 if (unsigned OpKind = IdentifyIntelInlineAsmOperator(Identifier)) {
1419 if (OpKind == IOK_OFFSET)
1420 return Error(IdentLoc, "Dealing OFFSET operator as part of"
1421 "a compound immediate expression is yet to be supported");
1422 if (int64_t Val = ParseIntelInlineAsmOperator(OpKind)) {
1423 if (SM.onInteger(Val, ErrMsg))
1424 return Error(IdentLoc, ErrMsg);
1429 // MS Dot Operator expression
1430 if (Identifier.count('.') && PrevTK == AsmToken::RBrac) {
1431 if (ParseIntelDotOperator(SM, End))
1435 // MS InlineAsm identifier
1436 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info, false, End))
1438 else if (SM.onIdentifierExpr(Val, Identifier, Info, true, ErrMsg))
1439 return Error(IdentLoc, ErrMsg);
1442 case AsmToken::Integer: {
1443 // Look for 'b' or 'f' following an Integer as a directional label
1444 SMLoc Loc = getTok().getLoc();
1445 int64_t IntVal = getTok().getIntVal();
1446 End = consumeToken();
1447 UpdateLocLex = false;
1448 if (getLexer().getKind() == AsmToken::Identifier) {
1449 StringRef IDVal = getTok().getString();
1450 if (IDVal == "f" || IDVal == "b") {
1452 getContext().getDirectionalLocalSymbol(IntVal, IDVal == "b");
1453 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1455 MCSymbolRefExpr::create(Sym, Variant, getContext());
1456 if (IDVal == "b" && Sym->isUndefined())
1457 return Error(Loc, "invalid reference to undefined symbol");
1458 StringRef Identifier = Sym->getName();
1459 InlineAsmIdentifierInfo Info;
1460 if (SM.onIdentifierExpr(Val, Identifier, Info,
1461 isParsingInlineAsm(), ErrMsg))
1462 return Error(Loc, ErrMsg);
1463 End = consumeToken();
1465 if (SM.onInteger(IntVal, ErrMsg))
1466 return Error(Loc, ErrMsg);
1469 if (SM.onInteger(IntVal, ErrMsg))
1470 return Error(Loc, ErrMsg);
1474 case AsmToken::Plus:
1475 if (SM.onPlus(ErrMsg))
1476 return Error(getTok().getLoc(), ErrMsg);
1478 case AsmToken::Minus:
1479 if (SM.onMinus(ErrMsg))
1480 return Error(getTok().getLoc(), ErrMsg);
1482 case AsmToken::Tilde: SM.onNot(); break;
1483 case AsmToken::Star: SM.onStar(); break;
1484 case AsmToken::Slash: SM.onDivide(); break;
1485 case AsmToken::Percent: SM.onMod(); break;
1486 case AsmToken::Pipe: SM.onOr(); break;
1487 case AsmToken::Caret: SM.onXor(); break;
1488 case AsmToken::Amp: SM.onAnd(); break;
1489 case AsmToken::LessLess:
1490 SM.onLShift(); break;
1491 case AsmToken::GreaterGreater:
1492 SM.onRShift(); break;
1493 case AsmToken::LBrac:
1495 return Error(Tok.getLoc(), "unexpected bracket encountered");
1497 case AsmToken::RBrac:
1499 return Error(Tok.getLoc(), "unexpected bracket encountered");
1501 case AsmToken::LParen: SM.onLParen(); break;
1502 case AsmToken::RParen: SM.onRParen(); break;
1505 return Error(Tok.getLoc(), "unknown token in expression");
1507 if (!Done && UpdateLocLex)
1508 End = consumeToken();
1515 void X86AsmParser::RewriteIntelExpression(IntelExprStateMachine &SM,
1516 SMLoc Start, SMLoc End) {
1518 unsigned ExprLen = End.getPointer() - Start.getPointer();
1519 // Skip everything before a symbol displacement (if we have one)
1521 StringRef SymName = SM.getSymName();
1522 if (unsigned Len = SymName.data() - Start.getPointer())
1523 InstInfo->AsmRewrites->emplace_back(AOK_Skip, Start, Len);
1524 Loc = SMLoc::getFromPointer(SymName.data() + SymName.size());
1525 ExprLen = End.getPointer() - (SymName.data() + SymName.size());
1526 // If we have only a symbol than there's no need for complex rewrite,
1527 // simply skip everything after it
1528 if (!(SM.getBaseReg() || SM.getIndexReg() || SM.getImm())) {
1530 InstInfo->AsmRewrites->emplace_back(AOK_Skip, Loc, ExprLen);
1534 // Build an Intel Expression rewrite
1535 StringRef BaseRegStr;
1536 StringRef IndexRegStr;
1537 if (SM.getBaseReg())
1538 BaseRegStr = X86IntelInstPrinter::getRegisterName(SM.getBaseReg());
1539 if (SM.getIndexReg())
1540 IndexRegStr = X86IntelInstPrinter::getRegisterName(SM.getIndexReg());
1542 IntelExpr Expr(BaseRegStr, IndexRegStr, SM.getScale(), SM.getImm(), SM.isMemExpr());
1543 InstInfo->AsmRewrites->emplace_back(Loc, ExprLen, Expr);
1546 // Inline assembly may use variable names with namespace alias qualifiers.
1547 bool X86AsmParser::ParseIntelInlineAsmIdentifier(const MCExpr *&Val,
1548 StringRef &Identifier,
1549 InlineAsmIdentifierInfo &Info,
1550 bool IsUnevaluatedOperand,
1552 MCAsmParser &Parser = getParser();
1553 assert(isParsingInlineAsm() && "Expected to be parsing inline assembly.");
1556 StringRef LineBuf(Identifier.data());
1557 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);
1559 const AsmToken &Tok = Parser.getTok();
1560 SMLoc Loc = Tok.getLoc();
1562 // Advance the token stream until the end of the current token is
1563 // after the end of what the frontend claimed.
1564 const char *EndPtr = Tok.getLoc().getPointer() + LineBuf.size();
1566 End = Tok.getEndLoc();
1568 } while (End.getPointer() < EndPtr);
1569 Identifier = LineBuf;
1571 // The frontend should end parsing on an assembler token boundary, unless it
1573 assert((End.getPointer() == EndPtr ||
1574 Info.isKind(InlineAsmIdentifierInfo::IK_Invalid)) &&
1575 "frontend claimed part of a token?");
1577 // If the identifier lookup was unsuccessful, assume that we are dealing with
1579 if (Info.isKind(InlineAsmIdentifierInfo::IK_Invalid)) {
1580 StringRef InternalName =
1581 SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(),
1583 assert(InternalName.size() && "We should have an internal name here.");
1584 // Push a rewrite for replacing the identifier name with the internal name.
1585 InstInfo->AsmRewrites->emplace_back(AOK_Label, Loc, Identifier.size(),
1587 } else if (Info.isKind(InlineAsmIdentifierInfo::IK_EnumVal))
1589 // Create the symbol reference.
1590 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
1591 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1592 Val = MCSymbolRefExpr::create(Sym, Variant, getParser().getContext());
1596 //ParseRoundingModeOp - Parse AVX-512 rounding mode operand
1597 std::unique_ptr<X86Operand>
1598 X86AsmParser::ParseRoundingModeOp(SMLoc Start, SMLoc End) {
1599 MCAsmParser &Parser = getParser();
1600 const AsmToken &Tok = Parser.getTok();
1601 // Eat "{" and mark the current place.
1602 const SMLoc consumedToken = consumeToken();
1603 if (Tok.getIdentifier().startswith("r")){
1604 int rndMode = StringSwitch<int>(Tok.getIdentifier())
1605 .Case("rn", X86::STATIC_ROUNDING::TO_NEAREST_INT)
1606 .Case("rd", X86::STATIC_ROUNDING::TO_NEG_INF)
1607 .Case("ru", X86::STATIC_ROUNDING::TO_POS_INF)
1608 .Case("rz", X86::STATIC_ROUNDING::TO_ZERO)
1611 return ErrorOperand(Tok.getLoc(), "Invalid rounding mode.");
1612 Parser.Lex(); // Eat "r*" of r*-sae
1613 if (!getLexer().is(AsmToken::Minus))
1614 return ErrorOperand(Tok.getLoc(), "Expected - at this point");
1615 Parser.Lex(); // Eat "-"
1616 Parser.Lex(); // Eat the sae
1617 if (!getLexer().is(AsmToken::RCurly))
1618 return ErrorOperand(Tok.getLoc(), "Expected } at this point");
1619 Parser.Lex(); // Eat "}"
1620 const MCExpr *RndModeOp =
1621 MCConstantExpr::create(rndMode, Parser.getContext());
1622 return X86Operand::CreateImm(RndModeOp, Start, End);
1624 if(Tok.getIdentifier().equals("sae")){
1625 Parser.Lex(); // Eat the sae
1626 if (!getLexer().is(AsmToken::RCurly))
1627 return ErrorOperand(Tok.getLoc(), "Expected } at this point");
1628 Parser.Lex(); // Eat "}"
1629 return X86Operand::CreateToken("{sae}", consumedToken);
1631 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1634 /// Parse the '.' operator.
1635 bool X86AsmParser::ParseIntelDotOperator(IntelExprStateMachine &SM, SMLoc &End) {
1636 const AsmToken &Tok = getTok();
1639 // Drop the optional '.'.
1640 StringRef DotDispStr = Tok.getString();
1641 if (DotDispStr.startswith("."))
1642 DotDispStr = DotDispStr.drop_front(1);
1644 // .Imm gets lexed as a real.
1645 if (Tok.is(AsmToken::Real)) {
1647 DotDispStr.getAsInteger(10, DotDisp);
1648 Offset = DotDisp.getZExtValue();
1649 } else if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) {
1650 std::pair<StringRef, StringRef> BaseMember = DotDispStr.split('.');
1651 if (SemaCallback->LookupInlineAsmField(BaseMember.first, BaseMember.second,
1653 return Error(Tok.getLoc(), "Unable to lookup field reference!");
1655 return Error(Tok.getLoc(), "Unexpected token type!");
1657 // Eat the DotExpression and update End
1658 End = SMLoc::getFromPointer(DotDispStr.data());
1659 const char *DotExprEndLoc = DotDispStr.data() + DotDispStr.size();
1660 while (Tok.getLoc().getPointer() < DotExprEndLoc)
1666 /// Parse the 'offset' operator. This operator is used to specify the
1667 /// location rather then the content of a variable.
1668 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOffsetOfOperator() {
1669 MCAsmParser &Parser = getParser();
1670 const AsmToken &Tok = Parser.getTok();
1671 SMLoc OffsetOfLoc = Tok.getLoc();
1672 Parser.Lex(); // Eat offset.
1675 InlineAsmIdentifierInfo Info;
1676 SMLoc Start = Tok.getLoc(), End;
1677 StringRef Identifier = Tok.getString();
1678 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
1679 /*Unevaluated=*/false, End))
1682 void *Decl = nullptr;
1683 // FIXME: MS evaluates "offset <Constant>" to the underlying integral
1684 if (Info.isKind(InlineAsmIdentifierInfo::IK_EnumVal))
1685 return ErrorOperand(Start, "offset operator cannot yet handle constants");
1686 else if (Info.isKind(InlineAsmIdentifierInfo::IK_Var))
1687 Decl = Info.Var.Decl;
1688 // Don't emit the offset operator.
1689 InstInfo->AsmRewrites->emplace_back(AOK_Skip, OffsetOfLoc, 7);
1691 // The offset operator will have an 'r' constraint, thus we need to create
1692 // register operand to ensure proper matching. Just pick a GPR based on
1693 // the size of a pointer.
1694 bool Parse32 = is32BitMode() || Code16GCC;
1695 unsigned RegNo = is64BitMode() ? X86::RBX : (Parse32 ? X86::EBX : X86::BX);
1697 return X86Operand::CreateReg(RegNo, Start, End, /*GetAddress=*/true,
1698 OffsetOfLoc, Identifier, Decl);
1701 // Query a candidate string for being an Intel assembly operator
1702 // Report back its kind, or IOK_INVALID if does not evaluated as a known one
1703 unsigned X86AsmParser::IdentifyIntelInlineAsmOperator(StringRef Name) {
1704 return StringSwitch<unsigned>(Name)
1705 .Cases("TYPE","type",IOK_TYPE)
1706 .Cases("SIZE","size",IOK_SIZE)
1707 .Cases("LENGTH","length",IOK_LENGTH)
1708 .Cases("OFFSET","offset",IOK_OFFSET)
1709 .Default(IOK_INVALID);
1712 /// Parse the 'LENGTH', 'TYPE' and 'SIZE' operators. The LENGTH operator
1713 /// returns the number of elements in an array. It returns the value 1 for
1714 /// non-array variables. The SIZE operator returns the size of a C or C++
1715 /// variable. A variable's size is the product of its LENGTH and TYPE. The
1716 /// TYPE operator returns the size of a C or C++ type or variable. If the
1717 /// variable is an array, TYPE returns the size of a single element.
1718 unsigned X86AsmParser::ParseIntelInlineAsmOperator(unsigned OpKind) {
1719 MCAsmParser &Parser = getParser();
1720 const AsmToken &Tok = Parser.getTok();
1721 Parser.Lex(); // Eat operator.
1723 const MCExpr *Val = nullptr;
1724 InlineAsmIdentifierInfo Info;
1725 SMLoc Start = Tok.getLoc(), End;
1726 StringRef Identifier = Tok.getString();
1727 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
1728 /*Unevaluated=*/true, End))
1731 if (!Info.isKind(InlineAsmIdentifierInfo::IK_Var)) {
1732 Error(Start, "unable to lookup expression");
1738 default: llvm_unreachable("Unexpected operand kind!");
1739 case IOK_LENGTH: CVal = Info.Var.Length; break;
1740 case IOK_SIZE: CVal = Info.Var.Size; break;
1741 case IOK_TYPE: CVal = Info.Var.Type; break;
1747 bool X86AsmParser::ParseIntelMemoryOperandSize(unsigned &Size) {
1748 Size = StringSwitch<unsigned>(getTok().getString())
1749 .Cases("BYTE", "byte", 8)
1750 .Cases("WORD", "word", 16)
1751 .Cases("DWORD", "dword", 32)
1752 .Cases("FLOAT", "float", 32)
1753 .Cases("LONG", "long", 32)
1754 .Cases("FWORD", "fword", 48)
1755 .Cases("DOUBLE", "double", 64)
1756 .Cases("QWORD", "qword", 64)
1757 .Cases("MMWORD","mmword", 64)
1758 .Cases("XWORD", "xword", 80)
1759 .Cases("TBYTE", "tbyte", 80)
1760 .Cases("XMMWORD", "xmmword", 128)
1761 .Cases("YMMWORD", "ymmword", 256)
1762 .Cases("ZMMWORD", "zmmword", 512)
1763 .Cases("OPAQUE", "opaque", -1U) // needs to be non-zero, but doesn't matter
1766 const AsmToken &Tok = Lex(); // Eat operand size (e.g., byte, word).
1767 if (!(Tok.getString().equals("PTR") || Tok.getString().equals("ptr")))
1768 return Error(Tok.getLoc(), "Expected 'PTR' or 'ptr' token!");
1774 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand() {
1775 MCAsmParser &Parser = getParser();
1776 const AsmToken &Tok = Parser.getTok();
1779 // FIXME: Offset operator
1780 // Should be handled as part of immediate expression, as other operators
1781 // Currently, only supported as a stand-alone operand
1782 if (isParsingInlineAsm())
1783 if (IdentifyIntelInlineAsmOperator(Tok.getString()) == IOK_OFFSET)
1784 return ParseIntelOffsetOfOperator();
1786 // Parse optional Size directive.
1788 if (ParseIntelMemoryOperandSize(Size))
1790 bool PtrInOperand = bool(Size);
1792 Start = Tok.getLoc();
1794 // Rounding mode operand.
1795 if (getSTI().getFeatureBits()[X86::FeatureAVX512] &&
1796 getLexer().is(AsmToken::LCurly))
1797 return ParseRoundingModeOp(Start, End);
1799 // Register operand.
1801 if (Tok.is(AsmToken::Identifier) && !ParseRegister(RegNo, Start, End)) {
1802 if (RegNo == X86::RIP)
1803 return ErrorOperand(Start, "rip can only be used as a base register");
1804 // A Register followed by ':' is considered a segment override
1805 if (Tok.isNot(AsmToken::Colon))
1806 return !PtrInOperand ? X86Operand::CreateReg(RegNo, Start, End) :
1807 ErrorOperand(Start, "expected memory operand after 'ptr', "
1808 "found register operand instead");
1809 // An alleged segment override. check if we have a valid segment register
1810 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo))
1811 return ErrorOperand(Start, "invalid segment register");
1812 // Eat ':' and update Start location
1813 Start = Lex().getLoc();
1816 // Immediates and Memory
1817 IntelExprStateMachine SM;
1818 if (ParseIntelExpression(SM, End))
1821 if (isParsingInlineAsm())
1822 RewriteIntelExpression(SM, Start, Tok.getLoc());
1824 int64_t Imm = SM.getImm();
1825 const MCExpr *Disp = SM.getSym();
1826 const MCExpr *ImmDisp = MCConstantExpr::create(Imm, getContext());
1828 Disp = MCBinaryExpr::createAdd(Disp, ImmDisp, getContext());
1832 // RegNo != 0 specifies a valid segment register,
1833 // and we are parsing a segment override
1834 if (!SM.isMemExpr() && !RegNo)
1835 return X86Operand::CreateImm(Disp, Start, End);
1838 unsigned BaseReg = SM.getBaseReg();
1839 unsigned IndexReg = SM.getIndexReg();
1840 unsigned Scale = SM.getScale();
1842 if ((BaseReg || IndexReg) &&
1843 CheckBaseRegAndIndexRegAndScale(BaseReg, IndexReg, Scale, ErrMsg))
1844 return ErrorOperand(Start, ErrMsg);
1845 if (isParsingInlineAsm())
1846 return CreateMemForInlineAsm(RegNo, Disp, BaseReg, IndexReg,
1847 Scale, Start, End, Size, SM.getSymName(),
1848 SM.getIdentifierInfo());
1849 if (!(BaseReg || IndexReg || RegNo))
1850 return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size);
1851 return X86Operand::CreateMem(getPointerWidth(), RegNo, Disp,
1852 BaseReg, IndexReg, Scale, Start, End, Size);
1855 std::unique_ptr<X86Operand> X86AsmParser::ParseATTOperand() {
1856 MCAsmParser &Parser = getParser();
1857 switch (getLexer().getKind()) {
1859 // Parse a memory operand with no segment register.
1860 return ParseMemOperand(0, Parser.getTok().getLoc());
1861 case AsmToken::Percent: {
1862 // Read the register.
1865 if (ParseRegister(RegNo, Start, End)) return nullptr;
1866 if (RegNo == X86::EIZ || RegNo == X86::RIZ) {
1867 Error(Start, "%eiz and %riz can only be used as index registers",
1868 SMRange(Start, End));
1871 if (RegNo == X86::RIP) {
1872 Error(Start, "%rip can only be used as a base register",
1873 SMRange(Start, End));
1877 // If this is a segment register followed by a ':', then this is the start
1878 // of a memory reference, otherwise this is a normal register reference.
1879 if (getLexer().isNot(AsmToken::Colon))
1880 return X86Operand::CreateReg(RegNo, Start, End);
1882 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo))
1883 return ErrorOperand(Start, "invalid segment register");
1885 getParser().Lex(); // Eat the colon.
1886 return ParseMemOperand(RegNo, Start);
1888 case AsmToken::Dollar: {
1889 // $42 -> immediate.
1890 SMLoc Start = Parser.getTok().getLoc(), End;
1893 if (getParser().parseExpression(Val, End))
1895 return X86Operand::CreateImm(Val, Start, End);
1897 case AsmToken::LCurly:{
1898 SMLoc Start = Parser.getTok().getLoc(), End;
1899 if (getSTI().getFeatureBits()[X86::FeatureAVX512])
1900 return ParseRoundingModeOp(Start, End);
1901 return ErrorOperand(Start, "Unexpected '{' in expression");
1906 // true on failure, false otherwise
1907 // If no {z} mark was found - Parser doesn't advance
1908 bool X86AsmParser::ParseZ(std::unique_ptr<X86Operand> &Z,
1909 const SMLoc &StartLoc) {
1910 MCAsmParser &Parser = getParser();
1911 // Assuming we are just pass the '{' mark, quering the next token
1912 // Searched for {z}, but none was found. Return false, as no parsing error was
1914 if (!(getLexer().is(AsmToken::Identifier) &&
1915 (getLexer().getTok().getIdentifier() == "z")))
1917 Parser.Lex(); // Eat z
1918 // Query and eat the '}' mark
1919 if (!getLexer().is(AsmToken::RCurly))
1920 return Error(getLexer().getLoc(), "Expected } at this point");
1921 Parser.Lex(); // Eat '}'
1922 // Assign Z with the {z} mark opernad
1923 Z = X86Operand::CreateToken("{z}", StartLoc);
1927 // true on failure, false otherwise
1928 bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands,
1929 const MCParsedAsmOperand &Op) {
1930 MCAsmParser &Parser = getParser();
1931 if(getSTI().getFeatureBits()[X86::FeatureAVX512]) {
1932 if (getLexer().is(AsmToken::LCurly)) {
1933 // Eat "{" and mark the current place.
1934 const SMLoc consumedToken = consumeToken();
1935 // Distinguish {1to<NUM>} from {%k<NUM>}.
1936 if(getLexer().is(AsmToken::Integer)) {
1937 // Parse memory broadcasting ({1to<NUM>}).
1938 if (getLexer().getTok().getIntVal() != 1)
1939 return TokError("Expected 1to<NUM> at this point");
1940 Parser.Lex(); // Eat "1" of 1to8
1941 if (!getLexer().is(AsmToken::Identifier) ||
1942 !getLexer().getTok().getIdentifier().startswith("to"))
1943 return TokError("Expected 1to<NUM> at this point");
1944 // Recognize only reasonable suffixes.
1945 const char *BroadcastPrimitive =
1946 StringSwitch<const char*>(getLexer().getTok().getIdentifier())
1947 .Case("to2", "{1to2}")
1948 .Case("to4", "{1to4}")
1949 .Case("to8", "{1to8}")
1950 .Case("to16", "{1to16}")
1952 if (!BroadcastPrimitive)
1953 return TokError("Invalid memory broadcast primitive.");
1954 Parser.Lex(); // Eat "toN" of 1toN
1955 if (!getLexer().is(AsmToken::RCurly))
1956 return TokError("Expected } at this point");
1957 Parser.Lex(); // Eat "}"
1958 Operands.push_back(X86Operand::CreateToken(BroadcastPrimitive,
1960 // No AVX512 specific primitives can pass
1961 // after memory broadcasting, so return.
1964 // Parse either {k}{z}, {z}{k}, {k} or {z}
1965 // last one have no meaning, but GCC accepts it
1966 // Currently, we're just pass a '{' mark
1967 std::unique_ptr<X86Operand> Z;
1968 if (ParseZ(Z, consumedToken))
1970 // Reaching here means that parsing of the allegadly '{z}' mark yielded
1972 // Query for the need of further parsing for a {%k<NUM>} mark
1973 if (!Z || getLexer().is(AsmToken::LCurly)) {
1974 SMLoc StartLoc = Z ? consumeToken() : consumedToken;
1975 // Parse an op-mask register mark ({%k<NUM>}), which is now to be
1979 if (!ParseRegister(RegNo, RegLoc, StartLoc) &&
1980 X86MCRegisterClasses[X86::VK1RegClassID].contains(RegNo)) {
1981 if (RegNo == X86::K0)
1982 return Error(RegLoc, "Register k0 can't be used as write mask");
1983 if (!getLexer().is(AsmToken::RCurly))
1984 return Error(getLexer().getLoc(), "Expected } at this point");
1985 Operands.push_back(X86Operand::CreateToken("{", StartLoc));
1987 X86Operand::CreateReg(RegNo, StartLoc, StartLoc));
1988 Operands.push_back(X86Operand::CreateToken("}", consumeToken()));
1990 return Error(getLexer().getLoc(),
1991 "Expected an op-mask register at this point");
1992 // {%k<NUM>} mark is found, inquire for {z}
1993 if (getLexer().is(AsmToken::LCurly) && !Z) {
1994 // Have we've found a parsing error, or found no (expected) {z} mark
1995 // - report an error
1996 if (ParseZ(Z, consumeToken()) || !Z)
1997 return Error(getLexer().getLoc(),
1998 "Expected a {z} mark at this point");
2001 // '{z}' on its own is meaningless, hence should be ignored.
2002 // on the contrary - have it been accompanied by a K register,
2005 Operands.push_back(std::move(Z));
2013 /// ParseMemOperand: segment: disp(basereg, indexreg, scale). The '%ds:' prefix
2014 /// has already been parsed if present.
2015 std::unique_ptr<X86Operand> X86AsmParser::ParseMemOperand(unsigned SegReg,
2018 MCAsmParser &Parser = getParser();
2019 // We have to disambiguate a parenthesized expression "(4+5)" from the start
2020 // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)". The
2021 // only way to do this without lookahead is to eat the '(' and see what is
2023 const MCExpr *Disp = MCConstantExpr::create(0, getParser().getContext());
2024 if (getLexer().isNot(AsmToken::LParen)) {
2026 if (getParser().parseExpression(Disp, ExprEnd)) return nullptr;
2028 // After parsing the base expression we could either have a parenthesized
2029 // memory address or not. If not, return now. If so, eat the (.
2030 if (getLexer().isNot(AsmToken::LParen)) {
2031 // Unless we have a segment register, treat this as an immediate.
2033 return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, ExprEnd);
2034 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
2041 // Okay, we have a '('. We don't know if this is an expression or not, but
2042 // so we have to eat the ( to see beyond it.
2043 SMLoc LParenLoc = Parser.getTok().getLoc();
2044 Parser.Lex(); // Eat the '('.
2046 if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) {
2047 // Nothing to do here, fall into the code below with the '(' part of the
2048 // memory operand consumed.
2051 getLexer().UnLex(AsmToken(AsmToken::LParen, "("));
2053 // It must be either an parenthesized expression, or an expression that
2054 // begins from a parenthesized expression, parse it now. Example: (1+2) or
2056 if (getParser().parseExpression(Disp, ExprEnd))
2059 // After parsing the base expression we could either have a parenthesized
2060 // memory address or not. If not, return now. If so, eat the (.
2061 if (getLexer().isNot(AsmToken::LParen)) {
2062 // Unless we have a segment register, treat this as an immediate.
2064 return X86Operand::CreateMem(getPointerWidth(), Disp, LParenLoc,
2066 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
2075 // If we reached here, then we just ate the ( of the memory operand. Process
2076 // the rest of the memory operand.
2077 unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
2078 SMLoc IndexLoc, BaseLoc;
2080 if (getLexer().is(AsmToken::Percent)) {
2081 SMLoc StartLoc, EndLoc;
2082 BaseLoc = Parser.getTok().getLoc();
2083 if (ParseRegister(BaseReg, StartLoc, EndLoc)) return nullptr;
2084 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) {
2085 Error(StartLoc, "eiz and riz can only be used as index registers",
2086 SMRange(StartLoc, EndLoc));
2091 if (getLexer().is(AsmToken::Comma)) {
2092 Parser.Lex(); // Eat the comma.
2093 IndexLoc = Parser.getTok().getLoc();
2095 // Following the comma we should have either an index register, or a scale
2096 // value. We don't support the later form, but we want to parse it
2099 // Not that even though it would be completely consistent to support syntax
2100 // like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this.
2101 if (getLexer().is(AsmToken::Percent)) {
2103 if (ParseRegister(IndexReg, L, L))
2105 if (BaseReg == X86::RIP) {
2106 Error(IndexLoc, "%rip as base register can not have an index register");
2109 if (IndexReg == X86::RIP) {
2110 Error(IndexLoc, "%rip is not allowed as an index register");
2114 if (getLexer().isNot(AsmToken::RParen)) {
2115 // Parse the scale amount:
2116 // ::= ',' [scale-expression]
2117 if (getLexer().isNot(AsmToken::Comma)) {
2118 Error(Parser.getTok().getLoc(),
2119 "expected comma in scale expression");
2122 Parser.Lex(); // Eat the comma.
2124 if (getLexer().isNot(AsmToken::RParen)) {
2125 SMLoc Loc = Parser.getTok().getLoc();
2128 if (getParser().parseAbsoluteExpression(ScaleVal)){
2129 Error(Loc, "expected scale expression");
2133 // Validate the scale amount.
2134 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
2136 Error(Loc, "scale factor in 16-bit address must be 1");
2139 if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 &&
2141 Error(Loc, "scale factor in address must be 1, 2, 4 or 8");
2144 Scale = (unsigned)ScaleVal;
2147 } else if (getLexer().isNot(AsmToken::RParen)) {
2148 // A scale amount without an index is ignored.
2150 SMLoc Loc = Parser.getTok().getLoc();
2153 if (getParser().parseAbsoluteExpression(Value))
2157 Warning(Loc, "scale factor without index register is ignored");
2162 // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
2163 if (getLexer().isNot(AsmToken::RParen)) {
2164 Error(Parser.getTok().getLoc(), "unexpected token in memory operand");
2167 SMLoc MemEnd = Parser.getTok().getEndLoc();
2168 Parser.Lex(); // Eat the ')'.
2170 // Check for use of invalid 16-bit registers. Only BX/BP/SI/DI are allowed,
2171 // and then only in non-64-bit modes. Except for DX, which is a special case
2172 // because an unofficial form of in/out instructions uses it.
2173 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
2174 (is64BitMode() || (BaseReg != X86::BX && BaseReg != X86::BP &&
2175 BaseReg != X86::SI && BaseReg != X86::DI)) &&
2176 BaseReg != X86::DX) {
2177 Error(BaseLoc, "invalid 16-bit base register");
2181 X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg)) {
2182 Error(IndexLoc, "16-bit memory operand may not include only index register");
2187 if (CheckBaseRegAndIndexRegAndScale(BaseReg, IndexReg, Scale, ErrMsg)) {
2188 Error(BaseLoc, ErrMsg);
2192 if (SegReg || BaseReg || IndexReg)
2193 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
2194 IndexReg, Scale, MemStart, MemEnd);
2195 return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, MemEnd);
2198 bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2199 SMLoc NameLoc, OperandVector &Operands) {
2200 MCAsmParser &Parser = getParser();
2202 StringRef PatchedName = Name;
2204 if ((Name.equals("jmp") || Name.equals("jc") || Name.equals("jz")) &&
2205 isParsingIntelSyntax() && isParsingInlineAsm()) {
2206 StringRef NextTok = Parser.getTok().getString();
2207 if (NextTok == "short") {
2209 NameLoc.getFromPointer(NameLoc.getPointer() + Name.size());
2210 // Eat the short keyword
2212 // MS ignores the short keyword, it determines the jmp type based
2213 // on the distance of the label
2214 InstInfo->AsmRewrites->emplace_back(AOK_Skip, NameEndLoc,
2215 NextTok.size() + 1);
2219 // FIXME: Hack to recognize setneb as setne.
2220 if (PatchedName.startswith("set") && PatchedName.endswith("b") &&
2221 PatchedName != "setb" && PatchedName != "setnb")
2222 PatchedName = PatchedName.substr(0, Name.size()-1);
2224 // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}.
2225 if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) &&
2226 (PatchedName.endswith("ss") || PatchedName.endswith("sd") ||
2227 PatchedName.endswith("ps") || PatchedName.endswith("pd"))) {
2228 bool IsVCMP = PatchedName[0] == 'v';
2229 unsigned CCIdx = IsVCMP ? 4 : 3;
2230 unsigned ComparisonCode = StringSwitch<unsigned>(
2231 PatchedName.slice(CCIdx, PatchedName.size() - 2))
2233 .Case("eq_oq", 0x00)
2235 .Case("lt_os", 0x01)
2237 .Case("le_os", 0x02)
2238 .Case("unord", 0x03)
2239 .Case("unord_q", 0x03)
2241 .Case("neq_uq", 0x04)
2243 .Case("nlt_us", 0x05)
2245 .Case("nle_us", 0x06)
2247 .Case("ord_q", 0x07)
2248 /* AVX only from here */
2249 .Case("eq_uq", 0x08)
2251 .Case("nge_us", 0x09)
2253 .Case("ngt_us", 0x0A)
2254 .Case("false", 0x0B)
2255 .Case("false_oq", 0x0B)
2256 .Case("neq_oq", 0x0C)
2258 .Case("ge_os", 0x0D)
2260 .Case("gt_os", 0x0E)
2262 .Case("true_uq", 0x0F)
2263 .Case("eq_os", 0x10)
2264 .Case("lt_oq", 0x11)
2265 .Case("le_oq", 0x12)
2266 .Case("unord_s", 0x13)
2267 .Case("neq_us", 0x14)
2268 .Case("nlt_uq", 0x15)
2269 .Case("nle_uq", 0x16)
2270 .Case("ord_s", 0x17)
2271 .Case("eq_us", 0x18)
2272 .Case("nge_uq", 0x19)
2273 .Case("ngt_uq", 0x1A)
2274 .Case("false_os", 0x1B)
2275 .Case("neq_os", 0x1C)
2276 .Case("ge_oq", 0x1D)
2277 .Case("gt_oq", 0x1E)
2278 .Case("true_us", 0x1F)
2280 if (ComparisonCode != ~0U && (IsVCMP || ComparisonCode < 8)) {
2282 Operands.push_back(X86Operand::CreateToken(PatchedName.slice(0, CCIdx),
2285 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2286 getParser().getContext());
2287 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2289 PatchedName = PatchedName.substr(PatchedName.size() - 2);
2293 // FIXME: Hack to recognize vpcmp<comparison code>{ub,uw,ud,uq,b,w,d,q}.
2294 if (PatchedName.startswith("vpcmp") &&
2295 (PatchedName.endswith("b") || PatchedName.endswith("w") ||
2296 PatchedName.endswith("d") || PatchedName.endswith("q"))) {
2297 unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1;
2298 unsigned ComparisonCode = StringSwitch<unsigned>(
2299 PatchedName.slice(5, PatchedName.size() - CCIdx))
2300 .Case("eq", 0x0) // Only allowed on unsigned. Checked below.
2303 //.Case("false", 0x3) // Not a documented alias.
2307 //.Case("true", 0x7) // Not a documented alias.
2309 if (ComparisonCode != ~0U && (ComparisonCode != 0 || CCIdx == 2)) {
2310 Operands.push_back(X86Operand::CreateToken("vpcmp", NameLoc));
2312 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2313 getParser().getContext());
2314 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2316 PatchedName = PatchedName.substr(PatchedName.size() - CCIdx);
2320 // FIXME: Hack to recognize vpcom<comparison code>{ub,uw,ud,uq,b,w,d,q}.
2321 if (PatchedName.startswith("vpcom") &&
2322 (PatchedName.endswith("b") || PatchedName.endswith("w") ||
2323 PatchedName.endswith("d") || PatchedName.endswith("q"))) {
2324 unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1;
2325 unsigned ComparisonCode = StringSwitch<unsigned>(
2326 PatchedName.slice(5, PatchedName.size() - CCIdx))
2336 if (ComparisonCode != ~0U) {
2337 Operands.push_back(X86Operand::CreateToken("vpcom", NameLoc));
2339 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2340 getParser().getContext());
2341 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2343 PatchedName = PatchedName.substr(PatchedName.size() - CCIdx);
2348 // Determine whether this is an instruction prefix.
2350 // Enhance prefixes integrity robustness. for example, following forms
2351 // are currently tolerated:
2352 // repz repnz <insn> ; GAS errors for the use of two similar prefixes
2353 // lock addq %rax, %rbx ; Destination operand must be of memory type
2354 // xacquire <insn> ; xacquire must be accompanied by 'lock'
2355 bool isPrefix = StringSwitch<bool>(Name)
2356 .Cases("rex64", "data32", "data16", true)
2357 .Cases("xacquire", "xrelease", true)
2358 .Cases("acquire", "release", isParsingIntelSyntax())
2361 auto isLockRepeatPrefix = [](StringRef N) {
2362 return StringSwitch<bool>(N)
2363 .Cases("lock", "rep", "repe", "repz", "repne", "repnz", true)
2367 bool CurlyAsEndOfStatement = false;
2369 unsigned Flags = X86::IP_NO_PREFIX;
2370 while (isLockRepeatPrefix(Name.lower())) {
2372 StringSwitch<unsigned>(Name)
2373 .Cases("lock", "lock", X86::IP_HAS_LOCK)
2374 .Cases("rep", "repe", "repz", X86::IP_HAS_REPEAT)
2375 .Cases("repne", "repnz", X86::IP_HAS_REPEAT_NE)
2376 .Default(X86::IP_NO_PREFIX); // Invalid prefix (impossible)
2378 Name = Parser.getTok().getString();
2379 Parser.Lex(); // eat the prefix
2380 // Hack: we could have something like "rep # some comment" or
2381 // "lock; cmpxchg16b $1" or "lock\0A\09incl" or "lock/incl"
2382 while (Name.startswith(";") || Name.startswith("\n") ||
2383 Name.startswith("#") || Name.startswith("\t") ||
2384 Name.startswith("/")) {
2385 Name = Parser.getTok().getString();
2386 Parser.Lex(); // go to next prefix or instr
2392 Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
2394 // This does the actual operand parsing. Don't parse any more if we have a
2395 // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we
2396 // just want to parse the "lock" as the first instruction and the "incl" as
2398 if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) {
2399 // Parse '*' modifier.
2400 if (getLexer().is(AsmToken::Star))
2401 Operands.push_back(X86Operand::CreateToken("*", consumeToken()));
2403 // Read the operands.
2405 if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
2406 Operands.push_back(std::move(Op));
2407 if (HandleAVX512Operand(Operands, *Operands.back()))
2412 // check for comma and eat it
2413 if (getLexer().is(AsmToken::Comma))
2419 // In MS inline asm curly braces mark the beginning/end of a block,
2420 // therefore they should be interepreted as end of statement
2421 CurlyAsEndOfStatement =
2422 isParsingIntelSyntax() && isParsingInlineAsm() &&
2423 (getLexer().is(AsmToken::LCurly) || getLexer().is(AsmToken::RCurly));
2424 if (getLexer().isNot(AsmToken::EndOfStatement) && !CurlyAsEndOfStatement)
2425 return TokError("unexpected token in argument list");
2428 // Consume the EndOfStatement or the prefix separator Slash
2429 if (getLexer().is(AsmToken::EndOfStatement) ||
2430 (isPrefix && getLexer().is(AsmToken::Slash)))
2432 else if (CurlyAsEndOfStatement)
2433 // Add an actual EndOfStatement before the curly brace
2434 Info.AsmRewrites->emplace_back(AOK_EndOfStatement,
2435 getLexer().getTok().getLoc(), 0);
2437 // This is for gas compatibility and cannot be done in td.
2438 // Adding "p" for some floating point with no argument.
2439 // For example: fsub --> fsubp
2441 Name == "fsub" || Name == "fdiv" || Name == "fsubr" || Name == "fdivr";
2442 if (IsFp && Operands.size() == 1) {
2443 const char *Repl = StringSwitch<const char *>(Name)
2444 .Case("fsub", "fsubp")
2445 .Case("fdiv", "fdivp")
2446 .Case("fsubr", "fsubrp")
2447 .Case("fdivr", "fdivrp");
2448 static_cast<X86Operand &>(*Operands[0]).setTokenValue(Repl);
2451 // Moving a 32 or 16 bit value into a segment register has the same
2452 // behavior. Modify such instructions to always take shorter form.
2453 if ((Name == "mov" || Name == "movw" || Name == "movl") &&
2454 (Operands.size() == 3)) {
2455 X86Operand &Op1 = (X86Operand &)*Operands[1];
2456 X86Operand &Op2 = (X86Operand &)*Operands[2];
2457 SMLoc Loc = Op1.getEndLoc();
2458 if (Op1.isReg() && Op2.isReg() &&
2459 X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(
2461 (X86MCRegisterClasses[X86::GR16RegClassID].contains(Op1.getReg()) ||
2462 X86MCRegisterClasses[X86::GR32RegClassID].contains(Op1.getReg()))) {
2463 // Change instruction name to match new instruction.
2464 if (Name != "mov" && Name[3] == (is16BitMode() ? 'l' : 'w')) {
2465 Name = is16BitMode() ? "movw" : "movl";
2466 Operands[0] = X86Operand::CreateToken(Name, NameLoc);
2468 // Select the correct equivalent 16-/32-bit source register.
2470 getX86SubSuperRegisterOrZero(Op1.getReg(), is16BitMode() ? 16 : 32);
2471 Operands[1] = X86Operand::CreateReg(Reg, Loc, Loc);
2475 // This is a terrible hack to handle "out[s]?[bwl]? %al, (%dx)" ->
2476 // "outb %al, %dx". Out doesn't take a memory form, but this is a widely
2477 // documented form in various unofficial manuals, so a lot of code uses it.
2478 if ((Name == "outb" || Name == "outsb" || Name == "outw" || Name == "outsw" ||
2479 Name == "outl" || Name == "outsl" || Name == "out" || Name == "outs") &&
2480 Operands.size() == 3) {
2481 X86Operand &Op = (X86Operand &)*Operands.back();
2482 if (Op.isMem() && Op.Mem.SegReg == 0 &&
2483 isa<MCConstantExpr>(Op.Mem.Disp) &&
2484 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
2485 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
2486 SMLoc Loc = Op.getEndLoc();
2487 Operands.back() = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
2490 // Same hack for "in[s]?[bwl]? (%dx), %al" -> "inb %dx, %al".
2491 if ((Name == "inb" || Name == "insb" || Name == "inw" || Name == "insw" ||
2492 Name == "inl" || Name == "insl" || Name == "in" || Name == "ins") &&
2493 Operands.size() == 3) {
2494 X86Operand &Op = (X86Operand &)*Operands[1];
2495 if (Op.isMem() && Op.Mem.SegReg == 0 &&
2496 isa<MCConstantExpr>(Op.Mem.Disp) &&
2497 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
2498 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
2499 SMLoc Loc = Op.getEndLoc();
2500 Operands[1] = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
2504 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 2> TmpOperands;
2505 bool HadVerifyError = false;
2507 // Append default arguments to "ins[bwld]"
2508 if (Name.startswith("ins") &&
2509 (Operands.size() == 1 || Operands.size() == 3) &&
2510 (Name == "insb" || Name == "insw" || Name == "insl" || Name == "insd" ||
2513 AddDefaultSrcDestOperands(TmpOperands,
2514 X86Operand::CreateReg(X86::DX, NameLoc, NameLoc),
2515 DefaultMemDIOperand(NameLoc));
2516 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2519 // Append default arguments to "outs[bwld]"
2520 if (Name.startswith("outs") &&
2521 (Operands.size() == 1 || Operands.size() == 3) &&
2522 (Name == "outsb" || Name == "outsw" || Name == "outsl" ||
2523 Name == "outsd" || Name == "outs")) {
2524 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
2525 X86Operand::CreateReg(X86::DX, NameLoc, NameLoc));
2526 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2529 // Transform "lods[bwlq]" into "lods[bwlq] ($SIREG)" for appropriate
2530 // values of $SIREG according to the mode. It would be nice if this
2531 // could be achieved with InstAlias in the tables.
2532 if (Name.startswith("lods") &&
2533 (Operands.size() == 1 || Operands.size() == 2) &&
2534 (Name == "lods" || Name == "lodsb" || Name == "lodsw" ||
2535 Name == "lodsl" || Name == "lodsd" || Name == "lodsq")) {
2536 TmpOperands.push_back(DefaultMemSIOperand(NameLoc));
2537 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2540 // Transform "stos[bwlq]" into "stos[bwlq] ($DIREG)" for appropriate
2541 // values of $DIREG according to the mode. It would be nice if this
2542 // could be achieved with InstAlias in the tables.
2543 if (Name.startswith("stos") &&
2544 (Operands.size() == 1 || Operands.size() == 2) &&
2545 (Name == "stos" || Name == "stosb" || Name == "stosw" ||
2546 Name == "stosl" || Name == "stosd" || Name == "stosq")) {
2547 TmpOperands.push_back(DefaultMemDIOperand(NameLoc));
2548 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2551 // Transform "scas[bwlq]" into "scas[bwlq] ($DIREG)" for appropriate
2552 // values of $DIREG according to the mode. It would be nice if this
2553 // could be achieved with InstAlias in the tables.
2554 if (Name.startswith("scas") &&
2555 (Operands.size() == 1 || Operands.size() == 2) &&
2556 (Name == "scas" || Name == "scasb" || Name == "scasw" ||
2557 Name == "scasl" || Name == "scasd" || Name == "scasq")) {
2558 TmpOperands.push_back(DefaultMemDIOperand(NameLoc));
2559 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2562 // Add default SI and DI operands to "cmps[bwlq]".
2563 if (Name.startswith("cmps") &&
2564 (Operands.size() == 1 || Operands.size() == 3) &&
2565 (Name == "cmps" || Name == "cmpsb" || Name == "cmpsw" ||
2566 Name == "cmpsl" || Name == "cmpsd" || Name == "cmpsq")) {
2567 AddDefaultSrcDestOperands(TmpOperands, DefaultMemDIOperand(NameLoc),
2568 DefaultMemSIOperand(NameLoc));
2569 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2572 // Add default SI and DI operands to "movs[bwlq]".
2573 if (((Name.startswith("movs") &&
2574 (Name == "movs" || Name == "movsb" || Name == "movsw" ||
2575 Name == "movsl" || Name == "movsd" || Name == "movsq")) ||
2576 (Name.startswith("smov") &&
2577 (Name == "smov" || Name == "smovb" || Name == "smovw" ||
2578 Name == "smovl" || Name == "smovd" || Name == "smovq"))) &&
2579 (Operands.size() == 1 || Operands.size() == 3)) {
2580 if (Name == "movsd" && Operands.size() == 1 && !isParsingIntelSyntax())
2581 Operands.back() = X86Operand::CreateToken("movsl", NameLoc);
2582 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
2583 DefaultMemDIOperand(NameLoc));
2584 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2587 // Check if we encountered an error for one the string insturctions
2588 if (HadVerifyError) {
2589 return HadVerifyError;
2592 // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>. Canonicalize to
2594 if ((Name.startswith("shr") || Name.startswith("sar") ||
2595 Name.startswith("shl") || Name.startswith("sal") ||
2596 Name.startswith("rcl") || Name.startswith("rcr") ||
2597 Name.startswith("rol") || Name.startswith("ror")) &&
2598 Operands.size() == 3) {
2599 if (isParsingIntelSyntax()) {
2601 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[2]);
2602 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2603 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2604 Operands.pop_back();
2606 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2607 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2608 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2609 Operands.erase(Operands.begin() + 1);
2613 // Transforms "int $3" into "int3" as a size optimization. We can't write an
2614 // instalias with an immediate operand yet.
2615 if (Name == "int" && Operands.size() == 2) {
2616 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2618 if (auto *CE = dyn_cast<MCConstantExpr>(Op1.getImm()))
2619 if (CE->getValue() == 3) {
2620 Operands.erase(Operands.begin() + 1);
2621 static_cast<X86Operand &>(*Operands[0]).setTokenValue("int3");
2625 // Transforms "xlat mem8" into "xlatb"
2626 if ((Name == "xlat" || Name == "xlatb") && Operands.size() == 2) {
2627 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2629 Warning(Op1.getStartLoc(), "memory operand is only for determining the "
2630 "size, (R|E)BX will be used for the location");
2631 Operands.pop_back();
2632 static_cast<X86Operand &>(*Operands[0]).setTokenValue("xlatb");
2637 Operands.push_back(X86Operand::CreatePrefix(Flags, NameLoc, NameLoc));
2641 bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) {
2645 bool X86AsmParser::validateInstruction(MCInst &Inst, const OperandVector &Ops) {
2646 const MCRegisterInfo *MRI = getContext().getRegisterInfo();
2648 switch (Inst.getOpcode()) {
2649 case X86::VGATHERDPDYrm:
2650 case X86::VGATHERDPDrm:
2651 case X86::VGATHERDPSYrm:
2652 case X86::VGATHERDPSrm:
2653 case X86::VGATHERQPDYrm:
2654 case X86::VGATHERQPDrm:
2655 case X86::VGATHERQPSYrm:
2656 case X86::VGATHERQPSrm:
2657 case X86::VPGATHERDDYrm:
2658 case X86::VPGATHERDDrm:
2659 case X86::VPGATHERDQYrm:
2660 case X86::VPGATHERDQrm:
2661 case X86::VPGATHERQDYrm:
2662 case X86::VPGATHERQDrm:
2663 case X86::VPGATHERQQYrm:
2664 case X86::VPGATHERQQrm: {
2665 unsigned Dest = MRI->getEncodingValue(Inst.getOperand(0).getReg());
2666 unsigned Mask = MRI->getEncodingValue(Inst.getOperand(1).getReg());
2668 MRI->getEncodingValue(Inst.getOperand(3 + X86::AddrIndexReg).getReg());
2669 if (Dest == Mask || Dest == Index || Mask == Index)
2670 return Warning(Ops[0]->getStartLoc(), "mask, index, and destination "
2671 "registers should be distinct");
2674 case X86::VGATHERDPDZ128rm:
2675 case X86::VGATHERDPDZ256rm:
2676 case X86::VGATHERDPDZrm:
2677 case X86::VGATHERDPSZ128rm:
2678 case X86::VGATHERDPSZ256rm:
2679 case X86::VGATHERDPSZrm:
2680 case X86::VGATHERQPDZ128rm:
2681 case X86::VGATHERQPDZ256rm:
2682 case X86::VGATHERQPDZrm:
2683 case X86::VGATHERQPSZ128rm:
2684 case X86::VGATHERQPSZ256rm:
2685 case X86::VGATHERQPSZrm:
2686 case X86::VPGATHERDDZ128rm:
2687 case X86::VPGATHERDDZ256rm:
2688 case X86::VPGATHERDDZrm:
2689 case X86::VPGATHERDQZ128rm:
2690 case X86::VPGATHERDQZ256rm:
2691 case X86::VPGATHERDQZrm:
2692 case X86::VPGATHERQDZ128rm:
2693 case X86::VPGATHERQDZ256rm:
2694 case X86::VPGATHERQDZrm:
2695 case X86::VPGATHERQQZ128rm:
2696 case X86::VPGATHERQQZ256rm:
2697 case X86::VPGATHERQQZrm: {
2698 unsigned Dest = MRI->getEncodingValue(Inst.getOperand(0).getReg());
2700 MRI->getEncodingValue(Inst.getOperand(4 + X86::AddrIndexReg).getReg());
2702 return Warning(Ops[0]->getStartLoc(), "index and destination registers "
2703 "should be distinct");
2711 static const char *getSubtargetFeatureName(uint64_t Val);
2713 void X86AsmParser::EmitInstruction(MCInst &Inst, OperandVector &Operands,
2715 Instrumentation->InstrumentAndEmitInstruction(
2716 Inst, Operands, getContext(), MII, Out,
2717 getParser().shouldPrintSchedInfo());
2720 bool X86AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2721 OperandVector &Operands,
2722 MCStreamer &Out, uint64_t &ErrorInfo,
2723 bool MatchingInlineAsm) {
2724 if (isParsingIntelSyntax())
2725 return MatchAndEmitIntelInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2727 return MatchAndEmitATTInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2731 void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op,
2732 OperandVector &Operands, MCStreamer &Out,
2733 bool MatchingInlineAsm) {
2734 // FIXME: This should be replaced with a real .td file alias mechanism.
2735 // Also, MatchInstructionImpl should actually *do* the EmitInstruction
2737 const char *Repl = StringSwitch<const char *>(Op.getToken())
2738 .Case("finit", "fninit")
2739 .Case("fsave", "fnsave")
2740 .Case("fstcw", "fnstcw")
2741 .Case("fstcww", "fnstcw")
2742 .Case("fstenv", "fnstenv")
2743 .Case("fstsw", "fnstsw")
2744 .Case("fstsww", "fnstsw")
2745 .Case("fclex", "fnclex")
2749 Inst.setOpcode(X86::WAIT);
2751 if (!MatchingInlineAsm)
2752 EmitInstruction(Inst, Operands, Out);
2753 Operands[0] = X86Operand::CreateToken(Repl, IDLoc);
2757 bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
2758 bool MatchingInlineAsm) {
2759 assert(ErrorInfo && "Unknown missing feature!");
2760 SmallString<126> Msg;
2761 raw_svector_ostream OS(Msg);
2762 OS << "instruction requires:";
2764 for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
2765 if (ErrorInfo & Mask)
2766 OS << ' ' << getSubtargetFeatureName(ErrorInfo & Mask);
2769 return Error(IDLoc, OS.str(), SMRange(), MatchingInlineAsm);
2772 static unsigned getPrefixes(OperandVector &Operands) {
2773 unsigned Result = 0;
2774 X86Operand &Prefix = static_cast<X86Operand &>(*Operands.back());
2775 if (Prefix.isPrefix()) {
2776 Result = Prefix.getPrefix();
2777 Operands.pop_back();
2782 bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
2783 OperandVector &Operands,
2785 uint64_t &ErrorInfo,
2786 bool MatchingInlineAsm) {
2787 assert(!Operands.empty() && "Unexpect empty operand list!");
2788 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2789 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
2790 SMRange EmptyRange = None;
2792 // First, handle aliases that expand to multiple instructions.
2793 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2795 bool WasOriginallyInvalidOperand = false;
2796 unsigned Prefixes = getPrefixes(Operands);
2801 Inst.setFlags(Prefixes);
2803 // First, try a direct match.
2804 switch (MatchInstruction(Operands, Inst, ErrorInfo, MatchingInlineAsm,
2805 isParsingIntelSyntax())) {
2806 default: llvm_unreachable("Unexpected match result!");
2808 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
2810 // Some instructions need post-processing to, for example, tweak which
2811 // encoding is selected. Loop on it while changes happen so the
2812 // individual transformations can chain off each other.
2813 if (!MatchingInlineAsm)
2814 while (processInstruction(Inst, Operands))
2818 if (!MatchingInlineAsm)
2819 EmitInstruction(Inst, Operands, Out);
2820 Opcode = Inst.getOpcode();
2822 case Match_MissingFeature:
2823 return ErrorMissingFeature(IDLoc, ErrorInfo, MatchingInlineAsm);
2824 case Match_InvalidOperand:
2825 WasOriginallyInvalidOperand = true;
2827 case Match_MnemonicFail:
2831 // FIXME: Ideally, we would only attempt suffix matches for things which are
2832 // valid prefixes, and we could just infer the right unambiguous
2833 // type. However, that requires substantially more matcher support than the
2836 // Change the operand to point to a temporary token.
2837 StringRef Base = Op.getToken();
2838 SmallString<16> Tmp;
2841 Op.setTokenValue(Tmp);
2843 // If this instruction starts with an 'f', then it is a floating point stack
2844 // instruction. These come in up to three forms for 32-bit, 64-bit, and
2845 // 80-bit floating point, which use the suffixes s,l,t respectively.
2847 // Otherwise, we assume that this may be an integer instruction, which comes
2848 // in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively.
2849 const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0";
2851 // Check for the various suffix matches.
2852 uint64_t ErrorInfoIgnore;
2853 uint64_t ErrorInfoMissingFeature = 0; // Init suppresses compiler warnings.
2856 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I) {
2857 Tmp.back() = Suffixes[I];
2858 Match[I] = MatchInstruction(Operands, Inst, ErrorInfoIgnore,
2859 MatchingInlineAsm, isParsingIntelSyntax());
2860 // If this returned as a missing feature failure, remember that.
2861 if (Match[I] == Match_MissingFeature)
2862 ErrorInfoMissingFeature = ErrorInfoIgnore;
2865 // Restore the old token.
2866 Op.setTokenValue(Base);
2868 // If exactly one matched, then we treat that as a successful match (and the
2869 // instruction will already have been filled in correctly, since the failing
2870 // matches won't have modified it).
2871 unsigned NumSuccessfulMatches =
2872 std::count(std::begin(Match), std::end(Match), Match_Success);
2873 if (NumSuccessfulMatches == 1) {
2875 if (!MatchingInlineAsm)
2876 EmitInstruction(Inst, Operands, Out);
2877 Opcode = Inst.getOpcode();
2881 // Otherwise, the match failed, try to produce a decent error message.
2883 // If we had multiple suffix matches, then identify this as an ambiguous
2885 if (NumSuccessfulMatches > 1) {
2887 unsigned NumMatches = 0;
2888 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I)
2889 if (Match[I] == Match_Success)
2890 MatchChars[NumMatches++] = Suffixes[I];
2892 SmallString<126> Msg;
2893 raw_svector_ostream OS(Msg);
2894 OS << "ambiguous instructions require an explicit suffix (could be ";
2895 for (unsigned i = 0; i != NumMatches; ++i) {
2898 if (i + 1 == NumMatches)
2900 OS << "'" << Base << MatchChars[i] << "'";
2903 Error(IDLoc, OS.str(), EmptyRange, MatchingInlineAsm);
2907 // Okay, we know that none of the variants matched successfully.
2909 // If all of the instructions reported an invalid mnemonic, then the original
2910 // mnemonic was invalid.
2911 if (std::count(std::begin(Match), std::end(Match), Match_MnemonicFail) == 4) {
2912 if (!WasOriginallyInvalidOperand) {
2913 return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'",
2914 Op.getLocRange(), MatchingInlineAsm);
2917 // Recover location info for the operand if we know which was the problem.
2918 if (ErrorInfo != ~0ULL) {
2919 if (ErrorInfo >= Operands.size())
2920 return Error(IDLoc, "too few operands for instruction", EmptyRange,
2923 X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo];
2924 if (Operand.getStartLoc().isValid()) {
2925 SMRange OperandRange = Operand.getLocRange();
2926 return Error(Operand.getStartLoc(), "invalid operand for instruction",
2927 OperandRange, MatchingInlineAsm);
2931 return Error(IDLoc, "invalid operand for instruction", EmptyRange,
2935 // If one instruction matched with a missing feature, report this as a
2937 if (std::count(std::begin(Match), std::end(Match),
2938 Match_MissingFeature) == 1) {
2939 ErrorInfo = ErrorInfoMissingFeature;
2940 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
2944 // If one instruction matched with an invalid operand, report this as an
2946 if (std::count(std::begin(Match), std::end(Match),
2947 Match_InvalidOperand) == 1) {
2948 return Error(IDLoc, "invalid operand for instruction", EmptyRange,
2952 // If all of these were an outright failure, report it in a useless way.
2953 Error(IDLoc, "unknown use of instruction mnemonic without a size suffix",
2954 EmptyRange, MatchingInlineAsm);
2958 bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
2959 OperandVector &Operands,
2961 uint64_t &ErrorInfo,
2962 bool MatchingInlineAsm) {
2963 assert(!Operands.empty() && "Unexpect empty operand list!");
2964 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2965 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
2966 StringRef Mnemonic = Op.getToken();
2967 SMRange EmptyRange = None;
2968 StringRef Base = Op.getToken();
2969 unsigned Prefixes = getPrefixes(Operands);
2971 // First, handle aliases that expand to multiple instructions.
2972 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2977 Inst.setFlags(Prefixes);
2979 // Find one unsized memory operand, if present.
2980 X86Operand *UnsizedMemOp = nullptr;
2981 for (const auto &Op : Operands) {
2982 X86Operand *X86Op = static_cast<X86Operand *>(Op.get());
2983 if (X86Op->isMemUnsized()) {
2984 UnsizedMemOp = X86Op;
2985 // Have we found an unqualified memory operand,
2986 // break. IA allows only one memory operand.
2991 // Allow some instructions to have implicitly pointer-sized operands. This is
2992 // compatible with gas.
2994 static const char *const PtrSizedInstrs[] = {"call", "jmp", "push"};
2995 for (const char *Instr : PtrSizedInstrs) {
2996 if (Mnemonic == Instr) {
2997 UnsizedMemOp->Mem.Size = getPointerWidth();
3003 SmallVector<unsigned, 8> Match;
3004 uint64_t ErrorInfoMissingFeature = 0;
3006 // If unsized push has immediate operand we should default the default pointer
3007 // size for the size.
3008 if (Mnemonic == "push" && Operands.size() == 2) {
3009 auto *X86Op = static_cast<X86Operand *>(Operands[1].get());
3010 if (X86Op->isImm()) {
3011 // If it's not a constant fall through and let remainder take care of it.
3012 const auto *CE = dyn_cast<MCConstantExpr>(X86Op->getImm());
3013 unsigned Size = getPointerWidth();
3015 (isIntN(Size, CE->getValue()) || isUIntN(Size, CE->getValue()))) {
3016 SmallString<16> Tmp;
3018 Tmp += (is64BitMode())
3020 : (is32BitMode()) ? "l" : (is16BitMode()) ? "w" : " ";
3021 Op.setTokenValue(Tmp);
3022 // Do match in ATT mode to allow explicit suffix usage.
3023 Match.push_back(MatchInstruction(Operands, Inst, ErrorInfo,
3025 false /*isParsingIntelSyntax()*/));
3026 Op.setTokenValue(Base);
3031 // If an unsized memory operand is present, try to match with each memory
3032 // operand size. In Intel assembly, the size is not part of the instruction
3034 if (UnsizedMemOp && UnsizedMemOp->isMemUnsized()) {
3035 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
3036 for (unsigned Size : MopSizes) {
3037 UnsizedMemOp->Mem.Size = Size;
3038 uint64_t ErrorInfoIgnore;
3039 unsigned LastOpcode = Inst.getOpcode();
3040 unsigned M = MatchInstruction(Operands, Inst, ErrorInfoIgnore,
3041 MatchingInlineAsm, isParsingIntelSyntax());
3042 if (Match.empty() || LastOpcode != Inst.getOpcode())
3045 // If this returned as a missing feature failure, remember that.
3046 if (Match.back() == Match_MissingFeature)
3047 ErrorInfoMissingFeature = ErrorInfoIgnore;
3050 // Restore the size of the unsized memory operand if we modified it.
3051 UnsizedMemOp->Mem.Size = 0;
3054 // If we haven't matched anything yet, this is not a basic integer or FPU
3055 // operation. There shouldn't be any ambiguity in our mnemonic table, so try
3056 // matching with the unsized operand.
3057 if (Match.empty()) {
3058 Match.push_back(MatchInstruction(
3059 Operands, Inst, ErrorInfo, MatchingInlineAsm, isParsingIntelSyntax()));
3060 // If this returned as a missing feature failure, remember that.
3061 if (Match.back() == Match_MissingFeature)
3062 ErrorInfoMissingFeature = ErrorInfo;
3065 // Restore the size of the unsized memory operand if we modified it.
3067 UnsizedMemOp->Mem.Size = 0;
3069 // If it's a bad mnemonic, all results will be the same.
3070 if (Match.back() == Match_MnemonicFail) {
3071 return Error(IDLoc, "invalid instruction mnemonic '" + Mnemonic + "'",
3072 Op.getLocRange(), MatchingInlineAsm);
3075 unsigned NumSuccessfulMatches =
3076 std::count(std::begin(Match), std::end(Match), Match_Success);
3078 // If matching was ambiguous and we had size information from the frontend,
3079 // try again with that. This handles cases like "movxz eax, m8/m16".
3080 if (UnsizedMemOp && NumSuccessfulMatches > 1 &&
3081 UnsizedMemOp->getMemFrontendSize()) {
3082 UnsizedMemOp->Mem.Size = UnsizedMemOp->getMemFrontendSize();
3083 unsigned M = MatchInstruction(
3084 Operands, Inst, ErrorInfo, MatchingInlineAsm, isParsingIntelSyntax());
3085 if (M == Match_Success)
3086 NumSuccessfulMatches = 1;
3088 // Add a rewrite that encodes the size information we used from the
3090 InstInfo->AsmRewrites->emplace_back(
3091 AOK_SizeDirective, UnsizedMemOp->getStartLoc(),
3092 /*Len=*/0, UnsizedMemOp->getMemFrontendSize());
3095 // If exactly one matched, then we treat that as a successful match (and the
3096 // instruction will already have been filled in correctly, since the failing
3097 // matches won't have modified it).
3098 if (NumSuccessfulMatches == 1) {
3099 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
3101 // Some instructions need post-processing to, for example, tweak which
3102 // encoding is selected. Loop on it while changes happen so the individual
3103 // transformations can chain off each other.
3104 if (!MatchingInlineAsm)
3105 while (processInstruction(Inst, Operands))
3108 if (!MatchingInlineAsm)
3109 EmitInstruction(Inst, Operands, Out);
3110 Opcode = Inst.getOpcode();
3112 } else if (NumSuccessfulMatches > 1) {
3113 assert(UnsizedMemOp &&
3114 "multiple matches only possible with unsized memory operands");
3115 return Error(UnsizedMemOp->getStartLoc(),
3116 "ambiguous operand size for instruction '" + Mnemonic + "\'",
3117 UnsizedMemOp->getLocRange());
3120 // If one instruction matched with a missing feature, report this as a
3122 if (std::count(std::begin(Match), std::end(Match),
3123 Match_MissingFeature) == 1) {
3124 ErrorInfo = ErrorInfoMissingFeature;
3125 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
3129 // If one instruction matched with an invalid operand, report this as an
3131 if (std::count(std::begin(Match), std::end(Match),
3132 Match_InvalidOperand) == 1) {
3133 return Error(IDLoc, "invalid operand for instruction", EmptyRange,
3137 // If all of these were an outright failure, report it in a useless way.
3138 return Error(IDLoc, "unknown instruction mnemonic", EmptyRange,
3142 bool X86AsmParser::OmitRegisterFromClobberLists(unsigned RegNo) {
3143 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo);
3146 bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
3147 MCAsmParser &Parser = getParser();
3148 StringRef IDVal = DirectiveID.getIdentifier();
3149 if (IDVal == ".word")
3150 return ParseDirectiveWord(2, DirectiveID.getLoc());
3151 else if (IDVal.startswith(".code"))
3152 return ParseDirectiveCode(IDVal, DirectiveID.getLoc());
3153 else if (IDVal.startswith(".att_syntax")) {
3154 getParser().setParsingInlineAsm(false);
3155 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3156 if (Parser.getTok().getString() == "prefix")
3158 else if (Parser.getTok().getString() == "noprefix")
3159 return Error(DirectiveID.getLoc(), "'.att_syntax noprefix' is not "
3160 "supported: registers must have a "
3161 "'%' prefix in .att_syntax");
3163 getParser().setAssemblerDialect(0);
3165 } else if (IDVal.startswith(".intel_syntax")) {
3166 getParser().setAssemblerDialect(1);
3167 getParser().setParsingInlineAsm(true);
3168 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3169 if (Parser.getTok().getString() == "noprefix")
3171 else if (Parser.getTok().getString() == "prefix")
3172 return Error(DirectiveID.getLoc(), "'.intel_syntax prefix' is not "
3173 "supported: registers must not have "
3174 "a '%' prefix in .intel_syntax");
3177 } else if (IDVal == ".even")
3178 return parseDirectiveEven(DirectiveID.getLoc());
3179 else if (IDVal == ".cv_fpo_proc")
3180 return parseDirectiveFPOProc(DirectiveID.getLoc());
3181 else if (IDVal == ".cv_fpo_setframe")
3182 return parseDirectiveFPOSetFrame(DirectiveID.getLoc());
3183 else if (IDVal == ".cv_fpo_pushreg")
3184 return parseDirectiveFPOPushReg(DirectiveID.getLoc());
3185 else if (IDVal == ".cv_fpo_stackalloc")
3186 return parseDirectiveFPOStackAlloc(DirectiveID.getLoc());
3187 else if (IDVal == ".cv_fpo_endprologue")
3188 return parseDirectiveFPOEndPrologue(DirectiveID.getLoc());
3189 else if (IDVal == ".cv_fpo_endproc")
3190 return parseDirectiveFPOEndProc(DirectiveID.getLoc());
3195 /// parseDirectiveEven
3197 bool X86AsmParser::parseDirectiveEven(SMLoc L) {
3198 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3199 TokError("unexpected token in directive");
3202 const MCSection *Section = getStreamer().getCurrentSectionOnly();
3204 getStreamer().InitSections(false);
3205 Section = getStreamer().getCurrentSectionOnly();
3207 if (Section->UseCodeAlign())
3208 getStreamer().EmitCodeAlignment(2, 0);
3210 getStreamer().EmitValueToAlignment(2, 0, 1, 0);
3213 /// ParseDirectiveWord
3214 /// ::= .word [ expression (, expression)* ]
3215 bool X86AsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
3216 MCAsmParser &Parser = getParser();
3217 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3219 const MCExpr *Value;
3220 SMLoc ExprLoc = getLexer().getLoc();
3221 if (getParser().parseExpression(Value))
3224 if (const auto *MCE = dyn_cast<MCConstantExpr>(Value)) {
3225 assert(Size <= 8 && "Invalid size");
3226 uint64_t IntValue = MCE->getValue();
3227 if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))
3228 return Error(ExprLoc, "literal value out of range for directive");
3229 getStreamer().EmitIntValue(IntValue, Size);
3231 getStreamer().EmitValue(Value, Size, ExprLoc);
3234 if (getLexer().is(AsmToken::EndOfStatement))
3237 // FIXME: Improve diagnostic.
3238 if (getLexer().isNot(AsmToken::Comma)) {
3239 Error(L, "unexpected token in directive");
3250 /// ParseDirectiveCode
3251 /// ::= .code16 | .code32 | .code64
3252 bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
3253 MCAsmParser &Parser = getParser();
3255 if (IDVal == ".code16") {
3257 if (!is16BitMode()) {
3258 SwitchMode(X86::Mode16Bit);
3259 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
3261 } else if (IDVal == ".code16gcc") {
3262 // .code16gcc parses as if in 32-bit mode, but emits code in 16-bit mode.
3265 if (!is16BitMode()) {
3266 SwitchMode(X86::Mode16Bit);
3267 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
3269 } else if (IDVal == ".code32") {
3271 if (!is32BitMode()) {
3272 SwitchMode(X86::Mode32Bit);
3273 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
3275 } else if (IDVal == ".code64") {
3277 if (!is64BitMode()) {
3278 SwitchMode(X86::Mode64Bit);
3279 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code64);
3282 Error(L, "unknown directive " + IDVal);
3290 bool X86AsmParser::parseDirectiveFPOProc(SMLoc L) {
3291 MCAsmParser &Parser = getParser();
3294 if (Parser.parseIdentifier(ProcName))
3295 return Parser.TokError("expected symbol name");
3296 if (Parser.parseIntToken(ParamsSize, "expected parameter byte count"))
3298 if (!isUIntN(32, ParamsSize))
3299 return Parser.TokError("parameters size out of range");
3300 if (Parser.parseEOL("unexpected tokens"))
3301 return addErrorSuffix(" in '.cv_fpo_proc' directive");
3302 MCSymbol *ProcSym = getContext().getOrCreateSymbol(ProcName);
3303 return getTargetStreamer().emitFPOProc(ProcSym, ParamsSize, L);
3306 // .cv_fpo_setframe ebp
3307 bool X86AsmParser::parseDirectiveFPOSetFrame(SMLoc L) {
3308 MCAsmParser &Parser = getParser();
3311 if (ParseRegister(Reg, DummyLoc, DummyLoc) ||
3312 Parser.parseEOL("unexpected tokens"))
3313 return addErrorSuffix(" in '.cv_fpo_setframe' directive");
3314 return getTargetStreamer().emitFPOSetFrame(Reg, L);
3317 // .cv_fpo_pushreg ebx
3318 bool X86AsmParser::parseDirectiveFPOPushReg(SMLoc L) {
3319 MCAsmParser &Parser = getParser();
3322 if (ParseRegister(Reg, DummyLoc, DummyLoc) ||
3323 Parser.parseEOL("unexpected tokens"))
3324 return addErrorSuffix(" in '.cv_fpo_pushreg' directive");
3325 return getTargetStreamer().emitFPOPushReg(Reg, L);
3328 // .cv_fpo_stackalloc 20
3329 bool X86AsmParser::parseDirectiveFPOStackAlloc(SMLoc L) {
3330 MCAsmParser &Parser = getParser();
3332 if (Parser.parseIntToken(Offset, "expected offset") ||
3333 Parser.parseEOL("unexpected tokens"))
3334 return addErrorSuffix(" in '.cv_fpo_stackalloc' directive");
3335 return getTargetStreamer().emitFPOStackAlloc(Offset, L);
3338 // .cv_fpo_endprologue
3339 bool X86AsmParser::parseDirectiveFPOEndPrologue(SMLoc L) {
3340 MCAsmParser &Parser = getParser();
3341 if (Parser.parseEOL("unexpected tokens"))
3342 return addErrorSuffix(" in '.cv_fpo_endprologue' directive");
3343 return getTargetStreamer().emitFPOEndPrologue(L);
3347 bool X86AsmParser::parseDirectiveFPOEndProc(SMLoc L) {
3348 MCAsmParser &Parser = getParser();
3349 if (Parser.parseEOL("unexpected tokens"))
3350 return addErrorSuffix(" in '.cv_fpo_endproc' directive");
3351 return getTargetStreamer().emitFPOEndProc(L);
3354 // Force static initialization.
3355 extern "C" void LLVMInitializeX86AsmParser() {
3356 RegisterMCAsmParser<X86AsmParser> X(getTheX86_32Target());
3357 RegisterMCAsmParser<X86AsmParser> Y(getTheX86_64Target());
3360 #define GET_REGISTER_MATCHER
3361 #define GET_MATCHER_IMPLEMENTATION
3362 #define GET_SUBTARGET_FEATURE_NAME
3363 #include "X86GenAsmMatcher.inc"