52 "x86-experimental-lvi-inline-asm-hardening",
53 cl::desc(
"Harden inline assembly code that may be vulnerable to Load Value"
54 " Injection (LVI). This feature is experimental."),
cl::Hidden);
57 if (Scale != 1 && Scale != 2 && Scale != 4 && Scale != 8) {
58 ErrMsg =
"scale factor in address must be 1, 2, 4 or 8";
67#define GET_X86_SSE2AVX_TABLE
68#include "X86GenInstrMapping.inc"
70static const char OpPrecedence[] = {
96 ParseInstructionInfo *InstInfo;
98 unsigned ForcedDataPrefix = 0;
101 OpcodePrefix_Default,
110 OpcodePrefix ForcedOpcodePrefix = OpcodePrefix_Default;
113 DispEncoding_Default,
118 DispEncoding ForcedDispEncoding = DispEncoding_Default;
121 bool UseApxExtendedReg =
false;
123 bool ForcedNoFlag =
false;
126 SMLoc consumeToken() {
127 MCAsmParser &Parser = getParser();
137 X86TargetStreamer &getTargetStreamer() {
138 assert(getParser().getStreamer().getTargetStreamer() &&
139 "do not have a target streamer");
140 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
141 return static_cast<X86TargetStreamer &
>(TS);
145 uint64_t &ErrorInfo, FeatureBitset &MissingFeatures,
146 bool matchingInlineAsm,
unsigned VariantID = 0) {
149 SwitchMode(X86::Is32Bit);
150 unsigned rv = MatchInstructionImpl(
Operands, Inst, ErrorInfo,
151 MissingFeatures, matchingInlineAsm,
154 SwitchMode(X86::Is16Bit);
158 enum InfixCalculatorTok {
183 enum IntelOperatorKind {
190 enum MasmOperatorKind {
197 class InfixCalculator {
198 typedef std::pair< InfixCalculatorTok, int64_t > ICToken;
202 bool isUnaryOperator(InfixCalculatorTok
Op)
const {
203 return Op == IC_NEG ||
Op == IC_NOT;
207 int64_t popOperand() {
208 assert (!PostfixStack.empty() &&
"Poped an empty stack!");
209 ICToken
Op = PostfixStack.pop_back_val();
210 if (!(
Op.first == IC_IMM ||
Op.first == IC_REGISTER))
214 void pushOperand(InfixCalculatorTok
Op, int64_t Val = 0) {
215 assert ((
Op == IC_IMM ||
Op == IC_REGISTER) &&
216 "Unexpected operand!");
217 PostfixStack.push_back(std::make_pair(
Op, Val));
220 void popOperator() { InfixOperatorStack.pop_back(); }
221 void pushOperator(InfixCalculatorTok
Op) {
223 if (InfixOperatorStack.empty()) {
224 InfixOperatorStack.push_back(
Op);
231 unsigned Idx = InfixOperatorStack.size() - 1;
232 InfixCalculatorTok StackOp = InfixOperatorStack[Idx];
233 if (OpPrecedence[
Op] > OpPrecedence[StackOp] || StackOp == IC_LPAREN) {
234 InfixOperatorStack.push_back(
Op);
240 unsigned ParenCount = 0;
243 if (InfixOperatorStack.empty())
246 Idx = InfixOperatorStack.size() - 1;
247 StackOp = InfixOperatorStack[Idx];
248 if (!(OpPrecedence[StackOp] >= OpPrecedence[
Op] || ParenCount))
253 if (!ParenCount && StackOp == IC_LPAREN)
256 if (StackOp == IC_RPAREN) {
258 InfixOperatorStack.pop_back();
259 }
else if (StackOp == IC_LPAREN) {
261 InfixOperatorStack.pop_back();
263 InfixOperatorStack.pop_back();
264 PostfixStack.push_back(std::make_pair(StackOp, 0));
268 InfixOperatorStack.push_back(
Op);
273 while (!InfixOperatorStack.empty()) {
274 InfixCalculatorTok StackOp = InfixOperatorStack.pop_back_val();
275 if (StackOp != IC_LPAREN && StackOp != IC_RPAREN)
276 PostfixStack.push_back(std::make_pair(StackOp, 0));
279 if (PostfixStack.empty())
283 for (
const ICToken &
Op : PostfixStack) {
284 if (
Op.first == IC_IMM ||
Op.first == IC_REGISTER) {
286 }
else if (isUnaryOperator(
Op.first)) {
287 assert (OperandStack.
size() > 0 &&
"Too few operands.");
289 assert (Operand.first == IC_IMM &&
290 "Unary operation with a register!");
296 OperandStack.
push_back(std::make_pair(IC_IMM, -Operand.second));
299 OperandStack.
push_back(std::make_pair(IC_IMM, ~Operand.second));
303 assert (OperandStack.
size() > 1 &&
"Too few operands.");
312 Val = Op1.second + Op2.second;
313 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
316 Val = Op1.second - Op2.second;
317 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
320 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
321 "Multiply operation with an immediate and a register!");
322 Val = Op1.second * Op2.second;
323 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
326 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
327 "Divide operation with an immediate and a register!");
328 assert (Op2.second != 0 &&
"Division by zero!");
329 Val = Op1.second / Op2.second;
330 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
333 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
334 "Modulo operation with an immediate and a register!");
335 Val = Op1.second % Op2.second;
336 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
339 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
340 "Or operation with an immediate and a register!");
341 Val = Op1.second | Op2.second;
342 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
345 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
346 "Xor operation with an immediate and a register!");
347 Val = Op1.second ^ Op2.second;
348 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
351 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
352 "And operation with an immediate and a register!");
353 Val = Op1.second & Op2.second;
354 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
357 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
358 "Left shift operation with an immediate and a register!");
359 Val = Op1.second << Op2.second;
360 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
363 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
364 "Right shift operation with an immediate and a register!");
365 Val = Op1.second >> Op2.second;
366 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
369 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
370 "Equals operation with an immediate and a register!");
371 Val = (Op1.second == Op2.second) ? -1 : 0;
372 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
375 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
376 "Not-equals operation with an immediate and a register!");
377 Val = (Op1.second != Op2.second) ? -1 : 0;
378 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
381 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
382 "Less-than operation with an immediate and a register!");
383 Val = (Op1.second < Op2.second) ? -1 : 0;
384 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
387 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
388 "Less-than-or-equal operation with an immediate and a "
390 Val = (Op1.second <= Op2.second) ? -1 : 0;
391 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
394 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
395 "Greater-than operation with an immediate and a register!");
396 Val = (Op1.second > Op2.second) ? -1 : 0;
397 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
400 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
401 "Greater-than-or-equal operation with an immediate and a "
403 Val = (Op1.second >= Op2.second) ? -1 : 0;
404 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
409 assert (OperandStack.
size() == 1 &&
"Expected a single result.");
414 enum IntelExprState {
444 class IntelExprStateMachine {
445 IntelExprState State = IES_INIT, PrevState = IES_ERROR;
446 MCRegister BaseReg, IndexReg, TmpReg;
449 const MCExpr *Sym =
nullptr;
452 InlineAsmIdentifierInfo Info;
454 bool MemExpr =
false;
455 bool BracketUsed =
false;
456 bool OffsetOperator =
false;
457 bool AttachToOperandIdx =
false;
459 SMLoc OffsetOperatorLoc;
462 bool setSymRef(
const MCExpr *Val, StringRef
ID, StringRef &ErrMsg) {
464 ErrMsg =
"cannot use more than one symbol in memory operand";
473 IntelExprStateMachine() =
default;
475 void addImm(int64_t imm) { Imm += imm; }
476 short getBracCount()
const {
return BracCount; }
477 bool isMemExpr()
const {
return MemExpr; }
478 bool isBracketUsed()
const {
return BracketUsed; }
479 bool isOffsetOperator()
const {
return OffsetOperator; }
480 SMLoc getOffsetLoc()
const {
return OffsetOperatorLoc; }
481 MCRegister getBaseReg()
const {
return BaseReg; }
482 MCRegister getIndexReg()
const {
return IndexReg; }
483 unsigned getScale()
const {
return Scale; }
484 const MCExpr *
getSym()
const {
return Sym; }
485 StringRef getSymName()
const {
return SymName; }
486 StringRef
getType()
const {
return CurType.Name; }
487 unsigned getSize()
const {
return CurType.Size; }
488 unsigned getElementSize()
const {
return CurType.ElementSize; }
489 unsigned getLength()
const {
return CurType.Length; }
490 int64_t
getImm() {
return Imm + IC.execute(); }
491 bool isValidEndState()
const {
492 return State == IES_RBRAC || State == IES_RPAREN ||
493 State == IES_INTEGER || State == IES_REGISTER ||
501 void setAppendAfterOperand() { AttachToOperandIdx =
true; }
503 bool isPIC()
const {
return IsPIC; }
504 void setPIC() { IsPIC =
true; }
506 bool hadError()
const {
return State == IES_ERROR; }
507 const InlineAsmIdentifierInfo &getIdentifierInfo()
const {
return Info; }
509 bool regsUseUpError(StringRef &ErrMsg) {
512 if (IsPIC && AttachToOperandIdx)
513 ErrMsg =
"Don't use 2 or more regs for mem offset in PIC model!";
515 ErrMsg =
"BaseReg/IndexReg already set!";
520 IntelExprState CurrState = State;
529 IC.pushOperator(IC_OR);
532 PrevState = CurrState;
535 IntelExprState CurrState = State;
544 IC.pushOperator(IC_XOR);
547 PrevState = CurrState;
550 IntelExprState CurrState = State;
559 IC.pushOperator(IC_AND);
562 PrevState = CurrState;
565 IntelExprState CurrState = State;
574 IC.pushOperator(IC_EQ);
577 PrevState = CurrState;
580 IntelExprState CurrState = State;
589 IC.pushOperator(IC_NE);
592 PrevState = CurrState;
595 IntelExprState CurrState = State;
604 IC.pushOperator(IC_LT);
607 PrevState = CurrState;
610 IntelExprState CurrState = State;
619 IC.pushOperator(IC_LE);
622 PrevState = CurrState;
625 IntelExprState CurrState = State;
634 IC.pushOperator(IC_GT);
637 PrevState = CurrState;
640 IntelExprState CurrState = State;
649 IC.pushOperator(IC_GE);
652 PrevState = CurrState;
655 IntelExprState CurrState = State;
664 IC.pushOperator(IC_LSHIFT);
667 PrevState = CurrState;
670 IntelExprState CurrState = State;
679 IC.pushOperator(IC_RSHIFT);
682 PrevState = CurrState;
684 bool onPlus(StringRef &ErrMsg) {
685 IntelExprState CurrState = State;
695 IC.pushOperator(IC_PLUS);
696 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
703 return regsUseUpError(ErrMsg);
710 PrevState = CurrState;
713 bool onMinus(StringRef &ErrMsg) {
714 IntelExprState CurrState = State;
745 if (CurrState == IES_REGISTER || CurrState == IES_RPAREN ||
746 CurrState == IES_INTEGER || CurrState == IES_RBRAC ||
747 CurrState == IES_OFFSET)
748 IC.pushOperator(IC_MINUS);
749 else if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
751 ErrMsg =
"Scale can't be negative";
754 IC.pushOperator(IC_NEG);
755 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
762 return regsUseUpError(ErrMsg);
769 PrevState = CurrState;
773 IntelExprState CurrState = State;
799 IC.pushOperator(IC_NOT);
802 PrevState = CurrState;
804 bool onRegister(MCRegister
Reg, StringRef &ErrMsg) {
805 IntelExprState CurrState = State;
813 State = IES_REGISTER;
815 IC.pushOperand(IC_REGISTER);
819 if (PrevState == IES_INTEGER) {
821 return regsUseUpError(ErrMsg);
822 State = IES_REGISTER;
825 Scale = IC.popOperand();
828 IC.pushOperand(IC_IMM);
835 PrevState = CurrState;
838 bool onIdentifierExpr(
const MCExpr *SymRef, StringRef SymRefName,
839 const InlineAsmIdentifierInfo &IDInfo,
840 const AsmTypeInfo &
Type,
bool ParsingMSInlineAsm,
843 if (ParsingMSInlineAsm)
848 return onInteger(
CE->getValue(), ErrMsg);
861 if (setSymRef(SymRef, SymRefName, ErrMsg))
865 IC.pushOperand(IC_IMM);
866 if (ParsingMSInlineAsm)
873 bool onInteger(int64_t TmpInt, StringRef &ErrMsg) {
874 IntelExprState CurrState = State;
900 if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
903 return regsUseUpError(ErrMsg);
911 IC.pushOperand(IC_IMM, TmpInt);
915 PrevState = CurrState;
927 State = IES_MULTIPLY;
928 IC.pushOperator(IC_MULTIPLY);
941 IC.pushOperator(IC_DIVIDE);
954 IC.pushOperator(IC_MOD);
970 IC.pushOperator(IC_PLUS);
972 CurType.Size = CurType.ElementSize;
976 assert(!BracCount &&
"BracCount should be zero on parsing's start");
985 bool onRBrac(StringRef &ErrMsg) {
986 IntelExprState CurrState = State;
995 if (BracCount-- != 1) {
996 ErrMsg =
"unexpected bracket encountered";
1000 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
1007 return regsUseUpError(ErrMsg);
1014 PrevState = CurrState;
1018 IntelExprState CurrState = State;
1044 IC.pushOperator(IC_LPAREN);
1047 PrevState = CurrState;
1049 bool onRParen(StringRef &ErrMsg) {
1050 IntelExprState CurrState = State;
1065 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
1072 return regsUseUpError(ErrMsg);
1077 IC.pushOperator(IC_RPAREN);
1080 PrevState = CurrState;
1083 bool onOffset(
const MCExpr *Val, SMLoc OffsetLoc, StringRef
ID,
1084 const InlineAsmIdentifierInfo &IDInfo,
1085 bool ParsingMSInlineAsm, StringRef &ErrMsg) {
1089 ErrMsg =
"unexpected offset operator expression";
1094 if (setSymRef(Val,
ID, ErrMsg))
1096 OffsetOperator =
true;
1097 OffsetOperatorLoc = OffsetLoc;
1101 IC.pushOperand(IC_IMM);
1102 if (ParsingMSInlineAsm) {
1109 void onCast(AsmTypeInfo Info) {
1121 void setTypeInfo(AsmTypeInfo
Type) { CurType =
Type; }
1124 bool Error(SMLoc L,
const Twine &Msg, SMRange
Range = std::nullopt,
1125 bool MatchingInlineAsm =
false) {
1126 MCAsmParser &Parser = getParser();
1127 if (MatchingInlineAsm) {
1133 bool MatchRegisterByName(MCRegister &RegNo, StringRef
RegName, SMLoc StartLoc,
1135 bool ParseRegister(MCRegister &RegNo, SMLoc &StartLoc, SMLoc &EndLoc,
1136 bool RestoreOnFailure);
1138 std::unique_ptr<X86Operand> DefaultMemSIOperand(SMLoc Loc);
1139 std::unique_ptr<X86Operand> DefaultMemDIOperand(SMLoc Loc);
1140 bool IsSIReg(MCRegister
Reg);
1141 MCRegister GetSIDIForRegClass(
unsigned RegClassID,
bool IsSIReg);
1144 std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
1145 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst);
1151 bool ParseIntelOffsetOperator(
const MCExpr *&Val, StringRef &
ID,
1152 InlineAsmIdentifierInfo &
Info, SMLoc &End);
1153 bool ParseIntelDotOperator(IntelExprStateMachine &SM, SMLoc &End);
1154 unsigned IdentifyIntelInlineAsmOperator(StringRef Name);
1155 unsigned ParseIntelInlineAsmOperator(
unsigned OpKind);
1156 unsigned IdentifyMasmOperator(StringRef Name);
1157 bool ParseMasmOperator(
unsigned OpKind, int64_t &Val);
1160 bool ParseIntelNamedOperator(StringRef Name, IntelExprStateMachine &SM,
1161 bool &ParseError, SMLoc &End);
1162 bool ParseMasmNamedOperator(StringRef Name, IntelExprStateMachine &SM,
1163 bool &ParseError, SMLoc &End);
1164 void RewriteIntelExpression(IntelExprStateMachine &SM, SMLoc Start,
1166 bool ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End);
1167 bool ParseIntelInlineAsmIdentifier(
const MCExpr *&Val, StringRef &Identifier,
1168 InlineAsmIdentifierInfo &
Info,
1169 bool IsUnevaluatedOperand, SMLoc &End,
1170 bool IsParsingOffsetOperator =
false);
1172 IntelExprStateMachine &SM);
1174 bool ParseMemOperand(MCRegister SegReg,
const MCExpr *Disp, SMLoc StartLoc,
1179 bool ParseIntelMemoryOperandSize(
unsigned &
Size, StringRef *SizeStr);
1180 bool CreateMemForMSInlineAsm(MCRegister SegReg,
const MCExpr *Disp,
1181 MCRegister BaseReg, MCRegister IndexReg,
1182 unsigned Scale,
bool NonAbsMem, SMLoc Start,
1183 SMLoc End,
unsigned Size, StringRef Identifier,
1184 const InlineAsmIdentifierInfo &
Info,
1187 bool parseDirectiveArch();
1188 bool parseDirectiveNops(SMLoc L);
1189 bool parseDirectiveEven(SMLoc L);
1190 bool ParseDirectiveCode(StringRef IDVal, SMLoc L);
1193 bool parseDirectiveFPOProc(SMLoc L);
1194 bool parseDirectiveFPOSetFrame(SMLoc L);
1195 bool parseDirectiveFPOPushReg(SMLoc L);
1196 bool parseDirectiveFPOStackAlloc(SMLoc L);
1197 bool parseDirectiveFPOStackAlign(SMLoc L);
1198 bool parseDirectiveFPOEndPrologue(SMLoc L);
1199 bool parseDirectiveFPOEndProc(SMLoc L);
1202 bool parseSEHRegisterNumber(
unsigned RegClassID, MCRegister &RegNo);
1203 bool parseDirectiveSEHPushReg(SMLoc);
1204 bool parseDirectiveSEHSetFrame(SMLoc);
1205 bool parseDirectiveSEHSaveReg(SMLoc);
1206 bool parseDirectiveSEHSaveXMM(SMLoc);
1207 bool parseDirectiveSEHPushFrame(SMLoc);
1209 unsigned checkTargetMatchPredicate(MCInst &Inst)
override;
1215 void emitWarningForSpecialLVIInstruction(SMLoc Loc);
1216 void applyLVICFIMitigation(MCInst &Inst, MCStreamer &Out);
1217 void applyLVILoadHardeningMitigation(MCInst &Inst, MCStreamer &Out);
1223 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1225 uint64_t &ErrorInfo,
1226 bool MatchingInlineAsm)
override;
1229 MCStreamer &Out,
bool MatchingInlineAsm);
1231 bool ErrorMissingFeature(SMLoc IDLoc,
const FeatureBitset &MissingFeatures,
1232 bool MatchingInlineAsm);
1234 bool matchAndEmitATTInstruction(SMLoc IDLoc,
unsigned &Opcode, MCInst &Inst,
1236 uint64_t &ErrorInfo,
bool MatchingInlineAsm);
1238 bool matchAndEmitIntelInstruction(SMLoc IDLoc,
unsigned &Opcode, MCInst &Inst,
1240 uint64_t &ErrorInfo,
1241 bool MatchingInlineAsm);
1243 bool omitRegisterFromClobberLists(MCRegister
Reg)
override;
1250 bool ParseZ(std::unique_ptr<X86Operand> &Z,
const SMLoc &StartLoc);
1252 bool is64BitMode()
const {
1254 return getSTI().hasFeature(X86::Is64Bit);
1256 bool is32BitMode()
const {
1258 return getSTI().hasFeature(X86::Is32Bit);
1260 bool is16BitMode()
const {
1262 return getSTI().hasFeature(X86::Is16Bit);
1264 void SwitchMode(
unsigned mode) {
1265 MCSubtargetInfo &STI = copySTI();
1266 FeatureBitset AllModes({X86::Is64Bit, X86::Is32Bit, X86::Is16Bit});
1268 FeatureBitset FB = ComputeAvailableFeatures(
1270 setAvailableFeatures(FB);
1275 unsigned getPointerWidth() {
1276 if (is16BitMode())
return 16;
1277 if (is32BitMode())
return 32;
1278 if (is64BitMode())
return 64;
1282 bool isParsingIntelSyntax() {
1283 return getParser().getAssemblerDialect();
1289#define GET_ASSEMBLER_HEADER
1290#include "X86GenAsmMatcher.inc"
1295 enum X86MatchResultTy {
1296 Match_Unsupported = FIRST_TARGET_MATCH_RESULT_TY,
1297#define GET_OPERAND_DIAGNOSTIC_TYPES
1298#include "X86GenAsmMatcher.inc"
1301 X86AsmParser(
const MCSubtargetInfo &sti, MCAsmParser &Parser,
1302 const MCInstrInfo &mii,
const MCTargetOptions &
Options)
1303 : MCTargetAsmParser(
Options, sti, mii), InstInfo(nullptr),
1309 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
1312 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
1313 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1314 SMLoc &EndLoc)
override;
1316 bool parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc)
override;
1318 bool parseInstruction(ParseInstructionInfo &
Info, StringRef Name,
1321 bool ParseDirective(AsmToken DirectiveID)
override;
1325#define GET_REGISTER_MATCHER
1326#define GET_SUBTARGET_FEATURE_NAME
1327#include "X86GenAsmMatcher.inc"
1338 !(BaseReg == X86::RIP || BaseReg == X86::EIP ||
1339 X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg) ||
1340 X86MCRegisterClasses[X86::GR32RegClassID].
contains(BaseReg) ||
1341 X86MCRegisterClasses[X86::GR64RegClassID].
contains(BaseReg))) {
1342 ErrMsg =
"invalid base+index expression";
1347 !(IndexReg == X86::EIZ || IndexReg == X86::RIZ ||
1348 X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg) ||
1349 X86MCRegisterClasses[X86::GR32RegClassID].
contains(IndexReg) ||
1350 X86MCRegisterClasses[X86::GR64RegClassID].
contains(IndexReg) ||
1351 X86MCRegisterClasses[X86::VR128XRegClassID].
contains(IndexReg) ||
1352 X86MCRegisterClasses[X86::VR256XRegClassID].
contains(IndexReg) ||
1353 X86MCRegisterClasses[X86::VR512RegClassID].
contains(IndexReg))) {
1354 ErrMsg =
"invalid base+index expression";
1358 if (((BaseReg == X86::RIP || BaseReg == X86::EIP) && IndexReg) ||
1359 IndexReg == X86::EIP || IndexReg == X86::RIP || IndexReg == X86::ESP ||
1360 IndexReg == X86::RSP) {
1361 ErrMsg =
"invalid base+index expression";
1367 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg) &&
1368 (Is64BitMode || (BaseReg != X86::BX && BaseReg != X86::BP &&
1369 BaseReg != X86::SI && BaseReg != X86::DI))) {
1370 ErrMsg =
"invalid 16-bit base register";
1375 X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg)) {
1376 ErrMsg =
"16-bit memory operand may not include only index register";
1380 if (BaseReg && IndexReg) {
1381 if (X86MCRegisterClasses[X86::GR64RegClassID].
contains(BaseReg) &&
1382 (X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg) ||
1383 X86MCRegisterClasses[X86::GR32RegClassID].
contains(IndexReg) ||
1384 IndexReg == X86::EIZ)) {
1385 ErrMsg =
"base register is 64-bit, but index register is not";
1388 if (X86MCRegisterClasses[X86::GR32RegClassID].
contains(BaseReg) &&
1389 (X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg) ||
1390 X86MCRegisterClasses[X86::GR64RegClassID].
contains(IndexReg) ||
1391 IndexReg == X86::RIZ)) {
1392 ErrMsg =
"base register is 32-bit, but index register is not";
1395 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg)) {
1396 if (X86MCRegisterClasses[X86::GR32RegClassID].
contains(IndexReg) ||
1397 X86MCRegisterClasses[X86::GR64RegClassID].
contains(IndexReg)) {
1398 ErrMsg =
"base register is 16-bit, but index register is not";
1401 if ((BaseReg != X86::BX && BaseReg != X86::BP) ||
1402 (IndexReg != X86::SI && IndexReg != X86::DI)) {
1403 ErrMsg =
"invalid 16-bit base/index register combination";
1410 if (!Is64BitMode && (BaseReg == X86::RIP || BaseReg == X86::EIP)) {
1411 ErrMsg =
"IP-relative addressing requires 64-bit mode";
1432 if (isParsingMSInlineAsm() && isParsingIntelSyntax() &&
1433 (RegNo == X86::EFLAGS || RegNo == X86::MXCSR))
1434 RegNo = MCRegister();
1436 if (!is64BitMode()) {
1440 if (RegNo == X86::RIZ || RegNo == X86::RIP ||
1441 X86MCRegisterClasses[X86::GR64RegClassID].
contains(RegNo) ||
1444 return Error(StartLoc,
1445 "register %" +
RegName +
" is only available in 64-bit mode",
1446 SMRange(StartLoc, EndLoc));
1451 UseApxExtendedReg =
true;
1455 if (!RegNo &&
RegName.starts_with(
"db")) {
1514 if (isParsingIntelSyntax())
1516 return Error(StartLoc,
"invalid register name", SMRange(StartLoc, EndLoc));
1521bool X86AsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
1522 SMLoc &EndLoc,
bool RestoreOnFailure) {
1523 MCAsmParser &Parser = getParser();
1524 AsmLexer &Lexer = getLexer();
1525 RegNo = MCRegister();
1528 auto OnFailure = [RestoreOnFailure, &Lexer, &Tokens]() {
1529 if (RestoreOnFailure) {
1530 while (!Tokens.
empty()) {
1536 const AsmToken &PercentTok = Parser.
getTok();
1537 StartLoc = PercentTok.
getLoc();
1546 const AsmToken &Tok = Parser.
getTok();
1551 if (isParsingIntelSyntax())
return true;
1552 return Error(StartLoc,
"invalid register name",
1553 SMRange(StartLoc, EndLoc));
1556 if (MatchRegisterByName(RegNo, Tok.
getString(), StartLoc, EndLoc)) {
1562 if (RegNo == X86::ST0) {
1573 const AsmToken &IntTok = Parser.
getTok();
1576 return Error(IntTok.
getLoc(),
"expected stack index");
1579 case 0: RegNo = X86::ST0;
break;
1580 case 1: RegNo = X86::ST1;
break;
1581 case 2: RegNo = X86::ST2;
break;
1582 case 3: RegNo = X86::ST3;
break;
1583 case 4: RegNo = X86::ST4;
break;
1584 case 5: RegNo = X86::ST5;
break;
1585 case 6: RegNo = X86::ST6;
break;
1586 case 7: RegNo = X86::ST7;
break;
1589 return Error(IntTok.
getLoc(),
"invalid stack index");
1609 if (isParsingIntelSyntax())
return true;
1610 return Error(StartLoc,
"invalid register name",
1611 SMRange(StartLoc, EndLoc));
1618bool X86AsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1620 return ParseRegister(
Reg, StartLoc, EndLoc,
false);
1623ParseStatus X86AsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1625 bool Result = ParseRegister(
Reg, StartLoc, EndLoc,
true);
1626 bool PendingErrors = getParser().hasPendingError();
1627 getParser().clearPendingErrors();
1635std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(SMLoc Loc) {
1636 bool Parse32 = is32BitMode() || Code16GCC;
1637 MCRegister Basereg =
1638 is64BitMode() ? X86::RSI : (Parse32 ? X86::ESI : X86::SI);
1645std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand(SMLoc Loc) {
1646 bool Parse32 = is32BitMode() || Code16GCC;
1647 MCRegister Basereg =
1648 is64BitMode() ? X86::RDI : (Parse32 ? X86::EDI : X86::DI);
1655bool X86AsmParser::IsSIReg(MCRegister
Reg) {
1669MCRegister X86AsmParser::GetSIDIForRegClass(
unsigned RegClassID,
bool IsSIReg) {
1670 switch (RegClassID) {
1672 case X86::GR64RegClassID:
1673 return IsSIReg ? X86::RSI : X86::RDI;
1674 case X86::GR32RegClassID:
1675 return IsSIReg ? X86::ESI : X86::EDI;
1676 case X86::GR16RegClassID:
1677 return IsSIReg ? X86::SI : X86::DI;
1681void X86AsmParser::AddDefaultSrcDestOperands(
1683 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst) {
1684 if (isParsingIntelSyntax()) {
1685 Operands.push_back(std::move(Dst));
1686 Operands.push_back(std::move(Src));
1689 Operands.push_back(std::move(Src));
1690 Operands.push_back(std::move(Dst));
1694bool X86AsmParser::VerifyAndAdjustOperands(
OperandVector &OrigOperands,
1697 if (OrigOperands.
size() > 1) {
1700 "Operand size mismatch");
1704 int RegClassID = -1;
1705 for (
unsigned int i = 0; i < FinalOperands.
size(); ++i) {
1706 X86Operand &OrigOp =
static_cast<X86Operand &
>(*OrigOperands[i + 1]);
1707 X86Operand &FinalOp =
static_cast<X86Operand &
>(*FinalOperands[i]);
1709 if (FinalOp.
isReg() &&
1714 if (FinalOp.
isMem()) {
1716 if (!OrigOp.
isMem())
1725 if (RegClassID != -1 &&
1726 !X86MCRegisterClasses[RegClassID].
contains(OrigReg)) {
1728 "mismatching source and destination index registers");
1731 if (X86MCRegisterClasses[X86::GR64RegClassID].
contains(OrigReg))
1732 RegClassID = X86::GR64RegClassID;
1733 else if (X86MCRegisterClasses[X86::GR32RegClassID].
contains(OrigReg))
1734 RegClassID = X86::GR32RegClassID;
1735 else if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(OrigReg))
1736 RegClassID = X86::GR16RegClassID;
1742 bool IsSI = IsSIReg(FinalReg);
1743 FinalReg = GetSIDIForRegClass(RegClassID, IsSI);
1745 if (FinalReg != OrigReg) {
1746 std::string
RegName = IsSI ?
"ES:(R|E)SI" :
"ES:(R|E)DI";
1749 "memory operand is only for determining the size, " +
RegName +
1750 " will be used for the location"));
1761 for (
auto &WarningMsg : Warnings) {
1762 Warning(WarningMsg.first, WarningMsg.second);
1766 for (
unsigned int i = 0; i < FinalOperands.
size(); ++i)
1770 for (
auto &
Op : FinalOperands)
1777 if (isParsingIntelSyntax())
1778 return parseIntelOperand(
Operands, Name);
1783bool X86AsmParser::CreateMemForMSInlineAsm(
1784 MCRegister SegReg,
const MCExpr *Disp, MCRegister BaseReg,
1785 MCRegister IndexReg,
unsigned Scale,
bool NonAbsMem, SMLoc Start, SMLoc End,
1786 unsigned Size, StringRef Identifier,
const InlineAsmIdentifierInfo &
Info,
1794 End,
Size, Identifier,
1801 unsigned FrontendSize = 0;
1802 void *Decl =
nullptr;
1803 bool IsGlobalLV =
false;
1806 FrontendSize =
Info.Var.Type * 8;
1807 Decl =
Info.Var.Decl;
1808 IsGlobalLV =
Info.Var.IsGlobalLV;
1813 if (BaseReg || IndexReg) {
1815 End,
Size, Identifier, Decl, 0,
1816 BaseReg && IndexReg));
1823 getPointerWidth(), SegReg, Disp, BaseReg, IndexReg, Scale, Start, End,
1825 X86::RIP, Identifier, Decl, FrontendSize));
1832bool X86AsmParser::ParseIntelNamedOperator(StringRef Name,
1833 IntelExprStateMachine &SM,
1834 bool &ParseError, SMLoc &End) {
1837 if (Name !=
Name.lower() && Name !=
Name.upper() &&
1838 !getParser().isParsingMasm())
1840 if (
Name.equals_insensitive(
"not")) {
1842 }
else if (
Name.equals_insensitive(
"or")) {
1844 }
else if (
Name.equals_insensitive(
"shl")) {
1846 }
else if (
Name.equals_insensitive(
"shr")) {
1848 }
else if (
Name.equals_insensitive(
"xor")) {
1850 }
else if (
Name.equals_insensitive(
"and")) {
1852 }
else if (
Name.equals_insensitive(
"mod")) {
1854 }
else if (
Name.equals_insensitive(
"offset")) {
1855 SMLoc OffsetLoc = getTok().getLoc();
1856 const MCExpr *Val =
nullptr;
1858 InlineAsmIdentifierInfo
Info;
1864 SM.onOffset(Val, OffsetLoc,
ID,
Info, isParsingMSInlineAsm(), ErrMsg);
1870 if (!
Name.equals_insensitive(
"offset"))
1871 End = consumeToken();
1874bool X86AsmParser::ParseMasmNamedOperator(StringRef Name,
1875 IntelExprStateMachine &SM,
1876 bool &ParseError, SMLoc &End) {
1877 if (
Name.equals_insensitive(
"eq")) {
1879 }
else if (
Name.equals_insensitive(
"ne")) {
1881 }
else if (
Name.equals_insensitive(
"lt")) {
1883 }
else if (
Name.equals_insensitive(
"le")) {
1885 }
else if (
Name.equals_insensitive(
"gt")) {
1887 }
else if (
Name.equals_insensitive(
"ge")) {
1892 End = consumeToken();
1899 IntelExprStateMachine &SM) {
1903 SM.setAppendAfterOperand();
1906bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
1907 MCAsmParser &Parser = getParser();
1912 if (
getContext().getObjectFileInfo()->isPositionIndependent())
1919 const AsmToken &Tok = Parser.
getTok();
1921 bool UpdateLocLex =
true;
1926 if ((
Done = SM.isValidEndState()))
1928 return Error(Tok.
getLoc(),
"unknown token in expression");
1930 return Error(getLexer().getErrLoc(), getLexer().getErr());
1934 UpdateLocLex =
false;
1935 if (ParseIntelDotOperator(SM, End))
1940 if ((
Done = SM.isValidEndState()))
1942 return Error(Tok.
getLoc(),
"unknown token in expression");
1946 UpdateLocLex =
false;
1947 if (ParseIntelDotOperator(SM, End))
1952 if ((
Done = SM.isValidEndState()))
1954 return Error(Tok.
getLoc(),
"unknown token in expression");
1960 SMLoc ValueLoc = Tok.
getLoc();
1965 UpdateLocLex =
false;
1966 if (!Val->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
1967 return Error(ValueLoc,
"expected absolute value");
1968 if (SM.onInteger(Res, ErrMsg))
1969 return Error(ValueLoc, ErrMsg);
1976 SMLoc IdentLoc = Tok.
getLoc();
1978 UpdateLocLex =
false;
1980 size_t DotOffset =
Identifier.find_first_of(
'.');
1984 StringRef Dot =
Identifier.substr(DotOffset, 1);
1998 const AsmToken &NextTok = getLexer().peekTok();
2007 End = consumeToken();
2014 if (!ParseRegister(
Reg, IdentLoc, End,
true)) {
2015 if (SM.onRegister(
Reg, ErrMsg))
2016 return Error(IdentLoc, ErrMsg);
2020 const std::pair<StringRef, StringRef> IDField =
2022 const StringRef
ID = IDField.first,
Field = IDField.second;
2024 if (!
Field.empty() &&
2025 !MatchRegisterByName(
Reg,
ID, IdentLoc, IDEndLoc)) {
2026 if (SM.onRegister(
Reg, ErrMsg))
2027 return Error(IdentLoc, ErrMsg);
2032 return Error(FieldStartLoc,
"unknown offset");
2033 else if (SM.onPlus(ErrMsg))
2034 return Error(getTok().getLoc(), ErrMsg);
2035 else if (SM.onInteger(
Info.Offset, ErrMsg))
2036 return Error(IdentLoc, ErrMsg);
2037 SM.setTypeInfo(
Info.Type);
2039 End = consumeToken();
2046 if (ParseIntelNamedOperator(Identifier, SM, ParseError, End)) {
2052 ParseMasmNamedOperator(Identifier, SM, ParseError, End)) {
2058 InlineAsmIdentifierInfo
Info;
2059 AsmFieldInfo FieldInfo;
2065 if (ParseIntelDotOperator(SM, End))
2070 if (isParsingMSInlineAsm()) {
2072 if (
unsigned OpKind = IdentifyIntelInlineAsmOperator(Identifier)) {
2073 if (int64_t Val = ParseIntelInlineAsmOperator(OpKind)) {
2074 if (SM.onInteger(Val, ErrMsg))
2075 return Error(IdentLoc, ErrMsg);
2084 return Error(IdentLoc,
"expected identifier");
2085 if (ParseIntelInlineAsmIdentifier(Val, Identifier,
Info,
false, End))
2087 else if (SM.onIdentifierExpr(Val, Identifier,
Info, FieldInfo.
Type,
2089 return Error(IdentLoc, ErrMsg);
2093 if (
unsigned OpKind = IdentifyMasmOperator(Identifier)) {
2095 if (ParseMasmOperator(OpKind, Val))
2097 if (SM.onInteger(Val, ErrMsg))
2098 return Error(IdentLoc, ErrMsg);
2101 if (!getParser().lookUpType(Identifier, FieldInfo.
Type)) {
2107 getParser().parseIdentifier(Identifier);
2111 if (getParser().lookUpField(FieldInfo.
Type.
Name, Identifier,
2115 return Error(IdentLoc,
"Unable to lookup field reference!",
2116 SMRange(IdentLoc, IDEnd));
2121 if (SM.onInteger(FieldInfo.
Offset, ErrMsg))
2122 return Error(IdentLoc, ErrMsg);
2126 if (getParser().parsePrimaryExpr(Val, End, &FieldInfo.
Type)) {
2127 return Error(Tok.
getLoc(),
"Unexpected identifier!");
2128 }
else if (SM.onIdentifierExpr(Val, Identifier,
Info, FieldInfo.
Type,
2130 return Error(IdentLoc, ErrMsg);
2136 SMLoc Loc = getTok().getLoc();
2137 int64_t
IntVal = getTok().getIntVal();
2138 End = consumeToken();
2139 UpdateLocLex =
false;
2141 StringRef IDVal = getTok().getString();
2142 if (IDVal ==
"f" || IDVal ==
"b") {
2144 getContext().getDirectionalLocalSymbol(IntVal, IDVal ==
"b");
2149 return Error(Loc,
"invalid reference to undefined symbol");
2151 InlineAsmIdentifierInfo
Info;
2153 if (SM.onIdentifierExpr(Val, Identifier,
Info,
Type,
2154 isParsingMSInlineAsm(), ErrMsg))
2155 return Error(Loc, ErrMsg);
2156 End = consumeToken();
2158 if (SM.onInteger(IntVal, ErrMsg))
2159 return Error(Loc, ErrMsg);
2162 if (SM.onInteger(IntVal, ErrMsg))
2163 return Error(Loc, ErrMsg);
2168 if (SM.onPlus(ErrMsg))
2169 return Error(getTok().getLoc(), ErrMsg);
2172 if (SM.onMinus(ErrMsg))
2173 return Error(getTok().getLoc(), ErrMsg);
2183 SM.onLShift();
break;
2185 SM.onRShift();
break;
2188 return Error(Tok.
getLoc(),
"unexpected bracket encountered");
2189 tryParseOperandIdx(PrevTK, SM);
2192 if (SM.onRBrac(ErrMsg)) {
2198 if (SM.onRParen(ErrMsg)) {
2204 return Error(Tok.
getLoc(),
"unknown token in expression");
2206 if (!
Done && UpdateLocLex)
2207 End = consumeToken();
2214void X86AsmParser::RewriteIntelExpression(IntelExprStateMachine &SM,
2215 SMLoc Start, SMLoc End) {
2219 if (SM.getSym() && !SM.isOffsetOperator()) {
2220 StringRef SymName = SM.getSymName();
2221 if (
unsigned Len = SymName.
data() -
Start.getPointer())
2227 if (!(SM.getBaseReg() || SM.getIndexReg() || SM.getImm())) {
2234 StringRef BaseRegStr;
2235 StringRef IndexRegStr;
2236 StringRef OffsetNameStr;
2237 if (SM.getBaseReg())
2239 if (SM.getIndexReg())
2241 if (SM.isOffsetOperator())
2242 OffsetNameStr = SM.getSymName();
2244 IntelExpr Expr(BaseRegStr, IndexRegStr, SM.getScale(), OffsetNameStr,
2245 SM.getImm(), SM.isMemExpr());
2246 InstInfo->
AsmRewrites->emplace_back(Loc, ExprLen, Expr);
2250bool X86AsmParser::ParseIntelInlineAsmIdentifier(
2251 const MCExpr *&Val, StringRef &Identifier, InlineAsmIdentifierInfo &
Info,
2252 bool IsUnevaluatedOperand, SMLoc &End,
bool IsParsingOffsetOperator) {
2253 MCAsmParser &Parser = getParser();
2254 assert(isParsingMSInlineAsm() &&
"Expected to be parsing inline assembly.");
2258 SemaCallback->LookupInlineAsmIdentifier(LineBuf,
Info, IsUnevaluatedOperand);
2260 const AsmToken &Tok = Parser.
getTok();
2261 SMLoc Loc = Tok.
getLoc();
2276 "frontend claimed part of a token?");
2281 StringRef InternalName =
2282 SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(),
2284 assert(InternalName.
size() &&
"We should have an internal name here.");
2287 if (!IsParsingOffsetOperator)
2303 MCAsmParser &Parser = getParser();
2304 const AsmToken &Tok = Parser.
getTok();
2306 const SMLoc consumedToken = consumeToken();
2308 return Error(Tok.
getLoc(),
"Expected an identifier after {");
2311 .Case(
"rn", X86::STATIC_ROUNDING::TO_NEAREST_INT)
2312 .Case(
"rd", X86::STATIC_ROUNDING::TO_NEG_INF)
2313 .Case(
"ru", X86::STATIC_ROUNDING::TO_POS_INF)
2314 .Case(
"rz", X86::STATIC_ROUNDING::TO_ZERO)
2317 return Error(Tok.
getLoc(),
"Invalid rounding mode.");
2320 return Error(Tok.
getLoc(),
"Expected - at this point");
2324 return Error(Tok.
getLoc(),
"Expected } at this point");
2327 const MCExpr *RndModeOp =
2335 return Error(Tok.
getLoc(),
"Expected } at this point");
2340 return Error(Tok.
getLoc(),
"unknown token in expression");
2346 MCAsmParser &Parser = getParser();
2347 AsmToken Tok = Parser.
getTok();
2350 return Error(Tok.
getLoc(),
"Expected { at this point");
2354 return Error(Tok.
getLoc(),
"Expected dfv at this point");
2358 return Error(Tok.
getLoc(),
"Expected = at this point");
2370 unsigned CFlags = 0;
2371 for (
unsigned I = 0;
I < 4; ++
I) {
2380 return Error(Tok.
getLoc(),
"Invalid conditional flags");
2383 return Error(Tok.
getLoc(),
"Duplicated conditional flag");
2394 }
else if (
I == 3) {
2395 return Error(Tok.
getLoc(),
"Expected } at this point");
2397 return Error(Tok.
getLoc(),
"Expected } or , at this point");
2405bool X86AsmParser::ParseIntelDotOperator(IntelExprStateMachine &SM,
2407 const AsmToken &Tok = getTok();
2413 bool TrailingDot =
false;
2421 }
else if ((isParsingMSInlineAsm() || getParser().isParsingMasm()) &&
2424 const std::pair<StringRef, StringRef> BaseMember = DotDispStr.
split(
'.');
2425 const StringRef
Base = BaseMember.first,
Member = BaseMember.second;
2426 if (getParser().lookUpField(SM.getType(), DotDispStr,
Info) &&
2427 getParser().lookUpField(SM.getSymName(), DotDispStr,
Info) &&
2428 getParser().lookUpField(DotDispStr,
Info) &&
2430 SemaCallback->LookupInlineAsmField(
Base, Member,
Info.Offset)))
2431 return Error(Tok.
getLoc(),
"Unable to lookup field reference!");
2433 return Error(Tok.
getLoc(),
"Unexpected token type!");
2438 const char *DotExprEndLoc = DotDispStr.
data() + DotDispStr.
size();
2443 SM.addImm(
Info.Offset);
2444 SM.setTypeInfo(
Info.Type);
2450bool X86AsmParser::ParseIntelOffsetOperator(
const MCExpr *&Val, StringRef &
ID,
2451 InlineAsmIdentifierInfo &
Info,
2454 SMLoc
Start = Lex().getLoc();
2455 ID = getTok().getString();
2456 if (!isParsingMSInlineAsm()) {
2459 getParser().parsePrimaryExpr(Val, End,
nullptr))
2460 return Error(Start,
"unexpected token!");
2461 }
else if (ParseIntelInlineAsmIdentifier(Val,
ID,
Info,
false, End,
true)) {
2462 return Error(Start,
"unable to lookup expression");
2464 return Error(Start,
"offset operator cannot yet handle constants");
2471unsigned X86AsmParser::IdentifyIntelInlineAsmOperator(StringRef Name) {
2472 return StringSwitch<unsigned>(Name)
2473 .Cases(
"TYPE",
"type",IOK_TYPE)
2474 .Cases(
"SIZE",
"size",IOK_SIZE)
2475 .Cases(
"LENGTH",
"length",IOK_LENGTH)
2476 .Default(IOK_INVALID);
2485unsigned X86AsmParser::ParseIntelInlineAsmOperator(
unsigned OpKind) {
2486 MCAsmParser &Parser = getParser();
2487 const AsmToken &Tok = Parser.
getTok();
2490 const MCExpr *Val =
nullptr;
2491 InlineAsmIdentifierInfo
Info;
2494 if (ParseIntelInlineAsmIdentifier(Val, Identifier,
Info,
2499 Error(Start,
"unable to lookup expression");
2506 case IOK_LENGTH: CVal =
Info.Var.Length;
break;
2507 case IOK_SIZE: CVal =
Info.Var.Size;
break;
2508 case IOK_TYPE: CVal =
Info.Var.Type;
break;
2516unsigned X86AsmParser::IdentifyMasmOperator(StringRef Name) {
2517 return StringSwitch<unsigned>(
Name.lower())
2518 .Case(
"type", MOK_TYPE)
2519 .Cases(
"size",
"sizeof", MOK_SIZEOF)
2520 .Cases(
"length",
"lengthof", MOK_LENGTHOF)
2521 .Default(MOK_INVALID);
2530bool X86AsmParser::ParseMasmOperator(
unsigned OpKind, int64_t &Val) {
2531 MCAsmParser &Parser = getParser();
2536 if (OpKind == MOK_SIZEOF || OpKind == MOK_TYPE) {
2539 const AsmToken &IDTok = InParens ? getLexer().peekTok() : Parser.
getTok();
2555 IntelExprStateMachine SM;
2557 if (ParseIntelExpression(SM, End))
2567 Val = SM.getLength();
2570 Val = SM.getElementSize();
2575 return Error(OpLoc,
"expression has unknown type", SMRange(Start, End));
2581bool X86AsmParser::ParseIntelMemoryOperandSize(
unsigned &
Size,
2582 StringRef *SizeStr) {
2583 Size = StringSwitch<unsigned>(getTok().getString())
2584 .Cases(
"BYTE",
"byte", 8)
2585 .Cases(
"WORD",
"word", 16)
2586 .Cases(
"DWORD",
"dword", 32)
2587 .Cases(
"FLOAT",
"float", 32)
2588 .Cases(
"LONG",
"long", 32)
2589 .Cases(
"FWORD",
"fword", 48)
2590 .Cases(
"DOUBLE",
"double", 64)
2591 .Cases(
"QWORD",
"qword", 64)
2592 .Cases(
"MMWORD",
"mmword", 64)
2593 .Cases(
"XWORD",
"xword", 80)
2594 .Cases(
"TBYTE",
"tbyte", 80)
2595 .Cases(
"XMMWORD",
"xmmword", 128)
2596 .Cases(
"YMMWORD",
"ymmword", 256)
2597 .Cases(
"ZMMWORD",
"zmmword", 512)
2601 *SizeStr = getTok().getString();
2602 const AsmToken &Tok = Lex();
2604 return Error(Tok.
getLoc(),
"Expected 'PTR' or 'ptr' token!");
2611 if (X86MCRegisterClasses[X86::GR8RegClassID].
contains(RegNo))
2613 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(RegNo))
2615 if (X86MCRegisterClasses[X86::GR32RegClassID].
contains(RegNo))
2617 if (X86MCRegisterClasses[X86::GR64RegClassID].
contains(RegNo))
2624 MCAsmParser &Parser = getParser();
2625 const AsmToken &Tok = Parser.
getTok();
2631 if (ParseIntelMemoryOperandSize(
Size, &SizeStr))
2633 bool PtrInOperand = bool(
Size);
2639 return ParseRoundingModeOp(Start,
Operands);
2644 if (RegNo == X86::RIP)
2645 return Error(Start,
"rip can only be used as a base register");
2650 return Error(Start,
"expected memory operand after 'ptr', "
2651 "found register operand instead");
2660 "cannot cast register '" +
2662 "'; its size is not easily defined.");
2666 std::to_string(
RegSize) +
"-bit register '" +
2668 "' cannot be used as a " + std::to_string(
Size) +
"-bit " +
2675 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].
contains(RegNo))
2676 return Error(Start,
"invalid segment register");
2678 Start = Lex().getLoc();
2682 IntelExprStateMachine SM;
2683 if (ParseIntelExpression(SM, End))
2686 if (isParsingMSInlineAsm())
2687 RewriteIntelExpression(SM, Start, Tok.
getLoc());
2689 int64_t
Imm = SM.getImm();
2690 const MCExpr *Disp = SM.getSym();
2699 if (!SM.isMemExpr() && !RegNo) {
2700 if (isParsingMSInlineAsm() && SM.isOffsetOperator()) {
2701 const InlineAsmIdentifierInfo &
Info = SM.getIdentifierInfo();
2706 SM.getSymName(),
Info.Var.Decl,
2707 Info.Var.IsGlobalLV));
2717 MCRegister
BaseReg = SM.getBaseReg();
2718 MCRegister IndexReg = SM.getIndexReg();
2719 if (IndexReg && BaseReg == X86::RIP)
2721 unsigned Scale = SM.getScale();
2723 Size = SM.getElementSize() << 3;
2725 if (Scale == 0 && BaseReg != X86::ESP && BaseReg != X86::RSP &&
2726 (IndexReg == X86::ESP || IndexReg == X86::RSP))
2732 !(X86MCRegisterClasses[X86::VR128XRegClassID].
contains(IndexReg) ||
2733 X86MCRegisterClasses[X86::VR256XRegClassID].
contains(IndexReg) ||
2734 X86MCRegisterClasses[X86::VR512RegClassID].
contains(IndexReg)) &&
2735 (X86MCRegisterClasses[X86::VR128XRegClassID].
contains(BaseReg) ||
2736 X86MCRegisterClasses[X86::VR256XRegClassID].
contains(BaseReg) ||
2737 X86MCRegisterClasses[X86::VR512RegClassID].
contains(BaseReg)))
2741 X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg))
2742 return Error(Start,
"16-bit addresses cannot have a scale");
2751 if ((BaseReg == X86::SI || BaseReg == X86::DI) &&
2752 (IndexReg == X86::BX || IndexReg == X86::BP))
2755 if ((BaseReg || IndexReg) &&
2758 return Error(Start, ErrMsg);
2759 bool IsUnconditionalBranch =
2760 Name.equals_insensitive(
"jmp") ||
Name.equals_insensitive(
"call");
2761 if (isParsingMSInlineAsm())
2762 return CreateMemForMSInlineAsm(RegNo, Disp, BaseReg, IndexReg, Scale,
2763 IsUnconditionalBranch && is64BitMode(),
2764 Start, End,
Size, SM.getSymName(),
2769 MCRegister DefaultBaseReg;
2770 bool MaybeDirectBranchDest =
true;
2773 if (is64BitMode() &&
2774 ((PtrInOperand && !IndexReg) || SM.getElementSize() > 0)) {
2775 DefaultBaseReg = X86::RIP;
2777 if (IsUnconditionalBranch) {
2779 MaybeDirectBranchDest =
false;
2781 DefaultBaseReg = X86::RIP;
2782 }
else if (!BaseReg && !IndexReg && Disp &&
2784 if (is64BitMode()) {
2785 if (SM.getSize() == 8) {
2786 MaybeDirectBranchDest =
false;
2787 DefaultBaseReg = X86::RIP;
2790 if (SM.getSize() == 4 || SM.getSize() == 2)
2791 MaybeDirectBranchDest =
false;
2795 }
else if (IsUnconditionalBranch) {
2797 if (!PtrInOperand && SM.isOffsetOperator())
2799 Start,
"`OFFSET` operator cannot be used in an unconditional branch");
2800 if (PtrInOperand || SM.isBracketUsed())
2801 MaybeDirectBranchDest =
false;
2804 if ((BaseReg || IndexReg || RegNo || DefaultBaseReg))
2806 getPointerWidth(), RegNo, Disp, BaseReg, IndexReg, Scale, Start, End,
2807 Size, DefaultBaseReg, StringRef(),
nullptr,
2808 0,
false, MaybeDirectBranchDest));
2811 getPointerWidth(), Disp, Start, End,
Size, StringRef(),
2813 MaybeDirectBranchDest));
2818 MCAsmParser &Parser = getParser();
2819 switch (getLexer().getKind()) {
2829 "expected immediate expression") ||
2830 getParser().parseExpression(Val, End) ||
2838 return ParseRoundingModeOp(Start,
Operands);
2847 const MCExpr *Expr =
nullptr;
2859 if (
Reg == X86::EIZ ||
Reg == X86::RIZ)
2861 Loc,
"%eiz and %riz can only be used as index registers",
2862 SMRange(Loc, EndLoc));
2863 if (
Reg == X86::RIP)
2864 return Error(Loc,
"%rip can only be used as a base register",
2865 SMRange(Loc, EndLoc));
2871 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].
contains(
Reg))
2872 return Error(Loc,
"invalid segment register");
2880 return ParseMemOperand(
Reg, Expr, Loc, EndLoc,
Operands);
2887X86::CondCode X86AsmParser::ParseConditionCode(StringRef CC) {
2888 return StringSwitch<X86::CondCode>(CC)
2910bool X86AsmParser::ParseZ(std::unique_ptr<X86Operand> &Z,
2911 const SMLoc &StartLoc) {
2912 MCAsmParser &Parser = getParser();
2917 (getLexer().getTok().getIdentifier() ==
"z")))
2922 return Error(getLexer().getLoc(),
"Expected } at this point");
2931 MCAsmParser &Parser = getParser();
2934 const SMLoc consumedToken = consumeToken();
2938 if (getLexer().getTok().getIntVal() != 1)
2939 return TokError(
"Expected 1to<NUM> at this point");
2940 StringRef
Prefix = getLexer().getTok().getString();
2943 return TokError(
"Expected 1to<NUM> at this point");
2946 StringRef BroadcastString = (
Prefix + getLexer().getTok().getIdentifier())
2949 return TokError(
"Expected 1to<NUM> at this point");
2950 const char *BroadcastPrimitive =
2951 StringSwitch<const char *>(BroadcastString)
2952 .Case(
"1to2",
"{1to2}")
2953 .Case(
"1to4",
"{1to4}")
2954 .Case(
"1to8",
"{1to8}")
2955 .Case(
"1to16",
"{1to16}")
2956 .Case(
"1to32",
"{1to32}")
2958 if (!BroadcastPrimitive)
2959 return TokError(
"Invalid memory broadcast primitive.");
2962 return TokError(
"Expected } at this point");
2973 std::unique_ptr<X86Operand>
Z;
2974 if (ParseZ(Z, consumedToken))
2980 SMLoc StartLoc =
Z ? consumeToken() : consumedToken;
2985 if (!parseRegister(RegNo, RegLoc, StartLoc) &&
2986 X86MCRegisterClasses[X86::VK1RegClassID].
contains(RegNo)) {
2987 if (RegNo == X86::K0)
2988 return Error(RegLoc,
"Register k0 can't be used as write mask");
2990 return Error(getLexer().getLoc(),
"Expected } at this point");
2996 return Error(getLexer().getLoc(),
2997 "Expected an op-mask register at this point");
3002 if (ParseZ(Z, consumeToken()) || !Z)
3003 return Error(getLexer().getLoc(),
3004 "Expected a {z} mark at this point");
3020bool X86AsmParser::ParseMemOperand(MCRegister SegReg,
const MCExpr *Disp,
3021 SMLoc StartLoc, SMLoc EndLoc,
3023 MCAsmParser &Parser = getParser();
3041 auto isAtMemOperand = [
this]() {
3046 auto TokCount = this->getLexer().peekTokens(Buf,
true);
3049 switch (Buf[0].getKind()) {
3056 if ((TokCount > 1) &&
3058 (Buf[0].getLoc().getPointer() + 1 == Buf[1].getLoc().getPointer()))
3059 Id = StringRef(Buf[0].getLoc().getPointer(),
3060 Buf[1].getIdentifier().
size() + 1);
3082 if (!isAtMemOperand()) {
3101 0, 0, 1, StartLoc, EndLoc));
3109 SMLoc BaseLoc = getLexer().getLoc();
3121 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ)
3122 return Error(BaseLoc,
"eiz and riz can only be used as index registers",
3123 SMRange(BaseLoc, EndLoc));
3141 if (!
E->evaluateAsAbsolute(ScaleVal, getStreamer().getAssemblerPtr()))
3142 return Error(Loc,
"expected absolute expression");
3144 Warning(Loc,
"scale factor without index register is ignored");
3149 if (BaseReg == X86::RIP)
3151 "%rip as base register can not have an index register");
3152 if (IndexReg == X86::RIP)
3153 return Error(Loc,
"%rip is not allowed as an index register");
3164 return Error(Loc,
"expected scale expression");
3165 Scale = (unsigned)ScaleVal;
3167 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg) &&
3169 return Error(Loc,
"scale factor in 16-bit address must be 1");
3171 return Error(Loc, ErrMsg);
3185 if (BaseReg == X86::DX && !IndexReg && Scale == 1 && !SegReg &&
3194 return Error(BaseLoc, ErrMsg);
3201 if (BaseReg || IndexReg) {
3203 auto Imm =
CE->getValue();
3204 bool Is64 = X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) ||
3205 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg);
3206 bool Is16 = X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg);
3209 return Error(BaseLoc,
"displacement " + Twine(Imm) +
3210 " is not within [-2147483648, 2147483647]");
3212 if (!
isUInt<32>(Imm < 0 ? -uint64_t(Imm) : uint64_t(Imm))) {
3213 Warning(BaseLoc,
"displacement " + Twine(Imm) +
3214 " shortened to 32-bit signed " +
3215 Twine(
static_cast<int32_t
>(Imm)));
3217 }
else if (!
isUInt<16>(Imm < 0 ? -uint64_t(Imm) : uint64_t(Imm))) {
3218 Warning(BaseLoc,
"displacement " + Twine(Imm) +
3219 " shortened to 16-bit signed " +
3220 Twine(
static_cast<int16_t
>(Imm)));
3225 if (SegReg || BaseReg || IndexReg)
3227 BaseReg, IndexReg, Scale, StartLoc,
3236bool X86AsmParser::parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
3237 MCAsmParser &Parser = getParser();
3244 if (parseRegister(RegNo, StartLoc, EndLoc))
3252bool X86AsmParser::parseInstruction(ParseInstructionInfo &
Info, StringRef Name,
3254 MCAsmParser &Parser = getParser();
3258 ForcedOpcodePrefix = OpcodePrefix_Default;
3259 ForcedDispEncoding = DispEncoding_Default;
3260 UseApxExtendedReg =
false;
3261 ForcedNoFlag =
false;
3274 if (Prefix ==
"rex")
3275 ForcedOpcodePrefix = OpcodePrefix_REX;
3276 else if (Prefix ==
"rex2")
3277 ForcedOpcodePrefix = OpcodePrefix_REX2;
3278 else if (Prefix ==
"vex")
3279 ForcedOpcodePrefix = OpcodePrefix_VEX;
3280 else if (Prefix ==
"vex2")
3281 ForcedOpcodePrefix = OpcodePrefix_VEX2;
3282 else if (Prefix ==
"vex3")
3283 ForcedOpcodePrefix = OpcodePrefix_VEX3;
3284 else if (Prefix ==
"evex")
3285 ForcedOpcodePrefix = OpcodePrefix_EVEX;
3286 else if (Prefix ==
"disp8")
3287 ForcedDispEncoding = DispEncoding_Disp8;
3288 else if (Prefix ==
"disp32")
3289 ForcedDispEncoding = DispEncoding_Disp32;
3290 else if (Prefix ==
"nf")
3291 ForcedNoFlag =
true;
3293 return Error(NameLoc,
"unknown prefix");
3309 if (isParsingMSInlineAsm()) {
3310 if (
Name.equals_insensitive(
"vex"))
3311 ForcedOpcodePrefix = OpcodePrefix_VEX;
3312 else if (
Name.equals_insensitive(
"vex2"))
3313 ForcedOpcodePrefix = OpcodePrefix_VEX2;
3314 else if (
Name.equals_insensitive(
"vex3"))
3315 ForcedOpcodePrefix = OpcodePrefix_VEX3;
3316 else if (
Name.equals_insensitive(
"evex"))
3317 ForcedOpcodePrefix = OpcodePrefix_EVEX;
3319 if (ForcedOpcodePrefix != OpcodePrefix_Default) {
3332 if (
Name.consume_back(
".d32")) {
3333 ForcedDispEncoding = DispEncoding_Disp32;
3334 }
else if (
Name.consume_back(
".d8")) {
3335 ForcedDispEncoding = DispEncoding_Disp8;
3338 StringRef PatchedName =
Name;
3341 if (isParsingIntelSyntax() &&
3342 (PatchedName ==
"jmp" || PatchedName ==
"jc" || PatchedName ==
"jnc" ||
3343 PatchedName ==
"jcxz" || PatchedName ==
"jecxz" ||
3348 : NextTok ==
"short") {
3357 NextTok.
size() + 1);
3363 PatchedName !=
"setzub" && PatchedName !=
"setzunb" &&
3364 PatchedName !=
"setb" && PatchedName !=
"setnb")
3365 PatchedName = PatchedName.
substr(0,
Name.size()-1);
3367 unsigned ComparisonPredicate = ~0
U;
3375 bool IsVCMP = PatchedName[0] ==
'v';
3376 unsigned CCIdx =
IsVCMP ? 4 : 3;
3377 unsigned suffixLength = PatchedName.
ends_with(
"bf16") ? 5 : 2;
3378 unsigned CC = StringSwitch<unsigned>(
3379 PatchedName.
slice(CCIdx, PatchedName.
size() - suffixLength))
3381 .Case(
"eq_oq", 0x00)
3383 .Case(
"lt_os", 0x01)
3385 .Case(
"le_os", 0x02)
3386 .Case(
"unord", 0x03)
3387 .Case(
"unord_q", 0x03)
3389 .Case(
"neq_uq", 0x04)
3391 .Case(
"nlt_us", 0x05)
3393 .Case(
"nle_us", 0x06)
3395 .Case(
"ord_q", 0x07)
3397 .Case(
"eq_uq", 0x08)
3399 .Case(
"nge_us", 0x09)
3401 .Case(
"ngt_us", 0x0A)
3402 .Case(
"false", 0x0B)
3403 .Case(
"false_oq", 0x0B)
3404 .Case(
"neq_oq", 0x0C)
3406 .Case(
"ge_os", 0x0D)
3408 .Case(
"gt_os", 0x0E)
3410 .Case(
"true_uq", 0x0F)
3411 .Case(
"eq_os", 0x10)
3412 .Case(
"lt_oq", 0x11)
3413 .Case(
"le_oq", 0x12)
3414 .Case(
"unord_s", 0x13)
3415 .Case(
"neq_us", 0x14)
3416 .Case(
"nlt_uq", 0x15)
3417 .Case(
"nle_uq", 0x16)
3418 .Case(
"ord_s", 0x17)
3419 .Case(
"eq_us", 0x18)
3420 .Case(
"nge_uq", 0x19)
3421 .Case(
"ngt_uq", 0x1A)
3422 .Case(
"false_os", 0x1B)
3423 .Case(
"neq_os", 0x1C)
3424 .Case(
"ge_oq", 0x1D)
3425 .Case(
"gt_oq", 0x1E)
3426 .Case(
"true_us", 0x1F)
3428 if (CC != ~0U && (
IsVCMP || CC < 8) &&
3431 PatchedName =
IsVCMP ?
"vcmpss" :
"cmpss";
3433 PatchedName =
IsVCMP ?
"vcmpsd" :
"cmpsd";
3435 PatchedName =
IsVCMP ?
"vcmpps" :
"cmpps";
3437 PatchedName =
IsVCMP ?
"vcmppd" :
"cmppd";
3439 PatchedName =
"vcmpsh";
3441 PatchedName =
"vcmpph";
3443 PatchedName =
"vcmpbf16";
3447 ComparisonPredicate = CC;
3453 (PatchedName.
back() ==
'b' || PatchedName.
back() ==
'w' ||
3454 PatchedName.
back() ==
'd' || PatchedName.
back() ==
'q')) {
3455 unsigned SuffixSize = PatchedName.
drop_back().
back() ==
'u' ? 2 : 1;
3456 unsigned CC = StringSwitch<unsigned>(
3457 PatchedName.
slice(5, PatchedName.
size() - SuffixSize))
3467 if (CC != ~0U && (CC != 0 || SuffixSize == 2)) {
3468 switch (PatchedName.
back()) {
3470 case 'b': PatchedName = SuffixSize == 2 ?
"vpcmpub" :
"vpcmpb";
break;
3471 case 'w': PatchedName = SuffixSize == 2 ?
"vpcmpuw" :
"vpcmpw";
break;
3472 case 'd': PatchedName = SuffixSize == 2 ?
"vpcmpud" :
"vpcmpd";
break;
3473 case 'q': PatchedName = SuffixSize == 2 ?
"vpcmpuq" :
"vpcmpq";
break;
3476 ComparisonPredicate = CC;
3482 (PatchedName.
back() ==
'b' || PatchedName.
back() ==
'w' ||
3483 PatchedName.
back() ==
'd' || PatchedName.
back() ==
'q')) {
3484 unsigned SuffixSize = PatchedName.
drop_back().
back() ==
'u' ? 2 : 1;
3485 unsigned CC = StringSwitch<unsigned>(
3486 PatchedName.
slice(5, PatchedName.
size() - SuffixSize))
3497 switch (PatchedName.
back()) {
3499 case 'b': PatchedName = SuffixSize == 2 ?
"vpcomub" :
"vpcomb";
break;
3500 case 'w': PatchedName = SuffixSize == 2 ?
"vpcomuw" :
"vpcomw";
break;
3501 case 'd': PatchedName = SuffixSize == 2 ?
"vpcomud" :
"vpcomd";
break;
3502 case 'q': PatchedName = SuffixSize == 2 ?
"vpcomuq" :
"vpcomq";
break;
3505 ComparisonPredicate = CC;
3517 StringSwitch<bool>(Name)
3518 .Cases(
"cs",
"ds",
"es",
"fs",
"gs",
"ss",
true)
3519 .Cases(
"rex64",
"data32",
"data16",
"addr32",
"addr16",
true)
3520 .Cases(
"xacquire",
"xrelease",
true)
3521 .Cases(
"acquire",
"release", isParsingIntelSyntax())
3524 auto isLockRepeatNtPrefix = [](StringRef
N) {
3525 return StringSwitch<bool>(
N)
3526 .Cases(
"lock",
"rep",
"repe",
"repz",
"repne",
"repnz",
"notrack",
true)
3530 bool CurlyAsEndOfStatement =
false;
3533 while (isLockRepeatNtPrefix(
Name.lower())) {
3535 StringSwitch<unsigned>(Name)
3554 while (
Name.starts_with(
";") ||
Name.starts_with(
"\n") ||
3555 Name.starts_with(
"#") ||
Name.starts_with(
"\t") ||
3556 Name.starts_with(
"/")) {
3567 if (PatchedName ==
"data16" && is16BitMode()) {
3568 return Error(NameLoc,
"redundant data16 prefix");
3570 if (PatchedName ==
"data32") {
3572 return Error(NameLoc,
"redundant data32 prefix");
3574 return Error(NameLoc,
"'data32' is not supported in 64-bit mode");
3576 PatchedName =
"data16";
3583 if (
Next ==
"callw")
3585 if (
Next ==
"ljmpw")
3590 ForcedDataPrefix = X86::Is32Bit;
3598 if (ComparisonPredicate != ~0U && !isParsingIntelSyntax()) {
3605 if ((
Name.starts_with(
"ccmp") ||
Name.starts_with(
"ctest")) &&
3634 CurlyAsEndOfStatement =
3635 isParsingIntelSyntax() && isParsingMSInlineAsm() &&
3638 return TokError(
"unexpected token in argument list");
3642 if (ComparisonPredicate != ~0U && isParsingIntelSyntax()) {
3652 else if (CurlyAsEndOfStatement)
3655 getLexer().getTok().getLoc(), 0);
3662 if (IsFp &&
Operands.size() == 1) {
3663 const char *Repl = StringSwitch<const char *>(Name)
3664 .Case(
"fsub",
"fsubp")
3665 .Case(
"fdiv",
"fdivp")
3666 .Case(
"fsubr",
"fsubrp")
3667 .Case(
"fdivr",
"fdivrp");
3668 static_cast<X86Operand &
>(*
Operands[0]).setTokenValue(Repl);
3671 if ((Name ==
"mov" || Name ==
"movw" || Name ==
"movl") &&
3673 X86Operand &Op1 = (X86Operand &)*
Operands[1];
3674 X86Operand &Op2 = (X86Operand &)*
Operands[2];
3679 X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(
3681 (X86MCRegisterClasses[X86::GR16RegClassID].contains(Op1.
getReg()) ||
3682 X86MCRegisterClasses[X86::GR32RegClassID].contains(Op1.
getReg()))) {
3684 if (Name !=
"mov" && Name[3] == (is16BitMode() ?
'l' :
'w')) {
3685 Name = is16BitMode() ?
"movw" :
"movl";
3698 if ((Name ==
"outb" || Name ==
"outsb" || Name ==
"outw" || Name ==
"outsw" ||
3699 Name ==
"outl" || Name ==
"outsl" || Name ==
"out" || Name ==
"outs") &&
3701 X86Operand &
Op = (X86Operand &)*
Operands.back();
3707 if ((Name ==
"inb" || Name ==
"insb" || Name ==
"inw" || Name ==
"insw" ||
3708 Name ==
"inl" || Name ==
"insl" || Name ==
"in" || Name ==
"ins") &&
3717 bool HadVerifyError =
false;
3720 if (
Name.starts_with(
"ins") &&
3722 (Name ==
"insb" || Name ==
"insw" || Name ==
"insl" || Name ==
"insd" ||
3725 AddDefaultSrcDestOperands(TmpOperands,
3727 DefaultMemDIOperand(NameLoc));
3728 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3732 if (
Name.starts_with(
"outs") &&
3734 (Name ==
"outsb" || Name ==
"outsw" || Name ==
"outsl" ||
3735 Name ==
"outsd" || Name ==
"outs")) {
3736 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
3738 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3744 if (
Name.starts_with(
"lods") &&
3746 (Name ==
"lods" || Name ==
"lodsb" || Name ==
"lodsw" ||
3747 Name ==
"lodsl" || Name ==
"lodsd" || Name ==
"lodsq")) {
3748 TmpOperands.
push_back(DefaultMemSIOperand(NameLoc));
3749 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3755 if (
Name.starts_with(
"stos") &&
3757 (Name ==
"stos" || Name ==
"stosb" || Name ==
"stosw" ||
3758 Name ==
"stosl" || Name ==
"stosd" || Name ==
"stosq")) {
3759 TmpOperands.
push_back(DefaultMemDIOperand(NameLoc));
3760 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3766 if (
Name.starts_with(
"scas") &&
3768 (Name ==
"scas" || Name ==
"scasb" || Name ==
"scasw" ||
3769 Name ==
"scasl" || Name ==
"scasd" || Name ==
"scasq")) {
3770 TmpOperands.
push_back(DefaultMemDIOperand(NameLoc));
3771 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3775 if (
Name.starts_with(
"cmps") &&
3777 (Name ==
"cmps" || Name ==
"cmpsb" || Name ==
"cmpsw" ||
3778 Name ==
"cmpsl" || Name ==
"cmpsd" || Name ==
"cmpsq")) {
3779 AddDefaultSrcDestOperands(TmpOperands, DefaultMemDIOperand(NameLoc),
3780 DefaultMemSIOperand(NameLoc));
3781 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3785 if (((
Name.starts_with(
"movs") &&
3786 (Name ==
"movs" || Name ==
"movsb" || Name ==
"movsw" ||
3787 Name ==
"movsl" || Name ==
"movsd" || Name ==
"movsq")) ||
3788 (
Name.starts_with(
"smov") &&
3789 (Name ==
"smov" || Name ==
"smovb" || Name ==
"smovw" ||
3790 Name ==
"smovl" || Name ==
"smovd" || Name ==
"smovq"))) &&
3792 if (Name ==
"movsd" &&
Operands.size() == 1 && !isParsingIntelSyntax())
3794 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
3795 DefaultMemDIOperand(NameLoc));
3796 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3800 if (HadVerifyError) {
3801 return HadVerifyError;
3805 if ((Name ==
"xlat" || Name ==
"xlatb") &&
Operands.size() == 2) {
3806 X86Operand &Op1 =
static_cast<X86Operand &
>(*
Operands[1]);
3809 "size, (R|E)BX will be used for the location");
3811 static_cast<X86Operand &
>(*
Operands[0]).setTokenValue(
"xlatb");
3824 if (
I == Table.
end() ||
I->OldOpc != Opcode)
3830 if (X86::isBLENDVPD(Opcode) || X86::isBLENDVPS(Opcode) ||
3831 X86::isPBLENDVB(Opcode))
3837bool X86AsmParser::processInstruction(MCInst &Inst,
const OperandVector &
Ops) {
3841 if (ForcedOpcodePrefix != OpcodePrefix_VEX3 &&
3848 auto replaceWithCCMPCTEST = [&](
unsigned Opcode) ->
bool {
3849 if (ForcedOpcodePrefix == OpcodePrefix_EVEX) {
3860 default:
return false;
3865 if (ForcedDispEncoding == DispEncoding_Disp32) {
3866 Inst.
setOpcode(is16BitMode() ? X86::JMP_2 : X86::JMP_4);
3875 if (ForcedDispEncoding == DispEncoding_Disp32) {
3876 Inst.
setOpcode(is16BitMode() ? X86::JCC_2 : X86::JCC_4);
3892#define FROM_TO(FROM, TO) \
3894 return replaceWithCCMPCTEST(X86::TO);
3896 FROM_TO(CMP64mi32, CCMP64mi32)
3899 FROM_TO(CMP64ri32, CCMP64ri32)
3926 FROM_TO(TEST64mi32, CTEST64mi32)
3928 FROM_TO(TEST64ri32, CTEST64ri32)
3948bool X86AsmParser::validateInstruction(MCInst &Inst,
const OperandVector &
Ops) {
3949 using namespace X86;
3952 uint64_t TSFlags = MII.get(Opcode).TSFlags;
3953 if (isVFCMADDCPH(Opcode) || isVFCMADDCSH(Opcode) || isVFMADDCPH(Opcode) ||
3954 isVFMADDCSH(Opcode)) {
3958 return Warning(
Ops[0]->getStartLoc(),
"Destination register should be "
3959 "distinct from source registers");
3960 }
else if (isVFCMULCPH(Opcode) || isVFCMULCSH(Opcode) || isVFMULCPH(Opcode) ||
3961 isVFMULCSH(Opcode)) {
3971 return Warning(
Ops[0]->getStartLoc(),
"Destination register should be "
3972 "distinct from source registers");
3973 }
else if (isV4FMADDPS(Opcode) || isV4FMADDSS(Opcode) ||
3974 isV4FNMADDPS(Opcode) || isV4FNMADDSS(Opcode) ||
3975 isVP4DPWSSDS(Opcode) || isVP4DPWSSD(Opcode)) {
3979 unsigned Src2Enc =
MRI->getEncodingValue(Src2);
3980 if (Src2Enc % 4 != 0) {
3982 unsigned GroupStart = (Src2Enc / 4) * 4;
3983 unsigned GroupEnd = GroupStart + 3;
3985 "source register '" +
RegName +
"' implicitly denotes '" +
3986 RegName.take_front(3) + Twine(GroupStart) +
"' to '" +
3987 RegName.take_front(3) + Twine(GroupEnd) +
3990 }
else if (isVGATHERDPD(Opcode) || isVGATHERDPS(Opcode) ||
3991 isVGATHERQPD(Opcode) || isVGATHERQPS(Opcode) ||
3992 isVPGATHERDD(Opcode) || isVPGATHERDQ(Opcode) ||
3993 isVPGATHERQD(Opcode) || isVPGATHERQQ(Opcode)) {
3997 unsigned Index =
MRI->getEncodingValue(
4000 return Warning(
Ops[0]->getStartLoc(),
"index and destination registers "
4001 "should be distinct");
4005 unsigned Index =
MRI->getEncodingValue(
4007 if (Dest == Mask || Dest == Index || Mask == Index)
4008 return Warning(
Ops[0]->getStartLoc(),
"mask, index, and destination "
4009 "registers should be distinct");
4011 }
else if (isTCMMIMFP16PS(Opcode) || isTCMMRLFP16PS(Opcode) ||
4012 isTDPBF16PS(Opcode) || isTDPFP16PS(Opcode) || isTDPBSSD(Opcode) ||
4013 isTDPBSUD(Opcode) || isTDPBUSD(Opcode) || isTDPBUUD(Opcode)) {
4017 if (SrcDest == Src1 || SrcDest == Src2 || Src1 == Src2)
4018 return Error(
Ops[0]->getStartLoc(),
"all tmm registers must be distinct");
4027 for (
unsigned i = 0; i !=
NumOps; ++i) {
4032 if (
Reg == X86::AH ||
Reg == X86::BH ||
Reg == X86::CH ||
Reg == X86::DH)
4039 if (UsesRex && HReg) {
4041 return Error(
Ops[0]->getStartLoc(),
4042 "can't encode '" +
RegName +
"' in an instruction requiring "
4047 if ((Opcode == X86::PREFETCHIT0 || Opcode == X86::PREFETCHIT1)) {
4051 Ops[0]->getStartLoc(),
4052 Twine((Inst.
getOpcode() == X86::PREFETCHIT0 ?
"'prefetchit0'"
4053 :
"'prefetchit1'")) +
4054 " only supports RIP-relative address");
4059void X86AsmParser::emitWarningForSpecialLVIInstruction(SMLoc Loc) {
4060 Warning(Loc,
"Instruction may be vulnerable to LVI and "
4061 "requires manual mitigation");
4062 Note(SMLoc(),
"See https://software.intel.com/"
4063 "security-software-guidance/insights/"
4064 "deep-dive-load-value-injection#specialinstructions"
4065 " for more information");
4077void X86AsmParser::applyLVICFIMitigation(MCInst &Inst, MCStreamer &Out) {
4088 MCInst ShlInst, FenceInst;
4089 bool Parse32 = is32BitMode() || Code16GCC;
4090 MCRegister Basereg =
4091 is64BitMode() ? X86::RSP : (Parse32 ? X86::ESP : X86::SP);
4095 1, SMLoc{}, SMLoc{}, 0);
4097 ShlMemOp->addMemOperands(ShlInst, 5);
4110 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4122void X86AsmParser::applyLVILoadHardeningMitigation(MCInst &Inst,
4139 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4142 }
else if (Opcode == X86::REP_PREFIX || Opcode == X86::REPNE_PREFIX) {
4145 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4149 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
4167 getSTI().hasFeature(X86::FeatureLVIControlFlowIntegrity))
4168 applyLVICFIMitigation(Inst, Out);
4173 getSTI().hasFeature(X86::FeatureLVILoadHardening))
4174 applyLVILoadHardeningMitigation(Inst, Out);
4178 unsigned Result = 0;
4180 if (Prefix.isPrefix()) {
4181 Result = Prefix.getPrefix();
4187bool X86AsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
4189 MCStreamer &Out, uint64_t &ErrorInfo,
4190 bool MatchingInlineAsm) {
4192 assert((*
Operands[0]).isToken() &&
"Leading operand should always be a mnemonic!");
4195 MatchFPUWaitAlias(IDLoc,
static_cast<X86Operand &
>(*
Operands[0]),
Operands,
4196 Out, MatchingInlineAsm);
4203 if (ForcedOpcodePrefix == OpcodePrefix_REX)
4205 else if (ForcedOpcodePrefix == OpcodePrefix_REX2)
4207 else if (ForcedOpcodePrefix == OpcodePrefix_VEX)
4209 else if (ForcedOpcodePrefix == OpcodePrefix_VEX2)
4211 else if (ForcedOpcodePrefix == OpcodePrefix_VEX3)
4213 else if (ForcedOpcodePrefix == OpcodePrefix_EVEX)
4217 if (ForcedDispEncoding == DispEncoding_Disp8)
4219 else if (ForcedDispEncoding == DispEncoding_Disp32)
4225 return isParsingIntelSyntax()
4226 ? matchAndEmitIntelInstruction(IDLoc, Opcode, Inst,
Operands, Out,
4227 ErrorInfo, MatchingInlineAsm)
4228 : matchAndEmitATTInstruction(IDLoc, Opcode, Inst,
Operands, Out,
4229 ErrorInfo, MatchingInlineAsm);
4232void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &
Op,
4234 bool MatchingInlineAsm) {
4238 const char *Repl = StringSwitch<const char *>(
Op.getToken())
4239 .Case(
"finit",
"fninit")
4240 .Case(
"fsave",
"fnsave")
4241 .Case(
"fstcw",
"fnstcw")
4242 .Case(
"fstcww",
"fnstcw")
4243 .Case(
"fstenv",
"fnstenv")
4244 .Case(
"fstsw",
"fnstsw")
4245 .Case(
"fstsww",
"fnstsw")
4246 .Case(
"fclex",
"fnclex")
4252 if (!MatchingInlineAsm)
4258bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc,
4259 const FeatureBitset &MissingFeatures,
4260 bool MatchingInlineAsm) {
4261 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
4262 SmallString<126> Msg;
4263 raw_svector_ostream OS(Msg);
4264 OS <<
"instruction requires:";
4265 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
4266 if (MissingFeatures[i])
4269 return Error(IDLoc, OS.str(), SMRange(), MatchingInlineAsm);
4272unsigned X86AsmParser::checkTargetMatchPredicate(MCInst &Inst) {
4274 const MCInstrDesc &MCID = MII.get(
Opc);
4275 uint64_t TSFlags = MCID.
TSFlags;
4278 return Match_Unsupported;
4280 return Match_Unsupported;
4282 switch (ForcedOpcodePrefix) {
4283 case OpcodePrefix_Default:
4285 case OpcodePrefix_REX:
4286 case OpcodePrefix_REX2:
4288 return Match_Unsupported;
4290 case OpcodePrefix_VEX:
4291 case OpcodePrefix_VEX2:
4292 case OpcodePrefix_VEX3:
4294 return Match_Unsupported;
4296 case OpcodePrefix_EVEX:
4298 !X86::isCMP(
Opc) && !X86::isTEST(
Opc))
4299 return Match_Unsupported;
4301 return Match_Unsupported;
4306 (ForcedOpcodePrefix != OpcodePrefix_VEX &&
4307 ForcedOpcodePrefix != OpcodePrefix_VEX2 &&
4308 ForcedOpcodePrefix != OpcodePrefix_VEX3))
4309 return Match_Unsupported;
4311 return Match_Success;
4314bool X86AsmParser::matchAndEmitATTInstruction(
4316 MCStreamer &Out, uint64_t &ErrorInfo,
bool MatchingInlineAsm) {
4317 X86Operand &
Op =
static_cast<X86Operand &
>(*
Operands[0]);
4318 SMRange EmptyRange = std::nullopt;
4321 if (ForcedDataPrefix == X86::Is32Bit)
4322 SwitchMode(X86::Is32Bit);
4324 FeatureBitset MissingFeatures;
4325 unsigned OriginalError = MatchInstruction(
Operands, Inst, ErrorInfo,
4326 MissingFeatures, MatchingInlineAsm,
4327 isParsingIntelSyntax());
4328 if (ForcedDataPrefix == X86::Is32Bit) {
4329 SwitchMode(X86::Is16Bit);
4330 ForcedDataPrefix = 0;
4332 switch (OriginalError) {
4335 if (!MatchingInlineAsm && validateInstruction(Inst,
Operands))
4340 if (!MatchingInlineAsm)
4341 while (processInstruction(Inst,
Operands))
4345 if (!MatchingInlineAsm)
4349 case Match_InvalidImmUnsignedi4: {
4350 SMLoc ErrorLoc = ((X86Operand &)*
Operands[ErrorInfo]).getStartLoc();
4351 if (ErrorLoc == SMLoc())
4353 return Error(ErrorLoc,
"immediate must be an integer in range [0, 15]",
4354 EmptyRange, MatchingInlineAsm);
4356 case Match_MissingFeature:
4357 return ErrorMissingFeature(IDLoc, MissingFeatures, MatchingInlineAsm);
4358 case Match_InvalidOperand:
4359 case Match_MnemonicFail:
4360 case Match_Unsupported:
4363 if (
Op.getToken().empty()) {
4364 Error(IDLoc,
"instruction must have size higher than 0", EmptyRange,
4375 StringRef
Base =
Op.getToken();
4376 SmallString<16> Tmp;
4379 Op.setTokenValue(Tmp);
4387 const char *Suffixes =
Base[0] !=
'f' ?
"bwlq" :
"slt\0";
4389 const char *MemSize =
Base[0] !=
'f' ?
"\x08\x10\x20\x40" :
"\x20\x40\x50\0";
4392 uint64_t ErrorInfoIgnore;
4393 FeatureBitset ErrorInfoMissingFeatures;
4401 bool HasVectorReg =
false;
4402 X86Operand *MemOp =
nullptr;
4404 X86Operand *X86Op =
static_cast<X86Operand *
>(
Op.get());
4406 HasVectorReg =
true;
4407 else if (X86Op->
isMem()) {
4409 assert(MemOp->Mem.Size == 0 &&
"Memory size always 0 under ATT syntax");
4416 for (
unsigned I = 0,
E = std::size(Match);
I !=
E; ++
I) {
4417 Tmp.
back() = Suffixes[
I];
4418 if (MemOp && HasVectorReg)
4419 MemOp->Mem.Size = MemSize[
I];
4420 Match[
I] = Match_MnemonicFail;
4421 if (MemOp || !HasVectorReg) {
4423 MatchInstruction(
Operands, Inst, ErrorInfoIgnore, MissingFeatures,
4424 MatchingInlineAsm, isParsingIntelSyntax());
4426 if (Match[
I] == Match_MissingFeature)
4427 ErrorInfoMissingFeatures = MissingFeatures;
4437 unsigned NumSuccessfulMatches =
llvm::count(Match, Match_Success);
4438 if (NumSuccessfulMatches == 1) {
4439 if (!MatchingInlineAsm && validateInstruction(Inst,
Operands))
4444 if (!MatchingInlineAsm)
4445 while (processInstruction(Inst,
Operands))
4449 if (!MatchingInlineAsm)
4459 if (NumSuccessfulMatches > 1) {
4461 unsigned NumMatches = 0;
4462 for (
unsigned I = 0,
E = std::size(Match);
I !=
E; ++
I)
4463 if (Match[
I] == Match_Success)
4464 MatchChars[NumMatches++] = Suffixes[
I];
4466 SmallString<126> Msg;
4467 raw_svector_ostream OS(Msg);
4468 OS <<
"ambiguous instructions require an explicit suffix (could be ";
4469 for (
unsigned i = 0; i != NumMatches; ++i) {
4472 if (i + 1 == NumMatches)
4474 OS <<
"'" <<
Base << MatchChars[i] <<
"'";
4477 Error(IDLoc, OS.str(), EmptyRange, MatchingInlineAsm);
4485 if (
llvm::count(Match, Match_MnemonicFail) == 4) {
4486 if (OriginalError == Match_MnemonicFail)
4487 return Error(IDLoc,
"invalid instruction mnemonic '" +
Base +
"'",
4488 Op.getLocRange(), MatchingInlineAsm);
4490 if (OriginalError == Match_Unsupported)
4491 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4494 assert(OriginalError == Match_InvalidOperand &&
"Unexpected error");
4496 if (ErrorInfo != ~0ULL) {
4498 return Error(IDLoc,
"too few operands for instruction", EmptyRange,
4501 X86Operand &Operand = (X86Operand &)*
Operands[ErrorInfo];
4505 OperandRange, MatchingInlineAsm);
4509 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4515 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4521 if (
llvm::count(Match, Match_MissingFeature) == 1) {
4522 ErrorInfo = Match_MissingFeature;
4523 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
4529 if (
llvm::count(Match, Match_InvalidOperand) == 1) {
4530 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4535 Error(IDLoc,
"unknown use of instruction mnemonic without a size suffix",
4536 EmptyRange, MatchingInlineAsm);
4540bool X86AsmParser::matchAndEmitIntelInstruction(
4542 MCStreamer &Out, uint64_t &ErrorInfo,
bool MatchingInlineAsm) {
4543 X86Operand &
Op =
static_cast<X86Operand &
>(*
Operands[0]);
4544 SMRange EmptyRange = std::nullopt;
4546 X86Operand *UnsizedMemOp =
nullptr;
4548 X86Operand *X86Op =
static_cast<X86Operand *
>(
Op.get());
4550 UnsizedMemOp = X86Op;
4561 static const char *
const PtrSizedInstrs[] = {
"call",
"jmp",
"push",
"pop"};
4562 for (
const char *Instr : PtrSizedInstrs) {
4563 if (Mnemonic == Instr) {
4564 UnsizedMemOp->
Mem.
Size = getPointerWidth();
4570 SmallVector<unsigned, 8> Match;
4571 FeatureBitset ErrorInfoMissingFeatures;
4572 FeatureBitset MissingFeatures;
4577 if (Mnemonic ==
"push" &&
Operands.size() == 2) {
4578 auto *X86Op =
static_cast<X86Operand *
>(
Operands[1].get());
4579 if (X86Op->
isImm()) {
4582 unsigned Size = getPointerWidth();
4585 SmallString<16> Tmp;
4587 Tmp += (is64BitMode())
4589 : (is32BitMode()) ?
"l" : (is16BitMode()) ?
"w" :
" ";
4590 Op.setTokenValue(Tmp);
4593 MissingFeatures, MatchingInlineAsm,
4604 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
4605 for (
unsigned Size : MopSizes) {
4607 uint64_t ErrorInfoIgnore;
4609 unsigned M = MatchInstruction(
Operands, Inst, ErrorInfoIgnore,
4610 MissingFeatures, MatchingInlineAsm,
4611 isParsingIntelSyntax());
4616 if (Match.
back() == Match_MissingFeature)
4617 ErrorInfoMissingFeatures = MissingFeatures;
4627 if (Match.
empty()) {
4629 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,
4630 isParsingIntelSyntax()));
4632 if (Match.
back() == Match_MissingFeature)
4633 ErrorInfoMissingFeatures = MissingFeatures;
4641 if (Match.
back() == Match_MnemonicFail) {
4642 return Error(IDLoc,
"invalid instruction mnemonic '" + Mnemonic +
"'",
4643 Op.getLocRange(), MatchingInlineAsm);
4646 unsigned NumSuccessfulMatches =
llvm::count(Match, Match_Success);
4650 if (UnsizedMemOp && NumSuccessfulMatches > 1 &&
4653 unsigned M = MatchInstruction(
4654 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,
4655 isParsingIntelSyntax());
4656 if (M == Match_Success)
4657 NumSuccessfulMatches = 1;
4669 if (NumSuccessfulMatches == 1) {
4670 if (!MatchingInlineAsm && validateInstruction(Inst,
Operands))
4675 if (!MatchingInlineAsm)
4676 while (processInstruction(Inst,
Operands))
4679 if (!MatchingInlineAsm)
4683 }
else if (NumSuccessfulMatches > 1) {
4685 "multiple matches only possible with unsized memory operands");
4687 "ambiguous operand size for instruction '" + Mnemonic +
"\'",
4693 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4699 if (
llvm::count(Match, Match_MissingFeature) == 1) {
4700 ErrorInfo = Match_MissingFeature;
4701 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
4707 if (
llvm::count(Match, Match_InvalidOperand) == 1) {
4708 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4712 if (
llvm::count(Match, Match_InvalidImmUnsignedi4) == 1) {
4713 SMLoc ErrorLoc = ((X86Operand &)*
Operands[ErrorInfo]).getStartLoc();
4714 if (ErrorLoc == SMLoc())
4716 return Error(ErrorLoc,
"immediate must be an integer in range [0, 15]",
4717 EmptyRange, MatchingInlineAsm);
4721 return Error(IDLoc,
"unknown instruction mnemonic", EmptyRange,
4725bool X86AsmParser::omitRegisterFromClobberLists(MCRegister
Reg) {
4726 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(
Reg);
4729bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
4730 MCAsmParser &Parser = getParser();
4733 return parseDirectiveArch();
4735 return ParseDirectiveCode(IDVal, DirectiveID.
getLoc());
4741 return Error(DirectiveID.
getLoc(),
"'.att_syntax noprefix' is not "
4742 "supported: registers must have a "
4743 "'%' prefix in .att_syntax");
4745 getParser().setAssemblerDialect(0);
4748 getParser().setAssemblerDialect(1);
4753 return Error(DirectiveID.
getLoc(),
"'.intel_syntax prefix' is not "
4754 "supported: registers must not have "
4755 "a '%' prefix in .intel_syntax");
4758 }
else if (IDVal ==
".nops")
4759 return parseDirectiveNops(DirectiveID.
getLoc());
4760 else if (IDVal ==
".even")
4761 return parseDirectiveEven(DirectiveID.
getLoc());
4762 else if (IDVal ==
".cv_fpo_proc")
4763 return parseDirectiveFPOProc(DirectiveID.
getLoc());
4764 else if (IDVal ==
".cv_fpo_setframe")
4765 return parseDirectiveFPOSetFrame(DirectiveID.
getLoc());
4766 else if (IDVal ==
".cv_fpo_pushreg")
4767 return parseDirectiveFPOPushReg(DirectiveID.
getLoc());
4768 else if (IDVal ==
".cv_fpo_stackalloc")
4769 return parseDirectiveFPOStackAlloc(DirectiveID.
getLoc());
4770 else if (IDVal ==
".cv_fpo_stackalign")
4771 return parseDirectiveFPOStackAlign(DirectiveID.
getLoc());
4772 else if (IDVal ==
".cv_fpo_endprologue")
4773 return parseDirectiveFPOEndPrologue(DirectiveID.
getLoc());
4774 else if (IDVal ==
".cv_fpo_endproc")
4775 return parseDirectiveFPOEndProc(DirectiveID.
getLoc());
4776 else if (IDVal ==
".seh_pushreg" ||
4778 return parseDirectiveSEHPushReg(DirectiveID.
getLoc());
4779 else if (IDVal ==
".seh_setframe" ||
4781 return parseDirectiveSEHSetFrame(DirectiveID.
getLoc());
4782 else if (IDVal ==
".seh_savereg" ||
4784 return parseDirectiveSEHSaveReg(DirectiveID.
getLoc());
4785 else if (IDVal ==
".seh_savexmm" ||
4787 return parseDirectiveSEHSaveXMM(DirectiveID.
getLoc());
4788 else if (IDVal ==
".seh_pushframe" ||
4790 return parseDirectiveSEHPushFrame(DirectiveID.
getLoc());
4795bool X86AsmParser::parseDirectiveArch() {
4797 getParser().parseStringToEndOfStatement();
4803bool X86AsmParser::parseDirectiveNops(SMLoc L) {
4804 int64_t NumBytes = 0, Control = 0;
4805 SMLoc NumBytesLoc, ControlLoc;
4806 const MCSubtargetInfo& STI = getSTI();
4807 NumBytesLoc = getTok().getLoc();
4808 if (getParser().checkForValidSection() ||
4809 getParser().parseAbsoluteExpression(NumBytes))
4813 ControlLoc = getTok().getLoc();
4814 if (getParser().parseAbsoluteExpression(Control))
4817 if (getParser().parseEOL())
4820 if (NumBytes <= 0) {
4821 Error(NumBytesLoc,
"'.nops' directive with non-positive size");
4826 Error(ControlLoc,
"'.nops' directive with negative NOP size");
4831 getParser().getStreamer().emitNops(NumBytes, Control, L, STI);
4838bool X86AsmParser::parseDirectiveEven(SMLoc L) {
4842 const MCSection *
Section = getStreamer().getCurrentSectionOnly();
4844 getStreamer().initSections(
false, getSTI());
4845 Section = getStreamer().getCurrentSectionOnly();
4847 if (
getContext().getAsmInfo()->useCodeAlign(*Section))
4848 getStreamer().emitCodeAlignment(
Align(2), &getSTI(), 0);
4850 getStreamer().emitValueToAlignment(
Align(2), 0, 1, 0);
4856bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
4857 MCAsmParser &Parser = getParser();
4859 if (IDVal ==
".code16") {
4861 if (!is16BitMode()) {
4862 SwitchMode(X86::Is16Bit);
4863 getTargetStreamer().emitCode16();
4865 }
else if (IDVal ==
".code16gcc") {
4869 if (!is16BitMode()) {
4870 SwitchMode(X86::Is16Bit);
4871 getTargetStreamer().emitCode16();
4873 }
else if (IDVal ==
".code32") {
4875 if (!is32BitMode()) {
4876 SwitchMode(X86::Is32Bit);
4877 getTargetStreamer().emitCode32();
4879 }
else if (IDVal ==
".code64") {
4881 if (!is64BitMode()) {
4882 SwitchMode(X86::Is64Bit);
4883 getTargetStreamer().emitCode64();
4886 Error(L,
"unknown directive " + IDVal);
4894bool X86AsmParser::parseDirectiveFPOProc(SMLoc L) {
4895 MCAsmParser &Parser = getParser();
4899 return Parser.
TokError(
"expected symbol name");
4900 if (Parser.
parseIntToken(ParamsSize,
"expected parameter byte count"))
4903 return Parser.
TokError(
"parameters size out of range");
4907 return getTargetStreamer().emitFPOProc(ProcSym, ParamsSize, L);
4911bool X86AsmParser::parseDirectiveFPOSetFrame(SMLoc L) {
4914 if (parseRegister(
Reg, DummyLoc, DummyLoc) || parseEOL())
4916 return getTargetStreamer().emitFPOSetFrame(
Reg, L);
4920bool X86AsmParser::parseDirectiveFPOPushReg(SMLoc L) {
4923 if (parseRegister(
Reg, DummyLoc, DummyLoc) || parseEOL())
4925 return getTargetStreamer().emitFPOPushReg(
Reg, L);
4929bool X86AsmParser::parseDirectiveFPOStackAlloc(SMLoc L) {
4930 MCAsmParser &Parser = getParser();
4934 return getTargetStreamer().emitFPOStackAlloc(
Offset, L);
4938bool X86AsmParser::parseDirectiveFPOStackAlign(SMLoc L) {
4939 MCAsmParser &Parser = getParser();
4943 return getTargetStreamer().emitFPOStackAlign(
Offset, L);
4947bool X86AsmParser::parseDirectiveFPOEndPrologue(SMLoc L) {
4948 MCAsmParser &Parser = getParser();
4951 return getTargetStreamer().emitFPOEndPrologue(L);
4955bool X86AsmParser::parseDirectiveFPOEndProc(SMLoc L) {
4956 MCAsmParser &Parser = getParser();
4959 return getTargetStreamer().emitFPOEndProc(L);
4962bool X86AsmParser::parseSEHRegisterNumber(
unsigned RegClassID,
4963 MCRegister &RegNo) {
4964 SMLoc startLoc = getLexer().getLoc();
4970 if (parseRegister(RegNo, startLoc, endLoc))
4973 if (!X86MCRegisterClasses[RegClassID].
contains(RegNo)) {
4974 return Error(startLoc,
4975 "register is not supported for use with this directive");
4981 if (getParser().parseAbsoluteExpression(EncodedReg))
4986 RegNo = MCRegister();
4987 for (
MCPhysReg Reg : X86MCRegisterClasses[RegClassID]) {
4988 if (
MRI->getEncodingValue(
Reg) == EncodedReg) {
4994 return Error(startLoc,
4995 "incorrect register number for use with this directive");
5002bool X86AsmParser::parseDirectiveSEHPushReg(SMLoc Loc) {
5004 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5008 return TokError(
"expected end of directive");
5011 getStreamer().emitWinCFIPushReg(
Reg, Loc);
5015bool X86AsmParser::parseDirectiveSEHSetFrame(SMLoc Loc) {
5018 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5021 return TokError(
"you must specify a stack pointer offset");
5024 if (getParser().parseAbsoluteExpression(Off))
5028 return TokError(
"expected end of directive");
5031 getStreamer().emitWinCFISetFrame(
Reg, Off, Loc);
5035bool X86AsmParser::parseDirectiveSEHSaveReg(SMLoc Loc) {
5038 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5041 return TokError(
"you must specify an offset on the stack");
5044 if (getParser().parseAbsoluteExpression(Off))
5048 return TokError(
"expected end of directive");
5051 getStreamer().emitWinCFISaveReg(
Reg, Off, Loc);
5055bool X86AsmParser::parseDirectiveSEHSaveXMM(SMLoc Loc) {
5058 if (parseSEHRegisterNumber(X86::VR128XRegClassID,
Reg))
5061 return TokError(
"you must specify an offset on the stack");
5064 if (getParser().parseAbsoluteExpression(Off))
5068 return TokError(
"expected end of directive");
5071 getStreamer().emitWinCFISaveXMM(
Reg, Off, Loc);
5075bool X86AsmParser::parseDirectiveSEHPushFrame(SMLoc Loc) {
5079 SMLoc startLoc = getLexer().getLoc();
5081 if (!getParser().parseIdentifier(CodeID)) {
5082 if (CodeID !=
"code")
5083 return Error(startLoc,
"expected @code");
5089 return TokError(
"expected end of directive");
5092 getStreamer().emitWinCFIPushFrame(Code, Loc);
5102#define GET_MATCHER_IMPLEMENTATION
5103#include "X86GenAsmMatcher.inc"
unsigned const MachineRegisterInfo * MRI
static MCRegister MatchRegisterName(StringRef Name)
static const char * getSubtargetFeatureName(uint64_t Val)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
Function Alias Analysis false
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Analysis containing CSE Info
amode Optimize addressing mode
static ModuleSymbolTable::Symbol getSym(DataRefImpl &Symb)
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
mir Rename Register Operands
static bool IsVCMP(unsigned Opcode)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
OptimizedStructLayoutField Field
static StringRef getName(Value *V)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallString class.
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
static SymbolRef::Type getType(const Symbol *Sym)
#define LLVM_C_ABI
LLVM_C_ABI is the export/visibility macro used to mark symbols declared in llvm-c as exported when bu...
static cl::opt< bool > LVIInlineAsmHardening("x86-experimental-lvi-inline-asm-hardening", cl::desc("Harden inline assembly code that may be vulnerable to Load Value" " Injection (LVI). This feature is experimental."), cl::Hidden)
static bool checkScale(unsigned Scale, StringRef &ErrMsg)
LLVM_C_ABI void LLVMInitializeX86AsmParser()
static bool convertSSEToAVX(MCInst &Inst)
static unsigned getPrefixes(OperandVector &Operands)
static bool CheckBaseRegAndIndexRegAndScale(MCRegister BaseReg, MCRegister IndexReg, unsigned Scale, bool Is64BitMode, StringRef &ErrMsg)
#define FROM_TO(FROM, TO)
uint16_t RegSizeInBits(const MCRegisterInfo &MRI, MCRegister RegNo)
static unsigned getSize(unsigned Kind)
uint64_t getZExtValue() const
Get zero extended value.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
void UnLex(AsmToken const &Token)
bool isNot(AsmToken::TokenKind K) const
Check if the current token has kind K.
LLVM_ABI SMLoc getLoc() const
int64_t getIntVal() const
bool isNot(TokenKind K) const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
bool is(TokenKind K) const
TokenKind getKind() const
LLVM_ABI SMLoc getEndLoc() const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
constexpr size_t size() const
bool parseIntToken(int64_t &V, const Twine &ErrMsg="expected integer")
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual bool isParsingMasm() const
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents.
bool parseOptionalToken(AsmToken::TokenKind T)
Attempt to parse and consume token, returning true on success.
virtual bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc, AsmTypeInfo *TypeInfo=nullptr)=0
Parse a primary expression.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
virtual bool lookUpType(StringRef Name, AsmTypeInfo &Info) const
bool TokError(const Twine &Msg, SMRange Range=std::nullopt)
Report an error at the current lexer location.
virtual bool parseAbsoluteExpression(int64_t &Res)=0
Parse an expression which must evaluate to an absolute value.
virtual bool lookUpField(StringRef Name, AsmFieldInfo &Info) const
bool parseTokenLoc(SMLoc &Loc)
bool Error(SMLoc L, const Twine &Msg, SMRange Range=std::nullopt)
Return an error at the location L, with the message Msg.
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
@ SymbolRef
References to labels and assigned expressions.
Instances of this class represent a single low-level machine instruction.
unsigned getNumOperands() const
unsigned getFlags() const
unsigned getOpcode() const
void setFlags(unsigned F)
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
const MCOperand & getOperand(unsigned i) const
bool mayLoad() const
Return true if this instruction could possibly read memory.
bool isCall() const
Return true if the instruction is a call.
bool isTerminator() const
Returns true if this instruction part of the terminator for a basic block.
static MCOperand createImm(int64_t Val)
MCRegister getReg() const
Returns the register number.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Wrapper class representing physical registers. Should be passed by value.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
const FeatureBitset & getFeatureBits() const
FeatureBitset ToggleFeature(uint64_t FB)
Toggle a feature and return the re-computed feature bits.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
bool isUndefined() const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
StringRef getName() const
getName - Get the symbol name.
bool isVariable() const
isVariable - Check if this is a variable symbol.
const MCExpr * getVariableValue() const
Get the expression of the variable symbol.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
static constexpr StatusTy Failure
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
constexpr unsigned id() const
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
constexpr bool isValid() const
void push_back(const T &Elt)
StringRef - Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
bool consume_back(StringRef Suffix)
Returns true if this StringRef has the given suffix and removes that suffix.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
LLVM_ABI std::string upper() const
Convert the given ASCII string to uppercase.
char back() const
back - Get the last character in the string.
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
constexpr size_t size() const
size - Get the string size.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
bool consume_front(StringRef Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
LLVM_ABI std::string lower() const
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
static constexpr size_t npos
StringRef drop_back(size_t N=1) const
Return a StringRef equal to 'this' but with the last N elements dropped.
bool equals_insensitive(StringRef RHS) const
Check for string equality, ignoring case.
static const char * getRegisterName(MCRegister Reg)
static const X86MCExpr * create(MCRegister Reg, MCContext &Ctx)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
std::variant< std::monostate, Loc::Single, Loc::Multi, Loc::MMI, Loc::EntryValue > Variant
Alias for the std::variant specialization base class of DbgVariable.
@ CE
Windows NT (Windows on ARM)
@ X86
Windows x64, Windows Itanium (IA-64)
bool isX86_64NonExtLowByteReg(MCRegister Reg)
@ EVEX
EVEX - Specifies that this instruction use EVEX form which provides syntax support up to 32 512-bit r...
@ VEX
VEX - encoding using 0xC4/0xC5.
@ ExplicitVEXPrefix
For instructions that use VEX encoding only when {vex}, {vex2} or {vex3} is present.
bool canUseApxExtendedReg(const MCInstrDesc &Desc)
bool isX86_64ExtendedReg(MCRegister Reg)
bool isApxExtendedReg(MCRegister Reg)
void emitInstruction(MCObjectStreamer &, const MCInst &Inst, const MCSubtargetInfo &STI)
bool optimizeShiftRotateWithImmediateOne(MCInst &MI)
bool optimizeInstFromVEX3ToVEX2(MCInst &MI, const MCInstrDesc &Desc)
NodeAddr< CodeNode * > Code
Context & getContext() const
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
MCRegister getX86SubSuperRegister(MCRegister Reg, unsigned Size, bool High=false)
Target & getTheX86_32Target()
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
FunctionAddr VTableAddr Next
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
Target & getTheX86_64Target()
StringRef toStringRef(bool B)
Construct a string ref from a boolean.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
bool isKind(IdKind kind) const
SmallVectorImpl< AsmRewrite > * AsmRewrites
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
X86Operand - Instances of this class represent a parsed X86 machine instruction.
SMLoc getStartLoc() const override
getStartLoc - Get the location of the first token of this operand.
bool isImm() const override
isImm - Is this an immediate operand?
static std::unique_ptr< X86Operand > CreateImm(const MCExpr *Val, SMLoc StartLoc, SMLoc EndLoc, StringRef SymName=StringRef(), void *OpDecl=nullptr, bool GlobalRef=true)
static std::unique_ptr< X86Operand > CreatePrefix(unsigned Prefixes, SMLoc StartLoc, SMLoc EndLoc)
static std::unique_ptr< X86Operand > CreateDXReg(SMLoc StartLoc, SMLoc EndLoc)
static std::unique_ptr< X86Operand > CreateReg(MCRegister Reg, SMLoc StartLoc, SMLoc EndLoc, bool AddressOf=false, SMLoc OffsetOfLoc=SMLoc(), StringRef SymName=StringRef(), void *OpDecl=nullptr)
SMRange getLocRange() const
getLocRange - Get the range between the first and last token of this operand.
SMLoc getEndLoc() const override
getEndLoc - Get the location of the last token of this operand.
bool isReg() const override
isReg - Is this a register operand?
bool isMem() const override
isMem - Is this a memory operand?
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, bool UseUpRegs=false, bool MaybeDirectBranchDest=true)
Create an absolute memory operand.
static std::unique_ptr< X86Operand > CreateToken(StringRef Str, SMLoc Loc)
bool isMemUnsized() const
const MCExpr * getImm() const
unsigned getMemFrontendSize() const
MCRegister getReg() const override