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 = {},
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 CheckDispOverflow(MCRegister BaseReg, MCRegister IndexReg,
1175 const MCExpr *Disp, SMLoc Loc);
1177 bool ParseMemOperand(MCRegister SegReg,
const MCExpr *Disp, SMLoc StartLoc,
1182 bool ParseIntelMemoryOperandSize(
unsigned &
Size, StringRef *SizeStr);
1183 bool CreateMemForMSInlineAsm(MCRegister SegReg,
const MCExpr *Disp,
1184 MCRegister BaseReg, MCRegister IndexReg,
1185 unsigned Scale,
bool NonAbsMem, SMLoc Start,
1186 SMLoc End,
unsigned Size, StringRef Identifier,
1187 const InlineAsmIdentifierInfo &
Info,
1190 bool parseDirectiveArch();
1191 bool parseDirectiveNops(SMLoc L);
1192 bool parseDirectiveEven(SMLoc L);
1193 bool ParseDirectiveCode(StringRef IDVal, SMLoc L);
1196 bool parseDirectiveFPOProc(SMLoc L);
1197 bool parseDirectiveFPOSetFrame(SMLoc L);
1198 bool parseDirectiveFPOPushReg(SMLoc L);
1199 bool parseDirectiveFPOStackAlloc(SMLoc L);
1200 bool parseDirectiveFPOStackAlign(SMLoc L);
1201 bool parseDirectiveFPOEndPrologue(SMLoc L);
1202 bool parseDirectiveFPOEndProc(SMLoc L);
1205 bool parseSEHRegisterNumber(
unsigned RegClassID, MCRegister &RegNo);
1206 bool parseDirectiveSEHPushReg(SMLoc);
1207 bool parseDirectiveSEHSetFrame(SMLoc);
1208 bool parseDirectiveSEHSaveReg(SMLoc);
1209 bool parseDirectiveSEHSaveXMM(SMLoc);
1210 bool parseDirectiveSEHPushFrame(SMLoc);
1212 unsigned checkTargetMatchPredicate(MCInst &Inst)
override;
1218 void emitWarningForSpecialLVIInstruction(SMLoc Loc);
1219 void applyLVICFIMitigation(MCInst &Inst, MCStreamer &Out);
1220 void applyLVILoadHardeningMitigation(MCInst &Inst, MCStreamer &Out);
1226 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1228 uint64_t &ErrorInfo,
1229 bool MatchingInlineAsm)
override;
1231 void MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &
Op,
OperandVector &Operands,
1232 MCStreamer &Out,
bool MatchingInlineAsm);
1234 bool ErrorMissingFeature(SMLoc IDLoc,
const FeatureBitset &MissingFeatures,
1235 bool MatchingInlineAsm);
1237 bool matchAndEmitATTInstruction(SMLoc IDLoc,
unsigned &Opcode, MCInst &Inst,
1239 uint64_t &ErrorInfo,
bool MatchingInlineAsm);
1241 bool matchAndEmitIntelInstruction(SMLoc IDLoc,
unsigned &Opcode, MCInst &Inst,
1243 uint64_t &ErrorInfo,
1244 bool MatchingInlineAsm);
1246 bool omitRegisterFromClobberLists(MCRegister
Reg)
override;
1253 bool ParseZ(std::unique_ptr<X86Operand> &Z, SMLoc StartLoc);
1255 bool is64BitMode()
const {
1257 return getSTI().hasFeature(X86::Is64Bit);
1259 bool is32BitMode()
const {
1261 return getSTI().hasFeature(X86::Is32Bit);
1263 bool is16BitMode()
const {
1265 return getSTI().hasFeature(X86::Is16Bit);
1267 void SwitchMode(
unsigned mode) {
1268 MCSubtargetInfo &STI = copySTI();
1269 FeatureBitset AllModes({X86::Is64Bit, X86::Is32Bit, X86::Is16Bit});
1271 FeatureBitset FB = ComputeAvailableFeatures(
1273 setAvailableFeatures(FB);
1278 unsigned getPointerWidth() {
1279 if (is16BitMode())
return 16;
1280 if (is32BitMode())
return 32;
1281 if (is64BitMode())
return 64;
1285 bool isParsingIntelSyntax() {
1286 return getParser().getAssemblerDialect();
1292#define GET_ASSEMBLER_HEADER
1293#include "X86GenAsmMatcher.inc"
1298 enum X86MatchResultTy {
1299 Match_Unsupported = FIRST_TARGET_MATCH_RESULT_TY,
1300#define GET_OPERAND_DIAGNOSTIC_TYPES
1301#include "X86GenAsmMatcher.inc"
1304 X86AsmParser(
const MCSubtargetInfo &sti, MCAsmParser &Parser,
1305 const MCInstrInfo &mii,
const MCTargetOptions &
Options)
1306 : MCTargetAsmParser(
Options, sti, mii), InstInfo(nullptr),
1312 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
1315 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
1316 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1317 SMLoc &EndLoc)
override;
1319 bool parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc)
override;
1321 bool parseInstruction(ParseInstructionInfo &
Info, StringRef Name,
1324 bool ParseDirective(AsmToken DirectiveID)
override;
1328#define GET_REGISTER_MATCHER
1329#define GET_SUBTARGET_FEATURE_NAME
1330#include "X86GenAsmMatcher.inc"
1341 !(BaseReg == X86::RIP || BaseReg == X86::EIP ||
1342 X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg) ||
1343 X86MCRegisterClasses[X86::GR32RegClassID].
contains(BaseReg) ||
1344 X86MCRegisterClasses[X86::GR64RegClassID].
contains(BaseReg))) {
1345 ErrMsg =
"invalid base+index expression";
1350 !(IndexReg == X86::EIZ || IndexReg == X86::RIZ ||
1351 X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg) ||
1352 X86MCRegisterClasses[X86::GR32RegClassID].
contains(IndexReg) ||
1353 X86MCRegisterClasses[X86::GR64RegClassID].
contains(IndexReg) ||
1354 X86MCRegisterClasses[X86::VR128XRegClassID].
contains(IndexReg) ||
1355 X86MCRegisterClasses[X86::VR256XRegClassID].
contains(IndexReg) ||
1356 X86MCRegisterClasses[X86::VR512RegClassID].
contains(IndexReg))) {
1357 ErrMsg =
"invalid base+index expression";
1361 if (((BaseReg == X86::RIP || BaseReg == X86::EIP) && IndexReg) ||
1362 IndexReg == X86::EIP || IndexReg == X86::RIP || IndexReg == X86::ESP ||
1363 IndexReg == X86::RSP) {
1364 ErrMsg =
"invalid base+index expression";
1370 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg) &&
1371 (Is64BitMode || (BaseReg != X86::BX && BaseReg != X86::BP &&
1372 BaseReg != X86::SI && BaseReg != X86::DI))) {
1373 ErrMsg =
"invalid 16-bit base register";
1378 X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg)) {
1379 ErrMsg =
"16-bit memory operand may not include only index register";
1383 if (BaseReg && IndexReg) {
1384 if (X86MCRegisterClasses[X86::GR64RegClassID].
contains(BaseReg) &&
1385 (X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg) ||
1386 X86MCRegisterClasses[X86::GR32RegClassID].
contains(IndexReg) ||
1387 IndexReg == X86::EIZ)) {
1388 ErrMsg =
"base register is 64-bit, but index register is not";
1391 if (X86MCRegisterClasses[X86::GR32RegClassID].
contains(BaseReg) &&
1392 (X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg) ||
1393 X86MCRegisterClasses[X86::GR64RegClassID].
contains(IndexReg) ||
1394 IndexReg == X86::RIZ)) {
1395 ErrMsg =
"base register is 32-bit, but index register is not";
1398 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg)) {
1399 if (X86MCRegisterClasses[X86::GR32RegClassID].
contains(IndexReg) ||
1400 X86MCRegisterClasses[X86::GR64RegClassID].
contains(IndexReg)) {
1401 ErrMsg =
"base register is 16-bit, but index register is not";
1404 if ((BaseReg != X86::BX && BaseReg != X86::BP) ||
1405 (IndexReg != X86::SI && IndexReg != X86::DI)) {
1406 ErrMsg =
"invalid 16-bit base/index register combination";
1413 if (!Is64BitMode && (BaseReg == X86::RIP || BaseReg == X86::EIP)) {
1414 ErrMsg =
"IP-relative addressing requires 64-bit mode";
1435 if (isParsingMSInlineAsm() && isParsingIntelSyntax() &&
1436 (RegNo == X86::EFLAGS || RegNo == X86::MXCSR))
1437 RegNo = MCRegister();
1439 if (!is64BitMode()) {
1443 if (RegNo == X86::RIZ || RegNo == X86::RIP ||
1444 X86MCRegisterClasses[X86::GR64RegClassID].
contains(RegNo) ||
1447 return Error(StartLoc,
1448 "register %" +
RegName +
" is only available in 64-bit mode",
1449 SMRange(StartLoc, EndLoc));
1454 UseApxExtendedReg =
true;
1458 if (!RegNo &&
RegName.starts_with(
"db")) {
1517 if (isParsingIntelSyntax())
1519 return Error(StartLoc,
"invalid register name", SMRange(StartLoc, EndLoc));
1524bool X86AsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
1525 SMLoc &EndLoc,
bool RestoreOnFailure) {
1526 MCAsmParser &Parser = getParser();
1527 AsmLexer &Lexer = getLexer();
1528 RegNo = MCRegister();
1531 auto OnFailure = [RestoreOnFailure, &Lexer, &Tokens]() {
1532 if (RestoreOnFailure) {
1533 while (!Tokens.
empty()) {
1539 const AsmToken &PercentTok = Parser.
getTok();
1540 StartLoc = PercentTok.
getLoc();
1549 const AsmToken &Tok = Parser.
getTok();
1554 if (isParsingIntelSyntax())
return true;
1555 return Error(StartLoc,
"invalid register name",
1556 SMRange(StartLoc, EndLoc));
1559 if (MatchRegisterByName(RegNo, Tok.
getString(), StartLoc, EndLoc)) {
1565 if (RegNo == X86::ST0) {
1576 const AsmToken &IntTok = Parser.
getTok();
1579 return Error(IntTok.
getLoc(),
"expected stack index");
1582 case 0: RegNo = X86::ST0;
break;
1583 case 1: RegNo = X86::ST1;
break;
1584 case 2: RegNo = X86::ST2;
break;
1585 case 3: RegNo = X86::ST3;
break;
1586 case 4: RegNo = X86::ST4;
break;
1587 case 5: RegNo = X86::ST5;
break;
1588 case 6: RegNo = X86::ST6;
break;
1589 case 7: RegNo = X86::ST7;
break;
1592 return Error(IntTok.
getLoc(),
"invalid stack index");
1612 if (isParsingIntelSyntax())
return true;
1613 return Error(StartLoc,
"invalid register name",
1614 SMRange(StartLoc, EndLoc));
1621bool X86AsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1623 return ParseRegister(
Reg, StartLoc, EndLoc,
false);
1626ParseStatus X86AsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1628 bool Result = ParseRegister(
Reg, StartLoc, EndLoc,
true);
1629 bool PendingErrors = getParser().hasPendingError();
1630 getParser().clearPendingErrors();
1638std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(SMLoc Loc) {
1639 bool Parse32 = is32BitMode() || Code16GCC;
1640 MCRegister Basereg =
1641 is64BitMode() ? X86::RSI : (Parse32 ? X86::ESI : X86::SI);
1648std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand(SMLoc Loc) {
1649 bool Parse32 = is32BitMode() || Code16GCC;
1650 MCRegister Basereg =
1651 is64BitMode() ? X86::RDI : (Parse32 ? X86::EDI : X86::DI);
1658bool X86AsmParser::IsSIReg(MCRegister
Reg) {
1672MCRegister X86AsmParser::GetSIDIForRegClass(
unsigned RegClassID,
bool IsSIReg) {
1673 switch (RegClassID) {
1675 case X86::GR64RegClassID:
1676 return IsSIReg ? X86::RSI : X86::RDI;
1677 case X86::GR32RegClassID:
1678 return IsSIReg ? X86::ESI : X86::EDI;
1679 case X86::GR16RegClassID:
1680 return IsSIReg ? X86::SI : X86::DI;
1684void X86AsmParser::AddDefaultSrcDestOperands(
1685 OperandVector& Operands, std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
1686 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst) {
1687 if (isParsingIntelSyntax()) {
1697bool X86AsmParser::VerifyAndAdjustOperands(
OperandVector &OrigOperands,
1700 if (OrigOperands.
size() > 1) {
1703 "Operand size mismatch");
1707 int RegClassID = -1;
1708 for (
unsigned int i = 0; i < FinalOperands.
size(); ++i) {
1709 X86Operand &OrigOp =
static_cast<X86Operand &
>(*OrigOperands[i + 1]);
1710 X86Operand &FinalOp =
static_cast<X86Operand &
>(*FinalOperands[i]);
1712 if (FinalOp.
isReg() &&
1717 if (FinalOp.
isMem()) {
1719 if (!OrigOp.
isMem())
1728 if (RegClassID != -1 &&
1729 !X86MCRegisterClasses[RegClassID].
contains(OrigReg)) {
1731 "mismatching source and destination index registers");
1734 if (X86MCRegisterClasses[X86::GR64RegClassID].
contains(OrigReg))
1735 RegClassID = X86::GR64RegClassID;
1736 else if (X86MCRegisterClasses[X86::GR32RegClassID].
contains(OrigReg))
1737 RegClassID = X86::GR32RegClassID;
1738 else if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(OrigReg))
1739 RegClassID = X86::GR16RegClassID;
1745 bool IsSI = IsSIReg(FinalReg);
1746 FinalReg = GetSIDIForRegClass(RegClassID, IsSI);
1748 if (FinalReg != OrigReg) {
1749 std::string
RegName = IsSI ?
"ES:(R|E)SI" :
"ES:(R|E)DI";
1752 "memory operand is only for determining the size, " +
RegName +
1753 " will be used for the location"));
1764 for (
auto &WarningMsg : Warnings) {
1765 Warning(WarningMsg.first, WarningMsg.second);
1769 for (
unsigned int i = 0; i < FinalOperands.
size(); ++i)
1773 for (
auto &
Op : FinalOperands)
1779bool X86AsmParser::parseOperand(
OperandVector &Operands, StringRef Name) {
1780 if (isParsingIntelSyntax())
1781 return parseIntelOperand(Operands, Name);
1783 return parseATTOperand(Operands);
1786bool X86AsmParser::CreateMemForMSInlineAsm(
1787 MCRegister SegReg,
const MCExpr *Disp, MCRegister BaseReg,
1788 MCRegister IndexReg,
unsigned Scale,
bool NonAbsMem, SMLoc Start, SMLoc End,
1789 unsigned Size, StringRef Identifier,
const InlineAsmIdentifierInfo &
Info,
1797 End,
Size, Identifier,
1804 unsigned FrontendSize = 0;
1805 void *Decl =
nullptr;
1806 bool IsGlobalLV =
false;
1809 FrontendSize =
Info.Var.Type * 8;
1810 Decl =
Info.Var.Decl;
1811 IsGlobalLV =
Info.Var.IsGlobalLV;
1816 if (BaseReg || IndexReg) {
1818 End,
Size, Identifier, Decl, 0,
1819 BaseReg && IndexReg));
1826 getPointerWidth(), SegReg, Disp, BaseReg, IndexReg, Scale, Start, End,
1828 X86::RIP, Identifier, Decl, FrontendSize));
1835bool X86AsmParser::ParseIntelNamedOperator(StringRef Name,
1836 IntelExprStateMachine &SM,
1837 bool &ParseError, SMLoc &End) {
1840 if (Name !=
Name.lower() && Name !=
Name.upper() &&
1841 !getParser().isParsingMasm())
1843 if (
Name.equals_insensitive(
"not")) {
1845 }
else if (
Name.equals_insensitive(
"or")) {
1847 }
else if (
Name.equals_insensitive(
"shl")) {
1849 }
else if (
Name.equals_insensitive(
"shr")) {
1851 }
else if (
Name.equals_insensitive(
"xor")) {
1853 }
else if (
Name.equals_insensitive(
"and")) {
1855 }
else if (
Name.equals_insensitive(
"mod")) {
1857 }
else if (
Name.equals_insensitive(
"offset")) {
1858 SMLoc OffsetLoc = getTok().getLoc();
1859 const MCExpr *Val =
nullptr;
1861 InlineAsmIdentifierInfo
Info;
1867 SM.onOffset(Val, OffsetLoc,
ID,
Info, isParsingMSInlineAsm(), ErrMsg);
1873 if (!
Name.equals_insensitive(
"offset"))
1874 End = consumeToken();
1877bool X86AsmParser::ParseMasmNamedOperator(StringRef Name,
1878 IntelExprStateMachine &SM,
1879 bool &ParseError, SMLoc &End) {
1880 if (
Name.equals_insensitive(
"eq")) {
1882 }
else if (
Name.equals_insensitive(
"ne")) {
1884 }
else if (
Name.equals_insensitive(
"lt")) {
1886 }
else if (
Name.equals_insensitive(
"le")) {
1888 }
else if (
Name.equals_insensitive(
"gt")) {
1890 }
else if (
Name.equals_insensitive(
"ge")) {
1895 End = consumeToken();
1902 IntelExprStateMachine &SM) {
1906 SM.setAppendAfterOperand();
1909bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
1910 MCAsmParser &Parser = getParser();
1915 if (
getContext().getObjectFileInfo()->isPositionIndependent())
1922 const AsmToken &Tok = Parser.
getTok();
1924 bool UpdateLocLex =
true;
1929 if ((
Done = SM.isValidEndState()))
1931 return Error(Tok.
getLoc(),
"unknown token in expression");
1933 return Error(getLexer().getErrLoc(), getLexer().getErr());
1937 UpdateLocLex =
false;
1938 if (ParseIntelDotOperator(SM, End))
1943 if ((
Done = SM.isValidEndState()))
1945 return Error(Tok.
getLoc(),
"unknown token in expression");
1949 UpdateLocLex =
false;
1950 if (ParseIntelDotOperator(SM, End))
1955 if ((
Done = SM.isValidEndState()))
1957 return Error(Tok.
getLoc(),
"unknown token in expression");
1963 SMLoc ValueLoc = Tok.
getLoc();
1968 UpdateLocLex =
false;
1969 if (!Val->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
1970 return Error(ValueLoc,
"expected absolute value");
1971 if (SM.onInteger(Res, ErrMsg))
1972 return Error(ValueLoc, ErrMsg);
1979 SMLoc IdentLoc = Tok.
getLoc();
1981 UpdateLocLex =
false;
1983 size_t DotOffset =
Identifier.find_first_of(
'.');
1987 StringRef Dot =
Identifier.substr(DotOffset, 1);
2001 const AsmToken &NextTok = getLexer().peekTok();
2010 End = consumeToken();
2017 if (!ParseRegister(
Reg, IdentLoc, End,
true)) {
2018 if (SM.onRegister(
Reg, ErrMsg))
2019 return Error(IdentLoc, ErrMsg);
2023 const std::pair<StringRef, StringRef> IDField =
2025 const StringRef
ID = IDField.first,
Field = IDField.second;
2027 if (!
Field.empty() &&
2028 !MatchRegisterByName(
Reg,
ID, IdentLoc, IDEndLoc)) {
2029 if (SM.onRegister(
Reg, ErrMsg))
2030 return Error(IdentLoc, ErrMsg);
2035 return Error(FieldStartLoc,
"unknown offset");
2036 else if (SM.onPlus(ErrMsg))
2037 return Error(getTok().getLoc(), ErrMsg);
2038 else if (SM.onInteger(
Info.Offset, ErrMsg))
2039 return Error(IdentLoc, ErrMsg);
2040 SM.setTypeInfo(
Info.Type);
2042 End = consumeToken();
2049 if (ParseIntelNamedOperator(Identifier, SM, ParseError, End)) {
2055 ParseMasmNamedOperator(Identifier, SM, ParseError, End)) {
2061 InlineAsmIdentifierInfo
Info;
2062 AsmFieldInfo FieldInfo;
2068 if (ParseIntelDotOperator(SM, End))
2073 if (isParsingMSInlineAsm()) {
2075 if (
unsigned OpKind = IdentifyIntelInlineAsmOperator(Identifier)) {
2076 if (int64_t Val = ParseIntelInlineAsmOperator(OpKind)) {
2077 if (SM.onInteger(Val, ErrMsg))
2078 return Error(IdentLoc, ErrMsg);
2087 return Error(IdentLoc,
"expected identifier");
2088 if (ParseIntelInlineAsmIdentifier(Val, Identifier,
Info,
false, End))
2090 else if (SM.onIdentifierExpr(Val, Identifier,
Info, FieldInfo.
Type,
2092 return Error(IdentLoc, ErrMsg);
2096 if (
unsigned OpKind = IdentifyMasmOperator(Identifier)) {
2098 if (ParseMasmOperator(OpKind, Val))
2100 if (SM.onInteger(Val, ErrMsg))
2101 return Error(IdentLoc, ErrMsg);
2104 if (!getParser().lookUpType(Identifier, FieldInfo.
Type)) {
2110 getParser().parseIdentifier(Identifier);
2114 if (getParser().lookUpField(FieldInfo.
Type.
Name, Identifier,
2118 return Error(IdentLoc,
"Unable to lookup field reference!",
2119 SMRange(IdentLoc, IDEnd));
2124 if (SM.onInteger(FieldInfo.
Offset, ErrMsg))
2125 return Error(IdentLoc, ErrMsg);
2129 if (getParser().parsePrimaryExpr(Val, End, &FieldInfo.
Type)) {
2130 return Error(Tok.
getLoc(),
"Unexpected identifier!");
2131 }
else if (SM.onIdentifierExpr(Val, Identifier,
Info, FieldInfo.
Type,
2133 return Error(IdentLoc, ErrMsg);
2139 SMLoc Loc = getTok().getLoc();
2140 int64_t
IntVal = getTok().getIntVal();
2141 End = consumeToken();
2142 UpdateLocLex =
false;
2144 StringRef IDVal = getTok().getString();
2145 if (IDVal ==
"f" || IDVal ==
"b") {
2147 getContext().getDirectionalLocalSymbol(IntVal, IDVal ==
"b");
2152 return Error(Loc,
"invalid reference to undefined symbol");
2154 InlineAsmIdentifierInfo
Info;
2156 if (SM.onIdentifierExpr(Val, Identifier,
Info,
Type,
2157 isParsingMSInlineAsm(), ErrMsg))
2158 return Error(Loc, ErrMsg);
2159 End = consumeToken();
2161 if (SM.onInteger(IntVal, ErrMsg))
2162 return Error(Loc, ErrMsg);
2165 if (SM.onInteger(IntVal, ErrMsg))
2166 return Error(Loc, ErrMsg);
2171 if (SM.onPlus(ErrMsg))
2172 return Error(getTok().getLoc(), ErrMsg);
2175 if (SM.onMinus(ErrMsg))
2176 return Error(getTok().getLoc(), ErrMsg);
2186 SM.onLShift();
break;
2188 SM.onRShift();
break;
2191 return Error(Tok.
getLoc(),
"unexpected bracket encountered");
2192 tryParseOperandIdx(PrevTK, SM);
2195 if (SM.onRBrac(ErrMsg)) {
2201 if (SM.onRParen(ErrMsg)) {
2207 return Error(Tok.
getLoc(),
"unknown token in expression");
2209 if (!
Done && UpdateLocLex)
2210 End = consumeToken();
2217void X86AsmParser::RewriteIntelExpression(IntelExprStateMachine &SM,
2218 SMLoc Start, SMLoc End) {
2222 if (SM.getSym() && !SM.isOffsetOperator()) {
2223 StringRef SymName = SM.getSymName();
2224 if (
unsigned Len = SymName.
data() -
Start.getPointer())
2230 if (!(SM.getBaseReg() || SM.getIndexReg() || SM.getImm())) {
2237 StringRef BaseRegStr;
2238 StringRef IndexRegStr;
2239 StringRef OffsetNameStr;
2240 if (SM.getBaseReg())
2242 if (SM.getIndexReg())
2244 if (SM.isOffsetOperator())
2245 OffsetNameStr = SM.getSymName();
2247 IntelExpr Expr(BaseRegStr, IndexRegStr, SM.getScale(), OffsetNameStr,
2248 SM.getImm(), SM.isMemExpr());
2249 InstInfo->
AsmRewrites->emplace_back(Loc, ExprLen, Expr);
2253bool X86AsmParser::ParseIntelInlineAsmIdentifier(
2254 const MCExpr *&Val, StringRef &Identifier, InlineAsmIdentifierInfo &
Info,
2255 bool IsUnevaluatedOperand, SMLoc &End,
bool IsParsingOffsetOperator) {
2256 MCAsmParser &Parser = getParser();
2257 assert(isParsingMSInlineAsm() &&
"Expected to be parsing inline assembly.");
2261 SemaCallback->LookupInlineAsmIdentifier(LineBuf,
Info, IsUnevaluatedOperand);
2263 const AsmToken &Tok = Parser.
getTok();
2264 SMLoc Loc = Tok.
getLoc();
2279 "frontend claimed part of a token?");
2284 StringRef InternalName =
2285 SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(),
2287 assert(InternalName.
size() &&
"We should have an internal name here.");
2290 if (!IsParsingOffsetOperator)
2305bool X86AsmParser::ParseRoundingModeOp(SMLoc Start,
OperandVector &Operands) {
2306 MCAsmParser &Parser = getParser();
2307 const AsmToken &Tok = Parser.
getTok();
2309 const SMLoc consumedToken = consumeToken();
2311 return Error(Tok.
getLoc(),
"Expected an identifier after {");
2314 .Case(
"rn", X86::STATIC_ROUNDING::TO_NEAREST_INT)
2315 .Case(
"rd", X86::STATIC_ROUNDING::TO_NEG_INF)
2316 .Case(
"ru", X86::STATIC_ROUNDING::TO_POS_INF)
2317 .Case(
"rz", X86::STATIC_ROUNDING::TO_ZERO)
2320 return Error(Tok.
getLoc(),
"Invalid rounding mode.");
2323 return Error(Tok.
getLoc(),
"Expected - at this point");
2327 return Error(Tok.
getLoc(),
"Expected } at this point");
2330 const MCExpr *RndModeOp =
2338 return Error(Tok.
getLoc(),
"Expected } at this point");
2343 return Error(Tok.
getLoc(),
"unknown token in expression");
2349 MCAsmParser &Parser = getParser();
2350 AsmToken Tok = Parser.
getTok();
2353 return Error(Tok.
getLoc(),
"Expected { at this point");
2357 return Error(Tok.
getLoc(),
"Expected dfv at this point");
2361 return Error(Tok.
getLoc(),
"Expected = at this point");
2373 unsigned CFlags = 0;
2374 for (
unsigned I = 0;
I < 4; ++
I) {
2383 return Error(Tok.
getLoc(),
"Invalid conditional flags");
2386 return Error(Tok.
getLoc(),
"Duplicated conditional flag");
2397 }
else if (
I == 3) {
2398 return Error(Tok.
getLoc(),
"Expected } at this point");
2400 return Error(Tok.
getLoc(),
"Expected } or , at this point");
2408bool X86AsmParser::ParseIntelDotOperator(IntelExprStateMachine &SM,
2410 const AsmToken &Tok = getTok();
2416 bool TrailingDot =
false;
2424 }
else if ((isParsingMSInlineAsm() || getParser().isParsingMasm()) &&
2427 const std::pair<StringRef, StringRef> BaseMember = DotDispStr.
split(
'.');
2428 const StringRef
Base = BaseMember.first,
Member = BaseMember.second;
2429 if (getParser().lookUpField(SM.getType(), DotDispStr,
Info) &&
2430 getParser().lookUpField(SM.getSymName(), DotDispStr,
Info) &&
2431 getParser().lookUpField(DotDispStr,
Info) &&
2433 SemaCallback->LookupInlineAsmField(
Base, Member,
Info.Offset)))
2434 return Error(Tok.
getLoc(),
"Unable to lookup field reference!");
2436 return Error(Tok.
getLoc(),
"Unexpected token type!");
2441 const char *DotExprEndLoc = DotDispStr.
data() + DotDispStr.
size();
2446 SM.addImm(
Info.Offset);
2447 SM.setTypeInfo(
Info.Type);
2453bool X86AsmParser::ParseIntelOffsetOperator(
const MCExpr *&Val, StringRef &
ID,
2454 InlineAsmIdentifierInfo &
Info,
2457 SMLoc
Start = Lex().getLoc();
2458 ID = getTok().getString();
2459 if (!isParsingMSInlineAsm()) {
2462 getParser().parsePrimaryExpr(Val, End,
nullptr))
2463 return Error(Start,
"unexpected token!");
2464 }
else if (ParseIntelInlineAsmIdentifier(Val,
ID,
Info,
false, End,
true)) {
2465 return Error(Start,
"unable to lookup expression");
2467 return Error(Start,
"offset operator cannot yet handle constants");
2474unsigned X86AsmParser::IdentifyIntelInlineAsmOperator(StringRef Name) {
2475 return StringSwitch<unsigned>(Name)
2476 .Cases({
"TYPE",
"type"}, IOK_TYPE)
2477 .Cases({
"SIZE",
"size"}, IOK_SIZE)
2478 .Cases({
"LENGTH",
"length"}, IOK_LENGTH)
2488unsigned X86AsmParser::ParseIntelInlineAsmOperator(
unsigned OpKind) {
2489 MCAsmParser &Parser = getParser();
2490 const AsmToken &Tok = Parser.
getTok();
2493 const MCExpr *Val =
nullptr;
2494 InlineAsmIdentifierInfo
Info;
2497 if (ParseIntelInlineAsmIdentifier(Val, Identifier,
Info,
2502 Error(Start,
"unable to lookup expression");
2509 case IOK_LENGTH: CVal =
Info.Var.Length;
break;
2510 case IOK_SIZE: CVal =
Info.Var.Size;
break;
2511 case IOK_TYPE: CVal =
Info.Var.Type;
break;
2519unsigned X86AsmParser::IdentifyMasmOperator(StringRef Name) {
2520 return StringSwitch<unsigned>(
Name.lower())
2521 .Case(
"type", MOK_TYPE)
2522 .Cases({
"size",
"sizeof"}, MOK_SIZEOF)
2523 .Cases({
"length",
"lengthof"}, MOK_LENGTHOF)
2533bool X86AsmParser::ParseMasmOperator(
unsigned OpKind, int64_t &Val) {
2534 MCAsmParser &Parser = getParser();
2539 if (OpKind == MOK_SIZEOF || OpKind == MOK_TYPE) {
2542 const AsmToken &IDTok = InParens ? getLexer().peekTok() : Parser.
getTok();
2558 IntelExprStateMachine SM;
2560 if (ParseIntelExpression(SM, End))
2570 Val = SM.getLength();
2573 Val = SM.getElementSize();
2578 return Error(OpLoc,
"expression has unknown type", SMRange(Start, End));
2584bool X86AsmParser::ParseIntelMemoryOperandSize(
unsigned &
Size,
2585 StringRef *SizeStr) {
2586 Size = StringSwitch<unsigned>(getTok().getString())
2587 .Cases({
"BYTE",
"byte"}, 8)
2588 .Cases({
"WORD",
"word"}, 16)
2589 .Cases({
"DWORD",
"dword"}, 32)
2590 .Cases({
"FLOAT",
"float"}, 32)
2591 .Cases({
"LONG",
"long"}, 32)
2592 .Cases({
"FWORD",
"fword"}, 48)
2593 .Cases({
"DOUBLE",
"double"}, 64)
2594 .Cases({
"QWORD",
"qword"}, 64)
2595 .Cases({
"MMWORD",
"mmword"}, 64)
2596 .Cases({
"XWORD",
"xword"}, 80)
2597 .Cases({
"TBYTE",
"tbyte"}, 80)
2598 .Cases({
"XMMWORD",
"xmmword"}, 128)
2599 .Cases({
"YMMWORD",
"ymmword"}, 256)
2600 .Cases({
"ZMMWORD",
"zmmword"}, 512)
2604 *SizeStr = getTok().getString();
2605 const AsmToken &Tok = Lex();
2607 return Error(Tok.
getLoc(),
"Expected 'PTR' or 'ptr' token!");
2614 if (X86MCRegisterClasses[X86::GR8RegClassID].
contains(RegNo))
2616 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(RegNo))
2618 if (X86MCRegisterClasses[X86::GR32RegClassID].
contains(RegNo))
2620 if (X86MCRegisterClasses[X86::GR64RegClassID].
contains(RegNo))
2626bool X86AsmParser::parseIntelOperand(
OperandVector &Operands, StringRef Name) {
2627 MCAsmParser &Parser = getParser();
2628 const AsmToken &Tok = Parser.
getTok();
2634 if (ParseIntelMemoryOperandSize(
Size, &SizeStr))
2636 bool PtrInOperand = bool(
Size);
2642 return ParseRoundingModeOp(Start, Operands);
2647 if (RegNo == X86::RIP)
2648 return Error(Start,
"rip can only be used as a base register");
2653 return Error(Start,
"expected memory operand after 'ptr', "
2654 "found register operand instead");
2663 "cannot cast register '" +
2665 "'; its size is not easily defined.");
2669 std::to_string(
RegSize) +
"-bit register '" +
2671 "' cannot be used as a " + std::to_string(
Size) +
"-bit " +
2678 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].
contains(RegNo))
2679 return Error(Start,
"invalid segment register");
2681 Start = Lex().getLoc();
2685 IntelExprStateMachine SM;
2686 if (ParseIntelExpression(SM, End))
2689 if (isParsingMSInlineAsm())
2690 RewriteIntelExpression(SM, Start, Tok.
getLoc());
2692 int64_t
Imm = SM.getImm();
2693 const MCExpr *Disp = SM.getSym();
2702 if (!SM.isMemExpr() && !RegNo) {
2703 if (isParsingMSInlineAsm() && SM.isOffsetOperator()) {
2704 const InlineAsmIdentifierInfo &
Info = SM.getIdentifierInfo();
2709 SM.getSymName(),
Info.Var.Decl,
2710 Info.Var.IsGlobalLV));
2720 MCRegister
BaseReg = SM.getBaseReg();
2721 MCRegister IndexReg = SM.getIndexReg();
2722 if (IndexReg && BaseReg == X86::RIP)
2724 unsigned Scale = SM.getScale();
2726 Size = SM.getElementSize() << 3;
2728 if (Scale == 0 && BaseReg != X86::ESP && BaseReg != X86::RSP &&
2729 (IndexReg == X86::ESP || IndexReg == X86::RSP))
2735 !(X86MCRegisterClasses[X86::VR128XRegClassID].
contains(IndexReg) ||
2736 X86MCRegisterClasses[X86::VR256XRegClassID].
contains(IndexReg) ||
2737 X86MCRegisterClasses[X86::VR512RegClassID].
contains(IndexReg)) &&
2738 (X86MCRegisterClasses[X86::VR128XRegClassID].
contains(BaseReg) ||
2739 X86MCRegisterClasses[X86::VR256XRegClassID].
contains(BaseReg) ||
2740 X86MCRegisterClasses[X86::VR512RegClassID].
contains(BaseReg)))
2744 X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg))
2745 return Error(Start,
"16-bit addresses cannot have a scale");
2754 if ((BaseReg == X86::SI || BaseReg == X86::DI) &&
2755 (IndexReg == X86::BX || IndexReg == X86::BP))
2758 if ((BaseReg || IndexReg) &&
2761 return Error(Start, ErrMsg);
2762 bool IsUnconditionalBranch =
2763 Name.equals_insensitive(
"jmp") ||
Name.equals_insensitive(
"call");
2764 if (isParsingMSInlineAsm())
2765 return CreateMemForMSInlineAsm(RegNo, Disp, BaseReg, IndexReg, Scale,
2766 IsUnconditionalBranch && is64BitMode(),
2767 Start, End,
Size, SM.getSymName(),
2768 SM.getIdentifierInfo(), Operands);
2772 MCRegister DefaultBaseReg;
2773 bool MaybeDirectBranchDest =
true;
2776 if (is64BitMode() &&
2777 ((PtrInOperand && !IndexReg) || SM.getElementSize() > 0)) {
2778 DefaultBaseReg = X86::RIP;
2780 if (IsUnconditionalBranch) {
2782 MaybeDirectBranchDest =
false;
2784 DefaultBaseReg = X86::RIP;
2785 }
else if (!BaseReg && !IndexReg && Disp &&
2787 if (is64BitMode()) {
2788 if (SM.getSize() == 8) {
2789 MaybeDirectBranchDest =
false;
2790 DefaultBaseReg = X86::RIP;
2793 if (SM.getSize() == 4 || SM.getSize() == 2)
2794 MaybeDirectBranchDest =
false;
2798 }
else if (IsUnconditionalBranch) {
2800 if (!PtrInOperand && SM.isOffsetOperator())
2802 Start,
"`OFFSET` operator cannot be used in an unconditional branch");
2803 if (PtrInOperand || SM.isBracketUsed())
2804 MaybeDirectBranchDest =
false;
2807 if (CheckDispOverflow(BaseReg, IndexReg, Disp, Start))
2810 if ((BaseReg || IndexReg || RegNo || DefaultBaseReg))
2812 getPointerWidth(), RegNo, Disp, BaseReg, IndexReg, Scale, Start, End,
2813 Size, DefaultBaseReg, StringRef(),
nullptr,
2814 0,
false, MaybeDirectBranchDest));
2817 getPointerWidth(), Disp, Start, End,
Size, StringRef(),
2819 MaybeDirectBranchDest));
2823bool X86AsmParser::parseATTOperand(
OperandVector &Operands) {
2824 MCAsmParser &Parser = getParser();
2825 switch (getLexer().getKind()) {
2835 "expected immediate expression") ||
2836 getParser().parseExpression(Val, End) ||
2844 return ParseRoundingModeOp(Start, Operands);
2853 const MCExpr *Expr =
nullptr;
2865 if (
Reg == X86::EIZ ||
Reg == X86::RIZ)
2867 Loc,
"%eiz and %riz can only be used as index registers",
2868 SMRange(Loc, EndLoc));
2869 if (
Reg == X86::RIP)
2870 return Error(Loc,
"%rip can only be used as a base register",
2871 SMRange(Loc, EndLoc));
2877 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].
contains(
Reg))
2878 return Error(Loc,
"invalid segment register");
2886 return ParseMemOperand(
Reg, Expr, Loc, EndLoc, Operands);
2893X86::CondCode X86AsmParser::ParseConditionCode(StringRef CC) {
2894 return StringSwitch<X86::CondCode>(CC)
2916bool X86AsmParser::ParseZ(std::unique_ptr<X86Operand> &Z, SMLoc StartLoc) {
2917 MCAsmParser &Parser = getParser();
2922 (getLexer().getTok().getIdentifier() ==
"z")))
2927 return Error(getLexer().getLoc(),
"Expected } at this point");
2935bool X86AsmParser::HandleAVX512Operand(
OperandVector &Operands) {
2936 MCAsmParser &Parser = getParser();
2939 const SMLoc consumedToken = consumeToken();
2943 if (getLexer().getTok().getIntVal() != 1)
2944 return TokError(
"Expected 1to<NUM> at this point");
2945 StringRef
Prefix = getLexer().getTok().getString();
2948 return TokError(
"Expected 1to<NUM> at this point");
2951 StringRef BroadcastString = (
Prefix + getLexer().getTok().getIdentifier())
2954 return TokError(
"Expected 1to<NUM> at this point");
2955 const char *BroadcastPrimitive =
2956 StringSwitch<const char *>(BroadcastString)
2957 .Case(
"1to2",
"{1to2}")
2958 .Case(
"1to4",
"{1to4}")
2959 .Case(
"1to8",
"{1to8}")
2960 .Case(
"1to16",
"{1to16}")
2961 .Case(
"1to32",
"{1to32}")
2963 if (!BroadcastPrimitive)
2964 return TokError(
"Invalid memory broadcast primitive.");
2967 return TokError(
"Expected } at this point");
2978 std::unique_ptr<X86Operand>
Z;
2979 if (ParseZ(Z, consumedToken))
2985 SMLoc StartLoc =
Z ? consumeToken() : consumedToken;
2990 if (!parseRegister(RegNo, RegLoc, StartLoc) &&
2991 X86MCRegisterClasses[X86::VK1RegClassID].
contains(RegNo)) {
2992 if (RegNo == X86::K0)
2993 return Error(RegLoc,
"Register k0 can't be used as write mask");
2995 return Error(getLexer().getLoc(),
"Expected } at this point");
3001 return Error(getLexer().getLoc(),
3002 "Expected an op-mask register at this point");
3007 if (ParseZ(Z, consumeToken()) || !Z)
3008 return Error(getLexer().getLoc(),
3009 "Expected a {z} mark at this point");
3024bool X86AsmParser::CheckDispOverflow(MCRegister BaseReg, MCRegister IndexReg,
3025 const MCExpr *Disp, SMLoc Loc) {
3031 if (BaseReg || IndexReg) {
3033 auto Imm =
CE->getValue();
3034 bool Is64 = X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) ||
3035 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg);
3036 bool Is16 = X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg);
3039 return Error(Loc,
"displacement " + Twine(Imm) +
3040 " is not within [-2147483648, 2147483647]");
3042 if (!
isUInt<32>(Imm < 0 ? -uint64_t(Imm) : uint64_t(Imm))) {
3043 Warning(Loc,
"displacement " + Twine(Imm) +
3044 " shortened to 32-bit signed " +
3045 Twine(
static_cast<int32_t
>(Imm)));
3047 }
else if (!
isUInt<16>(Imm < 0 ? -uint64_t(Imm) : uint64_t(Imm))) {
3048 Warning(Loc,
"displacement " + Twine(Imm) +
3049 " shortened to 16-bit signed " +
3050 Twine(
static_cast<int16_t
>(Imm)));
3059bool X86AsmParser::ParseMemOperand(MCRegister SegReg,
const MCExpr *Disp,
3060 SMLoc StartLoc, SMLoc EndLoc,
3062 MCAsmParser &Parser = getParser();
3080 auto isAtMemOperand = [
this]() {
3085 auto TokCount = this->getLexer().peekTokens(Buf,
true);
3088 switch (Buf[0].getKind()) {
3095 if ((TokCount > 1) &&
3099 Buf[1].getIdentifier().
size() + 1);
3121 if (!isAtMemOperand()) {
3140 0, 0, 1, StartLoc, EndLoc));
3148 SMLoc BaseLoc = getLexer().getLoc();
3160 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ)
3161 return Error(BaseLoc,
"eiz and riz can only be used as index registers",
3162 SMRange(BaseLoc, EndLoc));
3180 if (!
E->evaluateAsAbsolute(ScaleVal, getStreamer().getAssemblerPtr()))
3181 return Error(Loc,
"expected absolute expression");
3183 Warning(Loc,
"scale factor without index register is ignored");
3188 if (BaseReg == X86::RIP)
3190 "%rip as base register can not have an index register");
3191 if (IndexReg == X86::RIP)
3192 return Error(Loc,
"%rip is not allowed as an index register");
3203 return Error(Loc,
"expected scale expression");
3204 Scale = (unsigned)ScaleVal;
3206 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg) &&
3208 return Error(Loc,
"scale factor in 16-bit address must be 1");
3210 return Error(Loc, ErrMsg);
3224 if (BaseReg == X86::DX && !IndexReg && Scale == 1 && !SegReg &&
3233 return Error(BaseLoc, ErrMsg);
3235 if (CheckDispOverflow(BaseReg, IndexReg, Disp, BaseLoc))
3238 if (SegReg || BaseReg || IndexReg)
3240 BaseReg, IndexReg, Scale, StartLoc,
3249bool X86AsmParser::parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
3250 MCAsmParser &Parser = getParser();
3257 if (parseRegister(RegNo, StartLoc, EndLoc))
3265bool X86AsmParser::parseInstruction(ParseInstructionInfo &
Info, StringRef Name,
3267 MCAsmParser &Parser = getParser();
3271 ForcedOpcodePrefix = OpcodePrefix_Default;
3272 ForcedDispEncoding = DispEncoding_Default;
3273 UseApxExtendedReg =
false;
3274 ForcedNoFlag =
false;
3287 if (Prefix ==
"rex")
3288 ForcedOpcodePrefix = OpcodePrefix_REX;
3289 else if (Prefix ==
"rex2")
3290 ForcedOpcodePrefix = OpcodePrefix_REX2;
3291 else if (Prefix ==
"vex")
3292 ForcedOpcodePrefix = OpcodePrefix_VEX;
3293 else if (Prefix ==
"vex2")
3294 ForcedOpcodePrefix = OpcodePrefix_VEX2;
3295 else if (Prefix ==
"vex3")
3296 ForcedOpcodePrefix = OpcodePrefix_VEX3;
3297 else if (Prefix ==
"evex")
3298 ForcedOpcodePrefix = OpcodePrefix_EVEX;
3299 else if (Prefix ==
"disp8")
3300 ForcedDispEncoding = DispEncoding_Disp8;
3301 else if (Prefix ==
"disp32")
3302 ForcedDispEncoding = DispEncoding_Disp32;
3303 else if (Prefix ==
"nf")
3304 ForcedNoFlag =
true;
3306 return Error(NameLoc,
"unknown prefix");
3322 if (isParsingMSInlineAsm()) {
3323 if (
Name.equals_insensitive(
"vex"))
3324 ForcedOpcodePrefix = OpcodePrefix_VEX;
3325 else if (
Name.equals_insensitive(
"vex2"))
3326 ForcedOpcodePrefix = OpcodePrefix_VEX2;
3327 else if (
Name.equals_insensitive(
"vex3"))
3328 ForcedOpcodePrefix = OpcodePrefix_VEX3;
3329 else if (
Name.equals_insensitive(
"evex"))
3330 ForcedOpcodePrefix = OpcodePrefix_EVEX;
3332 if (ForcedOpcodePrefix != OpcodePrefix_Default) {
3345 if (
Name.consume_back(
".d32")) {
3346 ForcedDispEncoding = DispEncoding_Disp32;
3347 }
else if (
Name.consume_back(
".d8")) {
3348 ForcedDispEncoding = DispEncoding_Disp8;
3351 StringRef PatchedName =
Name;
3354 if (isParsingIntelSyntax() &&
3355 (PatchedName ==
"jmp" || PatchedName ==
"jc" || PatchedName ==
"jnc" ||
3356 PatchedName ==
"jcxz" || PatchedName ==
"jecxz" ||
3361 : NextTok ==
"short") {
3370 NextTok.
size() + 1);
3376 PatchedName !=
"setzub" && PatchedName !=
"setzunb" &&
3377 PatchedName !=
"setb" && PatchedName !=
"setnb")
3378 PatchedName = PatchedName.
substr(0,
Name.size()-1);
3380 unsigned ComparisonPredicate = ~0
U;
3388 bool IsVCMP = PatchedName[0] ==
'v';
3389 unsigned CCIdx =
IsVCMP ? 4 : 3;
3390 unsigned suffixLength = PatchedName.
ends_with(
"bf16") ? 5 : 2;
3391 unsigned CC = StringSwitch<unsigned>(
3392 PatchedName.
slice(CCIdx, PatchedName.
size() - suffixLength))
3394 .Case(
"eq_oq", 0x00)
3396 .Case(
"lt_os", 0x01)
3398 .Case(
"le_os", 0x02)
3399 .Case(
"unord", 0x03)
3400 .Case(
"unord_q", 0x03)
3402 .Case(
"neq_uq", 0x04)
3404 .Case(
"nlt_us", 0x05)
3406 .Case(
"nle_us", 0x06)
3408 .Case(
"ord_q", 0x07)
3410 .Case(
"eq_uq", 0x08)
3412 .Case(
"nge_us", 0x09)
3414 .Case(
"ngt_us", 0x0A)
3415 .Case(
"false", 0x0B)
3416 .Case(
"false_oq", 0x0B)
3417 .Case(
"neq_oq", 0x0C)
3419 .Case(
"ge_os", 0x0D)
3421 .Case(
"gt_os", 0x0E)
3423 .Case(
"true_uq", 0x0F)
3424 .Case(
"eq_os", 0x10)
3425 .Case(
"lt_oq", 0x11)
3426 .Case(
"le_oq", 0x12)
3427 .Case(
"unord_s", 0x13)
3428 .Case(
"neq_us", 0x14)
3429 .Case(
"nlt_uq", 0x15)
3430 .Case(
"nle_uq", 0x16)
3431 .Case(
"ord_s", 0x17)
3432 .Case(
"eq_us", 0x18)
3433 .Case(
"nge_uq", 0x19)
3434 .Case(
"ngt_uq", 0x1A)
3435 .Case(
"false_os", 0x1B)
3436 .Case(
"neq_os", 0x1C)
3437 .Case(
"ge_oq", 0x1D)
3438 .Case(
"gt_oq", 0x1E)
3439 .Case(
"true_us", 0x1F)
3441 if (CC != ~0U && (
IsVCMP || CC < 8) &&
3444 PatchedName =
IsVCMP ?
"vcmpss" :
"cmpss";
3446 PatchedName =
IsVCMP ?
"vcmpsd" :
"cmpsd";
3448 PatchedName =
IsVCMP ?
"vcmpps" :
"cmpps";
3450 PatchedName =
IsVCMP ?
"vcmppd" :
"cmppd";
3452 PatchedName =
"vcmpsh";
3454 PatchedName =
"vcmpph";
3456 PatchedName =
"vcmpbf16";
3460 ComparisonPredicate = CC;
3466 (PatchedName.
back() ==
'b' || PatchedName.
back() ==
'w' ||
3467 PatchedName.
back() ==
'd' || PatchedName.
back() ==
'q')) {
3468 unsigned SuffixSize = PatchedName.
drop_back().
back() ==
'u' ? 2 : 1;
3469 unsigned CC = StringSwitch<unsigned>(
3470 PatchedName.
slice(5, PatchedName.
size() - SuffixSize))
3480 if (CC != ~0U && (CC != 0 || SuffixSize == 2)) {
3481 switch (PatchedName.
back()) {
3483 case 'b': PatchedName = SuffixSize == 2 ?
"vpcmpub" :
"vpcmpb";
break;
3484 case 'w': PatchedName = SuffixSize == 2 ?
"vpcmpuw" :
"vpcmpw";
break;
3485 case 'd': PatchedName = SuffixSize == 2 ?
"vpcmpud" :
"vpcmpd";
break;
3486 case 'q': PatchedName = SuffixSize == 2 ?
"vpcmpuq" :
"vpcmpq";
break;
3489 ComparisonPredicate = CC;
3495 (PatchedName.
back() ==
'b' || PatchedName.
back() ==
'w' ||
3496 PatchedName.
back() ==
'd' || PatchedName.
back() ==
'q')) {
3497 unsigned SuffixSize = PatchedName.
drop_back().
back() ==
'u' ? 2 : 1;
3498 unsigned CC = StringSwitch<unsigned>(
3499 PatchedName.
slice(5, PatchedName.
size() - SuffixSize))
3510 switch (PatchedName.
back()) {
3512 case 'b': PatchedName = SuffixSize == 2 ?
"vpcomub" :
"vpcomb";
break;
3513 case 'w': PatchedName = SuffixSize == 2 ?
"vpcomuw" :
"vpcomw";
break;
3514 case 'd': PatchedName = SuffixSize == 2 ?
"vpcomud" :
"vpcomd";
break;
3515 case 'q': PatchedName = SuffixSize == 2 ?
"vpcomuq" :
"vpcomq";
break;
3518 ComparisonPredicate = CC;
3530 StringSwitch<bool>(Name)
3531 .Cases({
"cs",
"ds",
"es",
"fs",
"gs",
"ss"},
true)
3532 .Cases({
"rex64",
"data32",
"data16",
"addr32",
"addr16"},
true)
3533 .Cases({
"xacquire",
"xrelease"},
true)
3534 .Cases({
"acquire",
"release"}, isParsingIntelSyntax())
3537 auto isLockRepeatNtPrefix = [](StringRef
N) {
3538 return StringSwitch<bool>(
N)
3539 .Cases({
"lock",
"rep",
"repe",
"repz",
"repne",
"repnz",
"notrack"},
3544 bool CurlyAsEndOfStatement =
false;
3547 while (isLockRepeatNtPrefix(
Name.lower())) {
3549 StringSwitch<unsigned>(Name)
3568 while (
Name.starts_with(
";") ||
Name.starts_with(
"\n") ||
3569 Name.starts_with(
"#") ||
Name.starts_with(
"\t") ||
3570 Name.starts_with(
"/")) {
3581 if (PatchedName ==
"data16" && is16BitMode()) {
3582 return Error(NameLoc,
"redundant data16 prefix");
3584 if (PatchedName ==
"data32") {
3586 return Error(NameLoc,
"redundant data32 prefix");
3588 return Error(NameLoc,
"'data32' is not supported in 64-bit mode");
3590 PatchedName =
"data16";
3597 if (
Next ==
"callw")
3599 if (
Next ==
"ljmpw")
3604 ForcedDataPrefix = X86::Is32Bit;
3612 if (ComparisonPredicate != ~0U && !isParsingIntelSyntax()) {
3619 if ((
Name.starts_with(
"ccmp") ||
Name.starts_with(
"ctest")) &&
3620 parseCFlagsOp(Operands))
3634 if (parseOperand(Operands, Name))
3636 if (HandleAVX512Operand(Operands))
3648 CurlyAsEndOfStatement =
3649 isParsingIntelSyntax() && isParsingMSInlineAsm() &&
3652 return TokError(
"unexpected token in argument list");
3656 if (ComparisonPredicate != ~0U && isParsingIntelSyntax()) {
3666 else if (CurlyAsEndOfStatement)
3669 getLexer().getTok().getLoc(), 0);
3676 if (IsFp && Operands.
size() == 1) {
3677 const char *Repl = StringSwitch<const char *>(Name)
3678 .Case(
"fsub",
"fsubp")
3679 .Case(
"fdiv",
"fdivp")
3680 .Case(
"fsubr",
"fsubrp")
3681 .Case(
"fdivr",
"fdivrp");
3682 static_cast<X86Operand &
>(*Operands[0]).setTokenValue(Repl);
3685 if ((Name ==
"mov" || Name ==
"movw" || Name ==
"movl") &&
3686 (Operands.
size() == 3)) {
3687 X86Operand &Op1 = (X86Operand &)*Operands[1];
3688 X86Operand &Op2 = (X86Operand &)*Operands[2];
3693 X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(
3695 (X86MCRegisterClasses[X86::GR16RegClassID].contains(Op1.
getReg()) ||
3696 X86MCRegisterClasses[X86::GR32RegClassID].contains(Op1.
getReg()))) {
3698 if (Name !=
"mov" && Name[3] == (is16BitMode() ?
'l' :
'w')) {
3699 Name = is16BitMode() ?
"movw" :
"movl";
3712 if ((Name ==
"outb" || Name ==
"outsb" || Name ==
"outw" || Name ==
"outsw" ||
3713 Name ==
"outl" || Name ==
"outsl" || Name ==
"out" || Name ==
"outs") &&
3714 Operands.
size() == 3) {
3715 X86Operand &
Op = (X86Operand &)*Operands.
back();
3721 if ((Name ==
"inb" || Name ==
"insb" || Name ==
"inw" || Name ==
"insw" ||
3722 Name ==
"inl" || Name ==
"insl" || Name ==
"in" || Name ==
"ins") &&
3723 Operands.
size() == 3) {
3724 X86Operand &
Op = (X86Operand &)*Operands[1];
3731 bool HadVerifyError =
false;
3734 if (
Name.starts_with(
"ins") &&
3735 (Operands.
size() == 1 || Operands.
size() == 3) &&
3736 (Name ==
"insb" || Name ==
"insw" || Name ==
"insl" || Name ==
"insd" ||
3739 AddDefaultSrcDestOperands(TmpOperands,
3741 DefaultMemDIOperand(NameLoc));
3742 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3746 if (
Name.starts_with(
"outs") &&
3747 (Operands.
size() == 1 || Operands.
size() == 3) &&
3748 (Name ==
"outsb" || Name ==
"outsw" || Name ==
"outsl" ||
3749 Name ==
"outsd" || Name ==
"outs")) {
3750 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
3752 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3758 if (
Name.starts_with(
"lods") &&
3759 (Operands.
size() == 1 || Operands.
size() == 2) &&
3760 (Name ==
"lods" || Name ==
"lodsb" || Name ==
"lodsw" ||
3761 Name ==
"lodsl" || Name ==
"lodsd" || Name ==
"lodsq")) {
3762 TmpOperands.
push_back(DefaultMemSIOperand(NameLoc));
3763 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3769 if (
Name.starts_with(
"stos") &&
3770 (Operands.
size() == 1 || Operands.
size() == 2) &&
3771 (Name ==
"stos" || Name ==
"stosb" || Name ==
"stosw" ||
3772 Name ==
"stosl" || Name ==
"stosd" || Name ==
"stosq")) {
3773 TmpOperands.
push_back(DefaultMemDIOperand(NameLoc));
3774 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3780 if (
Name.starts_with(
"scas") &&
3781 (Operands.
size() == 1 || Operands.
size() == 2) &&
3782 (Name ==
"scas" || Name ==
"scasb" || Name ==
"scasw" ||
3783 Name ==
"scasl" || Name ==
"scasd" || Name ==
"scasq")) {
3784 TmpOperands.
push_back(DefaultMemDIOperand(NameLoc));
3785 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3789 if (
Name.starts_with(
"cmps") &&
3790 (Operands.
size() == 1 || Operands.
size() == 3) &&
3791 (Name ==
"cmps" || Name ==
"cmpsb" || Name ==
"cmpsw" ||
3792 Name ==
"cmpsl" || Name ==
"cmpsd" || Name ==
"cmpsq")) {
3793 AddDefaultSrcDestOperands(TmpOperands, DefaultMemDIOperand(NameLoc),
3794 DefaultMemSIOperand(NameLoc));
3795 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3799 if (((
Name.starts_with(
"movs") &&
3800 (Name ==
"movs" || Name ==
"movsb" || Name ==
"movsw" ||
3801 Name ==
"movsl" || Name ==
"movsd" || Name ==
"movsq")) ||
3802 (
Name.starts_with(
"smov") &&
3803 (Name ==
"smov" || Name ==
"smovb" || Name ==
"smovw" ||
3804 Name ==
"smovl" || Name ==
"smovd" || Name ==
"smovq"))) &&
3805 (Operands.
size() == 1 || Operands.
size() == 3)) {
3806 if (Name ==
"movsd" && Operands.
size() == 1 && !isParsingIntelSyntax())
3808 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
3809 DefaultMemDIOperand(NameLoc));
3810 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3814 if (HadVerifyError) {
3815 return HadVerifyError;
3819 if ((Name ==
"xlat" || Name ==
"xlatb") && Operands.
size() == 2) {
3820 X86Operand &Op1 =
static_cast<X86Operand &
>(*Operands[1]);
3823 "size, (R|E)BX will be used for the location");
3825 static_cast<X86Operand &
>(*Operands[0]).setTokenValue(
"xlatb");
3838 if (
I == Table.
end() ||
I->OldOpc != Opcode)
3844 if (X86::isBLENDVPD(Opcode) || X86::isBLENDVPS(Opcode) ||
3845 X86::isPBLENDVB(Opcode))
3851bool X86AsmParser::processInstruction(MCInst &Inst,
const OperandVector &
Ops) {
3855 if (ForcedOpcodePrefix != OpcodePrefix_VEX3 &&
3862 auto replaceWithCCMPCTEST = [&](
unsigned Opcode) ->
bool {
3863 if (ForcedOpcodePrefix == OpcodePrefix_EVEX) {
3874 default:
return false;
3879 if (ForcedDispEncoding == DispEncoding_Disp32) {
3880 Inst.
setOpcode(is16BitMode() ? X86::JMP_2 : X86::JMP_4);
3889 if (ForcedDispEncoding == DispEncoding_Disp32) {
3890 Inst.
setOpcode(is16BitMode() ? X86::JCC_2 : X86::JCC_4);
3906#define FROM_TO(FROM, TO) \
3908 return replaceWithCCMPCTEST(X86::TO);
3910 FROM_TO(CMP64mi32, CCMP64mi32)
3913 FROM_TO(CMP64ri32, CCMP64ri32)
3940 FROM_TO(TEST64mi32, CTEST64mi32)
3942 FROM_TO(TEST64ri32, CTEST64ri32)
3962bool X86AsmParser::validateInstruction(MCInst &Inst,
const OperandVector &
Ops) {
3963 using namespace X86;
3966 uint64_t TSFlags = MII.get(Opcode).TSFlags;
3967 if (isVFCMADDCPH(Opcode) || isVFCMADDCSH(Opcode) || isVFMADDCPH(Opcode) ||
3968 isVFMADDCSH(Opcode)) {
3972 return Warning(
Ops[0]->getStartLoc(),
"Destination register should be "
3973 "distinct from source registers");
3974 }
else if (isVFCMULCPH(Opcode) || isVFCMULCSH(Opcode) || isVFMULCPH(Opcode) ||
3975 isVFMULCSH(Opcode)) {
3985 return Warning(
Ops[0]->getStartLoc(),
"Destination register should be "
3986 "distinct from source registers");
3987 }
else if (isV4FMADDPS(Opcode) || isV4FMADDSS(Opcode) ||
3988 isV4FNMADDPS(Opcode) || isV4FNMADDSS(Opcode) ||
3989 isVP4DPWSSDS(Opcode) || isVP4DPWSSD(Opcode)) {
3993 unsigned Src2Enc =
MRI->getEncodingValue(Src2);
3994 if (Src2Enc % 4 != 0) {
3996 unsigned GroupStart = (Src2Enc / 4) * 4;
3997 unsigned GroupEnd = GroupStart + 3;
3999 "source register '" +
RegName +
"' implicitly denotes '" +
4000 RegName.take_front(3) + Twine(GroupStart) +
"' to '" +
4001 RegName.take_front(3) + Twine(GroupEnd) +
4004 }
else if (isVGATHERDPD(Opcode) || isVGATHERDPS(Opcode) ||
4005 isVGATHERQPD(Opcode) || isVGATHERQPS(Opcode) ||
4006 isVPGATHERDD(Opcode) || isVPGATHERDQ(Opcode) ||
4007 isVPGATHERQD(Opcode) || isVPGATHERQQ(Opcode)) {
4011 unsigned Index =
MRI->getEncodingValue(
4014 return Warning(
Ops[0]->getStartLoc(),
"index and destination registers "
4015 "should be distinct");
4019 unsigned Index =
MRI->getEncodingValue(
4021 if (Dest == Mask || Dest == Index || Mask == Index)
4022 return Warning(
Ops[0]->getStartLoc(),
"mask, index, and destination "
4023 "registers should be distinct");
4025 }
else if (isTCMMIMFP16PS(Opcode) || isTCMMRLFP16PS(Opcode) ||
4026 isTDPBF16PS(Opcode) || isTDPFP16PS(Opcode) || isTDPBSSD(Opcode) ||
4027 isTDPBSUD(Opcode) || isTDPBUSD(Opcode) || isTDPBUUD(Opcode)) {
4031 if (SrcDest == Src1 || SrcDest == Src2 || Src1 == Src2)
4032 return Error(
Ops[0]->getStartLoc(),
"all tmm registers must be distinct");
4046 for (
unsigned i = 0; i !=
NumOps; ++i) {
4051 if (
Reg == X86::AH ||
Reg == X86::BH ||
Reg == X86::CH ||
Reg == X86::DH)
4059 (Enc ==
X86II::EVEX || ForcedOpcodePrefix == OpcodePrefix_REX2 ||
4060 ForcedOpcodePrefix == OpcodePrefix_REX || UsesRex)) {
4062 return Error(
Ops[0]->getStartLoc(),
4063 "can't encode '" +
RegName.str() +
4064 "' in an instruction requiring EVEX/REX2/REX prefix");
4068 if ((Opcode == X86::PREFETCHIT0 || Opcode == X86::PREFETCHIT1)) {
4072 Ops[0]->getStartLoc(),
4073 Twine((Inst.
getOpcode() == X86::PREFETCHIT0 ?
"'prefetchit0'"
4074 :
"'prefetchit1'")) +
4075 " only supports RIP-relative address");
4080void X86AsmParser::emitWarningForSpecialLVIInstruction(SMLoc Loc) {
4081 Warning(Loc,
"Instruction may be vulnerable to LVI and "
4082 "requires manual mitigation");
4083 Note(SMLoc(),
"See https://software.intel.com/"
4084 "security-software-guidance/insights/"
4085 "deep-dive-load-value-injection#specialinstructions"
4086 " for more information");
4098void X86AsmParser::applyLVICFIMitigation(MCInst &Inst, MCStreamer &Out) {
4109 MCInst ShlInst, FenceInst;
4110 bool Parse32 = is32BitMode() || Code16GCC;
4111 MCRegister Basereg =
4112 is64BitMode() ? X86::RSP : (Parse32 ? X86::ESP : X86::SP);
4116 1, SMLoc{}, SMLoc{}, 0);
4118 ShlMemOp->addMemOperands(ShlInst, 5);
4131 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4143void X86AsmParser::applyLVILoadHardeningMitigation(MCInst &Inst,
4160 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4163 }
else if (Opcode == X86::REP_PREFIX || Opcode == X86::REPNE_PREFIX) {
4166 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4170 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
4185void X86AsmParser::emitInstruction(MCInst &Inst,
OperandVector &Operands,
4188 getSTI().hasFeature(X86::FeatureLVIControlFlowIntegrity))
4189 applyLVICFIMitigation(Inst, Out);
4194 getSTI().hasFeature(X86::FeatureLVILoadHardening))
4195 applyLVILoadHardeningMitigation(Inst, Out);
4199 unsigned Result = 0;
4201 if (Prefix.isPrefix()) {
4202 Result = Prefix.getPrefix();
4208bool X86AsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
4210 MCStreamer &Out, uint64_t &ErrorInfo,
4211 bool MatchingInlineAsm) {
4212 assert(!Operands.
empty() &&
"Unexpect empty operand list!");
4213 assert((*Operands[0]).isToken() &&
"Leading operand should always be a mnemonic!");
4216 MatchFPUWaitAlias(IDLoc,
static_cast<X86Operand &
>(*Operands[0]), Operands,
4217 Out, MatchingInlineAsm);
4224 if (ForcedOpcodePrefix == OpcodePrefix_REX)
4226 else if (ForcedOpcodePrefix == OpcodePrefix_REX2)
4228 else if (ForcedOpcodePrefix == OpcodePrefix_VEX)
4230 else if (ForcedOpcodePrefix == OpcodePrefix_VEX2)
4232 else if (ForcedOpcodePrefix == OpcodePrefix_VEX3)
4234 else if (ForcedOpcodePrefix == OpcodePrefix_EVEX)
4238 if (ForcedDispEncoding == DispEncoding_Disp8)
4240 else if (ForcedDispEncoding == DispEncoding_Disp32)
4246 return isParsingIntelSyntax()
4247 ? matchAndEmitIntelInstruction(IDLoc, Opcode, Inst, Operands, Out,
4248 ErrorInfo, MatchingInlineAsm)
4249 : matchAndEmitATTInstruction(IDLoc, Opcode, Inst, Operands, Out,
4250 ErrorInfo, MatchingInlineAsm);
4253void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &
Op,
4255 bool MatchingInlineAsm) {
4259 const char *Repl = StringSwitch<const char *>(
Op.getToken())
4260 .Case(
"finit",
"fninit")
4261 .Case(
"fsave",
"fnsave")
4262 .Case(
"fstcw",
"fnstcw")
4263 .Case(
"fstcww",
"fnstcw")
4264 .Case(
"fstenv",
"fnstenv")
4265 .Case(
"fstsw",
"fnstsw")
4266 .Case(
"fstsww",
"fnstsw")
4267 .Case(
"fclex",
"fnclex")
4273 if (!MatchingInlineAsm)
4279bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc,
4280 const FeatureBitset &MissingFeatures,
4281 bool MatchingInlineAsm) {
4282 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
4283 SmallString<126> Msg;
4284 raw_svector_ostream OS(Msg);
4285 OS <<
"instruction requires:";
4286 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
4287 if (MissingFeatures[i])
4290 return Error(IDLoc, OS.str(), SMRange(), MatchingInlineAsm);
4293unsigned X86AsmParser::checkTargetMatchPredicate(MCInst &Inst) {
4295 const MCInstrDesc &MCID = MII.get(
Opc);
4296 uint64_t TSFlags = MCID.
TSFlags;
4299 return Match_Unsupported;
4301 return Match_Unsupported;
4303 switch (ForcedOpcodePrefix) {
4304 case OpcodePrefix_Default:
4306 case OpcodePrefix_REX:
4307 case OpcodePrefix_REX2:
4309 return Match_Unsupported;
4311 case OpcodePrefix_VEX:
4312 case OpcodePrefix_VEX2:
4313 case OpcodePrefix_VEX3:
4315 return Match_Unsupported;
4317 case OpcodePrefix_EVEX:
4319 !X86::isCMP(
Opc) && !X86::isTEST(
Opc))
4320 return Match_Unsupported;
4322 return Match_Unsupported;
4327 (ForcedOpcodePrefix != OpcodePrefix_VEX &&
4328 ForcedOpcodePrefix != OpcodePrefix_VEX2 &&
4329 ForcedOpcodePrefix != OpcodePrefix_VEX3))
4330 return Match_Unsupported;
4332 return Match_Success;
4335bool X86AsmParser::matchAndEmitATTInstruction(
4336 SMLoc IDLoc,
unsigned &Opcode, MCInst &Inst,
OperandVector &Operands,
4337 MCStreamer &Out, uint64_t &ErrorInfo,
bool MatchingInlineAsm) {
4338 X86Operand &
Op =
static_cast<X86Operand &
>(*Operands[0]);
4342 if (ForcedDataPrefix == X86::Is32Bit)
4343 SwitchMode(X86::Is32Bit);
4345 FeatureBitset MissingFeatures;
4346 unsigned OriginalError = MatchInstruction(Operands, Inst, ErrorInfo,
4347 MissingFeatures, MatchingInlineAsm,
4348 isParsingIntelSyntax());
4349 if (ForcedDataPrefix == X86::Is32Bit) {
4350 SwitchMode(X86::Is16Bit);
4351 ForcedDataPrefix = 0;
4353 switch (OriginalError) {
4356 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
4361 if (!MatchingInlineAsm)
4362 while (processInstruction(Inst, Operands))
4366 if (!MatchingInlineAsm)
4370 case Match_InvalidImmUnsignedi4: {
4371 SMLoc ErrorLoc = ((X86Operand &)*Operands[ErrorInfo]).getStartLoc();
4372 if (ErrorLoc == SMLoc())
4374 return Error(ErrorLoc,
"immediate must be an integer in range [0, 15]",
4375 EmptyRange, MatchingInlineAsm);
4377 case Match_MissingFeature:
4378 return ErrorMissingFeature(IDLoc, MissingFeatures, MatchingInlineAsm);
4379 case Match_InvalidOperand:
4380 case Match_MnemonicFail:
4381 case Match_Unsupported:
4384 if (
Op.getToken().empty()) {
4385 Error(IDLoc,
"instruction must have size higher than 0", EmptyRange,
4396 StringRef
Base =
Op.getToken();
4397 SmallString<16> Tmp;
4400 Op.setTokenValue(Tmp);
4408 const char *Suffixes =
Base[0] !=
'f' ?
"bwlq" :
"slt\0";
4410 const char *MemSize =
Base[0] !=
'f' ?
"\x08\x10\x20\x40" :
"\x20\x40\x50\0";
4413 uint64_t ErrorInfoIgnore;
4414 FeatureBitset ErrorInfoMissingFeatures;
4422 bool HasVectorReg =
false;
4423 X86Operand *MemOp =
nullptr;
4424 for (
const auto &
Op : Operands) {
4425 X86Operand *X86Op =
static_cast<X86Operand *
>(
Op.get());
4427 HasVectorReg =
true;
4428 else if (X86Op->
isMem()) {
4430 assert(MemOp->Mem.Size == 0 &&
"Memory size always 0 under ATT syntax");
4437 for (
unsigned I = 0,
E = std::size(Match);
I !=
E; ++
I) {
4438 Tmp.
back() = Suffixes[
I];
4439 if (MemOp && HasVectorReg)
4440 MemOp->Mem.Size = MemSize[
I];
4441 Match[
I] = Match_MnemonicFail;
4442 if (MemOp || !HasVectorReg) {
4444 MatchInstruction(Operands, Inst, ErrorInfoIgnore, MissingFeatures,
4445 MatchingInlineAsm, isParsingIntelSyntax());
4447 if (Match[
I] == Match_MissingFeature)
4448 ErrorInfoMissingFeatures = MissingFeatures;
4458 unsigned NumSuccessfulMatches =
llvm::count(Match, Match_Success);
4459 if (NumSuccessfulMatches == 1) {
4460 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
4465 if (!MatchingInlineAsm)
4466 while (processInstruction(Inst, Operands))
4470 if (!MatchingInlineAsm)
4480 if (NumSuccessfulMatches > 1) {
4482 unsigned NumMatches = 0;
4483 for (
unsigned I = 0,
E = std::size(Match);
I !=
E; ++
I)
4484 if (Match[
I] == Match_Success)
4485 MatchChars[NumMatches++] = Suffixes[
I];
4487 SmallString<126> Msg;
4488 raw_svector_ostream OS(Msg);
4489 OS <<
"ambiguous instructions require an explicit suffix (could be ";
4490 for (
unsigned i = 0; i != NumMatches; ++i) {
4493 if (i + 1 == NumMatches)
4495 OS <<
"'" <<
Base << MatchChars[i] <<
"'";
4498 Error(IDLoc, OS.str(), EmptyRange, MatchingInlineAsm);
4506 if (
llvm::count(Match, Match_MnemonicFail) == 4) {
4507 if (OriginalError == Match_MnemonicFail)
4508 return Error(IDLoc,
"invalid instruction mnemonic '" +
Base +
"'",
4509 Op.getLocRange(), MatchingInlineAsm);
4511 if (OriginalError == Match_Unsupported)
4512 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4515 assert(OriginalError == Match_InvalidOperand &&
"Unexpected error");
4517 if (ErrorInfo != ~0ULL) {
4518 if (ErrorInfo >= Operands.size())
4519 return Error(IDLoc,
"too few operands for instruction", EmptyRange,
4522 X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo];
4526 OperandRange, MatchingInlineAsm);
4530 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4536 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4542 if (
llvm::count(Match, Match_MissingFeature) == 1) {
4543 ErrorInfo = Match_MissingFeature;
4544 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
4550 if (
llvm::count(Match, Match_InvalidOperand) == 1) {
4551 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4556 Error(IDLoc,
"unknown use of instruction mnemonic without a size suffix",
4557 EmptyRange, MatchingInlineAsm);
4561bool X86AsmParser::matchAndEmitIntelInstruction(
4562 SMLoc IDLoc,
unsigned &Opcode, MCInst &Inst,
OperandVector &Operands,
4563 MCStreamer &Out, uint64_t &ErrorInfo,
bool MatchingInlineAsm) {
4564 X86Operand &
Op =
static_cast<X86Operand &
>(*Operands[0]);
4567 X86Operand *UnsizedMemOp =
nullptr;
4568 for (
const auto &
Op : Operands) {
4569 X86Operand *X86Op =
static_cast<X86Operand *
>(
Op.get());
4571 UnsizedMemOp = X86Op;
4580 StringRef Mnemonic = (
static_cast<X86Operand &
>(*Operands[0])).
getToken();
4582 static const char *
const PtrSizedInstrs[] = {
"call",
"jmp",
"push",
"pop"};
4583 for (
const char *Instr : PtrSizedInstrs) {
4584 if (Mnemonic == Instr) {
4585 UnsizedMemOp->
Mem.
Size = getPointerWidth();
4591 SmallVector<unsigned, 8> Match;
4592 FeatureBitset ErrorInfoMissingFeatures;
4593 FeatureBitset MissingFeatures;
4594 StringRef
Base = (
static_cast<X86Operand &
>(*Operands[0])).
getToken();
4598 if (Mnemonic ==
"push" && Operands.size() == 2) {
4599 auto *X86Op =
static_cast<X86Operand *
>(Operands[1].get());
4600 if (X86Op->
isImm()) {
4603 unsigned Size = getPointerWidth();
4606 SmallString<16> Tmp;
4608 Tmp += (is64BitMode())
4610 : (is32BitMode()) ?
"l" : (is16BitMode()) ?
"w" :
" ";
4611 Op.setTokenValue(Tmp);
4613 Match.
push_back(MatchInstruction(Operands, Inst, ErrorInfo,
4614 MissingFeatures, MatchingInlineAsm,
4625 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
4626 for (
unsigned Size : MopSizes) {
4628 uint64_t ErrorInfoIgnore;
4630 unsigned M = MatchInstruction(Operands, Inst, ErrorInfoIgnore,
4631 MissingFeatures, MatchingInlineAsm,
4632 isParsingIntelSyntax());
4637 if (Match.
back() == Match_MissingFeature)
4638 ErrorInfoMissingFeatures = MissingFeatures;
4648 if (Match.
empty()) {
4650 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,
4651 isParsingIntelSyntax()));
4653 if (Match.
back() == Match_MissingFeature)
4654 ErrorInfoMissingFeatures = MissingFeatures;
4662 if (Match.
back() == Match_MnemonicFail) {
4663 return Error(IDLoc,
"invalid instruction mnemonic '" + Mnemonic +
"'",
4664 Op.getLocRange(), MatchingInlineAsm);
4667 unsigned NumSuccessfulMatches =
llvm::count(Match, Match_Success);
4671 if (UnsizedMemOp && NumSuccessfulMatches > 1 &&
4674 unsigned M = MatchInstruction(
4675 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,
4676 isParsingIntelSyntax());
4677 if (M == Match_Success)
4678 NumSuccessfulMatches = 1;
4690 if (NumSuccessfulMatches == 1) {
4691 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
4696 if (!MatchingInlineAsm)
4697 while (processInstruction(Inst, Operands))
4700 if (!MatchingInlineAsm)
4704 }
else if (NumSuccessfulMatches > 1) {
4706 "multiple matches only possible with unsized memory operands");
4708 "ambiguous operand size for instruction '" + Mnemonic +
"\'",
4714 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4720 if (
llvm::count(Match, Match_MissingFeature) == 1) {
4721 ErrorInfo = Match_MissingFeature;
4722 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
4728 if (
llvm::count(Match, Match_InvalidOperand) == 1) {
4729 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4733 if (
llvm::count(Match, Match_InvalidImmUnsignedi4) == 1) {
4734 SMLoc ErrorLoc = ((X86Operand &)*Operands[ErrorInfo]).getStartLoc();
4735 if (ErrorLoc == SMLoc())
4737 return Error(ErrorLoc,
"immediate must be an integer in range [0, 15]",
4738 EmptyRange, MatchingInlineAsm);
4742 return Error(IDLoc,
"unknown instruction mnemonic", EmptyRange,
4746bool X86AsmParser::omitRegisterFromClobberLists(MCRegister
Reg) {
4747 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(
Reg);
4750bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
4751 MCAsmParser &Parser = getParser();
4754 return parseDirectiveArch();
4756 return ParseDirectiveCode(IDVal, DirectiveID.
getLoc());
4762 return Error(DirectiveID.
getLoc(),
"'.att_syntax noprefix' is not "
4763 "supported: registers must have a "
4764 "'%' prefix in .att_syntax");
4766 getParser().setAssemblerDialect(0);
4769 getParser().setAssemblerDialect(1);
4774 return Error(DirectiveID.
getLoc(),
"'.intel_syntax prefix' is not "
4775 "supported: registers must not have "
4776 "a '%' prefix in .intel_syntax");
4779 }
else if (IDVal ==
".nops")
4780 return parseDirectiveNops(DirectiveID.
getLoc());
4781 else if (IDVal ==
".even")
4782 return parseDirectiveEven(DirectiveID.
getLoc());
4783 else if (IDVal ==
".cv_fpo_proc")
4784 return parseDirectiveFPOProc(DirectiveID.
getLoc());
4785 else if (IDVal ==
".cv_fpo_setframe")
4786 return parseDirectiveFPOSetFrame(DirectiveID.
getLoc());
4787 else if (IDVal ==
".cv_fpo_pushreg")
4788 return parseDirectiveFPOPushReg(DirectiveID.
getLoc());
4789 else if (IDVal ==
".cv_fpo_stackalloc")
4790 return parseDirectiveFPOStackAlloc(DirectiveID.
getLoc());
4791 else if (IDVal ==
".cv_fpo_stackalign")
4792 return parseDirectiveFPOStackAlign(DirectiveID.
getLoc());
4793 else if (IDVal ==
".cv_fpo_endprologue")
4794 return parseDirectiveFPOEndPrologue(DirectiveID.
getLoc());
4795 else if (IDVal ==
".cv_fpo_endproc")
4796 return parseDirectiveFPOEndProc(DirectiveID.
getLoc());
4797 else if (IDVal ==
".seh_pushreg" ||
4799 return parseDirectiveSEHPushReg(DirectiveID.
getLoc());
4800 else if (IDVal ==
".seh_setframe" ||
4802 return parseDirectiveSEHSetFrame(DirectiveID.
getLoc());
4803 else if (IDVal ==
".seh_savereg" ||
4805 return parseDirectiveSEHSaveReg(DirectiveID.
getLoc());
4806 else if (IDVal ==
".seh_savexmm" ||
4808 return parseDirectiveSEHSaveXMM(DirectiveID.
getLoc());
4809 else if (IDVal ==
".seh_pushframe" ||
4811 return parseDirectiveSEHPushFrame(DirectiveID.
getLoc());
4816bool X86AsmParser::parseDirectiveArch() {
4818 getParser().parseStringToEndOfStatement();
4824bool X86AsmParser::parseDirectiveNops(SMLoc L) {
4825 int64_t NumBytes = 0, Control = 0;
4826 SMLoc NumBytesLoc, ControlLoc;
4827 const MCSubtargetInfo& STI = getSTI();
4828 NumBytesLoc = getTok().getLoc();
4829 if (getParser().checkForValidSection() ||
4830 getParser().parseAbsoluteExpression(NumBytes))
4834 ControlLoc = getTok().getLoc();
4835 if (getParser().parseAbsoluteExpression(Control))
4838 if (getParser().parseEOL())
4841 if (NumBytes <= 0) {
4842 Error(NumBytesLoc,
"'.nops' directive with non-positive size");
4847 Error(ControlLoc,
"'.nops' directive with negative NOP size");
4852 getParser().getStreamer().emitNops(NumBytes, Control, L, STI);
4859bool X86AsmParser::parseDirectiveEven(SMLoc L) {
4863 const MCSection *
Section = getStreamer().getCurrentSectionOnly();
4865 getStreamer().initSections(
false, getSTI());
4866 Section = getStreamer().getCurrentSectionOnly();
4868 if (
getContext().getAsmInfo()->useCodeAlign(*Section))
4869 getStreamer().emitCodeAlignment(
Align(2), &getSTI(), 0);
4871 getStreamer().emitValueToAlignment(
Align(2), 0, 1, 0);
4877bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
4878 MCAsmParser &Parser = getParser();
4880 if (IDVal ==
".code16") {
4882 if (!is16BitMode()) {
4883 SwitchMode(X86::Is16Bit);
4884 getTargetStreamer().emitCode16();
4886 }
else if (IDVal ==
".code16gcc") {
4890 if (!is16BitMode()) {
4891 SwitchMode(X86::Is16Bit);
4892 getTargetStreamer().emitCode16();
4894 }
else if (IDVal ==
".code32") {
4896 if (!is32BitMode()) {
4897 SwitchMode(X86::Is32Bit);
4898 getTargetStreamer().emitCode32();
4900 }
else if (IDVal ==
".code64") {
4902 if (!is64BitMode()) {
4903 SwitchMode(X86::Is64Bit);
4904 getTargetStreamer().emitCode64();
4907 Error(L,
"unknown directive " + IDVal);
4915bool X86AsmParser::parseDirectiveFPOProc(SMLoc L) {
4916 MCAsmParser &Parser = getParser();
4920 return Parser.
TokError(
"expected symbol name");
4921 if (Parser.
parseIntToken(ParamsSize,
"expected parameter byte count"))
4924 return Parser.
TokError(
"parameters size out of range");
4928 return getTargetStreamer().emitFPOProc(ProcSym, ParamsSize, L);
4932bool X86AsmParser::parseDirectiveFPOSetFrame(SMLoc L) {
4935 if (parseRegister(
Reg, DummyLoc, DummyLoc) || parseEOL())
4937 return getTargetStreamer().emitFPOSetFrame(
Reg, L);
4941bool X86AsmParser::parseDirectiveFPOPushReg(SMLoc L) {
4944 if (parseRegister(
Reg, DummyLoc, DummyLoc) || parseEOL())
4946 return getTargetStreamer().emitFPOPushReg(
Reg, L);
4950bool X86AsmParser::parseDirectiveFPOStackAlloc(SMLoc L) {
4951 MCAsmParser &Parser = getParser();
4955 return getTargetStreamer().emitFPOStackAlloc(
Offset, L);
4959bool X86AsmParser::parseDirectiveFPOStackAlign(SMLoc L) {
4960 MCAsmParser &Parser = getParser();
4964 return getTargetStreamer().emitFPOStackAlign(
Offset, L);
4968bool X86AsmParser::parseDirectiveFPOEndPrologue(SMLoc L) {
4969 MCAsmParser &Parser = getParser();
4972 return getTargetStreamer().emitFPOEndPrologue(L);
4976bool X86AsmParser::parseDirectiveFPOEndProc(SMLoc L) {
4977 MCAsmParser &Parser = getParser();
4980 return getTargetStreamer().emitFPOEndProc(L);
4983bool X86AsmParser::parseSEHRegisterNumber(
unsigned RegClassID,
4984 MCRegister &RegNo) {
4985 SMLoc startLoc = getLexer().getLoc();
4991 if (parseRegister(RegNo, startLoc, endLoc))
4994 if (!X86MCRegisterClasses[RegClassID].
contains(RegNo)) {
4995 return Error(startLoc,
4996 "register is not supported for use with this directive");
5002 if (getParser().parseAbsoluteExpression(EncodedReg))
5007 RegNo = MCRegister();
5008 for (
MCPhysReg Reg : X86MCRegisterClasses[RegClassID]) {
5009 if (
MRI->getEncodingValue(
Reg) == EncodedReg) {
5015 return Error(startLoc,
5016 "incorrect register number for use with this directive");
5023bool X86AsmParser::parseDirectiveSEHPushReg(SMLoc Loc) {
5025 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5029 return TokError(
"expected end of directive");
5032 getStreamer().emitWinCFIPushReg(
Reg, Loc);
5036bool X86AsmParser::parseDirectiveSEHSetFrame(SMLoc Loc) {
5039 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5042 return TokError(
"you must specify a stack pointer offset");
5045 if (getParser().parseAbsoluteExpression(Off))
5049 return TokError(
"expected end of directive");
5052 getStreamer().emitWinCFISetFrame(
Reg, Off, Loc);
5056bool X86AsmParser::parseDirectiveSEHSaveReg(SMLoc Loc) {
5059 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5062 return TokError(
"you must specify an offset on the stack");
5065 if (getParser().parseAbsoluteExpression(Off))
5069 return TokError(
"expected end of directive");
5072 getStreamer().emitWinCFISaveReg(
Reg, Off, Loc);
5076bool X86AsmParser::parseDirectiveSEHSaveXMM(SMLoc Loc) {
5079 if (parseSEHRegisterNumber(X86::VR128XRegClassID,
Reg))
5082 return TokError(
"you must specify an offset on the stack");
5085 if (getParser().parseAbsoluteExpression(Off))
5089 return TokError(
"expected end of directive");
5092 getStreamer().emitWinCFISaveXMM(
Reg, Off, Loc);
5096bool X86AsmParser::parseDirectiveSEHPushFrame(SMLoc Loc) {
5100 SMLoc startLoc = getLexer().getLoc();
5102 if (!getParser().parseIdentifier(CodeID)) {
5103 if (CodeID !=
"code")
5104 return Error(startLoc,
"expected @code");
5110 return TokError(
"expected end of directive");
5113 getStreamer().emitWinCFIPushFrame(Code, Loc);
5123#define GET_MATCHER_IMPLEMENTATION
5124#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
Value * getPointer(Value *Ptr)
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 Error(SMLoc L, const Twine &Msg, SMRange Range={})
Return an error at the location L, with the message Msg.
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.
bool TokError(const Twine &Msg, SMRange Range={})
Report an error at the current lexer location.
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
virtual bool lookUpType(StringRef Name, AsmTypeInfo &Info) const
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)
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.
static constexpr size_t npos
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).
LLVM_ABI std::string lower() const
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
bool consume_front(char Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
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