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()) {
3274 return Error(Loc,
"unexpected register in memory operand",
3275 SMRange(Loc, EndLoc));
3291 0, 0, 1, StartLoc, EndLoc));
3299 SMLoc BaseLoc = getLexer().getLoc();
3311 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ)
3312 return Error(BaseLoc,
"eiz and riz can only be used as index registers",
3313 SMRange(BaseLoc, EndLoc));
3331 if (!
E->evaluateAsAbsolute(ScaleVal, getStreamer().getAssemblerPtr()))
3332 return Error(Loc,
"expected absolute expression");
3334 Warning(Loc,
"scale factor without index register is ignored");
3339 if (BaseReg == X86::RIP)
3341 "%rip as base register can not have an index register");
3342 if (IndexReg == X86::RIP)
3343 return Error(Loc,
"%rip is not allowed as an index register");
3354 return Error(Loc,
"expected scale expression");
3355 Scale = (unsigned)ScaleVal;
3357 if (getX86MCRegisterClass(X86::GR16RegClassID).
contains(BaseReg) &&
3359 return Error(Loc,
"scale factor in 16-bit address must be 1");
3361 return Error(Loc, ErrMsg);
3375 if (BaseReg == X86::DX && !IndexReg && Scale == 1 && !SegReg &&
3384 return Error(BaseLoc, ErrMsg);
3386 if (CheckDispOverflow(BaseReg, IndexReg, Disp, BaseLoc))
3389 if (SegReg || BaseReg || IndexReg)
3391 BaseReg, IndexReg, Scale, StartLoc,
3400bool X86AsmParser::parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
3401 MCAsmParser &Parser = getParser();
3408 if (parseRegister(RegNo, StartLoc, EndLoc))
3416bool X86AsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
3418 MCAsmParser &Parser = getParser();
3422 ForcedOpcodePrefix = OpcodePrefix_Default;
3423 ForcedDispEncoding = DispEncoding_Default;
3424 UseApxExtendedReg =
false;
3425 ForcedNoFlag =
false;
3438 if (Prefix ==
"rex")
3439 ForcedOpcodePrefix = OpcodePrefix_REX;
3440 else if (Prefix ==
"rex2")
3441 ForcedOpcodePrefix = OpcodePrefix_REX2;
3442 else if (Prefix ==
"vex")
3443 ForcedOpcodePrefix = OpcodePrefix_VEX;
3444 else if (Prefix ==
"vex2")
3445 ForcedOpcodePrefix = OpcodePrefix_VEX2;
3446 else if (Prefix ==
"vex3")
3447 ForcedOpcodePrefix = OpcodePrefix_VEX3;
3448 else if (Prefix ==
"evex")
3449 ForcedOpcodePrefix = OpcodePrefix_EVEX;
3450 else if (Prefix ==
"disp8")
3451 ForcedDispEncoding = DispEncoding_Disp8;
3452 else if (Prefix ==
"disp32")
3453 ForcedDispEncoding = DispEncoding_Disp32;
3454 else if (Prefix ==
"nf")
3455 ForcedNoFlag =
true;
3457 return Error(NameLoc,
"unknown prefix");
3473 if (isParsingMSInlineAsm()) {
3474 if (
Name.equals_insensitive(
"vex"))
3475 ForcedOpcodePrefix = OpcodePrefix_VEX;
3476 else if (
Name.equals_insensitive(
"vex2"))
3477 ForcedOpcodePrefix = OpcodePrefix_VEX2;
3478 else if (
Name.equals_insensitive(
"vex3"))
3479 ForcedOpcodePrefix = OpcodePrefix_VEX3;
3480 else if (
Name.equals_insensitive(
"evex"))
3481 ForcedOpcodePrefix = OpcodePrefix_EVEX;
3483 if (ForcedOpcodePrefix != OpcodePrefix_Default) {
3496 if (
Name.consume_back(
".d32")) {
3497 ForcedDispEncoding = DispEncoding_Disp32;
3498 }
else if (
Name.consume_back(
".d8")) {
3499 ForcedDispEncoding = DispEncoding_Disp8;
3502 StringRef PatchedName =
Name;
3505 if (isParsingIntelSyntax() &&
3506 (PatchedName ==
"jmp" || PatchedName ==
"jc" || PatchedName ==
"jnc" ||
3507 PatchedName ==
"jcxz" || PatchedName ==
"jecxz" ||
3512 : NextTok ==
"short") {
3521 NextTok.
size() + 1);
3527 PatchedName !=
"setzub" && PatchedName !=
"setzunb" &&
3528 PatchedName !=
"setb" && PatchedName !=
"setnb")
3529 PatchedName = PatchedName.
substr(0,
Name.size()-1);
3531 unsigned ComparisonPredicate = ~0
U;
3539 bool IsVCMP = PatchedName[0] ==
'v';
3540 unsigned CCIdx =
IsVCMP ? 4 : 3;
3541 unsigned suffixLength = PatchedName.
ends_with(
"bf16") ? 5 : 2;
3542 unsigned CC = StringSwitch<unsigned>(
3543 PatchedName.
slice(CCIdx, PatchedName.
size() - suffixLength))
3545 .Case(
"eq_oq", 0x00)
3547 .Case(
"lt_os", 0x01)
3549 .Case(
"le_os", 0x02)
3550 .Case(
"unord", 0x03)
3551 .Case(
"unord_q", 0x03)
3553 .Case(
"neq_uq", 0x04)
3555 .Case(
"nlt_us", 0x05)
3557 .Case(
"nle_us", 0x06)
3559 .Case(
"ord_q", 0x07)
3561 .Case(
"eq_uq", 0x08)
3563 .Case(
"nge_us", 0x09)
3565 .Case(
"ngt_us", 0x0A)
3566 .Case(
"false", 0x0B)
3567 .Case(
"false_oq", 0x0B)
3568 .Case(
"neq_oq", 0x0C)
3570 .Case(
"ge_os", 0x0D)
3572 .Case(
"gt_os", 0x0E)
3574 .Case(
"true_uq", 0x0F)
3575 .Case(
"eq_os", 0x10)
3576 .Case(
"lt_oq", 0x11)
3577 .Case(
"le_oq", 0x12)
3578 .Case(
"unord_s", 0x13)
3579 .Case(
"neq_us", 0x14)
3580 .Case(
"nlt_uq", 0x15)
3581 .Case(
"nle_uq", 0x16)
3582 .Case(
"ord_s", 0x17)
3583 .Case(
"eq_us", 0x18)
3584 .Case(
"nge_uq", 0x19)
3585 .Case(
"ngt_uq", 0x1A)
3586 .Case(
"false_os", 0x1B)
3587 .Case(
"neq_os", 0x1C)
3588 .Case(
"ge_oq", 0x1D)
3589 .Case(
"gt_oq", 0x1E)
3590 .Case(
"true_us", 0x1F)
3592 if (CC != ~0U && (
IsVCMP || CC < 8) &&
3595 PatchedName =
IsVCMP ?
"vcmpss" :
"cmpss";
3597 PatchedName =
IsVCMP ?
"vcmpsd" :
"cmpsd";
3599 PatchedName =
IsVCMP ?
"vcmpps" :
"cmpps";
3601 PatchedName =
IsVCMP ?
"vcmppd" :
"cmppd";
3603 PatchedName =
"vcmpsh";
3605 PatchedName =
"vcmpph";
3607 PatchedName =
"vcmpbf16";
3611 ComparisonPredicate = CC;
3617 (PatchedName.
back() ==
'b' || PatchedName.
back() ==
'w' ||
3618 PatchedName.
back() ==
'd' || PatchedName.
back() ==
'q')) {
3619 unsigned SuffixSize = PatchedName.
drop_back().
back() ==
'u' ? 2 : 1;
3620 unsigned CC = StringSwitch<unsigned>(
3621 PatchedName.
slice(5, PatchedName.
size() - SuffixSize))
3631 if (CC != ~0U && (CC != 0 || SuffixSize == 2)) {
3632 switch (PatchedName.
back()) {
3634 case 'b': PatchedName = SuffixSize == 2 ?
"vpcmpub" :
"vpcmpb";
break;
3635 case 'w': PatchedName = SuffixSize == 2 ?
"vpcmpuw" :
"vpcmpw";
break;
3636 case 'd': PatchedName = SuffixSize == 2 ?
"vpcmpud" :
"vpcmpd";
break;
3637 case 'q': PatchedName = SuffixSize == 2 ?
"vpcmpuq" :
"vpcmpq";
break;
3640 ComparisonPredicate = CC;
3646 (PatchedName.
back() ==
'b' || PatchedName.
back() ==
'w' ||
3647 PatchedName.
back() ==
'd' || PatchedName.
back() ==
'q')) {
3648 unsigned SuffixSize = PatchedName.
drop_back().
back() ==
'u' ? 2 : 1;
3649 unsigned CC = StringSwitch<unsigned>(
3650 PatchedName.
slice(5, PatchedName.
size() - SuffixSize))
3661 switch (PatchedName.
back()) {
3663 case 'b': PatchedName = SuffixSize == 2 ?
"vpcomub" :
"vpcomb";
break;
3664 case 'w': PatchedName = SuffixSize == 2 ?
"vpcomuw" :
"vpcomw";
break;
3665 case 'd': PatchedName = SuffixSize == 2 ?
"vpcomud" :
"vpcomd";
break;
3666 case 'q': PatchedName = SuffixSize == 2 ?
"vpcomuq" :
"vpcomq";
break;
3669 ComparisonPredicate = CC;
3681 StringSwitch<bool>(Name)
3682 .Cases({
"cs",
"ds",
"es",
"fs",
"gs",
"ss"},
true)
3683 .Cases({
"rex64",
"data32",
"data16",
"addr32",
"addr16"},
true)
3684 .Cases({
"xacquire",
"xrelease"},
true)
3685 .Cases({
"acquire",
"release"}, isParsingIntelSyntax())
3688 auto isLockRepeatNtPrefix = [](StringRef
N) {
3689 return StringSwitch<bool>(
N)
3690 .Cases({
"lock",
"rep",
"repe",
"repz",
"repne",
"repnz",
"notrack"},
3695 bool CurlyAsEndOfStatement =
false;
3698 while (isLockRepeatNtPrefix(
Name.lower())) {
3700 StringSwitch<unsigned>(Name)
3719 while (
Name.starts_with(
";") ||
Name.starts_with(
"\n") ||
3720 Name.starts_with(
"#") ||
Name.starts_with(
"\t") ||
3721 Name.starts_with(
"/")) {
3732 if (PatchedName ==
"data16" && is16BitMode()) {
3733 return Error(NameLoc,
"redundant data16 prefix");
3735 if (PatchedName ==
"data32") {
3737 return Error(NameLoc,
"redundant data32 prefix");
3739 return Error(NameLoc,
"'data32' is not supported in 64-bit mode");
3741 PatchedName =
"data16";
3748 if (
Next ==
"callw")
3750 if (
Next ==
"ljmpw")
3755 ForcedDataPrefix = X86::Is32Bit;
3763 if (ComparisonPredicate != ~0U && !isParsingIntelSyntax()) {
3770 if ((
Name.starts_with(
"ccmp") ||
Name.starts_with(
"ctest")) &&
3799 CurlyAsEndOfStatement =
3800 isParsingIntelSyntax() && isParsingMSInlineAsm() &&
3803 return TokError(
"unexpected token in argument list");
3807 if (ComparisonPredicate != ~0U && isParsingIntelSyntax()) {
3817 else if (CurlyAsEndOfStatement)
3820 getLexer().getTok().getLoc(), 0);
3827 if (IsFp &&
Operands.size() == 1) {
3828 const char *Repl = StringSwitch<const char *>(Name)
3829 .Case(
"fsub",
"fsubp")
3830 .Case(
"fdiv",
"fdivp")
3831 .Case(
"fsubr",
"fsubrp")
3832 .Case(
"fdivr",
"fdivrp");
3833 static_cast<X86Operand &
>(*
Operands[0]).setTokenValue(Repl);
3836 if ((Name ==
"mov" || Name ==
"movw" || Name ==
"movl") &&
3838 X86Operand &Op1 = (X86Operand &)*
Operands[1];
3839 X86Operand &Op2 = (X86Operand &)*
Operands[2];
3844 getX86MCRegisterClass(X86::SEGMENT_REGRegClassID)
3846 (getX86MCRegisterClass(X86::GR16RegClassID).
contains(Op1.
getReg()) ||
3847 getX86MCRegisterClass(X86::GR32RegClassID).
contains(Op1.
getReg()))) {
3849 if (Name !=
"mov" && Name[3] == (is16BitMode() ?
'l' :
'w')) {
3850 Name = is16BitMode() ?
"movw" :
"movl";
3863 if ((Name ==
"outb" || Name ==
"outsb" || Name ==
"outw" || Name ==
"outsw" ||
3864 Name ==
"outl" || Name ==
"outsl" || Name ==
"out" || Name ==
"outs") &&
3866 X86Operand &
Op = (X86Operand &)*
Operands.back();
3872 if ((Name ==
"inb" || Name ==
"insb" || Name ==
"inw" || Name ==
"insw" ||
3873 Name ==
"inl" || Name ==
"insl" || Name ==
"in" || Name ==
"ins") &&
3882 bool HadVerifyError =
false;
3885 if (
Name.starts_with(
"ins") &&
3887 (Name ==
"insb" || Name ==
"insw" || Name ==
"insl" || Name ==
"insd" ||
3890 AddDefaultSrcDestOperands(TmpOperands,
3892 DefaultMemDIOperand(NameLoc));
3893 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3897 if (
Name.starts_with(
"outs") &&
3899 (Name ==
"outsb" || Name ==
"outsw" || Name ==
"outsl" ||
3900 Name ==
"outsd" || Name ==
"outs")) {
3901 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
3903 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3909 if (
Name.starts_with(
"lods") &&
3911 (Name ==
"lods" || Name ==
"lodsb" || Name ==
"lodsw" ||
3912 Name ==
"lodsl" || Name ==
"lodsd" || Name ==
"lodsq")) {
3913 TmpOperands.
push_back(DefaultMemSIOperand(NameLoc));
3914 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3920 if (
Name.starts_with(
"stos") &&
3922 (Name ==
"stos" || Name ==
"stosb" || Name ==
"stosw" ||
3923 Name ==
"stosl" || Name ==
"stosd" || Name ==
"stosq")) {
3924 TmpOperands.
push_back(DefaultMemDIOperand(NameLoc));
3925 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3931 if (
Name.starts_with(
"scas") &&
3933 (Name ==
"scas" || Name ==
"scasb" || Name ==
"scasw" ||
3934 Name ==
"scasl" || Name ==
"scasd" || Name ==
"scasq")) {
3935 TmpOperands.
push_back(DefaultMemDIOperand(NameLoc));
3936 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3940 if (
Name.starts_with(
"cmps") &&
3942 (Name ==
"cmps" || Name ==
"cmpsb" || Name ==
"cmpsw" ||
3943 Name ==
"cmpsl" || Name ==
"cmpsd" || Name ==
"cmpsq")) {
3944 AddDefaultSrcDestOperands(TmpOperands, DefaultMemDIOperand(NameLoc),
3945 DefaultMemSIOperand(NameLoc));
3946 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3950 if (((
Name.starts_with(
"movs") &&
3951 (Name ==
"movs" || Name ==
"movsb" || Name ==
"movsw" ||
3952 Name ==
"movsl" || Name ==
"movsd" || Name ==
"movsq")) ||
3953 (
Name.starts_with(
"smov") &&
3954 (Name ==
"smov" || Name ==
"smovb" || Name ==
"smovw" ||
3955 Name ==
"smovl" || Name ==
"smovd" || Name ==
"smovq"))) &&
3957 if (Name ==
"movsd" &&
Operands.size() == 1 && !isParsingIntelSyntax())
3959 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
3960 DefaultMemDIOperand(NameLoc));
3961 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3965 if (HadVerifyError) {
3966 return HadVerifyError;
3970 if ((Name ==
"xlat" || Name ==
"xlatb") &&
Operands.size() == 2) {
3971 X86Operand &Op1 =
static_cast<X86Operand &
>(*
Operands[1]);
3974 "size, (R|E)BX will be used for the location");
3976 static_cast<X86Operand &
>(*
Operands[0]).setTokenValue(
"xlatb");
3989 if (
I ==
Table.end() ||
I->OldOpc != Opcode)
3995 if (X86::isBLENDVPD(Opcode) || X86::isBLENDVPS(Opcode) ||
3996 X86::isPBLENDVB(Opcode))
4002bool X86AsmParser::processInstruction(MCInst &Inst,
const OperandVector &
Ops) {
4006 if (ForcedOpcodePrefix != OpcodePrefix_VEX3 &&
4013 auto replaceWithCCMPCTEST = [&](
unsigned Opcode) ->
bool {
4014 if (ForcedOpcodePrefix == OpcodePrefix_EVEX) {
4025 default:
return false;
4030 if (ForcedDispEncoding == DispEncoding_Disp32) {
4031 Inst.
setOpcode(is16BitMode() ? X86::JMP_2 : X86::JMP_4);
4040 if (ForcedDispEncoding == DispEncoding_Disp32) {
4041 Inst.
setOpcode(is16BitMode() ? X86::JCC_2 : X86::JCC_4);
4057#define FROM_TO(FROM, TO) \
4059 return replaceWithCCMPCTEST(X86::TO);
4061 FROM_TO(CMP64mi32, CCMP64mi32)
4064 FROM_TO(CMP64ri32, CCMP64ri32)
4091 FROM_TO(TEST64mi32, CTEST64mi32)
4093 FROM_TO(TEST64ri32, CTEST64ri32)
4113bool X86AsmParser::validateInstruction(MCInst &Inst,
const OperandVector &
Ops) {
4114 using namespace X86;
4115 const MCRegisterInfo *MRI =
getContext().getRegisterInfo();
4117 uint64_t TSFlags = MII.get(Opcode).TSFlags;
4118 if (isVFCMADDCPH(Opcode) || isVFCMADDCSH(Opcode) || isVFMADDCPH(Opcode) ||
4119 isVFMADDCSH(Opcode)) {
4123 return Warning(
Ops[0]->getStartLoc(),
"Destination register should be "
4124 "distinct from source registers");
4125 }
else if (isVFCMULCPH(Opcode) || isVFCMULCSH(Opcode) || isVFMULCPH(Opcode) ||
4126 isVFMULCSH(Opcode)) {
4136 return Warning(
Ops[0]->getStartLoc(),
"Destination register should be "
4137 "distinct from source registers");
4138 }
else if (isV4FMADDPS(Opcode) || isV4FMADDSS(Opcode) ||
4139 isV4FNMADDPS(Opcode) || isV4FNMADDSS(Opcode) ||
4140 isVP4DPWSSDS(Opcode) || isVP4DPWSSD(Opcode)) {
4145 if (Src2Enc % 4 != 0) {
4147 unsigned GroupStart = (Src2Enc / 4) * 4;
4148 unsigned GroupEnd = GroupStart + 3;
4150 "source register '" +
RegName +
"' implicitly denotes '" +
4151 RegName.take_front(3) + Twine(GroupStart) +
"' to '" +
4152 RegName.take_front(3) + Twine(GroupEnd) +
4155 }
else if (isVGATHERDPD(Opcode) || isVGATHERDPS(Opcode) ||
4156 isVGATHERQPD(Opcode) || isVGATHERQPS(Opcode) ||
4157 isVPGATHERDD(Opcode) || isVPGATHERDQ(Opcode) ||
4158 isVPGATHERQD(Opcode) || isVPGATHERQQ(Opcode)) {
4165 return Warning(
Ops[0]->getStartLoc(),
"index and destination registers "
4166 "should be distinct");
4172 if (Dest == Mask || Dest == Index || Mask == Index)
4173 return Warning(
Ops[0]->getStartLoc(),
"mask, index, and destination "
4174 "registers should be distinct");
4176 }
else if (isTCMMIMFP16PS(Opcode) || isTCMMRLFP16PS(Opcode) ||
4177 isTDPBF16PS(Opcode) || isTDPFP16PS(Opcode) || isTDPBSSD(Opcode) ||
4178 isTDPBSUD(Opcode) || isTDPBUSD(Opcode) || isTDPBUUD(Opcode)) {
4182 if (SrcDest == Src1 || SrcDest == Src2 || Src1 == Src2)
4183 return Error(
Ops[0]->getStartLoc(),
"all tmm registers must be distinct");
4197 for (
unsigned i = 0; i !=
NumOps; ++i) {
4202 if (
Reg == X86::AH ||
Reg == X86::BH ||
Reg == X86::CH ||
Reg == X86::DH)
4210 (Enc ==
X86II::EVEX || ForcedOpcodePrefix == OpcodePrefix_REX2 ||
4211 ForcedOpcodePrefix == OpcodePrefix_REX || UsesRex)) {
4213 return Error(
Ops[0]->getStartLoc(),
4214 "can't encode '" +
RegName.str() +
4215 "' in an instruction requiring EVEX/REX2/REX prefix");
4219 if ((Opcode == X86::PREFETCHIT0 || Opcode == X86::PREFETCHIT1)) {
4223 Ops[0]->getStartLoc(),
4224 Twine((Inst.
getOpcode() == X86::PREFETCHIT0 ?
"'prefetchit0'"
4225 :
"'prefetchit1'")) +
4226 " only supports RIP-relative address");
4231void X86AsmParser::emitWarningForSpecialLVIInstruction(SMLoc Loc) {
4232 Warning(Loc,
"Instruction may be vulnerable to LVI and "
4233 "requires manual mitigation");
4234 Note(SMLoc(),
"See https://software.intel.com/"
4235 "security-software-guidance/insights/"
4236 "deep-dive-load-value-injection#specialinstructions"
4237 " for more information");
4249void X86AsmParser::applyLVICFIMitigation(MCInst &Inst, MCStreamer &Out) {
4260 MCInst ShlInst, FenceInst;
4261 bool Parse32 = is32BitMode() || Code16GCC;
4262 MCRegister Basereg =
4263 is64BitMode() ? X86::RSP : (Parse32 ? X86::ESP : X86::SP);
4267 1, SMLoc{}, SMLoc{}, 0);
4269 ShlMemOp->addMemOperands(ShlInst, 5);
4272 Out.emitInstruction(ShlInst, getSTI());
4273 Out.emitInstruction(FenceInst, getSTI());
4282 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4294void X86AsmParser::applyLVILoadHardeningMitigation(MCInst &Inst,
4311 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4314 }
else if (Opcode == X86::REP_PREFIX || Opcode == X86::REPNE_PREFIX) {
4317 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4321 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
4332 Out.emitInstruction(FenceInst, getSTI());
4339 getSTI().
hasFeature(X86::FeatureLVIControlFlowIntegrity))
4340 applyLVICFIMitigation(Inst, Out);
4342 Out.emitInstruction(Inst, getSTI());
4345 getSTI().
hasFeature(X86::FeatureLVILoadHardening))
4346 applyLVILoadHardeningMitigation(Inst, Out);
4350 unsigned Result = 0;
4352 if (Prefix.isPrefix()) {
4353 Result = Prefix.getPrefix();
4359bool X86AsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
4361 MCStreamer &Out,
uint64_t &ErrorInfo,
4362 bool MatchingInlineAsm) {
4364 assert((*
Operands[0]).isToken() &&
"Leading operand should always be a mnemonic!");
4367 MatchFPUWaitAlias(IDLoc,
static_cast<X86Operand &
>(*
Operands[0]),
Operands,
4368 Out, MatchingInlineAsm);
4375 if (ForcedOpcodePrefix == OpcodePrefix_REX)
4377 else if (ForcedOpcodePrefix == OpcodePrefix_REX2)
4379 else if (ForcedOpcodePrefix == OpcodePrefix_VEX)
4381 else if (ForcedOpcodePrefix == OpcodePrefix_VEX2)
4383 else if (ForcedOpcodePrefix == OpcodePrefix_VEX3)
4385 else if (ForcedOpcodePrefix == OpcodePrefix_EVEX)
4389 if (ForcedDispEncoding == DispEncoding_Disp8)
4391 else if (ForcedDispEncoding == DispEncoding_Disp32)
4397 return isParsingIntelSyntax()
4398 ? matchAndEmitIntelInstruction(IDLoc, Opcode, Inst,
Operands, Out,
4399 ErrorInfo, MatchingInlineAsm)
4400 : matchAndEmitATTInstruction(IDLoc, Opcode, Inst,
Operands,
Out,
4401 ErrorInfo, MatchingInlineAsm);
4404void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &
Op,
4406 bool MatchingInlineAsm) {
4410 const char *Repl = StringSwitch<const char *>(
Op.getToken())
4411 .Case(
"finit",
"fninit")
4412 .Case(
"fsave",
"fnsave")
4413 .Case(
"fstcw",
"fnstcw")
4414 .Case(
"fstcww",
"fnstcw")
4415 .Case(
"fstenv",
"fnstenv")
4416 .Case(
"fstsw",
"fnstsw")
4417 .Case(
"fstsww",
"fnstsw")
4418 .Case(
"fclex",
"fnclex")
4424 if (!MatchingInlineAsm)
4430bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc,
4431 const FeatureBitset &MissingFeatures,
4432 bool MatchingInlineAsm) {
4433 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
4434 SmallString<126>
Msg;
4435 raw_svector_ostream OS(
Msg);
4436 OS <<
"instruction requires:";
4437 for (
unsigned Feature : MissingFeatures)
4439 return Error(IDLoc, OS.str(), SMRange(), MatchingInlineAsm);
4442unsigned X86AsmParser::checkTargetMatchPredicate(MCInst &Inst) {
4444 const MCInstrDesc &MCID = MII.get(
Opc);
4448 return Match_Unsupported;
4450 return Match_Unsupported;
4452 switch (ForcedOpcodePrefix) {
4453 case OpcodePrefix_Default:
4455 case OpcodePrefix_REX:
4456 case OpcodePrefix_REX2:
4458 return Match_Unsupported;
4460 case OpcodePrefix_VEX:
4461 case OpcodePrefix_VEX2:
4462 case OpcodePrefix_VEX3:
4464 return Match_Unsupported;
4466 case OpcodePrefix_EVEX:
4468 !X86::isCMP(
Opc) && !X86::isTEST(
Opc))
4469 return Match_Unsupported;
4471 return Match_Unsupported;
4476 (ForcedOpcodePrefix != OpcodePrefix_VEX &&
4477 ForcedOpcodePrefix != OpcodePrefix_VEX2 &&
4478 ForcedOpcodePrefix != OpcodePrefix_VEX3))
4479 return Match_Unsupported;
4481 return Match_Success;
4484bool X86AsmParser::matchAndEmitATTInstruction(
4486 MCStreamer &Out,
uint64_t &ErrorInfo,
bool MatchingInlineAsm) {
4487 X86Operand &
Op =
static_cast<X86Operand &
>(*
Operands[0]);
4491 if (ForcedDataPrefix == X86::Is32Bit)
4492 SwitchMode(X86::Is32Bit);
4494 FeatureBitset MissingFeatures;
4495 unsigned OriginalError = MatchInstruction(
Operands, Inst, ErrorInfo,
4496 MissingFeatures, MatchingInlineAsm,
4497 isParsingIntelSyntax());
4498 if (ForcedDataPrefix == X86::Is32Bit) {
4499 SwitchMode(X86::Is16Bit);
4500 ForcedDataPrefix = 0;
4502 switch (OriginalError) {
4505 if (!MatchingInlineAsm && validateInstruction(Inst,
Operands))
4510 if (!MatchingInlineAsm)
4511 while (processInstruction(Inst,
Operands))
4515 if (!MatchingInlineAsm)
4519 case Match_InvalidImmUnsignedi4: {
4520 SMLoc ErrorLoc = ((X86Operand &)*
Operands[ErrorInfo]).getStartLoc();
4521 if (ErrorLoc == SMLoc())
4523 return Error(ErrorLoc,
"immediate must be an integer in range [0, 15]",
4524 EmptyRange, MatchingInlineAsm);
4526 case Match_InvalidImmUnsignedi6: {
4527 SMLoc ErrorLoc = ((X86Operand &)*
Operands[ErrorInfo]).getStartLoc();
4528 if (ErrorLoc == SMLoc())
4530 return Error(ErrorLoc,
"immediate must be an integer in range [0, 63]",
4531 EmptyRange, MatchingInlineAsm);
4533 case Match_MissingFeature:
4534 return ErrorMissingFeature(IDLoc, MissingFeatures, MatchingInlineAsm);
4535 case Match_InvalidOperand:
4536 case Match_MnemonicFail:
4537 case Match_Unsupported:
4540 if (
Op.getToken().empty()) {
4541 Error(IDLoc,
"instruction must have size higher than 0", EmptyRange,
4552 StringRef
Base =
Op.getToken();
4553 SmallString<16> Tmp;
4556 Op.setTokenValue(Tmp);
4564 const char *Suffixes =
Base[0] !=
'f' ?
"bwlq" :
"slt\0";
4566 const char *MemSize =
Base[0] !=
'f' ?
"\x08\x10\x20\x40" :
"\x20\x40\x50\0";
4570 FeatureBitset ErrorInfoMissingFeatures;
4578 bool HasVectorReg =
false;
4579 X86Operand *MemOp =
nullptr;
4581 X86Operand *X86Op =
static_cast<X86Operand *
>(
Op.get());
4583 HasVectorReg =
true;
4584 else if (X86Op->
isMem()) {
4586 assert(MemOp->Mem.Size == 0 &&
"Memory size always 0 under ATT syntax");
4593 for (
unsigned I = 0,
E = std::size(Match);
I !=
E; ++
I) {
4594 Tmp.
back() = Suffixes[
I];
4595 if (MemOp && HasVectorReg)
4596 MemOp->Mem.Size = MemSize[
I];
4597 Match[
I] = Match_MnemonicFail;
4598 if (MemOp || !HasVectorReg) {
4600 MatchInstruction(
Operands, Inst, ErrorInfoIgnore, MissingFeatures,
4601 MatchingInlineAsm, isParsingIntelSyntax());
4603 if (Match[
I] == Match_MissingFeature)
4604 ErrorInfoMissingFeatures = MissingFeatures;
4614 unsigned NumSuccessfulMatches =
llvm::count(Match, Match_Success);
4615 if (NumSuccessfulMatches == 1) {
4616 if (!MatchingInlineAsm && validateInstruction(Inst,
Operands))
4621 if (!MatchingInlineAsm)
4622 while (processInstruction(Inst,
Operands))
4626 if (!MatchingInlineAsm)
4636 if (NumSuccessfulMatches > 1) {
4638 unsigned NumMatches = 0;
4639 for (
unsigned I = 0,
E = std::size(Match);
I !=
E; ++
I)
4640 if (Match[
I] == Match_Success)
4641 MatchChars[NumMatches++] = Suffixes[
I];
4643 SmallString<126>
Msg;
4644 raw_svector_ostream OS(
Msg);
4645 OS <<
"ambiguous instructions require an explicit suffix (could be ";
4646 for (
unsigned i = 0; i != NumMatches; ++i) {
4649 if (i + 1 == NumMatches)
4651 OS <<
"'" <<
Base << MatchChars[i] <<
"'";
4654 Error(IDLoc, OS.str(), EmptyRange, MatchingInlineAsm);
4662 if (
llvm::count(Match, Match_MnemonicFail) == 4) {
4663 if (OriginalError == Match_MnemonicFail)
4664 return Error(IDLoc,
"invalid instruction mnemonic '" +
Base +
"'",
4665 Op.getLocRange(), MatchingInlineAsm);
4667 if (OriginalError == Match_Unsupported)
4668 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4671 assert(OriginalError == Match_InvalidOperand &&
"Unexpected error");
4673 if (ErrorInfo != ~0ULL) {
4675 return Error(IDLoc,
"too few operands for instruction", EmptyRange,
4678 X86Operand &Operand = (X86Operand &)*
Operands[ErrorInfo];
4682 OperandRange, MatchingInlineAsm);
4686 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4692 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4698 if (
llvm::count(Match, Match_MissingFeature) == 1) {
4699 ErrorInfo = Match_MissingFeature;
4700 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
4706 if (
llvm::count(Match, Match_InvalidOperand) == 1) {
4707 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4712 Error(IDLoc,
"unknown use of instruction mnemonic without a size suffix",
4713 EmptyRange, MatchingInlineAsm);
4717bool X86AsmParser::matchAndEmitIntelInstruction(
4719 MCStreamer &Out,
uint64_t &ErrorInfo,
bool MatchingInlineAsm) {
4720 X86Operand &
Op =
static_cast<X86Operand &
>(*
Operands[0]);
4725 const bool ForcedData32 = ForcedDataPrefix == X86::Is32Bit;
4726 auto RestoreMode = [&] {
4728 SwitchMode(X86::Is16Bit);
4729 ForcedDataPrefix = 0;
4733 SwitchMode(X86::Is32Bit);
4735 X86Operand *UnsizedMemOp =
nullptr;
4737 X86Operand *X86Op =
static_cast<X86Operand *
>(
Op.get());
4739 UnsizedMemOp = X86Op;
4750 static const char *
const PtrSizedInstrs[] = {
"call",
"jmp",
"push",
"pop"};
4751 for (
const char *Instr : PtrSizedInstrs) {
4752 if (Mnemonic == Instr) {
4753 UnsizedMemOp->
Mem.
Size = getPointerWidth();
4759 SmallVector<unsigned, 8> Match;
4760 FeatureBitset ErrorInfoMissingFeatures;
4761 FeatureBitset MissingFeatures;
4766 if (Mnemonic ==
"push" &&
Operands.size() == 2) {
4767 auto *X86Op =
static_cast<X86Operand *
>(
Operands[1].get());
4768 if (X86Op->
isImm()) {
4771 unsigned Size = getPointerWidth();
4774 SmallString<16> Tmp;
4776 Tmp += (is64BitMode())
4778 : (is32BitMode()) ?
"l" : (is16BitMode()) ?
"w" :
" ";
4779 Op.setTokenValue(Tmp);
4782 MissingFeatures, MatchingInlineAsm,
4793 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
4794 for (
unsigned Size : MopSizes) {
4798 unsigned M = MatchInstruction(
Operands, Inst, ErrorInfoIgnore,
4799 MissingFeatures, MatchingInlineAsm,
4800 isParsingIntelSyntax());
4805 if (Match.
back() == Match_MissingFeature)
4806 ErrorInfoMissingFeatures = MissingFeatures;
4816 if (Match.
empty()) {
4818 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,
4819 isParsingIntelSyntax()));
4821 if (Match.
back() == Match_MissingFeature)
4822 ErrorInfoMissingFeatures = MissingFeatures;
4830 if (Match.
back() == Match_MnemonicFail) {
4832 return Error(IDLoc,
"invalid instruction mnemonic '" + Mnemonic +
"'",
4833 Op.getLocRange(), MatchingInlineAsm);
4836 unsigned NumSuccessfulMatches =
llvm::count(Match, Match_Success);
4840 if (UnsizedMemOp && NumSuccessfulMatches > 1 &&
4843 unsigned M = MatchInstruction(
4844 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,
4845 isParsingIntelSyntax());
4846 if (M == Match_Success)
4847 NumSuccessfulMatches = 1;
4862 if (NumSuccessfulMatches == 1) {
4863 if (!MatchingInlineAsm && validateInstruction(Inst,
Operands))
4868 if (!MatchingInlineAsm)
4869 while (processInstruction(Inst,
Operands))
4872 if (!MatchingInlineAsm)
4876 }
else if (NumSuccessfulMatches > 1) {
4878 "multiple matches only possible with unsized memory operands");
4880 "ambiguous operand size for instruction '" + Mnemonic +
"\'",
4886 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4892 if (
llvm::count(Match, Match_MissingFeature) == 1) {
4893 ErrorInfo = Match_MissingFeature;
4894 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
4900 if (
llvm::count(Match, Match_InvalidOperand) == 1) {
4901 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4905 if (
llvm::count(Match, Match_InvalidImmUnsignedi4) == 1) {
4906 SMLoc ErrorLoc = ((X86Operand &)*
Operands[ErrorInfo]).getStartLoc();
4907 if (ErrorLoc == SMLoc())
4909 return Error(ErrorLoc,
"immediate must be an integer in range [0, 15]",
4910 EmptyRange, MatchingInlineAsm);
4913 if (
llvm::count(Match, Match_InvalidImmUnsignedi6) == 1) {
4914 SMLoc ErrorLoc = ((X86Operand &)*
Operands[ErrorInfo]).getStartLoc();
4915 if (ErrorLoc == SMLoc())
4917 return Error(ErrorLoc,
"immediate must be an integer in range [0, 63]",
4918 EmptyRange, MatchingInlineAsm);
4922 return Error(IDLoc,
"unknown instruction mnemonic", EmptyRange,
4926bool X86AsmParser::omitRegisterFromClobberLists(MCRegister
Reg) {
4927 return getX86MCRegisterClass(X86::SEGMENT_REGRegClassID).contains(
Reg);
4930bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
4931 MCAsmParser &Parser = getParser();
4934 return parseDirectiveArch();
4936 return ParseDirectiveCode(IDVal, DirectiveID.
getLoc());
4942 return Error(DirectiveID.
getLoc(),
"'.att_syntax noprefix' is not "
4943 "supported: registers must have a "
4944 "'%' prefix in .att_syntax");
4946 getParser().setAssemblerDialect(0);
4949 getParser().setAssemblerDialect(1);
4954 return Error(DirectiveID.
getLoc(),
"'.intel_syntax prefix' is not "
4955 "supported: registers must not have "
4956 "a '%' prefix in .intel_syntax");
4959 }
else if (IDVal ==
".nops")
4960 return parseDirectiveNops(DirectiveID.
getLoc());
4961 else if (IDVal ==
".even")
4962 return parseDirectiveEven(DirectiveID.
getLoc());
4963 else if (IDVal ==
".cv_fpo_proc")
4964 return parseDirectiveFPOProc(DirectiveID.
getLoc());
4965 else if (IDVal ==
".cv_fpo_setframe")
4966 return parseDirectiveFPOSetFrame(DirectiveID.
getLoc());
4967 else if (IDVal ==
".cv_fpo_pushreg")
4968 return parseDirectiveFPOPushReg(DirectiveID.
getLoc());
4969 else if (IDVal ==
".cv_fpo_stackalloc")
4970 return parseDirectiveFPOStackAlloc(DirectiveID.
getLoc());
4971 else if (IDVal ==
".cv_fpo_stackalign")
4972 return parseDirectiveFPOStackAlign(DirectiveID.
getLoc());
4973 else if (IDVal ==
".cv_fpo_endprologue")
4974 return parseDirectiveFPOEndPrologue(DirectiveID.
getLoc());
4975 else if (IDVal ==
".cv_fpo_endproc")
4976 return parseDirectiveFPOEndProc(DirectiveID.
getLoc());
4977 else if (IDVal ==
".seh_pushreg")
4978 return parseDirectiveSEHPushReg(DirectiveID.
getLoc());
4979 else if (IDVal ==
".seh_push2regs")
4980 return parseDirectiveSEHPush2Regs(DirectiveID.
getLoc());
4981 else if (IDVal ==
".seh_setframe")
4982 return parseDirectiveSEHSetFrame(DirectiveID.
getLoc());
4983 else if (IDVal ==
".seh_savereg")
4984 return parseDirectiveSEHSaveReg(DirectiveID.
getLoc());
4985 else if (IDVal ==
".seh_savexmm")
4986 return parseDirectiveSEHSaveXMM(DirectiveID.
getLoc());
4987 else if (IDVal ==
".seh_pushframe")
4988 return parseDirectiveSEHPushFrame(DirectiveID.
getLoc());
4992 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
4993 parseDirectiveSEHPushReg(DirectiveID.
getLoc());
4995 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
4996 parseDirectiveSEHPush2Regs(DirectiveID.
getLoc());
4998 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
4999 parseDirectiveSEHSetFrame(DirectiveID.
getLoc());
5001 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
5002 parseDirectiveSEHSaveReg(DirectiveID.
getLoc());
5004 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
5005 parseDirectiveSEHSaveXMM(DirectiveID.
getLoc());
5007 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
5008 parseDirectiveSEHPushFrame(DirectiveID.
getLoc());
5012 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
5013 parseDirectiveSEHPushReg(DirectiveID.
getLoc());
5017 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
5018 parseDirectiveSEHPush2Regs(DirectiveID.
getLoc(),
5021 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
5022 parseDirectiveSEHSetFrame(DirectiveID.
getLoc());
5024 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
5025 parseDirectiveSEHSaveReg(DirectiveID.
getLoc());
5027 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
5028 parseDirectiveSEHSaveXMM(DirectiveID.
getLoc());
5035bool X86AsmParser::parseDirectiveArch() {
5037 getParser().parseStringToEndOfStatement();
5043bool X86AsmParser::parseDirectiveNops(SMLoc L) {
5044 int64_t NumBytes = 0, Control = 0;
5045 SMLoc NumBytesLoc, ControlLoc;
5046 const MCSubtargetInfo& STI = getSTI();
5047 NumBytesLoc = getTok().getLoc();
5048 if (getParser().checkForValidSection() ||
5049 getParser().parseAbsoluteExpression(NumBytes))
5053 ControlLoc = getTok().getLoc();
5054 if (getParser().parseAbsoluteExpression(Control))
5057 if (getParser().parseEOL())
5060 if (NumBytes <= 0) {
5061 Error(NumBytesLoc,
"'.nops' directive with non-positive size");
5066 Error(ControlLoc,
"'.nops' directive with negative NOP size");
5071 getParser().getStreamer().emitNops(NumBytes, Control, L, STI);
5078bool X86AsmParser::parseDirectiveEven(SMLoc L) {
5082 const MCSection *
Section = getStreamer().getCurrentSectionOnly();
5084 getStreamer().initSections(getSTI());
5085 Section = getStreamer().getCurrentSectionOnly();
5087 if (
getContext().getAsmInfo().useCodeAlign(*Section))
5088 getStreamer().emitCodeAlignment(
Align(2), getSTI(), 0);
5090 getStreamer().emitValueToAlignment(
Align(2), 0, 1, 0);
5096bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
5097 MCAsmParser &Parser = getParser();
5099 if (IDVal ==
".code16") {
5101 if (!is16BitMode()) {
5102 SwitchMode(X86::Is16Bit);
5103 getTargetStreamer().emitCode16();
5105 }
else if (IDVal ==
".code16gcc") {
5109 if (!is16BitMode()) {
5110 SwitchMode(X86::Is16Bit);
5111 getTargetStreamer().emitCode16();
5113 }
else if (IDVal ==
".code32") {
5115 if (!is32BitMode()) {
5116 SwitchMode(X86::Is32Bit);
5117 getTargetStreamer().emitCode32();
5119 }
else if (IDVal ==
".code64") {
5121 if (!is64BitMode()) {
5122 SwitchMode(X86::Is64Bit);
5123 getTargetStreamer().emitCode64();
5126 Error(L,
"unknown directive " + IDVal);
5134bool X86AsmParser::parseDirectiveFPOProc(SMLoc L) {
5135 MCAsmParser &Parser = getParser();
5139 return Parser.
TokError(
"expected symbol name");
5140 if (Parser.
parseIntToken(ParamsSize,
"expected parameter byte count"))
5143 return Parser.
TokError(
"parameters size out of range");
5147 return getTargetStreamer().emitFPOProc(ProcSym, ParamsSize, L);
5151bool X86AsmParser::parseDirectiveFPOSetFrame(SMLoc L) {
5154 if (parseRegister(
Reg, DummyLoc, DummyLoc) || parseEOL())
5156 return getTargetStreamer().emitFPOSetFrame(
Reg, L);
5160bool X86AsmParser::parseDirectiveFPOPushReg(SMLoc L) {
5163 if (parseRegister(
Reg, DummyLoc, DummyLoc) || parseEOL())
5165 return getTargetStreamer().emitFPOPushReg(
Reg, L);
5169bool X86AsmParser::parseDirectiveFPOStackAlloc(SMLoc L) {
5170 MCAsmParser &Parser = getParser();
5174 return getTargetStreamer().emitFPOStackAlloc(
Offset, L);
5178bool X86AsmParser::parseDirectiveFPOStackAlign(SMLoc L) {
5179 MCAsmParser &Parser = getParser();
5183 return getTargetStreamer().emitFPOStackAlign(
Offset, L);
5187bool X86AsmParser::parseDirectiveFPOEndPrologue(SMLoc L) {
5188 MCAsmParser &Parser = getParser();
5191 return getTargetStreamer().emitFPOEndPrologue(L);
5195bool X86AsmParser::parseDirectiveFPOEndProc(SMLoc L) {
5196 MCAsmParser &Parser = getParser();
5199 return getTargetStreamer().emitFPOEndProc(L);
5202bool X86AsmParser::parseSEHRegisterNumber(
unsigned RegClassID,
5203 MCRegister &RegNo) {
5204 SMLoc startLoc = getLexer().getLoc();
5205 const MCRegisterInfo *MRI =
getContext().getRegisterInfo();
5210 if (parseRegister(RegNo, startLoc, endLoc))
5213 if (!getX86MCRegisterClass(RegClassID).
contains(RegNo)) {
5214 return Error(startLoc,
5215 "register is not supported for use with this directive");
5221 if (getParser().parseAbsoluteExpression(EncodedReg))
5226 RegNo = MCRegister();
5227 for (
MCPhysReg Reg : getX86MCRegisterClass(RegClassID)) {
5234 return Error(startLoc,
5235 "incorrect register number for use with this directive");
5242bool X86AsmParser::parseDirectiveSEHPushReg(SMLoc Loc) {
5244 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5248 return TokError(
"expected end of directive");
5251 getStreamer().emitWinCFIPushReg(
Reg, Loc);
5255bool X86AsmParser::parseDirectiveSEHPush2Regs(SMLoc Loc,
bool SwapRegs) {
5257 if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg1))
5261 return TokError(
"expected comma between registers");
5265 if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg2))
5269 return TokError(
"expected end of directive");
5275 getStreamer().emitWinCFIPush2Regs(Reg1, Reg2, Loc);
5279bool X86AsmParser::parseDirectiveSEHSetFrame(SMLoc Loc) {
5282 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5285 return TokError(
"you must specify a stack pointer offset");
5288 if (getParser().parseAbsoluteExpression(Off))
5292 return TokError(
"expected end of directive");
5295 getStreamer().emitWinCFISetFrame(
Reg, Off, Loc);
5299bool X86AsmParser::parseDirectiveSEHSaveReg(SMLoc Loc) {
5302 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5305 return TokError(
"you must specify an offset on the stack");
5308 if (getParser().parseAbsoluteExpression(Off))
5312 return TokError(
"expected end of directive");
5315 getStreamer().emitWinCFISaveReg(
Reg, Off, Loc);
5319bool X86AsmParser::parseDirectiveSEHSaveXMM(SMLoc Loc) {
5322 if (parseSEHRegisterNumber(X86::VR128XRegClassID,
Reg))
5325 return TokError(
"you must specify an offset on the stack");
5328 if (getParser().parseAbsoluteExpression(Off))
5332 return TokError(
"expected end of directive");
5335 getStreamer().emitWinCFISaveXMM(
Reg, Off, Loc);
5339bool X86AsmParser::ensureMasmPrologContext(SMLoc Loc) {
5340 if (getStreamer().isWinCFIPrologEnded()) {
5341 return Error(Loc,
"prolog directive must be used inside a prolog");
5346bool X86AsmParser::ensureMasmEpilogContext(SMLoc Loc) {
5347 if (!getStreamer().isInEpilogCFI()) {
5348 return Error(Loc,
"epilog directive must be used inside an epilog");
5353bool X86AsmParser::parseDirectiveSEHPushFrame(SMLoc Loc) {
5357 SMLoc startLoc = getLexer().getLoc();
5359 if (!getParser().parseIdentifier(CodeID)) {
5360 if (CodeID !=
"code")
5361 return Error(startLoc,
"expected @code");
5364 }
else if (getParser().isParsingMasm() &&
5366 getTok().getString().equals_insensitive(
"code")) {
5372 return TokError(
"expected end of directive");
5375 getStreamer().emitWinCFIPushFrame(Code, Loc);
5385#define GET_MATCHER_IMPLEMENTATION
5386#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
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