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)
1306 : MCTargetAsmParser(sti, mii), InstInfo(nullptr), Code16GCC(
false) {
1311 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
1314 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
1315 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1316 SMLoc &EndLoc)
override;
1318 bool parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc)
override;
1320 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
1323 bool ParseDirective(AsmToken DirectiveID)
override;
1327#define GET_REGISTER_MATCHER
1328#define GET_SUBTARGET_FEATURE_NAME
1329#include "X86GenAsmMatcher.inc"
1340 !(BaseReg == X86::RIP || BaseReg == X86::EIP ||
1341 X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg) ||
1342 X86MCRegisterClasses[X86::GR32RegClassID].
contains(BaseReg) ||
1343 X86MCRegisterClasses[X86::GR64RegClassID].
contains(BaseReg))) {
1344 ErrMsg =
"invalid base+index expression";
1349 !(IndexReg == X86::EIZ || IndexReg == X86::RIZ ||
1350 X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg) ||
1351 X86MCRegisterClasses[X86::GR32RegClassID].
contains(IndexReg) ||
1352 X86MCRegisterClasses[X86::GR64RegClassID].
contains(IndexReg) ||
1353 X86MCRegisterClasses[X86::VR128XRegClassID].
contains(IndexReg) ||
1354 X86MCRegisterClasses[X86::VR256XRegClassID].
contains(IndexReg) ||
1355 X86MCRegisterClasses[X86::VR512RegClassID].
contains(IndexReg))) {
1356 ErrMsg =
"invalid base+index expression";
1360 if (((BaseReg == X86::RIP || BaseReg == X86::EIP) && IndexReg) ||
1361 IndexReg == X86::EIP || IndexReg == X86::RIP || IndexReg == X86::ESP ||
1362 IndexReg == X86::RSP) {
1363 ErrMsg =
"invalid base+index expression";
1369 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg) &&
1370 (Is64BitMode || (BaseReg != X86::BX && BaseReg != X86::BP &&
1371 BaseReg != X86::SI && BaseReg != X86::DI))) {
1372 ErrMsg =
"invalid 16-bit base register";
1377 X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg)) {
1378 ErrMsg =
"16-bit memory operand may not include only index register";
1382 if (BaseReg && IndexReg) {
1383 if (X86MCRegisterClasses[X86::GR64RegClassID].
contains(BaseReg) &&
1384 (X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg) ||
1385 X86MCRegisterClasses[X86::GR32RegClassID].
contains(IndexReg) ||
1386 IndexReg == X86::EIZ)) {
1387 ErrMsg =
"base register is 64-bit, but index register is not";
1390 if (X86MCRegisterClasses[X86::GR32RegClassID].
contains(BaseReg) &&
1391 (X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg) ||
1392 X86MCRegisterClasses[X86::GR64RegClassID].
contains(IndexReg) ||
1393 IndexReg == X86::RIZ)) {
1394 ErrMsg =
"base register is 32-bit, but index register is not";
1397 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg)) {
1398 if (X86MCRegisterClasses[X86::GR32RegClassID].
contains(IndexReg) ||
1399 X86MCRegisterClasses[X86::GR64RegClassID].
contains(IndexReg)) {
1400 ErrMsg =
"base register is 16-bit, but index register is not";
1403 if ((BaseReg != X86::BX && BaseReg != X86::BP) ||
1404 (IndexReg != X86::SI && IndexReg != X86::DI)) {
1405 ErrMsg =
"invalid 16-bit base/index register combination";
1412 if (!Is64BitMode && (BaseReg == X86::RIP || BaseReg == X86::EIP)) {
1413 ErrMsg =
"IP-relative addressing requires 64-bit mode";
1434 if (isParsingMSInlineAsm() && isParsingIntelSyntax() &&
1435 (RegNo == X86::EFLAGS || RegNo == X86::MXCSR))
1436 RegNo = MCRegister();
1438 if (!is64BitMode()) {
1442 if (RegNo == X86::RIZ || RegNo == X86::RIP ||
1443 X86MCRegisterClasses[X86::GR64RegClassID].
contains(RegNo) ||
1446 return Error(StartLoc,
1447 "register %" +
RegName +
" is only available in 64-bit mode",
1448 SMRange(StartLoc, EndLoc));
1453 UseApxExtendedReg =
true;
1457 if (!RegNo &&
RegName.starts_with(
"db")) {
1516 if (isParsingIntelSyntax())
1518 return Error(StartLoc,
"invalid register name", SMRange(StartLoc, EndLoc));
1523bool X86AsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
1524 SMLoc &EndLoc,
bool RestoreOnFailure) {
1525 MCAsmParser &Parser = getParser();
1526 AsmLexer &Lexer = getLexer();
1527 RegNo = MCRegister();
1530 auto OnFailure = [RestoreOnFailure, &Lexer, &Tokens]() {
1531 if (RestoreOnFailure) {
1532 while (!Tokens.
empty()) {
1538 const AsmToken &PercentTok = Parser.
getTok();
1539 StartLoc = PercentTok.
getLoc();
1548 const AsmToken &Tok = Parser.
getTok();
1553 if (isParsingIntelSyntax())
return true;
1554 return Error(StartLoc,
"invalid register name",
1555 SMRange(StartLoc, EndLoc));
1558 if (MatchRegisterByName(RegNo, Tok.
getString(), StartLoc, EndLoc)) {
1564 if (RegNo == X86::ST0) {
1575 const AsmToken &IntTok = Parser.
getTok();
1578 return Error(IntTok.
getLoc(),
"expected stack index");
1581 case 0: RegNo = X86::ST0;
break;
1582 case 1: RegNo = X86::ST1;
break;
1583 case 2: RegNo = X86::ST2;
break;
1584 case 3: RegNo = X86::ST3;
break;
1585 case 4: RegNo = X86::ST4;
break;
1586 case 5: RegNo = X86::ST5;
break;
1587 case 6: RegNo = X86::ST6;
break;
1588 case 7: RegNo = X86::ST7;
break;
1591 return Error(IntTok.
getLoc(),
"invalid stack index");
1611 if (isParsingIntelSyntax())
return true;
1612 return Error(StartLoc,
"invalid register name",
1613 SMRange(StartLoc, EndLoc));
1620bool X86AsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1622 return ParseRegister(
Reg, StartLoc, EndLoc,
false);
1625ParseStatus X86AsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1627 bool Result = ParseRegister(
Reg, StartLoc, EndLoc,
true);
1628 bool PendingErrors = getParser().hasPendingError();
1629 getParser().clearPendingErrors();
1637std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(SMLoc Loc) {
1638 bool Parse32 = is32BitMode() || Code16GCC;
1639 MCRegister Basereg =
1640 is64BitMode() ? X86::RSI : (Parse32 ? X86::ESI : X86::SI);
1647std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand(SMLoc Loc) {
1648 bool Parse32 = is32BitMode() || Code16GCC;
1649 MCRegister Basereg =
1650 is64BitMode() ? X86::RDI : (Parse32 ? X86::EDI : X86::DI);
1657bool X86AsmParser::IsSIReg(MCRegister
Reg) {
1671MCRegister X86AsmParser::GetSIDIForRegClass(
unsigned RegClassID,
bool IsSIReg) {
1672 switch (RegClassID) {
1674 case X86::GR64RegClassID:
1675 return IsSIReg ? X86::RSI : X86::RDI;
1676 case X86::GR32RegClassID:
1677 return IsSIReg ? X86::ESI : X86::EDI;
1678 case X86::GR16RegClassID:
1679 return IsSIReg ? X86::SI : X86::DI;
1683void X86AsmParser::AddDefaultSrcDestOperands(
1684 OperandVector& Operands, std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
1685 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst) {
1686 if (isParsingIntelSyntax()) {
1696bool X86AsmParser::VerifyAndAdjustOperands(
OperandVector &OrigOperands,
1699 if (OrigOperands.
size() > 1) {
1702 "Operand size mismatch");
1706 int RegClassID = -1;
1707 for (
unsigned int i = 0; i < FinalOperands.
size(); ++i) {
1708 X86Operand &OrigOp =
static_cast<X86Operand &
>(*OrigOperands[i + 1]);
1709 X86Operand &FinalOp =
static_cast<X86Operand &
>(*FinalOperands[i]);
1711 if (FinalOp.
isReg() &&
1716 if (FinalOp.
isMem()) {
1718 if (!OrigOp.
isMem())
1727 if (RegClassID != -1 &&
1728 !X86MCRegisterClasses[RegClassID].
contains(OrigReg)) {
1730 "mismatching source and destination index registers");
1733 if (X86MCRegisterClasses[X86::GR64RegClassID].
contains(OrigReg))
1734 RegClassID = X86::GR64RegClassID;
1735 else if (X86MCRegisterClasses[X86::GR32RegClassID].
contains(OrigReg))
1736 RegClassID = X86::GR32RegClassID;
1737 else if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(OrigReg))
1738 RegClassID = X86::GR16RegClassID;
1744 bool IsSI = IsSIReg(FinalReg);
1745 FinalReg = GetSIDIForRegClass(RegClassID, IsSI);
1747 if (FinalReg != OrigReg) {
1748 std::string
RegName = IsSI ?
"ES:(R|E)SI" :
"ES:(R|E)DI";
1751 "memory operand is only for determining the size, " +
RegName +
1752 " will be used for the location"));
1763 for (
auto &WarningMsg : Warnings) {
1764 Warning(WarningMsg.first, WarningMsg.second);
1768 for (
unsigned int i = 0; i < FinalOperands.
size(); ++i)
1772 for (
auto &
Op : FinalOperands)
1778bool X86AsmParser::parseOperand(
OperandVector &Operands, StringRef Name) {
1779 if (isParsingIntelSyntax())
1780 return parseIntelOperand(Operands, Name);
1782 return parseATTOperand(Operands);
1785bool X86AsmParser::CreateMemForMSInlineAsm(
1786 MCRegister SegReg,
const MCExpr *Disp, MCRegister BaseReg,
1787 MCRegister IndexReg,
unsigned Scale,
bool NonAbsMem, SMLoc Start, SMLoc End,
1788 unsigned Size, StringRef Identifier,
const InlineAsmIdentifierInfo &Info,
1796 End,
Size, Identifier,
1803 unsigned FrontendSize = 0;
1804 void *Decl =
nullptr;
1805 bool IsGlobalLV =
false;
1808 FrontendSize =
Info.Var.Type * 8;
1809 Decl =
Info.Var.Decl;
1810 IsGlobalLV =
Info.Var.IsGlobalLV;
1815 if (BaseReg || IndexReg) {
1817 End,
Size, Identifier, Decl, 0,
1818 BaseReg && IndexReg));
1825 getPointerWidth(), SegReg, Disp, BaseReg, IndexReg, Scale, Start, End,
1827 X86::RIP, Identifier, Decl, FrontendSize));
1834bool X86AsmParser::ParseIntelNamedOperator(StringRef Name,
1835 IntelExprStateMachine &
SM,
1836 bool &ParseError, SMLoc &End) {
1839 if (Name !=
Name.lower() && Name !=
Name.upper() &&
1840 !getParser().isParsingMasm())
1842 if (
Name.equals_insensitive(
"not")) {
1844 }
else if (
Name.equals_insensitive(
"or")) {
1846 }
else if (
Name.equals_insensitive(
"shl")) {
1848 }
else if (
Name.equals_insensitive(
"shr")) {
1850 }
else if (
Name.equals_insensitive(
"xor")) {
1852 }
else if (
Name.equals_insensitive(
"and")) {
1854 }
else if (
Name.equals_insensitive(
"mod")) {
1856 }
else if (
Name.equals_insensitive(
"offset")) {
1857 SMLoc OffsetLoc = getTok().getLoc();
1858 const MCExpr *Val =
nullptr;
1860 InlineAsmIdentifierInfo
Info;
1861 ParseError = ParseIntelOffsetOperator(Val,
ID, Info, End);
1866 SM.onOffset(Val, OffsetLoc,
ID, Info, isParsingMSInlineAsm(), ErrMsg);
1872 if (!
Name.equals_insensitive(
"offset"))
1873 End = consumeToken();
1876bool X86AsmParser::ParseMasmNamedOperator(StringRef Name,
1877 IntelExprStateMachine &
SM,
1878 bool &ParseError, SMLoc &End) {
1879 if (
Name.equals_insensitive(
"eq")) {
1881 }
else if (
Name.equals_insensitive(
"ne")) {
1883 }
else if (
Name.equals_insensitive(
"lt")) {
1885 }
else if (
Name.equals_insensitive(
"le")) {
1887 }
else if (
Name.equals_insensitive(
"gt")) {
1889 }
else if (
Name.equals_insensitive(
"ge")) {
1894 End = consumeToken();
1901 IntelExprStateMachine &
SM) {
1905 SM.setAppendAfterOperand();
1908bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &
SM, SMLoc &End) {
1909 MCAsmParser &Parser = getParser();
1914 if (
getContext().getObjectFileInfo()->isPositionIndependent())
1921 const AsmToken &Tok = Parser.
getTok();
1923 bool UpdateLocLex =
true;
1928 if ((
Done =
SM.isValidEndState()))
1930 return Error(Tok.
getLoc(),
"unknown token in expression");
1932 return Error(getLexer().getErrLoc(), getLexer().getErr());
1936 UpdateLocLex =
false;
1937 if (ParseIntelDotOperator(
SM, End))
1942 if ((
Done =
SM.isValidEndState()))
1944 return Error(Tok.
getLoc(),
"unknown token in expression");
1948 UpdateLocLex =
false;
1949 if (ParseIntelDotOperator(
SM, End))
1954 if ((
Done =
SM.isValidEndState()))
1956 return Error(Tok.
getLoc(),
"unknown token in expression");
1962 SMLoc ValueLoc = Tok.
getLoc();
1967 UpdateLocLex =
false;
1968 if (!Val->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
1969 return Error(ValueLoc,
"expected absolute value");
1970 if (
SM.onInteger(Res, ErrMsg))
1971 return Error(ValueLoc, ErrMsg);
1978 SMLoc IdentLoc = Tok.
getLoc();
1980 UpdateLocLex =
false;
1982 size_t DotOffset =
Identifier.find_first_of(
'.');
1986 StringRef Dot =
Identifier.substr(DotOffset, 1);
2000 const AsmToken &NextTok = getLexer().peekTok();
2009 End = consumeToken();
2016 if (!ParseRegister(
Reg, IdentLoc, End,
true)) {
2017 if (
SM.onRegister(
Reg, ErrMsg))
2018 return Error(IdentLoc, ErrMsg);
2022 const std::pair<StringRef, StringRef> IDField =
2024 const StringRef
ID = IDField.first,
Field = IDField.second;
2026 if (!
Field.empty() &&
2027 !MatchRegisterByName(
Reg,
ID, IdentLoc, IDEndLoc)) {
2028 if (
SM.onRegister(
Reg, ErrMsg))
2029 return Error(IdentLoc, ErrMsg);
2034 return Error(FieldStartLoc,
"unknown offset");
2035 else if (
SM.onPlus(ErrMsg))
2036 return Error(getTok().getLoc(), ErrMsg);
2037 else if (
SM.onInteger(
Info.Offset, ErrMsg))
2038 return Error(IdentLoc, ErrMsg);
2039 SM.setTypeInfo(
Info.Type);
2041 End = consumeToken();
2048 if (ParseIntelNamedOperator(Identifier,
SM, ParseError, End)) {
2054 ParseMasmNamedOperator(Identifier,
SM, ParseError, End)) {
2060 InlineAsmIdentifierInfo
Info;
2061 AsmFieldInfo FieldInfo;
2067 if (ParseIntelDotOperator(
SM, End))
2072 if (isParsingMSInlineAsm()) {
2074 if (
unsigned OpKind = IdentifyIntelInlineAsmOperator(Identifier)) {
2075 if (int64_t Val = ParseIntelInlineAsmOperator(OpKind)) {
2076 if (
SM.onInteger(Val, ErrMsg))
2077 return Error(IdentLoc, ErrMsg);
2086 return Error(IdentLoc,
"expected identifier");
2087 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
false, End))
2089 else if (
SM.onIdentifierExpr(Val, Identifier, Info, FieldInfo.
Type,
2091 return Error(IdentLoc, ErrMsg);
2095 if (
unsigned OpKind = IdentifyMasmOperator(Identifier)) {
2097 if (ParseMasmOperator(OpKind, Val))
2099 if (
SM.onInteger(Val, ErrMsg))
2100 return Error(IdentLoc, ErrMsg);
2103 if (!getParser().lookUpType(Identifier, FieldInfo.
Type)) {
2109 getParser().parseIdentifier(Identifier);
2113 if (getParser().lookUpField(FieldInfo.
Type.
Name, Identifier,
2117 return Error(IdentLoc,
"Unable to lookup field reference!",
2118 SMRange(IdentLoc, IDEnd));
2123 if (
SM.onInteger(FieldInfo.
Offset, ErrMsg))
2124 return Error(IdentLoc, ErrMsg);
2128 if (getParser().parsePrimaryExpr(Val, End, &FieldInfo.
Type)) {
2129 return Error(Tok.
getLoc(),
"Unexpected identifier!");
2130 }
else if (
SM.onIdentifierExpr(Val, Identifier, Info, FieldInfo.
Type,
2132 return Error(IdentLoc, ErrMsg);
2138 SMLoc Loc = getTok().getLoc();
2139 int64_t
IntVal = getTok().getIntVal();
2140 End = consumeToken();
2141 UpdateLocLex =
false;
2143 StringRef IDVal = getTok().getString();
2144 if (IDVal ==
"f" || IDVal ==
"b") {
2146 getContext().getDirectionalLocalSymbol(IntVal, IDVal ==
"b");
2151 return Error(Loc,
"invalid reference to undefined symbol");
2153 InlineAsmIdentifierInfo
Info;
2155 if (
SM.onIdentifierExpr(Val, Identifier, Info,
Type,
2156 isParsingMSInlineAsm(), ErrMsg))
2157 return Error(Loc, ErrMsg);
2158 End = consumeToken();
2160 if (
SM.onInteger(IntVal, ErrMsg))
2161 return Error(Loc, ErrMsg);
2164 if (
SM.onInteger(IntVal, ErrMsg))
2165 return Error(Loc, ErrMsg);
2170 if (
SM.onPlus(ErrMsg))
2171 return Error(getTok().getLoc(), ErrMsg);
2174 if (
SM.onMinus(ErrMsg))
2175 return Error(getTok().getLoc(), ErrMsg);
2185 SM.onLShift();
break;
2187 SM.onRShift();
break;
2190 return Error(Tok.
getLoc(),
"unexpected bracket encountered");
2191 tryParseOperandIdx(PrevTK,
SM);
2194 if (
SM.onRBrac(ErrMsg)) {
2200 if (
SM.onRParen(ErrMsg)) {
2206 return Error(Tok.
getLoc(),
"unknown token in expression");
2208 if (!
Done && UpdateLocLex)
2209 End = consumeToken();
2216void X86AsmParser::RewriteIntelExpression(IntelExprStateMachine &
SM,
2217 SMLoc Start, SMLoc End) {
2221 if (
SM.getSym() && !
SM.isOffsetOperator()) {
2222 StringRef SymName =
SM.getSymName();
2223 if (
unsigned Len = SymName.
data() -
Start.getPointer())
2229 if (!(
SM.getBaseReg() ||
SM.getIndexReg() ||
SM.getImm())) {
2236 StringRef BaseRegStr;
2237 StringRef IndexRegStr;
2238 StringRef OffsetNameStr;
2239 if (
SM.getBaseReg())
2241 if (
SM.getIndexReg())
2243 if (
SM.isOffsetOperator())
2244 OffsetNameStr =
SM.getSymName();
2246 IntelExpr Expr(BaseRegStr, IndexRegStr,
SM.getScale(), OffsetNameStr,
2247 SM.getImm(),
SM.isMemExpr());
2248 InstInfo->
AsmRewrites->emplace_back(Loc, ExprLen, Expr);
2252bool X86AsmParser::ParseIntelInlineAsmIdentifier(
2253 const MCExpr *&Val, StringRef &Identifier, InlineAsmIdentifierInfo &Info,
2254 bool IsUnevaluatedOperand, SMLoc &End,
bool IsParsingOffsetOperator) {
2255 MCAsmParser &Parser = getParser();
2256 assert(isParsingMSInlineAsm() &&
"Expected to be parsing inline assembly.");
2260 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);
2262 const AsmToken &Tok = Parser.
getTok();
2263 SMLoc Loc = Tok.
getLoc();
2278 "frontend claimed part of a token?");
2283 StringRef InternalName =
2284 SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(),
2286 assert(InternalName.
size() &&
"We should have an internal name here.");
2289 if (!IsParsingOffsetOperator)
2304bool X86AsmParser::ParseRoundingModeOp(SMLoc Start,
OperandVector &Operands) {
2305 MCAsmParser &Parser = getParser();
2306 const AsmToken &Tok = Parser.
getTok();
2308 const SMLoc consumedToken = consumeToken();
2310 return Error(Tok.
getLoc(),
"Expected an identifier after {");
2313 .Case(
"rn", X86::STATIC_ROUNDING::TO_NEAREST_INT)
2314 .Case(
"rd", X86::STATIC_ROUNDING::TO_NEG_INF)
2315 .Case(
"ru", X86::STATIC_ROUNDING::TO_POS_INF)
2316 .Case(
"rz", X86::STATIC_ROUNDING::TO_ZERO)
2319 return Error(Tok.
getLoc(),
"Invalid rounding mode.");
2322 return Error(Tok.
getLoc(),
"Expected - at this point");
2326 return Error(Tok.
getLoc(),
"Expected } at this point");
2329 const MCExpr *RndModeOp =
2337 return Error(Tok.
getLoc(),
"Expected } at this point");
2342 return Error(Tok.
getLoc(),
"unknown token in expression");
2348 MCAsmParser &Parser = getParser();
2349 AsmToken Tok = Parser.
getTok();
2352 return Error(Tok.
getLoc(),
"Expected { at this point");
2356 return Error(Tok.
getLoc(),
"Expected dfv at this point");
2360 return Error(Tok.
getLoc(),
"Expected = at this point");
2372 unsigned CFlags = 0;
2373 for (
unsigned I = 0;
I < 4; ++
I) {
2382 return Error(Tok.
getLoc(),
"Invalid conditional flags");
2385 return Error(Tok.
getLoc(),
"Duplicated conditional flag");
2396 }
else if (
I == 3) {
2397 return Error(Tok.
getLoc(),
"Expected } at this point");
2399 return Error(Tok.
getLoc(),
"Expected } or , at this point");
2407bool X86AsmParser::ParseIntelDotOperator(IntelExprStateMachine &
SM,
2409 const AsmToken &Tok = getTok();
2415 bool TrailingDot =
false;
2423 }
else if ((isParsingMSInlineAsm() || getParser().isParsingMasm()) &&
2426 const std::pair<StringRef, StringRef> BaseMember = DotDispStr.
split(
'.');
2427 const StringRef
Base = BaseMember.first,
Member = BaseMember.second;
2428 if (getParser().lookUpField(
SM.getType(), DotDispStr, Info) &&
2429 getParser().lookUpField(
SM.getSymName(), DotDispStr, Info) &&
2430 getParser().lookUpField(DotDispStr, Info) &&
2432 SemaCallback->LookupInlineAsmField(
Base, Member,
Info.Offset)))
2433 return Error(Tok.
getLoc(),
"Unable to lookup field reference!");
2435 return Error(Tok.
getLoc(),
"Unexpected token type!");
2440 const char *DotExprEndLoc = DotDispStr.
data() + DotDispStr.
size();
2446 SM.setTypeInfo(
Info.Type);
2452bool X86AsmParser::ParseIntelOffsetOperator(
const MCExpr *&Val, StringRef &
ID,
2453 InlineAsmIdentifierInfo &Info,
2456 SMLoc
Start = Lex().getLoc();
2457 ID = getTok().getString();
2458 if (!isParsingMSInlineAsm()) {
2461 getParser().parsePrimaryExpr(Val, End,
nullptr))
2462 return Error(Start,
"unexpected token!");
2463 }
else if (ParseIntelInlineAsmIdentifier(Val,
ID, Info,
false, End,
true)) {
2464 return Error(Start,
"unable to lookup expression");
2466 return Error(Start,
"offset operator cannot yet handle constants");
2473unsigned X86AsmParser::IdentifyIntelInlineAsmOperator(StringRef Name) {
2474 return StringSwitch<unsigned>(Name)
2475 .Cases({
"TYPE",
"type"}, IOK_TYPE)
2476 .Cases({
"SIZE",
"size"}, IOK_SIZE)
2477 .Cases({
"LENGTH",
"length"}, IOK_LENGTH)
2487unsigned X86AsmParser::ParseIntelInlineAsmOperator(
unsigned OpKind) {
2488 MCAsmParser &Parser = getParser();
2489 const AsmToken &Tok = Parser.
getTok();
2492 const MCExpr *Val =
nullptr;
2493 InlineAsmIdentifierInfo
Info;
2496 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
2501 Error(Start,
"unable to lookup expression");
2508 case IOK_LENGTH: CVal =
Info.Var.Length;
break;
2509 case IOK_SIZE: CVal =
Info.Var.Size;
break;
2510 case IOK_TYPE: CVal =
Info.Var.Type;
break;
2518unsigned X86AsmParser::IdentifyMasmOperator(StringRef Name) {
2519 return StringSwitch<unsigned>(
Name.lower())
2520 .Case(
"type", MOK_TYPE)
2521 .Cases({
"size",
"sizeof"}, MOK_SIZEOF)
2522 .Cases({
"length",
"lengthof"}, MOK_LENGTHOF)
2532bool X86AsmParser::ParseMasmOperator(
unsigned OpKind, int64_t &Val) {
2533 MCAsmParser &Parser = getParser();
2538 if (OpKind == MOK_SIZEOF || OpKind == MOK_TYPE) {
2541 const AsmToken &IDTok = InParens ? getLexer().peekTok() : Parser.
getTok();
2557 IntelExprStateMachine
SM;
2559 if (ParseIntelExpression(
SM, End))
2569 Val =
SM.getLength();
2572 Val =
SM.getElementSize();
2577 return Error(OpLoc,
"expression has unknown type", SMRange(Start, End));
2583bool X86AsmParser::ParseIntelMemoryOperandSize(
unsigned &
Size,
2584 StringRef *SizeStr) {
2585 Size = StringSwitch<unsigned>(getTok().getString())
2586 .Cases({
"BYTE",
"byte"}, 8)
2587 .Cases({
"WORD",
"word"}, 16)
2588 .Cases({
"DWORD",
"dword"}, 32)
2589 .Cases({
"FLOAT",
"float"}, 32)
2590 .Cases({
"LONG",
"long"}, 32)
2591 .Cases({
"FWORD",
"fword"}, 48)
2592 .Cases({
"DOUBLE",
"double"}, 64)
2593 .Cases({
"QWORD",
"qword"}, 64)
2594 .Cases({
"MMWORD",
"mmword"}, 64)
2595 .Cases({
"XWORD",
"xword"}, 80)
2596 .Cases({
"TBYTE",
"tbyte"}, 80)
2597 .Cases({
"XMMWORD",
"xmmword"}, 128)
2598 .Cases({
"YMMWORD",
"ymmword"}, 256)
2599 .Cases({
"ZMMWORD",
"zmmword"}, 512)
2603 *SizeStr = getTok().getString();
2604 const AsmToken &Tok = Lex();
2606 return Error(Tok.
getLoc(),
"Expected 'PTR' or 'ptr' token!");
2613 if (X86MCRegisterClasses[X86::GR8RegClassID].
contains(RegNo))
2615 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(RegNo))
2617 if (X86MCRegisterClasses[X86::GR32RegClassID].
contains(RegNo))
2619 if (X86MCRegisterClasses[X86::GR64RegClassID].
contains(RegNo))
2625bool X86AsmParser::parseIntelOperand(
OperandVector &Operands, StringRef Name) {
2626 MCAsmParser &Parser = getParser();
2627 const AsmToken &Tok = Parser.
getTok();
2633 if (ParseIntelMemoryOperandSize(
Size, &SizeStr))
2635 bool PtrInOperand = bool(
Size);
2641 return ParseRoundingModeOp(Start, Operands);
2646 if (RegNo == X86::RIP)
2647 return Error(Start,
"rip can only be used as a base register");
2652 return Error(Start,
"expected memory operand after 'ptr', "
2653 "found register operand instead");
2662 "cannot cast register '" +
2664 "'; its size is not easily defined.");
2668 std::to_string(
RegSize) +
"-bit register '" +
2670 "' cannot be used as a " + std::to_string(
Size) +
"-bit " +
2677 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].
contains(RegNo))
2678 return Error(Start,
"invalid segment register");
2680 Start = Lex().getLoc();
2684 IntelExprStateMachine
SM;
2685 if (ParseIntelExpression(
SM, End))
2688 if (isParsingMSInlineAsm())
2689 RewriteIntelExpression(
SM, Start, Tok.
getLoc());
2691 int64_t
Imm =
SM.getImm();
2692 const MCExpr *Disp =
SM.getSym();
2701 if (!
SM.isMemExpr() && !RegNo) {
2702 if (isParsingMSInlineAsm() &&
SM.isOffsetOperator()) {
2703 const InlineAsmIdentifierInfo &
Info =
SM.getIdentifierInfo();
2708 SM.getSymName(),
Info.Var.Decl,
2709 Info.Var.IsGlobalLV));
2720 MCRegister IndexReg =
SM.getIndexReg();
2721 if (IndexReg && BaseReg == X86::RIP)
2723 unsigned Scale =
SM.getScale();
2725 Size =
SM.getElementSize() << 3;
2727 if (Scale == 0 && BaseReg != X86::ESP && BaseReg != X86::RSP &&
2728 (IndexReg == X86::ESP || IndexReg == X86::RSP))
2734 !(X86MCRegisterClasses[X86::VR128XRegClassID].
contains(IndexReg) ||
2735 X86MCRegisterClasses[X86::VR256XRegClassID].
contains(IndexReg) ||
2736 X86MCRegisterClasses[X86::VR512RegClassID].
contains(IndexReg)) &&
2737 (X86MCRegisterClasses[X86::VR128XRegClassID].
contains(BaseReg) ||
2738 X86MCRegisterClasses[X86::VR256XRegClassID].
contains(BaseReg) ||
2739 X86MCRegisterClasses[X86::VR512RegClassID].
contains(BaseReg)))
2743 X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg))
2744 return Error(Start,
"16-bit addresses cannot have a scale");
2753 if ((BaseReg == X86::SI || BaseReg == X86::DI) &&
2754 (IndexReg == X86::BX || IndexReg == X86::BP))
2757 if ((BaseReg || IndexReg) &&
2760 return Error(Start, ErrMsg);
2761 bool IsUnconditionalBranch =
2762 Name.equals_insensitive(
"jmp") ||
Name.equals_insensitive(
"call");
2763 if (isParsingMSInlineAsm())
2764 return CreateMemForMSInlineAsm(RegNo, Disp, BaseReg, IndexReg, Scale,
2765 IsUnconditionalBranch && is64BitMode(),
2766 Start, End,
Size,
SM.getSymName(),
2767 SM.getIdentifierInfo(), Operands);
2771 MCRegister DefaultBaseReg;
2772 bool MaybeDirectBranchDest =
true;
2775 if (is64BitMode() &&
2776 ((PtrInOperand && !IndexReg) ||
SM.getElementSize() > 0)) {
2777 DefaultBaseReg = X86::RIP;
2779 if (IsUnconditionalBranch) {
2781 MaybeDirectBranchDest =
false;
2783 DefaultBaseReg = X86::RIP;
2784 }
else if (!BaseReg && !IndexReg && Disp &&
2786 if (is64BitMode()) {
2787 if (
SM.getSize() == 8) {
2788 MaybeDirectBranchDest =
false;
2789 DefaultBaseReg = X86::RIP;
2792 if (
SM.getSize() == 4 ||
SM.getSize() == 2)
2793 MaybeDirectBranchDest =
false;
2797 }
else if (IsUnconditionalBranch) {
2799 if (!PtrInOperand &&
SM.isOffsetOperator())
2801 Start,
"`OFFSET` operator cannot be used in an unconditional branch");
2802 if (PtrInOperand ||
SM.isBracketUsed())
2803 MaybeDirectBranchDest =
false;
2806 if (CheckDispOverflow(BaseReg, IndexReg, Disp, Start))
2809 if ((BaseReg || IndexReg || RegNo || DefaultBaseReg))
2811 getPointerWidth(), RegNo, Disp, BaseReg, IndexReg, Scale, Start, End,
2812 Size, DefaultBaseReg, StringRef(),
nullptr,
2813 0,
false, MaybeDirectBranchDest));
2816 getPointerWidth(), Disp, Start, End,
Size, StringRef(),
2818 MaybeDirectBranchDest));
2822bool X86AsmParser::parseATTOperand(
OperandVector &Operands) {
2823 MCAsmParser &Parser = getParser();
2824 switch (getLexer().getKind()) {
2834 "expected immediate expression") ||
2835 getParser().parseExpression(Val, End) ||
2843 return ParseRoundingModeOp(Start, Operands);
2852 const MCExpr *Expr =
nullptr;
2864 if (
Reg == X86::EIZ ||
Reg == X86::RIZ)
2866 Loc,
"%eiz and %riz can only be used as index registers",
2867 SMRange(Loc, EndLoc));
2868 if (
Reg == X86::RIP)
2869 return Error(Loc,
"%rip can only be used as a base register",
2870 SMRange(Loc, EndLoc));
2876 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].
contains(
Reg))
2877 return Error(Loc,
"invalid segment register");
2885 return ParseMemOperand(
Reg, Expr, Loc, EndLoc, Operands);
2892X86::CondCode X86AsmParser::ParseConditionCode(StringRef CC) {
2893 return StringSwitch<X86::CondCode>(CC)
2915bool X86AsmParser::ParseZ(std::unique_ptr<X86Operand> &Z, SMLoc StartLoc) {
2916 MCAsmParser &Parser = getParser();
2921 (getLexer().getTok().getIdentifier() ==
"z")))
2926 return Error(getLexer().getLoc(),
"Expected } at this point");
2934bool X86AsmParser::HandleAVX512Operand(
OperandVector &Operands) {
2935 MCAsmParser &Parser = getParser();
2938 const SMLoc consumedToken = consumeToken();
2942 if (getLexer().getTok().getIntVal() != 1)
2943 return TokError(
"Expected 1to<NUM> at this point");
2944 StringRef
Prefix = getLexer().getTok().getString();
2947 return TokError(
"Expected 1to<NUM> at this point");
2950 StringRef BroadcastString = (
Prefix + getLexer().getTok().getIdentifier())
2953 return TokError(
"Expected 1to<NUM> at this point");
2954 const char *BroadcastPrimitive =
2955 StringSwitch<const char *>(BroadcastString)
2956 .Case(
"1to2",
"{1to2}")
2957 .Case(
"1to4",
"{1to4}")
2958 .Case(
"1to8",
"{1to8}")
2959 .Case(
"1to16",
"{1to16}")
2960 .Case(
"1to32",
"{1to32}")
2962 if (!BroadcastPrimitive)
2963 return TokError(
"Invalid memory broadcast primitive.");
2966 return TokError(
"Expected } at this point");
2977 std::unique_ptr<X86Operand>
Z;
2978 if (ParseZ(Z, consumedToken))
2984 SMLoc StartLoc =
Z ? consumeToken() : consumedToken;
2989 if (!parseRegister(RegNo, RegLoc, StartLoc) &&
2990 X86MCRegisterClasses[X86::VK1RegClassID].
contains(RegNo)) {
2991 if (RegNo == X86::K0)
2992 return Error(RegLoc,
"Register k0 can't be used as write mask");
2994 return Error(getLexer().getLoc(),
"Expected } at this point");
3000 return Error(getLexer().getLoc(),
3001 "Expected an op-mask register at this point");
3006 if (ParseZ(Z, consumeToken()) || !Z)
3007 return Error(getLexer().getLoc(),
3008 "Expected a {z} mark at this point");
3023bool X86AsmParser::CheckDispOverflow(MCRegister BaseReg, MCRegister IndexReg,
3024 const MCExpr *Disp, SMLoc Loc) {
3030 if (BaseReg || IndexReg) {
3032 auto Imm =
CE->getValue();
3033 bool Is64 = X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) ||
3034 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg);
3035 bool Is16 = X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg);
3038 return Error(Loc,
"displacement " + Twine(Imm) +
3039 " is not within [-2147483648, 2147483647]");
3041 if (!
isUInt<32>(Imm < 0 ? -uint64_t(Imm) : uint64_t(Imm))) {
3042 Warning(Loc,
"displacement " + Twine(Imm) +
3043 " shortened to 32-bit signed " +
3044 Twine(
static_cast<int32_t
>(Imm)));
3046 }
else if (!
isUInt<16>(Imm < 0 ? -uint64_t(Imm) : uint64_t(Imm))) {
3047 Warning(Loc,
"displacement " + Twine(Imm) +
3048 " shortened to 16-bit signed " +
3049 Twine(
static_cast<int16_t
>(Imm)));
3058bool X86AsmParser::ParseMemOperand(MCRegister SegReg,
const MCExpr *Disp,
3059 SMLoc StartLoc, SMLoc EndLoc,
3061 MCAsmParser &Parser = getParser();
3079 auto isAtMemOperand = [
this]() {
3084 auto TokCount = this->getLexer().peekTokens(Buf,
true);
3087 switch (Buf[0].getKind()) {
3094 if ((TokCount > 1) &&
3098 Buf[1].getIdentifier().
size() + 1);
3120 if (!isAtMemOperand()) {
3139 0, 0, 1, StartLoc, EndLoc));
3147 SMLoc BaseLoc = getLexer().getLoc();
3159 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ)
3160 return Error(BaseLoc,
"eiz and riz can only be used as index registers",
3161 SMRange(BaseLoc, EndLoc));
3179 if (!
E->evaluateAsAbsolute(ScaleVal, getStreamer().getAssemblerPtr()))
3180 return Error(Loc,
"expected absolute expression");
3182 Warning(Loc,
"scale factor without index register is ignored");
3187 if (BaseReg == X86::RIP)
3189 "%rip as base register can not have an index register");
3190 if (IndexReg == X86::RIP)
3191 return Error(Loc,
"%rip is not allowed as an index register");
3202 return Error(Loc,
"expected scale expression");
3203 Scale = (unsigned)ScaleVal;
3205 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg) &&
3207 return Error(Loc,
"scale factor in 16-bit address must be 1");
3209 return Error(Loc, ErrMsg);
3223 if (BaseReg == X86::DX && !IndexReg && Scale == 1 && !SegReg &&
3232 return Error(BaseLoc, ErrMsg);
3234 if (CheckDispOverflow(BaseReg, IndexReg, Disp, BaseLoc))
3237 if (SegReg || BaseReg || IndexReg)
3239 BaseReg, IndexReg, Scale, StartLoc,
3248bool X86AsmParser::parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
3249 MCAsmParser &Parser = getParser();
3256 if (parseRegister(RegNo, StartLoc, EndLoc))
3264bool X86AsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
3266 MCAsmParser &Parser = getParser();
3270 ForcedOpcodePrefix = OpcodePrefix_Default;
3271 ForcedDispEncoding = DispEncoding_Default;
3272 UseApxExtendedReg =
false;
3273 ForcedNoFlag =
false;
3286 if (Prefix ==
"rex")
3287 ForcedOpcodePrefix = OpcodePrefix_REX;
3288 else if (Prefix ==
"rex2")
3289 ForcedOpcodePrefix = OpcodePrefix_REX2;
3290 else if (Prefix ==
"vex")
3291 ForcedOpcodePrefix = OpcodePrefix_VEX;
3292 else if (Prefix ==
"vex2")
3293 ForcedOpcodePrefix = OpcodePrefix_VEX2;
3294 else if (Prefix ==
"vex3")
3295 ForcedOpcodePrefix = OpcodePrefix_VEX3;
3296 else if (Prefix ==
"evex")
3297 ForcedOpcodePrefix = OpcodePrefix_EVEX;
3298 else if (Prefix ==
"disp8")
3299 ForcedDispEncoding = DispEncoding_Disp8;
3300 else if (Prefix ==
"disp32")
3301 ForcedDispEncoding = DispEncoding_Disp32;
3302 else if (Prefix ==
"nf")
3303 ForcedNoFlag =
true;
3305 return Error(NameLoc,
"unknown prefix");
3321 if (isParsingMSInlineAsm()) {
3322 if (
Name.equals_insensitive(
"vex"))
3323 ForcedOpcodePrefix = OpcodePrefix_VEX;
3324 else if (
Name.equals_insensitive(
"vex2"))
3325 ForcedOpcodePrefix = OpcodePrefix_VEX2;
3326 else if (
Name.equals_insensitive(
"vex3"))
3327 ForcedOpcodePrefix = OpcodePrefix_VEX3;
3328 else if (
Name.equals_insensitive(
"evex"))
3329 ForcedOpcodePrefix = OpcodePrefix_EVEX;
3331 if (ForcedOpcodePrefix != OpcodePrefix_Default) {
3344 if (
Name.consume_back(
".d32")) {
3345 ForcedDispEncoding = DispEncoding_Disp32;
3346 }
else if (
Name.consume_back(
".d8")) {
3347 ForcedDispEncoding = DispEncoding_Disp8;
3350 StringRef PatchedName =
Name;
3353 if (isParsingIntelSyntax() &&
3354 (PatchedName ==
"jmp" || PatchedName ==
"jc" || PatchedName ==
"jnc" ||
3355 PatchedName ==
"jcxz" || PatchedName ==
"jecxz" ||
3360 : NextTok ==
"short") {
3369 NextTok.
size() + 1);
3375 PatchedName !=
"setzub" && PatchedName !=
"setzunb" &&
3376 PatchedName !=
"setb" && PatchedName !=
"setnb")
3377 PatchedName = PatchedName.
substr(0,
Name.size()-1);
3379 unsigned ComparisonPredicate = ~0
U;
3387 bool IsVCMP = PatchedName[0] ==
'v';
3388 unsigned CCIdx =
IsVCMP ? 4 : 3;
3389 unsigned suffixLength = PatchedName.
ends_with(
"bf16") ? 5 : 2;
3390 unsigned CC = StringSwitch<unsigned>(
3391 PatchedName.
slice(CCIdx, PatchedName.
size() - suffixLength))
3393 .Case(
"eq_oq", 0x00)
3395 .Case(
"lt_os", 0x01)
3397 .Case(
"le_os", 0x02)
3398 .Case(
"unord", 0x03)
3399 .Case(
"unord_q", 0x03)
3401 .Case(
"neq_uq", 0x04)
3403 .Case(
"nlt_us", 0x05)
3405 .Case(
"nle_us", 0x06)
3407 .Case(
"ord_q", 0x07)
3409 .Case(
"eq_uq", 0x08)
3411 .Case(
"nge_us", 0x09)
3413 .Case(
"ngt_us", 0x0A)
3414 .Case(
"false", 0x0B)
3415 .Case(
"false_oq", 0x0B)
3416 .Case(
"neq_oq", 0x0C)
3418 .Case(
"ge_os", 0x0D)
3420 .Case(
"gt_os", 0x0E)
3422 .Case(
"true_uq", 0x0F)
3423 .Case(
"eq_os", 0x10)
3424 .Case(
"lt_oq", 0x11)
3425 .Case(
"le_oq", 0x12)
3426 .Case(
"unord_s", 0x13)
3427 .Case(
"neq_us", 0x14)
3428 .Case(
"nlt_uq", 0x15)
3429 .Case(
"nle_uq", 0x16)
3430 .Case(
"ord_s", 0x17)
3431 .Case(
"eq_us", 0x18)
3432 .Case(
"nge_uq", 0x19)
3433 .Case(
"ngt_uq", 0x1A)
3434 .Case(
"false_os", 0x1B)
3435 .Case(
"neq_os", 0x1C)
3436 .Case(
"ge_oq", 0x1D)
3437 .Case(
"gt_oq", 0x1E)
3438 .Case(
"true_us", 0x1F)
3440 if (CC != ~0U && (
IsVCMP || CC < 8) &&
3443 PatchedName =
IsVCMP ?
"vcmpss" :
"cmpss";
3445 PatchedName =
IsVCMP ?
"vcmpsd" :
"cmpsd";
3447 PatchedName =
IsVCMP ?
"vcmpps" :
"cmpps";
3449 PatchedName =
IsVCMP ?
"vcmppd" :
"cmppd";
3451 PatchedName =
"vcmpsh";
3453 PatchedName =
"vcmpph";
3455 PatchedName =
"vcmpbf16";
3459 ComparisonPredicate = CC;
3465 (PatchedName.
back() ==
'b' || PatchedName.
back() ==
'w' ||
3466 PatchedName.
back() ==
'd' || PatchedName.
back() ==
'q')) {
3467 unsigned SuffixSize = PatchedName.
drop_back().
back() ==
'u' ? 2 : 1;
3468 unsigned CC = StringSwitch<unsigned>(
3469 PatchedName.
slice(5, PatchedName.
size() - SuffixSize))
3479 if (CC != ~0U && (CC != 0 || SuffixSize == 2)) {
3480 switch (PatchedName.
back()) {
3482 case 'b': PatchedName = SuffixSize == 2 ?
"vpcmpub" :
"vpcmpb";
break;
3483 case 'w': PatchedName = SuffixSize == 2 ?
"vpcmpuw" :
"vpcmpw";
break;
3484 case 'd': PatchedName = SuffixSize == 2 ?
"vpcmpud" :
"vpcmpd";
break;
3485 case 'q': PatchedName = SuffixSize == 2 ?
"vpcmpuq" :
"vpcmpq";
break;
3488 ComparisonPredicate = CC;
3494 (PatchedName.
back() ==
'b' || PatchedName.
back() ==
'w' ||
3495 PatchedName.
back() ==
'd' || PatchedName.
back() ==
'q')) {
3496 unsigned SuffixSize = PatchedName.
drop_back().
back() ==
'u' ? 2 : 1;
3497 unsigned CC = StringSwitch<unsigned>(
3498 PatchedName.
slice(5, PatchedName.
size() - SuffixSize))
3509 switch (PatchedName.
back()) {
3511 case 'b': PatchedName = SuffixSize == 2 ?
"vpcomub" :
"vpcomb";
break;
3512 case 'w': PatchedName = SuffixSize == 2 ?
"vpcomuw" :
"vpcomw";
break;
3513 case 'd': PatchedName = SuffixSize == 2 ?
"vpcomud" :
"vpcomd";
break;
3514 case 'q': PatchedName = SuffixSize == 2 ?
"vpcomuq" :
"vpcomq";
break;
3517 ComparisonPredicate = CC;
3529 StringSwitch<bool>(Name)
3530 .Cases({
"cs",
"ds",
"es",
"fs",
"gs",
"ss"},
true)
3531 .Cases({
"rex64",
"data32",
"data16",
"addr32",
"addr16"},
true)
3532 .Cases({
"xacquire",
"xrelease"},
true)
3533 .Cases({
"acquire",
"release"}, isParsingIntelSyntax())
3536 auto isLockRepeatNtPrefix = [](StringRef
N) {
3537 return StringSwitch<bool>(
N)
3538 .Cases({
"lock",
"rep",
"repe",
"repz",
"repne",
"repnz",
"notrack"},
3543 bool CurlyAsEndOfStatement =
false;
3546 while (isLockRepeatNtPrefix(
Name.lower())) {
3548 StringSwitch<unsigned>(Name)
3567 while (
Name.starts_with(
";") ||
Name.starts_with(
"\n") ||
3568 Name.starts_with(
"#") ||
Name.starts_with(
"\t") ||
3569 Name.starts_with(
"/")) {
3580 if (PatchedName ==
"data16" && is16BitMode()) {
3581 return Error(NameLoc,
"redundant data16 prefix");
3583 if (PatchedName ==
"data32") {
3585 return Error(NameLoc,
"redundant data32 prefix");
3587 return Error(NameLoc,
"'data32' is not supported in 64-bit mode");
3589 PatchedName =
"data16";
3596 if (
Next ==
"callw")
3598 if (
Next ==
"ljmpw")
3603 ForcedDataPrefix = X86::Is32Bit;
3611 if (ComparisonPredicate != ~0U && !isParsingIntelSyntax()) {
3618 if ((
Name.starts_with(
"ccmp") ||
Name.starts_with(
"ctest")) &&
3619 parseCFlagsOp(Operands))
3633 if (parseOperand(Operands, Name))
3635 if (HandleAVX512Operand(Operands))
3647 CurlyAsEndOfStatement =
3648 isParsingIntelSyntax() && isParsingMSInlineAsm() &&
3651 return TokError(
"unexpected token in argument list");
3655 if (ComparisonPredicate != ~0U && isParsingIntelSyntax()) {
3665 else if (CurlyAsEndOfStatement)
3668 getLexer().getTok().getLoc(), 0);
3675 if (IsFp && Operands.
size() == 1) {
3676 const char *Repl = StringSwitch<const char *>(Name)
3677 .Case(
"fsub",
"fsubp")
3678 .Case(
"fdiv",
"fdivp")
3679 .Case(
"fsubr",
"fsubrp")
3680 .Case(
"fdivr",
"fdivrp");
3681 static_cast<X86Operand &
>(*Operands[0]).setTokenValue(Repl);
3684 if ((Name ==
"mov" || Name ==
"movw" || Name ==
"movl") &&
3685 (Operands.
size() == 3)) {
3686 X86Operand &Op1 = (X86Operand &)*Operands[1];
3687 X86Operand &Op2 = (X86Operand &)*Operands[2];
3692 X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(
3694 (X86MCRegisterClasses[X86::GR16RegClassID].contains(Op1.
getReg()) ||
3695 X86MCRegisterClasses[X86::GR32RegClassID].contains(Op1.
getReg()))) {
3697 if (Name !=
"mov" && Name[3] == (is16BitMode() ?
'l' :
'w')) {
3698 Name = is16BitMode() ?
"movw" :
"movl";
3711 if ((Name ==
"outb" || Name ==
"outsb" || Name ==
"outw" || Name ==
"outsw" ||
3712 Name ==
"outl" || Name ==
"outsl" || Name ==
"out" || Name ==
"outs") &&
3713 Operands.
size() == 3) {
3714 X86Operand &
Op = (X86Operand &)*Operands.
back();
3720 if ((Name ==
"inb" || Name ==
"insb" || Name ==
"inw" || Name ==
"insw" ||
3721 Name ==
"inl" || Name ==
"insl" || Name ==
"in" || Name ==
"ins") &&
3722 Operands.
size() == 3) {
3723 X86Operand &
Op = (X86Operand &)*Operands[1];
3730 bool HadVerifyError =
false;
3733 if (
Name.starts_with(
"ins") &&
3734 (Operands.
size() == 1 || Operands.
size() == 3) &&
3735 (Name ==
"insb" || Name ==
"insw" || Name ==
"insl" || Name ==
"insd" ||
3738 AddDefaultSrcDestOperands(TmpOperands,
3740 DefaultMemDIOperand(NameLoc));
3741 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3745 if (
Name.starts_with(
"outs") &&
3746 (Operands.
size() == 1 || Operands.
size() == 3) &&
3747 (Name ==
"outsb" || Name ==
"outsw" || Name ==
"outsl" ||
3748 Name ==
"outsd" || Name ==
"outs")) {
3749 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
3751 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3757 if (
Name.starts_with(
"lods") &&
3758 (Operands.
size() == 1 || Operands.
size() == 2) &&
3759 (Name ==
"lods" || Name ==
"lodsb" || Name ==
"lodsw" ||
3760 Name ==
"lodsl" || Name ==
"lodsd" || Name ==
"lodsq")) {
3761 TmpOperands.
push_back(DefaultMemSIOperand(NameLoc));
3762 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3768 if (
Name.starts_with(
"stos") &&
3769 (Operands.
size() == 1 || Operands.
size() == 2) &&
3770 (Name ==
"stos" || Name ==
"stosb" || Name ==
"stosw" ||
3771 Name ==
"stosl" || Name ==
"stosd" || Name ==
"stosq")) {
3772 TmpOperands.
push_back(DefaultMemDIOperand(NameLoc));
3773 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3779 if (
Name.starts_with(
"scas") &&
3780 (Operands.
size() == 1 || Operands.
size() == 2) &&
3781 (Name ==
"scas" || Name ==
"scasb" || Name ==
"scasw" ||
3782 Name ==
"scasl" || Name ==
"scasd" || Name ==
"scasq")) {
3783 TmpOperands.
push_back(DefaultMemDIOperand(NameLoc));
3784 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3788 if (
Name.starts_with(
"cmps") &&
3789 (Operands.
size() == 1 || Operands.
size() == 3) &&
3790 (Name ==
"cmps" || Name ==
"cmpsb" || Name ==
"cmpsw" ||
3791 Name ==
"cmpsl" || Name ==
"cmpsd" || Name ==
"cmpsq")) {
3792 AddDefaultSrcDestOperands(TmpOperands, DefaultMemDIOperand(NameLoc),
3793 DefaultMemSIOperand(NameLoc));
3794 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3798 if (((
Name.starts_with(
"movs") &&
3799 (Name ==
"movs" || Name ==
"movsb" || Name ==
"movsw" ||
3800 Name ==
"movsl" || Name ==
"movsd" || Name ==
"movsq")) ||
3801 (
Name.starts_with(
"smov") &&
3802 (Name ==
"smov" || Name ==
"smovb" || Name ==
"smovw" ||
3803 Name ==
"smovl" || Name ==
"smovd" || Name ==
"smovq"))) &&
3804 (Operands.
size() == 1 || Operands.
size() == 3)) {
3805 if (Name ==
"movsd" && Operands.
size() == 1 && !isParsingIntelSyntax())
3807 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
3808 DefaultMemDIOperand(NameLoc));
3809 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3813 if (HadVerifyError) {
3814 return HadVerifyError;
3818 if ((Name ==
"xlat" || Name ==
"xlatb") && Operands.
size() == 2) {
3819 X86Operand &Op1 =
static_cast<X86Operand &
>(*Operands[1]);
3822 "size, (R|E)BX will be used for the location");
3824 static_cast<X86Operand &
>(*Operands[0]).setTokenValue(
"xlatb");
3837 if (
I == Table.
end() ||
I->OldOpc != Opcode)
3843 if (X86::isBLENDVPD(Opcode) || X86::isBLENDVPS(Opcode) ||
3844 X86::isPBLENDVB(Opcode))
3850bool X86AsmParser::processInstruction(MCInst &Inst,
const OperandVector &
Ops) {
3854 if (ForcedOpcodePrefix != OpcodePrefix_VEX3 &&
3861 auto replaceWithCCMPCTEST = [&](
unsigned Opcode) ->
bool {
3862 if (ForcedOpcodePrefix == OpcodePrefix_EVEX) {
3873 default:
return false;
3878 if (ForcedDispEncoding == DispEncoding_Disp32) {
3879 Inst.
setOpcode(is16BitMode() ? X86::JMP_2 : X86::JMP_4);
3888 if (ForcedDispEncoding == DispEncoding_Disp32) {
3889 Inst.
setOpcode(is16BitMode() ? X86::JCC_2 : X86::JCC_4);
3905#define FROM_TO(FROM, TO) \
3907 return replaceWithCCMPCTEST(X86::TO);
3909 FROM_TO(CMP64mi32, CCMP64mi32)
3912 FROM_TO(CMP64ri32, CCMP64ri32)
3939 FROM_TO(TEST64mi32, CTEST64mi32)
3941 FROM_TO(TEST64ri32, CTEST64ri32)
3961bool X86AsmParser::validateInstruction(MCInst &Inst,
const OperandVector &
Ops) {
3962 using namespace X86;
3963 const MCRegisterInfo *MRI =
getContext().getRegisterInfo();
3965 uint64_t TSFlags = MII.get(Opcode).TSFlags;
3966 if (isVFCMADDCPH(Opcode) || isVFCMADDCSH(Opcode) || isVFMADDCPH(Opcode) ||
3967 isVFMADDCSH(Opcode)) {
3971 return Warning(
Ops[0]->getStartLoc(),
"Destination register should be "
3972 "distinct from source registers");
3973 }
else if (isVFCMULCPH(Opcode) || isVFCMULCSH(Opcode) || isVFMULCPH(Opcode) ||
3974 isVFMULCSH(Opcode)) {
3984 return Warning(
Ops[0]->getStartLoc(),
"Destination register should be "
3985 "distinct from source registers");
3986 }
else if (isV4FMADDPS(Opcode) || isV4FMADDSS(Opcode) ||
3987 isV4FNMADDPS(Opcode) || isV4FNMADDSS(Opcode) ||
3988 isVP4DPWSSDS(Opcode) || isVP4DPWSSD(Opcode)) {
3993 if (Src2Enc % 4 != 0) {
3995 unsigned GroupStart = (Src2Enc / 4) * 4;
3996 unsigned GroupEnd = GroupStart + 3;
3998 "source register '" +
RegName +
"' implicitly denotes '" +
3999 RegName.take_front(3) + Twine(GroupStart) +
"' to '" +
4000 RegName.take_front(3) + Twine(GroupEnd) +
4003 }
else if (isVGATHERDPD(Opcode) || isVGATHERDPS(Opcode) ||
4004 isVGATHERQPD(Opcode) || isVGATHERQPS(Opcode) ||
4005 isVPGATHERDD(Opcode) || isVPGATHERDQ(Opcode) ||
4006 isVPGATHERQD(Opcode) || isVPGATHERQQ(Opcode)) {
4013 return Warning(
Ops[0]->getStartLoc(),
"index and destination registers "
4014 "should be distinct");
4020 if (Dest == Mask || Dest == Index || Mask == Index)
4021 return Warning(
Ops[0]->getStartLoc(),
"mask, index, and destination "
4022 "registers should be distinct");
4024 }
else if (isTCMMIMFP16PS(Opcode) || isTCMMRLFP16PS(Opcode) ||
4025 isTDPBF16PS(Opcode) || isTDPFP16PS(Opcode) || isTDPBSSD(Opcode) ||
4026 isTDPBSUD(Opcode) || isTDPBUSD(Opcode) || isTDPBUUD(Opcode)) {
4030 if (SrcDest == Src1 || SrcDest == Src2 || Src1 == Src2)
4031 return Error(
Ops[0]->getStartLoc(),
"all tmm registers must be distinct");
4045 for (
unsigned i = 0; i !=
NumOps; ++i) {
4050 if (
Reg == X86::AH ||
Reg == X86::BH ||
Reg == X86::CH ||
Reg == X86::DH)
4058 (Enc ==
X86II::EVEX || ForcedOpcodePrefix == OpcodePrefix_REX2 ||
4059 ForcedOpcodePrefix == OpcodePrefix_REX || UsesRex)) {
4061 return Error(
Ops[0]->getStartLoc(),
4062 "can't encode '" +
RegName.str() +
4063 "' in an instruction requiring EVEX/REX2/REX prefix");
4067 if ((Opcode == X86::PREFETCHIT0 || Opcode == X86::PREFETCHIT1)) {
4071 Ops[0]->getStartLoc(),
4072 Twine((Inst.
getOpcode() == X86::PREFETCHIT0 ?
"'prefetchit0'"
4073 :
"'prefetchit1'")) +
4074 " only supports RIP-relative address");
4079void X86AsmParser::emitWarningForSpecialLVIInstruction(SMLoc Loc) {
4080 Warning(Loc,
"Instruction may be vulnerable to LVI and "
4081 "requires manual mitigation");
4082 Note(SMLoc(),
"See https://software.intel.com/"
4083 "security-software-guidance/insights/"
4084 "deep-dive-load-value-injection#specialinstructions"
4085 " for more information");
4097void X86AsmParser::applyLVICFIMitigation(MCInst &Inst, MCStreamer &Out) {
4108 MCInst ShlInst, FenceInst;
4109 bool Parse32 = is32BitMode() || Code16GCC;
4110 MCRegister Basereg =
4111 is64BitMode() ? X86::RSP : (Parse32 ? X86::ESP : X86::SP);
4115 1, SMLoc{}, SMLoc{}, 0);
4117 ShlMemOp->addMemOperands(ShlInst, 5);
4130 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4142void X86AsmParser::applyLVILoadHardeningMitigation(MCInst &Inst,
4159 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4162 }
else if (Opcode == X86::REP_PREFIX || Opcode == X86::REPNE_PREFIX) {
4165 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4169 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
4184void X86AsmParser::emitInstruction(MCInst &Inst,
OperandVector &Operands,
4187 getSTI().hasFeature(X86::FeatureLVIControlFlowIntegrity))
4188 applyLVICFIMitigation(Inst, Out);
4193 getSTI().hasFeature(X86::FeatureLVILoadHardening))
4194 applyLVILoadHardeningMitigation(Inst, Out);
4198 unsigned Result = 0;
4200 if (Prefix.isPrefix()) {
4201 Result = Prefix.getPrefix();
4207bool X86AsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
4209 MCStreamer &Out, uint64_t &ErrorInfo,
4210 bool MatchingInlineAsm) {
4211 assert(!Operands.
empty() &&
"Unexpect empty operand list!");
4212 assert((*Operands[0]).isToken() &&
"Leading operand should always be a mnemonic!");
4215 MatchFPUWaitAlias(IDLoc,
static_cast<X86Operand &
>(*Operands[0]), Operands,
4216 Out, MatchingInlineAsm);
4223 if (ForcedOpcodePrefix == OpcodePrefix_REX)
4225 else if (ForcedOpcodePrefix == OpcodePrefix_REX2)
4227 else if (ForcedOpcodePrefix == OpcodePrefix_VEX)
4229 else if (ForcedOpcodePrefix == OpcodePrefix_VEX2)
4231 else if (ForcedOpcodePrefix == OpcodePrefix_VEX3)
4233 else if (ForcedOpcodePrefix == OpcodePrefix_EVEX)
4237 if (ForcedDispEncoding == DispEncoding_Disp8)
4239 else if (ForcedDispEncoding == DispEncoding_Disp32)
4245 return isParsingIntelSyntax()
4246 ? matchAndEmitIntelInstruction(IDLoc, Opcode, Inst, Operands, Out,
4247 ErrorInfo, MatchingInlineAsm)
4248 : matchAndEmitATTInstruction(IDLoc, Opcode, Inst, Operands, Out,
4249 ErrorInfo, MatchingInlineAsm);
4252void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &
Op,
4254 bool MatchingInlineAsm) {
4258 const char *Repl = StringSwitch<const char *>(
Op.getToken())
4259 .Case(
"finit",
"fninit")
4260 .Case(
"fsave",
"fnsave")
4261 .Case(
"fstcw",
"fnstcw")
4262 .Case(
"fstcww",
"fnstcw")
4263 .Case(
"fstenv",
"fnstenv")
4264 .Case(
"fstsw",
"fnstsw")
4265 .Case(
"fstsww",
"fnstsw")
4266 .Case(
"fclex",
"fnclex")
4272 if (!MatchingInlineAsm)
4278bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc,
4279 const FeatureBitset &MissingFeatures,
4280 bool MatchingInlineAsm) {
4281 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
4282 SmallString<126> Msg;
4283 raw_svector_ostream OS(Msg);
4284 OS <<
"instruction requires:";
4285 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
4286 if (MissingFeatures[i])
4289 return Error(IDLoc, OS.str(), SMRange(), MatchingInlineAsm);
4292unsigned X86AsmParser::checkTargetMatchPredicate(MCInst &Inst) {
4294 const MCInstrDesc &MCID = MII.get(
Opc);
4295 uint64_t TSFlags = MCID.
TSFlags;
4298 return Match_Unsupported;
4300 return Match_Unsupported;
4302 switch (ForcedOpcodePrefix) {
4303 case OpcodePrefix_Default:
4305 case OpcodePrefix_REX:
4306 case OpcodePrefix_REX2:
4308 return Match_Unsupported;
4310 case OpcodePrefix_VEX:
4311 case OpcodePrefix_VEX2:
4312 case OpcodePrefix_VEX3:
4314 return Match_Unsupported;
4316 case OpcodePrefix_EVEX:
4318 !X86::isCMP(
Opc) && !X86::isTEST(
Opc))
4319 return Match_Unsupported;
4321 return Match_Unsupported;
4326 (ForcedOpcodePrefix != OpcodePrefix_VEX &&
4327 ForcedOpcodePrefix != OpcodePrefix_VEX2 &&
4328 ForcedOpcodePrefix != OpcodePrefix_VEX3))
4329 return Match_Unsupported;
4331 return Match_Success;
4334bool X86AsmParser::matchAndEmitATTInstruction(
4335 SMLoc IDLoc,
unsigned &Opcode, MCInst &Inst,
OperandVector &Operands,
4336 MCStreamer &Out, uint64_t &ErrorInfo,
bool MatchingInlineAsm) {
4337 X86Operand &
Op =
static_cast<X86Operand &
>(*Operands[0]);
4341 if (ForcedDataPrefix == X86::Is32Bit)
4342 SwitchMode(X86::Is32Bit);
4344 FeatureBitset MissingFeatures;
4345 unsigned OriginalError = MatchInstruction(Operands, Inst, ErrorInfo,
4346 MissingFeatures, MatchingInlineAsm,
4347 isParsingIntelSyntax());
4348 if (ForcedDataPrefix == X86::Is32Bit) {
4349 SwitchMode(X86::Is16Bit);
4350 ForcedDataPrefix = 0;
4352 switch (OriginalError) {
4355 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
4360 if (!MatchingInlineAsm)
4361 while (processInstruction(Inst, Operands))
4365 if (!MatchingInlineAsm)
4369 case Match_InvalidImmUnsignedi4: {
4370 SMLoc ErrorLoc = ((X86Operand &)*Operands[ErrorInfo]).getStartLoc();
4371 if (ErrorLoc == SMLoc())
4373 return Error(ErrorLoc,
"immediate must be an integer in range [0, 15]",
4374 EmptyRange, MatchingInlineAsm);
4376 case Match_InvalidImmUnsignedi6: {
4377 SMLoc ErrorLoc = ((X86Operand &)*Operands[ErrorInfo]).getStartLoc();
4378 if (ErrorLoc == SMLoc())
4380 return Error(ErrorLoc,
"immediate must be an integer in range [0, 63]",
4381 EmptyRange, MatchingInlineAsm);
4383 case Match_MissingFeature:
4384 return ErrorMissingFeature(IDLoc, MissingFeatures, MatchingInlineAsm);
4385 case Match_InvalidOperand:
4386 case Match_MnemonicFail:
4387 case Match_Unsupported:
4390 if (
Op.getToken().empty()) {
4391 Error(IDLoc,
"instruction must have size higher than 0", EmptyRange,
4402 StringRef
Base =
Op.getToken();
4403 SmallString<16> Tmp;
4406 Op.setTokenValue(Tmp);
4414 const char *Suffixes =
Base[0] !=
'f' ?
"bwlq" :
"slt\0";
4416 const char *MemSize =
Base[0] !=
'f' ?
"\x08\x10\x20\x40" :
"\x20\x40\x50\0";
4419 uint64_t ErrorInfoIgnore;
4420 FeatureBitset ErrorInfoMissingFeatures;
4428 bool HasVectorReg =
false;
4429 X86Operand *MemOp =
nullptr;
4430 for (
const auto &
Op : Operands) {
4431 X86Operand *X86Op =
static_cast<X86Operand *
>(
Op.get());
4433 HasVectorReg =
true;
4434 else if (X86Op->
isMem()) {
4436 assert(MemOp->Mem.Size == 0 &&
"Memory size always 0 under ATT syntax");
4443 for (
unsigned I = 0,
E = std::size(Match);
I !=
E; ++
I) {
4444 Tmp.
back() = Suffixes[
I];
4445 if (MemOp && HasVectorReg)
4446 MemOp->Mem.Size = MemSize[
I];
4447 Match[
I] = Match_MnemonicFail;
4448 if (MemOp || !HasVectorReg) {
4450 MatchInstruction(Operands, Inst, ErrorInfoIgnore, MissingFeatures,
4451 MatchingInlineAsm, isParsingIntelSyntax());
4453 if (Match[
I] == Match_MissingFeature)
4454 ErrorInfoMissingFeatures = MissingFeatures;
4464 unsigned NumSuccessfulMatches =
llvm::count(Match, Match_Success);
4465 if (NumSuccessfulMatches == 1) {
4466 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
4471 if (!MatchingInlineAsm)
4472 while (processInstruction(Inst, Operands))
4476 if (!MatchingInlineAsm)
4486 if (NumSuccessfulMatches > 1) {
4488 unsigned NumMatches = 0;
4489 for (
unsigned I = 0,
E = std::size(Match);
I !=
E; ++
I)
4490 if (Match[
I] == Match_Success)
4491 MatchChars[NumMatches++] = Suffixes[
I];
4493 SmallString<126> Msg;
4494 raw_svector_ostream OS(Msg);
4495 OS <<
"ambiguous instructions require an explicit suffix (could be ";
4496 for (
unsigned i = 0; i != NumMatches; ++i) {
4499 if (i + 1 == NumMatches)
4501 OS <<
"'" <<
Base << MatchChars[i] <<
"'";
4504 Error(IDLoc, OS.str(), EmptyRange, MatchingInlineAsm);
4512 if (
llvm::count(Match, Match_MnemonicFail) == 4) {
4513 if (OriginalError == Match_MnemonicFail)
4514 return Error(IDLoc,
"invalid instruction mnemonic '" +
Base +
"'",
4515 Op.getLocRange(), MatchingInlineAsm);
4517 if (OriginalError == Match_Unsupported)
4518 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4521 assert(OriginalError == Match_InvalidOperand &&
"Unexpected error");
4523 if (ErrorInfo != ~0ULL) {
4524 if (ErrorInfo >= Operands.size())
4525 return Error(IDLoc,
"too few operands for instruction", EmptyRange,
4528 X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo];
4532 OperandRange, MatchingInlineAsm);
4536 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4542 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4548 if (
llvm::count(Match, Match_MissingFeature) == 1) {
4549 ErrorInfo = Match_MissingFeature;
4550 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
4556 if (
llvm::count(Match, Match_InvalidOperand) == 1) {
4557 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4562 Error(IDLoc,
"unknown use of instruction mnemonic without a size suffix",
4563 EmptyRange, MatchingInlineAsm);
4567bool X86AsmParser::matchAndEmitIntelInstruction(
4568 SMLoc IDLoc,
unsigned &Opcode, MCInst &Inst,
OperandVector &Operands,
4569 MCStreamer &Out, uint64_t &ErrorInfo,
bool MatchingInlineAsm) {
4570 X86Operand &
Op =
static_cast<X86Operand &
>(*Operands[0]);
4573 X86Operand *UnsizedMemOp =
nullptr;
4574 for (
const auto &
Op : Operands) {
4575 X86Operand *X86Op =
static_cast<X86Operand *
>(
Op.get());
4577 UnsizedMemOp = X86Op;
4586 StringRef Mnemonic = (
static_cast<X86Operand &
>(*Operands[0])).
getToken();
4588 static const char *
const PtrSizedInstrs[] = {
"call",
"jmp",
"push",
"pop"};
4589 for (
const char *Instr : PtrSizedInstrs) {
4590 if (Mnemonic == Instr) {
4591 UnsizedMemOp->
Mem.
Size = getPointerWidth();
4597 SmallVector<unsigned, 8> Match;
4598 FeatureBitset ErrorInfoMissingFeatures;
4599 FeatureBitset MissingFeatures;
4600 StringRef
Base = (
static_cast<X86Operand &
>(*Operands[0])).
getToken();
4604 if (Mnemonic ==
"push" && Operands.size() == 2) {
4605 auto *X86Op =
static_cast<X86Operand *
>(Operands[1].get());
4606 if (X86Op->
isImm()) {
4609 unsigned Size = getPointerWidth();
4612 SmallString<16> Tmp;
4614 Tmp += (is64BitMode())
4616 : (is32BitMode()) ?
"l" : (is16BitMode()) ?
"w" :
" ";
4617 Op.setTokenValue(Tmp);
4619 Match.
push_back(MatchInstruction(Operands, Inst, ErrorInfo,
4620 MissingFeatures, MatchingInlineAsm,
4631 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
4632 for (
unsigned Size : MopSizes) {
4634 uint64_t ErrorInfoIgnore;
4636 unsigned M = MatchInstruction(Operands, Inst, ErrorInfoIgnore,
4637 MissingFeatures, MatchingInlineAsm,
4638 isParsingIntelSyntax());
4643 if (Match.
back() == Match_MissingFeature)
4644 ErrorInfoMissingFeatures = MissingFeatures;
4654 if (Match.
empty()) {
4656 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,
4657 isParsingIntelSyntax()));
4659 if (Match.
back() == Match_MissingFeature)
4660 ErrorInfoMissingFeatures = MissingFeatures;
4668 if (Match.
back() == Match_MnemonicFail) {
4669 return Error(IDLoc,
"invalid instruction mnemonic '" + Mnemonic +
"'",
4670 Op.getLocRange(), MatchingInlineAsm);
4673 unsigned NumSuccessfulMatches =
llvm::count(Match, Match_Success);
4677 if (UnsizedMemOp && NumSuccessfulMatches > 1 &&
4680 unsigned M = MatchInstruction(
4681 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,
4682 isParsingIntelSyntax());
4683 if (M == Match_Success)
4684 NumSuccessfulMatches = 1;
4696 if (NumSuccessfulMatches == 1) {
4697 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
4702 if (!MatchingInlineAsm)
4703 while (processInstruction(Inst, Operands))
4706 if (!MatchingInlineAsm)
4710 }
else if (NumSuccessfulMatches > 1) {
4712 "multiple matches only possible with unsized memory operands");
4714 "ambiguous operand size for instruction '" + Mnemonic +
"\'",
4720 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4726 if (
llvm::count(Match, Match_MissingFeature) == 1) {
4727 ErrorInfo = Match_MissingFeature;
4728 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
4734 if (
llvm::count(Match, Match_InvalidOperand) == 1) {
4735 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4739 if (
llvm::count(Match, Match_InvalidImmUnsignedi4) == 1) {
4740 SMLoc ErrorLoc = ((X86Operand &)*Operands[ErrorInfo]).getStartLoc();
4741 if (ErrorLoc == SMLoc())
4743 return Error(ErrorLoc,
"immediate must be an integer in range [0, 15]",
4744 EmptyRange, MatchingInlineAsm);
4747 if (
llvm::count(Match, Match_InvalidImmUnsignedi6) == 1) {
4748 SMLoc ErrorLoc = ((X86Operand &)*Operands[ErrorInfo]).getStartLoc();
4749 if (ErrorLoc == SMLoc())
4751 return Error(ErrorLoc,
"immediate must be an integer in range [0, 63]",
4752 EmptyRange, MatchingInlineAsm);
4756 return Error(IDLoc,
"unknown instruction mnemonic", EmptyRange,
4760bool X86AsmParser::omitRegisterFromClobberLists(MCRegister
Reg) {
4761 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(
Reg);
4764bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
4765 MCAsmParser &Parser = getParser();
4768 return parseDirectiveArch();
4770 return ParseDirectiveCode(IDVal, DirectiveID.
getLoc());
4776 return Error(DirectiveID.
getLoc(),
"'.att_syntax noprefix' is not "
4777 "supported: registers must have a "
4778 "'%' prefix in .att_syntax");
4780 getParser().setAssemblerDialect(0);
4783 getParser().setAssemblerDialect(1);
4788 return Error(DirectiveID.
getLoc(),
"'.intel_syntax prefix' is not "
4789 "supported: registers must not have "
4790 "a '%' prefix in .intel_syntax");
4793 }
else if (IDVal ==
".nops")
4794 return parseDirectiveNops(DirectiveID.
getLoc());
4795 else if (IDVal ==
".even")
4796 return parseDirectiveEven(DirectiveID.
getLoc());
4797 else if (IDVal ==
".cv_fpo_proc")
4798 return parseDirectiveFPOProc(DirectiveID.
getLoc());
4799 else if (IDVal ==
".cv_fpo_setframe")
4800 return parseDirectiveFPOSetFrame(DirectiveID.
getLoc());
4801 else if (IDVal ==
".cv_fpo_pushreg")
4802 return parseDirectiveFPOPushReg(DirectiveID.
getLoc());
4803 else if (IDVal ==
".cv_fpo_stackalloc")
4804 return parseDirectiveFPOStackAlloc(DirectiveID.
getLoc());
4805 else if (IDVal ==
".cv_fpo_stackalign")
4806 return parseDirectiveFPOStackAlign(DirectiveID.
getLoc());
4807 else if (IDVal ==
".cv_fpo_endprologue")
4808 return parseDirectiveFPOEndPrologue(DirectiveID.
getLoc());
4809 else if (IDVal ==
".cv_fpo_endproc")
4810 return parseDirectiveFPOEndProc(DirectiveID.
getLoc());
4811 else if (IDVal ==
".seh_pushreg" ||
4813 return parseDirectiveSEHPushReg(DirectiveID.
getLoc());
4814 else if (IDVal ==
".seh_setframe" ||
4816 return parseDirectiveSEHSetFrame(DirectiveID.
getLoc());
4817 else if (IDVal ==
".seh_savereg" ||
4819 return parseDirectiveSEHSaveReg(DirectiveID.
getLoc());
4820 else if (IDVal ==
".seh_savexmm" ||
4822 return parseDirectiveSEHSaveXMM(DirectiveID.
getLoc());
4823 else if (IDVal ==
".seh_pushframe" ||
4825 return parseDirectiveSEHPushFrame(DirectiveID.
getLoc());
4830bool X86AsmParser::parseDirectiveArch() {
4832 getParser().parseStringToEndOfStatement();
4838bool X86AsmParser::parseDirectiveNops(SMLoc L) {
4839 int64_t NumBytes = 0, Control = 0;
4840 SMLoc NumBytesLoc, ControlLoc;
4841 const MCSubtargetInfo& STI = getSTI();
4842 NumBytesLoc = getTok().getLoc();
4843 if (getParser().checkForValidSection() ||
4844 getParser().parseAbsoluteExpression(NumBytes))
4848 ControlLoc = getTok().getLoc();
4849 if (getParser().parseAbsoluteExpression(Control))
4852 if (getParser().parseEOL())
4855 if (NumBytes <= 0) {
4856 Error(NumBytesLoc,
"'.nops' directive with non-positive size");
4861 Error(ControlLoc,
"'.nops' directive with negative NOP size");
4866 getParser().getStreamer().emitNops(NumBytes, Control, L, STI);
4873bool X86AsmParser::parseDirectiveEven(SMLoc L) {
4877 const MCSection *
Section = getStreamer().getCurrentSectionOnly();
4879 getStreamer().initSections(getSTI());
4880 Section = getStreamer().getCurrentSectionOnly();
4882 if (
getContext().getAsmInfo().useCodeAlign(*Section))
4883 getStreamer().emitCodeAlignment(
Align(2), &getSTI(), 0);
4885 getStreamer().emitValueToAlignment(
Align(2), 0, 1, 0);
4891bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
4892 MCAsmParser &Parser = getParser();
4894 if (IDVal ==
".code16") {
4896 if (!is16BitMode()) {
4897 SwitchMode(X86::Is16Bit);
4898 getTargetStreamer().emitCode16();
4900 }
else if (IDVal ==
".code16gcc") {
4904 if (!is16BitMode()) {
4905 SwitchMode(X86::Is16Bit);
4906 getTargetStreamer().emitCode16();
4908 }
else if (IDVal ==
".code32") {
4910 if (!is32BitMode()) {
4911 SwitchMode(X86::Is32Bit);
4912 getTargetStreamer().emitCode32();
4914 }
else if (IDVal ==
".code64") {
4916 if (!is64BitMode()) {
4917 SwitchMode(X86::Is64Bit);
4918 getTargetStreamer().emitCode64();
4921 Error(L,
"unknown directive " + IDVal);
4929bool X86AsmParser::parseDirectiveFPOProc(SMLoc L) {
4930 MCAsmParser &Parser = getParser();
4934 return Parser.
TokError(
"expected symbol name");
4935 if (Parser.
parseIntToken(ParamsSize,
"expected parameter byte count"))
4938 return Parser.
TokError(
"parameters size out of range");
4942 return getTargetStreamer().emitFPOProc(ProcSym, ParamsSize, L);
4946bool X86AsmParser::parseDirectiveFPOSetFrame(SMLoc L) {
4949 if (parseRegister(
Reg, DummyLoc, DummyLoc) || parseEOL())
4951 return getTargetStreamer().emitFPOSetFrame(
Reg, L);
4955bool X86AsmParser::parseDirectiveFPOPushReg(SMLoc L) {
4958 if (parseRegister(
Reg, DummyLoc, DummyLoc) || parseEOL())
4960 return getTargetStreamer().emitFPOPushReg(
Reg, L);
4964bool X86AsmParser::parseDirectiveFPOStackAlloc(SMLoc L) {
4965 MCAsmParser &Parser = getParser();
4969 return getTargetStreamer().emitFPOStackAlloc(
Offset, L);
4973bool X86AsmParser::parseDirectiveFPOStackAlign(SMLoc L) {
4974 MCAsmParser &Parser = getParser();
4978 return getTargetStreamer().emitFPOStackAlign(
Offset, L);
4982bool X86AsmParser::parseDirectiveFPOEndPrologue(SMLoc L) {
4983 MCAsmParser &Parser = getParser();
4986 return getTargetStreamer().emitFPOEndPrologue(L);
4990bool X86AsmParser::parseDirectiveFPOEndProc(SMLoc L) {
4991 MCAsmParser &Parser = getParser();
4994 return getTargetStreamer().emitFPOEndProc(L);
4997bool X86AsmParser::parseSEHRegisterNumber(
unsigned RegClassID,
4998 MCRegister &RegNo) {
4999 SMLoc startLoc = getLexer().getLoc();
5000 const MCRegisterInfo *MRI =
getContext().getRegisterInfo();
5005 if (parseRegister(RegNo, startLoc, endLoc))
5008 if (!X86MCRegisterClasses[RegClassID].
contains(RegNo)) {
5009 return Error(startLoc,
5010 "register is not supported for use with this directive");
5016 if (getParser().parseAbsoluteExpression(EncodedReg))
5021 RegNo = MCRegister();
5022 for (
MCPhysReg Reg : X86MCRegisterClasses[RegClassID]) {
5029 return Error(startLoc,
5030 "incorrect register number for use with this directive");
5037bool X86AsmParser::parseDirectiveSEHPushReg(SMLoc Loc) {
5039 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5043 return TokError(
"expected end of directive");
5046 getStreamer().emitWinCFIPushReg(
Reg, Loc);
5050bool X86AsmParser::parseDirectiveSEHSetFrame(SMLoc Loc) {
5053 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5056 return TokError(
"you must specify a stack pointer offset");
5059 if (getParser().parseAbsoluteExpression(Off))
5063 return TokError(
"expected end of directive");
5066 getStreamer().emitWinCFISetFrame(
Reg, Off, Loc);
5070bool X86AsmParser::parseDirectiveSEHSaveReg(SMLoc Loc) {
5073 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5076 return TokError(
"you must specify an offset on the stack");
5079 if (getParser().parseAbsoluteExpression(Off))
5083 return TokError(
"expected end of directive");
5086 getStreamer().emitWinCFISaveReg(
Reg, Off, Loc);
5090bool X86AsmParser::parseDirectiveSEHSaveXMM(SMLoc Loc) {
5093 if (parseSEHRegisterNumber(X86::VR128XRegClassID,
Reg))
5096 return TokError(
"you must specify an offset on the stack");
5099 if (getParser().parseAbsoluteExpression(Off))
5103 return TokError(
"expected end of directive");
5106 getStreamer().emitWinCFISaveXMM(
Reg, Off, Loc);
5110bool X86AsmParser::parseDirectiveSEHPushFrame(SMLoc Loc) {
5114 SMLoc startLoc = getLexer().getLoc();
5116 if (!getParser().parseIdentifier(CodeID)) {
5117 if (CodeID !=
"code")
5118 return Error(startLoc,
"expected @code");
5124 return TokError(
"expected end of directive");
5127 getStreamer().emitWinCFIPushFrame(Code, Loc);
5137#define GET_MATCHER_IMPLEMENTATION
5138#include "X86GenAsmMatcher.inc"
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")
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)
static constexpr unsigned SM(unsigned Version)
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 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...
uint16_t getEncodingValue(MCRegister Reg) const
Returns the encoding for Reg.
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
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