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, 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, SMLoc StartLoc) {
2911 MCAsmParser &Parser = getParser();
2916 (getLexer().getTok().getIdentifier() ==
"z")))
2921 return Error(getLexer().getLoc(),
"Expected } at this point");
2930 MCAsmParser &Parser = getParser();
2933 const SMLoc consumedToken = consumeToken();
2937 if (getLexer().getTok().getIntVal() != 1)
2938 return TokError(
"Expected 1to<NUM> at this point");
2939 StringRef
Prefix = getLexer().getTok().getString();
2942 return TokError(
"Expected 1to<NUM> at this point");
2945 StringRef BroadcastString = (
Prefix + getLexer().getTok().getIdentifier())
2948 return TokError(
"Expected 1to<NUM> at this point");
2949 const char *BroadcastPrimitive =
2950 StringSwitch<const char *>(BroadcastString)
2951 .Case(
"1to2",
"{1to2}")
2952 .Case(
"1to4",
"{1to4}")
2953 .Case(
"1to8",
"{1to8}")
2954 .Case(
"1to16",
"{1to16}")
2955 .Case(
"1to32",
"{1to32}")
2957 if (!BroadcastPrimitive)
2958 return TokError(
"Invalid memory broadcast primitive.");
2961 return TokError(
"Expected } at this point");
2972 std::unique_ptr<X86Operand>
Z;
2973 if (ParseZ(Z, consumedToken))
2979 SMLoc StartLoc =
Z ? consumeToken() : consumedToken;
2984 if (!parseRegister(RegNo, RegLoc, StartLoc) &&
2985 X86MCRegisterClasses[X86::VK1RegClassID].
contains(RegNo)) {
2986 if (RegNo == X86::K0)
2987 return Error(RegLoc,
"Register k0 can't be used as write mask");
2989 return Error(getLexer().getLoc(),
"Expected } at this point");
2995 return Error(getLexer().getLoc(),
2996 "Expected an op-mask register at this point");
3001 if (ParseZ(Z, consumeToken()) || !Z)
3002 return Error(getLexer().getLoc(),
3003 "Expected a {z} mark at this point");
3019bool X86AsmParser::ParseMemOperand(MCRegister SegReg,
const MCExpr *Disp,
3020 SMLoc StartLoc, SMLoc EndLoc,
3022 MCAsmParser &Parser = getParser();
3040 auto isAtMemOperand = [
this]() {
3045 auto TokCount = this->getLexer().peekTokens(Buf,
true);
3048 switch (Buf[0].getKind()) {
3055 if ((TokCount > 1) &&
3057 (Buf[0].getLoc().getPointer() + 1 == Buf[1].getLoc().getPointer()))
3058 Id = StringRef(Buf[0].getLoc().getPointer(),
3059 Buf[1].getIdentifier().
size() + 1);
3081 if (!isAtMemOperand()) {
3100 0, 0, 1, StartLoc, EndLoc));
3108 SMLoc BaseLoc = getLexer().getLoc();
3120 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ)
3121 return Error(BaseLoc,
"eiz and riz can only be used as index registers",
3122 SMRange(BaseLoc, EndLoc));
3140 if (!
E->evaluateAsAbsolute(ScaleVal, getStreamer().getAssemblerPtr()))
3141 return Error(Loc,
"expected absolute expression");
3143 Warning(Loc,
"scale factor without index register is ignored");
3148 if (BaseReg == X86::RIP)
3150 "%rip as base register can not have an index register");
3151 if (IndexReg == X86::RIP)
3152 return Error(Loc,
"%rip is not allowed as an index register");
3163 return Error(Loc,
"expected scale expression");
3164 Scale = (unsigned)ScaleVal;
3166 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg) &&
3168 return Error(Loc,
"scale factor in 16-bit address must be 1");
3170 return Error(Loc, ErrMsg);
3184 if (BaseReg == X86::DX && !IndexReg && Scale == 1 && !SegReg &&
3193 return Error(BaseLoc, ErrMsg);
3200 if (BaseReg || IndexReg) {
3202 auto Imm =
CE->getValue();
3203 bool Is64 = X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) ||
3204 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg);
3205 bool Is16 = X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg);
3208 return Error(BaseLoc,
"displacement " + Twine(Imm) +
3209 " is not within [-2147483648, 2147483647]");
3211 if (!
isUInt<32>(Imm < 0 ? -uint64_t(Imm) : uint64_t(Imm))) {
3212 Warning(BaseLoc,
"displacement " + Twine(Imm) +
3213 " shortened to 32-bit signed " +
3214 Twine(
static_cast<int32_t
>(Imm)));
3216 }
else if (!
isUInt<16>(Imm < 0 ? -uint64_t(Imm) : uint64_t(Imm))) {
3217 Warning(BaseLoc,
"displacement " + Twine(Imm) +
3218 " shortened to 16-bit signed " +
3219 Twine(
static_cast<int16_t
>(Imm)));
3224 if (SegReg || BaseReg || IndexReg)
3226 BaseReg, IndexReg, Scale, StartLoc,
3235bool X86AsmParser::parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
3236 MCAsmParser &Parser = getParser();
3243 if (parseRegister(RegNo, StartLoc, EndLoc))
3251bool X86AsmParser::parseInstruction(ParseInstructionInfo &
Info, StringRef Name,
3253 MCAsmParser &Parser = getParser();
3257 ForcedOpcodePrefix = OpcodePrefix_Default;
3258 ForcedDispEncoding = DispEncoding_Default;
3259 UseApxExtendedReg =
false;
3260 ForcedNoFlag =
false;
3273 if (Prefix ==
"rex")
3274 ForcedOpcodePrefix = OpcodePrefix_REX;
3275 else if (Prefix ==
"rex2")
3276 ForcedOpcodePrefix = OpcodePrefix_REX2;
3277 else if (Prefix ==
"vex")
3278 ForcedOpcodePrefix = OpcodePrefix_VEX;
3279 else if (Prefix ==
"vex2")
3280 ForcedOpcodePrefix = OpcodePrefix_VEX2;
3281 else if (Prefix ==
"vex3")
3282 ForcedOpcodePrefix = OpcodePrefix_VEX3;
3283 else if (Prefix ==
"evex")
3284 ForcedOpcodePrefix = OpcodePrefix_EVEX;
3285 else if (Prefix ==
"disp8")
3286 ForcedDispEncoding = DispEncoding_Disp8;
3287 else if (Prefix ==
"disp32")
3288 ForcedDispEncoding = DispEncoding_Disp32;
3289 else if (Prefix ==
"nf")
3290 ForcedNoFlag =
true;
3292 return Error(NameLoc,
"unknown prefix");
3308 if (isParsingMSInlineAsm()) {
3309 if (
Name.equals_insensitive(
"vex"))
3310 ForcedOpcodePrefix = OpcodePrefix_VEX;
3311 else if (
Name.equals_insensitive(
"vex2"))
3312 ForcedOpcodePrefix = OpcodePrefix_VEX2;
3313 else if (
Name.equals_insensitive(
"vex3"))
3314 ForcedOpcodePrefix = OpcodePrefix_VEX3;
3315 else if (
Name.equals_insensitive(
"evex"))
3316 ForcedOpcodePrefix = OpcodePrefix_EVEX;
3318 if (ForcedOpcodePrefix != OpcodePrefix_Default) {
3331 if (
Name.consume_back(
".d32")) {
3332 ForcedDispEncoding = DispEncoding_Disp32;
3333 }
else if (
Name.consume_back(
".d8")) {
3334 ForcedDispEncoding = DispEncoding_Disp8;
3337 StringRef PatchedName =
Name;
3340 if (isParsingIntelSyntax() &&
3341 (PatchedName ==
"jmp" || PatchedName ==
"jc" || PatchedName ==
"jnc" ||
3342 PatchedName ==
"jcxz" || PatchedName ==
"jecxz" ||
3347 : NextTok ==
"short") {
3356 NextTok.
size() + 1);
3362 PatchedName !=
"setzub" && PatchedName !=
"setzunb" &&
3363 PatchedName !=
"setb" && PatchedName !=
"setnb")
3364 PatchedName = PatchedName.
substr(0,
Name.size()-1);
3366 unsigned ComparisonPredicate = ~0
U;
3374 bool IsVCMP = PatchedName[0] ==
'v';
3375 unsigned CCIdx =
IsVCMP ? 4 : 3;
3376 unsigned suffixLength = PatchedName.
ends_with(
"bf16") ? 5 : 2;
3377 unsigned CC = StringSwitch<unsigned>(
3378 PatchedName.
slice(CCIdx, PatchedName.
size() - suffixLength))
3380 .Case(
"eq_oq", 0x00)
3382 .Case(
"lt_os", 0x01)
3384 .Case(
"le_os", 0x02)
3385 .Case(
"unord", 0x03)
3386 .Case(
"unord_q", 0x03)
3388 .Case(
"neq_uq", 0x04)
3390 .Case(
"nlt_us", 0x05)
3392 .Case(
"nle_us", 0x06)
3394 .Case(
"ord_q", 0x07)
3396 .Case(
"eq_uq", 0x08)
3398 .Case(
"nge_us", 0x09)
3400 .Case(
"ngt_us", 0x0A)
3401 .Case(
"false", 0x0B)
3402 .Case(
"false_oq", 0x0B)
3403 .Case(
"neq_oq", 0x0C)
3405 .Case(
"ge_os", 0x0D)
3407 .Case(
"gt_os", 0x0E)
3409 .Case(
"true_uq", 0x0F)
3410 .Case(
"eq_os", 0x10)
3411 .Case(
"lt_oq", 0x11)
3412 .Case(
"le_oq", 0x12)
3413 .Case(
"unord_s", 0x13)
3414 .Case(
"neq_us", 0x14)
3415 .Case(
"nlt_uq", 0x15)
3416 .Case(
"nle_uq", 0x16)
3417 .Case(
"ord_s", 0x17)
3418 .Case(
"eq_us", 0x18)
3419 .Case(
"nge_uq", 0x19)
3420 .Case(
"ngt_uq", 0x1A)
3421 .Case(
"false_os", 0x1B)
3422 .Case(
"neq_os", 0x1C)
3423 .Case(
"ge_oq", 0x1D)
3424 .Case(
"gt_oq", 0x1E)
3425 .Case(
"true_us", 0x1F)
3427 if (CC != ~0U && (
IsVCMP || CC < 8) &&
3430 PatchedName =
IsVCMP ?
"vcmpss" :
"cmpss";
3432 PatchedName =
IsVCMP ?
"vcmpsd" :
"cmpsd";
3434 PatchedName =
IsVCMP ?
"vcmpps" :
"cmpps";
3436 PatchedName =
IsVCMP ?
"vcmppd" :
"cmppd";
3438 PatchedName =
"vcmpsh";
3440 PatchedName =
"vcmpph";
3442 PatchedName =
"vcmpbf16";
3446 ComparisonPredicate = CC;
3452 (PatchedName.
back() ==
'b' || PatchedName.
back() ==
'w' ||
3453 PatchedName.
back() ==
'd' || PatchedName.
back() ==
'q')) {
3454 unsigned SuffixSize = PatchedName.
drop_back().
back() ==
'u' ? 2 : 1;
3455 unsigned CC = StringSwitch<unsigned>(
3456 PatchedName.
slice(5, PatchedName.
size() - SuffixSize))
3466 if (CC != ~0U && (CC != 0 || SuffixSize == 2)) {
3467 switch (PatchedName.
back()) {
3469 case 'b': PatchedName = SuffixSize == 2 ?
"vpcmpub" :
"vpcmpb";
break;
3470 case 'w': PatchedName = SuffixSize == 2 ?
"vpcmpuw" :
"vpcmpw";
break;
3471 case 'd': PatchedName = SuffixSize == 2 ?
"vpcmpud" :
"vpcmpd";
break;
3472 case 'q': PatchedName = SuffixSize == 2 ?
"vpcmpuq" :
"vpcmpq";
break;
3475 ComparisonPredicate = CC;
3481 (PatchedName.
back() ==
'b' || PatchedName.
back() ==
'w' ||
3482 PatchedName.
back() ==
'd' || PatchedName.
back() ==
'q')) {
3483 unsigned SuffixSize = PatchedName.
drop_back().
back() ==
'u' ? 2 : 1;
3484 unsigned CC = StringSwitch<unsigned>(
3485 PatchedName.
slice(5, PatchedName.
size() - SuffixSize))
3496 switch (PatchedName.
back()) {
3498 case 'b': PatchedName = SuffixSize == 2 ?
"vpcomub" :
"vpcomb";
break;
3499 case 'w': PatchedName = SuffixSize == 2 ?
"vpcomuw" :
"vpcomw";
break;
3500 case 'd': PatchedName = SuffixSize == 2 ?
"vpcomud" :
"vpcomd";
break;
3501 case 'q': PatchedName = SuffixSize == 2 ?
"vpcomuq" :
"vpcomq";
break;
3504 ComparisonPredicate = CC;
3516 StringSwitch<bool>(Name)
3517 .Cases(
"cs",
"ds",
"es",
"fs",
"gs",
"ss",
true)
3518 .Cases(
"rex64",
"data32",
"data16",
"addr32",
"addr16",
true)
3519 .Cases(
"xacquire",
"xrelease",
true)
3520 .Cases(
"acquire",
"release", isParsingIntelSyntax())
3523 auto isLockRepeatNtPrefix = [](StringRef
N) {
3524 return StringSwitch<bool>(
N)
3525 .Cases(
"lock",
"rep",
"repe",
"repz",
"repne",
"repnz",
"notrack",
true)
3529 bool CurlyAsEndOfStatement =
false;
3532 while (isLockRepeatNtPrefix(
Name.lower())) {
3534 StringSwitch<unsigned>(Name)
3553 while (
Name.starts_with(
";") ||
Name.starts_with(
"\n") ||
3554 Name.starts_with(
"#") ||
Name.starts_with(
"\t") ||
3555 Name.starts_with(
"/")) {
3566 if (PatchedName ==
"data16" && is16BitMode()) {
3567 return Error(NameLoc,
"redundant data16 prefix");
3569 if (PatchedName ==
"data32") {
3571 return Error(NameLoc,
"redundant data32 prefix");
3573 return Error(NameLoc,
"'data32' is not supported in 64-bit mode");
3575 PatchedName =
"data16";
3582 if (
Next ==
"callw")
3584 if (
Next ==
"ljmpw")
3589 ForcedDataPrefix = X86::Is32Bit;
3597 if (ComparisonPredicate != ~0U && !isParsingIntelSyntax()) {
3604 if ((
Name.starts_with(
"ccmp") ||
Name.starts_with(
"ctest")) &&
3633 CurlyAsEndOfStatement =
3634 isParsingIntelSyntax() && isParsingMSInlineAsm() &&
3637 return TokError(
"unexpected token in argument list");
3641 if (ComparisonPredicate != ~0U && isParsingIntelSyntax()) {
3651 else if (CurlyAsEndOfStatement)
3654 getLexer().getTok().getLoc(), 0);
3661 if (IsFp &&
Operands.size() == 1) {
3662 const char *Repl = StringSwitch<const char *>(Name)
3663 .Case(
"fsub",
"fsubp")
3664 .Case(
"fdiv",
"fdivp")
3665 .Case(
"fsubr",
"fsubrp")
3666 .Case(
"fdivr",
"fdivrp");
3667 static_cast<X86Operand &
>(*
Operands[0]).setTokenValue(Repl);
3670 if ((Name ==
"mov" || Name ==
"movw" || Name ==
"movl") &&
3672 X86Operand &Op1 = (X86Operand &)*
Operands[1];
3673 X86Operand &Op2 = (X86Operand &)*
Operands[2];
3678 X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(
3680 (X86MCRegisterClasses[X86::GR16RegClassID].contains(Op1.
getReg()) ||
3681 X86MCRegisterClasses[X86::GR32RegClassID].contains(Op1.
getReg()))) {
3683 if (Name !=
"mov" && Name[3] == (is16BitMode() ?
'l' :
'w')) {
3684 Name = is16BitMode() ?
"movw" :
"movl";
3697 if ((Name ==
"outb" || Name ==
"outsb" || Name ==
"outw" || Name ==
"outsw" ||
3698 Name ==
"outl" || Name ==
"outsl" || Name ==
"out" || Name ==
"outs") &&
3700 X86Operand &
Op = (X86Operand &)*
Operands.back();
3706 if ((Name ==
"inb" || Name ==
"insb" || Name ==
"inw" || Name ==
"insw" ||
3707 Name ==
"inl" || Name ==
"insl" || Name ==
"in" || Name ==
"ins") &&
3716 bool HadVerifyError =
false;
3719 if (
Name.starts_with(
"ins") &&
3721 (Name ==
"insb" || Name ==
"insw" || Name ==
"insl" || Name ==
"insd" ||
3724 AddDefaultSrcDestOperands(TmpOperands,
3726 DefaultMemDIOperand(NameLoc));
3727 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3731 if (
Name.starts_with(
"outs") &&
3733 (Name ==
"outsb" || Name ==
"outsw" || Name ==
"outsl" ||
3734 Name ==
"outsd" || Name ==
"outs")) {
3735 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
3737 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3743 if (
Name.starts_with(
"lods") &&
3745 (Name ==
"lods" || Name ==
"lodsb" || Name ==
"lodsw" ||
3746 Name ==
"lodsl" || Name ==
"lodsd" || Name ==
"lodsq")) {
3747 TmpOperands.
push_back(DefaultMemSIOperand(NameLoc));
3748 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3754 if (
Name.starts_with(
"stos") &&
3756 (Name ==
"stos" || Name ==
"stosb" || Name ==
"stosw" ||
3757 Name ==
"stosl" || Name ==
"stosd" || Name ==
"stosq")) {
3758 TmpOperands.
push_back(DefaultMemDIOperand(NameLoc));
3759 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3765 if (
Name.starts_with(
"scas") &&
3767 (Name ==
"scas" || Name ==
"scasb" || Name ==
"scasw" ||
3768 Name ==
"scasl" || Name ==
"scasd" || Name ==
"scasq")) {
3769 TmpOperands.
push_back(DefaultMemDIOperand(NameLoc));
3770 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3774 if (
Name.starts_with(
"cmps") &&
3776 (Name ==
"cmps" || Name ==
"cmpsb" || Name ==
"cmpsw" ||
3777 Name ==
"cmpsl" || Name ==
"cmpsd" || Name ==
"cmpsq")) {
3778 AddDefaultSrcDestOperands(TmpOperands, DefaultMemDIOperand(NameLoc),
3779 DefaultMemSIOperand(NameLoc));
3780 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3784 if (((
Name.starts_with(
"movs") &&
3785 (Name ==
"movs" || Name ==
"movsb" || Name ==
"movsw" ||
3786 Name ==
"movsl" || Name ==
"movsd" || Name ==
"movsq")) ||
3787 (
Name.starts_with(
"smov") &&
3788 (Name ==
"smov" || Name ==
"smovb" || Name ==
"smovw" ||
3789 Name ==
"smovl" || Name ==
"smovd" || Name ==
"smovq"))) &&
3791 if (Name ==
"movsd" &&
Operands.size() == 1 && !isParsingIntelSyntax())
3793 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
3794 DefaultMemDIOperand(NameLoc));
3795 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3799 if (HadVerifyError) {
3800 return HadVerifyError;
3804 if ((Name ==
"xlat" || Name ==
"xlatb") &&
Operands.size() == 2) {
3805 X86Operand &Op1 =
static_cast<X86Operand &
>(*
Operands[1]);
3808 "size, (R|E)BX will be used for the location");
3810 static_cast<X86Operand &
>(*
Operands[0]).setTokenValue(
"xlatb");
3823 if (
I == Table.
end() ||
I->OldOpc != Opcode)
3829 if (X86::isBLENDVPD(Opcode) || X86::isBLENDVPS(Opcode) ||
3830 X86::isPBLENDVB(Opcode))
3836bool X86AsmParser::processInstruction(MCInst &Inst,
const OperandVector &
Ops) {
3840 if (ForcedOpcodePrefix != OpcodePrefix_VEX3 &&
3847 auto replaceWithCCMPCTEST = [&](
unsigned Opcode) ->
bool {
3848 if (ForcedOpcodePrefix == OpcodePrefix_EVEX) {
3859 default:
return false;
3864 if (ForcedDispEncoding == DispEncoding_Disp32) {
3865 Inst.
setOpcode(is16BitMode() ? X86::JMP_2 : X86::JMP_4);
3874 if (ForcedDispEncoding == DispEncoding_Disp32) {
3875 Inst.
setOpcode(is16BitMode() ? X86::JCC_2 : X86::JCC_4);
3891#define FROM_TO(FROM, TO) \
3893 return replaceWithCCMPCTEST(X86::TO);
3895 FROM_TO(CMP64mi32, CCMP64mi32)
3898 FROM_TO(CMP64ri32, CCMP64ri32)
3925 FROM_TO(TEST64mi32, CTEST64mi32)
3927 FROM_TO(TEST64ri32, CTEST64ri32)
3947bool X86AsmParser::validateInstruction(MCInst &Inst,
const OperandVector &
Ops) {
3948 using namespace X86;
3951 uint64_t TSFlags = MII.get(Opcode).TSFlags;
3952 if (isVFCMADDCPH(Opcode) || isVFCMADDCSH(Opcode) || isVFMADDCPH(Opcode) ||
3953 isVFMADDCSH(Opcode)) {
3957 return Warning(
Ops[0]->getStartLoc(),
"Destination register should be "
3958 "distinct from source registers");
3959 }
else if (isVFCMULCPH(Opcode) || isVFCMULCSH(Opcode) || isVFMULCPH(Opcode) ||
3960 isVFMULCSH(Opcode)) {
3970 return Warning(
Ops[0]->getStartLoc(),
"Destination register should be "
3971 "distinct from source registers");
3972 }
else if (isV4FMADDPS(Opcode) || isV4FMADDSS(Opcode) ||
3973 isV4FNMADDPS(Opcode) || isV4FNMADDSS(Opcode) ||
3974 isVP4DPWSSDS(Opcode) || isVP4DPWSSD(Opcode)) {
3978 unsigned Src2Enc =
MRI->getEncodingValue(Src2);
3979 if (Src2Enc % 4 != 0) {
3981 unsigned GroupStart = (Src2Enc / 4) * 4;
3982 unsigned GroupEnd = GroupStart + 3;
3984 "source register '" +
RegName +
"' implicitly denotes '" +
3985 RegName.take_front(3) + Twine(GroupStart) +
"' to '" +
3986 RegName.take_front(3) + Twine(GroupEnd) +
3989 }
else if (isVGATHERDPD(Opcode) || isVGATHERDPS(Opcode) ||
3990 isVGATHERQPD(Opcode) || isVGATHERQPS(Opcode) ||
3991 isVPGATHERDD(Opcode) || isVPGATHERDQ(Opcode) ||
3992 isVPGATHERQD(Opcode) || isVPGATHERQQ(Opcode)) {
3996 unsigned Index =
MRI->getEncodingValue(
3999 return Warning(
Ops[0]->getStartLoc(),
"index and destination registers "
4000 "should be distinct");
4004 unsigned Index =
MRI->getEncodingValue(
4006 if (Dest == Mask || Dest == Index || Mask == Index)
4007 return Warning(
Ops[0]->getStartLoc(),
"mask, index, and destination "
4008 "registers should be distinct");
4010 }
else if (isTCMMIMFP16PS(Opcode) || isTCMMRLFP16PS(Opcode) ||
4011 isTDPBF16PS(Opcode) || isTDPFP16PS(Opcode) || isTDPBSSD(Opcode) ||
4012 isTDPBSUD(Opcode) || isTDPBUSD(Opcode) || isTDPBUUD(Opcode)) {
4016 if (SrcDest == Src1 || SrcDest == Src2 || Src1 == Src2)
4017 return Error(
Ops[0]->getStartLoc(),
"all tmm registers must be distinct");
4031 for (
unsigned i = 0; i !=
NumOps; ++i) {
4036 if (
Reg == X86::AH ||
Reg == X86::BH ||
Reg == X86::CH ||
Reg == X86::DH)
4044 (Enc ==
X86II::EVEX || ForcedOpcodePrefix == OpcodePrefix_REX2 ||
4045 ForcedOpcodePrefix == OpcodePrefix_REX || UsesRex)) {
4047 return Error(
Ops[0]->getStartLoc(),
4048 "can't encode '" +
RegName.str() +
4049 "' in an instruction requiring EVEX/REX2/REX prefix");
4053 if ((Opcode == X86::PREFETCHIT0 || Opcode == X86::PREFETCHIT1)) {
4057 Ops[0]->getStartLoc(),
4058 Twine((Inst.
getOpcode() == X86::PREFETCHIT0 ?
"'prefetchit0'"
4059 :
"'prefetchit1'")) +
4060 " only supports RIP-relative address");
4065void X86AsmParser::emitWarningForSpecialLVIInstruction(SMLoc Loc) {
4066 Warning(Loc,
"Instruction may be vulnerable to LVI and "
4067 "requires manual mitigation");
4068 Note(SMLoc(),
"See https://software.intel.com/"
4069 "security-software-guidance/insights/"
4070 "deep-dive-load-value-injection#specialinstructions"
4071 " for more information");
4083void X86AsmParser::applyLVICFIMitigation(MCInst &Inst, MCStreamer &Out) {
4094 MCInst ShlInst, FenceInst;
4095 bool Parse32 = is32BitMode() || Code16GCC;
4096 MCRegister Basereg =
4097 is64BitMode() ? X86::RSP : (Parse32 ? X86::ESP : X86::SP);
4101 1, SMLoc{}, SMLoc{}, 0);
4103 ShlMemOp->addMemOperands(ShlInst, 5);
4116 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4128void X86AsmParser::applyLVILoadHardeningMitigation(MCInst &Inst,
4145 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4148 }
else if (Opcode == X86::REP_PREFIX || Opcode == X86::REPNE_PREFIX) {
4151 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4155 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
4173 getSTI().hasFeature(X86::FeatureLVIControlFlowIntegrity))
4174 applyLVICFIMitigation(Inst, Out);
4179 getSTI().hasFeature(X86::FeatureLVILoadHardening))
4180 applyLVILoadHardeningMitigation(Inst, Out);
4184 unsigned Result = 0;
4186 if (Prefix.isPrefix()) {
4187 Result = Prefix.getPrefix();
4193bool X86AsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
4195 MCStreamer &Out, uint64_t &ErrorInfo,
4196 bool MatchingInlineAsm) {
4198 assert((*
Operands[0]).isToken() &&
"Leading operand should always be a mnemonic!");
4201 MatchFPUWaitAlias(IDLoc,
static_cast<X86Operand &
>(*
Operands[0]),
Operands,
4202 Out, MatchingInlineAsm);
4209 if (ForcedOpcodePrefix == OpcodePrefix_REX)
4211 else if (ForcedOpcodePrefix == OpcodePrefix_REX2)
4213 else if (ForcedOpcodePrefix == OpcodePrefix_VEX)
4215 else if (ForcedOpcodePrefix == OpcodePrefix_VEX2)
4217 else if (ForcedOpcodePrefix == OpcodePrefix_VEX3)
4219 else if (ForcedOpcodePrefix == OpcodePrefix_EVEX)
4223 if (ForcedDispEncoding == DispEncoding_Disp8)
4225 else if (ForcedDispEncoding == DispEncoding_Disp32)
4231 return isParsingIntelSyntax()
4232 ? matchAndEmitIntelInstruction(IDLoc, Opcode, Inst,
Operands, Out,
4233 ErrorInfo, MatchingInlineAsm)
4234 : matchAndEmitATTInstruction(IDLoc, Opcode, Inst,
Operands, Out,
4235 ErrorInfo, MatchingInlineAsm);
4238void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &
Op,
4240 bool MatchingInlineAsm) {
4244 const char *Repl = StringSwitch<const char *>(
Op.getToken())
4245 .Case(
"finit",
"fninit")
4246 .Case(
"fsave",
"fnsave")
4247 .Case(
"fstcw",
"fnstcw")
4248 .Case(
"fstcww",
"fnstcw")
4249 .Case(
"fstenv",
"fnstenv")
4250 .Case(
"fstsw",
"fnstsw")
4251 .Case(
"fstsww",
"fnstsw")
4252 .Case(
"fclex",
"fnclex")
4258 if (!MatchingInlineAsm)
4264bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc,
4265 const FeatureBitset &MissingFeatures,
4266 bool MatchingInlineAsm) {
4267 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
4268 SmallString<126> Msg;
4269 raw_svector_ostream OS(Msg);
4270 OS <<
"instruction requires:";
4271 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
4272 if (MissingFeatures[i])
4275 return Error(IDLoc, OS.str(), SMRange(), MatchingInlineAsm);
4278unsigned X86AsmParser::checkTargetMatchPredicate(MCInst &Inst) {
4280 const MCInstrDesc &MCID = MII.get(
Opc);
4281 uint64_t TSFlags = MCID.
TSFlags;
4284 return Match_Unsupported;
4286 return Match_Unsupported;
4288 switch (ForcedOpcodePrefix) {
4289 case OpcodePrefix_Default:
4291 case OpcodePrefix_REX:
4292 case OpcodePrefix_REX2:
4294 return Match_Unsupported;
4296 case OpcodePrefix_VEX:
4297 case OpcodePrefix_VEX2:
4298 case OpcodePrefix_VEX3:
4300 return Match_Unsupported;
4302 case OpcodePrefix_EVEX:
4304 !X86::isCMP(
Opc) && !X86::isTEST(
Opc))
4305 return Match_Unsupported;
4307 return Match_Unsupported;
4312 (ForcedOpcodePrefix != OpcodePrefix_VEX &&
4313 ForcedOpcodePrefix != OpcodePrefix_VEX2 &&
4314 ForcedOpcodePrefix != OpcodePrefix_VEX3))
4315 return Match_Unsupported;
4317 return Match_Success;
4320bool X86AsmParser::matchAndEmitATTInstruction(
4322 MCStreamer &Out, uint64_t &ErrorInfo,
bool MatchingInlineAsm) {
4323 X86Operand &
Op =
static_cast<X86Operand &
>(*
Operands[0]);
4324 SMRange EmptyRange = std::nullopt;
4327 if (ForcedDataPrefix == X86::Is32Bit)
4328 SwitchMode(X86::Is32Bit);
4330 FeatureBitset MissingFeatures;
4331 unsigned OriginalError = MatchInstruction(
Operands, Inst, ErrorInfo,
4332 MissingFeatures, MatchingInlineAsm,
4333 isParsingIntelSyntax());
4334 if (ForcedDataPrefix == X86::Is32Bit) {
4335 SwitchMode(X86::Is16Bit);
4336 ForcedDataPrefix = 0;
4338 switch (OriginalError) {
4341 if (!MatchingInlineAsm && validateInstruction(Inst,
Operands))
4346 if (!MatchingInlineAsm)
4347 while (processInstruction(Inst,
Operands))
4351 if (!MatchingInlineAsm)
4355 case Match_InvalidImmUnsignedi4: {
4356 SMLoc ErrorLoc = ((X86Operand &)*
Operands[ErrorInfo]).getStartLoc();
4357 if (ErrorLoc == SMLoc())
4359 return Error(ErrorLoc,
"immediate must be an integer in range [0, 15]",
4360 EmptyRange, MatchingInlineAsm);
4362 case Match_MissingFeature:
4363 return ErrorMissingFeature(IDLoc, MissingFeatures, MatchingInlineAsm);
4364 case Match_InvalidOperand:
4365 case Match_MnemonicFail:
4366 case Match_Unsupported:
4369 if (
Op.getToken().empty()) {
4370 Error(IDLoc,
"instruction must have size higher than 0", EmptyRange,
4381 StringRef
Base =
Op.getToken();
4382 SmallString<16> Tmp;
4385 Op.setTokenValue(Tmp);
4393 const char *Suffixes =
Base[0] !=
'f' ?
"bwlq" :
"slt\0";
4395 const char *MemSize =
Base[0] !=
'f' ?
"\x08\x10\x20\x40" :
"\x20\x40\x50\0";
4398 uint64_t ErrorInfoIgnore;
4399 FeatureBitset ErrorInfoMissingFeatures;
4407 bool HasVectorReg =
false;
4408 X86Operand *MemOp =
nullptr;
4410 X86Operand *X86Op =
static_cast<X86Operand *
>(
Op.get());
4412 HasVectorReg =
true;
4413 else if (X86Op->
isMem()) {
4415 assert(MemOp->Mem.Size == 0 &&
"Memory size always 0 under ATT syntax");
4422 for (
unsigned I = 0,
E = std::size(Match);
I !=
E; ++
I) {
4423 Tmp.
back() = Suffixes[
I];
4424 if (MemOp && HasVectorReg)
4425 MemOp->Mem.Size = MemSize[
I];
4426 Match[
I] = Match_MnemonicFail;
4427 if (MemOp || !HasVectorReg) {
4429 MatchInstruction(
Operands, Inst, ErrorInfoIgnore, MissingFeatures,
4430 MatchingInlineAsm, isParsingIntelSyntax());
4432 if (Match[
I] == Match_MissingFeature)
4433 ErrorInfoMissingFeatures = MissingFeatures;
4443 unsigned NumSuccessfulMatches =
llvm::count(Match, Match_Success);
4444 if (NumSuccessfulMatches == 1) {
4445 if (!MatchingInlineAsm && validateInstruction(Inst,
Operands))
4450 if (!MatchingInlineAsm)
4451 while (processInstruction(Inst,
Operands))
4455 if (!MatchingInlineAsm)
4465 if (NumSuccessfulMatches > 1) {
4467 unsigned NumMatches = 0;
4468 for (
unsigned I = 0,
E = std::size(Match);
I !=
E; ++
I)
4469 if (Match[
I] == Match_Success)
4470 MatchChars[NumMatches++] = Suffixes[
I];
4472 SmallString<126> Msg;
4473 raw_svector_ostream OS(Msg);
4474 OS <<
"ambiguous instructions require an explicit suffix (could be ";
4475 for (
unsigned i = 0; i != NumMatches; ++i) {
4478 if (i + 1 == NumMatches)
4480 OS <<
"'" <<
Base << MatchChars[i] <<
"'";
4483 Error(IDLoc, OS.str(), EmptyRange, MatchingInlineAsm);
4491 if (
llvm::count(Match, Match_MnemonicFail) == 4) {
4492 if (OriginalError == Match_MnemonicFail)
4493 return Error(IDLoc,
"invalid instruction mnemonic '" +
Base +
"'",
4494 Op.getLocRange(), MatchingInlineAsm);
4496 if (OriginalError == Match_Unsupported)
4497 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4500 assert(OriginalError == Match_InvalidOperand &&
"Unexpected error");
4502 if (ErrorInfo != ~0ULL) {
4504 return Error(IDLoc,
"too few operands for instruction", EmptyRange,
4507 X86Operand &Operand = (X86Operand &)*
Operands[ErrorInfo];
4511 OperandRange, MatchingInlineAsm);
4515 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4521 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4527 if (
llvm::count(Match, Match_MissingFeature) == 1) {
4528 ErrorInfo = Match_MissingFeature;
4529 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
4535 if (
llvm::count(Match, Match_InvalidOperand) == 1) {
4536 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4541 Error(IDLoc,
"unknown use of instruction mnemonic without a size suffix",
4542 EmptyRange, MatchingInlineAsm);
4546bool X86AsmParser::matchAndEmitIntelInstruction(
4548 MCStreamer &Out, uint64_t &ErrorInfo,
bool MatchingInlineAsm) {
4549 X86Operand &
Op =
static_cast<X86Operand &
>(*
Operands[0]);
4550 SMRange EmptyRange = std::nullopt;
4552 X86Operand *UnsizedMemOp =
nullptr;
4554 X86Operand *X86Op =
static_cast<X86Operand *
>(
Op.get());
4556 UnsizedMemOp = X86Op;
4567 static const char *
const PtrSizedInstrs[] = {
"call",
"jmp",
"push",
"pop"};
4568 for (
const char *Instr : PtrSizedInstrs) {
4569 if (Mnemonic == Instr) {
4570 UnsizedMemOp->
Mem.
Size = getPointerWidth();
4576 SmallVector<unsigned, 8> Match;
4577 FeatureBitset ErrorInfoMissingFeatures;
4578 FeatureBitset MissingFeatures;
4583 if (Mnemonic ==
"push" &&
Operands.size() == 2) {
4584 auto *X86Op =
static_cast<X86Operand *
>(
Operands[1].get());
4585 if (X86Op->
isImm()) {
4588 unsigned Size = getPointerWidth();
4591 SmallString<16> Tmp;
4593 Tmp += (is64BitMode())
4595 : (is32BitMode()) ?
"l" : (is16BitMode()) ?
"w" :
" ";
4596 Op.setTokenValue(Tmp);
4599 MissingFeatures, MatchingInlineAsm,
4610 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
4611 for (
unsigned Size : MopSizes) {
4613 uint64_t ErrorInfoIgnore;
4615 unsigned M = MatchInstruction(
Operands, Inst, ErrorInfoIgnore,
4616 MissingFeatures, MatchingInlineAsm,
4617 isParsingIntelSyntax());
4622 if (Match.
back() == Match_MissingFeature)
4623 ErrorInfoMissingFeatures = MissingFeatures;
4633 if (Match.
empty()) {
4635 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,
4636 isParsingIntelSyntax()));
4638 if (Match.
back() == Match_MissingFeature)
4639 ErrorInfoMissingFeatures = MissingFeatures;
4647 if (Match.
back() == Match_MnemonicFail) {
4648 return Error(IDLoc,
"invalid instruction mnemonic '" + Mnemonic +
"'",
4649 Op.getLocRange(), MatchingInlineAsm);
4652 unsigned NumSuccessfulMatches =
llvm::count(Match, Match_Success);
4656 if (UnsizedMemOp && NumSuccessfulMatches > 1 &&
4659 unsigned M = MatchInstruction(
4660 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,
4661 isParsingIntelSyntax());
4662 if (M == Match_Success)
4663 NumSuccessfulMatches = 1;
4675 if (NumSuccessfulMatches == 1) {
4676 if (!MatchingInlineAsm && validateInstruction(Inst,
Operands))
4681 if (!MatchingInlineAsm)
4682 while (processInstruction(Inst,
Operands))
4685 if (!MatchingInlineAsm)
4689 }
else if (NumSuccessfulMatches > 1) {
4691 "multiple matches only possible with unsized memory operands");
4693 "ambiguous operand size for instruction '" + Mnemonic +
"\'",
4699 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4705 if (
llvm::count(Match, Match_MissingFeature) == 1) {
4706 ErrorInfo = Match_MissingFeature;
4707 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
4713 if (
llvm::count(Match, Match_InvalidOperand) == 1) {
4714 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4718 if (
llvm::count(Match, Match_InvalidImmUnsignedi4) == 1) {
4719 SMLoc ErrorLoc = ((X86Operand &)*
Operands[ErrorInfo]).getStartLoc();
4720 if (ErrorLoc == SMLoc())
4722 return Error(ErrorLoc,
"immediate must be an integer in range [0, 15]",
4723 EmptyRange, MatchingInlineAsm);
4727 return Error(IDLoc,
"unknown instruction mnemonic", EmptyRange,
4731bool X86AsmParser::omitRegisterFromClobberLists(MCRegister
Reg) {
4732 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(
Reg);
4735bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
4736 MCAsmParser &Parser = getParser();
4739 return parseDirectiveArch();
4741 return ParseDirectiveCode(IDVal, DirectiveID.
getLoc());
4747 return Error(DirectiveID.
getLoc(),
"'.att_syntax noprefix' is not "
4748 "supported: registers must have a "
4749 "'%' prefix in .att_syntax");
4751 getParser().setAssemblerDialect(0);
4754 getParser().setAssemblerDialect(1);
4759 return Error(DirectiveID.
getLoc(),
"'.intel_syntax prefix' is not "
4760 "supported: registers must not have "
4761 "a '%' prefix in .intel_syntax");
4764 }
else if (IDVal ==
".nops")
4765 return parseDirectiveNops(DirectiveID.
getLoc());
4766 else if (IDVal ==
".even")
4767 return parseDirectiveEven(DirectiveID.
getLoc());
4768 else if (IDVal ==
".cv_fpo_proc")
4769 return parseDirectiveFPOProc(DirectiveID.
getLoc());
4770 else if (IDVal ==
".cv_fpo_setframe")
4771 return parseDirectiveFPOSetFrame(DirectiveID.
getLoc());
4772 else if (IDVal ==
".cv_fpo_pushreg")
4773 return parseDirectiveFPOPushReg(DirectiveID.
getLoc());
4774 else if (IDVal ==
".cv_fpo_stackalloc")
4775 return parseDirectiveFPOStackAlloc(DirectiveID.
getLoc());
4776 else if (IDVal ==
".cv_fpo_stackalign")
4777 return parseDirectiveFPOStackAlign(DirectiveID.
getLoc());
4778 else if (IDVal ==
".cv_fpo_endprologue")
4779 return parseDirectiveFPOEndPrologue(DirectiveID.
getLoc());
4780 else if (IDVal ==
".cv_fpo_endproc")
4781 return parseDirectiveFPOEndProc(DirectiveID.
getLoc());
4782 else if (IDVal ==
".seh_pushreg" ||
4784 return parseDirectiveSEHPushReg(DirectiveID.
getLoc());
4785 else if (IDVal ==
".seh_setframe" ||
4787 return parseDirectiveSEHSetFrame(DirectiveID.
getLoc());
4788 else if (IDVal ==
".seh_savereg" ||
4790 return parseDirectiveSEHSaveReg(DirectiveID.
getLoc());
4791 else if (IDVal ==
".seh_savexmm" ||
4793 return parseDirectiveSEHSaveXMM(DirectiveID.
getLoc());
4794 else if (IDVal ==
".seh_pushframe" ||
4796 return parseDirectiveSEHPushFrame(DirectiveID.
getLoc());
4801bool X86AsmParser::parseDirectiveArch() {
4803 getParser().parseStringToEndOfStatement();
4809bool X86AsmParser::parseDirectiveNops(SMLoc L) {
4810 int64_t NumBytes = 0, Control = 0;
4811 SMLoc NumBytesLoc, ControlLoc;
4812 const MCSubtargetInfo& STI = getSTI();
4813 NumBytesLoc = getTok().getLoc();
4814 if (getParser().checkForValidSection() ||
4815 getParser().parseAbsoluteExpression(NumBytes))
4819 ControlLoc = getTok().getLoc();
4820 if (getParser().parseAbsoluteExpression(Control))
4823 if (getParser().parseEOL())
4826 if (NumBytes <= 0) {
4827 Error(NumBytesLoc,
"'.nops' directive with non-positive size");
4832 Error(ControlLoc,
"'.nops' directive with negative NOP size");
4837 getParser().getStreamer().emitNops(NumBytes, Control, L, STI);
4844bool X86AsmParser::parseDirectiveEven(SMLoc L) {
4848 const MCSection *
Section = getStreamer().getCurrentSectionOnly();
4850 getStreamer().initSections(
false, getSTI());
4851 Section = getStreamer().getCurrentSectionOnly();
4853 if (
getContext().getAsmInfo()->useCodeAlign(*Section))
4854 getStreamer().emitCodeAlignment(
Align(2), &getSTI(), 0);
4856 getStreamer().emitValueToAlignment(
Align(2), 0, 1, 0);
4862bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
4863 MCAsmParser &Parser = getParser();
4865 if (IDVal ==
".code16") {
4867 if (!is16BitMode()) {
4868 SwitchMode(X86::Is16Bit);
4869 getTargetStreamer().emitCode16();
4871 }
else if (IDVal ==
".code16gcc") {
4875 if (!is16BitMode()) {
4876 SwitchMode(X86::Is16Bit);
4877 getTargetStreamer().emitCode16();
4879 }
else if (IDVal ==
".code32") {
4881 if (!is32BitMode()) {
4882 SwitchMode(X86::Is32Bit);
4883 getTargetStreamer().emitCode32();
4885 }
else if (IDVal ==
".code64") {
4887 if (!is64BitMode()) {
4888 SwitchMode(X86::Is64Bit);
4889 getTargetStreamer().emitCode64();
4892 Error(L,
"unknown directive " + IDVal);
4900bool X86AsmParser::parseDirectiveFPOProc(SMLoc L) {
4901 MCAsmParser &Parser = getParser();
4905 return Parser.
TokError(
"expected symbol name");
4906 if (Parser.
parseIntToken(ParamsSize,
"expected parameter byte count"))
4909 return Parser.
TokError(
"parameters size out of range");
4913 return getTargetStreamer().emitFPOProc(ProcSym, ParamsSize, L);
4917bool X86AsmParser::parseDirectiveFPOSetFrame(SMLoc L) {
4920 if (parseRegister(
Reg, DummyLoc, DummyLoc) || parseEOL())
4922 return getTargetStreamer().emitFPOSetFrame(
Reg, L);
4926bool X86AsmParser::parseDirectiveFPOPushReg(SMLoc L) {
4929 if (parseRegister(
Reg, DummyLoc, DummyLoc) || parseEOL())
4931 return getTargetStreamer().emitFPOPushReg(
Reg, L);
4935bool X86AsmParser::parseDirectiveFPOStackAlloc(SMLoc L) {
4936 MCAsmParser &Parser = getParser();
4940 return getTargetStreamer().emitFPOStackAlloc(
Offset, L);
4944bool X86AsmParser::parseDirectiveFPOStackAlign(SMLoc L) {
4945 MCAsmParser &Parser = getParser();
4949 return getTargetStreamer().emitFPOStackAlign(
Offset, L);
4953bool X86AsmParser::parseDirectiveFPOEndPrologue(SMLoc L) {
4954 MCAsmParser &Parser = getParser();
4957 return getTargetStreamer().emitFPOEndPrologue(L);
4961bool X86AsmParser::parseDirectiveFPOEndProc(SMLoc L) {
4962 MCAsmParser &Parser = getParser();
4965 return getTargetStreamer().emitFPOEndProc(L);
4968bool X86AsmParser::parseSEHRegisterNumber(
unsigned RegClassID,
4969 MCRegister &RegNo) {
4970 SMLoc startLoc = getLexer().getLoc();
4976 if (parseRegister(RegNo, startLoc, endLoc))
4979 if (!X86MCRegisterClasses[RegClassID].
contains(RegNo)) {
4980 return Error(startLoc,
4981 "register is not supported for use with this directive");
4987 if (getParser().parseAbsoluteExpression(EncodedReg))
4992 RegNo = MCRegister();
4993 for (
MCPhysReg Reg : X86MCRegisterClasses[RegClassID]) {
4994 if (
MRI->getEncodingValue(
Reg) == EncodedReg) {
5000 return Error(startLoc,
5001 "incorrect register number for use with this directive");
5008bool X86AsmParser::parseDirectiveSEHPushReg(SMLoc Loc) {
5010 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5014 return TokError(
"expected end of directive");
5017 getStreamer().emitWinCFIPushReg(
Reg, Loc);
5021bool X86AsmParser::parseDirectiveSEHSetFrame(SMLoc Loc) {
5024 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5027 return TokError(
"you must specify a stack pointer offset");
5030 if (getParser().parseAbsoluteExpression(Off))
5034 return TokError(
"expected end of directive");
5037 getStreamer().emitWinCFISetFrame(
Reg, Off, Loc);
5041bool X86AsmParser::parseDirectiveSEHSaveReg(SMLoc Loc) {
5044 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5047 return TokError(
"you must specify an offset on the stack");
5050 if (getParser().parseAbsoluteExpression(Off))
5054 return TokError(
"expected end of directive");
5057 getStreamer().emitWinCFISaveReg(
Reg, Off, Loc);
5061bool X86AsmParser::parseDirectiveSEHSaveXMM(SMLoc Loc) {
5064 if (parseSEHRegisterNumber(X86::VR128XRegClassID,
Reg))
5067 return TokError(
"you must specify an offset on the stack");
5070 if (getParser().parseAbsoluteExpression(Off))
5074 return TokError(
"expected end of directive");
5077 getStreamer().emitWinCFISaveXMM(
Reg, Off, Loc);
5081bool X86AsmParser::parseDirectiveSEHPushFrame(SMLoc Loc) {
5085 SMLoc startLoc = getLexer().getLoc();
5087 if (!getParser().parseIdentifier(CodeID)) {
5088 if (CodeID !=
"code")
5089 return Error(startLoc,
"expected @code");
5095 return TokError(
"expected end of directive");
5098 getStreamer().emitWinCFIPushFrame(Code, Loc);
5108#define GET_MATCHER_IMPLEMENTATION
5109#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.
@ XOP
XOP - Opcode prefix used by XOP instructions.
@ 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