44 if (Scale != 1 && Scale != 2 && Scale != 4 && Scale != 8) {
45 ErrMsg =
"scale factor in address must be 1, 2, 4 or 8";
53 static const char OpPrecedence[] = {
74 std::unique_ptr<X86AsmInstrumentation> Instrumentation;
78 SMLoc consumeToken() {
86 assert(getParser().getStreamer().getTargetStreamer() &&
87 "do not have a target streamer");
93 uint64_t &
ErrorInfo,
bool matchingInlineAsm,
94 unsigned VariantID = 0) {
97 SwitchMode(X86::Mode32Bit);
98 unsigned rv = MatchInstructionImpl(Operands, Inst, ErrorInfo,
99 matchingInlineAsm, VariantID);
101 SwitchMode(X86::Mode16Bit);
105 enum InfixCalculatorTok {
124 enum IntelOperatorKind {
132 class InfixCalculator {
133 typedef std::pair< InfixCalculatorTok, int64_t > ICToken;
137 bool isUnaryOperator(
const InfixCalculatorTok
Op) {
138 return Op == IC_NEG || Op == IC_NOT;
142 int64_t popOperand() {
143 assert (!PostfixStack.
empty() &&
"Poped an empty stack!");
145 if (!(Op.first == IC_IMM || Op.first == IC_REGISTER))
149 void pushOperand(InfixCalculatorTok Op, int64_t Val = 0) {
150 assert ((Op == IC_IMM || Op == IC_REGISTER) &&
151 "Unexpected operand!");
152 PostfixStack.
push_back(std::make_pair(Op, Val));
155 void popOperator() { InfixOperatorStack.
pop_back(); }
156 void pushOperator(InfixCalculatorTok Op) {
158 if (InfixOperatorStack.
empty()) {
166 unsigned Idx = InfixOperatorStack.
size() - 1;
167 InfixCalculatorTok StackOp = InfixOperatorStack[Idx];
168 if (OpPrecedence[Op] > OpPrecedence[StackOp] || StackOp == IC_LPAREN) {
175 unsigned ParenCount = 0;
178 if (InfixOperatorStack.
empty())
181 Idx = InfixOperatorStack.
size() - 1;
182 StackOp = InfixOperatorStack[Idx];
183 if (!(OpPrecedence[StackOp] >= OpPrecedence[Op] || ParenCount))
188 if (!ParenCount && StackOp == IC_LPAREN)
191 if (StackOp == IC_RPAREN) {
194 }
else if (StackOp == IC_LPAREN) {
199 PostfixStack.
push_back(std::make_pair(StackOp, 0));
208 while (!InfixOperatorStack.
empty()) {
209 InfixCalculatorTok StackOp = InfixOperatorStack.
pop_back_val();
210 if (StackOp != IC_LPAREN && StackOp != IC_RPAREN)
211 PostfixStack.
push_back(std::make_pair(StackOp, 0));
214 if (PostfixStack.
empty())
218 for (
unsigned i = 0, e = PostfixStack.
size(); i != e; ++i) {
219 ICToken Op = PostfixStack[i];
220 if (Op.first == IC_IMM || Op.first == IC_REGISTER) {
222 }
else if (isUnaryOperator(Op.first)) {
223 assert (OperandStack.
size() > 0 &&
"Too few operands.");
225 assert (Operand.first == IC_IMM &&
226 "Unary operation with a register!");
232 OperandStack.
push_back(std::make_pair(IC_IMM, -Operand.second));
235 OperandStack.
push_back(std::make_pair(IC_IMM, ~Operand.second));
239 assert (OperandStack.
size() > 1 &&
"Too few operands.");
248 Val = Op1.second + Op2.second;
249 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
252 Val = Op1.second - Op2.second;
253 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
256 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
257 "Multiply operation with an immediate and a register!");
258 Val = Op1.second * Op2.second;
259 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
262 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
263 "Divide operation with an immediate and a register!");
264 assert (Op2.second != 0 &&
"Division by zero!");
265 Val = Op1.second / Op2.second;
266 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
269 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
270 "Modulo operation with an immediate and a register!");
271 Val = Op1.second % Op2.second;
272 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
275 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
276 "Or operation with an immediate and a register!");
277 Val = Op1.second | Op2.second;
278 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
281 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
282 "Xor operation with an immediate and a register!");
283 Val = Op1.second ^ Op2.second;
284 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
287 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
288 "And operation with an immediate and a register!");
289 Val = Op1.second & Op2.second;
290 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
293 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
294 "Left shift operation with an immediate and a register!");
295 Val = Op1.second << Op2.second;
296 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
299 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
300 "Right shift operation with an immediate and a register!");
301 Val = Op1.second >> Op2.second;
302 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
307 assert (OperandStack.
size() == 1 &&
"Expected a single result.");
312 enum IntelExprState {
335 class IntelExprStateMachine {
336 IntelExprState State, PrevState;
337 unsigned BaseReg, IndexReg, TmpReg, Scale;
347 IntelExprStateMachine()
348 : State(IES_INIT), PrevState(IES_ERROR), BaseReg(0), IndexReg(0),
349 TmpReg(0), Scale(0), Imm(0), Sym(
nullptr), BracCount(0),
352 void addImm(int64_t imm) { Imm += imm; }
353 short getBracCount() {
return BracCount; }
354 bool isMemExpr() {
return MemExpr; }
355 unsigned getBaseReg() {
return BaseReg; }
356 unsigned getIndexReg() {
return IndexReg; }
357 unsigned getScale() {
return Scale; }
359 StringRef getSymName() {
return SymName; }
360 int64_t getImm() {
return Imm + IC.execute(); }
361 bool isValidEndState() {
362 return State == IES_RBRAC || State == IES_INTEGER;
364 bool hadError() {
return State == IES_ERROR; }
368 IntelExprState CurrState = State;
377 IC.pushOperator(IC_OR);
380 PrevState = CurrState;
383 IntelExprState CurrState = State;
392 IC.pushOperator(IC_XOR);
395 PrevState = CurrState;
398 IntelExprState CurrState = State;
407 IC.pushOperator(IC_AND);
410 PrevState = CurrState;
413 IntelExprState CurrState = State;
422 IC.pushOperator(IC_LSHIFT);
425 PrevState = CurrState;
428 IntelExprState CurrState = State;
437 IC.pushOperator(IC_RSHIFT);
440 PrevState = CurrState;
443 IntelExprState CurrState = State;
452 IC.pushOperator(IC_PLUS);
453 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
460 ErrMsg =
"BaseReg/IndexReg already set!";
469 PrevState = CurrState;
473 IntelExprState CurrState = State;
497 if (CurrState == IES_REGISTER || CurrState == IES_RPAREN ||
498 CurrState == IES_INTEGER || CurrState == IES_RBRAC)
499 IC.pushOperator(IC_MINUS);
500 else if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
502 ErrMsg =
"Scale can't be negative";
505 IC.pushOperator(IC_NEG);
506 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
513 ErrMsg =
"BaseReg/IndexReg already set!";
522 PrevState = CurrState;
526 IntelExprState CurrState = State;
546 IC.pushOperator(IC_NOT);
549 PrevState = CurrState;
553 IntelExprState CurrState = State;
561 State = IES_REGISTER;
563 IC.pushOperand(IC_REGISTER);
567 if (PrevState == IES_INTEGER) {
569 ErrMsg =
"BaseReg/IndexReg already set!";
572 State = IES_REGISTER;
575 Scale = IC.popOperand();
578 IC.pushOperand(IC_IMM);
585 PrevState = CurrState;
590 bool ParsingInlineAsm,
StringRef &ErrMsg) {
592 if (ParsingInlineAsm)
596 if (
auto *CE = dyn_cast<MCConstantExpr>(SymRef))
597 return onInteger(CE->getValue(), ErrMsg);
599 bool HasSymbol = Sym !=
nullptr;
612 SymName = SymRefName;
613 IC.pushOperand(IC_IMM);
614 if (ParsingInlineAsm)
619 ErrMsg =
"cannot use more than one symbol in memory operand";
622 bool onInteger(int64_t TmpInt,
StringRef &ErrMsg) {
623 IntelExprState CurrState = State;
643 if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
646 ErrMsg =
"BaseReg/IndexReg already set!";
656 IC.pushOperand(IC_IMM, TmpInt);
660 PrevState = CurrState;
672 State = IES_MULTIPLY;
673 IC.pushOperator(IC_MULTIPLY);
686 IC.pushOperator(IC_DIVIDE);
699 IC.pushOperator(IC_MOD);
715 IC.pushOperator(IC_PLUS);
718 assert(!BracCount &&
"BracCount should be zero on parsing's start");
727 IntelExprState CurrState = State;
735 if (BracCount-- != 1)
738 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
744 assert (!IndexReg &&
"BaseReg/IndexReg already set!");
751 PrevState = CurrState;
755 IntelExprState CurrState = State;
775 IC.pushOperator(IC_LPAREN);
778 PrevState = CurrState;
790 IC.pushOperator(IC_RPAREN);
797 bool MatchingInlineAsm =
false) {
799 if (MatchingInlineAsm) {
800 if (!getLexer().isAtStartOfStatement())
804 return Parser.
Error(L, Msg, Range);
812 std::unique_ptr<X86Operand> DefaultMemSIOperand(
SMLoc Loc);
813 std::unique_ptr<X86Operand> DefaultMemDIOperand(
SMLoc Loc);
814 bool IsSIReg(
unsigned Reg);
815 unsigned GetSIDIForRegClass(
unsigned RegClassID,
unsigned Reg,
bool IsSIReg);
818 std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
819 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst);
822 std::unique_ptr<X86Operand> ParseOperand();
823 std::unique_ptr<X86Operand> ParseATTOperand();
824 std::unique_ptr<X86Operand> ParseIntelOperand();
825 std::unique_ptr<X86Operand> ParseIntelOffsetOfOperator();
826 bool ParseIntelDotOperator(IntelExprStateMachine &SM,
SMLoc &End);
828 unsigned ParseIntelInlineAsmOperator(
unsigned OpKind);
829 std::unique_ptr<X86Operand> ParseRoundingModeOp(
SMLoc Start);
830 bool ParseIntelNamedOperator(
StringRef Name, IntelExprStateMachine &SM);
831 void RewriteIntelExpression(IntelExprStateMachine &SM,
SMLoc Start,
833 bool ParseIntelExpression(IntelExprStateMachine &SM,
SMLoc &End);
834 bool ParseIntelInlineAsmIdentifier(
const MCExpr *&Val,
StringRef &Identifier,
836 bool IsUnevaluatedOperand,
SMLoc &End);
838 std::unique_ptr<X86Operand> ParseMemOperand(
unsigned SegReg,
840 const SMLoc &StartLoc,
843 bool ParseIntelMemoryOperandSize(
unsigned &
Size);
844 std::unique_ptr<X86Operand>
845 CreateMemForInlineAsm(
unsigned SegReg,
const MCExpr *Disp,
unsigned BaseReg,
846 unsigned IndexReg,
unsigned Scale,
SMLoc Start,
850 bool parseDirectiveEven(
SMLoc L);
854 bool parseDirectiveFPOProc(
SMLoc L);
855 bool parseDirectiveFPOSetFrame(
SMLoc L);
856 bool parseDirectiveFPOPushReg(
SMLoc L);
857 bool parseDirectiveFPOStackAlloc(
SMLoc L);
858 bool parseDirectiveFPOStackAlign(
SMLoc L);
859 bool parseDirectiveFPOEndPrologue(
SMLoc L);
860 bool parseDirectiveFPOEndProc(
SMLoc L);
861 bool parseDirectiveFPOData(
SMLoc L);
870 bool MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
873 bool MatchingInlineAsm)
override;
878 bool ErrorMissingFeature(
SMLoc IDLoc, uint64_t ErrorInfo,
879 bool MatchingInlineAsm);
881 bool MatchAndEmitATTInstruction(
SMLoc IDLoc,
unsigned &Opcode,
884 bool MatchingInlineAsm);
886 bool MatchAndEmitIntelInstruction(
SMLoc IDLoc,
unsigned &Opcode,
889 bool MatchingInlineAsm);
891 bool OmitRegisterFromClobberLists(
unsigned RegNo)
override;
899 bool ParseZ(std::unique_ptr<X86Operand> &
Z,
const SMLoc &StartLoc);
901 bool is64BitMode()
const {
903 return getSTI().getFeatureBits()[X86::Mode64Bit];
905 bool is32BitMode()
const {
907 return getSTI().getFeatureBits()[X86::Mode32Bit];
909 bool is16BitMode()
const {
911 return getSTI().getFeatureBits()[X86::Mode16Bit];
913 void SwitchMode(
unsigned mode) {
915 FeatureBitset AllModes({X86::Mode64Bit, X86::Mode32Bit, X86::Mode16Bit});
917 uint64_t FB = ComputeAvailableFeatures(
919 setAvailableFeatures(FB);
924 unsigned getPointerWidth() {
925 if (is16BitMode())
return 16;
926 if (is32BitMode())
return 32;
927 if (is64BitMode())
return 64;
931 bool isParsingIntelSyntax() {
932 return getParser().getAssemblerDialect();
938 #define GET_ASSEMBLER_HEADER 939 #include "X86GenAsmMatcher.inc" 953 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
954 Instrumentation.reset(
958 bool ParseRegister(
unsigned &RegNo,
SMLoc &StartLoc,
SMLoc &EndLoc)
override;
960 void SetFrameRegister(
unsigned RegNo)
override;
962 bool parsePrimaryExpr(
const MCExpr *&Res,
SMLoc &EndLoc)
override;
967 bool ParseDirective(
AsmToken DirectiveID)
override;
979 unsigned Scale,
bool Is64BitMode,
986 !(BaseReg == X86::RIP || BaseReg == X86::EIP ||
987 X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg) ||
988 X86MCRegisterClasses[X86::GR32RegClassID].
contains(BaseReg) ||
989 X86MCRegisterClasses[X86::GR64RegClassID].
contains(BaseReg))) {
990 ErrMsg =
"invalid base+index expression";
995 !(IndexReg == X86::EIZ || IndexReg == X86::RIZ ||
996 X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg) ||
997 X86MCRegisterClasses[X86::GR32RegClassID].
contains(IndexReg) ||
998 X86MCRegisterClasses[X86::GR64RegClassID].
contains(IndexReg) ||
999 X86MCRegisterClasses[X86::VR128XRegClassID].
contains(IndexReg) ||
1000 X86MCRegisterClasses[X86::VR256XRegClassID].
contains(IndexReg) ||
1001 X86MCRegisterClasses[X86::VR512RegClassID].
contains(IndexReg))) {
1002 ErrMsg =
"invalid base+index expression";
1006 if (((BaseReg == X86::RIP || BaseReg == X86::EIP) && IndexReg != 0) ||
1007 IndexReg == X86::EIP || IndexReg == X86::RIP ||
1008 IndexReg ==
X86::ESP || IndexReg == X86::RSP) {
1009 ErrMsg =
"invalid base+index expression";
1015 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg) &&
1016 (Is64BitMode || (BaseReg != X86::BX && BaseReg != X86::BP &&
1017 BaseReg !=
X86::SI && BaseReg != X86::DI))) {
1018 ErrMsg =
"invalid 16-bit base register";
1023 X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg)) {
1024 ErrMsg =
"16-bit memory operand may not include only index register";
1028 if (BaseReg != 0 && IndexReg != 0) {
1029 if (X86MCRegisterClasses[X86::GR64RegClassID].
contains(BaseReg) &&
1030 (X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg) ||
1031 X86MCRegisterClasses[X86::GR32RegClassID].
contains(IndexReg) ||
1032 IndexReg == X86::EIZ)) {
1033 ErrMsg =
"base register is 64-bit, but index register is not";
1036 if (X86MCRegisterClasses[X86::GR32RegClassID].
contains(BaseReg) &&
1037 (X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg) ||
1038 X86MCRegisterClasses[X86::GR64RegClassID].
contains(IndexReg) ||
1039 IndexReg == X86::RIZ)) {
1040 ErrMsg =
"base register is 32-bit, but index register is not";
1043 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg)) {
1044 if (X86MCRegisterClasses[X86::GR32RegClassID].
contains(IndexReg) ||
1045 X86MCRegisterClasses[X86::GR64RegClassID].
contains(IndexReg)) {
1046 ErrMsg =
"base register is 16-bit, but index register is not";
1049 if ((BaseReg != X86::BX && BaseReg != X86::BP) ||
1050 (IndexReg !=
X86::SI && IndexReg != X86::DI)) {
1051 ErrMsg =
"invalid 16-bit base/index register combination";
1058 if (!Is64BitMode && BaseReg != 0 &&
1059 (BaseReg == X86::RIP || BaseReg == X86::EIP)) {
1060 ErrMsg =
"IP-relative addressing requires 64-bit mode";
1067 bool X86AsmParser::ParseRegister(
unsigned &RegNo,
1072 StartLoc = PercentTok.
getLoc();
1083 if (isParsingIntelSyntax())
return true;
1084 return Error(StartLoc,
"invalid register name",
1096 if (isParsingInlineAsm() && isParsingIntelSyntax() && RegNo == X86::EFLAGS)
1099 if (!is64BitMode()) {
1105 if (RegNo == X86::RIZ || RegNo == X86::RIP ||
1106 X86MCRegisterClasses[X86::GR64RegClassID].
contains(RegNo) ||
1111 return Error(StartLoc,
1112 "register %" + RegName +
" is only available in 64-bit mode",
1118 if (RegNo == X86::ST0) {
1129 return Error(IntTok.
getLoc(),
"expected stack index");
1131 case 0: RegNo = X86::ST0;
break;
1132 case 1: RegNo = X86::ST1;
break;
1133 case 2: RegNo = X86::ST2;
break;
1134 case 3: RegNo = X86::ST3;
break;
1135 case 4: RegNo = X86::ST4;
break;
1136 case 5: RegNo = X86::ST5;
break;
1137 case 6: RegNo = X86::ST6;
break;
1138 case 7: RegNo = X86::ST7;
break;
1139 default:
return Error(IntTok.
getLoc(),
"invalid stack index");
1157 case '0': RegNo = X86::DR0;
break;
1158 case '1': RegNo = X86::DR1;
break;
1159 case '2': RegNo = X86::DR2;
break;
1160 case '3': RegNo = X86::DR3;
break;
1161 case '4': RegNo = X86::DR4;
break;
1162 case '5': RegNo = X86::DR5;
break;
1163 case '6': RegNo = X86::DR6;
break;
1164 case '7': RegNo = X86::DR7;
break;
1165 case '8': RegNo = X86::DR8;
break;
1166 case '9': RegNo = X86::DR9;
break;
1170 case '0': RegNo = X86::DR10;
break;
1171 case '1': RegNo = X86::DR11;
break;
1172 case '2': RegNo = X86::DR12;
break;
1173 case '3': RegNo = X86::DR13;
break;
1174 case '4': RegNo = X86::DR14;
break;
1175 case '5': RegNo = X86::DR15;
break;
1187 if (isParsingIntelSyntax())
return true;
1188 return Error(StartLoc,
"invalid register name",
1196 void X86AsmParser::SetFrameRegister(
unsigned RegNo) {
1197 Instrumentation->SetInitialFrameRegister(RegNo);
1200 std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(
SMLoc Loc) {
1201 bool Parse32 = is32BitMode() || Code16GCC;
1202 unsigned Basereg = is64BitMode() ? X86::RSI : (Parse32 ?
X86::ESI :
X86::SI);
1209 std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand(
SMLoc Loc) {
1210 bool Parse32 = is32BitMode() || Code16GCC;
1211 unsigned Basereg = is64BitMode() ? X86::RDI : (Parse32 ?
X86::EDI : X86::DI);
1218 bool X86AsmParser::IsSIReg(
unsigned Reg) {
1232 unsigned X86AsmParser::GetSIDIForRegClass(
unsigned RegClassID,
unsigned Reg,
1234 switch (RegClassID) {
1236 case X86::GR64RegClassID:
1237 return IsSIReg ? X86::RSI : X86::RDI;
1238 case X86::GR32RegClassID:
1240 case X86::GR16RegClassID:
1241 return IsSIReg ?
X86::SI : X86::DI;
1245 void X86AsmParser::AddDefaultSrcDestOperands(
1246 OperandVector& Operands, std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
1247 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst) {
1248 if (isParsingIntelSyntax()) {
1258 bool X86AsmParser::VerifyAndAdjustOperands(
OperandVector &OrigOperands,
1261 if (OrigOperands.
size() > 1) {
1264 "Operand size mismatch");
1268 int RegClassID = -1;
1269 for (
unsigned int i = 0; i < FinalOperands.
size(); ++i) {
1273 if (FinalOp.
isReg() &&
1278 if (FinalOp.
isMem()) {
1280 if (!OrigOp.
isMem())
1289 if (RegClassID != -1 &&
1290 !X86MCRegisterClasses[RegClassID].
contains(OrigReg)) {
1292 "mismatching source and destination index registers");
1295 if (X86MCRegisterClasses[X86::GR64RegClassID].
contains(OrigReg))
1296 RegClassID = X86::GR64RegClassID;
1297 else if (X86MCRegisterClasses[X86::GR32RegClassID].
contains(OrigReg))
1298 RegClassID = X86::GR32RegClassID;
1299 else if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(OrigReg))
1300 RegClassID = X86::GR16RegClassID;
1306 bool IsSI = IsSIReg(FinalReg);
1307 FinalReg = GetSIDIForRegClass(RegClassID, FinalReg, IsSI);
1309 if (FinalReg != OrigReg) {
1310 std::string RegName = IsSI ?
"ES:(R|E)SI" :
"ES:(R|E)DI";
1311 Warnings.push_back(std::make_pair(
1313 "memory operand is only for determining the size, " + RegName +
1314 " will be used for the location"));
1325 for (
auto &WarningMsg : Warnings) {
1326 Warning(WarningMsg.first, WarningMsg.second);
1330 for (
unsigned int i = 0; i < FinalOperands.
size(); ++i)
1334 for (
unsigned int i = 0; i < FinalOperands.
size(); ++i)
1335 OrigOperands.
push_back(std::move(FinalOperands[i]));
1340 std::unique_ptr<X86Operand> X86AsmParser::ParseOperand() {
1341 if (isParsingIntelSyntax())
1342 return ParseIntelOperand();
1343 return ParseATTOperand();
1346 std::unique_ptr<X86Operand> X86AsmParser::CreateMemForInlineAsm(
1347 unsigned SegReg,
const MCExpr *Disp,
unsigned BaseReg,
unsigned IndexReg,
1355 Size = getPointerWidth();
1367 unsigned FrontendSize = 0;
1368 void *Decl =
nullptr;
1369 bool IsGlobalLV =
false;
1372 FrontendSize = Info.
Var.
Type * 8;
1378 if (IsGlobalLV && (BaseReg || IndexReg)) {
1384 BaseReg = BaseReg ? BaseReg : 1;
1386 IndexReg, Scale, Start, End, Size, Identifier,
1387 Decl, FrontendSize);
1394 bool X86AsmParser::ParseIntelNamedOperator(
StringRef Name, IntelExprStateMachine &SM) {
1417 bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM,
SMLoc &End) {
1425 bool UpdateLocLex =
true;
1430 if ((Done = SM.isValidEndState()))
1432 return Error(Tok.
getLoc(),
"unknown token in expression");
1438 UpdateLocLex =
false;
1439 if (ParseIntelDotOperator(SM, End))
1447 UpdateLocLex =
false;
1451 if (SM.onRegister(Reg, ErrMsg))
1456 if ((UpdateLocLex = ParseIntelNamedOperator(Identifier, SM)))
1461 if (!isParsingInlineAsm()) {
1462 if (getParser().parsePrimaryExpr(Val, End)) {
1463 return Error(Tok.
getLoc(),
"Unexpected identifier!");
1464 }
else if (SM.onIdentifierExpr(Val, Identifier, Info,
false, ErrMsg)) {
1465 return Error(IdentLoc, ErrMsg);
1470 if (
unsigned OpKind = IdentifyIntelInlineAsmOperator(Identifier)) {
1471 if (OpKind == IOK_OFFSET)
1472 return Error(IdentLoc,
"Dealing OFFSET operator as part of" 1473 "a compound immediate expression is yet to be supported");
1474 if (int64_t Val = ParseIntelInlineAsmOperator(OpKind)) {
1475 if (SM.onInteger(Val, ErrMsg))
1476 return Error(IdentLoc, ErrMsg);
1483 if (ParseIntelDotOperator(SM, End))
1490 return Error(IdentLoc,
"expected identifier");
1491 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
false, End))
1493 else if (SM.onIdentifierExpr(Val, Identifier, Info,
true, ErrMsg))
1494 return Error(IdentLoc, ErrMsg);
1499 SMLoc Loc = getTok().getLoc();
1500 int64_t
IntVal = getTok().getIntVal();
1501 End = consumeToken();
1502 UpdateLocLex =
false;
1505 if (IDVal ==
"f" || IDVal ==
"b") {
1507 getContext().getDirectionalLocalSymbol(IntVal, IDVal ==
"b");
1512 return Error(Loc,
"invalid reference to undefined symbol");
1515 if (SM.onIdentifierExpr(Val, Identifier, Info,
1516 isParsingInlineAsm(), ErrMsg))
1517 return Error(Loc, ErrMsg);
1518 End = consumeToken();
1520 if (SM.onInteger(IntVal, ErrMsg))
1521 return Error(Loc, ErrMsg);
1524 if (SM.onInteger(IntVal, ErrMsg))
1525 return Error(Loc, ErrMsg);
1530 if (SM.onPlus(ErrMsg))
1531 return Error(getTok().getLoc(), ErrMsg);
1534 if (SM.onMinus(ErrMsg))
1535 return Error(getTok().getLoc(), ErrMsg);
1545 SM.onLShift();
break;
1547 SM.onRShift();
break;
1550 return Error(Tok.
getLoc(),
"unexpected bracket encountered");
1554 return Error(Tok.
getLoc(),
"unexpected bracket encountered");
1560 return Error(Tok.
getLoc(),
"unknown token in expression");
1562 if (!Done && UpdateLocLex)
1563 End = consumeToken();
1570 void X86AsmParser::RewriteIntelExpression(IntelExprStateMachine &SM,
1578 InstInfo->AsmRewrites->emplace_back(
AOK_Skip, Start, Len);
1583 if (!(SM.getBaseReg() || SM.getIndexReg() || SM.getImm())) {
1585 InstInfo->AsmRewrites->emplace_back(
AOK_Skip, Loc, ExprLen);
1592 if (SM.getBaseReg())
1594 if (SM.getIndexReg())
1597 IntelExpr Expr(BaseRegStr, IndexRegStr, SM.getScale(), SM.getImm(), SM.isMemExpr());
1598 InstInfo->AsmRewrites->emplace_back(Loc, ExprLen, Expr);
1602 bool X86AsmParser::ParseIntelInlineAsmIdentifier(
const MCExpr *&Val,
1605 bool IsUnevaluatedOperand,
1608 assert(isParsingInlineAsm() &&
"Expected to be parsing inline assembly.");
1612 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);
1624 Identifier = LineBuf;
1630 "frontend claimed part of a token?");
1636 SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(),
1638 assert(InternalName.
size() &&
"We should have an internal name here.");
1640 InstInfo->AsmRewrites->emplace_back(
AOK_Label, Loc, Identifier.
size(),
1645 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
1652 std::unique_ptr<X86Operand>
1653 X86AsmParser::ParseRoundingModeOp(
SMLoc Start) {
1657 const SMLoc consumedToken = consumeToken();
1666 return ErrorOperand(Tok.
getLoc(),
"Invalid rounding mode.");
1669 return ErrorOperand(Tok.
getLoc(),
"Expected - at this point");
1673 return ErrorOperand(Tok.
getLoc(),
"Expected } at this point");
1676 const MCExpr *RndModeOp =
1683 return ErrorOperand(Tok.
getLoc(),
"Expected } at this point");
1687 return ErrorOperand(Tok.
getLoc(),
"unknown token in expression");
1691 bool X86AsmParser::ParseIntelDotOperator(IntelExprStateMachine &SM,
SMLoc &End) {
1706 std::pair<StringRef, StringRef> BaseMember = DotDispStr.
split(
'.');
1707 if (SemaCallback->LookupInlineAsmField(BaseMember.first, BaseMember.second,
1709 return Error(Tok.
getLoc(),
"Unable to lookup field reference!");
1711 return Error(Tok.
getLoc(),
"Unexpected token type!");
1715 const char *DotExprEndLoc = DotDispStr.
data() + DotDispStr.
size();
1724 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOffsetOfOperator() {
1734 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
1738 void *Decl =
nullptr;
1741 return ErrorOperand(Start,
"offset operator cannot yet handle constants");
1745 InstInfo->AsmRewrites->emplace_back(
AOK_Skip, OffsetOfLoc, 7);
1750 bool Parse32 = is32BitMode() || Code16GCC;
1751 unsigned RegNo = is64BitMode() ? X86::RBX : (Parse32 ?
X86::EBX : X86::BX);
1754 OffsetOfLoc, Identifier, Decl);
1759 unsigned X86AsmParser::IdentifyIntelInlineAsmOperator(
StringRef Name) {
1761 .Cases(
"TYPE",
"type",IOK_TYPE)
1762 .
Cases(
"SIZE",
"size",IOK_SIZE)
1763 .
Cases(
"LENGTH",
"length",IOK_LENGTH)
1764 .
Cases(
"OFFSET",
"offset",IOK_OFFSET)
1774 unsigned X86AsmParser::ParseIntelInlineAsmOperator(
unsigned OpKind) {
1779 const MCExpr *Val =
nullptr;
1783 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
1788 Error(Start,
"unable to lookup expression");
1795 case IOK_LENGTH: CVal = Info.
Var.
Length;
break;
1796 case IOK_SIZE: CVal = Info.
Var.
Size;
break;
1797 case IOK_TYPE: CVal = Info.
Var.
Type;
break;
1803 bool X86AsmParser::ParseIntelMemoryOperandSize(
unsigned &Size) {
1805 .Cases(
"BYTE",
"byte", 8)
1806 .
Cases(
"WORD",
"word", 16)
1807 .
Cases(
"DWORD",
"dword", 32)
1808 .
Cases(
"FLOAT",
"float", 32)
1809 .
Cases(
"LONG",
"long", 32)
1810 .
Cases(
"FWORD",
"fword", 48)
1811 .
Cases(
"DOUBLE",
"double", 64)
1812 .
Cases(
"QWORD",
"qword", 64)
1813 .
Cases(
"MMWORD",
"mmword", 64)
1814 .
Cases(
"XWORD",
"xword", 80)
1815 .
Cases(
"TBYTE",
"tbyte", 80)
1816 .
Cases(
"XMMWORD",
"xmmword", 128)
1817 .
Cases(
"YMMWORD",
"ymmword", 256)
1818 .
Cases(
"ZMMWORD",
"zmmword", 512)
1823 return Error(Tok.
getLoc(),
"Expected 'PTR' or 'ptr' token!");
1829 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand() {
1837 if (isParsingInlineAsm())
1838 if (IdentifyIntelInlineAsmOperator(Tok.
getString()) == IOK_OFFSET)
1839 return ParseIntelOffsetOfOperator();
1843 if (ParseIntelMemoryOperandSize(Size))
1845 bool PtrInOperand =
bool(Size);
1851 return ParseRoundingModeOp(Start);
1856 if (RegNo == X86::RIP)
1857 return ErrorOperand(Start,
"rip can only be used as a base register");
1861 ErrorOperand(Start,
"expected memory operand after 'ptr', " 1862 "found register operand instead");
1864 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].
contains(RegNo))
1865 return ErrorOperand(Start,
"invalid segment register");
1867 Start = Lex().getLoc();
1871 IntelExprStateMachine SM;
1872 if (ParseIntelExpression(SM, End))
1875 if (isParsingInlineAsm())
1876 RewriteIntelExpression(SM, Start, Tok.
getLoc());
1878 int64_t Imm = SM.getImm();
1879 const MCExpr *Disp = SM.getSym();
1888 if (!SM.isMemExpr() && !RegNo)
1892 unsigned BaseReg = SM.getBaseReg();
1893 unsigned IndexReg = SM.getIndexReg();
1894 unsigned Scale = SM.getScale();
1896 if (Scale == 0 && BaseReg !=
X86::ESP && BaseReg != X86::RSP &&
1897 (IndexReg ==
X86::ESP || IndexReg == X86::RSP))
1903 !(X86MCRegisterClasses[X86::VR128XRegClassID].
contains(IndexReg) ||
1904 X86MCRegisterClasses[X86::VR256XRegClassID].
contains(IndexReg) ||
1905 X86MCRegisterClasses[X86::VR512RegClassID].
contains(IndexReg)) &&
1906 (X86MCRegisterClasses[X86::VR128XRegClassID].
contains(BaseReg) ||
1907 X86MCRegisterClasses[X86::VR256XRegClassID].
contains(BaseReg) ||
1908 X86MCRegisterClasses[X86::VR512RegClassID].
contains(BaseReg)))
1912 X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg))
1913 return ErrorOperand(Start,
"16-bit addresses cannot have a scale");
1922 if ((BaseReg ==
X86::SI || BaseReg == X86::DI) &&
1923 (IndexReg == X86::BX || IndexReg == X86::BP))
1926 if ((BaseReg || IndexReg) &&
1929 return ErrorOperand(Start, ErrMsg);
1930 if (isParsingInlineAsm())
1931 return CreateMemForInlineAsm(RegNo, Disp, BaseReg, IndexReg,
1932 Scale, Start, End, Size, SM.getSymName(),
1933 SM.getIdentifierInfo());
1934 if (!(BaseReg || IndexReg || RegNo))
1937 BaseReg, IndexReg, Scale, Start, End, Size);
1940 std::unique_ptr<X86Operand> X86AsmParser::ParseATTOperand() {
1942 switch (getLexer().getKind()) {
1952 "expected immediate expression") ||
1953 getParser().parseExpression(Val, End) ||
1954 check(isa<X86MCExpr>(Val), L,
"expected immediate expression"))
1960 return ParseRoundingModeOp(Start);
1969 const MCExpr *Expr =
nullptr;
1975 if (
auto *RE = dyn_cast<X86MCExpr>(Expr)) {
1978 Reg = RE->getRegNo();
1981 if (Reg == X86::EIZ || Reg == X86::RIZ)
1982 return ErrorOperand(
1983 Loc,
"%eiz and %riz can only be used as index registers",
1985 if (Reg == X86::RIP)
1986 return ErrorOperand(Loc,
"%rip can only be used as a base register",
1991 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].
contains(Reg))
1992 return ErrorOperand(Loc,
"invalid segment register");
1996 return ParseMemOperand(Reg, Expr, Loc, EndLoc);
2003 bool X86AsmParser::ParseZ(std::unique_ptr<X86Operand> &
Z,
2004 const SMLoc &StartLoc) {
2010 (getLexer().getTok().getIdentifier() ==
"z")))
2015 return Error(getLexer().getLoc(),
"Expected } at this point");
2023 bool X86AsmParser::HandleAVX512Operand(
OperandVector &Operands,
2028 const SMLoc consumedToken = consumeToken();
2032 if (getLexer().getTok().getIntVal() != 1)
2033 return TokError(
"Expected 1to<NUM> at this point");
2036 !getLexer().getTok().getIdentifier().
startswith(
"to"))
2037 return TokError(
"Expected 1to<NUM> at this point");
2039 const char *BroadcastPrimitive =
2041 .Case(
"to2",
"{1to2}")
2042 .
Case(
"to4",
"{1to4}")
2043 .
Case(
"to8",
"{1to8}")
2044 .
Case(
"to16",
"{1to16}")
2046 if (!BroadcastPrimitive)
2047 return TokError(
"Invalid memory broadcast primitive.");
2050 return TokError(
"Expected } at this point");
2061 std::unique_ptr<X86Operand>
Z;
2062 if (ParseZ(Z, consumedToken))
2068 SMLoc StartLoc = Z ? consumeToken() : consumedToken;
2073 if (!ParseRegister(RegNo, RegLoc, StartLoc) &&
2074 X86MCRegisterClasses[X86::VK1RegClassID].
contains(RegNo)) {
2075 if (RegNo == X86::K0)
2076 return Error(RegLoc,
"Register k0 can't be used as write mask");
2078 return Error(getLexer().getLoc(),
"Expected } at this point");
2084 return Error(getLexer().getLoc(),
2085 "Expected an op-mask register at this point");
2090 if (ParseZ(Z, consumeToken()) || !Z)
2091 return Error(getLexer().getLoc(),
2092 "Expected a {z} mark at this point");
2108 std::unique_ptr<X86Operand> X86AsmParser::ParseMemOperand(
unsigned SegReg,
2110 const SMLoc &StartLoc,
2130 auto isAtMemOperand = [
this]() {
2135 auto TokCount = this->getLexer().peekTokens(Buf,
true);
2138 switch (Buf[0].getKind()) {
2145 if ((TokCount > 1) &&
2147 (Buf[0].getLoc().getPointer() + 1 == Buf[1].getLoc().getPointer()))
2148 Id =
StringRef(Buf[0].getLoc().getPointer(),
2149 Buf[1].getIdentifier().
size() + 1);
2160 MCSymbol *Sym = this->getContext().getOrCreateSymbol(Id);
2163 return isa<X86MCExpr>(V);
2171 if (!isAtMemOperand()) {
2174 assert(!isa<X86MCExpr>(Disp) &&
"Expected non-register here.");
2193 unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
2194 SMLoc BaseLoc = getLexer().getLoc();
2201 check(!isa<X86MCExpr>(E), BaseLoc,
"expected register here"))
2205 BaseReg = cast<X86MCExpr>(
E)->getRegNo();
2206 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ)
2207 return ErrorOperand(BaseLoc,
2208 "eiz and riz can only be used as index registers",
2223 if (!isa<X86MCExpr>(E)) {
2227 if (!E->evaluateAsAbsolute(ScaleVal, getStreamer().getAssemblerPtr()))
2228 return ErrorOperand(Loc,
"expected absolute expression");
2230 Warning(Loc,
"scale factor without index register is ignored");
2233 IndexReg = cast<X86MCExpr>(
E)->getRegNo();
2235 if (BaseReg == X86::RIP)
2236 return ErrorOperand(
2237 Loc,
"%rip as base register can not have an index register");
2238 if (IndexReg == X86::RIP)
2239 return ErrorOperand(Loc,
"%rip is not allowed as an index register");
2250 return ErrorOperand(Loc,
"expected scale expression");
2253 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg) &&
2255 return ErrorOperand(Loc,
2256 "scale factor in 16-bit address must be 1");
2258 return ErrorOperand(Loc, ErrMsg);
2272 if (BaseReg == X86::DX && IndexReg == 0 && Scale == 1 && SegReg == 0 &&
2273 isa<MCConstantExpr>(Disp) && cast<MCConstantExpr>(Disp)->getValue() == 0)
2278 return ErrorOperand(BaseLoc, ErrMsg);
2280 if (SegReg || BaseReg || IndexReg)
2282 IndexReg, Scale, StartLoc, EndLoc);
2287 bool X86AsmParser::parsePrimaryExpr(
const MCExpr *&Res,
SMLoc &EndLoc) {
2295 if (ParseRegister(RegNo, StartLoc, EndLoc))
2310 isParsingIntelSyntax() && isParsingInlineAsm()) {
2312 if (NextTok ==
"short") {
2319 InstInfo->AsmRewrites->emplace_back(
AOK_Skip, NameEndLoc,
2320 NextTok.
size() + 1);
2326 PatchedName !=
"setb" && PatchedName !=
"setnb")
2327 PatchedName = PatchedName.
substr(0, Name.
size()-1);
2333 bool IsVCMP = PatchedName[0] ==
'v';
2334 unsigned CCIdx = IsVCMP ? 4 : 3;
2336 PatchedName.
slice(CCIdx, PatchedName.
size() - 2))
2338 .
Case(
"eq_oq", 0x00)
2340 .
Case(
"lt_os", 0x01)
2342 .
Case(
"le_os", 0x02)
2343 .
Case(
"unord", 0x03)
2344 .
Case(
"unord_q", 0x03)
2346 .
Case(
"neq_uq", 0x04)
2348 .
Case(
"nlt_us", 0x05)
2350 .
Case(
"nle_us", 0x06)
2352 .
Case(
"ord_q", 0x07)
2354 .
Case(
"eq_uq", 0x08)
2356 .
Case(
"nge_us", 0x09)
2358 .
Case(
"ngt_us", 0x0A)
2359 .
Case(
"false", 0x0B)
2360 .
Case(
"false_oq", 0x0B)
2361 .
Case(
"neq_oq", 0x0C)
2363 .
Case(
"ge_os", 0x0D)
2365 .
Case(
"gt_os", 0x0E)
2367 .
Case(
"true_uq", 0x0F)
2368 .
Case(
"eq_os", 0x10)
2369 .
Case(
"lt_oq", 0x11)
2370 .
Case(
"le_oq", 0x12)
2371 .
Case(
"unord_s", 0x13)
2372 .
Case(
"neq_us", 0x14)
2373 .
Case(
"nlt_uq", 0x15)
2374 .
Case(
"nle_uq", 0x16)
2375 .
Case(
"ord_s", 0x17)
2376 .
Case(
"eq_us", 0x18)
2377 .
Case(
"nge_uq", 0x19)
2378 .
Case(
"ngt_uq", 0x1A)
2379 .
Case(
"false_os", 0x1B)
2380 .
Case(
"neq_os", 0x1C)
2381 .
Case(
"ge_oq", 0x1D)
2382 .
Case(
"gt_oq", 0x1E)
2383 .
Case(
"true_us", 0x1F)
2385 if (ComparisonCode != ~0U && (IsVCMP || ComparisonCode < 8)) {
2391 getParser().getContext());
2394 PatchedName = PatchedName.
substr(PatchedName.
size() - 2);
2402 unsigned CCIdx = PatchedName.
drop_back().
back() ==
'u' ? 2 : 1;
2404 PatchedName.
slice(5, PatchedName.
size() - CCIdx))
2414 if (ComparisonCode != ~0U && (ComparisonCode != 0 || CCIdx == 2)) {
2418 getParser().getContext());
2421 PatchedName = PatchedName.
substr(PatchedName.
size() - CCIdx);
2429 unsigned CCIdx = PatchedName.
drop_back().
back() ==
'u' ? 2 : 1;
2431 PatchedName.
slice(5, PatchedName.
size() - CCIdx))
2441 if (ComparisonCode != ~0U) {
2445 getParser().getContext());
2448 PatchedName = PatchedName.
substr(PatchedName.
size() - CCIdx);
2461 .Cases(
"rex64",
"data32",
"data16",
true)
2462 .
Cases(
"xacquire",
"xrelease",
true)
2463 .
Cases(
"acquire",
"release", isParsingIntelSyntax())
2466 auto isLockRepeatNtPrefix = [](
StringRef N) {
2468 .Cases(
"lock",
"rep",
"repe",
"repz",
"repne",
"repnz",
"notrack",
true)
2472 bool CurlyAsEndOfStatement =
false;
2475 while (isLockRepeatNtPrefix(Name.
lower())) {
2507 if (PatchedName ==
"data16" && is16BitMode()) {
2508 return Error(NameLoc,
"redundant data16 prefix");
2510 if (PatchedName ==
"data32") {
2512 return Error(NameLoc,
"redundant data32 prefix");
2514 return Error(NameLoc,
"'data32' is not supported in 64-bit mode");
2516 PatchedName =
"data16";
2532 if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
2534 if (HandleAVX512Operand(Operands, *Operands.
back()))
2548 CurlyAsEndOfStatement =
2549 isParsingIntelSyntax() && isParsingInlineAsm() &&
2552 return TokError(
"unexpected token in argument list");
2559 else if (CurlyAsEndOfStatement)
2562 getLexer().getTok().getLoc(), 0);
2568 Name ==
"fsub" || Name ==
"fdiv" || Name ==
"fsubr" || Name ==
"fdivr";
2569 if (IsFp && Operands.
size() == 1) {
2571 .Case(
"fsub",
"fsubp")
2572 .
Case(
"fdiv",
"fdivp")
2573 .
Case(
"fsubr",
"fsubrp")
2574 .
Case(
"fdivr",
"fdivrp");
2575 static_cast<X86Operand &
>(*Operands[0]).setTokenValue(Repl);
2580 if ((Name ==
"mov" || Name ==
"movw" || Name ==
"movl") &&
2581 (Operands.
size() == 3)) {
2586 X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(
2588 (X86MCRegisterClasses[X86::GR16RegClassID].
contains(Op1.
getReg()) ||
2589 X86MCRegisterClasses[X86::GR32RegClassID].
contains(Op1.
getReg()))) {
2591 if (Name !=
"mov" && Name[3] == (is16BitMode() ?
'l' :
'w')) {
2592 Name = is16BitMode() ?
"movw" :
"movl";
2605 if ((Name ==
"outb" || Name ==
"outsb" || Name ==
"outw" || Name ==
"outsw" ||
2606 Name ==
"outl" || Name ==
"outsl" || Name ==
"out" || Name ==
"outs") &&
2607 Operands.
size() == 3) {
2614 if ((Name ==
"inb" || Name ==
"insb" || Name ==
"inw" || Name ==
"insw" ||
2615 Name ==
"inl" || Name ==
"insl" || Name ==
"in" || Name ==
"ins") &&
2616 Operands.
size() == 3) {
2624 bool HadVerifyError =
false;
2628 (Operands.
size() == 1 || Operands.
size() == 3) &&
2629 (Name ==
"insb" || Name ==
"insw" || Name ==
"insl" || Name ==
"insd" ||
2632 AddDefaultSrcDestOperands(TmpOperands,
2634 DefaultMemDIOperand(NameLoc));
2635 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2640 (Operands.
size() == 1 || Operands.
size() == 3) &&
2641 (Name ==
"outsb" || Name ==
"outsw" || Name ==
"outsl" ||
2642 Name ==
"outsd" || Name ==
"outs")) {
2643 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
2645 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2652 (Operands.
size() == 1 || Operands.
size() == 2) &&
2653 (Name ==
"lods" || Name ==
"lodsb" || Name ==
"lodsw" ||
2654 Name ==
"lodsl" || Name ==
"lodsd" || Name ==
"lodsq")) {
2655 TmpOperands.
push_back(DefaultMemSIOperand(NameLoc));
2656 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2663 (Operands.
size() == 1 || Operands.
size() == 2) &&
2664 (Name ==
"stos" || Name ==
"stosb" || Name ==
"stosw" ||
2665 Name ==
"stosl" || Name ==
"stosd" || Name ==
"stosq")) {
2666 TmpOperands.
push_back(DefaultMemDIOperand(NameLoc));
2667 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2674 (Operands.
size() == 1 || Operands.
size() == 2) &&
2675 (Name ==
"scas" || Name ==
"scasb" || Name ==
"scasw" ||
2676 Name ==
"scasl" || Name ==
"scasd" || Name ==
"scasq")) {
2677 TmpOperands.
push_back(DefaultMemDIOperand(NameLoc));
2678 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2683 (Operands.
size() == 1 || Operands.
size() == 3) &&
2684 (Name ==
"cmps" || Name ==
"cmpsb" || Name ==
"cmpsw" ||
2685 Name ==
"cmpsl" || Name ==
"cmpsd" || Name ==
"cmpsq")) {
2686 AddDefaultSrcDestOperands(TmpOperands, DefaultMemDIOperand(NameLoc),
2687 DefaultMemSIOperand(NameLoc));
2688 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2693 (Name ==
"movs" || Name ==
"movsb" || Name ==
"movsw" ||
2694 Name ==
"movsl" || Name ==
"movsd" || Name ==
"movsq")) ||
2696 (Name ==
"smov" || Name ==
"smovb" || Name ==
"smovw" ||
2697 Name ==
"smovl" || Name ==
"smovd" || Name ==
"smovq"))) &&
2698 (Operands.
size() == 1 || Operands.
size() == 3)) {
2699 if (Name ==
"movsd" && Operands.
size() == 1 && !isParsingIntelSyntax())
2701 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
2702 DefaultMemDIOperand(NameLoc));
2703 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2707 if (HadVerifyError) {
2708 return HadVerifyError;
2717 Operands.
size() == 3) {
2718 if (isParsingIntelSyntax()) {
2721 if (Op1.
isImm() && isa<MCConstantExpr>(Op1.
getImm()) &&
2722 cast<MCConstantExpr>(Op1.
getImm())->getValue() == 1)
2726 if (Op1.
isImm() && isa<MCConstantExpr>(Op1.
getImm()) &&
2727 cast<MCConstantExpr>(Op1.
getImm())->getValue() == 1)
2734 if (Name ==
"int" && Operands.
size() == 2) {
2737 if (
auto *CE = dyn_cast<MCConstantExpr>(Op1.
getImm()))
2738 if (CE->getValue() == 3) {
2740 static_cast<X86Operand &
>(*Operands[0]).setTokenValue(
"int3");
2745 if ((Name ==
"xlat" || Name ==
"xlatb") && Operands.
size() == 2) {
2749 "size, (R|E)BX will be used for the location");
2751 static_cast<X86Operand &
>(*Operands[0]).setTokenValue(
"xlatb");
2768 case X86::VGATHERDPDYrm:
2769 case X86::VGATHERDPDrm:
2770 case X86::VGATHERDPSYrm:
2771 case X86::VGATHERDPSrm:
2772 case X86::VGATHERQPDYrm:
2773 case X86::VGATHERQPDrm:
2774 case X86::VGATHERQPSYrm:
2775 case X86::VGATHERQPSrm:
2776 case X86::VPGATHERDDYrm:
2777 case X86::VPGATHERDDrm:
2778 case X86::VPGATHERDQYrm:
2779 case X86::VPGATHERDQrm:
2780 case X86::VPGATHERQDYrm:
2781 case X86::VPGATHERQDrm:
2782 case X86::VPGATHERQQYrm:
2783 case X86::VPGATHERQQrm: {
2788 if (Dest == Mask || Dest == Index || Mask == Index)
2789 return Warning(Ops[0]->getStartLoc(),
"mask, index, and destination " 2790 "registers should be distinct");
2793 case X86::VGATHERDPDZ128rm:
2794 case X86::VGATHERDPDZ256rm:
2795 case X86::VGATHERDPDZrm:
2796 case X86::VGATHERDPSZ128rm:
2797 case X86::VGATHERDPSZ256rm:
2798 case X86::VGATHERDPSZrm:
2799 case X86::VGATHERQPDZ128rm:
2800 case X86::VGATHERQPDZ256rm:
2801 case X86::VGATHERQPDZrm:
2802 case X86::VGATHERQPSZ128rm:
2803 case X86::VGATHERQPSZ256rm:
2804 case X86::VGATHERQPSZrm:
2805 case X86::VPGATHERDDZ128rm:
2806 case X86::VPGATHERDDZ256rm:
2807 case X86::VPGATHERDDZrm:
2808 case X86::VPGATHERDQZ128rm:
2809 case X86::VPGATHERDQZ256rm:
2810 case X86::VPGATHERDQZrm:
2811 case X86::VPGATHERQDZ128rm:
2812 case X86::VPGATHERQDZ256rm:
2813 case X86::VPGATHERQDZrm:
2814 case X86::VPGATHERQQZ128rm:
2815 case X86::VPGATHERQQZ256rm:
2816 case X86::VPGATHERQQZrm: {
2821 return Warning(Ops[0]->getStartLoc(),
"index and destination registers " 2822 "should be distinct");
2825 case X86::V4FMADDPSrm:
2826 case X86::V4FMADDPSrmk:
2827 case X86::V4FMADDPSrmkz:
2828 case X86::V4FMADDSSrm:
2829 case X86::V4FMADDSSrmk:
2830 case X86::V4FMADDSSrmkz:
2831 case X86::V4FNMADDPSrm:
2832 case X86::V4FNMADDPSrmk:
2833 case X86::V4FNMADDPSrmkz:
2834 case X86::V4FNMADDSSrm:
2835 case X86::V4FNMADDSSrmk:
2836 case X86::V4FNMADDSSrmkz:
2837 case X86::VP4DPWSSDSrm:
2838 case X86::VP4DPWSSDSrmk:
2839 case X86::VP4DPWSSDSrmkz:
2840 case X86::VP4DPWSSDrm:
2841 case X86::VP4DPWSSDrmk:
2842 case X86::VP4DPWSSDrmkz: {
2846 if (Src2Enc % 4 != 0) {
2848 unsigned GroupStart = (Src2Enc / 4) * 4;
2849 unsigned GroupEnd = GroupStart + 3;
2850 return Warning(Ops[0]->getStartLoc(),
2851 "source register '" + RegName +
"' implicitly denotes '" +
2867 Instrumentation->InstrumentAndEmitInstruction(
2868 Inst, Operands, getContext(), MII, Out,
2869 getParser().shouldPrintSchedInfo());
2872 bool X86AsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
2875 bool MatchingInlineAsm) {
2876 if (isParsingIntelSyntax())
2877 return MatchAndEmitIntelInstruction(IDLoc, Opcode, Operands, Out,
ErrorInfo,
2879 return MatchAndEmitATTInstruction(IDLoc, Opcode, Operands, Out,
ErrorInfo,
2885 bool MatchingInlineAsm) {
2890 .Case(
"finit",
"fninit")
2891 .
Case(
"fsave",
"fnsave")
2892 .
Case(
"fstcw",
"fnstcw")
2893 .
Case(
"fstcww",
"fnstcw")
2894 .
Case(
"fstenv",
"fnstenv")
2895 .
Case(
"fstsw",
"fnstsw")
2896 .
Case(
"fstsww",
"fnstsw")
2897 .
Case(
"fclex",
"fnclex")
2903 if (!MatchingInlineAsm)
2904 EmitInstruction(Inst, Operands, Out);
2909 bool X86AsmParser::ErrorMissingFeature(
SMLoc IDLoc, uint64_t
ErrorInfo,
2910 bool MatchingInlineAsm) {
2914 OS <<
"instruction requires:";
2916 for (
unsigned i = 0; i < (
sizeof(
ErrorInfo)*8-1); ++i) {
2925 unsigned Result = 0;
2934 bool X86AsmParser::MatchAndEmitATTInstruction(
SMLoc IDLoc,
unsigned &Opcode,
2938 bool MatchingInlineAsm) {
2939 assert(!Operands.
empty() &&
"Unexpect empty operand list!");
2941 assert(Op.isToken() &&
"Leading operand should always be a mnemonic!");
2945 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2947 bool WasOriginallyInvalidOperand =
false;
2956 switch (MatchInstruction(Operands, Inst,
ErrorInfo, MatchingInlineAsm,
2957 isParsingIntelSyntax())) {
2960 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
2965 if (!MatchingInlineAsm)
2966 while (processInstruction(Inst, Operands))
2970 if (!MatchingInlineAsm)
2971 EmitInstruction(Inst, Operands, Out);
2974 case Match_MissingFeature:
2975 return ErrorMissingFeature(IDLoc,
ErrorInfo, MatchingInlineAsm);
2976 case Match_InvalidOperand:
2977 WasOriginallyInvalidOperand =
true;
2979 case Match_MnemonicFail:
2993 Op.setTokenValue(Tmp);
3001 const char *Suffixes = Base[0] !=
'f' ?
"bwlq" :
"slt\0";
3004 uint64_t ErrorInfoIgnore;
3005 uint64_t ErrorInfoMissingFeature = 0;
3009 Tmp.
back() = Suffixes[
I];
3010 Match[
I] = MatchInstruction(Operands, Inst, ErrorInfoIgnore,
3011 MatchingInlineAsm, isParsingIntelSyntax());
3013 if (Match[
I] == Match_MissingFeature)
3014 ErrorInfoMissingFeature = ErrorInfoIgnore;
3018 Op.setTokenValue(Base);
3023 unsigned NumSuccessfulMatches =
3025 if (NumSuccessfulMatches == 1) {
3027 if (!MatchingInlineAsm)
3028 EmitInstruction(Inst, Operands, Out);
3037 if (NumSuccessfulMatches > 1) {
3039 unsigned NumMatches = 0;
3041 if (Match[
I] == Match_Success)
3042 MatchChars[NumMatches++] = Suffixes[
I];
3046 OS <<
"ambiguous instructions require an explicit suffix (could be ";
3047 for (
unsigned i = 0; i != NumMatches; ++i) {
3050 if (i + 1 == NumMatches)
3052 OS <<
"'" << Base << MatchChars[i] <<
"'";
3055 Error(IDLoc, OS.
str(), EmptyRange, MatchingInlineAsm);
3064 if (!WasOriginallyInvalidOperand) {
3065 return Error(IDLoc,
"invalid instruction mnemonic '" + Base +
"'",
3066 Op.getLocRange(), MatchingInlineAsm);
3072 return Error(IDLoc,
"too few operands for instruction", EmptyRange,
3079 OperandRange, MatchingInlineAsm);
3083 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
3090 Match_MissingFeature) == 1) {
3092 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
3099 Match_InvalidOperand) == 1) {
3100 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
3105 Error(IDLoc,
"unknown use of instruction mnemonic without a size suffix",
3106 EmptyRange, MatchingInlineAsm);
3110 bool X86AsmParser::MatchAndEmitIntelInstruction(
SMLoc IDLoc,
unsigned &Opcode,
3114 bool MatchingInlineAsm) {
3115 assert(!Operands.
empty() &&
"Unexpect empty operand list!");
3117 assert(Op.isToken() &&
"Leading operand should always be a mnemonic!");
3124 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
3133 for (
const auto &Op : Operands) {
3136 UnsizedMemOp = X86Op;
3146 static const char *
const PtrSizedInstrs[] = {
"call",
"jmp",
"push"};
3147 for (
const char *Instr : PtrSizedInstrs) {
3148 if (Mnemonic == Instr) {
3149 UnsizedMemOp->
Mem.
Size = getPointerWidth();
3156 uint64_t ErrorInfoMissingFeature = 0;
3160 if (Mnemonic ==
"push" && Operands.size() == 2) {
3161 auto *X86Op =
static_cast<X86Operand *
>(Operands[1].get());
3162 if (X86Op->isImm()) {
3165 unsigned Size = getPointerWidth();
3167 (
isIntN(Size, CE->getValue()) ||
isUIntN(Size, CE->getValue()))) {
3170 Tmp += (is64BitMode())
3172 : (is32BitMode()) ?
"l" : (is16BitMode()) ?
"w" :
" ";
3173 Op.setTokenValue(Tmp);
3178 Op.setTokenValue(Base);
3187 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
3188 for (
unsigned Size : MopSizes) {
3190 uint64_t ErrorInfoIgnore;
3192 unsigned M = MatchInstruction(Operands, Inst, ErrorInfoIgnore,
3193 MatchingInlineAsm, isParsingIntelSyntax());
3198 if (Match.
back() == Match_MissingFeature)
3199 ErrorInfoMissingFeature = ErrorInfoIgnore;
3209 if (Match.
empty()) {
3211 Operands, Inst,
ErrorInfo, MatchingInlineAsm, isParsingIntelSyntax()));
3213 if (Match.
back() == Match_MissingFeature)
3222 if (Match.
back() == Match_MnemonicFail) {
3223 return Error(IDLoc,
"invalid instruction mnemonic '" + Mnemonic +
"'",
3224 Op.getLocRange(), MatchingInlineAsm);
3227 unsigned NumSuccessfulMatches =
3232 if (UnsizedMemOp && NumSuccessfulMatches > 1 &&
3235 unsigned M = MatchInstruction(
3236 Operands, Inst,
ErrorInfo, MatchingInlineAsm, isParsingIntelSyntax());
3237 if (M == Match_Success)
3238 NumSuccessfulMatches = 1;
3242 InstInfo->AsmRewrites->emplace_back(
3250 if (NumSuccessfulMatches == 1) {
3251 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
3256 if (!MatchingInlineAsm)
3257 while (processInstruction(Inst, Operands))
3260 if (!MatchingInlineAsm)
3261 EmitInstruction(Inst, Operands, Out);
3264 }
else if (NumSuccessfulMatches > 1) {
3266 "multiple matches only possible with unsized memory operands");
3268 "ambiguous operand size for instruction '" + Mnemonic +
"\'",
3275 Match_MissingFeature) == 1) {
3277 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
3284 Match_InvalidOperand) == 1) {
3285 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
3290 return Error(IDLoc,
"unknown instruction mnemonic", EmptyRange,
3294 bool X86AsmParser::OmitRegisterFromClobberLists(
unsigned RegNo) {
3295 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo);
3298 bool X86AsmParser::ParseDirective(
AsmToken DirectiveID) {
3302 return ParseDirectiveCode(IDVal, DirectiveID.
getLoc());
3308 return Error(DirectiveID.
getLoc(),
"'.att_syntax noprefix' is not " 3309 "supported: registers must have a " 3310 "'%' prefix in .att_syntax");
3312 getParser().setAssemblerDialect(0);
3314 }
else if (IDVal.
startswith(
".intel_syntax")) {
3315 getParser().setAssemblerDialect(1);
3320 return Error(DirectiveID.
getLoc(),
"'.intel_syntax prefix' is not " 3321 "supported: registers must not have " 3322 "a '%' prefix in .intel_syntax");
3325 }
else if (IDVal ==
".even")
3326 return parseDirectiveEven(DirectiveID.
getLoc());
3327 else if (IDVal ==
".cv_fpo_proc")
3328 return parseDirectiveFPOProc(DirectiveID.
getLoc());
3329 else if (IDVal ==
".cv_fpo_setframe")
3330 return parseDirectiveFPOSetFrame(DirectiveID.
getLoc());
3331 else if (IDVal ==
".cv_fpo_pushreg")
3332 return parseDirectiveFPOPushReg(DirectiveID.
getLoc());
3333 else if (IDVal ==
".cv_fpo_stackalloc")
3334 return parseDirectiveFPOStackAlloc(DirectiveID.
getLoc());
3335 else if (IDVal ==
".cv_fpo_stackalign")
3336 return parseDirectiveFPOStackAlign(DirectiveID.
getLoc());
3337 else if (IDVal ==
".cv_fpo_endprologue")
3338 return parseDirectiveFPOEndPrologue(DirectiveID.
getLoc());
3339 else if (IDVal ==
".cv_fpo_endproc")
3340 return parseDirectiveFPOEndProc(DirectiveID.
getLoc());
3347 bool X86AsmParser::parseDirectiveEven(
SMLoc L) {
3353 getStreamer().InitSections(
false);
3354 Section = getStreamer().getCurrentSectionOnly();
3357 getStreamer().EmitCodeAlignment(2, 0);
3359 getStreamer().EmitValueToAlignment(2, 0, 1, 0);
3365 bool X86AsmParser::ParseDirectiveCode(
StringRef IDVal,
SMLoc L) {
3368 if (IDVal ==
".code16") {
3370 if (!is16BitMode()) {
3371 SwitchMode(X86::Mode16Bit);
3372 getParser().getStreamer().EmitAssemblerFlag(
MCAF_Code16);
3374 }
else if (IDVal ==
".code16gcc") {
3378 if (!is16BitMode()) {
3379 SwitchMode(X86::Mode16Bit);
3380 getParser().getStreamer().EmitAssemblerFlag(
MCAF_Code16);
3382 }
else if (IDVal ==
".code32") {
3384 if (!is32BitMode()) {
3385 SwitchMode(X86::Mode32Bit);
3386 getParser().getStreamer().EmitAssemblerFlag(
MCAF_Code32);
3388 }
else if (IDVal ==
".code64") {
3390 if (!is64BitMode()) {
3391 SwitchMode(X86::Mode64Bit);
3392 getParser().getStreamer().EmitAssemblerFlag(
MCAF_Code64);
3395 Error(L,
"unknown directive " + IDVal);
3403 bool X86AsmParser::parseDirectiveFPOProc(
SMLoc L) {
3408 return Parser.
TokError(
"expected symbol name");
3409 if (Parser.
parseIntToken(ParamsSize,
"expected parameter byte count"))
3412 return Parser.
TokError(
"parameters size out of range");
3413 if (Parser.
parseEOL(
"unexpected tokens"))
3414 return addErrorSuffix(
" in '.cv_fpo_proc' directive");
3415 MCSymbol *ProcSym = getContext().getOrCreateSymbol(ProcName);
3416 return getTargetStreamer().emitFPOProc(ProcSym, ParamsSize, L);
3420 bool X86AsmParser::parseDirectiveFPOSetFrame(
SMLoc L) {
3424 if (ParseRegister(Reg, DummyLoc, DummyLoc) ||
3425 Parser.
parseEOL(
"unexpected tokens"))
3426 return addErrorSuffix(
" in '.cv_fpo_setframe' directive");
3427 return getTargetStreamer().emitFPOSetFrame(Reg, L);
3431 bool X86AsmParser::parseDirectiveFPOPushReg(
SMLoc L) {
3435 if (ParseRegister(Reg, DummyLoc, DummyLoc) ||
3436 Parser.
parseEOL(
"unexpected tokens"))
3437 return addErrorSuffix(
" in '.cv_fpo_pushreg' directive");
3438 return getTargetStreamer().emitFPOPushReg(Reg, L);
3442 bool X86AsmParser::parseDirectiveFPOStackAlloc(
SMLoc L) {
3446 Parser.
parseEOL(
"unexpected tokens"))
3447 return addErrorSuffix(
" in '.cv_fpo_stackalloc' directive");
3448 return getTargetStreamer().emitFPOStackAlloc(Offset, L);
3452 bool X86AsmParser::parseDirectiveFPOStackAlign(
SMLoc L) {
3456 Parser.
parseEOL(
"unexpected tokens"))
3457 return addErrorSuffix(
" in '.cv_fpo_stackalign' directive");
3458 return getTargetStreamer().emitFPOStackAlign(Offset, L);
3462 bool X86AsmParser::parseDirectiveFPOEndPrologue(
SMLoc L) {
3464 if (Parser.
parseEOL(
"unexpected tokens"))
3465 return addErrorSuffix(
" in '.cv_fpo_endprologue' directive");
3466 return getTargetStreamer().emitFPOEndPrologue(L);
3470 bool X86AsmParser::parseDirectiveFPOEndProc(
SMLoc L) {
3472 if (Parser.
parseEOL(
"unexpected tokens"))
3473 return addErrorSuffix(
" in '.cv_fpo_endproc' directive");
3474 return getTargetStreamer().emitFPOEndProc(L);
3483 #define GET_REGISTER_MATCHER 3484 #define GET_MATCHER_IMPLEMENTATION 3485 #define GET_SUBTARGET_FEATURE_NAME 3486 #include "X86GenAsmMatcher.inc"
static const char * getSubtargetFeatureName(uint64_t Val)
Represents a range in source code.
Instances of this class represent a uniqued identifier for a section in the current translation unit...
static bool checkScale(unsigned Scale, StringRef &ErrMsg)
const_iterator end(StringRef path)
Get end iterator over path.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
uint64_t getZExtValue() const
Get zero extended value.
unsigned getMemFrontendSize() const
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
bool isX86_64NonExtLowByteReg(unsigned reg)
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
This class represents lattice values for constants.
SMRange getLocRange() const
getLocRange - Get the range between the first and last token of this operand.
bool isVariable() const
isVariable - Check if this is a variable symbol.
SmallVectorImpl< AsmRewrite > * AsmRewrites
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
LLVM_NODISCARD bool equals_lower(StringRef RHS) const
equals_lower - Check for string equality, ignoring case.
Generic assembler parser interface, for use by target specific assembly parsers.
bool isKind(IdKind kind) const
MCTargetAsmParser - Generic interface to target specific assembly parsers.
void push_back(const T &Elt)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
Target specific streamer interface.
bool isNot(TokenKind K) const
AddrNumOperands - Total number of operands in a memory reference.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
A raw_ostream that writes to an SmallVector or SmallString.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
static std::unique_ptr< X86Operand > CreateMem(unsigned ModeSize, const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc, unsigned Size=0, StringRef SymName=StringRef(), void *OpDecl=nullptr, unsigned FrontendSize=0)
Create an absolute memory operand.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
bool parseIntToken(int64_t &V, const Twine &ErrMsg)
return AArch64::GPR64RegClass contains(Reg)
static ModuleSymbolTable::Symbol getSym(DataRefImpl &Symb)
StringRef getToken() const
amode Optimize addressing mode
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool endswith(StringRef Suffix) const
Check if this string ends with the given Suffix.
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string...
amdgpu Simplify well known AMD library false Value Value const Twine & Name
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
void LLVMInitializeX86AsmParser()
const FeatureBitset & getFeatureBits() const
unsigned getPrefix() const
bool isMemUnsized() const
SMLoc getEndLoc() const override
getEndLoc - Get the location of the last token of this operand.
LLVM_NODISCARD size_t count(char C) const
Return the number of occurrences of C in the string.
bool isImm() const override
isImm - Is this an immediate operand?
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Base class for the full range of assembler expressions which are needed for parsing.
Target independent representation for an assembler token.
static bool CheckBaseRegAndIndexRegAndScale(unsigned BaseReg, unsigned IndexReg, unsigned Scale, bool Is64BitMode, StringRef &ErrMsg)
}
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE R Default(T Value)
zlib-gnu style compression
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand...
static std::unique_ptr< X86Operand > CreateImm(const MCExpr *Val, SMLoc StartLoc, SMLoc EndLoc)
static bool startswith(StringRef Magic, const char(&S)[N])
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
unsigned getReg() const
Returns the register number.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
unsigned getReg() const override
RegisterMCAsmParser - Helper template for registering a target specific assembly parser, for use in the target machine initialization function.
.code16 (X86) / .code 16 (ARM)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
LLVM_NODISCARD std::string upper() const
Convert the given ASCII string to uppercase.
Analysis containing CSE Info
Instances of this class represent a single low-level machine instruction.
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
auto count(R &&Range, const E &Element) -> typename std::iterator_traits< decltype(adl_begin(Range))>::difference_type
Wrapper function around std::count to count the number of times an element Element occurs in the give...
static const X86MCExpr * create(int64_t RegNo, MCContext &Ctx)
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
bool isX86_64ExtendedReg(unsigned RegNo)
isX86_64ExtendedReg - Is the MachineOperand a x86-64 extended (r8 or higher) register? e.g.
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
FeatureBitset ToggleFeature(uint64_t FB)
Toggle a feature and return the re-computed feature bits.
const char * getPointer() const
virtual MCContext & getContext()=0
A switch()-like statement whose cases are string literals.
Streaming machine code generation interface.
unsigned const MachineRegisterInfo * MRI
X86Operand - Instances of this class represent a parsed X86 machine instruction.
MCTargetStreamer * getTargetStreamer()
Container class for subtarget features.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
virtual bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse a primary expression.
Interface to description of machine instruction set.
const MCExpr * getImm() const
bool parseTokenLoc(SMLoc &Loc)
int64_t getIntVal() const
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE int compare(StringRef RHS) const
compare - Compare two strings; the result is -1, 0, or 1 if this string is lexicographically less tha...
unsigned getNumOperands() const
static std::unique_ptr< X86Operand > CreateDXReg(SMLoc StartLoc, SMLoc EndLoc)
bool Error(SMLoc L, const Twine &Msg, SMRange Range=None)
Return an error at the location L, with the message Msg.
static const char * getRegisterName(unsigned RegNo)
virtual bool UseCodeAlign() const =0
Return true if a .align directive should use "optimized nops" to fill instead of 0s.
bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
iterator erase(const_iterator CI)
LLVM_NODISCARD char back() const
back - Get the last character in the string.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
SMLoc getStartLoc() const override
getStartLoc - Get the location of the first token of this operand.
unsigned getX86SubSuperRegisterOrZero(unsigned, unsigned, bool High=false)
Returns the sub or super register of a specific X86 register.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef drop_back(size_t N=1) const
Return a StringRef equal to 'this' but with the last N elements dropped.
std::enable_if< std::numeric_limits< T >::is_signed, bool >::type getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
X86AsmInstrumentation * CreateX86AsmInstrumentation(const MCTargetOptions &MCOptions, const MCContext &Ctx, const MCSubtargetInfo *&STI)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
void setFlags(unsigned F)
MCStreamer & getStreamer()
void setOpcode(unsigned Op)
auto size(R &&Range, typename std::enable_if< std::is_same< typename std::iterator_traits< decltype(Range.begin())>::iterator_category, std::random_access_iterator_tag >::value, void >::type *=nullptr) -> decltype(std::distance(Range.begin(), Range.end()))
Get the size of a range.
bool isUndefined(bool SetUsed=true) const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
static unsigned MatchRegisterName(StringRef Name)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
const MCOperand & getOperand(unsigned i) const
LLVM_NODISCARD std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
constexpr size_t array_lengthof(T(&)[N])
Find the length of an array.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
LLVM_NODISCARD T pop_back_val()
StringRef str()
Return a StringRef for the vector contents.
X86 target streamer implementing x86-only assembly directives.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
bool is(TokenKind K) const
Class for arbitrary precision integers.
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
Base class for user error types.
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Case(StringLiteral S, T Value)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool equals(StringRef RHS) const
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
static std::unique_ptr< X86Operand > CreateToken(StringRef Str, SMLoc Loc)
.code32 (X86) / .code 32 (ARM)
static SMLoc getFromPointer(const char *Ptr)
static std::unique_ptr< X86Operand > CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc, bool AddressOf=false, SMLoc OffsetOfLoc=SMLoc(), StringRef SymName=StringRef(), void *OpDecl=nullptr)
uint16_t getEncodingValue(unsigned RegNo) const
Returns the encoding for RegNo.
LLVM_NODISCARD bool empty() const
static unsigned getPrefixes(OperandVector &Operands)
Generic base class for all target subtargets.
virtual bool parseAbsoluteExpression(int64_t &Res)=0
Parse an expression which must evaluate to an absolute value.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Cases(StringLiteral S0, StringLiteral S1, T Value)
Target & getTheX86_32Target()
StringRef getName() const
getName - Get the symbol name.
LLVM_NODISCARD std::string lower() const
static std::unique_ptr< X86Operand > CreatePrefix(unsigned Prefixes, SMLoc StartLoc, SMLoc EndLoc)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool TokError(const Twine &Msg, SMRange Range=None)
Report an error at the current lexer location.
const MCExpr * getVariableValue(bool SetUsed=true) const
getVariableValue - Get the value for variable symbols.
bool parseEOL(const Twine &ErrMsg)
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef take_front(size_t N=1) const
Return a StringRef equal to 'this' but with only the first N elements remaining.
bool parseOptionalToken(AsmToken::TokenKind T)
Attempt to parse and consume token, returning true on success.
bool isReg() const override
isReg - Is this a register operand?
StringRef - Represent a constant reference to a string, i.e.
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents...
Represents a location in source code.
unsigned getOpcode() const
bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
Target & getTheX86_64Target()
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx)
bool isMem() const override
isMem - Is this a memory operand?