52 "x86-experimental-lvi-inline-asm-hardening",
53 cl::desc(
"Harden inline assembly code that may be vulnerable to Load Value"
54 " Injection (LVI). This feature is experimental."),
cl::Hidden);
57 if (Scale != 1 && Scale != 2 && Scale != 4 && Scale != 8) {
58 ErrMsg =
"scale factor in address must be 1, 2, 4 or 8";
67#define GET_X86_SSE2AVX_TABLE
68#include "X86GenInstrMapping.inc"
70static const char OpPrecedence[] = {
96 ParseInstructionInfo *InstInfo;
98 unsigned ForcedDataPrefix = 0;
101 OpcodePrefix_Default,
110 OpcodePrefix ForcedOpcodePrefix = OpcodePrefix_Default;
113 DispEncoding_Default,
118 DispEncoding ForcedDispEncoding = DispEncoding_Default;
121 bool UseApxExtendedReg =
false;
123 bool ForcedNoFlag =
false;
126 SMLoc consumeToken() {
127 MCAsmParser &Parser = getParser();
137 X86TargetStreamer &getTargetStreamer() {
138 assert(getParser().getStreamer().getTargetStreamer() &&
139 "do not have a target streamer");
140 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
141 return static_cast<X86TargetStreamer &
>(TS);
145 uint64_t &ErrorInfo, FeatureBitset &MissingFeatures,
146 bool matchingInlineAsm,
unsigned VariantID = 0) {
149 SwitchMode(X86::Is32Bit);
150 unsigned rv = MatchInstructionImpl(
Operands, Inst, ErrorInfo,
151 MissingFeatures, matchingInlineAsm,
154 SwitchMode(X86::Is16Bit);
158 enum InfixCalculatorTok {
183 enum IntelOperatorKind {
190 enum MasmOperatorKind {
197 class InfixCalculator {
198 typedef std::pair< InfixCalculatorTok, int64_t > ICToken;
202 bool isUnaryOperator(InfixCalculatorTok
Op)
const {
203 return Op == IC_NEG ||
Op == IC_NOT;
207 int64_t popOperand() {
208 assert (!PostfixStack.empty() &&
"Poped an empty stack!");
209 ICToken
Op = PostfixStack.pop_back_val();
210 if (!(
Op.first == IC_IMM ||
Op.first == IC_REGISTER))
214 void pushOperand(InfixCalculatorTok
Op, int64_t Val = 0) {
215 assert ((
Op == IC_IMM ||
Op == IC_REGISTER) &&
216 "Unexpected operand!");
217 PostfixStack.push_back(std::make_pair(
Op, Val));
220 void popOperator() { InfixOperatorStack.pop_back(); }
221 void pushOperator(InfixCalculatorTok
Op) {
223 if (InfixOperatorStack.empty()) {
224 InfixOperatorStack.push_back(
Op);
231 unsigned Idx = InfixOperatorStack.size() - 1;
232 InfixCalculatorTok StackOp = InfixOperatorStack[Idx];
233 if (OpPrecedence[
Op] > OpPrecedence[StackOp] || StackOp == IC_LPAREN) {
234 InfixOperatorStack.push_back(
Op);
240 unsigned ParenCount = 0;
243 if (InfixOperatorStack.empty())
246 Idx = InfixOperatorStack.size() - 1;
247 StackOp = InfixOperatorStack[Idx];
248 if (!(OpPrecedence[StackOp] >= OpPrecedence[
Op] || ParenCount))
253 if (!ParenCount && StackOp == IC_LPAREN)
256 if (StackOp == IC_RPAREN) {
258 InfixOperatorStack.pop_back();
259 }
else if (StackOp == IC_LPAREN) {
261 InfixOperatorStack.pop_back();
263 InfixOperatorStack.pop_back();
264 PostfixStack.push_back(std::make_pair(StackOp, 0));
268 InfixOperatorStack.push_back(
Op);
273 while (!InfixOperatorStack.empty()) {
274 InfixCalculatorTok StackOp = InfixOperatorStack.pop_back_val();
275 if (StackOp != IC_LPAREN && StackOp != IC_RPAREN)
276 PostfixStack.push_back(std::make_pair(StackOp, 0));
279 if (PostfixStack.empty())
283 for (
const ICToken &
Op : PostfixStack) {
284 if (
Op.first == IC_IMM ||
Op.first == IC_REGISTER) {
286 }
else if (isUnaryOperator(
Op.first)) {
287 assert (OperandStack.
size() > 0 &&
"Too few operands.");
289 assert (Operand.first == IC_IMM &&
290 "Unary operation with a register!");
296 OperandStack.
push_back(std::make_pair(IC_IMM, -Operand.second));
299 OperandStack.
push_back(std::make_pair(IC_IMM, ~Operand.second));
303 assert (OperandStack.
size() > 1 &&
"Too few operands.");
312 Val = Op1.second + Op2.second;
313 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
316 Val = Op1.second - Op2.second;
317 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
320 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
321 "Multiply operation with an immediate and a register!");
322 Val = Op1.second * Op2.second;
323 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
326 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
327 "Divide operation with an immediate and a register!");
328 assert (Op2.second != 0 &&
"Division by zero!");
329 Val = Op1.second / Op2.second;
330 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
333 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
334 "Modulo operation with an immediate and a register!");
335 Val = Op1.second % Op2.second;
336 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
339 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
340 "Or operation with an immediate and a register!");
341 Val = Op1.second | Op2.second;
342 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
345 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
346 "Xor operation with an immediate and a register!");
347 Val = Op1.second ^ Op2.second;
348 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
351 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
352 "And operation with an immediate and a register!");
353 Val = Op1.second & Op2.second;
354 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
357 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
358 "Left shift operation with an immediate and a register!");
359 Val = Op1.second << Op2.second;
360 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
363 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
364 "Right shift operation with an immediate and a register!");
365 Val = Op1.second >> Op2.second;
366 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
369 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
370 "Equals operation with an immediate and a register!");
371 Val = (Op1.second == Op2.second) ? -1 : 0;
372 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
375 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
376 "Not-equals operation with an immediate and a register!");
377 Val = (Op1.second != Op2.second) ? -1 : 0;
378 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
381 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
382 "Less-than operation with an immediate and a register!");
383 Val = (Op1.second < Op2.second) ? -1 : 0;
384 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
387 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
388 "Less-than-or-equal operation with an immediate and a "
390 Val = (Op1.second <= Op2.second) ? -1 : 0;
391 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
394 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
395 "Greater-than operation with an immediate and a register!");
396 Val = (Op1.second > Op2.second) ? -1 : 0;
397 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
400 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
401 "Greater-than-or-equal operation with an immediate and a "
403 Val = (Op1.second >= Op2.second) ? -1 : 0;
404 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
409 assert (OperandStack.
size() == 1 &&
"Expected a single result.");
414 enum IntelExprState {
444 class IntelExprStateMachine {
445 IntelExprState State = IES_INIT, PrevState = IES_ERROR;
446 MCRegister BaseReg, IndexReg, TmpReg;
448 std::optional<unsigned> TmpScale = {};
450 const MCExpr *Sym =
nullptr;
453 InlineAsmIdentifierInfo Info;
455 short ParenCount = 0;
457 bool MemExpr =
false;
458 bool BracketUsed =
false;
459 bool NegativeAdditiveTerm =
false;
460 SMLoc NegativeAdditiveTermLoc;
461 bool OffsetOperator =
false;
462 bool AttachToOperandIdx =
false;
466 bool setSymRef(
const MCExpr *Val, StringRef ID, StringRef &ErrMsg) {
468 ErrMsg =
"cannot use more than one symbol in memory operand";
477 IntelExprStateMachine() =
default;
479 void addImm(int64_t imm) { Imm += imm; }
480 short getBracCount()
const {
return BracCount; }
481 bool isMemExpr()
const {
return MemExpr; }
482 bool isBracketUsed()
const {
return BracketUsed; }
483 bool isOffsetOperator()
const {
return OffsetOperator; }
484 MCRegister getBaseReg()
const {
return BaseReg; }
485 MCRegister getIndexReg()
const {
return IndexReg; }
486 unsigned getScale()
const {
return Scale; }
487 const MCExpr *
getSym()
const {
return Sym; }
488 StringRef getSymName()
const {
return SymName; }
489 StringRef
getType()
const {
return CurType.Name; }
490 unsigned getSize()
const {
return CurType.Size; }
491 unsigned getElementSize()
const {
return CurType.ElementSize; }
492 unsigned getLength()
const {
return CurType.Length; }
493 int64_t
getImm() {
return Imm + IC.execute(); }
494 bool isValidEndState()
const {
495 return State == IES_RBRAC || State == IES_RPAREN ||
496 State == IES_INTEGER || State == IES_REGISTER ||
499 bool hasUnmatchedParen()
const {
return ParenCount != 0; }
500 SMLoc getLParenLoc()
const {
return LParenLoc; }
506 void setAppendAfterOperand() { AttachToOperandIdx =
true; }
508 bool isPIC()
const {
return IsPIC; }
509 void setPIC() { IsPIC =
true; }
511 bool hadError()
const {
return State == IES_ERROR; }
512 SMLoc getErrorLoc(SMLoc DefaultLoc)
const {
513 return NegativeAdditiveTerm ? NegativeAdditiveTermLoc : DefaultLoc;
515 const InlineAsmIdentifierInfo &getIdentifierInfo()
const {
return Info; }
517 bool regsUseUpError(StringRef &ErrMsg) {
520 if (IsPIC && AttachToOperandIdx)
521 ErrMsg =
"Don't use 2 or more regs for mem offset in PIC model!";
523 ErrMsg =
"BaseReg/IndexReg already set!";
528 IntelExprState CurrState = State;
537 IC.pushOperator(IC_OR);
540 PrevState = CurrState;
543 IntelExprState CurrState = State;
552 IC.pushOperator(IC_XOR);
555 PrevState = CurrState;
558 IntelExprState CurrState = State;
567 IC.pushOperator(IC_AND);
570 PrevState = CurrState;
573 IntelExprState CurrState = State;
582 IC.pushOperator(IC_EQ);
585 PrevState = CurrState;
588 IntelExprState CurrState = State;
597 IC.pushOperator(IC_NE);
600 PrevState = CurrState;
603 IntelExprState CurrState = State;
612 IC.pushOperator(IC_LT);
615 PrevState = CurrState;
618 IntelExprState CurrState = State;
627 IC.pushOperator(IC_LE);
630 PrevState = CurrState;
633 IntelExprState CurrState = State;
642 IC.pushOperator(IC_GT);
645 PrevState = CurrState;
648 IntelExprState CurrState = State;
657 IC.pushOperator(IC_GE);
660 PrevState = CurrState;
663 IntelExprState CurrState = State;
672 IC.pushOperator(IC_LSHIFT);
675 PrevState = CurrState;
678 IntelExprState CurrState = State;
687 IC.pushOperator(IC_RSHIFT);
690 PrevState = CurrState;
692 bool onPlus(StringRef &ErrMsg) {
693 IntelExprState CurrState = State;
703 IC.pushOperator(IC_PLUS);
707 if (!BaseReg && !TmpScale.has_value()) {
712 return regsUseUpError(ErrMsg);
715 if (NegativeAdditiveTerm) {
716 ErrMsg =
"Scale can't be negative";
719 if (TmpScale.has_value() &&
checkScale(TmpScale.value(), ErrMsg)) {
722 Scale = TmpScale.value_or(0);
727 NegativeAdditiveTerm =
false;
728 NegativeAdditiveTermLoc = SMLoc();
731 PrevState = CurrState;
734 bool onMinus(SMLoc MinusLoc, StringRef &ErrMsg) {
735 IntelExprState CurrState = State;
765 NegativeAdditiveTerm =
true;
766 NegativeAdditiveTermLoc = MinusLoc;
768 if (CurrState == IES_REGISTER || CurrState == IES_RPAREN ||
769 CurrState == IES_INTEGER || CurrState == IES_RBRAC ||
770 CurrState == IES_OFFSET) {
771 IC.pushOperator(IC_MINUS);
775 if (!BaseReg && !TmpScale.has_value()) {
780 return regsUseUpError(ErrMsg);
783 if (TmpScale.has_value() &&
787 Scale = TmpScale.value_or(0);
790 }
else if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
792 ErrMsg =
"Scale can't be negative";
795 IC.pushOperator(IC_NEG);
800 PrevState = CurrState;
804 IntelExprState CurrState = State;
830 IC.pushOperator(IC_NOT);
833 PrevState = CurrState;
835 bool onRegister(MCRegister
Reg, StringRef &ErrMsg) {
836 IntelExprState CurrState = State;
844 State = IES_REGISTER;
846 IC.pushOperand(IC_REGISTER);
847 if (NegativeAdditiveTerm) {
848 ErrMsg =
"Scale can't be negative";
856 ErrMsg =
"Register can't be multiplied with register!";
859 State = IES_REGISTER;
864 if (TmpScale.has_value()) {
866 return regsUseUpError(ErrMsg);
867 if (NegativeAdditiveTerm) {
868 ErrMsg =
"Scale can't be negative";
873 IC.pushOperand(IC_IMM);
875 IC.pushOperand(IC_REGISTER);
879 PrevState = CurrState;
882 bool onIdentifierExpr(
const MCExpr *SymRef, StringRef SymRefName,
883 const InlineAsmIdentifierInfo &IDInfo,
884 const AsmTypeInfo &
Type,
bool ParsingMSInlineAsm,
887 if (ParsingMSInlineAsm)
892 return onInteger(
CE->getValue(), ErrMsg);
905 if (setSymRef(SymRef, SymRefName, ErrMsg))
911 IC.pushOperand(IC_IMM);
912 if (ParsingMSInlineAsm)
919 bool onInteger(int64_t TmpInt, StringRef &ErrMsg) {
920 IntelExprState CurrState = State;
927 ErrMsg =
"division by zero in assembly expression";
934 ErrMsg =
"modulo by zero in assembly expression";
959 if (TmpScale.has_value()) {
960 TmpScale.value() *= TmpInt;
965 if (TmpReg && NegativeAdditiveTerm) {
966 ErrMsg =
"Scale can't be negative";
969 if (TmpReg &&
checkScale(TmpScale.value(), ErrMsg))
971 IC.pushOperand(IC_IMM, TmpInt);
974 PrevState = CurrState;
984 State = IES_MULTIPLY;
985 IC.pushOperator(IC_MULTIPLY);
992 if (TmpReg && (!TmpScale.has_value())) {
994 IC.pushOperand(IC_IMM);
996 State = IES_MULTIPLY;
997 IC.pushOperator(IC_MULTIPLY);
1010 IC.pushOperator(IC_DIVIDE);
1023 IC.pushOperator(IC_MOD);
1039 IC.pushOperator(IC_PLUS);
1041 CurType.Size = CurType.ElementSize;
1045 assert(!BracCount &&
"BracCount should be zero on parsing's start");
1049 NegativeAdditiveTerm =
false;
1050 NegativeAdditiveTermLoc = SMLoc();
1058 bool onRBrac(StringRef &ErrMsg) {
1059 IntelExprState CurrState = State;
1068 if (BracCount-- != 1) {
1069 ErrMsg =
"unexpected bracket encountered";
1077 if (!BaseReg && !TmpScale.has_value()) {
1080 }
else if (!IndexReg) {
1081 if (NegativeAdditiveTerm) {
1082 ErrMsg =
"Scale can't be negative";
1087 if (TmpScale.has_value() &&
checkScale(TmpScale.value(), ErrMsg)) {
1090 Scale = TmpScale.value_or(0);
1092 return regsUseUpError(ErrMsg);
1095 NegativeAdditiveTerm =
false;
1096 NegativeAdditiveTermLoc = SMLoc();
1101 PrevState = CurrState;
1104 void onLParen(SMLoc Loc) {
1105 IntelExprState CurrState = State;
1133 IC.pushOperator(IC_LPAREN);
1136 PrevState = CurrState;
1138 bool onRParen(StringRef &ErrMsg) {
1139 IntelExprState CurrState = State;
1149 if (ParenCount == 0) {
1150 ErrMsg =
"unmatched parenthesis";
1155 IC.pushOperator(IC_RPAREN);
1158 PrevState = CurrState;
1161 bool onOffset(
const MCExpr *Val, StringRef ID,
1162 const InlineAsmIdentifierInfo &IDInfo,
1163 bool ParsingMSInlineAsm, StringRef &ErrMsg) {
1167 ErrMsg =
"unexpected offset operator expression";
1172 if (setSymRef(Val, ID, ErrMsg))
1174 OffsetOperator =
true;
1178 IC.pushOperand(IC_IMM);
1179 if (ParsingMSInlineAsm) {
1189 bool onImagerel(
const MCExpr *Val, StringRef ID, StringRef &ErrMsg) {
1195 if (setSymRef(Val, ID, ErrMsg))
1198 IC.pushOperand(IC_IMM);
1201 ErrMsg =
"unexpected imagerel operator expression";
1205 void onCast(AsmTypeInfo Info) {
1217 void setTypeInfo(AsmTypeInfo
Type) { CurType =
Type; }
1221 bool MatchingInlineAsm =
false) {
1222 MCAsmParser &Parser = getParser();
1223 if (MatchingInlineAsm) {
1229 bool MatchRegisterByName(MCRegister &RegNo, StringRef
RegName, SMLoc StartLoc,
1231 bool ParseRegister(MCRegister &RegNo, SMLoc &StartLoc, SMLoc &EndLoc,
1232 bool RestoreOnFailure);
1234 std::unique_ptr<X86Operand> DefaultMemSIOperand(SMLoc Loc);
1235 std::unique_ptr<X86Operand> DefaultMemDIOperand(SMLoc Loc);
1236 bool IsSIReg(MCRegister
Reg);
1237 MCRegister GetSIDIForRegClass(
unsigned RegClassID,
bool IsSIReg);
1240 std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
1241 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst);
1247 bool ParseIntelOffsetOperator(
const MCExpr *&Val, StringRef &ID,
1248 InlineAsmIdentifierInfo &Info, SMLoc &End);
1249 bool ParseIntelImagerelOperator(
const MCExpr *&Val, StringRef &ID,
1250 InlineAsmIdentifierInfo &Info, SMLoc &End);
1251 bool ParseIntelDotOperator(IntelExprStateMachine &SM, SMLoc &End);
1252 unsigned IdentifyIntelInlineAsmOperator(StringRef Name);
1253 unsigned ParseIntelInlineAsmOperator(
unsigned OpKind);
1254 unsigned IdentifyMasmOperator(StringRef Name);
1255 bool ParseMasmOperator(
unsigned OpKind, int64_t &Val);
1258 bool ParseIntelNamedOperator(StringRef Name, IntelExprStateMachine &SM,
1259 bool &ParseError, SMLoc &End);
1260 bool ParseMasmNamedOperator(StringRef Name, IntelExprStateMachine &SM,
1261 bool &ParseError, SMLoc &End);
1262 void RewriteIntelExpression(IntelExprStateMachine &SM, SMLoc Start,
1264 bool ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End);
1265 bool ParseIntelInlineAsmIdentifier(
const MCExpr *&Val, StringRef &Identifier,
1266 InlineAsmIdentifierInfo &Info,
1267 bool IsUnevaluatedOperand, SMLoc &End,
1268 bool IsParsingOffsetOperator =
false);
1270 IntelExprStateMachine &SM);
1272 bool CheckDispOverflow(MCRegister BaseReg, MCRegister IndexReg,
1273 const MCExpr *Disp, SMLoc Loc);
1275 bool ParseMemOperand(MCRegister SegReg,
const MCExpr *Disp, SMLoc StartLoc,
1280 bool ParseIntelMemoryOperandSize(
unsigned &
Size, StringRef *SizeStr);
1281 bool CreateMemForMSInlineAsm(MCRegister SegReg,
const MCExpr *Disp,
1282 MCRegister BaseReg, MCRegister IndexReg,
1283 unsigned Scale,
bool NonAbsMem, SMLoc Start,
1284 SMLoc End,
unsigned Size, StringRef Identifier,
1285 const InlineAsmIdentifierInfo &Info,
1288 bool parseDirectiveArch();
1289 bool parseDirectiveNops(SMLoc L);
1290 bool parseDirectiveEven(SMLoc L);
1291 bool ParseDirectiveCode(StringRef IDVal, SMLoc L);
1294 bool parseDirectiveFPOProc(SMLoc L);
1295 bool parseDirectiveFPOSetFrame(SMLoc L);
1296 bool parseDirectiveFPOPushReg(SMLoc L);
1297 bool parseDirectiveFPOStackAlloc(SMLoc L);
1298 bool parseDirectiveFPOStackAlign(SMLoc L);
1299 bool parseDirectiveFPOEndPrologue(SMLoc L);
1300 bool parseDirectiveFPOEndProc(SMLoc L);
1303 bool parseSEHRegisterNumber(
unsigned RegClassID, MCRegister &RegNo);
1304 bool parseDirectiveSEHPushReg(SMLoc);
1305 bool parseDirectiveSEHPush2Regs(SMLoc,
bool SwapRegs =
false);
1306 bool parseDirectiveSEHSetFrame(SMLoc);
1307 bool parseDirectiveSEHSaveReg(SMLoc);
1308 bool parseDirectiveSEHSaveXMM(SMLoc);
1309 bool parseDirectiveSEHPushFrame(SMLoc);
1311 bool ensureMasmEpilogContext(SMLoc Loc);
1312 bool ensureMasmPrologContext(SMLoc Loc);
1314 unsigned checkTargetMatchPredicate(MCInst &Inst)
override;
1320 void emitWarningForSpecialLVIInstruction(SMLoc Loc);
1321 void applyLVICFIMitigation(MCInst &Inst, MCStreamer &Out);
1322 void applyLVILoadHardeningMitigation(MCInst &Inst, MCStreamer &Out);
1328 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1331 bool MatchingInlineAsm)
override;
1334 MCStreamer &Out,
bool MatchingInlineAsm);
1336 bool ErrorMissingFeature(SMLoc IDLoc,
const FeatureBitset &MissingFeatures,
1337 bool MatchingInlineAsm);
1339 bool matchAndEmitATTInstruction(SMLoc IDLoc,
unsigned &Opcode, MCInst &Inst,
1341 uint64_t &ErrorInfo,
bool MatchingInlineAsm);
1343 bool matchAndEmitIntelInstruction(SMLoc IDLoc,
unsigned &Opcode, MCInst &Inst,
1346 bool MatchingInlineAsm);
1348 bool omitRegisterFromClobberLists(MCRegister
Reg)
override;
1355 bool ParseZ(std::unique_ptr<X86Operand> &Z, SMLoc StartLoc);
1357 bool is64BitMode()
const {
1359 return getSTI().hasFeature(X86::Is64Bit);
1361 bool is32BitMode()
const {
1363 return getSTI().hasFeature(X86::Is32Bit);
1365 bool is16BitMode()
const {
1367 return getSTI().hasFeature(X86::Is16Bit);
1369 void SwitchMode(
unsigned mode) {
1370 MCSubtargetInfo &STI = copySTI();
1371 FeatureBitset AllModes({X86::Is64Bit, X86::Is32Bit, X86::Is16Bit});
1373 FeatureBitset FB = ComputeAvailableFeatures(
1375 setAvailableFeatures(FB);
1380 unsigned getPointerWidth() {
1381 if (is16BitMode())
return 16;
1382 if (is32BitMode())
return 32;
1383 if (is64BitMode())
return 64;
1387 bool isParsingIntelSyntax() {
1388 return getParser().getAssemblerDialect();
1394#define GET_ASSEMBLER_HEADER
1395#include "X86GenAsmMatcher.inc"
1400 enum X86MatchResultTy {
1401 Match_Unsupported = FIRST_TARGET_MATCH_RESULT_TY,
1402#define GET_OPERAND_DIAGNOSTIC_TYPES
1403#include "X86GenAsmMatcher.inc"
1406 X86AsmParser(
const MCSubtargetInfo &sti, MCAsmParser &Parser,
1407 const MCInstrInfo &mii)
1408 : MCTargetAsmParser(sti, mii), InstInfo(nullptr), Code16GCC(
false) {
1413 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
1416 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
1417 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1418 SMLoc &EndLoc)
override;
1420 bool parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc)
override;
1422 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
1425 bool ParseDirective(AsmToken DirectiveID)
override;
1429#define GET_REGISTER_MATCHER
1430#define GET_SUBTARGET_FEATURE_NAME
1431#include "X86GenAsmMatcher.inc"
1442 !(BaseReg == X86::RIP || BaseReg == X86::EIP ||
1443 getX86MCRegisterClass(X86::GR16RegClassID).
contains(BaseReg) ||
1444 getX86MCRegisterClass(X86::GR32RegClassID).
contains(BaseReg) ||
1445 getX86MCRegisterClass(X86::GR64RegClassID).
contains(BaseReg))) {
1446 ErrMsg =
"invalid base+index expression";
1451 !(IndexReg == X86::EIZ || IndexReg == X86::RIZ ||
1452 getX86MCRegisterClass(X86::GR16RegClassID).
contains(IndexReg) ||
1453 getX86MCRegisterClass(X86::GR32RegClassID).
contains(IndexReg) ||
1454 getX86MCRegisterClass(X86::GR64RegClassID).
contains(IndexReg) ||
1455 getX86MCRegisterClass(X86::VR128XRegClassID).
contains(IndexReg) ||
1456 getX86MCRegisterClass(X86::VR256XRegClassID).
contains(IndexReg) ||
1457 getX86MCRegisterClass(X86::VR512RegClassID).
contains(IndexReg))) {
1458 ErrMsg =
"invalid base+index expression";
1462 if (((BaseReg == X86::RIP || BaseReg == X86::EIP) && IndexReg) ||
1463 IndexReg == X86::EIP || IndexReg == X86::RIP || IndexReg == X86::ESP ||
1464 IndexReg == X86::RSP) {
1465 ErrMsg =
"invalid base+index expression";
1471 if (getX86MCRegisterClass(X86::GR16RegClassID).
contains(BaseReg) &&
1472 (Is64BitMode || (BaseReg != X86::BX && BaseReg != X86::BP &&
1473 BaseReg != X86::SI && BaseReg != X86::DI))) {
1474 ErrMsg =
"invalid 16-bit base register";
1479 getX86MCRegisterClass(X86::GR16RegClassID).
contains(IndexReg)) {
1480 ErrMsg =
"16-bit memory operand may not include only index register";
1484 if (BaseReg && IndexReg) {
1485 if (getX86MCRegisterClass(X86::GR64RegClassID).
contains(BaseReg) &&
1486 (getX86MCRegisterClass(X86::GR16RegClassID).
contains(IndexReg) ||
1487 getX86MCRegisterClass(X86::GR32RegClassID).
contains(IndexReg) ||
1488 IndexReg == X86::EIZ)) {
1489 ErrMsg =
"base register is 64-bit, but index register is not";
1492 if (getX86MCRegisterClass(X86::GR32RegClassID).
contains(BaseReg) &&
1493 (getX86MCRegisterClass(X86::GR16RegClassID).
contains(IndexReg) ||
1494 getX86MCRegisterClass(X86::GR64RegClassID).
contains(IndexReg) ||
1495 IndexReg == X86::RIZ)) {
1496 ErrMsg =
"base register is 32-bit, but index register is not";
1499 if (getX86MCRegisterClass(X86::GR16RegClassID).
contains(BaseReg)) {
1500 if (getX86MCRegisterClass(X86::GR32RegClassID).
contains(IndexReg) ||
1501 getX86MCRegisterClass(X86::GR64RegClassID).
contains(IndexReg)) {
1502 ErrMsg =
"base register is 16-bit, but index register is not";
1505 if ((BaseReg != X86::BX && BaseReg != X86::BP) ||
1506 (IndexReg != X86::SI && IndexReg != X86::DI)) {
1507 ErrMsg =
"invalid 16-bit base/index register combination";
1514 if (!Is64BitMode && (BaseReg == X86::RIP || BaseReg == X86::EIP)) {
1515 ErrMsg =
"IP-relative addressing requires 64-bit mode";
1536 if (isParsingMSInlineAsm() && isParsingIntelSyntax() &&
1537 (RegNo == X86::EFLAGS || RegNo == X86::MXCSR))
1538 RegNo = MCRegister();
1540 if (!is64BitMode()) {
1544 if (RegNo == X86::RIZ || RegNo == X86::RIP ||
1545 getX86MCRegisterClass(X86::GR64RegClassID).
contains(RegNo) ||
1548 return Error(StartLoc,
1549 "register %" +
RegName +
" is only available in 64-bit mode",
1550 SMRange(StartLoc, EndLoc));
1555 UseApxExtendedReg =
true;
1559 if (!RegNo &&
RegName.starts_with(
"db")) {
1618 if (isParsingIntelSyntax())
1620 return Error(StartLoc,
"invalid register name", SMRange(StartLoc, EndLoc));
1625bool X86AsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
1626 SMLoc &EndLoc,
bool RestoreOnFailure) {
1627 MCAsmParser &Parser = getParser();
1628 AsmLexer &Lexer = getLexer();
1629 RegNo = MCRegister();
1632 auto OnFailure = [RestoreOnFailure, &Lexer, &Tokens]() {
1633 if (RestoreOnFailure) {
1634 while (!Tokens.
empty()) {
1640 const AsmToken &PercentTok = Parser.
getTok();
1641 StartLoc = PercentTok.
getLoc();
1650 const AsmToken &Tok = Parser.
getTok();
1655 if (isParsingIntelSyntax())
return true;
1656 return Error(StartLoc,
"invalid register name",
1657 SMRange(StartLoc, EndLoc));
1660 if (MatchRegisterByName(RegNo, Tok.
getString(), StartLoc, EndLoc)) {
1666 if (RegNo == X86::ST0) {
1677 const AsmToken &IntTok = Parser.
getTok();
1680 return Error(IntTok.
getLoc(),
"expected stack index");
1683 case 0: RegNo = X86::ST0;
break;
1684 case 1: RegNo = X86::ST1;
break;
1685 case 2: RegNo = X86::ST2;
break;
1686 case 3: RegNo = X86::ST3;
break;
1687 case 4: RegNo = X86::ST4;
break;
1688 case 5: RegNo = X86::ST5;
break;
1689 case 6: RegNo = X86::ST6;
break;
1690 case 7: RegNo = X86::ST7;
break;
1693 return Error(IntTok.
getLoc(),
"invalid stack index");
1713 if (isParsingIntelSyntax())
return true;
1714 return Error(StartLoc,
"invalid register name",
1715 SMRange(StartLoc, EndLoc));
1722bool X86AsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1724 return ParseRegister(
Reg, StartLoc, EndLoc,
false);
1727ParseStatus X86AsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1729 bool Result = ParseRegister(
Reg, StartLoc, EndLoc,
true);
1730 bool PendingErrors = getParser().hasPendingError();
1731 getParser().clearPendingErrors();
1739std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(SMLoc Loc) {
1740 bool Parse32 = is32BitMode() || Code16GCC;
1741 MCRegister Basereg =
1742 is64BitMode() ? X86::RSI : (Parse32 ? X86::ESI : X86::SI);
1749std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand(SMLoc Loc) {
1750 bool Parse32 = is32BitMode() || Code16GCC;
1751 MCRegister Basereg =
1752 is64BitMode() ? X86::RDI : (Parse32 ? X86::EDI : X86::DI);
1759bool X86AsmParser::IsSIReg(MCRegister
Reg) {
1773MCRegister X86AsmParser::GetSIDIForRegClass(
unsigned RegClassID,
bool IsSIReg) {
1774 switch (RegClassID) {
1776 case X86::GR64RegClassID:
1777 return IsSIReg ? X86::RSI : X86::RDI;
1778 case X86::GR32RegClassID:
1779 return IsSIReg ? X86::ESI : X86::EDI;
1780 case X86::GR16RegClassID:
1781 return IsSIReg ? X86::SI : X86::DI;
1785void X86AsmParser::AddDefaultSrcDestOperands(
1787 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst) {
1788 if (isParsingIntelSyntax()) {
1789 Operands.push_back(std::move(Dst));
1790 Operands.push_back(std::move(Src));
1793 Operands.push_back(std::move(Src));
1794 Operands.push_back(std::move(Dst));
1798bool X86AsmParser::VerifyAndAdjustOperands(
OperandVector &OrigOperands,
1801 if (OrigOperands.
size() > 1) {
1804 "Operand size mismatch");
1808 int RegClassID = -1;
1809 for (
unsigned int i = 0; i < FinalOperands.
size(); ++i) {
1810 X86Operand &OrigOp =
static_cast<X86Operand &
>(*OrigOperands[i + 1]);
1811 X86Operand &FinalOp =
static_cast<X86Operand &
>(*FinalOperands[i]);
1813 if (FinalOp.
isReg() &&
1818 if (FinalOp.
isMem()) {
1820 if (!OrigOp.
isMem())
1829 if (RegClassID != -1 &&
1830 !getX86MCRegisterClass(RegClassID).
contains(OrigReg)) {
1832 "mismatching source and destination index registers");
1835 if (getX86MCRegisterClass(X86::GR64RegClassID).
contains(OrigReg))
1836 RegClassID = X86::GR64RegClassID;
1837 else if (getX86MCRegisterClass(X86::GR32RegClassID).
contains(OrigReg))
1838 RegClassID = X86::GR32RegClassID;
1839 else if (getX86MCRegisterClass(X86::GR16RegClassID).
contains(OrigReg))
1840 RegClassID = X86::GR16RegClassID;
1846 bool IsSI = IsSIReg(FinalReg);
1847 FinalReg = GetSIDIForRegClass(RegClassID, IsSI);
1849 if (FinalReg != OrigReg) {
1850 std::string
RegName = IsSI ?
"ES:(R|E)SI" :
"ES:(R|E)DI";
1853 "memory operand is only for determining the size, " +
RegName +
1854 " will be used for the location"));
1865 for (
auto &WarningMsg : Warnings) {
1866 Warning(WarningMsg.first, WarningMsg.second);
1870 for (
unsigned int i = 0; i < FinalOperands.
size(); ++i)
1874 for (
auto &
Op : FinalOperands)
1881 if (isParsingIntelSyntax())
1882 return parseIntelOperand(
Operands, Name);
1887bool X86AsmParser::CreateMemForMSInlineAsm(
1888 MCRegister SegReg,
const MCExpr *Disp, MCRegister BaseReg,
1889 MCRegister IndexReg,
unsigned Scale,
bool NonAbsMem, SMLoc Start, SMLoc End,
1890 unsigned Size, StringRef Identifier,
const InlineAsmIdentifierInfo &Info,
1898 End,
Size, Identifier,
1905 unsigned FrontendSize = 0;
1906 void *Decl =
nullptr;
1907 bool IsGlobalLV =
false;
1910 FrontendSize =
Info.Var.Type * 8;
1911 Decl =
Info.Var.Decl;
1912 IsGlobalLV =
Info.Var.IsGlobalLV;
1917 if (BaseReg || IndexReg) {
1919 End,
Size, Identifier, Decl, 0,
1920 BaseReg && IndexReg));
1927 getPointerWidth(), SegReg, Disp, BaseReg, IndexReg, Scale, Start, End,
1929 X86::RIP, Identifier, Decl, FrontendSize));
1936bool X86AsmParser::ParseIntelNamedOperator(StringRef Name,
1937 IntelExprStateMachine &SM,
1938 bool &ParseError, SMLoc &End) {
1941 if (Name !=
Name.lower() && Name !=
Name.upper() &&
1942 !getParser().isParsingMasm())
1946 bool AlreadyConsumed =
false;
1947 if (
Name.equals_insensitive(
"not")) {
1949 }
else if (
Name.equals_insensitive(
"or")) {
1951 }
else if (
Name.equals_insensitive(
"shl")) {
1953 }
else if (
Name.equals_insensitive(
"shr")) {
1955 }
else if (
Name.equals_insensitive(
"xor")) {
1957 }
else if (
Name.equals_insensitive(
"and")) {
1959 }
else if (
Name.equals_insensitive(
"mod")) {
1961 }
else if (
Name.equals_insensitive(
"offset")) {
1962 const MCExpr *Val =
nullptr;
1964 InlineAsmIdentifierInfo
Info;
1965 ParseError = ParseIntelOffsetOperator(Val, ID, Info, End);
1969 ParseError = SM.onOffset(Val, ID, Info, isParsingMSInlineAsm(), ErrMsg);
1972 AlreadyConsumed =
true;
1973 }
else if (
Name.equals_insensitive(
"imagerel")) {
1976 InlineAsmIdentifierInfo
Info;
1977 ParseError = ParseIntelImagerelOperator(Val, ID, Info, End);
1984 AlreadyConsumed =
true;
1988 if (!AlreadyConsumed)
1989 End = consumeToken();
1992bool X86AsmParser::ParseMasmNamedOperator(StringRef Name,
1993 IntelExprStateMachine &SM,
1994 bool &ParseError, SMLoc &End) {
1995 if (
Name.equals_insensitive(
"eq")) {
1997 }
else if (
Name.equals_insensitive(
"ne")) {
1999 }
else if (
Name.equals_insensitive(
"lt")) {
2001 }
else if (
Name.equals_insensitive(
"le")) {
2003 }
else if (
Name.equals_insensitive(
"gt")) {
2005 }
else if (
Name.equals_insensitive(
"ge")) {
2010 End = consumeToken();
2017 IntelExprStateMachine &SM) {
2021 SM.setAppendAfterOperand();
2024bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
2025 MCAsmParser &Parser = getParser();
2030 if (
getContext().getObjectFileInfo()->isPositionIndependent())
2037 const AsmToken &Tok = Parser.
getTok();
2039 bool UpdateLocLex =
true;
2044 if ((
Done = SM.isValidEndState()))
2046 return Error(Tok.
getLoc(),
"unknown token in expression");
2048 return Error(getLexer().getErrLoc(), getLexer().getErr());
2052 UpdateLocLex =
false;
2053 if (ParseIntelDotOperator(SM, End))
2058 if ((
Done = SM.isValidEndState()))
2060 return Error(Tok.
getLoc(),
"unknown token in expression");
2064 UpdateLocLex =
false;
2065 if (ParseIntelDotOperator(SM, End))
2070 if ((
Done = SM.isValidEndState()))
2072 return Error(Tok.
getLoc(),
"unknown token in expression");
2078 SMLoc ValueLoc = Tok.
getLoc();
2083 UpdateLocLex =
false;
2084 if (!Val->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
2085 return Error(ValueLoc,
"expected absolute value");
2086 if (SM.onInteger(Res, ErrMsg))
2087 return Error(SM.getErrorLoc(ValueLoc), ErrMsg);
2094 SMLoc IdentLoc = Tok.
getLoc();
2096 UpdateLocLex =
false;
2098 size_t DotOffset =
Identifier.find_first_of(
'.');
2102 StringRef Dot =
Identifier.substr(DotOffset, 1);
2116 const AsmToken &NextTok = getLexer().peekTok();
2125 End = consumeToken();
2132 if (!ParseRegister(
Reg, IdentLoc, End,
true)) {
2133 if (SM.onRegister(
Reg, ErrMsg))
2134 return Error(SM.getErrorLoc(IdentLoc), ErrMsg);
2138 const std::pair<StringRef, StringRef> IDField =
2140 const StringRef
ID = IDField.first,
Field = IDField.second;
2142 if (!
Field.empty() &&
2143 !MatchRegisterByName(
Reg, ID, IdentLoc, IDEndLoc)) {
2144 if (SM.onRegister(
Reg, ErrMsg))
2145 return Error(SM.getErrorLoc(IdentLoc), ErrMsg);
2150 return Error(FieldStartLoc,
"unknown offset");
2151 else if (SM.onPlus(ErrMsg))
2152 return Error(getTok().getLoc(), ErrMsg);
2153 else if (SM.onInteger(
Info.Offset, ErrMsg))
2154 return Error(SM.getErrorLoc(IdentLoc), ErrMsg);
2155 SM.setTypeInfo(
Info.Type);
2157 End = consumeToken();
2164 if (ParseIntelNamedOperator(Identifier, SM, ParseError, End)) {
2170 ParseMasmNamedOperator(Identifier, SM, ParseError, End)) {
2176 InlineAsmIdentifierInfo
Info;
2177 AsmFieldInfo FieldInfo;
2183 if (ParseIntelDotOperator(SM, End))
2188 if (isParsingMSInlineAsm()) {
2190 if (
unsigned OpKind = IdentifyIntelInlineAsmOperator(Identifier)) {
2191 if (int64_t Val = ParseIntelInlineAsmOperator(OpKind)) {
2192 if (SM.onInteger(Val, ErrMsg))
2193 return Error(SM.getErrorLoc(IdentLoc), ErrMsg);
2202 return Error(IdentLoc,
"expected identifier");
2203 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
false, End))
2205 else if (SM.onIdentifierExpr(Val, Identifier, Info, FieldInfo.
Type,
2207 return Error(SM.getErrorLoc(IdentLoc), ErrMsg);
2211 if (
unsigned OpKind = IdentifyMasmOperator(Identifier)) {
2213 if (ParseMasmOperator(OpKind, Val))
2215 if (SM.onInteger(Val, ErrMsg))
2216 return Error(SM.getErrorLoc(IdentLoc), ErrMsg);
2219 if (!getParser().lookUpType(Identifier, FieldInfo.
Type)) {
2225 getParser().parseIdentifier(Identifier);
2229 if (getParser().lookUpField(FieldInfo.
Type.
Name, Identifier,
2233 return Error(IdentLoc,
"Unable to lookup field reference!",
2234 SMRange(IdentLoc, IDEnd));
2239 if (SM.onInteger(FieldInfo.
Offset, ErrMsg))
2240 return Error(SM.getErrorLoc(IdentLoc), ErrMsg);
2244 if (getParser().parsePrimaryExpr(Val, End, &FieldInfo.
Type)) {
2245 return Error(Tok.
getLoc(),
"Unexpected identifier!");
2246 }
else if (SM.onIdentifierExpr(Val, Identifier, Info, FieldInfo.
Type,
2248 return Error(SM.getErrorLoc(IdentLoc), ErrMsg);
2254 SMLoc Loc = getTok().getLoc();
2255 int64_t
IntVal = getTok().getIntVal();
2256 End = consumeToken();
2257 UpdateLocLex =
false;
2259 StringRef IDVal = getTok().getString();
2260 if (IDVal ==
"f" || IDVal ==
"b") {
2262 getContext().getDirectionalLocalSymbol(IntVal, IDVal ==
"b");
2267 return Error(Loc,
"invalid reference to undefined symbol");
2269 InlineAsmIdentifierInfo
Info;
2271 if (SM.onIdentifierExpr(Val, Identifier, Info,
Type,
2272 isParsingMSInlineAsm(), ErrMsg))
2273 return Error(SM.getErrorLoc(Loc), ErrMsg);
2274 End = consumeToken();
2276 if (SM.onInteger(IntVal, ErrMsg))
2277 return Error(SM.getErrorLoc(Loc), ErrMsg);
2280 if (SM.onInteger(IntVal, ErrMsg))
2281 return Error(SM.getErrorLoc(Loc), ErrMsg);
2286 if (SM.onPlus(ErrMsg))
2287 return Error(getTok().getLoc(), ErrMsg);
2290 if (SM.onMinus(getTok().getLoc(), ErrMsg))
2291 return Error(SM.getErrorLoc(getTok().getLoc()), ErrMsg);
2301 SM.onLShift();
break;
2303 SM.onRShift();
break;
2306 return Error(Tok.
getLoc(),
"unexpected bracket encountered");
2307 tryParseOperandIdx(PrevTK, SM);
2310 if (SM.onRBrac(ErrMsg)) {
2311 return Error(SM.getErrorLoc(Tok.
getLoc()), ErrMsg);
2315 SM.onLParen(Tok.
getLoc());
2318 if (SM.onRParen(ErrMsg)) {
2319 return Error(SM.getErrorLoc(Tok.
getLoc()), ErrMsg);
2324 return Error(Tok.
getLoc(),
"unknown token in expression");
2326 if (!
Done && UpdateLocLex)
2327 End = consumeToken();
2331 if (SM.hasUnmatchedParen())
2332 return Error(SM.getLParenLoc(),
"unmatched parenthesis");
2336void X86AsmParser::RewriteIntelExpression(IntelExprStateMachine &SM,
2337 SMLoc Start, SMLoc End) {
2341 if (SM.getSym() && !SM.isOffsetOperator()) {
2342 StringRef SymName = SM.getSymName();
2343 if (
unsigned Len = SymName.
data() -
Start.getPointer())
2349 if (!(SM.getBaseReg() || SM.getIndexReg() || SM.getImm())) {
2356 StringRef BaseRegStr;
2357 StringRef IndexRegStr;
2358 StringRef OffsetNameStr;
2359 if (SM.getBaseReg())
2361 if (SM.getIndexReg())
2363 if (SM.isOffsetOperator())
2364 OffsetNameStr = SM.getSymName();
2366 IntelExpr Expr(BaseRegStr, IndexRegStr, SM.getScale(), OffsetNameStr,
2367 SM.getImm(), SM.isMemExpr());
2368 InstInfo->
AsmRewrites->emplace_back(Loc, ExprLen, Expr);
2372bool X86AsmParser::ParseIntelInlineAsmIdentifier(
2373 const MCExpr *&Val, StringRef &Identifier, InlineAsmIdentifierInfo &Info,
2374 bool IsUnevaluatedOperand, SMLoc &End,
bool IsParsingOffsetOperator) {
2375 MCAsmParser &Parser = getParser();
2376 assert(isParsingMSInlineAsm() &&
"Expected to be parsing inline assembly.");
2380 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);
2382 const AsmToken &Tok = Parser.
getTok();
2383 SMLoc Loc = Tok.
getLoc();
2398 "frontend claimed part of a token?");
2403 StringRef InternalName =
2404 SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(),
2406 assert(InternalName.
size() &&
"We should have an internal name here.");
2409 if (!IsParsingOffsetOperator)
2425 MCAsmParser &Parser = getParser();
2426 const AsmToken &Tok = Parser.
getTok();
2428 const SMLoc consumedToken = consumeToken();
2430 return Error(Tok.
getLoc(),
"Expected an identifier after {");
2433 .Case(
"rn", X86::STATIC_ROUNDING::TO_NEAREST_INT)
2434 .Case(
"rd", X86::STATIC_ROUNDING::TO_NEG_INF)
2435 .Case(
"ru", X86::STATIC_ROUNDING::TO_POS_INF)
2436 .Case(
"rz", X86::STATIC_ROUNDING::TO_ZERO)
2439 return Error(Tok.
getLoc(),
"Invalid rounding mode.");
2442 return Error(Tok.
getLoc(),
"Expected - at this point");
2446 return Error(Tok.
getLoc(),
"Expected } at this point");
2449 const MCExpr *RndModeOp =
2457 return Error(Tok.
getLoc(),
"Expected } at this point");
2462 return Error(Tok.
getLoc(),
"unknown token in expression");
2468 MCAsmParser &Parser = getParser();
2469 AsmToken Tok = Parser.
getTok();
2472 return Error(Tok.
getLoc(),
"Expected { at this point");
2476 return Error(Tok.
getLoc(),
"Expected dfv at this point");
2480 return Error(Tok.
getLoc(),
"Expected = at this point");
2492 unsigned CFlags = 0;
2493 for (
unsigned I = 0;
I < 4; ++
I) {
2502 return Error(Tok.
getLoc(),
"Invalid conditional flags");
2505 return Error(Tok.
getLoc(),
"Duplicated conditional flag");
2516 }
else if (
I == 3) {
2517 return Error(Tok.
getLoc(),
"Expected } at this point");
2519 return Error(Tok.
getLoc(),
"Expected } or , at this point");
2527bool X86AsmParser::ParseIntelDotOperator(IntelExprStateMachine &SM,
2529 const AsmToken &Tok = getTok();
2535 bool TrailingDot =
false;
2543 }
else if ((isParsingMSInlineAsm() || getParser().isParsingMasm()) &&
2546 const std::pair<StringRef, StringRef> BaseMember = DotDispStr.
split(
'.');
2547 const StringRef
Base = BaseMember.first,
Member = BaseMember.second;
2548 if (getParser().lookUpField(SM.getType(), DotDispStr, Info) &&
2549 getParser().lookUpField(SM.getSymName(), DotDispStr, Info) &&
2550 getParser().lookUpField(DotDispStr, Info) &&
2552 SemaCallback->LookupInlineAsmField(
Base, Member,
Info.Offset)))
2553 return Error(Tok.
getLoc(),
"Unable to lookup field reference!");
2555 return Error(Tok.
getLoc(),
"Unexpected token type!");
2560 const char *DotExprEndLoc = DotDispStr.
data() + DotDispStr.
size();
2565 SM.addImm(
Info.Offset);
2566 SM.setTypeInfo(
Info.Type);
2572bool X86AsmParser::ParseIntelOffsetOperator(
const MCExpr *&Val, StringRef &ID,
2573 InlineAsmIdentifierInfo &Info,
2576 SMLoc
Start = Lex().getLoc();
2577 ID = getTok().getString();
2578 if (!isParsingMSInlineAsm()) {
2581 getParser().parsePrimaryExpr(Val, End,
nullptr))
2582 return Error(Start,
"unexpected token!");
2583 }
else if (ParseIntelInlineAsmIdentifier(Val, ID, Info,
false, End,
true)) {
2584 return Error(Start,
"unable to lookup expression");
2586 return Error(Start,
"offset operator cannot yet handle constants");
2593bool X86AsmParser::ParseIntelImagerelOperator(
const MCExpr *&Val, StringRef &ID,
2594 InlineAsmIdentifierInfo &Info,
2597 SMLoc
Start = Lex().getLoc();
2598 ID = getTok().getString();
2599 if (!isParsingMSInlineAsm()) {
2602 getParser().parsePrimaryExpr(Val, End,
nullptr))
2603 return Error(Start,
"unexpected token!");
2604 }
else if (ParseIntelInlineAsmIdentifier(Val, ID, Info,
false, End,
true)) {
2605 return Error(Start,
"unable to lookup expression");
2607 return Error(Start,
"imagerel operator cannot yet handle constants");
2610 const MCExpr *ModifiedVal =
2613 return Error(Start,
"cannot apply 'imagerel' to this expression");
2620unsigned X86AsmParser::IdentifyIntelInlineAsmOperator(StringRef Name) {
2621 return StringSwitch<unsigned>(Name)
2622 .Cases({
"TYPE",
"type"}, IOK_TYPE)
2623 .Cases({
"SIZE",
"size"}, IOK_SIZE)
2624 .Cases({
"LENGTH",
"length"}, IOK_LENGTH)
2634unsigned X86AsmParser::ParseIntelInlineAsmOperator(
unsigned OpKind) {
2635 MCAsmParser &Parser = getParser();
2636 const AsmToken &Tok = Parser.
getTok();
2639 const MCExpr *Val =
nullptr;
2640 InlineAsmIdentifierInfo
Info;
2643 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
2648 Error(Start,
"unable to lookup expression");
2655 case IOK_LENGTH: CVal =
Info.Var.Length;
break;
2656 case IOK_SIZE: CVal =
Info.Var.Size;
break;
2657 case IOK_TYPE: CVal =
Info.Var.Type;
break;
2665unsigned X86AsmParser::IdentifyMasmOperator(StringRef Name) {
2666 return StringSwitch<unsigned>(
Name.lower())
2667 .Case(
"type", MOK_TYPE)
2668 .Cases({
"size",
"sizeof"}, MOK_SIZEOF)
2669 .Cases({
"length",
"lengthof"}, MOK_LENGTHOF)
2679bool X86AsmParser::ParseMasmOperator(
unsigned OpKind, int64_t &Val) {
2680 MCAsmParser &Parser = getParser();
2685 if (OpKind == MOK_SIZEOF || OpKind == MOK_TYPE) {
2688 const AsmToken &IDTok = InParens ? getLexer().peekTok() : Parser.
getTok();
2704 IntelExprStateMachine SM;
2706 if (ParseIntelExpression(SM, End))
2716 Val = SM.getLength();
2719 Val = SM.getElementSize();
2724 return Error(OpLoc,
"expression has unknown type", SMRange(Start, End));
2730bool X86AsmParser::ParseIntelMemoryOperandSize(
unsigned &
Size,
2731 StringRef *SizeStr) {
2732 Size = StringSwitch<unsigned>(getTok().getString())
2733 .Cases({
"BYTE",
"byte"}, 8)
2734 .Cases({
"WORD",
"word"}, 16)
2735 .Cases({
"DWORD",
"dword"}, 32)
2736 .Cases({
"FLOAT",
"float"}, 32)
2737 .Cases({
"LONG",
"long"}, 32)
2738 .Cases({
"FWORD",
"fword"}, 48)
2739 .Cases({
"DOUBLE",
"double"}, 64)
2740 .Cases({
"QWORD",
"qword"}, 64)
2741 .Cases({
"MMWORD",
"mmword"}, 64)
2742 .Cases({
"XWORD",
"xword"}, 80)
2743 .Cases({
"TBYTE",
"tbyte"}, 80)
2744 .Cases({
"XMMWORD",
"xmmword"}, 128)
2745 .Cases({
"YMMWORD",
"ymmword"}, 256)
2746 .Cases({
"ZMMWORD",
"zmmword"}, 512)
2750 *SizeStr = getTok().getString();
2751 const AsmToken &Tok = Lex();
2753 return Error(Tok.
getLoc(),
"Expected 'PTR' or 'ptr' token!");
2760 if (getX86MCRegisterClass(X86::GR8RegClassID).
contains(RegNo))
2762 if (getX86MCRegisterClass(X86::GR16RegClassID).
contains(RegNo))
2764 if (getX86MCRegisterClass(X86::GR32RegClassID).
contains(RegNo))
2766 if (getX86MCRegisterClass(X86::GR64RegClassID).
contains(RegNo))
2773 MCAsmParser &Parser = getParser();
2774 const AsmToken &Tok = Parser.
getTok();
2780 if (ParseIntelMemoryOperandSize(
Size, &SizeStr))
2782 bool PtrInOperand = bool(
Size);
2788 return ParseRoundingModeOp(Start,
Operands);
2793 if (RegNo == X86::RIP)
2794 return Error(Start,
"rip can only be used as a base register");
2799 return Error(Start,
"expected memory operand after 'ptr', "
2800 "found register operand instead");
2809 "cannot cast register '" +
2811 "'; its size is not easily defined.");
2815 std::to_string(
RegSize) +
"-bit register '" +
2817 "' cannot be used as a " + std::to_string(
Size) +
"-bit " +
2824 if (!getX86MCRegisterClass(X86::SEGMENT_REGRegClassID).
contains(RegNo))
2825 return Error(Start,
"invalid segment register");
2827 Start = Lex().getLoc();
2831 IntelExprStateMachine SM;
2832 if (ParseIntelExpression(SM, End))
2835 if (isParsingMSInlineAsm())
2836 RewriteIntelExpression(SM, Start, Tok.
getLoc());
2838 int64_t
Imm = SM.getImm();
2839 const MCExpr *Disp = SM.getSym();
2848 if (!SM.isMemExpr() && !RegNo) {
2849 if (isParsingMSInlineAsm() && SM.isOffsetOperator()) {
2850 const InlineAsmIdentifierInfo &
Info = SM.getIdentifierInfo();
2855 SM.getSymName(),
Info.Var.Decl,
2856 Info.Var.IsGlobalLV));
2866 MCRegister
BaseReg = SM.getBaseReg();
2867 MCRegister IndexReg = SM.getIndexReg();
2868 if (IndexReg && BaseReg == X86::RIP)
2870 unsigned Scale = SM.getScale();
2872 Size = SM.getElementSize() << 3;
2874 if (Scale == 0 && BaseReg != X86::ESP && BaseReg != X86::RSP &&
2875 (IndexReg == X86::ESP || IndexReg == X86::RSP))
2881 !(getX86MCRegisterClass(X86::VR128XRegClassID).
contains(IndexReg) ||
2882 getX86MCRegisterClass(X86::VR256XRegClassID).
contains(IndexReg) ||
2883 getX86MCRegisterClass(X86::VR512RegClassID).
contains(IndexReg)) &&
2884 (getX86MCRegisterClass(X86::VR128XRegClassID).
contains(BaseReg) ||
2885 getX86MCRegisterClass(X86::VR256XRegClassID).
contains(BaseReg) ||
2886 getX86MCRegisterClass(X86::VR512RegClassID).
contains(BaseReg)))
2890 getX86MCRegisterClass(X86::GR16RegClassID).
contains(IndexReg))
2891 return Error(Start,
"16-bit addresses cannot have a scale");
2900 if ((BaseReg == X86::SI || BaseReg == X86::DI) &&
2901 (IndexReg == X86::BX || IndexReg == X86::BP))
2904 if ((BaseReg || IndexReg) &&
2907 return Error(Start, ErrMsg);
2908 bool IsUnconditionalBranch =
2909 Name.equals_insensitive(
"jmp") ||
Name.equals_insensitive(
"call");
2910 if (isParsingMSInlineAsm())
2911 return CreateMemForMSInlineAsm(RegNo, Disp, BaseReg, IndexReg, Scale,
2912 IsUnconditionalBranch && is64BitMode(),
2913 Start, End,
Size, SM.getSymName(),
2918 MCRegister DefaultBaseReg;
2919 bool MaybeDirectBranchDest =
true;
2922 if (is64BitMode() &&
2923 ((PtrInOperand && !IndexReg) || SM.getElementSize() > 0)) {
2924 DefaultBaseReg = X86::RIP;
2926 if (IsUnconditionalBranch) {
2928 MaybeDirectBranchDest =
false;
2930 DefaultBaseReg = X86::RIP;
2931 }
else if (!BaseReg && !IndexReg && Disp &&
2933 if (is64BitMode()) {
2934 if (SM.getSize() == 8) {
2935 MaybeDirectBranchDest =
false;
2936 DefaultBaseReg = X86::RIP;
2939 if (SM.getSize() == 4 || SM.getSize() == 2)
2940 MaybeDirectBranchDest =
false;
2944 }
else if (IsUnconditionalBranch) {
2946 if (!PtrInOperand && SM.isOffsetOperator())
2948 Start,
"`OFFSET` operator cannot be used in an unconditional branch");
2949 if (PtrInOperand || SM.isBracketUsed())
2950 MaybeDirectBranchDest =
false;
2953 if (CheckDispOverflow(BaseReg, IndexReg, Disp, Start))
2956 if ((BaseReg || IndexReg || RegNo || DefaultBaseReg))
2958 getPointerWidth(), RegNo, Disp, BaseReg, IndexReg, Scale, Start, End,
2959 Size, DefaultBaseReg, StringRef(),
nullptr,
2960 0,
false, MaybeDirectBranchDest));
2963 getPointerWidth(), Disp, Start, End,
Size, StringRef(),
2965 MaybeDirectBranchDest));
2970 MCAsmParser &Parser = getParser();
2971 switch (getLexer().getKind()) {
2981 "expected immediate expression") ||
2982 getParser().parseExpression(Val, End) ||
2990 return ParseRoundingModeOp(Start,
Operands);
2999 const MCExpr *Expr =
nullptr;
3011 if (
Reg == X86::EIZ ||
Reg == X86::RIZ)
3013 Loc,
"%eiz and %riz can only be used as index registers",
3014 SMRange(Loc, EndLoc));
3015 if (
Reg == X86::RIP)
3016 return Error(Loc,
"%rip can only be used as a base register",
3017 SMRange(Loc, EndLoc));
3023 if (!getX86MCRegisterClass(X86::SEGMENT_REGRegClassID).
contains(
Reg))
3024 return Error(Loc,
"invalid segment register");
3032 return ParseMemOperand(
Reg, Expr, Loc, EndLoc,
Operands);
3039X86::CondCode X86AsmParser::ParseConditionCode(StringRef CC) {
3040 return StringSwitch<X86::CondCode>(CC)
3062bool X86AsmParser::ParseZ(std::unique_ptr<X86Operand> &Z, SMLoc StartLoc) {
3063 MCAsmParser &Parser = getParser();
3068 (getLexer().getTok().getIdentifier() ==
"z")))
3073 return Error(getLexer().getLoc(),
"Expected } at this point");
3082 MCAsmParser &Parser = getParser();
3085 const SMLoc consumedToken = consumeToken();
3089 if (getLexer().getTok().getIntVal() != 1)
3090 return TokError(
"Expected 1to<NUM> at this point");
3091 StringRef
Prefix = getLexer().getTok().getString();
3094 return TokError(
"Expected 1to<NUM> at this point");
3097 StringRef BroadcastString = (
Prefix + getLexer().getTok().getIdentifier())
3100 return TokError(
"Expected 1to<NUM> at this point");
3101 const char *BroadcastPrimitive =
3102 StringSwitch<const char *>(BroadcastString)
3103 .Case(
"1to2",
"{1to2}")
3104 .Case(
"1to4",
"{1to4}")
3105 .Case(
"1to8",
"{1to8}")
3106 .Case(
"1to16",
"{1to16}")
3107 .Case(
"1to32",
"{1to32}")
3109 if (!BroadcastPrimitive)
3110 return TokError(
"Invalid memory broadcast primitive.");
3113 return TokError(
"Expected } at this point");
3124 std::unique_ptr<X86Operand>
Z;
3125 if (ParseZ(Z, consumedToken))
3131 SMLoc StartLoc =
Z ? consumeToken() : consumedToken;
3136 if (!parseRegister(RegNo, RegLoc, StartLoc) &&
3137 getX86MCRegisterClass(X86::VK1RegClassID).
contains(RegNo)) {
3138 if (RegNo == X86::K0)
3139 return Error(RegLoc,
"Register k0 can't be used as write mask");
3141 return Error(getLexer().getLoc(),
"Expected } at this point");
3147 return Error(getLexer().getLoc(),
3148 "Expected an op-mask register at this point");
3153 if (ParseZ(Z, consumeToken()) || !Z)
3154 return Error(getLexer().getLoc(),
3155 "Expected a {z} mark at this point");
3170bool X86AsmParser::CheckDispOverflow(MCRegister BaseReg, MCRegister IndexReg,
3171 const MCExpr *Disp, SMLoc Loc) {
3177 if (BaseReg || IndexReg) {
3179 auto Imm =
CE->getValue();
3181 getX86MCRegisterClass(X86::GR64RegClassID).contains(BaseReg) ||
3182 getX86MCRegisterClass(X86::GR64RegClassID).contains(IndexReg);
3183 bool Is16 = getX86MCRegisterClass(X86::GR16RegClassID).contains(BaseReg);
3186 return Error(Loc,
"displacement " + Twine(
Imm) +
3187 " is not within [-2147483648, 2147483647]");
3191 " shortened to 32-bit signed " +
3192 Twine(
static_cast<int32_t
>(
Imm)));
3196 " shortened to 16-bit signed " +
3197 Twine(
static_cast<int16_t
>(
Imm)));
3206bool X86AsmParser::ParseMemOperand(MCRegister SegReg,
const MCExpr *Disp,
3207 SMLoc StartLoc, SMLoc EndLoc,
3209 MCAsmParser &Parser = getParser();
3227 auto isAtMemOperand = [
this]() {
3232 auto TokCount = this->getLexer().peekTokens(Buf,
true);
3235 switch (Buf[0].getKind()) {
3242 if ((TokCount > 1) &&
3246 Buf[1].getIdentifier().
size() + 1);
3268 if (!isAtMemOperand()) {
3287 0, 0, 1, StartLoc, EndLoc));
3295 SMLoc BaseLoc = getLexer().getLoc();
3307 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ)
3308 return Error(BaseLoc,
"eiz and riz can only be used as index registers",
3309 SMRange(BaseLoc, EndLoc));
3327 if (!
E->evaluateAsAbsolute(ScaleVal, getStreamer().getAssemblerPtr()))
3328 return Error(Loc,
"expected absolute expression");
3330 Warning(Loc,
"scale factor without index register is ignored");
3335 if (BaseReg == X86::RIP)
3337 "%rip as base register can not have an index register");
3338 if (IndexReg == X86::RIP)
3339 return Error(Loc,
"%rip is not allowed as an index register");
3350 return Error(Loc,
"expected scale expression");
3351 Scale = (unsigned)ScaleVal;
3353 if (getX86MCRegisterClass(X86::GR16RegClassID).
contains(BaseReg) &&
3355 return Error(Loc,
"scale factor in 16-bit address must be 1");
3357 return Error(Loc, ErrMsg);
3371 if (BaseReg == X86::DX && !IndexReg && Scale == 1 && !SegReg &&
3380 return Error(BaseLoc, ErrMsg);
3382 if (CheckDispOverflow(BaseReg, IndexReg, Disp, BaseLoc))
3385 if (SegReg || BaseReg || IndexReg)
3387 BaseReg, IndexReg, Scale, StartLoc,
3396bool X86AsmParser::parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
3397 MCAsmParser &Parser = getParser();
3404 if (parseRegister(RegNo, StartLoc, EndLoc))
3412bool X86AsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
3414 MCAsmParser &Parser = getParser();
3418 ForcedOpcodePrefix = OpcodePrefix_Default;
3419 ForcedDispEncoding = DispEncoding_Default;
3420 UseApxExtendedReg =
false;
3421 ForcedNoFlag =
false;
3434 if (Prefix ==
"rex")
3435 ForcedOpcodePrefix = OpcodePrefix_REX;
3436 else if (Prefix ==
"rex2")
3437 ForcedOpcodePrefix = OpcodePrefix_REX2;
3438 else if (Prefix ==
"vex")
3439 ForcedOpcodePrefix = OpcodePrefix_VEX;
3440 else if (Prefix ==
"vex2")
3441 ForcedOpcodePrefix = OpcodePrefix_VEX2;
3442 else if (Prefix ==
"vex3")
3443 ForcedOpcodePrefix = OpcodePrefix_VEX3;
3444 else if (Prefix ==
"evex")
3445 ForcedOpcodePrefix = OpcodePrefix_EVEX;
3446 else if (Prefix ==
"disp8")
3447 ForcedDispEncoding = DispEncoding_Disp8;
3448 else if (Prefix ==
"disp32")
3449 ForcedDispEncoding = DispEncoding_Disp32;
3450 else if (Prefix ==
"nf")
3451 ForcedNoFlag =
true;
3453 return Error(NameLoc,
"unknown prefix");
3469 if (isParsingMSInlineAsm()) {
3470 if (
Name.equals_insensitive(
"vex"))
3471 ForcedOpcodePrefix = OpcodePrefix_VEX;
3472 else if (
Name.equals_insensitive(
"vex2"))
3473 ForcedOpcodePrefix = OpcodePrefix_VEX2;
3474 else if (
Name.equals_insensitive(
"vex3"))
3475 ForcedOpcodePrefix = OpcodePrefix_VEX3;
3476 else if (
Name.equals_insensitive(
"evex"))
3477 ForcedOpcodePrefix = OpcodePrefix_EVEX;
3479 if (ForcedOpcodePrefix != OpcodePrefix_Default) {
3492 if (
Name.consume_back(
".d32")) {
3493 ForcedDispEncoding = DispEncoding_Disp32;
3494 }
else if (
Name.consume_back(
".d8")) {
3495 ForcedDispEncoding = DispEncoding_Disp8;
3498 StringRef PatchedName =
Name;
3501 if (isParsingIntelSyntax() &&
3502 (PatchedName ==
"jmp" || PatchedName ==
"jc" || PatchedName ==
"jnc" ||
3503 PatchedName ==
"jcxz" || PatchedName ==
"jecxz" ||
3508 : NextTok ==
"short") {
3517 NextTok.
size() + 1);
3523 PatchedName !=
"setzub" && PatchedName !=
"setzunb" &&
3524 PatchedName !=
"setb" && PatchedName !=
"setnb")
3525 PatchedName = PatchedName.
substr(0,
Name.size()-1);
3527 unsigned ComparisonPredicate = ~0
U;
3535 bool IsVCMP = PatchedName[0] ==
'v';
3536 unsigned CCIdx =
IsVCMP ? 4 : 3;
3537 unsigned suffixLength = PatchedName.
ends_with(
"bf16") ? 5 : 2;
3538 unsigned CC = StringSwitch<unsigned>(
3539 PatchedName.
slice(CCIdx, PatchedName.
size() - suffixLength))
3541 .Case(
"eq_oq", 0x00)
3543 .Case(
"lt_os", 0x01)
3545 .Case(
"le_os", 0x02)
3546 .Case(
"unord", 0x03)
3547 .Case(
"unord_q", 0x03)
3549 .Case(
"neq_uq", 0x04)
3551 .Case(
"nlt_us", 0x05)
3553 .Case(
"nle_us", 0x06)
3555 .Case(
"ord_q", 0x07)
3557 .Case(
"eq_uq", 0x08)
3559 .Case(
"nge_us", 0x09)
3561 .Case(
"ngt_us", 0x0A)
3562 .Case(
"false", 0x0B)
3563 .Case(
"false_oq", 0x0B)
3564 .Case(
"neq_oq", 0x0C)
3566 .Case(
"ge_os", 0x0D)
3568 .Case(
"gt_os", 0x0E)
3570 .Case(
"true_uq", 0x0F)
3571 .Case(
"eq_os", 0x10)
3572 .Case(
"lt_oq", 0x11)
3573 .Case(
"le_oq", 0x12)
3574 .Case(
"unord_s", 0x13)
3575 .Case(
"neq_us", 0x14)
3576 .Case(
"nlt_uq", 0x15)
3577 .Case(
"nle_uq", 0x16)
3578 .Case(
"ord_s", 0x17)
3579 .Case(
"eq_us", 0x18)
3580 .Case(
"nge_uq", 0x19)
3581 .Case(
"ngt_uq", 0x1A)
3582 .Case(
"false_os", 0x1B)
3583 .Case(
"neq_os", 0x1C)
3584 .Case(
"ge_oq", 0x1D)
3585 .Case(
"gt_oq", 0x1E)
3586 .Case(
"true_us", 0x1F)
3588 if (CC != ~0U && (
IsVCMP || CC < 8) &&
3591 PatchedName =
IsVCMP ?
"vcmpss" :
"cmpss";
3593 PatchedName =
IsVCMP ?
"vcmpsd" :
"cmpsd";
3595 PatchedName =
IsVCMP ?
"vcmpps" :
"cmpps";
3597 PatchedName =
IsVCMP ?
"vcmppd" :
"cmppd";
3599 PatchedName =
"vcmpsh";
3601 PatchedName =
"vcmpph";
3603 PatchedName =
"vcmpbf16";
3607 ComparisonPredicate = CC;
3613 (PatchedName.
back() ==
'b' || PatchedName.
back() ==
'w' ||
3614 PatchedName.
back() ==
'd' || PatchedName.
back() ==
'q')) {
3615 unsigned SuffixSize = PatchedName.
drop_back().
back() ==
'u' ? 2 : 1;
3616 unsigned CC = StringSwitch<unsigned>(
3617 PatchedName.
slice(5, PatchedName.
size() - SuffixSize))
3627 if (CC != ~0U && (CC != 0 || SuffixSize == 2)) {
3628 switch (PatchedName.
back()) {
3630 case 'b': PatchedName = SuffixSize == 2 ?
"vpcmpub" :
"vpcmpb";
break;
3631 case 'w': PatchedName = SuffixSize == 2 ?
"vpcmpuw" :
"vpcmpw";
break;
3632 case 'd': PatchedName = SuffixSize == 2 ?
"vpcmpud" :
"vpcmpd";
break;
3633 case 'q': PatchedName = SuffixSize == 2 ?
"vpcmpuq" :
"vpcmpq";
break;
3636 ComparisonPredicate = CC;
3642 (PatchedName.
back() ==
'b' || PatchedName.
back() ==
'w' ||
3643 PatchedName.
back() ==
'd' || PatchedName.
back() ==
'q')) {
3644 unsigned SuffixSize = PatchedName.
drop_back().
back() ==
'u' ? 2 : 1;
3645 unsigned CC = StringSwitch<unsigned>(
3646 PatchedName.
slice(5, PatchedName.
size() - SuffixSize))
3657 switch (PatchedName.
back()) {
3659 case 'b': PatchedName = SuffixSize == 2 ?
"vpcomub" :
"vpcomb";
break;
3660 case 'w': PatchedName = SuffixSize == 2 ?
"vpcomuw" :
"vpcomw";
break;
3661 case 'd': PatchedName = SuffixSize == 2 ?
"vpcomud" :
"vpcomd";
break;
3662 case 'q': PatchedName = SuffixSize == 2 ?
"vpcomuq" :
"vpcomq";
break;
3665 ComparisonPredicate = CC;
3677 StringSwitch<bool>(Name)
3678 .Cases({
"cs",
"ds",
"es",
"fs",
"gs",
"ss"},
true)
3679 .Cases({
"rex64",
"data32",
"data16",
"addr32",
"addr16"},
true)
3680 .Cases({
"xacquire",
"xrelease"},
true)
3681 .Cases({
"acquire",
"release"}, isParsingIntelSyntax())
3684 auto isLockRepeatNtPrefix = [](StringRef
N) {
3685 return StringSwitch<bool>(
N)
3686 .Cases({
"lock",
"rep",
"repe",
"repz",
"repne",
"repnz",
"notrack"},
3691 bool CurlyAsEndOfStatement =
false;
3694 while (isLockRepeatNtPrefix(
Name.lower())) {
3696 StringSwitch<unsigned>(Name)
3715 while (
Name.starts_with(
";") ||
Name.starts_with(
"\n") ||
3716 Name.starts_with(
"#") ||
Name.starts_with(
"\t") ||
3717 Name.starts_with(
"/")) {
3728 if (PatchedName ==
"data16" && is16BitMode()) {
3729 return Error(NameLoc,
"redundant data16 prefix");
3731 if (PatchedName ==
"data32") {
3733 return Error(NameLoc,
"redundant data32 prefix");
3735 return Error(NameLoc,
"'data32' is not supported in 64-bit mode");
3737 PatchedName =
"data16";
3744 if (
Next ==
"callw")
3746 if (
Next ==
"ljmpw")
3751 ForcedDataPrefix = X86::Is32Bit;
3759 if (ComparisonPredicate != ~0U && !isParsingIntelSyntax()) {
3766 if ((
Name.starts_with(
"ccmp") ||
Name.starts_with(
"ctest")) &&
3795 CurlyAsEndOfStatement =
3796 isParsingIntelSyntax() && isParsingMSInlineAsm() &&
3799 return TokError(
"unexpected token in argument list");
3803 if (ComparisonPredicate != ~0U && isParsingIntelSyntax()) {
3813 else if (CurlyAsEndOfStatement)
3816 getLexer().getTok().getLoc(), 0);
3823 if (IsFp &&
Operands.size() == 1) {
3824 const char *Repl = StringSwitch<const char *>(Name)
3825 .Case(
"fsub",
"fsubp")
3826 .Case(
"fdiv",
"fdivp")
3827 .Case(
"fsubr",
"fsubrp")
3828 .Case(
"fdivr",
"fdivrp");
3829 static_cast<X86Operand &
>(*
Operands[0]).setTokenValue(Repl);
3832 if ((Name ==
"mov" || Name ==
"movw" || Name ==
"movl") &&
3834 X86Operand &Op1 = (X86Operand &)*
Operands[1];
3835 X86Operand &Op2 = (X86Operand &)*
Operands[2];
3840 getX86MCRegisterClass(X86::SEGMENT_REGRegClassID)
3842 (getX86MCRegisterClass(X86::GR16RegClassID).
contains(Op1.
getReg()) ||
3843 getX86MCRegisterClass(X86::GR32RegClassID).
contains(Op1.
getReg()))) {
3845 if (Name !=
"mov" && Name[3] == (is16BitMode() ?
'l' :
'w')) {
3846 Name = is16BitMode() ?
"movw" :
"movl";
3859 if ((Name ==
"outb" || Name ==
"outsb" || Name ==
"outw" || Name ==
"outsw" ||
3860 Name ==
"outl" || Name ==
"outsl" || Name ==
"out" || Name ==
"outs") &&
3862 X86Operand &
Op = (X86Operand &)*
Operands.back();
3868 if ((Name ==
"inb" || Name ==
"insb" || Name ==
"inw" || Name ==
"insw" ||
3869 Name ==
"inl" || Name ==
"insl" || Name ==
"in" || Name ==
"ins") &&
3878 bool HadVerifyError =
false;
3881 if (
Name.starts_with(
"ins") &&
3883 (Name ==
"insb" || Name ==
"insw" || Name ==
"insl" || Name ==
"insd" ||
3886 AddDefaultSrcDestOperands(TmpOperands,
3888 DefaultMemDIOperand(NameLoc));
3889 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3893 if (
Name.starts_with(
"outs") &&
3895 (Name ==
"outsb" || Name ==
"outsw" || Name ==
"outsl" ||
3896 Name ==
"outsd" || Name ==
"outs")) {
3897 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
3899 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3905 if (
Name.starts_with(
"lods") &&
3907 (Name ==
"lods" || Name ==
"lodsb" || Name ==
"lodsw" ||
3908 Name ==
"lodsl" || Name ==
"lodsd" || Name ==
"lodsq")) {
3909 TmpOperands.
push_back(DefaultMemSIOperand(NameLoc));
3910 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3916 if (
Name.starts_with(
"stos") &&
3918 (Name ==
"stos" || Name ==
"stosb" || Name ==
"stosw" ||
3919 Name ==
"stosl" || Name ==
"stosd" || Name ==
"stosq")) {
3920 TmpOperands.
push_back(DefaultMemDIOperand(NameLoc));
3921 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3927 if (
Name.starts_with(
"scas") &&
3929 (Name ==
"scas" || Name ==
"scasb" || Name ==
"scasw" ||
3930 Name ==
"scasl" || Name ==
"scasd" || Name ==
"scasq")) {
3931 TmpOperands.
push_back(DefaultMemDIOperand(NameLoc));
3932 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3936 if (
Name.starts_with(
"cmps") &&
3938 (Name ==
"cmps" || Name ==
"cmpsb" || Name ==
"cmpsw" ||
3939 Name ==
"cmpsl" || Name ==
"cmpsd" || Name ==
"cmpsq")) {
3940 AddDefaultSrcDestOperands(TmpOperands, DefaultMemDIOperand(NameLoc),
3941 DefaultMemSIOperand(NameLoc));
3942 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3946 if (((
Name.starts_with(
"movs") &&
3947 (Name ==
"movs" || Name ==
"movsb" || Name ==
"movsw" ||
3948 Name ==
"movsl" || Name ==
"movsd" || Name ==
"movsq")) ||
3949 (
Name.starts_with(
"smov") &&
3950 (Name ==
"smov" || Name ==
"smovb" || Name ==
"smovw" ||
3951 Name ==
"smovl" || Name ==
"smovd" || Name ==
"smovq"))) &&
3953 if (Name ==
"movsd" &&
Operands.size() == 1 && !isParsingIntelSyntax())
3955 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
3956 DefaultMemDIOperand(NameLoc));
3957 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3961 if (HadVerifyError) {
3962 return HadVerifyError;
3966 if ((Name ==
"xlat" || Name ==
"xlatb") &&
Operands.size() == 2) {
3967 X86Operand &Op1 =
static_cast<X86Operand &
>(*
Operands[1]);
3970 "size, (R|E)BX will be used for the location");
3972 static_cast<X86Operand &
>(*
Operands[0]).setTokenValue(
"xlatb");
3985 if (
I ==
Table.end() ||
I->OldOpc != Opcode)
3991 if (X86::isBLENDVPD(Opcode) || X86::isBLENDVPS(Opcode) ||
3992 X86::isPBLENDVB(Opcode))
3998bool X86AsmParser::processInstruction(MCInst &Inst,
const OperandVector &
Ops) {
4002 if (ForcedOpcodePrefix != OpcodePrefix_VEX3 &&
4009 auto replaceWithCCMPCTEST = [&](
unsigned Opcode) ->
bool {
4010 if (ForcedOpcodePrefix == OpcodePrefix_EVEX) {
4021 default:
return false;
4026 if (ForcedDispEncoding == DispEncoding_Disp32) {
4027 Inst.
setOpcode(is16BitMode() ? X86::JMP_2 : X86::JMP_4);
4036 if (ForcedDispEncoding == DispEncoding_Disp32) {
4037 Inst.
setOpcode(is16BitMode() ? X86::JCC_2 : X86::JCC_4);
4053#define FROM_TO(FROM, TO) \
4055 return replaceWithCCMPCTEST(X86::TO);
4057 FROM_TO(CMP64mi32, CCMP64mi32)
4060 FROM_TO(CMP64ri32, CCMP64ri32)
4087 FROM_TO(TEST64mi32, CTEST64mi32)
4089 FROM_TO(TEST64ri32, CTEST64ri32)
4109bool X86AsmParser::validateInstruction(MCInst &Inst,
const OperandVector &
Ops) {
4110 using namespace X86;
4111 const MCRegisterInfo *MRI =
getContext().getRegisterInfo();
4113 uint64_t TSFlags = MII.get(Opcode).TSFlags;
4114 if (isVFCMADDCPH(Opcode) || isVFCMADDCSH(Opcode) || isVFMADDCPH(Opcode) ||
4115 isVFMADDCSH(Opcode)) {
4119 return Warning(
Ops[0]->getStartLoc(),
"Destination register should be "
4120 "distinct from source registers");
4121 }
else if (isVFCMULCPH(Opcode) || isVFCMULCSH(Opcode) || isVFMULCPH(Opcode) ||
4122 isVFMULCSH(Opcode)) {
4132 return Warning(
Ops[0]->getStartLoc(),
"Destination register should be "
4133 "distinct from source registers");
4134 }
else if (isV4FMADDPS(Opcode) || isV4FMADDSS(Opcode) ||
4135 isV4FNMADDPS(Opcode) || isV4FNMADDSS(Opcode) ||
4136 isVP4DPWSSDS(Opcode) || isVP4DPWSSD(Opcode)) {
4141 if (Src2Enc % 4 != 0) {
4143 unsigned GroupStart = (Src2Enc / 4) * 4;
4144 unsigned GroupEnd = GroupStart + 3;
4146 "source register '" +
RegName +
"' implicitly denotes '" +
4147 RegName.take_front(3) + Twine(GroupStart) +
"' to '" +
4148 RegName.take_front(3) + Twine(GroupEnd) +
4151 }
else if (isVGATHERDPD(Opcode) || isVGATHERDPS(Opcode) ||
4152 isVGATHERQPD(Opcode) || isVGATHERQPS(Opcode) ||
4153 isVPGATHERDD(Opcode) || isVPGATHERDQ(Opcode) ||
4154 isVPGATHERQD(Opcode) || isVPGATHERQQ(Opcode)) {
4161 return Warning(
Ops[0]->getStartLoc(),
"index and destination registers "
4162 "should be distinct");
4168 if (Dest == Mask || Dest == Index || Mask == Index)
4169 return Warning(
Ops[0]->getStartLoc(),
"mask, index, and destination "
4170 "registers should be distinct");
4172 }
else if (isTCMMIMFP16PS(Opcode) || isTCMMRLFP16PS(Opcode) ||
4173 isTDPBF16PS(Opcode) || isTDPFP16PS(Opcode) || isTDPBSSD(Opcode) ||
4174 isTDPBSUD(Opcode) || isTDPBUSD(Opcode) || isTDPBUUD(Opcode)) {
4178 if (SrcDest == Src1 || SrcDest == Src2 || Src1 == Src2)
4179 return Error(
Ops[0]->getStartLoc(),
"all tmm registers must be distinct");
4193 for (
unsigned i = 0; i !=
NumOps; ++i) {
4198 if (
Reg == X86::AH ||
Reg == X86::BH ||
Reg == X86::CH ||
Reg == X86::DH)
4206 (Enc ==
X86II::EVEX || ForcedOpcodePrefix == OpcodePrefix_REX2 ||
4207 ForcedOpcodePrefix == OpcodePrefix_REX || UsesRex)) {
4209 return Error(
Ops[0]->getStartLoc(),
4210 "can't encode '" +
RegName.str() +
4211 "' in an instruction requiring EVEX/REX2/REX prefix");
4215 if ((Opcode == X86::PREFETCHIT0 || Opcode == X86::PREFETCHIT1)) {
4219 Ops[0]->getStartLoc(),
4220 Twine((Inst.
getOpcode() == X86::PREFETCHIT0 ?
"'prefetchit0'"
4221 :
"'prefetchit1'")) +
4222 " only supports RIP-relative address");
4227void X86AsmParser::emitWarningForSpecialLVIInstruction(SMLoc Loc) {
4228 Warning(Loc,
"Instruction may be vulnerable to LVI and "
4229 "requires manual mitigation");
4230 Note(SMLoc(),
"See https://software.intel.com/"
4231 "security-software-guidance/insights/"
4232 "deep-dive-load-value-injection#specialinstructions"
4233 " for more information");
4245void X86AsmParser::applyLVICFIMitigation(MCInst &Inst, MCStreamer &Out) {
4256 MCInst ShlInst, FenceInst;
4257 bool Parse32 = is32BitMode() || Code16GCC;
4258 MCRegister Basereg =
4259 is64BitMode() ? X86::RSP : (Parse32 ? X86::ESP : X86::SP);
4263 1, SMLoc{}, SMLoc{}, 0);
4265 ShlMemOp->addMemOperands(ShlInst, 5);
4278 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4290void X86AsmParser::applyLVILoadHardeningMitigation(MCInst &Inst,
4307 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4310 }
else if (Opcode == X86::REP_PREFIX || Opcode == X86::REPNE_PREFIX) {
4313 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4317 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
4335 getSTI().
hasFeature(X86::FeatureLVIControlFlowIntegrity))
4336 applyLVICFIMitigation(Inst, Out);
4341 getSTI().
hasFeature(X86::FeatureLVILoadHardening))
4342 applyLVILoadHardeningMitigation(Inst, Out);
4346 unsigned Result = 0;
4348 if (Prefix.isPrefix()) {
4349 Result = Prefix.getPrefix();
4355bool X86AsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
4357 MCStreamer &Out,
uint64_t &ErrorInfo,
4358 bool MatchingInlineAsm) {
4360 assert((*
Operands[0]).isToken() &&
"Leading operand should always be a mnemonic!");
4363 MatchFPUWaitAlias(IDLoc,
static_cast<X86Operand &
>(*
Operands[0]),
Operands,
4364 Out, MatchingInlineAsm);
4371 if (ForcedOpcodePrefix == OpcodePrefix_REX)
4373 else if (ForcedOpcodePrefix == OpcodePrefix_REX2)
4375 else if (ForcedOpcodePrefix == OpcodePrefix_VEX)
4377 else if (ForcedOpcodePrefix == OpcodePrefix_VEX2)
4379 else if (ForcedOpcodePrefix == OpcodePrefix_VEX3)
4381 else if (ForcedOpcodePrefix == OpcodePrefix_EVEX)
4385 if (ForcedDispEncoding == DispEncoding_Disp8)
4387 else if (ForcedDispEncoding == DispEncoding_Disp32)
4393 return isParsingIntelSyntax()
4394 ? matchAndEmitIntelInstruction(IDLoc, Opcode, Inst,
Operands, Out,
4395 ErrorInfo, MatchingInlineAsm)
4396 : matchAndEmitATTInstruction(IDLoc, Opcode, Inst,
Operands, Out,
4397 ErrorInfo, MatchingInlineAsm);
4400void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &
Op,
4402 bool MatchingInlineAsm) {
4406 const char *Repl = StringSwitch<const char *>(
Op.getToken())
4407 .Case(
"finit",
"fninit")
4408 .Case(
"fsave",
"fnsave")
4409 .Case(
"fstcw",
"fnstcw")
4410 .Case(
"fstcww",
"fnstcw")
4411 .Case(
"fstenv",
"fnstenv")
4412 .Case(
"fstsw",
"fnstsw")
4413 .Case(
"fstsww",
"fnstsw")
4414 .Case(
"fclex",
"fnclex")
4420 if (!MatchingInlineAsm)
4426bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc,
4427 const FeatureBitset &MissingFeatures,
4428 bool MatchingInlineAsm) {
4429 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
4430 SmallString<126>
Msg;
4431 raw_svector_ostream OS(
Msg);
4432 OS <<
"instruction requires:";
4433 for (
unsigned Feature : MissingFeatures)
4435 return Error(IDLoc, OS.str(), SMRange(), MatchingInlineAsm);
4438unsigned X86AsmParser::checkTargetMatchPredicate(MCInst &Inst) {
4440 const MCInstrDesc &MCID = MII.get(
Opc);
4444 return Match_Unsupported;
4446 return Match_Unsupported;
4448 switch (ForcedOpcodePrefix) {
4449 case OpcodePrefix_Default:
4451 case OpcodePrefix_REX:
4452 case OpcodePrefix_REX2:
4454 return Match_Unsupported;
4456 case OpcodePrefix_VEX:
4457 case OpcodePrefix_VEX2:
4458 case OpcodePrefix_VEX3:
4460 return Match_Unsupported;
4462 case OpcodePrefix_EVEX:
4464 !X86::isCMP(
Opc) && !X86::isTEST(
Opc))
4465 return Match_Unsupported;
4467 return Match_Unsupported;
4472 (ForcedOpcodePrefix != OpcodePrefix_VEX &&
4473 ForcedOpcodePrefix != OpcodePrefix_VEX2 &&
4474 ForcedOpcodePrefix != OpcodePrefix_VEX3))
4475 return Match_Unsupported;
4477 return Match_Success;
4480bool X86AsmParser::matchAndEmitATTInstruction(
4482 MCStreamer &Out,
uint64_t &ErrorInfo,
bool MatchingInlineAsm) {
4483 X86Operand &
Op =
static_cast<X86Operand &
>(*
Operands[0]);
4487 if (ForcedDataPrefix == X86::Is32Bit)
4488 SwitchMode(X86::Is32Bit);
4490 FeatureBitset MissingFeatures;
4491 unsigned OriginalError = MatchInstruction(
Operands, Inst, ErrorInfo,
4492 MissingFeatures, MatchingInlineAsm,
4493 isParsingIntelSyntax());
4494 if (ForcedDataPrefix == X86::Is32Bit) {
4495 SwitchMode(X86::Is16Bit);
4496 ForcedDataPrefix = 0;
4498 switch (OriginalError) {
4501 if (!MatchingInlineAsm && validateInstruction(Inst,
Operands))
4506 if (!MatchingInlineAsm)
4507 while (processInstruction(Inst,
Operands))
4511 if (!MatchingInlineAsm)
4515 case Match_InvalidImmUnsignedi4: {
4516 SMLoc ErrorLoc = ((X86Operand &)*
Operands[ErrorInfo]).getStartLoc();
4517 if (ErrorLoc == SMLoc())
4519 return Error(ErrorLoc,
"immediate must be an integer in range [0, 15]",
4520 EmptyRange, MatchingInlineAsm);
4522 case Match_InvalidImmUnsignedi6: {
4523 SMLoc ErrorLoc = ((X86Operand &)*
Operands[ErrorInfo]).getStartLoc();
4524 if (ErrorLoc == SMLoc())
4526 return Error(ErrorLoc,
"immediate must be an integer in range [0, 63]",
4527 EmptyRange, MatchingInlineAsm);
4529 case Match_MissingFeature:
4530 return ErrorMissingFeature(IDLoc, MissingFeatures, MatchingInlineAsm);
4531 case Match_InvalidOperand:
4532 case Match_MnemonicFail:
4533 case Match_Unsupported:
4536 if (
Op.getToken().empty()) {
4537 Error(IDLoc,
"instruction must have size higher than 0", EmptyRange,
4548 StringRef
Base =
Op.getToken();
4549 SmallString<16> Tmp;
4552 Op.setTokenValue(Tmp);
4560 const char *Suffixes =
Base[0] !=
'f' ?
"bwlq" :
"slt\0";
4562 const char *MemSize =
Base[0] !=
'f' ?
"\x08\x10\x20\x40" :
"\x20\x40\x50\0";
4566 FeatureBitset ErrorInfoMissingFeatures;
4574 bool HasVectorReg =
false;
4575 X86Operand *MemOp =
nullptr;
4577 X86Operand *X86Op =
static_cast<X86Operand *
>(
Op.get());
4579 HasVectorReg =
true;
4580 else if (X86Op->
isMem()) {
4582 assert(MemOp->Mem.Size == 0 &&
"Memory size always 0 under ATT syntax");
4589 for (
unsigned I = 0,
E = std::size(Match);
I !=
E; ++
I) {
4590 Tmp.
back() = Suffixes[
I];
4591 if (MemOp && HasVectorReg)
4592 MemOp->Mem.Size = MemSize[
I];
4593 Match[
I] = Match_MnemonicFail;
4594 if (MemOp || !HasVectorReg) {
4596 MatchInstruction(
Operands, Inst, ErrorInfoIgnore, MissingFeatures,
4597 MatchingInlineAsm, isParsingIntelSyntax());
4599 if (Match[
I] == Match_MissingFeature)
4600 ErrorInfoMissingFeatures = MissingFeatures;
4610 unsigned NumSuccessfulMatches =
llvm::count(Match, Match_Success);
4611 if (NumSuccessfulMatches == 1) {
4612 if (!MatchingInlineAsm && validateInstruction(Inst,
Operands))
4617 if (!MatchingInlineAsm)
4618 while (processInstruction(Inst,
Operands))
4622 if (!MatchingInlineAsm)
4632 if (NumSuccessfulMatches > 1) {
4634 unsigned NumMatches = 0;
4635 for (
unsigned I = 0,
E = std::size(Match);
I !=
E; ++
I)
4636 if (Match[
I] == Match_Success)
4637 MatchChars[NumMatches++] = Suffixes[
I];
4639 SmallString<126>
Msg;
4640 raw_svector_ostream OS(
Msg);
4641 OS <<
"ambiguous instructions require an explicit suffix (could be ";
4642 for (
unsigned i = 0; i != NumMatches; ++i) {
4645 if (i + 1 == NumMatches)
4647 OS <<
"'" <<
Base << MatchChars[i] <<
"'";
4650 Error(IDLoc, OS.str(), EmptyRange, MatchingInlineAsm);
4658 if (
llvm::count(Match, Match_MnemonicFail) == 4) {
4659 if (OriginalError == Match_MnemonicFail)
4660 return Error(IDLoc,
"invalid instruction mnemonic '" +
Base +
"'",
4661 Op.getLocRange(), MatchingInlineAsm);
4663 if (OriginalError == Match_Unsupported)
4664 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4667 assert(OriginalError == Match_InvalidOperand &&
"Unexpected error");
4669 if (ErrorInfo != ~0ULL) {
4671 return Error(IDLoc,
"too few operands for instruction", EmptyRange,
4674 X86Operand &Operand = (X86Operand &)*
Operands[ErrorInfo];
4678 OperandRange, MatchingInlineAsm);
4682 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4688 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4694 if (
llvm::count(Match, Match_MissingFeature) == 1) {
4695 ErrorInfo = Match_MissingFeature;
4696 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
4702 if (
llvm::count(Match, Match_InvalidOperand) == 1) {
4703 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4708 Error(IDLoc,
"unknown use of instruction mnemonic without a size suffix",
4709 EmptyRange, MatchingInlineAsm);
4713bool X86AsmParser::matchAndEmitIntelInstruction(
4715 MCStreamer &Out,
uint64_t &ErrorInfo,
bool MatchingInlineAsm) {
4716 X86Operand &
Op =
static_cast<X86Operand &
>(*
Operands[0]);
4721 const bool ForcedData32 = ForcedDataPrefix == X86::Is32Bit;
4722 auto RestoreMode = [&] {
4724 SwitchMode(X86::Is16Bit);
4725 ForcedDataPrefix = 0;
4729 SwitchMode(X86::Is32Bit);
4731 X86Operand *UnsizedMemOp =
nullptr;
4733 X86Operand *X86Op =
static_cast<X86Operand *
>(
Op.get());
4735 UnsizedMemOp = X86Op;
4746 static const char *
const PtrSizedInstrs[] = {
"call",
"jmp",
"push",
"pop"};
4747 for (
const char *Instr : PtrSizedInstrs) {
4748 if (Mnemonic == Instr) {
4749 UnsizedMemOp->
Mem.
Size = getPointerWidth();
4755 SmallVector<unsigned, 8> Match;
4756 FeatureBitset ErrorInfoMissingFeatures;
4757 FeatureBitset MissingFeatures;
4762 if (Mnemonic ==
"push" &&
Operands.size() == 2) {
4763 auto *X86Op =
static_cast<X86Operand *
>(
Operands[1].get());
4764 if (X86Op->
isImm()) {
4767 unsigned Size = getPointerWidth();
4770 SmallString<16> Tmp;
4772 Tmp += (is64BitMode())
4774 : (is32BitMode()) ?
"l" : (is16BitMode()) ?
"w" :
" ";
4775 Op.setTokenValue(Tmp);
4778 MissingFeatures, MatchingInlineAsm,
4789 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
4790 for (
unsigned Size : MopSizes) {
4794 unsigned M = MatchInstruction(
Operands, Inst, ErrorInfoIgnore,
4795 MissingFeatures, MatchingInlineAsm,
4796 isParsingIntelSyntax());
4801 if (Match.
back() == Match_MissingFeature)
4802 ErrorInfoMissingFeatures = MissingFeatures;
4812 if (Match.
empty()) {
4814 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,
4815 isParsingIntelSyntax()));
4817 if (Match.
back() == Match_MissingFeature)
4818 ErrorInfoMissingFeatures = MissingFeatures;
4826 if (Match.
back() == Match_MnemonicFail) {
4828 return Error(IDLoc,
"invalid instruction mnemonic '" + Mnemonic +
"'",
4829 Op.getLocRange(), MatchingInlineAsm);
4832 unsigned NumSuccessfulMatches =
llvm::count(Match, Match_Success);
4836 if (UnsizedMemOp && NumSuccessfulMatches > 1 &&
4839 unsigned M = MatchInstruction(
4840 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,
4841 isParsingIntelSyntax());
4842 if (M == Match_Success)
4843 NumSuccessfulMatches = 1;
4858 if (NumSuccessfulMatches == 1) {
4859 if (!MatchingInlineAsm && validateInstruction(Inst,
Operands))
4864 if (!MatchingInlineAsm)
4865 while (processInstruction(Inst,
Operands))
4868 if (!MatchingInlineAsm)
4872 }
else if (NumSuccessfulMatches > 1) {
4874 "multiple matches only possible with unsized memory operands");
4876 "ambiguous operand size for instruction '" + Mnemonic +
"\'",
4882 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4888 if (
llvm::count(Match, Match_MissingFeature) == 1) {
4889 ErrorInfo = Match_MissingFeature;
4890 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
4896 if (
llvm::count(Match, Match_InvalidOperand) == 1) {
4897 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4901 if (
llvm::count(Match, Match_InvalidImmUnsignedi4) == 1) {
4902 SMLoc ErrorLoc = ((X86Operand &)*
Operands[ErrorInfo]).getStartLoc();
4903 if (ErrorLoc == SMLoc())
4905 return Error(ErrorLoc,
"immediate must be an integer in range [0, 15]",
4906 EmptyRange, MatchingInlineAsm);
4909 if (
llvm::count(Match, Match_InvalidImmUnsignedi6) == 1) {
4910 SMLoc ErrorLoc = ((X86Operand &)*
Operands[ErrorInfo]).getStartLoc();
4911 if (ErrorLoc == SMLoc())
4913 return Error(ErrorLoc,
"immediate must be an integer in range [0, 63]",
4914 EmptyRange, MatchingInlineAsm);
4918 return Error(IDLoc,
"unknown instruction mnemonic", EmptyRange,
4922bool X86AsmParser::omitRegisterFromClobberLists(MCRegister
Reg) {
4923 return getX86MCRegisterClass(X86::SEGMENT_REGRegClassID).contains(
Reg);
4926bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
4927 MCAsmParser &Parser = getParser();
4930 return parseDirectiveArch();
4932 return ParseDirectiveCode(IDVal, DirectiveID.
getLoc());
4938 return Error(DirectiveID.
getLoc(),
"'.att_syntax noprefix' is not "
4939 "supported: registers must have a "
4940 "'%' prefix in .att_syntax");
4942 getParser().setAssemblerDialect(0);
4945 getParser().setAssemblerDialect(1);
4950 return Error(DirectiveID.
getLoc(),
"'.intel_syntax prefix' is not "
4951 "supported: registers must not have "
4952 "a '%' prefix in .intel_syntax");
4955 }
else if (IDVal ==
".nops")
4956 return parseDirectiveNops(DirectiveID.
getLoc());
4957 else if (IDVal ==
".even")
4958 return parseDirectiveEven(DirectiveID.
getLoc());
4959 else if (IDVal ==
".cv_fpo_proc")
4960 return parseDirectiveFPOProc(DirectiveID.
getLoc());
4961 else if (IDVal ==
".cv_fpo_setframe")
4962 return parseDirectiveFPOSetFrame(DirectiveID.
getLoc());
4963 else if (IDVal ==
".cv_fpo_pushreg")
4964 return parseDirectiveFPOPushReg(DirectiveID.
getLoc());
4965 else if (IDVal ==
".cv_fpo_stackalloc")
4966 return parseDirectiveFPOStackAlloc(DirectiveID.
getLoc());
4967 else if (IDVal ==
".cv_fpo_stackalign")
4968 return parseDirectiveFPOStackAlign(DirectiveID.
getLoc());
4969 else if (IDVal ==
".cv_fpo_endprologue")
4970 return parseDirectiveFPOEndPrologue(DirectiveID.
getLoc());
4971 else if (IDVal ==
".cv_fpo_endproc")
4972 return parseDirectiveFPOEndProc(DirectiveID.
getLoc());
4973 else if (IDVal ==
".seh_pushreg")
4974 return parseDirectiveSEHPushReg(DirectiveID.
getLoc());
4975 else if (IDVal ==
".seh_push2regs")
4976 return parseDirectiveSEHPush2Regs(DirectiveID.
getLoc());
4977 else if (IDVal ==
".seh_setframe")
4978 return parseDirectiveSEHSetFrame(DirectiveID.
getLoc());
4979 else if (IDVal ==
".seh_savereg")
4980 return parseDirectiveSEHSaveReg(DirectiveID.
getLoc());
4981 else if (IDVal ==
".seh_savexmm")
4982 return parseDirectiveSEHSaveXMM(DirectiveID.
getLoc());
4983 else if (IDVal ==
".seh_pushframe")
4984 return parseDirectiveSEHPushFrame(DirectiveID.
getLoc());
4988 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
4989 parseDirectiveSEHPushReg(DirectiveID.
getLoc());
4991 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
4992 parseDirectiveSEHPush2Regs(DirectiveID.
getLoc());
4994 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
4995 parseDirectiveSEHSetFrame(DirectiveID.
getLoc());
4997 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
4998 parseDirectiveSEHSaveReg(DirectiveID.
getLoc());
5000 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
5001 parseDirectiveSEHSaveXMM(DirectiveID.
getLoc());
5003 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
5004 parseDirectiveSEHPushFrame(DirectiveID.
getLoc());
5008 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
5009 parseDirectiveSEHPushReg(DirectiveID.
getLoc());
5013 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
5014 parseDirectiveSEHPush2Regs(DirectiveID.
getLoc(),
5017 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
5018 parseDirectiveSEHSetFrame(DirectiveID.
getLoc());
5020 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
5021 parseDirectiveSEHSaveReg(DirectiveID.
getLoc());
5023 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
5024 parseDirectiveSEHSaveXMM(DirectiveID.
getLoc());
5031bool X86AsmParser::parseDirectiveArch() {
5033 getParser().parseStringToEndOfStatement();
5039bool X86AsmParser::parseDirectiveNops(SMLoc L) {
5040 int64_t NumBytes = 0, Control = 0;
5041 SMLoc NumBytesLoc, ControlLoc;
5042 const MCSubtargetInfo& STI = getSTI();
5043 NumBytesLoc = getTok().getLoc();
5044 if (getParser().checkForValidSection() ||
5045 getParser().parseAbsoluteExpression(NumBytes))
5049 ControlLoc = getTok().getLoc();
5050 if (getParser().parseAbsoluteExpression(Control))
5053 if (getParser().parseEOL())
5056 if (NumBytes <= 0) {
5057 Error(NumBytesLoc,
"'.nops' directive with non-positive size");
5062 Error(ControlLoc,
"'.nops' directive with negative NOP size");
5067 getParser().getStreamer().emitNops(NumBytes, Control, L, STI);
5074bool X86AsmParser::parseDirectiveEven(SMLoc L) {
5078 const MCSection *
Section = getStreamer().getCurrentSectionOnly();
5080 getStreamer().initSections(getSTI());
5081 Section = getStreamer().getCurrentSectionOnly();
5083 if (
getContext().getAsmInfo().useCodeAlign(*Section))
5084 getStreamer().emitCodeAlignment(
Align(2), getSTI(), 0);
5086 getStreamer().emitValueToAlignment(
Align(2), 0, 1, 0);
5092bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
5093 MCAsmParser &Parser = getParser();
5095 if (IDVal ==
".code16") {
5097 if (!is16BitMode()) {
5098 SwitchMode(X86::Is16Bit);
5099 getTargetStreamer().emitCode16();
5101 }
else if (IDVal ==
".code16gcc") {
5105 if (!is16BitMode()) {
5106 SwitchMode(X86::Is16Bit);
5107 getTargetStreamer().emitCode16();
5109 }
else if (IDVal ==
".code32") {
5111 if (!is32BitMode()) {
5112 SwitchMode(X86::Is32Bit);
5113 getTargetStreamer().emitCode32();
5115 }
else if (IDVal ==
".code64") {
5117 if (!is64BitMode()) {
5118 SwitchMode(X86::Is64Bit);
5119 getTargetStreamer().emitCode64();
5122 Error(L,
"unknown directive " + IDVal);
5130bool X86AsmParser::parseDirectiveFPOProc(SMLoc L) {
5131 MCAsmParser &Parser = getParser();
5135 return Parser.
TokError(
"expected symbol name");
5136 if (Parser.
parseIntToken(ParamsSize,
"expected parameter byte count"))
5139 return Parser.
TokError(
"parameters size out of range");
5143 return getTargetStreamer().emitFPOProc(ProcSym, ParamsSize, L);
5147bool X86AsmParser::parseDirectiveFPOSetFrame(SMLoc L) {
5150 if (parseRegister(
Reg, DummyLoc, DummyLoc) || parseEOL())
5152 return getTargetStreamer().emitFPOSetFrame(
Reg, L);
5156bool X86AsmParser::parseDirectiveFPOPushReg(SMLoc L) {
5159 if (parseRegister(
Reg, DummyLoc, DummyLoc) || parseEOL())
5161 return getTargetStreamer().emitFPOPushReg(
Reg, L);
5165bool X86AsmParser::parseDirectiveFPOStackAlloc(SMLoc L) {
5166 MCAsmParser &Parser = getParser();
5170 return getTargetStreamer().emitFPOStackAlloc(
Offset, L);
5174bool X86AsmParser::parseDirectiveFPOStackAlign(SMLoc L) {
5175 MCAsmParser &Parser = getParser();
5179 return getTargetStreamer().emitFPOStackAlign(
Offset, L);
5183bool X86AsmParser::parseDirectiveFPOEndPrologue(SMLoc L) {
5184 MCAsmParser &Parser = getParser();
5187 return getTargetStreamer().emitFPOEndPrologue(L);
5191bool X86AsmParser::parseDirectiveFPOEndProc(SMLoc L) {
5192 MCAsmParser &Parser = getParser();
5195 return getTargetStreamer().emitFPOEndProc(L);
5198bool X86AsmParser::parseSEHRegisterNumber(
unsigned RegClassID,
5199 MCRegister &RegNo) {
5200 SMLoc startLoc = getLexer().getLoc();
5201 const MCRegisterInfo *MRI =
getContext().getRegisterInfo();
5206 if (parseRegister(RegNo, startLoc, endLoc))
5209 if (!getX86MCRegisterClass(RegClassID).
contains(RegNo)) {
5210 return Error(startLoc,
5211 "register is not supported for use with this directive");
5217 if (getParser().parseAbsoluteExpression(EncodedReg))
5222 RegNo = MCRegister();
5223 for (
MCPhysReg Reg : getX86MCRegisterClass(RegClassID)) {
5230 return Error(startLoc,
5231 "incorrect register number for use with this directive");
5238bool X86AsmParser::parseDirectiveSEHPushReg(SMLoc Loc) {
5240 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5244 return TokError(
"expected end of directive");
5247 getStreamer().emitWinCFIPushReg(
Reg, Loc);
5251bool X86AsmParser::parseDirectiveSEHPush2Regs(SMLoc Loc,
bool SwapRegs) {
5253 if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg1))
5257 return TokError(
"expected comma between registers");
5261 if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg2))
5265 return TokError(
"expected end of directive");
5271 getStreamer().emitWinCFIPush2Regs(Reg1, Reg2, Loc);
5275bool X86AsmParser::parseDirectiveSEHSetFrame(SMLoc Loc) {
5278 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5281 return TokError(
"you must specify a stack pointer offset");
5284 if (getParser().parseAbsoluteExpression(Off))
5288 return TokError(
"expected end of directive");
5291 getStreamer().emitWinCFISetFrame(
Reg, Off, Loc);
5295bool X86AsmParser::parseDirectiveSEHSaveReg(SMLoc Loc) {
5298 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5301 return TokError(
"you must specify an offset on the stack");
5304 if (getParser().parseAbsoluteExpression(Off))
5308 return TokError(
"expected end of directive");
5311 getStreamer().emitWinCFISaveReg(
Reg, Off, Loc);
5315bool X86AsmParser::parseDirectiveSEHSaveXMM(SMLoc Loc) {
5318 if (parseSEHRegisterNumber(X86::VR128XRegClassID,
Reg))
5321 return TokError(
"you must specify an offset on the stack");
5324 if (getParser().parseAbsoluteExpression(Off))
5328 return TokError(
"expected end of directive");
5331 getStreamer().emitWinCFISaveXMM(
Reg, Off, Loc);
5335bool X86AsmParser::ensureMasmPrologContext(SMLoc Loc) {
5336 if (getStreamer().isWinCFIPrologEnded()) {
5337 return Error(Loc,
"prolog directive must be used inside a prolog");
5342bool X86AsmParser::ensureMasmEpilogContext(SMLoc Loc) {
5343 if (!getStreamer().isInEpilogCFI()) {
5344 return Error(Loc,
"epilog directive must be used inside an epilog");
5349bool X86AsmParser::parseDirectiveSEHPushFrame(SMLoc Loc) {
5353 SMLoc startLoc = getLexer().getLoc();
5355 if (!getParser().parseIdentifier(CodeID)) {
5356 if (CodeID !=
"code")
5357 return Error(startLoc,
"expected @code");
5360 }
else if (getParser().isParsingMasm() &&
5362 getTok().getString().equals_insensitive(
"code")) {
5368 return TokError(
"expected end of directive");
5371 getStreamer().emitWinCFIPushFrame(Code, Loc);
5381#define GET_MATCHER_IMPLEMENTATION
5382#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