53 "x86-experimental-lvi-inline-asm-hardening",
54 cl::desc(
"Harden inline assembly code that may be vulnerable to Load Value"
55 " Injection (LVI). This feature is experimental."),
cl::Hidden);
58 if (Scale != 1 && Scale != 2 && Scale != 4 && Scale != 8) {
59 ErrMsg =
"scale factor in address must be 1, 2, 4 or 8";
68#define GET_X86_SSE2AVX_TABLE
69#include "X86GenInstrMapping.inc"
71static const char OpPrecedence[] = {
97 ParseInstructionInfo *InstInfo;
99 unsigned ForcedDataPrefix = 0;
102 OpcodePrefix_Default,
111 OpcodePrefix ForcedOpcodePrefix = OpcodePrefix_Default;
114 DispEncoding_Default,
119 DispEncoding ForcedDispEncoding = DispEncoding_Default;
122 bool UseApxExtendedReg =
false;
124 bool ForcedNoFlag =
false;
127 SMLoc consumeToken() {
128 MCAsmParser &Parser = getParser();
138 X86TargetStreamer &getTargetStreamer() {
139 assert(getParser().getStreamer().getTargetStreamer() &&
140 "do not have a target streamer");
141 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
142 return static_cast<X86TargetStreamer &
>(TS);
146 uint64_t &ErrorInfo, FeatureBitset &MissingFeatures,
147 bool matchingInlineAsm,
unsigned VariantID = 0) {
150 SwitchMode(X86::Is32Bit);
151 unsigned rv = MatchInstructionImpl(
Operands, Inst, ErrorInfo,
152 MissingFeatures, matchingInlineAsm,
155 SwitchMode(X86::Is16Bit);
159 enum InfixCalculatorTok {
184 enum IntelOperatorKind {
191 enum MasmOperatorKind {
198 class InfixCalculator {
199 typedef std::pair< InfixCalculatorTok, int64_t > ICToken;
203 bool isUnaryOperator(InfixCalculatorTok
Op)
const {
204 return Op == IC_NEG ||
Op == IC_NOT;
208 int64_t popOperand() {
209 assert (!PostfixStack.empty() &&
"Poped an empty stack!");
210 ICToken
Op = PostfixStack.pop_back_val();
211 if (!(
Op.first == IC_IMM ||
Op.first == IC_REGISTER))
215 void pushOperand(InfixCalculatorTok
Op, int64_t Val = 0) {
216 assert ((
Op == IC_IMM ||
Op == IC_REGISTER) &&
217 "Unexpected operand!");
218 PostfixStack.push_back(std::make_pair(
Op, Val));
221 void popOperator() { InfixOperatorStack.pop_back(); }
222 void pushOperator(InfixCalculatorTok
Op) {
224 if (InfixOperatorStack.empty()) {
225 InfixOperatorStack.push_back(
Op);
232 unsigned Idx = InfixOperatorStack.size() - 1;
233 InfixCalculatorTok StackOp = InfixOperatorStack[Idx];
234 if (OpPrecedence[
Op] > OpPrecedence[StackOp] || StackOp == IC_LPAREN) {
235 InfixOperatorStack.push_back(
Op);
241 unsigned ParenCount = 0;
244 if (InfixOperatorStack.empty())
247 Idx = InfixOperatorStack.size() - 1;
248 StackOp = InfixOperatorStack[Idx];
249 if (!(OpPrecedence[StackOp] >= OpPrecedence[
Op] || ParenCount))
254 if (!ParenCount && StackOp == IC_LPAREN)
257 if (StackOp == IC_RPAREN) {
259 InfixOperatorStack.pop_back();
260 }
else if (StackOp == IC_LPAREN) {
262 InfixOperatorStack.pop_back();
264 InfixOperatorStack.pop_back();
265 PostfixStack.push_back(std::make_pair(StackOp, 0));
269 InfixOperatorStack.push_back(
Op);
274 while (!InfixOperatorStack.empty()) {
275 InfixCalculatorTok StackOp = InfixOperatorStack.pop_back_val();
276 if (StackOp != IC_LPAREN && StackOp != IC_RPAREN)
277 PostfixStack.push_back(std::make_pair(StackOp, 0));
280 if (PostfixStack.empty())
284 for (
const ICToken &
Op : PostfixStack) {
285 if (
Op.first == IC_IMM ||
Op.first == IC_REGISTER) {
287 }
else if (isUnaryOperator(
Op.first)) {
288 assert (OperandStack.
size() > 0 &&
"Too few operands.");
290 assert (Operand.first == IC_IMM &&
291 "Unary operation with a register!");
297 OperandStack.
push_back(std::make_pair(IC_IMM, -Operand.second));
300 OperandStack.
push_back(std::make_pair(IC_IMM, ~Operand.second));
304 assert (OperandStack.
size() > 1 &&
"Too few operands.");
313 Val = Op1.second + Op2.second;
314 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
317 Val = Op1.second - Op2.second;
318 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
321 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
322 "Multiply operation with an immediate and a register!");
323 Val = Op1.second * Op2.second;
324 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
327 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
328 "Divide operation with an immediate and a register!");
329 assert (Op2.second != 0 &&
"Division by zero!");
330 Val = Op1.second / Op2.second;
331 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
334 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
335 "Modulo operation with an immediate and a register!");
336 Val = Op1.second % Op2.second;
337 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
340 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
341 "Or operation with an immediate and a register!");
342 Val = Op1.second | Op2.second;
343 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
346 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
347 "Xor operation with an immediate and a register!");
348 Val = Op1.second ^ Op2.second;
349 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
352 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
353 "And operation with an immediate and a register!");
354 Val = Op1.second & Op2.second;
355 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
358 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
359 "Left shift operation with an immediate and a register!");
360 Val = Op1.second << Op2.second;
361 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
364 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
365 "Right shift operation with an immediate and a register!");
366 Val = Op1.second >> Op2.second;
367 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
370 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
371 "Equals operation with an immediate and a register!");
372 Val = (Op1.second == Op2.second) ? -1 : 0;
373 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
376 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
377 "Not-equals operation with an immediate and a register!");
378 Val = (Op1.second != Op2.second) ? -1 : 0;
379 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
382 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
383 "Less-than operation with an immediate and a register!");
384 Val = (Op1.second < Op2.second) ? -1 : 0;
385 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
388 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
389 "Less-than-or-equal operation with an immediate and a "
391 Val = (Op1.second <= Op2.second) ? -1 : 0;
392 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
395 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
396 "Greater-than operation with an immediate and a register!");
397 Val = (Op1.second > Op2.second) ? -1 : 0;
398 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
401 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
402 "Greater-than-or-equal operation with an immediate and a "
404 Val = (Op1.second >= Op2.second) ? -1 : 0;
405 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
410 assert (OperandStack.
size() == 1 &&
"Expected a single result.");
415 enum IntelExprState {
445 class IntelExprStateMachine {
446 IntelExprState State = IES_INIT, PrevState = IES_ERROR;
447 MCRegister BaseReg, IndexReg, TmpReg;
449 std::optional<unsigned> TmpScale = {};
451 const MCExpr *Sym =
nullptr;
454 InlineAsmIdentifierInfo Info;
456 short ParenCount = 0;
458 bool MemExpr =
false;
459 bool BracketUsed =
false;
460 bool NegativeAdditiveTerm =
false;
461 SMLoc NegativeAdditiveTermLoc;
462 bool OffsetOperator =
false;
463 bool AttachToOperandIdx =
false;
465 SMLoc OffsetOperatorLoc;
468 bool setSymRef(
const MCExpr *Val, StringRef ID, StringRef &ErrMsg) {
470 ErrMsg =
"cannot use more than one symbol in memory operand";
479 IntelExprStateMachine() =
default;
481 void addImm(int64_t imm) { Imm += imm; }
482 short getBracCount()
const {
return BracCount; }
483 bool isMemExpr()
const {
return MemExpr; }
484 bool isBracketUsed()
const {
return BracketUsed; }
485 bool isOffsetOperator()
const {
return OffsetOperator; }
486 SMLoc getOffsetLoc()
const {
return OffsetOperatorLoc; }
487 MCRegister getBaseReg()
const {
return BaseReg; }
488 MCRegister getIndexReg()
const {
return IndexReg; }
489 unsigned getScale()
const {
return Scale; }
490 const MCExpr *
getSym()
const {
return Sym; }
491 StringRef getSymName()
const {
return SymName; }
492 StringRef
getType()
const {
return CurType.Name; }
493 unsigned getSize()
const {
return CurType.Size; }
494 unsigned getElementSize()
const {
return CurType.ElementSize; }
495 unsigned getLength()
const {
return CurType.Length; }
496 int64_t
getImm() {
return Imm + IC.execute(); }
497 bool isValidEndState()
const {
498 return State == IES_RBRAC || State == IES_RPAREN ||
499 State == IES_INTEGER || State == IES_REGISTER ||
502 bool hasUnmatchedParen()
const {
return ParenCount != 0; }
503 SMLoc getLParenLoc()
const {
return LParenLoc; }
509 void setAppendAfterOperand() { AttachToOperandIdx =
true; }
511 bool isPIC()
const {
return IsPIC; }
512 void setPIC() { IsPIC =
true; }
514 bool hadError()
const {
return State == IES_ERROR; }
515 SMLoc getErrorLoc(SMLoc DefaultLoc)
const {
516 return NegativeAdditiveTerm ? NegativeAdditiveTermLoc : DefaultLoc;
518 const InlineAsmIdentifierInfo &getIdentifierInfo()
const {
return Info; }
520 bool regsUseUpError(StringRef &ErrMsg) {
523 if (IsPIC && AttachToOperandIdx)
524 ErrMsg =
"Don't use 2 or more regs for mem offset in PIC model!";
526 ErrMsg =
"BaseReg/IndexReg already set!";
531 IntelExprState CurrState = State;
540 IC.pushOperator(IC_OR);
543 PrevState = CurrState;
546 IntelExprState CurrState = State;
555 IC.pushOperator(IC_XOR);
558 PrevState = CurrState;
561 IntelExprState CurrState = State;
570 IC.pushOperator(IC_AND);
573 PrevState = CurrState;
576 IntelExprState CurrState = State;
585 IC.pushOperator(IC_EQ);
588 PrevState = CurrState;
591 IntelExprState CurrState = State;
600 IC.pushOperator(IC_NE);
603 PrevState = CurrState;
606 IntelExprState CurrState = State;
615 IC.pushOperator(IC_LT);
618 PrevState = CurrState;
621 IntelExprState CurrState = State;
630 IC.pushOperator(IC_LE);
633 PrevState = CurrState;
636 IntelExprState CurrState = State;
645 IC.pushOperator(IC_GT);
648 PrevState = CurrState;
651 IntelExprState CurrState = State;
660 IC.pushOperator(IC_GE);
663 PrevState = CurrState;
666 IntelExprState CurrState = State;
675 IC.pushOperator(IC_LSHIFT);
678 PrevState = CurrState;
681 IntelExprState CurrState = State;
690 IC.pushOperator(IC_RSHIFT);
693 PrevState = CurrState;
695 bool onPlus(StringRef &ErrMsg) {
696 IntelExprState CurrState = State;
706 IC.pushOperator(IC_PLUS);
710 if (!BaseReg && !TmpScale.has_value()) {
715 return regsUseUpError(ErrMsg);
718 if (NegativeAdditiveTerm) {
719 ErrMsg =
"Scale can't be negative";
722 if (TmpScale.has_value() &&
checkScale(TmpScale.value(), ErrMsg)) {
725 Scale = TmpScale.value_or(0);
730 NegativeAdditiveTerm =
false;
731 NegativeAdditiveTermLoc = SMLoc();
734 PrevState = CurrState;
737 bool onMinus(SMLoc MinusLoc, StringRef &ErrMsg) {
738 IntelExprState CurrState = State;
768 NegativeAdditiveTerm =
true;
769 NegativeAdditiveTermLoc = MinusLoc;
771 if (CurrState == IES_REGISTER || CurrState == IES_RPAREN ||
772 CurrState == IES_INTEGER || CurrState == IES_RBRAC ||
773 CurrState == IES_OFFSET) {
774 IC.pushOperator(IC_MINUS);
778 if (!BaseReg && !TmpScale.has_value()) {
783 return regsUseUpError(ErrMsg);
786 if (TmpScale.has_value() &&
790 Scale = TmpScale.value_or(0);
793 }
else if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
795 ErrMsg =
"Scale can't be negative";
798 IC.pushOperator(IC_NEG);
803 PrevState = CurrState;
807 IntelExprState CurrState = State;
833 IC.pushOperator(IC_NOT);
836 PrevState = CurrState;
838 bool onRegister(MCRegister
Reg, StringRef &ErrMsg) {
839 IntelExprState CurrState = State;
847 State = IES_REGISTER;
849 IC.pushOperand(IC_REGISTER);
850 if (NegativeAdditiveTerm) {
851 ErrMsg =
"Scale can't be negative";
859 ErrMsg =
"Register can't be multiplied with register!";
862 State = IES_REGISTER;
867 if (TmpScale.has_value()) {
869 return regsUseUpError(ErrMsg);
870 if (NegativeAdditiveTerm) {
871 ErrMsg =
"Scale can't be negative";
876 IC.pushOperand(IC_IMM);
878 IC.pushOperand(IC_REGISTER);
882 PrevState = CurrState;
885 bool onIdentifierExpr(
const MCExpr *SymRef, StringRef SymRefName,
886 const InlineAsmIdentifierInfo &IDInfo,
887 const AsmTypeInfo &
Type,
bool ParsingMSInlineAsm,
890 if (ParsingMSInlineAsm)
895 return onInteger(
CE->getValue(), ErrMsg);
908 if (setSymRef(SymRef, SymRefName, ErrMsg))
914 IC.pushOperand(IC_IMM);
915 if (ParsingMSInlineAsm)
922 bool onInteger(int64_t TmpInt, StringRef &ErrMsg) {
923 IntelExprState CurrState = State;
930 ErrMsg =
"division by zero in assembly expression";
937 ErrMsg =
"modulo by zero in assembly expression";
962 if (TmpScale.has_value()) {
963 TmpScale.value() *= TmpInt;
968 if (TmpReg && NegativeAdditiveTerm) {
969 ErrMsg =
"Scale can't be negative";
972 if (TmpReg &&
checkScale(TmpScale.value(), ErrMsg))
974 IC.pushOperand(IC_IMM, TmpInt);
977 PrevState = CurrState;
987 State = IES_MULTIPLY;
988 IC.pushOperator(IC_MULTIPLY);
995 if (TmpReg && (!TmpScale.has_value())) {
997 IC.pushOperand(IC_IMM);
999 State = IES_MULTIPLY;
1000 IC.pushOperator(IC_MULTIPLY);
1013 IC.pushOperator(IC_DIVIDE);
1026 IC.pushOperator(IC_MOD);
1042 IC.pushOperator(IC_PLUS);
1044 CurType.Size = CurType.ElementSize;
1048 assert(!BracCount &&
"BracCount should be zero on parsing's start");
1052 NegativeAdditiveTerm =
false;
1053 NegativeAdditiveTermLoc = SMLoc();
1061 bool onRBrac(StringRef &ErrMsg) {
1062 IntelExprState CurrState = State;
1071 if (BracCount-- != 1) {
1072 ErrMsg =
"unexpected bracket encountered";
1080 if (!BaseReg && !TmpScale.has_value()) {
1083 }
else if (!IndexReg) {
1084 if (NegativeAdditiveTerm) {
1085 ErrMsg =
"Scale can't be negative";
1090 if (TmpScale.has_value() &&
checkScale(TmpScale.value(), ErrMsg)) {
1093 Scale = TmpScale.value_or(0);
1095 return regsUseUpError(ErrMsg);
1098 NegativeAdditiveTerm =
false;
1099 NegativeAdditiveTermLoc = SMLoc();
1104 PrevState = CurrState;
1107 void onLParen(SMLoc Loc) {
1108 IntelExprState CurrState = State;
1136 IC.pushOperator(IC_LPAREN);
1139 PrevState = CurrState;
1141 bool onRParen(StringRef &ErrMsg) {
1142 IntelExprState CurrState = State;
1152 if (ParenCount == 0) {
1153 ErrMsg =
"unmatched parenthesis";
1158 IC.pushOperator(IC_RPAREN);
1161 PrevState = CurrState;
1164 bool onOffset(
const MCExpr *Val, SMLoc OffsetLoc, StringRef ID,
1165 const InlineAsmIdentifierInfo &IDInfo,
1166 bool ParsingMSInlineAsm, StringRef &ErrMsg) {
1170 ErrMsg =
"unexpected offset operator expression";
1175 if (setSymRef(Val, ID, ErrMsg))
1177 OffsetOperator =
true;
1178 OffsetOperatorLoc = OffsetLoc;
1182 IC.pushOperand(IC_IMM);
1183 if (ParsingMSInlineAsm) {
1190 void onCast(AsmTypeInfo Info) {
1202 void setTypeInfo(AsmTypeInfo
Type) { CurType =
Type; }
1206 bool MatchingInlineAsm =
false) {
1207 MCAsmParser &Parser = getParser();
1208 if (MatchingInlineAsm) {
1214 bool MatchRegisterByName(MCRegister &RegNo, StringRef
RegName, SMLoc StartLoc,
1216 bool ParseRegister(MCRegister &RegNo, SMLoc &StartLoc, SMLoc &EndLoc,
1217 bool RestoreOnFailure);
1219 std::unique_ptr<X86Operand> DefaultMemSIOperand(SMLoc Loc);
1220 std::unique_ptr<X86Operand> DefaultMemDIOperand(SMLoc Loc);
1221 bool IsSIReg(MCRegister
Reg);
1222 MCRegister GetSIDIForRegClass(
unsigned RegClassID,
bool IsSIReg);
1225 std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
1226 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst);
1232 bool ParseIntelOffsetOperator(
const MCExpr *&Val, StringRef &ID,
1233 InlineAsmIdentifierInfo &Info, SMLoc &End);
1234 bool ParseIntelDotOperator(IntelExprStateMachine &SM, SMLoc &End);
1235 unsigned IdentifyIntelInlineAsmOperator(StringRef Name);
1236 unsigned ParseIntelInlineAsmOperator(
unsigned OpKind);
1237 unsigned IdentifyMasmOperator(StringRef Name);
1238 bool ParseMasmOperator(
unsigned OpKind, int64_t &Val);
1241 bool ParseIntelNamedOperator(StringRef Name, IntelExprStateMachine &SM,
1242 bool &ParseError, SMLoc &End);
1243 bool ParseMasmNamedOperator(StringRef Name, IntelExprStateMachine &SM,
1244 bool &ParseError, SMLoc &End);
1245 void RewriteIntelExpression(IntelExprStateMachine &SM, SMLoc Start,
1247 bool ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End);
1248 bool ParseIntelInlineAsmIdentifier(
const MCExpr *&Val, StringRef &Identifier,
1249 InlineAsmIdentifierInfo &Info,
1250 bool IsUnevaluatedOperand, SMLoc &End,
1251 bool IsParsingOffsetOperator =
false);
1253 IntelExprStateMachine &SM);
1255 bool CheckDispOverflow(MCRegister BaseReg, MCRegister IndexReg,
1256 const MCExpr *Disp, SMLoc Loc);
1258 bool ParseMemOperand(MCRegister SegReg,
const MCExpr *Disp, SMLoc StartLoc,
1263 bool ParseIntelMemoryOperandSize(
unsigned &
Size, StringRef *SizeStr);
1264 bool CreateMemForMSInlineAsm(MCRegister SegReg,
const MCExpr *Disp,
1265 MCRegister BaseReg, MCRegister IndexReg,
1266 unsigned Scale,
bool NonAbsMem, SMLoc Start,
1267 SMLoc End,
unsigned Size, StringRef Identifier,
1268 const InlineAsmIdentifierInfo &Info,
1271 bool parseDirectiveArch();
1272 bool parseDirectiveNops(SMLoc L);
1273 bool parseDirectiveEven(SMLoc L);
1274 bool ParseDirectiveCode(StringRef IDVal, SMLoc L);
1277 bool parseDirectiveFPOProc(SMLoc L);
1278 bool parseDirectiveFPOSetFrame(SMLoc L);
1279 bool parseDirectiveFPOPushReg(SMLoc L);
1280 bool parseDirectiveFPOStackAlloc(SMLoc L);
1281 bool parseDirectiveFPOStackAlign(SMLoc L);
1282 bool parseDirectiveFPOEndPrologue(SMLoc L);
1283 bool parseDirectiveFPOEndProc(SMLoc L);
1286 bool parseSEHRegisterNumber(
unsigned RegClassID, MCRegister &RegNo);
1287 bool parseDirectiveSEHPushReg(SMLoc);
1288 bool parseDirectiveSEHPush2Regs(SMLoc,
bool SwapRegs =
false);
1289 bool parseDirectiveSEHSetFrame(SMLoc);
1290 bool parseDirectiveSEHSaveReg(SMLoc);
1291 bool parseDirectiveSEHSaveXMM(SMLoc);
1292 bool parseDirectiveSEHPushFrame(SMLoc);
1294 bool ensureMasmEpilogContext(SMLoc Loc);
1295 bool ensureMasmPrologContext(SMLoc Loc);
1297 unsigned checkTargetMatchPredicate(MCInst &Inst)
override;
1303 void emitWarningForSpecialLVIInstruction(SMLoc Loc);
1304 void applyLVICFIMitigation(MCInst &Inst, MCStreamer &Out);
1305 void applyLVILoadHardeningMitigation(MCInst &Inst, MCStreamer &Out);
1311 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1313 uint64_t &ErrorInfo,
1314 bool MatchingInlineAsm)
override;
1317 MCStreamer &Out,
bool MatchingInlineAsm);
1319 bool ErrorMissingFeature(SMLoc IDLoc,
const FeatureBitset &MissingFeatures,
1320 bool MatchingInlineAsm);
1322 bool matchAndEmitATTInstruction(SMLoc IDLoc,
unsigned &Opcode, MCInst &Inst,
1324 uint64_t &ErrorInfo,
bool MatchingInlineAsm);
1326 bool matchAndEmitIntelInstruction(SMLoc IDLoc,
unsigned &Opcode, MCInst &Inst,
1328 uint64_t &ErrorInfo,
1329 bool MatchingInlineAsm);
1331 bool omitRegisterFromClobberLists(MCRegister
Reg)
override;
1338 bool ParseZ(std::unique_ptr<X86Operand> &Z, SMLoc StartLoc);
1340 bool is64BitMode()
const {
1342 return getSTI().hasFeature(X86::Is64Bit);
1344 bool is32BitMode()
const {
1346 return getSTI().hasFeature(X86::Is32Bit);
1348 bool is16BitMode()
const {
1350 return getSTI().hasFeature(X86::Is16Bit);
1352 void SwitchMode(
unsigned mode) {
1353 MCSubtargetInfo &STI = copySTI();
1354 FeatureBitset AllModes({X86::Is64Bit, X86::Is32Bit, X86::Is16Bit});
1356 FeatureBitset FB = ComputeAvailableFeatures(
1358 setAvailableFeatures(FB);
1363 unsigned getPointerWidth() {
1364 if (is16BitMode())
return 16;
1365 if (is32BitMode())
return 32;
1366 if (is64BitMode())
return 64;
1370 bool isParsingIntelSyntax() {
1371 return getParser().getAssemblerDialect();
1377#define GET_ASSEMBLER_HEADER
1378#include "X86GenAsmMatcher.inc"
1383 enum X86MatchResultTy {
1384 Match_Unsupported = FIRST_TARGET_MATCH_RESULT_TY,
1385#define GET_OPERAND_DIAGNOSTIC_TYPES
1386#include "X86GenAsmMatcher.inc"
1389 X86AsmParser(
const MCSubtargetInfo &sti, MCAsmParser &Parser,
1390 const MCInstrInfo &mii)
1391 : MCTargetAsmParser(sti, mii), InstInfo(nullptr), Code16GCC(
false) {
1396 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
1399 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
1400 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1401 SMLoc &EndLoc)
override;
1403 bool parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc)
override;
1405 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
1408 bool ParseDirective(AsmToken DirectiveID)
override;
1412#define GET_REGISTER_MATCHER
1413#define GET_SUBTARGET_FEATURE_NAME
1414#include "X86GenAsmMatcher.inc"
1425 !(BaseReg == X86::RIP || BaseReg == X86::EIP ||
1426 getX86MCRegisterClass(X86::GR16RegClassID).
contains(BaseReg) ||
1427 getX86MCRegisterClass(X86::GR32RegClassID).
contains(BaseReg) ||
1428 getX86MCRegisterClass(X86::GR64RegClassID).
contains(BaseReg))) {
1429 ErrMsg =
"invalid base+index expression";
1434 !(IndexReg == X86::EIZ || IndexReg == X86::RIZ ||
1435 getX86MCRegisterClass(X86::GR16RegClassID).
contains(IndexReg) ||
1436 getX86MCRegisterClass(X86::GR32RegClassID).
contains(IndexReg) ||
1437 getX86MCRegisterClass(X86::GR64RegClassID).
contains(IndexReg) ||
1438 getX86MCRegisterClass(X86::VR128XRegClassID).
contains(IndexReg) ||
1439 getX86MCRegisterClass(X86::VR256XRegClassID).
contains(IndexReg) ||
1440 getX86MCRegisterClass(X86::VR512RegClassID).
contains(IndexReg))) {
1441 ErrMsg =
"invalid base+index expression";
1445 if (((BaseReg == X86::RIP || BaseReg == X86::EIP) && IndexReg) ||
1446 IndexReg == X86::EIP || IndexReg == X86::RIP || IndexReg == X86::ESP ||
1447 IndexReg == X86::RSP) {
1448 ErrMsg =
"invalid base+index expression";
1454 if (getX86MCRegisterClass(X86::GR16RegClassID).
contains(BaseReg) &&
1455 (Is64BitMode || (BaseReg != X86::BX && BaseReg != X86::BP &&
1456 BaseReg != X86::SI && BaseReg != X86::DI))) {
1457 ErrMsg =
"invalid 16-bit base register";
1462 getX86MCRegisterClass(X86::GR16RegClassID).
contains(IndexReg)) {
1463 ErrMsg =
"16-bit memory operand may not include only index register";
1467 if (BaseReg && IndexReg) {
1468 if (getX86MCRegisterClass(X86::GR64RegClassID).
contains(BaseReg) &&
1469 (getX86MCRegisterClass(X86::GR16RegClassID).
contains(IndexReg) ||
1470 getX86MCRegisterClass(X86::GR32RegClassID).
contains(IndexReg) ||
1471 IndexReg == X86::EIZ)) {
1472 ErrMsg =
"base register is 64-bit, but index register is not";
1475 if (getX86MCRegisterClass(X86::GR32RegClassID).
contains(BaseReg) &&
1476 (getX86MCRegisterClass(X86::GR16RegClassID).
contains(IndexReg) ||
1477 getX86MCRegisterClass(X86::GR64RegClassID).
contains(IndexReg) ||
1478 IndexReg == X86::RIZ)) {
1479 ErrMsg =
"base register is 32-bit, but index register is not";
1482 if (getX86MCRegisterClass(X86::GR16RegClassID).
contains(BaseReg)) {
1483 if (getX86MCRegisterClass(X86::GR32RegClassID).
contains(IndexReg) ||
1484 getX86MCRegisterClass(X86::GR64RegClassID).
contains(IndexReg)) {
1485 ErrMsg =
"base register is 16-bit, but index register is not";
1488 if ((BaseReg != X86::BX && BaseReg != X86::BP) ||
1489 (IndexReg != X86::SI && IndexReg != X86::DI)) {
1490 ErrMsg =
"invalid 16-bit base/index register combination";
1497 if (!Is64BitMode && (BaseReg == X86::RIP || BaseReg == X86::EIP)) {
1498 ErrMsg =
"IP-relative addressing requires 64-bit mode";
1519 if (isParsingMSInlineAsm() && isParsingIntelSyntax() &&
1520 (RegNo == X86::EFLAGS || RegNo == X86::MXCSR))
1521 RegNo = MCRegister();
1523 if (!is64BitMode()) {
1527 if (RegNo == X86::RIZ || RegNo == X86::RIP ||
1528 getX86MCRegisterClass(X86::GR64RegClassID).
contains(RegNo) ||
1531 return Error(StartLoc,
1532 "register %" +
RegName +
" is only available in 64-bit mode",
1533 SMRange(StartLoc, EndLoc));
1538 UseApxExtendedReg =
true;
1542 if (!RegNo &&
RegName.starts_with(
"db")) {
1601 if (isParsingIntelSyntax())
1603 return Error(StartLoc,
"invalid register name", SMRange(StartLoc, EndLoc));
1608bool X86AsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
1609 SMLoc &EndLoc,
bool RestoreOnFailure) {
1610 MCAsmParser &Parser = getParser();
1611 AsmLexer &Lexer = getLexer();
1612 RegNo = MCRegister();
1615 auto OnFailure = [RestoreOnFailure, &Lexer, &Tokens]() {
1616 if (RestoreOnFailure) {
1617 while (!Tokens.
empty()) {
1623 const AsmToken &PercentTok = Parser.
getTok();
1624 StartLoc = PercentTok.
getLoc();
1633 const AsmToken &Tok = Parser.
getTok();
1638 if (isParsingIntelSyntax())
return true;
1639 return Error(StartLoc,
"invalid register name",
1640 SMRange(StartLoc, EndLoc));
1643 if (MatchRegisterByName(RegNo, Tok.
getString(), StartLoc, EndLoc)) {
1649 if (RegNo == X86::ST0) {
1660 const AsmToken &IntTok = Parser.
getTok();
1663 return Error(IntTok.
getLoc(),
"expected stack index");
1666 case 0: RegNo = X86::ST0;
break;
1667 case 1: RegNo = X86::ST1;
break;
1668 case 2: RegNo = X86::ST2;
break;
1669 case 3: RegNo = X86::ST3;
break;
1670 case 4: RegNo = X86::ST4;
break;
1671 case 5: RegNo = X86::ST5;
break;
1672 case 6: RegNo = X86::ST6;
break;
1673 case 7: RegNo = X86::ST7;
break;
1676 return Error(IntTok.
getLoc(),
"invalid stack index");
1696 if (isParsingIntelSyntax())
return true;
1697 return Error(StartLoc,
"invalid register name",
1698 SMRange(StartLoc, EndLoc));
1705bool X86AsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1707 return ParseRegister(
Reg, StartLoc, EndLoc,
false);
1710ParseStatus X86AsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1712 bool Result = ParseRegister(
Reg, StartLoc, EndLoc,
true);
1713 bool PendingErrors = getParser().hasPendingError();
1714 getParser().clearPendingErrors();
1722std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(SMLoc Loc) {
1723 bool Parse32 = is32BitMode() || Code16GCC;
1724 MCRegister Basereg =
1725 is64BitMode() ? X86::RSI : (Parse32 ? X86::ESI : X86::SI);
1732std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand(SMLoc Loc) {
1733 bool Parse32 = is32BitMode() || Code16GCC;
1734 MCRegister Basereg =
1735 is64BitMode() ? X86::RDI : (Parse32 ? X86::EDI : X86::DI);
1742bool X86AsmParser::IsSIReg(MCRegister
Reg) {
1756MCRegister X86AsmParser::GetSIDIForRegClass(
unsigned RegClassID,
bool IsSIReg) {
1757 switch (RegClassID) {
1759 case X86::GR64RegClassID:
1760 return IsSIReg ? X86::RSI : X86::RDI;
1761 case X86::GR32RegClassID:
1762 return IsSIReg ? X86::ESI : X86::EDI;
1763 case X86::GR16RegClassID:
1764 return IsSIReg ? X86::SI : X86::DI;
1768void X86AsmParser::AddDefaultSrcDestOperands(
1770 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst) {
1771 if (isParsingIntelSyntax()) {
1772 Operands.push_back(std::move(Dst));
1773 Operands.push_back(std::move(Src));
1776 Operands.push_back(std::move(Src));
1777 Operands.push_back(std::move(Dst));
1781bool X86AsmParser::VerifyAndAdjustOperands(
OperandVector &OrigOperands,
1784 if (OrigOperands.
size() > 1) {
1787 "Operand size mismatch");
1791 int RegClassID = -1;
1792 for (
unsigned int i = 0; i < FinalOperands.
size(); ++i) {
1793 X86Operand &OrigOp =
static_cast<X86Operand &
>(*OrigOperands[i + 1]);
1794 X86Operand &FinalOp =
static_cast<X86Operand &
>(*FinalOperands[i]);
1796 if (FinalOp.
isReg() &&
1801 if (FinalOp.
isMem()) {
1803 if (!OrigOp.
isMem())
1812 if (RegClassID != -1 &&
1813 !getX86MCRegisterClass(RegClassID).
contains(OrigReg)) {
1815 "mismatching source and destination index registers");
1818 if (getX86MCRegisterClass(X86::GR64RegClassID).
contains(OrigReg))
1819 RegClassID = X86::GR64RegClassID;
1820 else if (getX86MCRegisterClass(X86::GR32RegClassID).
contains(OrigReg))
1821 RegClassID = X86::GR32RegClassID;
1822 else if (getX86MCRegisterClass(X86::GR16RegClassID).
contains(OrigReg))
1823 RegClassID = X86::GR16RegClassID;
1829 bool IsSI = IsSIReg(FinalReg);
1830 FinalReg = GetSIDIForRegClass(RegClassID, IsSI);
1832 if (FinalReg != OrigReg) {
1833 std::string
RegName = IsSI ?
"ES:(R|E)SI" :
"ES:(R|E)DI";
1836 "memory operand is only for determining the size, " +
RegName +
1837 " will be used for the location"));
1848 for (
auto &WarningMsg : Warnings) {
1849 Warning(WarningMsg.first, WarningMsg.second);
1853 for (
unsigned int i = 0; i < FinalOperands.
size(); ++i)
1857 for (
auto &
Op : FinalOperands)
1864 if (isParsingIntelSyntax())
1865 return parseIntelOperand(
Operands, Name);
1870bool X86AsmParser::CreateMemForMSInlineAsm(
1871 MCRegister SegReg,
const MCExpr *Disp, MCRegister BaseReg,
1872 MCRegister IndexReg,
unsigned Scale,
bool NonAbsMem, SMLoc Start, SMLoc End,
1873 unsigned Size, StringRef Identifier,
const InlineAsmIdentifierInfo &Info,
1881 End,
Size, Identifier,
1888 unsigned FrontendSize = 0;
1889 void *Decl =
nullptr;
1890 bool IsGlobalLV =
false;
1893 FrontendSize =
Info.Var.Type * 8;
1894 Decl =
Info.Var.Decl;
1895 IsGlobalLV =
Info.Var.IsGlobalLV;
1900 if (BaseReg || IndexReg) {
1902 End,
Size, Identifier, Decl, 0,
1903 BaseReg && IndexReg));
1910 getPointerWidth(), SegReg, Disp, BaseReg, IndexReg, Scale, Start, End,
1912 X86::RIP, Identifier, Decl, FrontendSize));
1919bool X86AsmParser::ParseIntelNamedOperator(StringRef Name,
1920 IntelExprStateMachine &SM,
1921 bool &ParseError, SMLoc &End) {
1924 if (Name !=
Name.lower() && Name !=
Name.upper() &&
1925 !getParser().isParsingMasm())
1927 if (
Name.equals_insensitive(
"not")) {
1929 }
else if (
Name.equals_insensitive(
"or")) {
1931 }
else if (
Name.equals_insensitive(
"shl")) {
1933 }
else if (
Name.equals_insensitive(
"shr")) {
1935 }
else if (
Name.equals_insensitive(
"xor")) {
1937 }
else if (
Name.equals_insensitive(
"and")) {
1939 }
else if (
Name.equals_insensitive(
"mod")) {
1941 }
else if (
Name.equals_insensitive(
"offset")) {
1942 SMLoc OffsetLoc = getTok().getLoc();
1943 const MCExpr *Val =
nullptr;
1945 InlineAsmIdentifierInfo
Info;
1946 ParseError = ParseIntelOffsetOperator(Val, ID, Info, End);
1951 SM.onOffset(Val, OffsetLoc, ID, Info, isParsingMSInlineAsm(), ErrMsg);
1957 if (!
Name.equals_insensitive(
"offset"))
1958 End = consumeToken();
1961bool X86AsmParser::ParseMasmNamedOperator(StringRef Name,
1962 IntelExprStateMachine &SM,
1963 bool &ParseError, SMLoc &End) {
1964 if (
Name.equals_insensitive(
"eq")) {
1966 }
else if (
Name.equals_insensitive(
"ne")) {
1968 }
else if (
Name.equals_insensitive(
"lt")) {
1970 }
else if (
Name.equals_insensitive(
"le")) {
1972 }
else if (
Name.equals_insensitive(
"gt")) {
1974 }
else if (
Name.equals_insensitive(
"ge")) {
1979 End = consumeToken();
1986 IntelExprStateMachine &SM) {
1990 SM.setAppendAfterOperand();
1993bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
1994 MCAsmParser &Parser = getParser();
1999 if (
getContext().getObjectFileInfo()->isPositionIndependent())
2006 const AsmToken &Tok = Parser.
getTok();
2008 bool UpdateLocLex =
true;
2013 if ((
Done = SM.isValidEndState()))
2015 return Error(Tok.
getLoc(),
"unknown token in expression");
2017 return Error(getLexer().getErrLoc(), getLexer().getErr());
2021 UpdateLocLex =
false;
2022 if (ParseIntelDotOperator(SM, End))
2027 if ((
Done = SM.isValidEndState()))
2029 return Error(Tok.
getLoc(),
"unknown token in expression");
2033 UpdateLocLex =
false;
2034 if (ParseIntelDotOperator(SM, End))
2039 if ((
Done = SM.isValidEndState()))
2041 return Error(Tok.
getLoc(),
"unknown token in expression");
2047 SMLoc ValueLoc = Tok.
getLoc();
2052 UpdateLocLex =
false;
2053 if (!Val->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
2054 return Error(ValueLoc,
"expected absolute value");
2055 if (SM.onInteger(Res, ErrMsg))
2056 return Error(SM.getErrorLoc(ValueLoc), ErrMsg);
2063 SMLoc IdentLoc = Tok.
getLoc();
2065 UpdateLocLex =
false;
2067 size_t DotOffset =
Identifier.find_first_of(
'.');
2071 StringRef Dot =
Identifier.substr(DotOffset, 1);
2085 const AsmToken &NextTok = getLexer().peekTok();
2094 End = consumeToken();
2101 if (!ParseRegister(
Reg, IdentLoc, End,
true)) {
2102 if (SM.onRegister(
Reg, ErrMsg))
2103 return Error(SM.getErrorLoc(IdentLoc), ErrMsg);
2107 const std::pair<StringRef, StringRef> IDField =
2109 const StringRef
ID = IDField.first,
Field = IDField.second;
2111 if (!
Field.empty() &&
2112 !MatchRegisterByName(
Reg, ID, IdentLoc, IDEndLoc)) {
2113 if (SM.onRegister(
Reg, ErrMsg))
2114 return Error(SM.getErrorLoc(IdentLoc), ErrMsg);
2119 return Error(FieldStartLoc,
"unknown offset");
2120 else if (SM.onPlus(ErrMsg))
2121 return Error(getTok().getLoc(), ErrMsg);
2122 else if (SM.onInteger(
Info.Offset, ErrMsg))
2123 return Error(SM.getErrorLoc(IdentLoc), ErrMsg);
2124 SM.setTypeInfo(
Info.Type);
2126 End = consumeToken();
2133 if (ParseIntelNamedOperator(Identifier, SM, ParseError, End)) {
2139 ParseMasmNamedOperator(Identifier, SM, ParseError, End)) {
2145 InlineAsmIdentifierInfo
Info;
2146 AsmFieldInfo FieldInfo;
2152 if (ParseIntelDotOperator(SM, End))
2157 if (isParsingMSInlineAsm()) {
2159 if (
unsigned OpKind = IdentifyIntelInlineAsmOperator(Identifier)) {
2160 if (int64_t Val = ParseIntelInlineAsmOperator(OpKind)) {
2161 if (SM.onInteger(Val, ErrMsg))
2162 return Error(SM.getErrorLoc(IdentLoc), ErrMsg);
2171 return Error(IdentLoc,
"expected identifier");
2172 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
false, End))
2174 else if (SM.onIdentifierExpr(Val, Identifier, Info, FieldInfo.
Type,
2176 return Error(SM.getErrorLoc(IdentLoc), ErrMsg);
2180 if (
unsigned OpKind = IdentifyMasmOperator(Identifier)) {
2182 if (ParseMasmOperator(OpKind, Val))
2184 if (SM.onInteger(Val, ErrMsg))
2185 return Error(SM.getErrorLoc(IdentLoc), ErrMsg);
2188 if (!getParser().lookUpType(Identifier, FieldInfo.
Type)) {
2194 getParser().parseIdentifier(Identifier);
2198 if (getParser().lookUpField(FieldInfo.
Type.
Name, Identifier,
2202 return Error(IdentLoc,
"Unable to lookup field reference!",
2203 SMRange(IdentLoc, IDEnd));
2208 if (SM.onInteger(FieldInfo.
Offset, ErrMsg))
2209 return Error(SM.getErrorLoc(IdentLoc), ErrMsg);
2213 if (getParser().parsePrimaryExpr(Val, End, &FieldInfo.
Type)) {
2214 return Error(Tok.
getLoc(),
"Unexpected identifier!");
2215 }
else if (SM.onIdentifierExpr(Val, Identifier, Info, FieldInfo.
Type,
2217 return Error(SM.getErrorLoc(IdentLoc), ErrMsg);
2223 SMLoc Loc = getTok().getLoc();
2224 int64_t
IntVal = getTok().getIntVal();
2225 End = consumeToken();
2226 UpdateLocLex =
false;
2228 StringRef IDVal = getTok().getString();
2229 if (IDVal ==
"f" || IDVal ==
"b") {
2231 getContext().getDirectionalLocalSymbol(IntVal, IDVal ==
"b");
2236 return Error(Loc,
"invalid reference to undefined symbol");
2238 InlineAsmIdentifierInfo
Info;
2240 if (SM.onIdentifierExpr(Val, Identifier, Info,
Type,
2241 isParsingMSInlineAsm(), ErrMsg))
2242 return Error(SM.getErrorLoc(Loc), ErrMsg);
2243 End = consumeToken();
2245 if (SM.onInteger(IntVal, ErrMsg))
2246 return Error(SM.getErrorLoc(Loc), ErrMsg);
2249 if (SM.onInteger(IntVal, ErrMsg))
2250 return Error(SM.getErrorLoc(Loc), ErrMsg);
2255 if (SM.onPlus(ErrMsg))
2256 return Error(getTok().getLoc(), ErrMsg);
2259 if (SM.onMinus(getTok().getLoc(), ErrMsg))
2260 return Error(SM.getErrorLoc(getTok().getLoc()), ErrMsg);
2270 SM.onLShift();
break;
2272 SM.onRShift();
break;
2275 return Error(Tok.
getLoc(),
"unexpected bracket encountered");
2276 tryParseOperandIdx(PrevTK, SM);
2279 if (SM.onRBrac(ErrMsg)) {
2280 return Error(SM.getErrorLoc(Tok.
getLoc()), ErrMsg);
2284 SM.onLParen(Tok.
getLoc());
2287 if (SM.onRParen(ErrMsg)) {
2288 return Error(SM.getErrorLoc(Tok.
getLoc()), ErrMsg);
2293 return Error(Tok.
getLoc(),
"unknown token in expression");
2295 if (!
Done && UpdateLocLex)
2296 End = consumeToken();
2300 if (SM.hasUnmatchedParen())
2301 return Error(SM.getLParenLoc(),
"unmatched parenthesis");
2305void X86AsmParser::RewriteIntelExpression(IntelExprStateMachine &SM,
2306 SMLoc Start, SMLoc End) {
2310 if (SM.getSym() && !SM.isOffsetOperator()) {
2311 StringRef SymName = SM.getSymName();
2312 if (
unsigned Len = SymName.
data() -
Start.getPointer())
2318 if (!(SM.getBaseReg() || SM.getIndexReg() || SM.getImm())) {
2325 StringRef BaseRegStr;
2326 StringRef IndexRegStr;
2327 StringRef OffsetNameStr;
2328 if (SM.getBaseReg())
2330 if (SM.getIndexReg())
2332 if (SM.isOffsetOperator())
2333 OffsetNameStr = SM.getSymName();
2335 IntelExpr Expr(BaseRegStr, IndexRegStr, SM.getScale(), OffsetNameStr,
2336 SM.getImm(), SM.isMemExpr());
2337 InstInfo->
AsmRewrites->emplace_back(Loc, ExprLen, Expr);
2341bool X86AsmParser::ParseIntelInlineAsmIdentifier(
2342 const MCExpr *&Val, StringRef &Identifier, InlineAsmIdentifierInfo &Info,
2343 bool IsUnevaluatedOperand, SMLoc &End,
bool IsParsingOffsetOperator) {
2344 MCAsmParser &Parser = getParser();
2345 assert(isParsingMSInlineAsm() &&
"Expected to be parsing inline assembly.");
2349 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);
2351 const AsmToken &Tok = Parser.
getTok();
2352 SMLoc Loc = Tok.
getLoc();
2367 "frontend claimed part of a token?");
2372 StringRef InternalName =
2373 SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(),
2375 assert(InternalName.
size() &&
"We should have an internal name here.");
2378 if (!IsParsingOffsetOperator)
2394 MCAsmParser &Parser = getParser();
2395 const AsmToken &Tok = Parser.
getTok();
2397 const SMLoc consumedToken = consumeToken();
2399 return Error(Tok.
getLoc(),
"Expected an identifier after {");
2402 .Case(
"rn", X86::STATIC_ROUNDING::TO_NEAREST_INT)
2403 .Case(
"rd", X86::STATIC_ROUNDING::TO_NEG_INF)
2404 .Case(
"ru", X86::STATIC_ROUNDING::TO_POS_INF)
2405 .Case(
"rz", X86::STATIC_ROUNDING::TO_ZERO)
2408 return Error(Tok.
getLoc(),
"Invalid rounding mode.");
2411 return Error(Tok.
getLoc(),
"Expected - at this point");
2415 return Error(Tok.
getLoc(),
"Expected } at this point");
2418 const MCExpr *RndModeOp =
2426 return Error(Tok.
getLoc(),
"Expected } at this point");
2431 return Error(Tok.
getLoc(),
"unknown token in expression");
2437 MCAsmParser &Parser = getParser();
2438 AsmToken Tok = Parser.
getTok();
2441 return Error(Tok.
getLoc(),
"Expected { at this point");
2445 return Error(Tok.
getLoc(),
"Expected dfv at this point");
2449 return Error(Tok.
getLoc(),
"Expected = at this point");
2461 unsigned CFlags = 0;
2462 for (
unsigned I = 0;
I < 4; ++
I) {
2471 return Error(Tok.
getLoc(),
"Invalid conditional flags");
2474 return Error(Tok.
getLoc(),
"Duplicated conditional flag");
2485 }
else if (
I == 3) {
2486 return Error(Tok.
getLoc(),
"Expected } at this point");
2488 return Error(Tok.
getLoc(),
"Expected } or , at this point");
2496bool X86AsmParser::ParseIntelDotOperator(IntelExprStateMachine &SM,
2498 const AsmToken &Tok = getTok();
2504 bool TrailingDot =
false;
2512 }
else if ((isParsingMSInlineAsm() || getParser().isParsingMasm()) &&
2515 const std::pair<StringRef, StringRef> BaseMember = DotDispStr.
split(
'.');
2516 const StringRef
Base = BaseMember.first,
Member = BaseMember.second;
2517 if (getParser().lookUpField(SM.getType(), DotDispStr, Info) &&
2518 getParser().lookUpField(SM.getSymName(), DotDispStr, Info) &&
2519 getParser().lookUpField(DotDispStr, Info) &&
2521 SemaCallback->LookupInlineAsmField(
Base, Member,
Info.Offset)))
2522 return Error(Tok.
getLoc(),
"Unable to lookup field reference!");
2524 return Error(Tok.
getLoc(),
"Unexpected token type!");
2529 const char *DotExprEndLoc = DotDispStr.
data() + DotDispStr.
size();
2534 SM.addImm(
Info.Offset);
2535 SM.setTypeInfo(
Info.Type);
2541bool X86AsmParser::ParseIntelOffsetOperator(
const MCExpr *&Val, StringRef &ID,
2542 InlineAsmIdentifierInfo &Info,
2545 SMLoc
Start = Lex().getLoc();
2546 ID = getTok().getString();
2547 if (!isParsingMSInlineAsm()) {
2550 getParser().parsePrimaryExpr(Val, End,
nullptr))
2551 return Error(Start,
"unexpected token!");
2552 }
else if (ParseIntelInlineAsmIdentifier(Val, ID, Info,
false, End,
true)) {
2553 return Error(Start,
"unable to lookup expression");
2555 return Error(Start,
"offset operator cannot yet handle constants");
2562unsigned X86AsmParser::IdentifyIntelInlineAsmOperator(StringRef Name) {
2563 return StringSwitch<unsigned>(Name)
2564 .Cases({
"TYPE",
"type"}, IOK_TYPE)
2565 .Cases({
"SIZE",
"size"}, IOK_SIZE)
2566 .Cases({
"LENGTH",
"length"}, IOK_LENGTH)
2576unsigned X86AsmParser::ParseIntelInlineAsmOperator(
unsigned OpKind) {
2577 MCAsmParser &Parser = getParser();
2578 const AsmToken &Tok = Parser.
getTok();
2581 const MCExpr *Val =
nullptr;
2582 InlineAsmIdentifierInfo
Info;
2585 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
2590 Error(Start,
"unable to lookup expression");
2597 case IOK_LENGTH: CVal =
Info.Var.Length;
break;
2598 case IOK_SIZE: CVal =
Info.Var.Size;
break;
2599 case IOK_TYPE: CVal =
Info.Var.Type;
break;
2607unsigned X86AsmParser::IdentifyMasmOperator(StringRef Name) {
2608 return StringSwitch<unsigned>(
Name.lower())
2609 .Case(
"type", MOK_TYPE)
2610 .Cases({
"size",
"sizeof"}, MOK_SIZEOF)
2611 .Cases({
"length",
"lengthof"}, MOK_LENGTHOF)
2621bool X86AsmParser::ParseMasmOperator(
unsigned OpKind, int64_t &Val) {
2622 MCAsmParser &Parser = getParser();
2627 if (OpKind == MOK_SIZEOF || OpKind == MOK_TYPE) {
2630 const AsmToken &IDTok = InParens ? getLexer().peekTok() : Parser.
getTok();
2646 IntelExprStateMachine SM;
2648 if (ParseIntelExpression(SM, End))
2658 Val = SM.getLength();
2661 Val = SM.getElementSize();
2666 return Error(OpLoc,
"expression has unknown type", SMRange(Start, End));
2672bool X86AsmParser::ParseIntelMemoryOperandSize(
unsigned &
Size,
2673 StringRef *SizeStr) {
2674 Size = StringSwitch<unsigned>(getTok().getString())
2675 .Cases({
"BYTE",
"byte"}, 8)
2676 .Cases({
"WORD",
"word"}, 16)
2677 .Cases({
"DWORD",
"dword"}, 32)
2678 .Cases({
"FLOAT",
"float"}, 32)
2679 .Cases({
"LONG",
"long"}, 32)
2680 .Cases({
"FWORD",
"fword"}, 48)
2681 .Cases({
"DOUBLE",
"double"}, 64)
2682 .Cases({
"QWORD",
"qword"}, 64)
2683 .Cases({
"MMWORD",
"mmword"}, 64)
2684 .Cases({
"XWORD",
"xword"}, 80)
2685 .Cases({
"TBYTE",
"tbyte"}, 80)
2686 .Cases({
"XMMWORD",
"xmmword"}, 128)
2687 .Cases({
"YMMWORD",
"ymmword"}, 256)
2688 .Cases({
"ZMMWORD",
"zmmword"}, 512)
2692 *SizeStr = getTok().getString();
2693 const AsmToken &Tok = Lex();
2695 return Error(Tok.
getLoc(),
"Expected 'PTR' or 'ptr' token!");
2702 if (getX86MCRegisterClass(X86::GR8RegClassID).
contains(RegNo))
2704 if (getX86MCRegisterClass(X86::GR16RegClassID).
contains(RegNo))
2706 if (getX86MCRegisterClass(X86::GR32RegClassID).
contains(RegNo))
2708 if (getX86MCRegisterClass(X86::GR64RegClassID).
contains(RegNo))
2715 MCAsmParser &Parser = getParser();
2716 const AsmToken &Tok = Parser.
getTok();
2722 if (ParseIntelMemoryOperandSize(
Size, &SizeStr))
2724 bool PtrInOperand = bool(
Size);
2730 return ParseRoundingModeOp(Start,
Operands);
2735 if (RegNo == X86::RIP)
2736 return Error(Start,
"rip can only be used as a base register");
2741 return Error(Start,
"expected memory operand after 'ptr', "
2742 "found register operand instead");
2751 "cannot cast register '" +
2753 "'; its size is not easily defined.");
2757 std::to_string(
RegSize) +
"-bit register '" +
2759 "' cannot be used as a " + std::to_string(
Size) +
"-bit " +
2766 if (!getX86MCRegisterClass(X86::SEGMENT_REGRegClassID).
contains(RegNo))
2767 return Error(Start,
"invalid segment register");
2769 Start = Lex().getLoc();
2773 IntelExprStateMachine SM;
2774 if (ParseIntelExpression(SM, End))
2777 if (isParsingMSInlineAsm())
2778 RewriteIntelExpression(SM, Start, Tok.
getLoc());
2780 int64_t
Imm = SM.getImm();
2781 const MCExpr *Disp = SM.getSym();
2790 if (!SM.isMemExpr() && !RegNo) {
2791 if (isParsingMSInlineAsm() && SM.isOffsetOperator()) {
2792 const InlineAsmIdentifierInfo &
Info = SM.getIdentifierInfo();
2797 SM.getSymName(),
Info.Var.Decl,
2798 Info.Var.IsGlobalLV));
2808 MCRegister
BaseReg = SM.getBaseReg();
2809 MCRegister IndexReg = SM.getIndexReg();
2810 if (IndexReg && BaseReg == X86::RIP)
2812 unsigned Scale = SM.getScale();
2814 Size = SM.getElementSize() << 3;
2816 if (Scale == 0 && BaseReg != X86::ESP && BaseReg != X86::RSP &&
2817 (IndexReg == X86::ESP || IndexReg == X86::RSP))
2823 !(getX86MCRegisterClass(X86::VR128XRegClassID).
contains(IndexReg) ||
2824 getX86MCRegisterClass(X86::VR256XRegClassID).
contains(IndexReg) ||
2825 getX86MCRegisterClass(X86::VR512RegClassID).
contains(IndexReg)) &&
2826 (getX86MCRegisterClass(X86::VR128XRegClassID).
contains(BaseReg) ||
2827 getX86MCRegisterClass(X86::VR256XRegClassID).
contains(BaseReg) ||
2828 getX86MCRegisterClass(X86::VR512RegClassID).
contains(BaseReg)))
2832 getX86MCRegisterClass(X86::GR16RegClassID).
contains(IndexReg))
2833 return Error(Start,
"16-bit addresses cannot have a scale");
2842 if ((BaseReg == X86::SI || BaseReg == X86::DI) &&
2843 (IndexReg == X86::BX || IndexReg == X86::BP))
2846 if ((BaseReg || IndexReg) &&
2849 return Error(Start, ErrMsg);
2850 bool IsUnconditionalBranch =
2851 Name.equals_insensitive(
"jmp") ||
Name.equals_insensitive(
"call");
2852 if (isParsingMSInlineAsm())
2853 return CreateMemForMSInlineAsm(RegNo, Disp, BaseReg, IndexReg, Scale,
2854 IsUnconditionalBranch && is64BitMode(),
2855 Start, End,
Size, SM.getSymName(),
2860 MCRegister DefaultBaseReg;
2861 bool MaybeDirectBranchDest =
true;
2864 if (is64BitMode() &&
2865 ((PtrInOperand && !IndexReg) || SM.getElementSize() > 0)) {
2866 DefaultBaseReg = X86::RIP;
2868 if (IsUnconditionalBranch) {
2870 MaybeDirectBranchDest =
false;
2872 DefaultBaseReg = X86::RIP;
2873 }
else if (!BaseReg && !IndexReg && Disp &&
2875 if (is64BitMode()) {
2876 if (SM.getSize() == 8) {
2877 MaybeDirectBranchDest =
false;
2878 DefaultBaseReg = X86::RIP;
2881 if (SM.getSize() == 4 || SM.getSize() == 2)
2882 MaybeDirectBranchDest =
false;
2886 }
else if (IsUnconditionalBranch) {
2888 if (!PtrInOperand && SM.isOffsetOperator())
2890 Start,
"`OFFSET` operator cannot be used in an unconditional branch");
2891 if (PtrInOperand || SM.isBracketUsed())
2892 MaybeDirectBranchDest =
false;
2895 if (CheckDispOverflow(BaseReg, IndexReg, Disp, Start))
2898 if ((BaseReg || IndexReg || RegNo || DefaultBaseReg))
2900 getPointerWidth(), RegNo, Disp, BaseReg, IndexReg, Scale, Start, End,
2901 Size, DefaultBaseReg, StringRef(),
nullptr,
2902 0,
false, MaybeDirectBranchDest));
2905 getPointerWidth(), Disp, Start, End,
Size, StringRef(),
2907 MaybeDirectBranchDest));
2912 MCAsmParser &Parser = getParser();
2913 switch (getLexer().getKind()) {
2923 "expected immediate expression") ||
2924 getParser().parseExpression(Val, End) ||
2932 return ParseRoundingModeOp(Start,
Operands);
2941 const MCExpr *Expr =
nullptr;
2953 if (
Reg == X86::EIZ ||
Reg == X86::RIZ)
2955 Loc,
"%eiz and %riz can only be used as index registers",
2956 SMRange(Loc, EndLoc));
2957 if (
Reg == X86::RIP)
2958 return Error(Loc,
"%rip can only be used as a base register",
2959 SMRange(Loc, EndLoc));
2965 if (!getX86MCRegisterClass(X86::SEGMENT_REGRegClassID).
contains(
Reg))
2966 return Error(Loc,
"invalid segment register");
2974 return ParseMemOperand(
Reg, Expr, Loc, EndLoc,
Operands);
2981X86::CondCode X86AsmParser::ParseConditionCode(StringRef CC) {
2982 return StringSwitch<X86::CondCode>(CC)
3004bool X86AsmParser::ParseZ(std::unique_ptr<X86Operand> &Z, SMLoc StartLoc) {
3005 MCAsmParser &Parser = getParser();
3010 (getLexer().getTok().getIdentifier() ==
"z")))
3015 return Error(getLexer().getLoc(),
"Expected } at this point");
3024 MCAsmParser &Parser = getParser();
3027 const SMLoc consumedToken = consumeToken();
3031 if (getLexer().getTok().getIntVal() != 1)
3032 return TokError(
"Expected 1to<NUM> at this point");
3033 StringRef
Prefix = getLexer().getTok().getString();
3036 return TokError(
"Expected 1to<NUM> at this point");
3039 StringRef BroadcastString = (
Prefix + getLexer().getTok().getIdentifier())
3042 return TokError(
"Expected 1to<NUM> at this point");
3043 const char *BroadcastPrimitive =
3044 StringSwitch<const char *>(BroadcastString)
3045 .Case(
"1to2",
"{1to2}")
3046 .Case(
"1to4",
"{1to4}")
3047 .Case(
"1to8",
"{1to8}")
3048 .Case(
"1to16",
"{1to16}")
3049 .Case(
"1to32",
"{1to32}")
3051 if (!BroadcastPrimitive)
3052 return TokError(
"Invalid memory broadcast primitive.");
3055 return TokError(
"Expected } at this point");
3066 std::unique_ptr<X86Operand>
Z;
3067 if (ParseZ(Z, consumedToken))
3073 SMLoc StartLoc =
Z ? consumeToken() : consumedToken;
3078 if (!parseRegister(RegNo, RegLoc, StartLoc) &&
3079 getX86MCRegisterClass(X86::VK1RegClassID).
contains(RegNo)) {
3080 if (RegNo == X86::K0)
3081 return Error(RegLoc,
"Register k0 can't be used as write mask");
3083 return Error(getLexer().getLoc(),
"Expected } at this point");
3089 return Error(getLexer().getLoc(),
3090 "Expected an op-mask register at this point");
3095 if (ParseZ(Z, consumeToken()) || !Z)
3096 return Error(getLexer().getLoc(),
3097 "Expected a {z} mark at this point");
3112bool X86AsmParser::CheckDispOverflow(MCRegister BaseReg, MCRegister IndexReg,
3113 const MCExpr *Disp, SMLoc Loc) {
3119 if (BaseReg || IndexReg) {
3121 auto Imm =
CE->getValue();
3123 getX86MCRegisterClass(X86::GR64RegClassID).contains(BaseReg) ||
3124 getX86MCRegisterClass(X86::GR64RegClassID).contains(IndexReg);
3125 bool Is16 = getX86MCRegisterClass(X86::GR16RegClassID).contains(BaseReg);
3128 return Error(Loc,
"displacement " + Twine(Imm) +
3129 " is not within [-2147483648, 2147483647]");
3131 if (!
isUInt<32>(Imm < 0 ? -uint64_t(Imm) : uint64_t(Imm))) {
3132 Warning(Loc,
"displacement " + Twine(Imm) +
3133 " shortened to 32-bit signed " +
3134 Twine(
static_cast<int32_t
>(Imm)));
3136 }
else if (!
isUInt<16>(Imm < 0 ? -uint64_t(Imm) : uint64_t(Imm))) {
3137 Warning(Loc,
"displacement " + Twine(Imm) +
3138 " shortened to 16-bit signed " +
3139 Twine(
static_cast<int16_t
>(Imm)));
3148bool X86AsmParser::ParseMemOperand(MCRegister SegReg,
const MCExpr *Disp,
3149 SMLoc StartLoc, SMLoc EndLoc,
3151 MCAsmParser &Parser = getParser();
3169 auto isAtMemOperand = [
this]() {
3174 auto TokCount = this->getLexer().peekTokens(Buf,
true);
3177 switch (Buf[0].getKind()) {
3184 if ((TokCount > 1) &&
3188 Buf[1].getIdentifier().
size() + 1);
3210 if (!isAtMemOperand()) {
3229 0, 0, 1, StartLoc, EndLoc));
3237 SMLoc BaseLoc = getLexer().getLoc();
3249 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ)
3250 return Error(BaseLoc,
"eiz and riz can only be used as index registers",
3251 SMRange(BaseLoc, EndLoc));
3269 if (!
E->evaluateAsAbsolute(ScaleVal, getStreamer().getAssemblerPtr()))
3270 return Error(Loc,
"expected absolute expression");
3272 Warning(Loc,
"scale factor without index register is ignored");
3277 if (BaseReg == X86::RIP)
3279 "%rip as base register can not have an index register");
3280 if (IndexReg == X86::RIP)
3281 return Error(Loc,
"%rip is not allowed as an index register");
3292 return Error(Loc,
"expected scale expression");
3293 Scale = (unsigned)ScaleVal;
3295 if (getX86MCRegisterClass(X86::GR16RegClassID).
contains(BaseReg) &&
3297 return Error(Loc,
"scale factor in 16-bit address must be 1");
3299 return Error(Loc, ErrMsg);
3313 if (BaseReg == X86::DX && !IndexReg && Scale == 1 && !SegReg &&
3322 return Error(BaseLoc, ErrMsg);
3324 if (CheckDispOverflow(BaseReg, IndexReg, Disp, BaseLoc))
3327 if (SegReg || BaseReg || IndexReg)
3329 BaseReg, IndexReg, Scale, StartLoc,
3338bool X86AsmParser::parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
3339 MCAsmParser &Parser = getParser();
3346 if (parseRegister(RegNo, StartLoc, EndLoc))
3354bool X86AsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
3356 MCAsmParser &Parser = getParser();
3360 ForcedOpcodePrefix = OpcodePrefix_Default;
3361 ForcedDispEncoding = DispEncoding_Default;
3362 UseApxExtendedReg =
false;
3363 ForcedNoFlag =
false;
3376 if (Prefix ==
"rex")
3377 ForcedOpcodePrefix = OpcodePrefix_REX;
3378 else if (Prefix ==
"rex2")
3379 ForcedOpcodePrefix = OpcodePrefix_REX2;
3380 else if (Prefix ==
"vex")
3381 ForcedOpcodePrefix = OpcodePrefix_VEX;
3382 else if (Prefix ==
"vex2")
3383 ForcedOpcodePrefix = OpcodePrefix_VEX2;
3384 else if (Prefix ==
"vex3")
3385 ForcedOpcodePrefix = OpcodePrefix_VEX3;
3386 else if (Prefix ==
"evex")
3387 ForcedOpcodePrefix = OpcodePrefix_EVEX;
3388 else if (Prefix ==
"disp8")
3389 ForcedDispEncoding = DispEncoding_Disp8;
3390 else if (Prefix ==
"disp32")
3391 ForcedDispEncoding = DispEncoding_Disp32;
3392 else if (Prefix ==
"nf")
3393 ForcedNoFlag =
true;
3395 return Error(NameLoc,
"unknown prefix");
3411 if (isParsingMSInlineAsm()) {
3412 if (
Name.equals_insensitive(
"vex"))
3413 ForcedOpcodePrefix = OpcodePrefix_VEX;
3414 else if (
Name.equals_insensitive(
"vex2"))
3415 ForcedOpcodePrefix = OpcodePrefix_VEX2;
3416 else if (
Name.equals_insensitive(
"vex3"))
3417 ForcedOpcodePrefix = OpcodePrefix_VEX3;
3418 else if (
Name.equals_insensitive(
"evex"))
3419 ForcedOpcodePrefix = OpcodePrefix_EVEX;
3421 if (ForcedOpcodePrefix != OpcodePrefix_Default) {
3434 if (
Name.consume_back(
".d32")) {
3435 ForcedDispEncoding = DispEncoding_Disp32;
3436 }
else if (
Name.consume_back(
".d8")) {
3437 ForcedDispEncoding = DispEncoding_Disp8;
3440 StringRef PatchedName =
Name;
3443 if (isParsingIntelSyntax() &&
3444 (PatchedName ==
"jmp" || PatchedName ==
"jc" || PatchedName ==
"jnc" ||
3445 PatchedName ==
"jcxz" || PatchedName ==
"jecxz" ||
3450 : NextTok ==
"short") {
3459 NextTok.
size() + 1);
3465 PatchedName !=
"setzub" && PatchedName !=
"setzunb" &&
3466 PatchedName !=
"setb" && PatchedName !=
"setnb")
3467 PatchedName = PatchedName.
substr(0,
Name.size()-1);
3469 unsigned ComparisonPredicate = ~0
U;
3477 bool IsVCMP = PatchedName[0] ==
'v';
3478 unsigned CCIdx =
IsVCMP ? 4 : 3;
3479 unsigned suffixLength = PatchedName.
ends_with(
"bf16") ? 5 : 2;
3480 unsigned CC = StringSwitch<unsigned>(
3481 PatchedName.
slice(CCIdx, PatchedName.
size() - suffixLength))
3483 .Case(
"eq_oq", 0x00)
3485 .Case(
"lt_os", 0x01)
3487 .Case(
"le_os", 0x02)
3488 .Case(
"unord", 0x03)
3489 .Case(
"unord_q", 0x03)
3491 .Case(
"neq_uq", 0x04)
3493 .Case(
"nlt_us", 0x05)
3495 .Case(
"nle_us", 0x06)
3497 .Case(
"ord_q", 0x07)
3499 .Case(
"eq_uq", 0x08)
3501 .Case(
"nge_us", 0x09)
3503 .Case(
"ngt_us", 0x0A)
3504 .Case(
"false", 0x0B)
3505 .Case(
"false_oq", 0x0B)
3506 .Case(
"neq_oq", 0x0C)
3508 .Case(
"ge_os", 0x0D)
3510 .Case(
"gt_os", 0x0E)
3512 .Case(
"true_uq", 0x0F)
3513 .Case(
"eq_os", 0x10)
3514 .Case(
"lt_oq", 0x11)
3515 .Case(
"le_oq", 0x12)
3516 .Case(
"unord_s", 0x13)
3517 .Case(
"neq_us", 0x14)
3518 .Case(
"nlt_uq", 0x15)
3519 .Case(
"nle_uq", 0x16)
3520 .Case(
"ord_s", 0x17)
3521 .Case(
"eq_us", 0x18)
3522 .Case(
"nge_uq", 0x19)
3523 .Case(
"ngt_uq", 0x1A)
3524 .Case(
"false_os", 0x1B)
3525 .Case(
"neq_os", 0x1C)
3526 .Case(
"ge_oq", 0x1D)
3527 .Case(
"gt_oq", 0x1E)
3528 .Case(
"true_us", 0x1F)
3530 if (CC != ~0U && (
IsVCMP || CC < 8) &&
3533 PatchedName =
IsVCMP ?
"vcmpss" :
"cmpss";
3535 PatchedName =
IsVCMP ?
"vcmpsd" :
"cmpsd";
3537 PatchedName =
IsVCMP ?
"vcmpps" :
"cmpps";
3539 PatchedName =
IsVCMP ?
"vcmppd" :
"cmppd";
3541 PatchedName =
"vcmpsh";
3543 PatchedName =
"vcmpph";
3545 PatchedName =
"vcmpbf16";
3549 ComparisonPredicate = CC;
3555 (PatchedName.
back() ==
'b' || PatchedName.
back() ==
'w' ||
3556 PatchedName.
back() ==
'd' || PatchedName.
back() ==
'q')) {
3557 unsigned SuffixSize = PatchedName.
drop_back().
back() ==
'u' ? 2 : 1;
3558 unsigned CC = StringSwitch<unsigned>(
3559 PatchedName.
slice(5, PatchedName.
size() - SuffixSize))
3569 if (CC != ~0U && (CC != 0 || SuffixSize == 2)) {
3570 switch (PatchedName.
back()) {
3572 case 'b': PatchedName = SuffixSize == 2 ?
"vpcmpub" :
"vpcmpb";
break;
3573 case 'w': PatchedName = SuffixSize == 2 ?
"vpcmpuw" :
"vpcmpw";
break;
3574 case 'd': PatchedName = SuffixSize == 2 ?
"vpcmpud" :
"vpcmpd";
break;
3575 case 'q': PatchedName = SuffixSize == 2 ?
"vpcmpuq" :
"vpcmpq";
break;
3578 ComparisonPredicate = CC;
3584 (PatchedName.
back() ==
'b' || PatchedName.
back() ==
'w' ||
3585 PatchedName.
back() ==
'd' || PatchedName.
back() ==
'q')) {
3586 unsigned SuffixSize = PatchedName.
drop_back().
back() ==
'u' ? 2 : 1;
3587 unsigned CC = StringSwitch<unsigned>(
3588 PatchedName.
slice(5, PatchedName.
size() - SuffixSize))
3599 switch (PatchedName.
back()) {
3601 case 'b': PatchedName = SuffixSize == 2 ?
"vpcomub" :
"vpcomb";
break;
3602 case 'w': PatchedName = SuffixSize == 2 ?
"vpcomuw" :
"vpcomw";
break;
3603 case 'd': PatchedName = SuffixSize == 2 ?
"vpcomud" :
"vpcomd";
break;
3604 case 'q': PatchedName = SuffixSize == 2 ?
"vpcomuq" :
"vpcomq";
break;
3607 ComparisonPredicate = CC;
3619 StringSwitch<bool>(Name)
3620 .Cases({
"cs",
"ds",
"es",
"fs",
"gs",
"ss"},
true)
3621 .Cases({
"rex64",
"data32",
"data16",
"addr32",
"addr16"},
true)
3622 .Cases({
"xacquire",
"xrelease"},
true)
3623 .Cases({
"acquire",
"release"}, isParsingIntelSyntax())
3626 auto isLockRepeatNtPrefix = [](StringRef
N) {
3627 return StringSwitch<bool>(
N)
3628 .Cases({
"lock",
"rep",
"repe",
"repz",
"repne",
"repnz",
"notrack"},
3633 bool CurlyAsEndOfStatement =
false;
3636 while (isLockRepeatNtPrefix(
Name.lower())) {
3638 StringSwitch<unsigned>(Name)
3657 while (
Name.starts_with(
";") ||
Name.starts_with(
"\n") ||
3658 Name.starts_with(
"#") ||
Name.starts_with(
"\t") ||
3659 Name.starts_with(
"/")) {
3670 if (PatchedName ==
"data16" && is16BitMode()) {
3671 return Error(NameLoc,
"redundant data16 prefix");
3673 if (PatchedName ==
"data32") {
3675 return Error(NameLoc,
"redundant data32 prefix");
3677 return Error(NameLoc,
"'data32' is not supported in 64-bit mode");
3679 PatchedName =
"data16";
3686 if (
Next ==
"callw")
3688 if (
Next ==
"ljmpw")
3693 ForcedDataPrefix = X86::Is32Bit;
3701 if (ComparisonPredicate != ~0U && !isParsingIntelSyntax()) {
3708 if ((
Name.starts_with(
"ccmp") ||
Name.starts_with(
"ctest")) &&
3737 CurlyAsEndOfStatement =
3738 isParsingIntelSyntax() && isParsingMSInlineAsm() &&
3741 return TokError(
"unexpected token in argument list");
3745 if (ComparisonPredicate != ~0U && isParsingIntelSyntax()) {
3755 else if (CurlyAsEndOfStatement)
3758 getLexer().getTok().getLoc(), 0);
3765 if (IsFp &&
Operands.size() == 1) {
3766 const char *Repl = StringSwitch<const char *>(Name)
3767 .Case(
"fsub",
"fsubp")
3768 .Case(
"fdiv",
"fdivp")
3769 .Case(
"fsubr",
"fsubrp")
3770 .Case(
"fdivr",
"fdivrp");
3771 static_cast<X86Operand &
>(*
Operands[0]).setTokenValue(Repl);
3774 if ((Name ==
"mov" || Name ==
"movw" || Name ==
"movl") &&
3776 X86Operand &Op1 = (X86Operand &)*
Operands[1];
3777 X86Operand &Op2 = (X86Operand &)*
Operands[2];
3782 getX86MCRegisterClass(X86::SEGMENT_REGRegClassID)
3784 (getX86MCRegisterClass(X86::GR16RegClassID).
contains(Op1.
getReg()) ||
3785 getX86MCRegisterClass(X86::GR32RegClassID).
contains(Op1.
getReg()))) {
3787 if (Name !=
"mov" && Name[3] == (is16BitMode() ?
'l' :
'w')) {
3788 Name = is16BitMode() ?
"movw" :
"movl";
3801 if ((Name ==
"outb" || Name ==
"outsb" || Name ==
"outw" || Name ==
"outsw" ||
3802 Name ==
"outl" || Name ==
"outsl" || Name ==
"out" || Name ==
"outs") &&
3804 X86Operand &
Op = (X86Operand &)*
Operands.back();
3810 if ((Name ==
"inb" || Name ==
"insb" || Name ==
"inw" || Name ==
"insw" ||
3811 Name ==
"inl" || Name ==
"insl" || Name ==
"in" || Name ==
"ins") &&
3820 bool HadVerifyError =
false;
3823 if (
Name.starts_with(
"ins") &&
3825 (Name ==
"insb" || Name ==
"insw" || Name ==
"insl" || Name ==
"insd" ||
3828 AddDefaultSrcDestOperands(TmpOperands,
3830 DefaultMemDIOperand(NameLoc));
3831 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3835 if (
Name.starts_with(
"outs") &&
3837 (Name ==
"outsb" || Name ==
"outsw" || Name ==
"outsl" ||
3838 Name ==
"outsd" || Name ==
"outs")) {
3839 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
3841 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3847 if (
Name.starts_with(
"lods") &&
3849 (Name ==
"lods" || Name ==
"lodsb" || Name ==
"lodsw" ||
3850 Name ==
"lodsl" || Name ==
"lodsd" || Name ==
"lodsq")) {
3851 TmpOperands.
push_back(DefaultMemSIOperand(NameLoc));
3852 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3858 if (
Name.starts_with(
"stos") &&
3860 (Name ==
"stos" || Name ==
"stosb" || Name ==
"stosw" ||
3861 Name ==
"stosl" || Name ==
"stosd" || Name ==
"stosq")) {
3862 TmpOperands.
push_back(DefaultMemDIOperand(NameLoc));
3863 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3869 if (
Name.starts_with(
"scas") &&
3871 (Name ==
"scas" || Name ==
"scasb" || Name ==
"scasw" ||
3872 Name ==
"scasl" || Name ==
"scasd" || Name ==
"scasq")) {
3873 TmpOperands.
push_back(DefaultMemDIOperand(NameLoc));
3874 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3878 if (
Name.starts_with(
"cmps") &&
3880 (Name ==
"cmps" || Name ==
"cmpsb" || Name ==
"cmpsw" ||
3881 Name ==
"cmpsl" || Name ==
"cmpsd" || Name ==
"cmpsq")) {
3882 AddDefaultSrcDestOperands(TmpOperands, DefaultMemDIOperand(NameLoc),
3883 DefaultMemSIOperand(NameLoc));
3884 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3888 if (((
Name.starts_with(
"movs") &&
3889 (Name ==
"movs" || Name ==
"movsb" || Name ==
"movsw" ||
3890 Name ==
"movsl" || Name ==
"movsd" || Name ==
"movsq")) ||
3891 (
Name.starts_with(
"smov") &&
3892 (Name ==
"smov" || Name ==
"smovb" || Name ==
"smovw" ||
3893 Name ==
"smovl" || Name ==
"smovd" || Name ==
"smovq"))) &&
3895 if (Name ==
"movsd" &&
Operands.size() == 1 && !isParsingIntelSyntax())
3897 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
3898 DefaultMemDIOperand(NameLoc));
3899 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3903 if (HadVerifyError) {
3904 return HadVerifyError;
3908 if ((Name ==
"xlat" || Name ==
"xlatb") &&
Operands.size() == 2) {
3909 X86Operand &Op1 =
static_cast<X86Operand &
>(*
Operands[1]);
3912 "size, (R|E)BX will be used for the location");
3914 static_cast<X86Operand &
>(*
Operands[0]).setTokenValue(
"xlatb");
3927 if (
I ==
Table.end() ||
I->OldOpc != Opcode)
3933 if (X86::isBLENDVPD(Opcode) || X86::isBLENDVPS(Opcode) ||
3934 X86::isPBLENDVB(Opcode))
3940bool X86AsmParser::processInstruction(MCInst &Inst,
const OperandVector &
Ops) {
3944 if (ForcedOpcodePrefix != OpcodePrefix_VEX3 &&
3951 auto replaceWithCCMPCTEST = [&](
unsigned Opcode) ->
bool {
3952 if (ForcedOpcodePrefix == OpcodePrefix_EVEX) {
3963 default:
return false;
3968 if (ForcedDispEncoding == DispEncoding_Disp32) {
3969 Inst.
setOpcode(is16BitMode() ? X86::JMP_2 : X86::JMP_4);
3978 if (ForcedDispEncoding == DispEncoding_Disp32) {
3979 Inst.
setOpcode(is16BitMode() ? X86::JCC_2 : X86::JCC_4);
3995#define FROM_TO(FROM, TO) \
3997 return replaceWithCCMPCTEST(X86::TO);
3999 FROM_TO(CMP64mi32, CCMP64mi32)
4002 FROM_TO(CMP64ri32, CCMP64ri32)
4029 FROM_TO(TEST64mi32, CTEST64mi32)
4031 FROM_TO(TEST64ri32, CTEST64ri32)
4051bool X86AsmParser::validateInstruction(MCInst &Inst,
const OperandVector &
Ops) {
4052 using namespace X86;
4053 const MCRegisterInfo *MRI =
getContext().getRegisterInfo();
4055 uint64_t TSFlags = MII.get(Opcode).TSFlags;
4056 if (isVFCMADDCPH(Opcode) || isVFCMADDCSH(Opcode) || isVFMADDCPH(Opcode) ||
4057 isVFMADDCSH(Opcode)) {
4061 return Warning(
Ops[0]->getStartLoc(),
"Destination register should be "
4062 "distinct from source registers");
4063 }
else if (isVFCMULCPH(Opcode) || isVFCMULCSH(Opcode) || isVFMULCPH(Opcode) ||
4064 isVFMULCSH(Opcode)) {
4074 return Warning(
Ops[0]->getStartLoc(),
"Destination register should be "
4075 "distinct from source registers");
4076 }
else if (isV4FMADDPS(Opcode) || isV4FMADDSS(Opcode) ||
4077 isV4FNMADDPS(Opcode) || isV4FNMADDSS(Opcode) ||
4078 isVP4DPWSSDS(Opcode) || isVP4DPWSSD(Opcode)) {
4083 if (Src2Enc % 4 != 0) {
4085 unsigned GroupStart = (Src2Enc / 4) * 4;
4086 unsigned GroupEnd = GroupStart + 3;
4088 "source register '" +
RegName +
"' implicitly denotes '" +
4089 RegName.take_front(3) + Twine(GroupStart) +
"' to '" +
4090 RegName.take_front(3) + Twine(GroupEnd) +
4093 }
else if (isVGATHERDPD(Opcode) || isVGATHERDPS(Opcode) ||
4094 isVGATHERQPD(Opcode) || isVGATHERQPS(Opcode) ||
4095 isVPGATHERDD(Opcode) || isVPGATHERDQ(Opcode) ||
4096 isVPGATHERQD(Opcode) || isVPGATHERQQ(Opcode)) {
4103 return Warning(
Ops[0]->getStartLoc(),
"index and destination registers "
4104 "should be distinct");
4110 if (Dest == Mask || Dest == Index || Mask == Index)
4111 return Warning(
Ops[0]->getStartLoc(),
"mask, index, and destination "
4112 "registers should be distinct");
4114 }
else if (isTCMMIMFP16PS(Opcode) || isTCMMRLFP16PS(Opcode) ||
4115 isTDPBF16PS(Opcode) || isTDPFP16PS(Opcode) || isTDPBSSD(Opcode) ||
4116 isTDPBSUD(Opcode) || isTDPBUSD(Opcode) || isTDPBUUD(Opcode)) {
4120 if (SrcDest == Src1 || SrcDest == Src2 || Src1 == Src2)
4121 return Error(
Ops[0]->getStartLoc(),
"all tmm registers must be distinct");
4135 for (
unsigned i = 0; i !=
NumOps; ++i) {
4140 if (
Reg == X86::AH ||
Reg == X86::BH ||
Reg == X86::CH ||
Reg == X86::DH)
4148 (Enc ==
X86II::EVEX || ForcedOpcodePrefix == OpcodePrefix_REX2 ||
4149 ForcedOpcodePrefix == OpcodePrefix_REX || UsesRex)) {
4151 return Error(
Ops[0]->getStartLoc(),
4152 "can't encode '" +
RegName.str() +
4153 "' in an instruction requiring EVEX/REX2/REX prefix");
4157 if ((Opcode == X86::PREFETCHIT0 || Opcode == X86::PREFETCHIT1)) {
4161 Ops[0]->getStartLoc(),
4162 Twine((Inst.
getOpcode() == X86::PREFETCHIT0 ?
"'prefetchit0'"
4163 :
"'prefetchit1'")) +
4164 " only supports RIP-relative address");
4169void X86AsmParser::emitWarningForSpecialLVIInstruction(SMLoc Loc) {
4170 Warning(Loc,
"Instruction may be vulnerable to LVI and "
4171 "requires manual mitigation");
4172 Note(SMLoc(),
"See https://software.intel.com/"
4173 "security-software-guidance/insights/"
4174 "deep-dive-load-value-injection#specialinstructions"
4175 " for more information");
4187void X86AsmParser::applyLVICFIMitigation(MCInst &Inst, MCStreamer &Out) {
4198 MCInst ShlInst, FenceInst;
4199 bool Parse32 = is32BitMode() || Code16GCC;
4200 MCRegister Basereg =
4201 is64BitMode() ? X86::RSP : (Parse32 ? X86::ESP : X86::SP);
4205 1, SMLoc{}, SMLoc{}, 0);
4207 ShlMemOp->addMemOperands(ShlInst, 5);
4220 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4232void X86AsmParser::applyLVILoadHardeningMitigation(MCInst &Inst,
4249 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4252 }
else if (Opcode == X86::REP_PREFIX || Opcode == X86::REPNE_PREFIX) {
4255 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4259 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
4277 getSTI().
hasFeature(X86::FeatureLVIControlFlowIntegrity))
4278 applyLVICFIMitigation(Inst, Out);
4283 getSTI().
hasFeature(X86::FeatureLVILoadHardening))
4284 applyLVILoadHardeningMitigation(Inst, Out);
4288 unsigned Result = 0;
4290 if (Prefix.isPrefix()) {
4291 Result = Prefix.getPrefix();
4297bool X86AsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
4299 MCStreamer &Out, uint64_t &ErrorInfo,
4300 bool MatchingInlineAsm) {
4302 assert((*
Operands[0]).isToken() &&
"Leading operand should always be a mnemonic!");
4305 MatchFPUWaitAlias(IDLoc,
static_cast<X86Operand &
>(*
Operands[0]),
Operands,
4306 Out, MatchingInlineAsm);
4313 if (ForcedOpcodePrefix == OpcodePrefix_REX)
4315 else if (ForcedOpcodePrefix == OpcodePrefix_REX2)
4317 else if (ForcedOpcodePrefix == OpcodePrefix_VEX)
4319 else if (ForcedOpcodePrefix == OpcodePrefix_VEX2)
4321 else if (ForcedOpcodePrefix == OpcodePrefix_VEX3)
4323 else if (ForcedOpcodePrefix == OpcodePrefix_EVEX)
4327 if (ForcedDispEncoding == DispEncoding_Disp8)
4329 else if (ForcedDispEncoding == DispEncoding_Disp32)
4335 return isParsingIntelSyntax()
4336 ? matchAndEmitIntelInstruction(IDLoc, Opcode, Inst,
Operands, Out,
4337 ErrorInfo, MatchingInlineAsm)
4338 : matchAndEmitATTInstruction(IDLoc, Opcode, Inst,
Operands, Out,
4339 ErrorInfo, MatchingInlineAsm);
4342void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &
Op,
4344 bool MatchingInlineAsm) {
4348 const char *Repl = StringSwitch<const char *>(
Op.getToken())
4349 .Case(
"finit",
"fninit")
4350 .Case(
"fsave",
"fnsave")
4351 .Case(
"fstcw",
"fnstcw")
4352 .Case(
"fstcww",
"fnstcw")
4353 .Case(
"fstenv",
"fnstenv")
4354 .Case(
"fstsw",
"fnstsw")
4355 .Case(
"fstsww",
"fnstsw")
4356 .Case(
"fclex",
"fnclex")
4362 if (!MatchingInlineAsm)
4368bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc,
4369 const FeatureBitset &MissingFeatures,
4370 bool MatchingInlineAsm) {
4371 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
4372 SmallString<126>
Msg;
4373 raw_svector_ostream OS(
Msg);
4374 OS <<
"instruction requires:";
4375 for (
unsigned Feature : MissingFeatures)
4377 return Error(IDLoc, OS.str(), SMRange(), MatchingInlineAsm);
4380unsigned X86AsmParser::checkTargetMatchPredicate(MCInst &Inst) {
4382 const MCInstrDesc &MCID = MII.get(
Opc);
4383 uint64_t TSFlags = MCID.
TSFlags;
4386 return Match_Unsupported;
4388 return Match_Unsupported;
4390 switch (ForcedOpcodePrefix) {
4391 case OpcodePrefix_Default:
4393 case OpcodePrefix_REX:
4394 case OpcodePrefix_REX2:
4396 return Match_Unsupported;
4398 case OpcodePrefix_VEX:
4399 case OpcodePrefix_VEX2:
4400 case OpcodePrefix_VEX3:
4402 return Match_Unsupported;
4404 case OpcodePrefix_EVEX:
4406 !X86::isCMP(
Opc) && !X86::isTEST(
Opc))
4407 return Match_Unsupported;
4409 return Match_Unsupported;
4414 (ForcedOpcodePrefix != OpcodePrefix_VEX &&
4415 ForcedOpcodePrefix != OpcodePrefix_VEX2 &&
4416 ForcedOpcodePrefix != OpcodePrefix_VEX3))
4417 return Match_Unsupported;
4419 return Match_Success;
4422bool X86AsmParser::matchAndEmitATTInstruction(
4424 MCStreamer &Out, uint64_t &ErrorInfo,
bool MatchingInlineAsm) {
4425 X86Operand &
Op =
static_cast<X86Operand &
>(*
Operands[0]);
4429 if (ForcedDataPrefix == X86::Is32Bit)
4430 SwitchMode(X86::Is32Bit);
4432 FeatureBitset MissingFeatures;
4433 unsigned OriginalError = MatchInstruction(
Operands, Inst, ErrorInfo,
4434 MissingFeatures, MatchingInlineAsm,
4435 isParsingIntelSyntax());
4436 if (ForcedDataPrefix == X86::Is32Bit) {
4437 SwitchMode(X86::Is16Bit);
4438 ForcedDataPrefix = 0;
4440 switch (OriginalError) {
4443 if (!MatchingInlineAsm && validateInstruction(Inst,
Operands))
4448 if (!MatchingInlineAsm)
4449 while (processInstruction(Inst,
Operands))
4453 if (!MatchingInlineAsm)
4457 case Match_InvalidImmUnsignedi4: {
4458 SMLoc ErrorLoc = ((X86Operand &)*
Operands[ErrorInfo]).getStartLoc();
4459 if (ErrorLoc == SMLoc())
4461 return Error(ErrorLoc,
"immediate must be an integer in range [0, 15]",
4462 EmptyRange, MatchingInlineAsm);
4464 case Match_InvalidImmUnsignedi6: {
4465 SMLoc ErrorLoc = ((X86Operand &)*
Operands[ErrorInfo]).getStartLoc();
4466 if (ErrorLoc == SMLoc())
4468 return Error(ErrorLoc,
"immediate must be an integer in range [0, 63]",
4469 EmptyRange, MatchingInlineAsm);
4471 case Match_MissingFeature:
4472 return ErrorMissingFeature(IDLoc, MissingFeatures, MatchingInlineAsm);
4473 case Match_InvalidOperand:
4474 case Match_MnemonicFail:
4475 case Match_Unsupported:
4478 if (
Op.getToken().empty()) {
4479 Error(IDLoc,
"instruction must have size higher than 0", EmptyRange,
4490 StringRef
Base =
Op.getToken();
4491 SmallString<16> Tmp;
4494 Op.setTokenValue(Tmp);
4502 const char *Suffixes =
Base[0] !=
'f' ?
"bwlq" :
"slt\0";
4504 const char *MemSize =
Base[0] !=
'f' ?
"\x08\x10\x20\x40" :
"\x20\x40\x50\0";
4507 uint64_t ErrorInfoIgnore;
4508 FeatureBitset ErrorInfoMissingFeatures;
4516 bool HasVectorReg =
false;
4517 X86Operand *MemOp =
nullptr;
4519 X86Operand *X86Op =
static_cast<X86Operand *
>(
Op.get());
4521 HasVectorReg =
true;
4522 else if (X86Op->
isMem()) {
4524 assert(MemOp->Mem.Size == 0 &&
"Memory size always 0 under ATT syntax");
4531 for (
unsigned I = 0,
E = std::size(Match);
I !=
E; ++
I) {
4532 Tmp.
back() = Suffixes[
I];
4533 if (MemOp && HasVectorReg)
4534 MemOp->Mem.Size = MemSize[
I];
4535 Match[
I] = Match_MnemonicFail;
4536 if (MemOp || !HasVectorReg) {
4538 MatchInstruction(
Operands, Inst, ErrorInfoIgnore, MissingFeatures,
4539 MatchingInlineAsm, isParsingIntelSyntax());
4541 if (Match[
I] == Match_MissingFeature)
4542 ErrorInfoMissingFeatures = MissingFeatures;
4552 unsigned NumSuccessfulMatches =
llvm::count(Match, Match_Success);
4553 if (NumSuccessfulMatches == 1) {
4554 if (!MatchingInlineAsm && validateInstruction(Inst,
Operands))
4559 if (!MatchingInlineAsm)
4560 while (processInstruction(Inst,
Operands))
4564 if (!MatchingInlineAsm)
4574 if (NumSuccessfulMatches > 1) {
4576 unsigned NumMatches = 0;
4577 for (
unsigned I = 0,
E = std::size(Match);
I !=
E; ++
I)
4578 if (Match[
I] == Match_Success)
4579 MatchChars[NumMatches++] = Suffixes[
I];
4581 SmallString<126>
Msg;
4582 raw_svector_ostream OS(
Msg);
4583 OS <<
"ambiguous instructions require an explicit suffix (could be ";
4584 for (
unsigned i = 0; i != NumMatches; ++i) {
4587 if (i + 1 == NumMatches)
4589 OS <<
"'" <<
Base << MatchChars[i] <<
"'";
4592 Error(IDLoc, OS.str(), EmptyRange, MatchingInlineAsm);
4600 if (
llvm::count(Match, Match_MnemonicFail) == 4) {
4601 if (OriginalError == Match_MnemonicFail)
4602 return Error(IDLoc,
"invalid instruction mnemonic '" +
Base +
"'",
4603 Op.getLocRange(), MatchingInlineAsm);
4605 if (OriginalError == Match_Unsupported)
4606 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4609 assert(OriginalError == Match_InvalidOperand &&
"Unexpected error");
4611 if (ErrorInfo != ~0ULL) {
4613 return Error(IDLoc,
"too few operands for instruction", EmptyRange,
4616 X86Operand &Operand = (X86Operand &)*
Operands[ErrorInfo];
4620 OperandRange, MatchingInlineAsm);
4624 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4630 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4636 if (
llvm::count(Match, Match_MissingFeature) == 1) {
4637 ErrorInfo = Match_MissingFeature;
4638 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
4644 if (
llvm::count(Match, Match_InvalidOperand) == 1) {
4645 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4650 Error(IDLoc,
"unknown use of instruction mnemonic without a size suffix",
4651 EmptyRange, MatchingInlineAsm);
4655bool X86AsmParser::matchAndEmitIntelInstruction(
4657 MCStreamer &Out, uint64_t &ErrorInfo,
bool MatchingInlineAsm) {
4658 X86Operand &
Op =
static_cast<X86Operand &
>(*
Operands[0]);
4663 const bool ForcedData32 = ForcedDataPrefix == X86::Is32Bit;
4664 auto RestoreMode = [&] {
4666 SwitchMode(X86::Is16Bit);
4667 ForcedDataPrefix = 0;
4671 SwitchMode(X86::Is32Bit);
4673 X86Operand *UnsizedMemOp =
nullptr;
4675 X86Operand *X86Op =
static_cast<X86Operand *
>(
Op.get());
4677 UnsizedMemOp = X86Op;
4688 static const char *
const PtrSizedInstrs[] = {
"call",
"jmp",
"push",
"pop"};
4689 for (
const char *Instr : PtrSizedInstrs) {
4690 if (Mnemonic == Instr) {
4691 UnsizedMemOp->
Mem.
Size = getPointerWidth();
4697 SmallVector<unsigned, 8> Match;
4698 FeatureBitset ErrorInfoMissingFeatures;
4699 FeatureBitset MissingFeatures;
4704 if (Mnemonic ==
"push" &&
Operands.size() == 2) {
4705 auto *X86Op =
static_cast<X86Operand *
>(
Operands[1].get());
4706 if (X86Op->
isImm()) {
4709 unsigned Size = getPointerWidth();
4712 SmallString<16> Tmp;
4714 Tmp += (is64BitMode())
4716 : (is32BitMode()) ?
"l" : (is16BitMode()) ?
"w" :
" ";
4717 Op.setTokenValue(Tmp);
4720 MissingFeatures, MatchingInlineAsm,
4731 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
4732 for (
unsigned Size : MopSizes) {
4734 uint64_t ErrorInfoIgnore;
4736 unsigned M = MatchInstruction(
Operands, Inst, ErrorInfoIgnore,
4737 MissingFeatures, MatchingInlineAsm,
4738 isParsingIntelSyntax());
4743 if (Match.
back() == Match_MissingFeature)
4744 ErrorInfoMissingFeatures = MissingFeatures;
4754 if (Match.
empty()) {
4756 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,
4757 isParsingIntelSyntax()));
4759 if (Match.
back() == Match_MissingFeature)
4760 ErrorInfoMissingFeatures = MissingFeatures;
4768 if (Match.
back() == Match_MnemonicFail) {
4770 return Error(IDLoc,
"invalid instruction mnemonic '" + Mnemonic +
"'",
4771 Op.getLocRange(), MatchingInlineAsm);
4774 unsigned NumSuccessfulMatches =
llvm::count(Match, Match_Success);
4778 if (UnsizedMemOp && NumSuccessfulMatches > 1 &&
4781 unsigned M = MatchInstruction(
4782 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,
4783 isParsingIntelSyntax());
4784 if (M == Match_Success)
4785 NumSuccessfulMatches = 1;
4800 if (NumSuccessfulMatches == 1) {
4801 if (!MatchingInlineAsm && validateInstruction(Inst,
Operands))
4806 if (!MatchingInlineAsm)
4807 while (processInstruction(Inst,
Operands))
4810 if (!MatchingInlineAsm)
4814 }
else if (NumSuccessfulMatches > 1) {
4816 "multiple matches only possible with unsized memory operands");
4818 "ambiguous operand size for instruction '" + Mnemonic +
"\'",
4824 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4830 if (
llvm::count(Match, Match_MissingFeature) == 1) {
4831 ErrorInfo = Match_MissingFeature;
4832 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
4838 if (
llvm::count(Match, Match_InvalidOperand) == 1) {
4839 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4843 if (
llvm::count(Match, Match_InvalidImmUnsignedi4) == 1) {
4844 SMLoc ErrorLoc = ((X86Operand &)*
Operands[ErrorInfo]).getStartLoc();
4845 if (ErrorLoc == SMLoc())
4847 return Error(ErrorLoc,
"immediate must be an integer in range [0, 15]",
4848 EmptyRange, MatchingInlineAsm);
4851 if (
llvm::count(Match, Match_InvalidImmUnsignedi6) == 1) {
4852 SMLoc ErrorLoc = ((X86Operand &)*
Operands[ErrorInfo]).getStartLoc();
4853 if (ErrorLoc == SMLoc())
4855 return Error(ErrorLoc,
"immediate must be an integer in range [0, 63]",
4856 EmptyRange, MatchingInlineAsm);
4860 return Error(IDLoc,
"unknown instruction mnemonic", EmptyRange,
4864bool X86AsmParser::omitRegisterFromClobberLists(MCRegister
Reg) {
4865 return getX86MCRegisterClass(X86::SEGMENT_REGRegClassID).contains(
Reg);
4868bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
4869 MCAsmParser &Parser = getParser();
4872 return parseDirectiveArch();
4874 return ParseDirectiveCode(IDVal, DirectiveID.
getLoc());
4880 return Error(DirectiveID.
getLoc(),
"'.att_syntax noprefix' is not "
4881 "supported: registers must have a "
4882 "'%' prefix in .att_syntax");
4884 getParser().setAssemblerDialect(0);
4887 getParser().setAssemblerDialect(1);
4892 return Error(DirectiveID.
getLoc(),
"'.intel_syntax prefix' is not "
4893 "supported: registers must not have "
4894 "a '%' prefix in .intel_syntax");
4897 }
else if (IDVal ==
".nops")
4898 return parseDirectiveNops(DirectiveID.
getLoc());
4899 else if (IDVal ==
".even")
4900 return parseDirectiveEven(DirectiveID.
getLoc());
4901 else if (IDVal ==
".cv_fpo_proc")
4902 return parseDirectiveFPOProc(DirectiveID.
getLoc());
4903 else if (IDVal ==
".cv_fpo_setframe")
4904 return parseDirectiveFPOSetFrame(DirectiveID.
getLoc());
4905 else if (IDVal ==
".cv_fpo_pushreg")
4906 return parseDirectiveFPOPushReg(DirectiveID.
getLoc());
4907 else if (IDVal ==
".cv_fpo_stackalloc")
4908 return parseDirectiveFPOStackAlloc(DirectiveID.
getLoc());
4909 else if (IDVal ==
".cv_fpo_stackalign")
4910 return parseDirectiveFPOStackAlign(DirectiveID.
getLoc());
4911 else if (IDVal ==
".cv_fpo_endprologue")
4912 return parseDirectiveFPOEndPrologue(DirectiveID.
getLoc());
4913 else if (IDVal ==
".cv_fpo_endproc")
4914 return parseDirectiveFPOEndProc(DirectiveID.
getLoc());
4915 else if (IDVal ==
".seh_pushreg")
4916 return parseDirectiveSEHPushReg(DirectiveID.
getLoc());
4917 else if (IDVal ==
".seh_push2regs")
4918 return parseDirectiveSEHPush2Regs(DirectiveID.
getLoc());
4919 else if (IDVal ==
".seh_setframe")
4920 return parseDirectiveSEHSetFrame(DirectiveID.
getLoc());
4921 else if (IDVal ==
".seh_savereg")
4922 return parseDirectiveSEHSaveReg(DirectiveID.
getLoc());
4923 else if (IDVal ==
".seh_savexmm")
4924 return parseDirectiveSEHSaveXMM(DirectiveID.
getLoc());
4925 else if (IDVal ==
".seh_pushframe")
4926 return parseDirectiveSEHPushFrame(DirectiveID.
getLoc());
4930 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
4931 parseDirectiveSEHPushReg(DirectiveID.
getLoc());
4933 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
4934 parseDirectiveSEHPush2Regs(DirectiveID.
getLoc());
4936 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
4937 parseDirectiveSEHSetFrame(DirectiveID.
getLoc());
4939 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
4940 parseDirectiveSEHSaveReg(DirectiveID.
getLoc());
4942 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
4943 parseDirectiveSEHSaveXMM(DirectiveID.
getLoc());
4945 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
4946 parseDirectiveSEHPushFrame(DirectiveID.
getLoc());
4950 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
4951 parseDirectiveSEHPushReg(DirectiveID.
getLoc());
4955 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
4956 parseDirectiveSEHPush2Regs(DirectiveID.
getLoc(),
4959 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
4960 parseDirectiveSEHSetFrame(DirectiveID.
getLoc());
4962 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
4963 parseDirectiveSEHSaveReg(DirectiveID.
getLoc());
4965 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
4966 parseDirectiveSEHSaveXMM(DirectiveID.
getLoc());
4973bool X86AsmParser::parseDirectiveArch() {
4975 getParser().parseStringToEndOfStatement();
4981bool X86AsmParser::parseDirectiveNops(SMLoc L) {
4982 int64_t NumBytes = 0, Control = 0;
4983 SMLoc NumBytesLoc, ControlLoc;
4984 const MCSubtargetInfo& STI = getSTI();
4985 NumBytesLoc = getTok().getLoc();
4986 if (getParser().checkForValidSection() ||
4987 getParser().parseAbsoluteExpression(NumBytes))
4991 ControlLoc = getTok().getLoc();
4992 if (getParser().parseAbsoluteExpression(Control))
4995 if (getParser().parseEOL())
4998 if (NumBytes <= 0) {
4999 Error(NumBytesLoc,
"'.nops' directive with non-positive size");
5004 Error(ControlLoc,
"'.nops' directive with negative NOP size");
5009 getParser().getStreamer().emitNops(NumBytes, Control, L, STI);
5016bool X86AsmParser::parseDirectiveEven(SMLoc L) {
5020 const MCSection *
Section = getStreamer().getCurrentSectionOnly();
5022 getStreamer().initSections(getSTI());
5023 Section = getStreamer().getCurrentSectionOnly();
5025 if (
getContext().getAsmInfo().useCodeAlign(*Section))
5026 getStreamer().emitCodeAlignment(
Align(2), getSTI(), 0);
5028 getStreamer().emitValueToAlignment(
Align(2), 0, 1, 0);
5034bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
5035 MCAsmParser &Parser = getParser();
5037 if (IDVal ==
".code16") {
5039 if (!is16BitMode()) {
5040 SwitchMode(X86::Is16Bit);
5041 getTargetStreamer().emitCode16();
5043 }
else if (IDVal ==
".code16gcc") {
5047 if (!is16BitMode()) {
5048 SwitchMode(X86::Is16Bit);
5049 getTargetStreamer().emitCode16();
5051 }
else if (IDVal ==
".code32") {
5053 if (!is32BitMode()) {
5054 SwitchMode(X86::Is32Bit);
5055 getTargetStreamer().emitCode32();
5057 }
else if (IDVal ==
".code64") {
5059 if (!is64BitMode()) {
5060 SwitchMode(X86::Is64Bit);
5061 getTargetStreamer().emitCode64();
5064 Error(L,
"unknown directive " + IDVal);
5072bool X86AsmParser::parseDirectiveFPOProc(SMLoc L) {
5073 MCAsmParser &Parser = getParser();
5077 return Parser.
TokError(
"expected symbol name");
5078 if (Parser.
parseIntToken(ParamsSize,
"expected parameter byte count"))
5081 return Parser.
TokError(
"parameters size out of range");
5085 return getTargetStreamer().emitFPOProc(ProcSym, ParamsSize, L);
5089bool X86AsmParser::parseDirectiveFPOSetFrame(SMLoc L) {
5092 if (parseRegister(
Reg, DummyLoc, DummyLoc) || parseEOL())
5094 return getTargetStreamer().emitFPOSetFrame(
Reg, L);
5098bool X86AsmParser::parseDirectiveFPOPushReg(SMLoc L) {
5101 if (parseRegister(
Reg, DummyLoc, DummyLoc) || parseEOL())
5103 return getTargetStreamer().emitFPOPushReg(
Reg, L);
5107bool X86AsmParser::parseDirectiveFPOStackAlloc(SMLoc L) {
5108 MCAsmParser &Parser = getParser();
5112 return getTargetStreamer().emitFPOStackAlloc(
Offset, L);
5116bool X86AsmParser::parseDirectiveFPOStackAlign(SMLoc L) {
5117 MCAsmParser &Parser = getParser();
5121 return getTargetStreamer().emitFPOStackAlign(
Offset, L);
5125bool X86AsmParser::parseDirectiveFPOEndPrologue(SMLoc L) {
5126 MCAsmParser &Parser = getParser();
5129 return getTargetStreamer().emitFPOEndPrologue(L);
5133bool X86AsmParser::parseDirectiveFPOEndProc(SMLoc L) {
5134 MCAsmParser &Parser = getParser();
5137 return getTargetStreamer().emitFPOEndProc(L);
5140bool X86AsmParser::parseSEHRegisterNumber(
unsigned RegClassID,
5141 MCRegister &RegNo) {
5142 SMLoc startLoc = getLexer().getLoc();
5143 const MCRegisterInfo *MRI =
getContext().getRegisterInfo();
5148 if (parseRegister(RegNo, startLoc, endLoc))
5151 if (!getX86MCRegisterClass(RegClassID).
contains(RegNo)) {
5152 return Error(startLoc,
5153 "register is not supported for use with this directive");
5159 if (getParser().parseAbsoluteExpression(EncodedReg))
5164 RegNo = MCRegister();
5165 for (
MCPhysReg Reg : getX86MCRegisterClass(RegClassID)) {
5172 return Error(startLoc,
5173 "incorrect register number for use with this directive");
5180bool X86AsmParser::parseDirectiveSEHPushReg(SMLoc Loc) {
5182 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5186 return TokError(
"expected end of directive");
5189 getStreamer().emitWinCFIPushReg(
Reg, Loc);
5193bool X86AsmParser::parseDirectiveSEHPush2Regs(SMLoc Loc,
bool SwapRegs) {
5195 if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg1))
5199 return TokError(
"expected comma between registers");
5203 if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg2))
5207 return TokError(
"expected end of directive");
5213 getStreamer().emitWinCFIPush2Regs(Reg1, Reg2, Loc);
5217bool X86AsmParser::parseDirectiveSEHSetFrame(SMLoc Loc) {
5220 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5223 return TokError(
"you must specify a stack pointer offset");
5226 if (getParser().parseAbsoluteExpression(Off))
5230 return TokError(
"expected end of directive");
5233 getStreamer().emitWinCFISetFrame(
Reg, Off, Loc);
5237bool X86AsmParser::parseDirectiveSEHSaveReg(SMLoc Loc) {
5240 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5243 return TokError(
"you must specify an offset on the stack");
5246 if (getParser().parseAbsoluteExpression(Off))
5250 return TokError(
"expected end of directive");
5253 getStreamer().emitWinCFISaveReg(
Reg, Off, Loc);
5257bool X86AsmParser::parseDirectiveSEHSaveXMM(SMLoc Loc) {
5260 if (parseSEHRegisterNumber(X86::VR128XRegClassID,
Reg))
5263 return TokError(
"you must specify an offset on the stack");
5266 if (getParser().parseAbsoluteExpression(Off))
5270 return TokError(
"expected end of directive");
5273 getStreamer().emitWinCFISaveXMM(
Reg, Off, Loc);
5277bool X86AsmParser::ensureMasmPrologContext(SMLoc Loc) {
5278 if (getStreamer().isWinCFIPrologEnded()) {
5279 return Error(Loc,
"prolog directive must be used inside a prolog");
5284bool X86AsmParser::ensureMasmEpilogContext(SMLoc Loc) {
5285 if (!getStreamer().isInEpilogCFI()) {
5286 return Error(Loc,
"epilog directive must be used inside an epilog");
5291bool X86AsmParser::parseDirectiveSEHPushFrame(SMLoc Loc) {
5295 SMLoc startLoc = getLexer().getLoc();
5297 if (!getParser().parseIdentifier(CodeID)) {
5298 if (CodeID !=
"code")
5299 return Error(startLoc,
"expected @code");
5302 }
else if (getParser().isParsingMasm() &&
5304 getTok().getString().equals_insensitive(
"code")) {
5310 return TokError(
"expected end of directive");
5313 getStreamer().emitWinCFIPushFrame(Code, Loc);
5323#define GET_MATCHER_IMPLEMENTATION
5324#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)
static constexpr Value * getValue(Ty &ValueOrUse)
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static bool hasFeature(StringRef Feature, const FeatureBitset &FeatureBits, ArrayRef< SubtargetFeatureKV > ProcFeatures)
static bool IsVCMP(unsigned Opcode)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
OptimizedStructLayoutField Field
static StringRef getName(Value *V)
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
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.
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.
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.
static constexpr unsigned NoRegister
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)
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
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
Get the string size.
constexpr const char * data() const
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.
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
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...
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.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
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