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);
144 unsigned MatchInstruction(
const OperandVector &Operands, MCInst &Inst,
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);
1150 bool parseIntelOperand(
OperandVector &Operands, StringRef Name);
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);
1158 bool ParseRoundingModeOp(SMLoc Start,
OperandVector &Operands);
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;
1228 void MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &
Op,
OperandVector &Operands,
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(
1682 OperandVector& Operands, std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
1683 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst) {
1684 if (isParsingIntelSyntax()) {
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)
1776bool X86AsmParser::parseOperand(
OperandVector &Operands, StringRef Name) {
1777 if (isParsingIntelSyntax())
1778 return parseIntelOperand(Operands, Name);
1780 return parseATTOperand(Operands);
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)
2302bool X86AsmParser::ParseRoundingModeOp(SMLoc Start,
OperandVector &Operands) {
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))
2623bool X86AsmParser::parseIntelOperand(
OperandVector &Operands, StringRef Name) {
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(),
2765 SM.getIdentifierInfo(), Operands);
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));
2817bool X86AsmParser::parseATTOperand(
OperandVector &Operands) {
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");
2929bool X86AsmParser::HandleAVX512Operand(
OperandVector &Operands) {
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"},
3530 bool CurlyAsEndOfStatement =
false;
3533 while (isLockRepeatNtPrefix(
Name.lower())) {
3535 StringSwitch<unsigned>(Name)
3554 while (
Name.starts_with(
";") ||
Name.starts_with(
"\n") ||
3555 Name.starts_with(
"#") ||
Name.starts_with(
"\t") ||
3556 Name.starts_with(
"/")) {
3567 if (PatchedName ==
"data16" && is16BitMode()) {
3568 return Error(NameLoc,
"redundant data16 prefix");
3570 if (PatchedName ==
"data32") {
3572 return Error(NameLoc,
"redundant data32 prefix");
3574 return Error(NameLoc,
"'data32' is not supported in 64-bit mode");
3576 PatchedName =
"data16";
3583 if (
Next ==
"callw")
3585 if (
Next ==
"ljmpw")
3590 ForcedDataPrefix = X86::Is32Bit;
3598 if (ComparisonPredicate != ~0U && !isParsingIntelSyntax()) {
3605 if ((
Name.starts_with(
"ccmp") ||
Name.starts_with(
"ctest")) &&
3606 parseCFlagsOp(Operands))
3620 if (parseOperand(Operands, Name))
3622 if (HandleAVX512Operand(Operands))
3634 CurlyAsEndOfStatement =
3635 isParsingIntelSyntax() && isParsingMSInlineAsm() &&
3638 return TokError(
"unexpected token in argument list");
3642 if (ComparisonPredicate != ~0U && isParsingIntelSyntax()) {
3652 else if (CurlyAsEndOfStatement)
3655 getLexer().getTok().getLoc(), 0);
3662 if (IsFp && Operands.
size() == 1) {
3663 const char *Repl = StringSwitch<const char *>(Name)
3664 .Case(
"fsub",
"fsubp")
3665 .Case(
"fdiv",
"fdivp")
3666 .Case(
"fsubr",
"fsubrp")
3667 .Case(
"fdivr",
"fdivrp");
3668 static_cast<X86Operand &
>(*Operands[0]).setTokenValue(Repl);
3671 if ((Name ==
"mov" || Name ==
"movw" || Name ==
"movl") &&
3672 (Operands.
size() == 3)) {
3673 X86Operand &Op1 = (X86Operand &)*Operands[1];
3674 X86Operand &Op2 = (X86Operand &)*Operands[2];
3679 X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(
3681 (X86MCRegisterClasses[X86::GR16RegClassID].contains(Op1.
getReg()) ||
3682 X86MCRegisterClasses[X86::GR32RegClassID].contains(Op1.
getReg()))) {
3684 if (Name !=
"mov" && Name[3] == (is16BitMode() ?
'l' :
'w')) {
3685 Name = is16BitMode() ?
"movw" :
"movl";
3698 if ((Name ==
"outb" || Name ==
"outsb" || Name ==
"outw" || Name ==
"outsw" ||
3699 Name ==
"outl" || Name ==
"outsl" || Name ==
"out" || Name ==
"outs") &&
3700 Operands.
size() == 3) {
3701 X86Operand &
Op = (X86Operand &)*Operands.
back();
3707 if ((Name ==
"inb" || Name ==
"insb" || Name ==
"inw" || Name ==
"insw" ||
3708 Name ==
"inl" || Name ==
"insl" || Name ==
"in" || Name ==
"ins") &&
3709 Operands.
size() == 3) {
3710 X86Operand &
Op = (X86Operand &)*Operands[1];
3717 bool HadVerifyError =
false;
3720 if (
Name.starts_with(
"ins") &&
3721 (Operands.
size() == 1 || Operands.
size() == 3) &&
3722 (Name ==
"insb" || Name ==
"insw" || Name ==
"insl" || Name ==
"insd" ||
3725 AddDefaultSrcDestOperands(TmpOperands,
3727 DefaultMemDIOperand(NameLoc));
3728 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3732 if (
Name.starts_with(
"outs") &&
3733 (Operands.
size() == 1 || Operands.
size() == 3) &&
3734 (Name ==
"outsb" || Name ==
"outsw" || Name ==
"outsl" ||
3735 Name ==
"outsd" || Name ==
"outs")) {
3736 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
3738 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3744 if (
Name.starts_with(
"lods") &&
3745 (Operands.
size() == 1 || Operands.
size() == 2) &&
3746 (Name ==
"lods" || Name ==
"lodsb" || Name ==
"lodsw" ||
3747 Name ==
"lodsl" || Name ==
"lodsd" || Name ==
"lodsq")) {
3748 TmpOperands.
push_back(DefaultMemSIOperand(NameLoc));
3749 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3755 if (
Name.starts_with(
"stos") &&
3756 (Operands.
size() == 1 || Operands.
size() == 2) &&
3757 (Name ==
"stos" || Name ==
"stosb" || Name ==
"stosw" ||
3758 Name ==
"stosl" || Name ==
"stosd" || Name ==
"stosq")) {
3759 TmpOperands.
push_back(DefaultMemDIOperand(NameLoc));
3760 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3766 if (
Name.starts_with(
"scas") &&
3767 (Operands.
size() == 1 || Operands.
size() == 2) &&
3768 (Name ==
"scas" || Name ==
"scasb" || Name ==
"scasw" ||
3769 Name ==
"scasl" || Name ==
"scasd" || Name ==
"scasq")) {
3770 TmpOperands.
push_back(DefaultMemDIOperand(NameLoc));
3771 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3775 if (
Name.starts_with(
"cmps") &&
3776 (Operands.
size() == 1 || Operands.
size() == 3) &&
3777 (Name ==
"cmps" || Name ==
"cmpsb" || Name ==
"cmpsw" ||
3778 Name ==
"cmpsl" || Name ==
"cmpsd" || Name ==
"cmpsq")) {
3779 AddDefaultSrcDestOperands(TmpOperands, DefaultMemDIOperand(NameLoc),
3780 DefaultMemSIOperand(NameLoc));
3781 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3785 if (((
Name.starts_with(
"movs") &&
3786 (Name ==
"movs" || Name ==
"movsb" || Name ==
"movsw" ||
3787 Name ==
"movsl" || Name ==
"movsd" || Name ==
"movsq")) ||
3788 (
Name.starts_with(
"smov") &&
3789 (Name ==
"smov" || Name ==
"smovb" || Name ==
"smovw" ||
3790 Name ==
"smovl" || Name ==
"smovd" || Name ==
"smovq"))) &&
3791 (Operands.
size() == 1 || Operands.
size() == 3)) {
3792 if (Name ==
"movsd" && Operands.
size() == 1 && !isParsingIntelSyntax())
3794 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
3795 DefaultMemDIOperand(NameLoc));
3796 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3800 if (HadVerifyError) {
3801 return HadVerifyError;
3805 if ((Name ==
"xlat" || Name ==
"xlatb") && Operands.
size() == 2) {
3806 X86Operand &Op1 =
static_cast<X86Operand &
>(*Operands[1]);
3809 "size, (R|E)BX will be used for the location");
3811 static_cast<X86Operand &
>(*Operands[0]).setTokenValue(
"xlatb");
3824 if (
I == Table.
end() ||
I->OldOpc != Opcode)
3830 if (X86::isBLENDVPD(Opcode) || X86::isBLENDVPS(Opcode) ||
3831 X86::isPBLENDVB(Opcode))
3837bool X86AsmParser::processInstruction(MCInst &Inst,
const OperandVector &
Ops) {
3841 if (ForcedOpcodePrefix != OpcodePrefix_VEX3 &&
3848 auto replaceWithCCMPCTEST = [&](
unsigned Opcode) ->
bool {
3849 if (ForcedOpcodePrefix == OpcodePrefix_EVEX) {
3860 default:
return false;
3865 if (ForcedDispEncoding == DispEncoding_Disp32) {
3866 Inst.
setOpcode(is16BitMode() ? X86::JMP_2 : X86::JMP_4);
3875 if (ForcedDispEncoding == DispEncoding_Disp32) {
3876 Inst.
setOpcode(is16BitMode() ? X86::JCC_2 : X86::JCC_4);
3892#define FROM_TO(FROM, TO) \
3894 return replaceWithCCMPCTEST(X86::TO);
3896 FROM_TO(CMP64mi32, CCMP64mi32)
3899 FROM_TO(CMP64ri32, CCMP64ri32)
3926 FROM_TO(TEST64mi32, CTEST64mi32)
3928 FROM_TO(TEST64ri32, CTEST64ri32)
3948bool X86AsmParser::validateInstruction(MCInst &Inst,
const OperandVector &
Ops) {
3949 using namespace X86;
3952 uint64_t TSFlags = MII.get(Opcode).TSFlags;
3953 if (isVFCMADDCPH(Opcode) || isVFCMADDCSH(Opcode) || isVFMADDCPH(Opcode) ||
3954 isVFMADDCSH(Opcode)) {
3958 return Warning(
Ops[0]->getStartLoc(),
"Destination register should be "
3959 "distinct from source registers");
3960 }
else if (isVFCMULCPH(Opcode) || isVFCMULCSH(Opcode) || isVFMULCPH(Opcode) ||
3961 isVFMULCSH(Opcode)) {
3971 return Warning(
Ops[0]->getStartLoc(),
"Destination register should be "
3972 "distinct from source registers");
3973 }
else if (isV4FMADDPS(Opcode) || isV4FMADDSS(Opcode) ||
3974 isV4FNMADDPS(Opcode) || isV4FNMADDSS(Opcode) ||
3975 isVP4DPWSSDS(Opcode) || isVP4DPWSSD(Opcode)) {
3979 unsigned Src2Enc =
MRI->getEncodingValue(Src2);
3980 if (Src2Enc % 4 != 0) {
3982 unsigned GroupStart = (Src2Enc / 4) * 4;
3983 unsigned GroupEnd = GroupStart + 3;
3985 "source register '" +
RegName +
"' implicitly denotes '" +
3986 RegName.take_front(3) + Twine(GroupStart) +
"' to '" +
3987 RegName.take_front(3) + Twine(GroupEnd) +
3990 }
else if (isVGATHERDPD(Opcode) || isVGATHERDPS(Opcode) ||
3991 isVGATHERQPD(Opcode) || isVGATHERQPS(Opcode) ||
3992 isVPGATHERDD(Opcode) || isVPGATHERDQ(Opcode) ||
3993 isVPGATHERQD(Opcode) || isVPGATHERQQ(Opcode)) {
3997 unsigned Index =
MRI->getEncodingValue(
4000 return Warning(
Ops[0]->getStartLoc(),
"index and destination registers "
4001 "should be distinct");
4005 unsigned Index =
MRI->getEncodingValue(
4007 if (Dest == Mask || Dest == Index || Mask == Index)
4008 return Warning(
Ops[0]->getStartLoc(),
"mask, index, and destination "
4009 "registers should be distinct");
4011 }
else if (isTCMMIMFP16PS(Opcode) || isTCMMRLFP16PS(Opcode) ||
4012 isTDPBF16PS(Opcode) || isTDPFP16PS(Opcode) || isTDPBSSD(Opcode) ||
4013 isTDPBSUD(Opcode) || isTDPBUSD(Opcode) || isTDPBUUD(Opcode)) {
4017 if (SrcDest == Src1 || SrcDest == Src2 || Src1 == Src2)
4018 return Error(
Ops[0]->getStartLoc(),
"all tmm registers must be distinct");
4032 for (
unsigned i = 0; i !=
NumOps; ++i) {
4037 if (
Reg == X86::AH ||
Reg == X86::BH ||
Reg == X86::CH ||
Reg == X86::DH)
4045 (Enc ==
X86II::EVEX || ForcedOpcodePrefix == OpcodePrefix_REX2 ||
4046 ForcedOpcodePrefix == OpcodePrefix_REX || UsesRex)) {
4048 return Error(
Ops[0]->getStartLoc(),
4049 "can't encode '" +
RegName.str() +
4050 "' in an instruction requiring EVEX/REX2/REX prefix");
4054 if ((Opcode == X86::PREFETCHIT0 || Opcode == X86::PREFETCHIT1)) {
4058 Ops[0]->getStartLoc(),
4059 Twine((Inst.
getOpcode() == X86::PREFETCHIT0 ?
"'prefetchit0'"
4060 :
"'prefetchit1'")) +
4061 " only supports RIP-relative address");
4066void X86AsmParser::emitWarningForSpecialLVIInstruction(SMLoc Loc) {
4067 Warning(Loc,
"Instruction may be vulnerable to LVI and "
4068 "requires manual mitigation");
4069 Note(SMLoc(),
"See https://software.intel.com/"
4070 "security-software-guidance/insights/"
4071 "deep-dive-load-value-injection#specialinstructions"
4072 " for more information");
4084void X86AsmParser::applyLVICFIMitigation(MCInst &Inst, MCStreamer &Out) {
4095 MCInst ShlInst, FenceInst;
4096 bool Parse32 = is32BitMode() || Code16GCC;
4097 MCRegister Basereg =
4098 is64BitMode() ? X86::RSP : (Parse32 ? X86::ESP : X86::SP);
4102 1, SMLoc{}, SMLoc{}, 0);
4104 ShlMemOp->addMemOperands(ShlInst, 5);
4117 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4129void X86AsmParser::applyLVILoadHardeningMitigation(MCInst &Inst,
4146 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4149 }
else if (Opcode == X86::REP_PREFIX || Opcode == X86::REPNE_PREFIX) {
4152 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4156 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
4171void X86AsmParser::emitInstruction(MCInst &Inst,
OperandVector &Operands,
4174 getSTI().hasFeature(X86::FeatureLVIControlFlowIntegrity))
4175 applyLVICFIMitigation(Inst, Out);
4180 getSTI().hasFeature(X86::FeatureLVILoadHardening))
4181 applyLVILoadHardeningMitigation(Inst, Out);
4185 unsigned Result = 0;
4187 if (Prefix.isPrefix()) {
4188 Result = Prefix.getPrefix();
4194bool X86AsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
4196 MCStreamer &Out, uint64_t &ErrorInfo,
4197 bool MatchingInlineAsm) {
4198 assert(!Operands.
empty() &&
"Unexpect empty operand list!");
4199 assert((*Operands[0]).isToken() &&
"Leading operand should always be a mnemonic!");
4202 MatchFPUWaitAlias(IDLoc,
static_cast<X86Operand &
>(*Operands[0]), Operands,
4203 Out, MatchingInlineAsm);
4210 if (ForcedOpcodePrefix == OpcodePrefix_REX)
4212 else if (ForcedOpcodePrefix == OpcodePrefix_REX2)
4214 else if (ForcedOpcodePrefix == OpcodePrefix_VEX)
4216 else if (ForcedOpcodePrefix == OpcodePrefix_VEX2)
4218 else if (ForcedOpcodePrefix == OpcodePrefix_VEX3)
4220 else if (ForcedOpcodePrefix == OpcodePrefix_EVEX)
4224 if (ForcedDispEncoding == DispEncoding_Disp8)
4226 else if (ForcedDispEncoding == DispEncoding_Disp32)
4232 return isParsingIntelSyntax()
4233 ? matchAndEmitIntelInstruction(IDLoc, Opcode, Inst, Operands, Out,
4234 ErrorInfo, MatchingInlineAsm)
4235 : matchAndEmitATTInstruction(IDLoc, Opcode, Inst, Operands, Out,
4236 ErrorInfo, MatchingInlineAsm);
4239void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &
Op,
4241 bool MatchingInlineAsm) {
4245 const char *Repl = StringSwitch<const char *>(
Op.getToken())
4246 .Case(
"finit",
"fninit")
4247 .Case(
"fsave",
"fnsave")
4248 .Case(
"fstcw",
"fnstcw")
4249 .Case(
"fstcww",
"fnstcw")
4250 .Case(
"fstenv",
"fnstenv")
4251 .Case(
"fstsw",
"fnstsw")
4252 .Case(
"fstsww",
"fnstsw")
4253 .Case(
"fclex",
"fnclex")
4259 if (!MatchingInlineAsm)
4265bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc,
4266 const FeatureBitset &MissingFeatures,
4267 bool MatchingInlineAsm) {
4268 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
4269 SmallString<126> Msg;
4270 raw_svector_ostream OS(Msg);
4271 OS <<
"instruction requires:";
4272 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
4273 if (MissingFeatures[i])
4276 return Error(IDLoc, OS.str(), SMRange(), MatchingInlineAsm);
4279unsigned X86AsmParser::checkTargetMatchPredicate(MCInst &Inst) {
4281 const MCInstrDesc &MCID = MII.get(
Opc);
4282 uint64_t TSFlags = MCID.
TSFlags;
4285 return Match_Unsupported;
4287 return Match_Unsupported;
4289 switch (ForcedOpcodePrefix) {
4290 case OpcodePrefix_Default:
4292 case OpcodePrefix_REX:
4293 case OpcodePrefix_REX2:
4295 return Match_Unsupported;
4297 case OpcodePrefix_VEX:
4298 case OpcodePrefix_VEX2:
4299 case OpcodePrefix_VEX3:
4301 return Match_Unsupported;
4303 case OpcodePrefix_EVEX:
4305 !X86::isCMP(
Opc) && !X86::isTEST(
Opc))
4306 return Match_Unsupported;
4308 return Match_Unsupported;
4313 (ForcedOpcodePrefix != OpcodePrefix_VEX &&
4314 ForcedOpcodePrefix != OpcodePrefix_VEX2 &&
4315 ForcedOpcodePrefix != OpcodePrefix_VEX3))
4316 return Match_Unsupported;
4318 return Match_Success;
4321bool X86AsmParser::matchAndEmitATTInstruction(
4322 SMLoc IDLoc,
unsigned &Opcode, MCInst &Inst,
OperandVector &Operands,
4323 MCStreamer &Out, uint64_t &ErrorInfo,
bool MatchingInlineAsm) {
4324 X86Operand &
Op =
static_cast<X86Operand &
>(*Operands[0]);
4325 SMRange EmptyRange = std::nullopt;
4328 if (ForcedDataPrefix == X86::Is32Bit)
4329 SwitchMode(X86::Is32Bit);
4331 FeatureBitset MissingFeatures;
4332 unsigned OriginalError = MatchInstruction(Operands, Inst, ErrorInfo,
4333 MissingFeatures, MatchingInlineAsm,
4334 isParsingIntelSyntax());
4335 if (ForcedDataPrefix == X86::Is32Bit) {
4336 SwitchMode(X86::Is16Bit);
4337 ForcedDataPrefix = 0;
4339 switch (OriginalError) {
4342 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
4347 if (!MatchingInlineAsm)
4348 while (processInstruction(Inst, Operands))
4352 if (!MatchingInlineAsm)
4356 case Match_InvalidImmUnsignedi4: {
4357 SMLoc ErrorLoc = ((X86Operand &)*Operands[ErrorInfo]).getStartLoc();
4358 if (ErrorLoc == SMLoc())
4360 return Error(ErrorLoc,
"immediate must be an integer in range [0, 15]",
4361 EmptyRange, MatchingInlineAsm);
4363 case Match_MissingFeature:
4364 return ErrorMissingFeature(IDLoc, MissingFeatures, MatchingInlineAsm);
4365 case Match_InvalidOperand:
4366 case Match_MnemonicFail:
4367 case Match_Unsupported:
4370 if (
Op.getToken().empty()) {
4371 Error(IDLoc,
"instruction must have size higher than 0", EmptyRange,
4382 StringRef
Base =
Op.getToken();
4383 SmallString<16> Tmp;
4386 Op.setTokenValue(Tmp);
4394 const char *Suffixes =
Base[0] !=
'f' ?
"bwlq" :
"slt\0";
4396 const char *MemSize =
Base[0] !=
'f' ?
"\x08\x10\x20\x40" :
"\x20\x40\x50\0";
4399 uint64_t ErrorInfoIgnore;
4400 FeatureBitset ErrorInfoMissingFeatures;
4408 bool HasVectorReg =
false;
4409 X86Operand *MemOp =
nullptr;
4410 for (
const auto &
Op : Operands) {
4411 X86Operand *X86Op =
static_cast<X86Operand *
>(
Op.get());
4413 HasVectorReg =
true;
4414 else if (X86Op->
isMem()) {
4416 assert(MemOp->Mem.Size == 0 &&
"Memory size always 0 under ATT syntax");
4423 for (
unsigned I = 0,
E = std::size(Match);
I !=
E; ++
I) {
4424 Tmp.
back() = Suffixes[
I];
4425 if (MemOp && HasVectorReg)
4426 MemOp->Mem.Size = MemSize[
I];
4427 Match[
I] = Match_MnemonicFail;
4428 if (MemOp || !HasVectorReg) {
4430 MatchInstruction(Operands, Inst, ErrorInfoIgnore, MissingFeatures,
4431 MatchingInlineAsm, isParsingIntelSyntax());
4433 if (Match[
I] == Match_MissingFeature)
4434 ErrorInfoMissingFeatures = MissingFeatures;
4444 unsigned NumSuccessfulMatches =
llvm::count(Match, Match_Success);
4445 if (NumSuccessfulMatches == 1) {
4446 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
4451 if (!MatchingInlineAsm)
4452 while (processInstruction(Inst, Operands))
4456 if (!MatchingInlineAsm)
4466 if (NumSuccessfulMatches > 1) {
4468 unsigned NumMatches = 0;
4469 for (
unsigned I = 0,
E = std::size(Match);
I !=
E; ++
I)
4470 if (Match[
I] == Match_Success)
4471 MatchChars[NumMatches++] = Suffixes[
I];
4473 SmallString<126> Msg;
4474 raw_svector_ostream OS(Msg);
4475 OS <<
"ambiguous instructions require an explicit suffix (could be ";
4476 for (
unsigned i = 0; i != NumMatches; ++i) {
4479 if (i + 1 == NumMatches)
4481 OS <<
"'" <<
Base << MatchChars[i] <<
"'";
4484 Error(IDLoc, OS.str(), EmptyRange, MatchingInlineAsm);
4492 if (
llvm::count(Match, Match_MnemonicFail) == 4) {
4493 if (OriginalError == Match_MnemonicFail)
4494 return Error(IDLoc,
"invalid instruction mnemonic '" +
Base +
"'",
4495 Op.getLocRange(), MatchingInlineAsm);
4497 if (OriginalError == Match_Unsupported)
4498 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4501 assert(OriginalError == Match_InvalidOperand &&
"Unexpected error");
4503 if (ErrorInfo != ~0ULL) {
4504 if (ErrorInfo >= Operands.size())
4505 return Error(IDLoc,
"too few operands for instruction", EmptyRange,
4508 X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo];
4512 OperandRange, MatchingInlineAsm);
4516 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4522 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4528 if (
llvm::count(Match, Match_MissingFeature) == 1) {
4529 ErrorInfo = Match_MissingFeature;
4530 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
4536 if (
llvm::count(Match, Match_InvalidOperand) == 1) {
4537 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4542 Error(IDLoc,
"unknown use of instruction mnemonic without a size suffix",
4543 EmptyRange, MatchingInlineAsm);
4547bool X86AsmParser::matchAndEmitIntelInstruction(
4548 SMLoc IDLoc,
unsigned &Opcode, MCInst &Inst,
OperandVector &Operands,
4549 MCStreamer &Out, uint64_t &ErrorInfo,
bool MatchingInlineAsm) {
4550 X86Operand &
Op =
static_cast<X86Operand &
>(*Operands[0]);
4551 SMRange EmptyRange = std::nullopt;
4553 X86Operand *UnsizedMemOp =
nullptr;
4554 for (
const auto &
Op : Operands) {
4555 X86Operand *X86Op =
static_cast<X86Operand *
>(
Op.get());
4557 UnsizedMemOp = X86Op;
4566 StringRef Mnemonic = (
static_cast<X86Operand &
>(*Operands[0])).
getToken();
4568 static const char *
const PtrSizedInstrs[] = {
"call",
"jmp",
"push",
"pop"};
4569 for (
const char *Instr : PtrSizedInstrs) {
4570 if (Mnemonic == Instr) {
4571 UnsizedMemOp->
Mem.
Size = getPointerWidth();
4577 SmallVector<unsigned, 8> Match;
4578 FeatureBitset ErrorInfoMissingFeatures;
4579 FeatureBitset MissingFeatures;
4580 StringRef
Base = (
static_cast<X86Operand &
>(*Operands[0])).
getToken();
4584 if (Mnemonic ==
"push" && Operands.size() == 2) {
4585 auto *X86Op =
static_cast<X86Operand *
>(Operands[1].get());
4586 if (X86Op->
isImm()) {
4589 unsigned Size = getPointerWidth();
4592 SmallString<16> Tmp;
4594 Tmp += (is64BitMode())
4596 : (is32BitMode()) ?
"l" : (is16BitMode()) ?
"w" :
" ";
4597 Op.setTokenValue(Tmp);
4599 Match.
push_back(MatchInstruction(Operands, Inst, ErrorInfo,
4600 MissingFeatures, MatchingInlineAsm,
4611 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
4612 for (
unsigned Size : MopSizes) {
4614 uint64_t ErrorInfoIgnore;
4616 unsigned M = MatchInstruction(Operands, Inst, ErrorInfoIgnore,
4617 MissingFeatures, MatchingInlineAsm,
4618 isParsingIntelSyntax());
4623 if (Match.
back() == Match_MissingFeature)
4624 ErrorInfoMissingFeatures = MissingFeatures;
4634 if (Match.
empty()) {
4636 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,
4637 isParsingIntelSyntax()));
4639 if (Match.
back() == Match_MissingFeature)
4640 ErrorInfoMissingFeatures = MissingFeatures;
4648 if (Match.
back() == Match_MnemonicFail) {
4649 return Error(IDLoc,
"invalid instruction mnemonic '" + Mnemonic +
"'",
4650 Op.getLocRange(), MatchingInlineAsm);
4653 unsigned NumSuccessfulMatches =
llvm::count(Match, Match_Success);
4657 if (UnsizedMemOp && NumSuccessfulMatches > 1 &&
4660 unsigned M = MatchInstruction(
4661 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,
4662 isParsingIntelSyntax());
4663 if (M == Match_Success)
4664 NumSuccessfulMatches = 1;
4676 if (NumSuccessfulMatches == 1) {
4677 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
4682 if (!MatchingInlineAsm)
4683 while (processInstruction(Inst, Operands))
4686 if (!MatchingInlineAsm)
4690 }
else if (NumSuccessfulMatches > 1) {
4692 "multiple matches only possible with unsized memory operands");
4694 "ambiguous operand size for instruction '" + Mnemonic +
"\'",
4700 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4706 if (
llvm::count(Match, Match_MissingFeature) == 1) {
4707 ErrorInfo = Match_MissingFeature;
4708 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
4714 if (
llvm::count(Match, Match_InvalidOperand) == 1) {
4715 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4719 if (
llvm::count(Match, Match_InvalidImmUnsignedi4) == 1) {
4720 SMLoc ErrorLoc = ((X86Operand &)*Operands[ErrorInfo]).getStartLoc();
4721 if (ErrorLoc == SMLoc())
4723 return Error(ErrorLoc,
"immediate must be an integer in range [0, 15]",
4724 EmptyRange, MatchingInlineAsm);
4728 return Error(IDLoc,
"unknown instruction mnemonic", EmptyRange,
4732bool X86AsmParser::omitRegisterFromClobberLists(MCRegister
Reg) {
4733 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(
Reg);
4736bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
4737 MCAsmParser &Parser = getParser();
4740 return parseDirectiveArch();
4742 return ParseDirectiveCode(IDVal, DirectiveID.
getLoc());
4748 return Error(DirectiveID.
getLoc(),
"'.att_syntax noprefix' is not "
4749 "supported: registers must have a "
4750 "'%' prefix in .att_syntax");
4752 getParser().setAssemblerDialect(0);
4755 getParser().setAssemblerDialect(1);
4760 return Error(DirectiveID.
getLoc(),
"'.intel_syntax prefix' is not "
4761 "supported: registers must not have "
4762 "a '%' prefix in .intel_syntax");
4765 }
else if (IDVal ==
".nops")
4766 return parseDirectiveNops(DirectiveID.
getLoc());
4767 else if (IDVal ==
".even")
4768 return parseDirectiveEven(DirectiveID.
getLoc());
4769 else if (IDVal ==
".cv_fpo_proc")
4770 return parseDirectiveFPOProc(DirectiveID.
getLoc());
4771 else if (IDVal ==
".cv_fpo_setframe")
4772 return parseDirectiveFPOSetFrame(DirectiveID.
getLoc());
4773 else if (IDVal ==
".cv_fpo_pushreg")
4774 return parseDirectiveFPOPushReg(DirectiveID.
getLoc());
4775 else if (IDVal ==
".cv_fpo_stackalloc")
4776 return parseDirectiveFPOStackAlloc(DirectiveID.
getLoc());
4777 else if (IDVal ==
".cv_fpo_stackalign")
4778 return parseDirectiveFPOStackAlign(DirectiveID.
getLoc());
4779 else if (IDVal ==
".cv_fpo_endprologue")
4780 return parseDirectiveFPOEndPrologue(DirectiveID.
getLoc());
4781 else if (IDVal ==
".cv_fpo_endproc")
4782 return parseDirectiveFPOEndProc(DirectiveID.
getLoc());
4783 else if (IDVal ==
".seh_pushreg" ||
4785 return parseDirectiveSEHPushReg(DirectiveID.
getLoc());
4786 else if (IDVal ==
".seh_setframe" ||
4788 return parseDirectiveSEHSetFrame(DirectiveID.
getLoc());
4789 else if (IDVal ==
".seh_savereg" ||
4791 return parseDirectiveSEHSaveReg(DirectiveID.
getLoc());
4792 else if (IDVal ==
".seh_savexmm" ||
4794 return parseDirectiveSEHSaveXMM(DirectiveID.
getLoc());
4795 else if (IDVal ==
".seh_pushframe" ||
4797 return parseDirectiveSEHPushFrame(DirectiveID.
getLoc());
4802bool X86AsmParser::parseDirectiveArch() {
4804 getParser().parseStringToEndOfStatement();
4810bool X86AsmParser::parseDirectiveNops(SMLoc L) {
4811 int64_t NumBytes = 0, Control = 0;
4812 SMLoc NumBytesLoc, ControlLoc;
4813 const MCSubtargetInfo& STI = getSTI();
4814 NumBytesLoc = getTok().getLoc();
4815 if (getParser().checkForValidSection() ||
4816 getParser().parseAbsoluteExpression(NumBytes))
4820 ControlLoc = getTok().getLoc();
4821 if (getParser().parseAbsoluteExpression(Control))
4824 if (getParser().parseEOL())
4827 if (NumBytes <= 0) {
4828 Error(NumBytesLoc,
"'.nops' directive with non-positive size");
4833 Error(ControlLoc,
"'.nops' directive with negative NOP size");
4838 getParser().getStreamer().emitNops(NumBytes, Control, L, STI);
4845bool X86AsmParser::parseDirectiveEven(SMLoc L) {
4849 const MCSection *
Section = getStreamer().getCurrentSectionOnly();
4851 getStreamer().initSections(
false, getSTI());
4852 Section = getStreamer().getCurrentSectionOnly();
4854 if (
getContext().getAsmInfo()->useCodeAlign(*Section))
4855 getStreamer().emitCodeAlignment(
Align(2), &getSTI(), 0);
4857 getStreamer().emitValueToAlignment(
Align(2), 0, 1, 0);
4863bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
4864 MCAsmParser &Parser = getParser();
4866 if (IDVal ==
".code16") {
4868 if (!is16BitMode()) {
4869 SwitchMode(X86::Is16Bit);
4870 getTargetStreamer().emitCode16();
4872 }
else if (IDVal ==
".code16gcc") {
4876 if (!is16BitMode()) {
4877 SwitchMode(X86::Is16Bit);
4878 getTargetStreamer().emitCode16();
4880 }
else if (IDVal ==
".code32") {
4882 if (!is32BitMode()) {
4883 SwitchMode(X86::Is32Bit);
4884 getTargetStreamer().emitCode32();
4886 }
else if (IDVal ==
".code64") {
4888 if (!is64BitMode()) {
4889 SwitchMode(X86::Is64Bit);
4890 getTargetStreamer().emitCode64();
4893 Error(L,
"unknown directive " + IDVal);
4901bool X86AsmParser::parseDirectiveFPOProc(SMLoc L) {
4902 MCAsmParser &Parser = getParser();
4906 return Parser.
TokError(
"expected symbol name");
4907 if (Parser.
parseIntToken(ParamsSize,
"expected parameter byte count"))
4910 return Parser.
TokError(
"parameters size out of range");
4914 return getTargetStreamer().emitFPOProc(ProcSym, ParamsSize, L);
4918bool X86AsmParser::parseDirectiveFPOSetFrame(SMLoc L) {
4921 if (parseRegister(
Reg, DummyLoc, DummyLoc) || parseEOL())
4923 return getTargetStreamer().emitFPOSetFrame(
Reg, L);
4927bool X86AsmParser::parseDirectiveFPOPushReg(SMLoc L) {
4930 if (parseRegister(
Reg, DummyLoc, DummyLoc) || parseEOL())
4932 return getTargetStreamer().emitFPOPushReg(
Reg, L);
4936bool X86AsmParser::parseDirectiveFPOStackAlloc(SMLoc L) {
4937 MCAsmParser &Parser = getParser();
4941 return getTargetStreamer().emitFPOStackAlloc(
Offset, L);
4945bool X86AsmParser::parseDirectiveFPOStackAlign(SMLoc L) {
4946 MCAsmParser &Parser = getParser();
4950 return getTargetStreamer().emitFPOStackAlign(
Offset, L);
4954bool X86AsmParser::parseDirectiveFPOEndPrologue(SMLoc L) {
4955 MCAsmParser &Parser = getParser();
4958 return getTargetStreamer().emitFPOEndPrologue(L);
4962bool X86AsmParser::parseDirectiveFPOEndProc(SMLoc L) {
4963 MCAsmParser &Parser = getParser();
4966 return getTargetStreamer().emitFPOEndProc(L);
4969bool X86AsmParser::parseSEHRegisterNumber(
unsigned RegClassID,
4970 MCRegister &RegNo) {
4971 SMLoc startLoc = getLexer().getLoc();
4977 if (parseRegister(RegNo, startLoc, endLoc))
4980 if (!X86MCRegisterClasses[RegClassID].
contains(RegNo)) {
4981 return Error(startLoc,
4982 "register is not supported for use with this directive");
4988 if (getParser().parseAbsoluteExpression(EncodedReg))
4993 RegNo = MCRegister();
4994 for (
MCPhysReg Reg : X86MCRegisterClasses[RegClassID]) {
4995 if (
MRI->getEncodingValue(
Reg) == EncodedReg) {
5001 return Error(startLoc,
5002 "incorrect register number for use with this directive");
5009bool X86AsmParser::parseDirectiveSEHPushReg(SMLoc Loc) {
5011 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5015 return TokError(
"expected end of directive");
5018 getStreamer().emitWinCFIPushReg(
Reg, Loc);
5022bool X86AsmParser::parseDirectiveSEHSetFrame(SMLoc Loc) {
5025 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5028 return TokError(
"you must specify a stack pointer offset");
5031 if (getParser().parseAbsoluteExpression(Off))
5035 return TokError(
"expected end of directive");
5038 getStreamer().emitWinCFISetFrame(
Reg, Off, Loc);
5042bool X86AsmParser::parseDirectiveSEHSaveReg(SMLoc Loc) {
5045 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5048 return TokError(
"you must specify an offset on the stack");
5051 if (getParser().parseAbsoluteExpression(Off))
5055 return TokError(
"expected end of directive");
5058 getStreamer().emitWinCFISaveReg(
Reg, Off, Loc);
5062bool X86AsmParser::parseDirectiveSEHSaveXMM(SMLoc Loc) {
5065 if (parseSEHRegisterNumber(X86::VR128XRegClassID,
Reg))
5068 return TokError(
"you must specify an offset on the stack");
5071 if (getParser().parseAbsoluteExpression(Off))
5075 return TokError(
"expected end of directive");
5078 getStreamer().emitWinCFISaveXMM(
Reg, Off, Loc);
5082bool X86AsmParser::parseDirectiveSEHPushFrame(SMLoc Loc) {
5086 SMLoc startLoc = getLexer().getLoc();
5088 if (!getParser().parseIdentifier(CodeID)) {
5089 if (CodeID !=
"code")
5090 return Error(startLoc,
"expected @code");
5096 return TokError(
"expected end of directive");
5099 getStreamer().emitWinCFIPushFrame(Code, Loc);
5109#define GET_MATCHER_IMPLEMENTATION
5110#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[]
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