52 "x86-experimental-lvi-inline-asm-hardening",
53 cl::desc(
"Harden inline assembly code that may be vulnerable to Load Value"
54 " Injection (LVI). This feature is experimental."),
cl::Hidden);
57 if (Scale != 1 && Scale != 2 && Scale != 4 && Scale != 8) {
58 ErrMsg =
"scale factor in address must be 1, 2, 4 or 8";
67#define GET_X86_SSE2AVX_TABLE
68#include "X86GenInstrMapping.inc"
70static const char OpPrecedence[] = {
96 ParseInstructionInfo *InstInfo;
98 unsigned ForcedDataPrefix = 0;
101 OpcodePrefix_Default,
110 OpcodePrefix ForcedOpcodePrefix = OpcodePrefix_Default;
113 DispEncoding_Default,
118 DispEncoding ForcedDispEncoding = DispEncoding_Default;
121 bool UseApxExtendedReg =
false;
123 bool ForcedNoFlag =
false;
126 SMLoc consumeToken() {
127 MCAsmParser &Parser = getParser();
137 X86TargetStreamer &getTargetStreamer() {
138 assert(getParser().getStreamer().getTargetStreamer() &&
139 "do not have a target streamer");
140 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
141 return static_cast<X86TargetStreamer &
>(TS);
144 unsigned MatchInstruction(
const OperandVector &Operands, MCInst &Inst,
145 uint64_t &ErrorInfo, FeatureBitset &MissingFeatures,
146 bool matchingInlineAsm,
unsigned VariantID = 0) {
149 SwitchMode(X86::Is32Bit);
150 unsigned rv = MatchInstructionImpl(Operands, Inst, ErrorInfo,
151 MissingFeatures, matchingInlineAsm,
154 SwitchMode(X86::Is16Bit);
158 enum InfixCalculatorTok {
183 enum IntelOperatorKind {
190 enum MasmOperatorKind {
197 class InfixCalculator {
198 typedef std::pair< InfixCalculatorTok, int64_t > ICToken;
202 bool isUnaryOperator(InfixCalculatorTok
Op)
const {
203 return Op == IC_NEG ||
Op == IC_NOT;
207 int64_t popOperand() {
208 assert (!PostfixStack.empty() &&
"Poped an empty stack!");
209 ICToken
Op = PostfixStack.pop_back_val();
210 if (!(
Op.first == IC_IMM ||
Op.first == IC_REGISTER))
214 void pushOperand(InfixCalculatorTok
Op, int64_t Val = 0) {
215 assert ((
Op == IC_IMM ||
Op == IC_REGISTER) &&
216 "Unexpected operand!");
217 PostfixStack.push_back(std::make_pair(
Op, Val));
220 void popOperator() { InfixOperatorStack.pop_back(); }
221 void pushOperator(InfixCalculatorTok
Op) {
223 if (InfixOperatorStack.empty()) {
224 InfixOperatorStack.push_back(
Op);
231 unsigned Idx = InfixOperatorStack.size() - 1;
232 InfixCalculatorTok StackOp = InfixOperatorStack[Idx];
233 if (OpPrecedence[
Op] > OpPrecedence[StackOp] || StackOp == IC_LPAREN) {
234 InfixOperatorStack.push_back(
Op);
240 unsigned ParenCount = 0;
243 if (InfixOperatorStack.empty())
246 Idx = InfixOperatorStack.size() - 1;
247 StackOp = InfixOperatorStack[Idx];
248 if (!(OpPrecedence[StackOp] >= OpPrecedence[
Op] || ParenCount))
253 if (!ParenCount && StackOp == IC_LPAREN)
256 if (StackOp == IC_RPAREN) {
258 InfixOperatorStack.pop_back();
259 }
else if (StackOp == IC_LPAREN) {
261 InfixOperatorStack.pop_back();
263 InfixOperatorStack.pop_back();
264 PostfixStack.push_back(std::make_pair(StackOp, 0));
268 InfixOperatorStack.push_back(
Op);
273 while (!InfixOperatorStack.empty()) {
274 InfixCalculatorTok StackOp = InfixOperatorStack.pop_back_val();
275 if (StackOp != IC_LPAREN && StackOp != IC_RPAREN)
276 PostfixStack.push_back(std::make_pair(StackOp, 0));
279 if (PostfixStack.empty())
283 for (
const ICToken &
Op : PostfixStack) {
284 if (
Op.first == IC_IMM ||
Op.first == IC_REGISTER) {
286 }
else if (isUnaryOperator(
Op.first)) {
287 assert (OperandStack.
size() > 0 &&
"Too few operands.");
289 assert (Operand.first == IC_IMM &&
290 "Unary operation with a register!");
296 OperandStack.
push_back(std::make_pair(IC_IMM, -Operand.second));
299 OperandStack.
push_back(std::make_pair(IC_IMM, ~Operand.second));
303 assert (OperandStack.
size() > 1 &&
"Too few operands.");
312 Val = Op1.second + Op2.second;
313 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
316 Val = Op1.second - Op2.second;
317 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
320 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
321 "Multiply operation with an immediate and a register!");
322 Val = Op1.second * Op2.second;
323 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
326 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
327 "Divide operation with an immediate and a register!");
328 assert (Op2.second != 0 &&
"Division by zero!");
329 Val = Op1.second / Op2.second;
330 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
333 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
334 "Modulo operation with an immediate and a register!");
335 Val = Op1.second % Op2.second;
336 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
339 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
340 "Or operation with an immediate and a register!");
341 Val = Op1.second | Op2.second;
342 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
345 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
346 "Xor operation with an immediate and a register!");
347 Val = Op1.second ^ Op2.second;
348 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
351 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
352 "And operation with an immediate and a register!");
353 Val = Op1.second & Op2.second;
354 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
357 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
358 "Left shift operation with an immediate and a register!");
359 Val = Op1.second << Op2.second;
360 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
363 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
364 "Right shift operation with an immediate and a register!");
365 Val = Op1.second >> Op2.second;
366 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
369 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
370 "Equals operation with an immediate and a register!");
371 Val = (Op1.second == Op2.second) ? -1 : 0;
372 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
375 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
376 "Not-equals operation with an immediate and a register!");
377 Val = (Op1.second != Op2.second) ? -1 : 0;
378 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
381 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
382 "Less-than operation with an immediate and a register!");
383 Val = (Op1.second < Op2.second) ? -1 : 0;
384 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
387 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
388 "Less-than-or-equal operation with an immediate and a "
390 Val = (Op1.second <= Op2.second) ? -1 : 0;
391 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
394 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
395 "Greater-than operation with an immediate and a register!");
396 Val = (Op1.second > Op2.second) ? -1 : 0;
397 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
400 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
401 "Greater-than-or-equal operation with an immediate and a "
403 Val = (Op1.second >= Op2.second) ? -1 : 0;
404 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
409 assert (OperandStack.
size() == 1 &&
"Expected a single result.");
414 enum IntelExprState {
444 class IntelExprStateMachine {
445 IntelExprState State = IES_INIT, PrevState = IES_ERROR;
446 MCRegister BaseReg, IndexReg, TmpReg;
449 const MCExpr *Sym =
nullptr;
452 InlineAsmIdentifierInfo Info;
454 bool MemExpr =
false;
455 bool BracketUsed =
false;
456 bool NegativeAdditiveTerm =
false;
457 SMLoc NegativeAdditiveTermLoc;
458 bool OffsetOperator =
false;
459 bool AttachToOperandIdx =
false;
461 SMLoc OffsetOperatorLoc;
464 bool setSymRef(
const MCExpr *Val, StringRef
ID, StringRef &ErrMsg) {
466 ErrMsg =
"cannot use more than one symbol in memory operand";
475 IntelExprStateMachine() =
default;
477 void addImm(int64_t imm) { Imm += imm; }
478 short getBracCount()
const {
return BracCount; }
479 bool isMemExpr()
const {
return MemExpr; }
480 bool isBracketUsed()
const {
return BracketUsed; }
481 bool isOffsetOperator()
const {
return OffsetOperator; }
482 SMLoc getOffsetLoc()
const {
return OffsetOperatorLoc; }
483 MCRegister getBaseReg()
const {
return BaseReg; }
484 MCRegister getIndexReg()
const {
return IndexReg; }
485 unsigned getScale()
const {
return Scale; }
486 const MCExpr *
getSym()
const {
return Sym; }
487 StringRef getSymName()
const {
return SymName; }
488 StringRef
getType()
const {
return CurType.Name; }
489 unsigned getSize()
const {
return CurType.Size; }
490 unsigned getElementSize()
const {
return CurType.ElementSize; }
491 unsigned getLength()
const {
return CurType.Length; }
492 int64_t
getImm() {
return Imm + IC.execute(); }
493 bool isValidEndState()
const {
494 return State == IES_RBRAC || State == IES_RPAREN ||
495 State == IES_INTEGER || State == IES_REGISTER ||
503 void setAppendAfterOperand() { AttachToOperandIdx =
true; }
505 bool isPIC()
const {
return IsPIC; }
506 void setPIC() { IsPIC =
true; }
508 bool hadError()
const {
return State == IES_ERROR; }
509 SMLoc getErrorLoc(SMLoc DefaultLoc)
const {
510 return NegativeAdditiveTerm ? NegativeAdditiveTermLoc : DefaultLoc;
512 const InlineAsmIdentifierInfo &getIdentifierInfo()
const {
return Info; }
514 bool regsUseUpError(StringRef &ErrMsg) {
517 if (IsPIC && AttachToOperandIdx)
518 ErrMsg =
"Don't use 2 or more regs for mem offset in PIC model!";
520 ErrMsg =
"BaseReg/IndexReg already set!";
525 IntelExprState CurrState = State;
534 IC.pushOperator(IC_OR);
537 PrevState = CurrState;
540 IntelExprState CurrState = State;
549 IC.pushOperator(IC_XOR);
552 PrevState = CurrState;
555 IntelExprState CurrState = State;
564 IC.pushOperator(IC_AND);
567 PrevState = CurrState;
570 IntelExprState CurrState = State;
579 IC.pushOperator(IC_EQ);
582 PrevState = CurrState;
585 IntelExprState CurrState = State;
594 IC.pushOperator(IC_NE);
597 PrevState = CurrState;
600 IntelExprState CurrState = State;
609 IC.pushOperator(IC_LT);
612 PrevState = CurrState;
615 IntelExprState CurrState = State;
624 IC.pushOperator(IC_LE);
627 PrevState = CurrState;
630 IntelExprState CurrState = State;
639 IC.pushOperator(IC_GT);
642 PrevState = CurrState;
645 IntelExprState CurrState = State;
654 IC.pushOperator(IC_GE);
657 PrevState = CurrState;
660 IntelExprState CurrState = State;
669 IC.pushOperator(IC_LSHIFT);
672 PrevState = CurrState;
675 IntelExprState CurrState = State;
684 IC.pushOperator(IC_RSHIFT);
687 PrevState = CurrState;
689 bool onPlus(StringRef &ErrMsg) {
690 IntelExprState CurrState = State;
700 IC.pushOperator(IC_PLUS);
701 NegativeAdditiveTerm =
false;
702 NegativeAdditiveTermLoc = SMLoc();
703 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
710 return regsUseUpError(ErrMsg);
717 PrevState = CurrState;
720 bool onMinus(SMLoc MinusLoc, StringRef &ErrMsg) {
721 IntelExprState CurrState = State;
752 if (CurrState == IES_REGISTER || CurrState == IES_RPAREN ||
753 CurrState == IES_INTEGER || CurrState == IES_RBRAC ||
754 CurrState == IES_OFFSET) {
755 IC.pushOperator(IC_MINUS);
756 NegativeAdditiveTerm =
true;
757 NegativeAdditiveTermLoc = MinusLoc;
758 }
else if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
760 ErrMsg =
"Scale can't be negative";
763 IC.pushOperator(IC_NEG);
764 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
771 return regsUseUpError(ErrMsg);
778 PrevState = CurrState;
782 IntelExprState CurrState = State;
808 IC.pushOperator(IC_NOT);
811 PrevState = CurrState;
813 bool onRegister(MCRegister
Reg, StringRef &ErrMsg) {
814 IntelExprState CurrState = State;
823 State = IES_REGISTER;
825 IC.pushOperand(IC_REGISTER);
829 if (PrevState == IES_INTEGER) {
831 return regsUseUpError(ErrMsg);
832 if (NegativeAdditiveTerm) {
833 ErrMsg =
"Scale can't be negative";
836 State = IES_REGISTER;
839 Scale = IC.popOperand();
842 IC.pushOperand(IC_IMM);
849 PrevState = CurrState;
852 bool onIdentifierExpr(
const MCExpr *SymRef, StringRef SymRefName,
853 const InlineAsmIdentifierInfo &IDInfo,
854 const AsmTypeInfo &
Type,
bool ParsingMSInlineAsm,
857 if (ParsingMSInlineAsm)
862 return onInteger(
CE->getValue(), ErrMsg);
875 if (setSymRef(SymRef, SymRefName, ErrMsg))
879 IC.pushOperand(IC_IMM);
880 if (ParsingMSInlineAsm)
887 bool onInteger(int64_t TmpInt, StringRef &ErrMsg) {
888 IntelExprState CurrState = State;
914 if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
917 return regsUseUpError(ErrMsg);
918 if (NegativeAdditiveTerm) {
919 ErrMsg =
"Scale can't be negative";
929 IC.pushOperand(IC_IMM, TmpInt);
933 PrevState = CurrState;
945 State = IES_MULTIPLY;
946 IC.pushOperator(IC_MULTIPLY);
959 IC.pushOperator(IC_DIVIDE);
972 IC.pushOperator(IC_MOD);
988 IC.pushOperator(IC_PLUS);
990 CurType.Size = CurType.ElementSize;
994 assert(!BracCount &&
"BracCount should be zero on parsing's start");
1003 bool onRBrac(StringRef &ErrMsg) {
1004 IntelExprState CurrState = State;
1013 if (BracCount-- != 1) {
1014 ErrMsg =
"unexpected bracket encountered";
1018 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
1025 return regsUseUpError(ErrMsg);
1026 if (NegativeAdditiveTerm) {
1027 ErrMsg =
"Scale can't be negative";
1034 NegativeAdditiveTerm =
false;
1035 NegativeAdditiveTermLoc = SMLoc();
1038 PrevState = CurrState;
1042 IntelExprState CurrState = State;
1068 IC.pushOperator(IC_LPAREN);
1071 PrevState = CurrState;
1073 bool onRParen(StringRef &ErrMsg) {
1074 IntelExprState CurrState = State;
1089 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
1096 return regsUseUpError(ErrMsg);
1097 if (NegativeAdditiveTerm) {
1098 ErrMsg =
"Scale can't be negative";
1105 IC.pushOperator(IC_RPAREN);
1108 PrevState = CurrState;
1111 bool onOffset(
const MCExpr *Val, SMLoc OffsetLoc, StringRef
ID,
1112 const InlineAsmIdentifierInfo &IDInfo,
1113 bool ParsingMSInlineAsm, StringRef &ErrMsg) {
1117 ErrMsg =
"unexpected offset operator expression";
1122 if (setSymRef(Val,
ID, ErrMsg))
1124 OffsetOperator =
true;
1125 OffsetOperatorLoc = OffsetLoc;
1129 IC.pushOperand(IC_IMM);
1130 if (ParsingMSInlineAsm) {
1137 void onCast(AsmTypeInfo Info) {
1149 void setTypeInfo(AsmTypeInfo
Type) { CurType =
Type; }
1152 bool Error(SMLoc L,
const Twine &Msg, SMRange
Range = {},
1153 bool MatchingInlineAsm =
false) {
1154 MCAsmParser &Parser = getParser();
1155 if (MatchingInlineAsm) {
1161 bool MatchRegisterByName(MCRegister &RegNo, StringRef
RegName, SMLoc StartLoc,
1163 bool ParseRegister(MCRegister &RegNo, SMLoc &StartLoc, SMLoc &EndLoc,
1164 bool RestoreOnFailure);
1166 std::unique_ptr<X86Operand> DefaultMemSIOperand(SMLoc Loc);
1167 std::unique_ptr<X86Operand> DefaultMemDIOperand(SMLoc Loc);
1168 bool IsSIReg(MCRegister
Reg);
1169 MCRegister GetSIDIForRegClass(
unsigned RegClassID,
bool IsSIReg);
1172 std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
1173 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst);
1178 bool parseIntelOperand(
OperandVector &Operands, StringRef Name);
1179 bool ParseIntelOffsetOperator(
const MCExpr *&Val, StringRef &
ID,
1180 InlineAsmIdentifierInfo &Info, SMLoc &End);
1181 bool ParseIntelDotOperator(IntelExprStateMachine &
SM, SMLoc &End);
1182 unsigned IdentifyIntelInlineAsmOperator(StringRef Name);
1183 unsigned ParseIntelInlineAsmOperator(
unsigned OpKind);
1184 unsigned IdentifyMasmOperator(StringRef Name);
1185 bool ParseMasmOperator(
unsigned OpKind, int64_t &Val);
1186 bool ParseRoundingModeOp(SMLoc Start,
OperandVector &Operands);
1188 bool ParseIntelNamedOperator(StringRef Name, IntelExprStateMachine &
SM,
1189 bool &ParseError, SMLoc &End);
1190 bool ParseMasmNamedOperator(StringRef Name, IntelExprStateMachine &
SM,
1191 bool &ParseError, SMLoc &End);
1192 void RewriteIntelExpression(IntelExprStateMachine &
SM, SMLoc Start,
1194 bool ParseIntelExpression(IntelExprStateMachine &
SM, SMLoc &End);
1195 bool ParseIntelInlineAsmIdentifier(
const MCExpr *&Val, StringRef &Identifier,
1196 InlineAsmIdentifierInfo &Info,
1197 bool IsUnevaluatedOperand, SMLoc &End,
1198 bool IsParsingOffsetOperator =
false);
1200 IntelExprStateMachine &
SM);
1202 bool CheckDispOverflow(MCRegister BaseReg, MCRegister IndexReg,
1203 const MCExpr *Disp, SMLoc Loc);
1205 bool ParseMemOperand(MCRegister SegReg,
const MCExpr *Disp, SMLoc StartLoc,
1210 bool ParseIntelMemoryOperandSize(
unsigned &
Size, StringRef *SizeStr);
1211 bool CreateMemForMSInlineAsm(MCRegister SegReg,
const MCExpr *Disp,
1212 MCRegister BaseReg, MCRegister IndexReg,
1213 unsigned Scale,
bool NonAbsMem, SMLoc Start,
1214 SMLoc End,
unsigned Size, StringRef Identifier,
1215 const InlineAsmIdentifierInfo &Info,
1218 bool parseDirectiveArch();
1219 bool parseDirectiveNops(SMLoc L);
1220 bool parseDirectiveEven(SMLoc L);
1221 bool ParseDirectiveCode(StringRef IDVal, SMLoc L);
1224 bool parseDirectiveFPOProc(SMLoc L);
1225 bool parseDirectiveFPOSetFrame(SMLoc L);
1226 bool parseDirectiveFPOPushReg(SMLoc L);
1227 bool parseDirectiveFPOStackAlloc(SMLoc L);
1228 bool parseDirectiveFPOStackAlign(SMLoc L);
1229 bool parseDirectiveFPOEndPrologue(SMLoc L);
1230 bool parseDirectiveFPOEndProc(SMLoc L);
1233 bool parseSEHRegisterNumber(
unsigned RegClassID, MCRegister &RegNo);
1234 bool parseDirectiveSEHPushReg(SMLoc);
1235 bool parseDirectiveSEHSetFrame(SMLoc);
1236 bool parseDirectiveSEHSaveReg(SMLoc);
1237 bool parseDirectiveSEHSaveXMM(SMLoc);
1238 bool parseDirectiveSEHPushFrame(SMLoc);
1240 unsigned checkTargetMatchPredicate(MCInst &Inst)
override;
1246 void emitWarningForSpecialLVIInstruction(SMLoc Loc);
1247 void applyLVICFIMitigation(MCInst &Inst, MCStreamer &Out);
1248 void applyLVILoadHardeningMitigation(MCInst &Inst, MCStreamer &Out);
1254 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1256 uint64_t &ErrorInfo,
1257 bool MatchingInlineAsm)
override;
1259 void MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &
Op,
OperandVector &Operands,
1260 MCStreamer &Out,
bool MatchingInlineAsm);
1262 bool ErrorMissingFeature(SMLoc IDLoc,
const FeatureBitset &MissingFeatures,
1263 bool MatchingInlineAsm);
1265 bool matchAndEmitATTInstruction(SMLoc IDLoc,
unsigned &Opcode, MCInst &Inst,
1267 uint64_t &ErrorInfo,
bool MatchingInlineAsm);
1269 bool matchAndEmitIntelInstruction(SMLoc IDLoc,
unsigned &Opcode, MCInst &Inst,
1271 uint64_t &ErrorInfo,
1272 bool MatchingInlineAsm);
1274 bool omitRegisterFromClobberLists(MCRegister
Reg)
override;
1281 bool ParseZ(std::unique_ptr<X86Operand> &Z, SMLoc StartLoc);
1283 bool is64BitMode()
const {
1285 return getSTI().hasFeature(X86::Is64Bit);
1287 bool is32BitMode()
const {
1289 return getSTI().hasFeature(X86::Is32Bit);
1291 bool is16BitMode()
const {
1293 return getSTI().hasFeature(X86::Is16Bit);
1295 void SwitchMode(
unsigned mode) {
1296 MCSubtargetInfo &STI = copySTI();
1297 FeatureBitset AllModes({X86::Is64Bit, X86::Is32Bit, X86::Is16Bit});
1299 FeatureBitset FB = ComputeAvailableFeatures(
1301 setAvailableFeatures(FB);
1306 unsigned getPointerWidth() {
1307 if (is16BitMode())
return 16;
1308 if (is32BitMode())
return 32;
1309 if (is64BitMode())
return 64;
1313 bool isParsingIntelSyntax() {
1314 return getParser().getAssemblerDialect();
1320#define GET_ASSEMBLER_HEADER
1321#include "X86GenAsmMatcher.inc"
1326 enum X86MatchResultTy {
1327 Match_Unsupported = FIRST_TARGET_MATCH_RESULT_TY,
1328#define GET_OPERAND_DIAGNOSTIC_TYPES
1329#include "X86GenAsmMatcher.inc"
1332 X86AsmParser(
const MCSubtargetInfo &sti, MCAsmParser &Parser,
1333 const MCInstrInfo &mii)
1334 : MCTargetAsmParser(sti, mii), InstInfo(nullptr), Code16GCC(
false) {
1339 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
1342 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
1343 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1344 SMLoc &EndLoc)
override;
1346 bool parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc)
override;
1348 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
1351 bool ParseDirective(AsmToken DirectiveID)
override;
1355#define GET_REGISTER_MATCHER
1356#define GET_SUBTARGET_FEATURE_NAME
1357#include "X86GenAsmMatcher.inc"
1368 !(BaseReg == X86::RIP || BaseReg == X86::EIP ||
1369 X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg) ||
1370 X86MCRegisterClasses[X86::GR32RegClassID].
contains(BaseReg) ||
1371 X86MCRegisterClasses[X86::GR64RegClassID].
contains(BaseReg))) {
1372 ErrMsg =
"invalid base+index expression";
1377 !(IndexReg == X86::EIZ || IndexReg == X86::RIZ ||
1378 X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg) ||
1379 X86MCRegisterClasses[X86::GR32RegClassID].
contains(IndexReg) ||
1380 X86MCRegisterClasses[X86::GR64RegClassID].
contains(IndexReg) ||
1381 X86MCRegisterClasses[X86::VR128XRegClassID].
contains(IndexReg) ||
1382 X86MCRegisterClasses[X86::VR256XRegClassID].
contains(IndexReg) ||
1383 X86MCRegisterClasses[X86::VR512RegClassID].
contains(IndexReg))) {
1384 ErrMsg =
"invalid base+index expression";
1388 if (((BaseReg == X86::RIP || BaseReg == X86::EIP) && IndexReg) ||
1389 IndexReg == X86::EIP || IndexReg == X86::RIP || IndexReg == X86::ESP ||
1390 IndexReg == X86::RSP) {
1391 ErrMsg =
"invalid base+index expression";
1397 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg) &&
1398 (Is64BitMode || (BaseReg != X86::BX && BaseReg != X86::BP &&
1399 BaseReg != X86::SI && BaseReg != X86::DI))) {
1400 ErrMsg =
"invalid 16-bit base register";
1405 X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg)) {
1406 ErrMsg =
"16-bit memory operand may not include only index register";
1410 if (BaseReg && IndexReg) {
1411 if (X86MCRegisterClasses[X86::GR64RegClassID].
contains(BaseReg) &&
1412 (X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg) ||
1413 X86MCRegisterClasses[X86::GR32RegClassID].
contains(IndexReg) ||
1414 IndexReg == X86::EIZ)) {
1415 ErrMsg =
"base register is 64-bit, but index register is not";
1418 if (X86MCRegisterClasses[X86::GR32RegClassID].
contains(BaseReg) &&
1419 (X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg) ||
1420 X86MCRegisterClasses[X86::GR64RegClassID].
contains(IndexReg) ||
1421 IndexReg == X86::RIZ)) {
1422 ErrMsg =
"base register is 32-bit, but index register is not";
1425 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg)) {
1426 if (X86MCRegisterClasses[X86::GR32RegClassID].
contains(IndexReg) ||
1427 X86MCRegisterClasses[X86::GR64RegClassID].
contains(IndexReg)) {
1428 ErrMsg =
"base register is 16-bit, but index register is not";
1431 if ((BaseReg != X86::BX && BaseReg != X86::BP) ||
1432 (IndexReg != X86::SI && IndexReg != X86::DI)) {
1433 ErrMsg =
"invalid 16-bit base/index register combination";
1440 if (!Is64BitMode && (BaseReg == X86::RIP || BaseReg == X86::EIP)) {
1441 ErrMsg =
"IP-relative addressing requires 64-bit mode";
1462 if (isParsingMSInlineAsm() && isParsingIntelSyntax() &&
1463 (RegNo == X86::EFLAGS || RegNo == X86::MXCSR))
1464 RegNo = MCRegister();
1466 if (!is64BitMode()) {
1470 if (RegNo == X86::RIZ || RegNo == X86::RIP ||
1471 X86MCRegisterClasses[X86::GR64RegClassID].
contains(RegNo) ||
1474 return Error(StartLoc,
1475 "register %" +
RegName +
" is only available in 64-bit mode",
1476 SMRange(StartLoc, EndLoc));
1481 UseApxExtendedReg =
true;
1485 if (!RegNo &&
RegName.starts_with(
"db")) {
1544 if (isParsingIntelSyntax())
1546 return Error(StartLoc,
"invalid register name", SMRange(StartLoc, EndLoc));
1551bool X86AsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
1552 SMLoc &EndLoc,
bool RestoreOnFailure) {
1553 MCAsmParser &Parser = getParser();
1554 AsmLexer &Lexer = getLexer();
1555 RegNo = MCRegister();
1558 auto OnFailure = [RestoreOnFailure, &Lexer, &Tokens]() {
1559 if (RestoreOnFailure) {
1560 while (!Tokens.
empty()) {
1566 const AsmToken &PercentTok = Parser.
getTok();
1567 StartLoc = PercentTok.
getLoc();
1576 const AsmToken &Tok = Parser.
getTok();
1581 if (isParsingIntelSyntax())
return true;
1582 return Error(StartLoc,
"invalid register name",
1583 SMRange(StartLoc, EndLoc));
1586 if (MatchRegisterByName(RegNo, Tok.
getString(), StartLoc, EndLoc)) {
1592 if (RegNo == X86::ST0) {
1603 const AsmToken &IntTok = Parser.
getTok();
1606 return Error(IntTok.
getLoc(),
"expected stack index");
1609 case 0: RegNo = X86::ST0;
break;
1610 case 1: RegNo = X86::ST1;
break;
1611 case 2: RegNo = X86::ST2;
break;
1612 case 3: RegNo = X86::ST3;
break;
1613 case 4: RegNo = X86::ST4;
break;
1614 case 5: RegNo = X86::ST5;
break;
1615 case 6: RegNo = X86::ST6;
break;
1616 case 7: RegNo = X86::ST7;
break;
1619 return Error(IntTok.
getLoc(),
"invalid stack index");
1639 if (isParsingIntelSyntax())
return true;
1640 return Error(StartLoc,
"invalid register name",
1641 SMRange(StartLoc, EndLoc));
1648bool X86AsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1650 return ParseRegister(
Reg, StartLoc, EndLoc,
false);
1653ParseStatus X86AsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1655 bool Result = ParseRegister(
Reg, StartLoc, EndLoc,
true);
1656 bool PendingErrors = getParser().hasPendingError();
1657 getParser().clearPendingErrors();
1665std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(SMLoc Loc) {
1666 bool Parse32 = is32BitMode() || Code16GCC;
1667 MCRegister Basereg =
1668 is64BitMode() ? X86::RSI : (Parse32 ? X86::ESI : X86::SI);
1675std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand(SMLoc Loc) {
1676 bool Parse32 = is32BitMode() || Code16GCC;
1677 MCRegister Basereg =
1678 is64BitMode() ? X86::RDI : (Parse32 ? X86::EDI : X86::DI);
1685bool X86AsmParser::IsSIReg(MCRegister
Reg) {
1699MCRegister X86AsmParser::GetSIDIForRegClass(
unsigned RegClassID,
bool IsSIReg) {
1700 switch (RegClassID) {
1702 case X86::GR64RegClassID:
1703 return IsSIReg ? X86::RSI : X86::RDI;
1704 case X86::GR32RegClassID:
1705 return IsSIReg ? X86::ESI : X86::EDI;
1706 case X86::GR16RegClassID:
1707 return IsSIReg ? X86::SI : X86::DI;
1711void X86AsmParser::AddDefaultSrcDestOperands(
1712 OperandVector& Operands, std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
1713 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst) {
1714 if (isParsingIntelSyntax()) {
1724bool X86AsmParser::VerifyAndAdjustOperands(
OperandVector &OrigOperands,
1727 if (OrigOperands.
size() > 1) {
1730 "Operand size mismatch");
1734 int RegClassID = -1;
1735 for (
unsigned int i = 0; i < FinalOperands.
size(); ++i) {
1736 X86Operand &OrigOp =
static_cast<X86Operand &
>(*OrigOperands[i + 1]);
1737 X86Operand &FinalOp =
static_cast<X86Operand &
>(*FinalOperands[i]);
1739 if (FinalOp.
isReg() &&
1744 if (FinalOp.
isMem()) {
1746 if (!OrigOp.
isMem())
1755 if (RegClassID != -1 &&
1756 !X86MCRegisterClasses[RegClassID].
contains(OrigReg)) {
1758 "mismatching source and destination index registers");
1761 if (X86MCRegisterClasses[X86::GR64RegClassID].
contains(OrigReg))
1762 RegClassID = X86::GR64RegClassID;
1763 else if (X86MCRegisterClasses[X86::GR32RegClassID].
contains(OrigReg))
1764 RegClassID = X86::GR32RegClassID;
1765 else if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(OrigReg))
1766 RegClassID = X86::GR16RegClassID;
1772 bool IsSI = IsSIReg(FinalReg);
1773 FinalReg = GetSIDIForRegClass(RegClassID, IsSI);
1775 if (FinalReg != OrigReg) {
1776 std::string
RegName = IsSI ?
"ES:(R|E)SI" :
"ES:(R|E)DI";
1779 "memory operand is only for determining the size, " +
RegName +
1780 " will be used for the location"));
1791 for (
auto &WarningMsg : Warnings) {
1792 Warning(WarningMsg.first, WarningMsg.second);
1796 for (
unsigned int i = 0; i < FinalOperands.
size(); ++i)
1800 for (
auto &
Op : FinalOperands)
1806bool X86AsmParser::parseOperand(
OperandVector &Operands, StringRef Name) {
1807 if (isParsingIntelSyntax())
1808 return parseIntelOperand(Operands, Name);
1810 return parseATTOperand(Operands);
1813bool X86AsmParser::CreateMemForMSInlineAsm(
1814 MCRegister SegReg,
const MCExpr *Disp, MCRegister BaseReg,
1815 MCRegister IndexReg,
unsigned Scale,
bool NonAbsMem, SMLoc Start, SMLoc End,
1816 unsigned Size, StringRef Identifier,
const InlineAsmIdentifierInfo &Info,
1824 End,
Size, Identifier,
1831 unsigned FrontendSize = 0;
1832 void *Decl =
nullptr;
1833 bool IsGlobalLV =
false;
1836 FrontendSize =
Info.Var.Type * 8;
1837 Decl =
Info.Var.Decl;
1838 IsGlobalLV =
Info.Var.IsGlobalLV;
1843 if (BaseReg || IndexReg) {
1845 End,
Size, Identifier, Decl, 0,
1846 BaseReg && IndexReg));
1853 getPointerWidth(), SegReg, Disp, BaseReg, IndexReg, Scale, Start, End,
1855 X86::RIP, Identifier, Decl, FrontendSize));
1862bool X86AsmParser::ParseIntelNamedOperator(StringRef Name,
1863 IntelExprStateMachine &
SM,
1864 bool &ParseError, SMLoc &End) {
1867 if (Name !=
Name.lower() && Name !=
Name.upper() &&
1868 !getParser().isParsingMasm())
1870 if (
Name.equals_insensitive(
"not")) {
1872 }
else if (
Name.equals_insensitive(
"or")) {
1874 }
else if (
Name.equals_insensitive(
"shl")) {
1876 }
else if (
Name.equals_insensitive(
"shr")) {
1878 }
else if (
Name.equals_insensitive(
"xor")) {
1880 }
else if (
Name.equals_insensitive(
"and")) {
1882 }
else if (
Name.equals_insensitive(
"mod")) {
1884 }
else if (
Name.equals_insensitive(
"offset")) {
1885 SMLoc OffsetLoc = getTok().getLoc();
1886 const MCExpr *Val =
nullptr;
1888 InlineAsmIdentifierInfo
Info;
1889 ParseError = ParseIntelOffsetOperator(Val,
ID, Info, End);
1894 SM.onOffset(Val, OffsetLoc,
ID, Info, isParsingMSInlineAsm(), ErrMsg);
1900 if (!
Name.equals_insensitive(
"offset"))
1901 End = consumeToken();
1904bool X86AsmParser::ParseMasmNamedOperator(StringRef Name,
1905 IntelExprStateMachine &
SM,
1906 bool &ParseError, SMLoc &End) {
1907 if (
Name.equals_insensitive(
"eq")) {
1909 }
else if (
Name.equals_insensitive(
"ne")) {
1911 }
else if (
Name.equals_insensitive(
"lt")) {
1913 }
else if (
Name.equals_insensitive(
"le")) {
1915 }
else if (
Name.equals_insensitive(
"gt")) {
1917 }
else if (
Name.equals_insensitive(
"ge")) {
1922 End = consumeToken();
1929 IntelExprStateMachine &
SM) {
1933 SM.setAppendAfterOperand();
1936bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &
SM, SMLoc &End) {
1937 MCAsmParser &Parser = getParser();
1942 if (
getContext().getObjectFileInfo()->isPositionIndependent())
1949 const AsmToken &Tok = Parser.
getTok();
1951 bool UpdateLocLex =
true;
1956 if ((
Done =
SM.isValidEndState()))
1958 return Error(Tok.
getLoc(),
"unknown token in expression");
1960 return Error(getLexer().getErrLoc(), getLexer().getErr());
1964 UpdateLocLex =
false;
1965 if (ParseIntelDotOperator(
SM, End))
1970 if ((
Done =
SM.isValidEndState()))
1972 return Error(Tok.
getLoc(),
"unknown token in expression");
1976 UpdateLocLex =
false;
1977 if (ParseIntelDotOperator(
SM, End))
1982 if ((
Done =
SM.isValidEndState()))
1984 return Error(Tok.
getLoc(),
"unknown token in expression");
1990 SMLoc ValueLoc = Tok.
getLoc();
1995 UpdateLocLex =
false;
1996 if (!Val->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
1997 return Error(ValueLoc,
"expected absolute value");
1998 if (
SM.onInteger(Res, ErrMsg))
1999 return Error(
SM.getErrorLoc(ValueLoc), ErrMsg);
2006 SMLoc IdentLoc = Tok.
getLoc();
2008 UpdateLocLex =
false;
2010 size_t DotOffset =
Identifier.find_first_of(
'.');
2014 StringRef Dot =
Identifier.substr(DotOffset, 1);
2028 const AsmToken &NextTok = getLexer().peekTok();
2037 End = consumeToken();
2044 if (!ParseRegister(
Reg, IdentLoc, End,
true)) {
2045 if (
SM.onRegister(
Reg, ErrMsg))
2046 return Error(
SM.getErrorLoc(IdentLoc), ErrMsg);
2050 const std::pair<StringRef, StringRef> IDField =
2052 const StringRef
ID = IDField.first,
Field = IDField.second;
2054 if (!
Field.empty() &&
2055 !MatchRegisterByName(
Reg,
ID, IdentLoc, IDEndLoc)) {
2056 if (
SM.onRegister(
Reg, ErrMsg))
2057 return Error(
SM.getErrorLoc(IdentLoc), ErrMsg);
2062 return Error(FieldStartLoc,
"unknown offset");
2063 else if (
SM.onPlus(ErrMsg))
2064 return Error(getTok().getLoc(), ErrMsg);
2065 else if (
SM.onInteger(
Info.Offset, ErrMsg))
2066 return Error(
SM.getErrorLoc(IdentLoc), ErrMsg);
2067 SM.setTypeInfo(
Info.Type);
2069 End = consumeToken();
2076 if (ParseIntelNamedOperator(Identifier,
SM, ParseError, End)) {
2082 ParseMasmNamedOperator(Identifier,
SM, ParseError, End)) {
2088 InlineAsmIdentifierInfo
Info;
2089 AsmFieldInfo FieldInfo;
2095 if (ParseIntelDotOperator(
SM, End))
2100 if (isParsingMSInlineAsm()) {
2102 if (
unsigned OpKind = IdentifyIntelInlineAsmOperator(Identifier)) {
2103 if (int64_t Val = ParseIntelInlineAsmOperator(OpKind)) {
2104 if (
SM.onInteger(Val, ErrMsg))
2105 return Error(
SM.getErrorLoc(IdentLoc), ErrMsg);
2114 return Error(IdentLoc,
"expected identifier");
2115 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
false, End))
2117 else if (
SM.onIdentifierExpr(Val, Identifier, Info, FieldInfo.
Type,
2119 return Error(
SM.getErrorLoc(IdentLoc), ErrMsg);
2123 if (
unsigned OpKind = IdentifyMasmOperator(Identifier)) {
2125 if (ParseMasmOperator(OpKind, Val))
2127 if (
SM.onInteger(Val, ErrMsg))
2128 return Error(
SM.getErrorLoc(IdentLoc), ErrMsg);
2131 if (!getParser().lookUpType(Identifier, FieldInfo.
Type)) {
2137 getParser().parseIdentifier(Identifier);
2141 if (getParser().lookUpField(FieldInfo.
Type.
Name, Identifier,
2145 return Error(IdentLoc,
"Unable to lookup field reference!",
2146 SMRange(IdentLoc, IDEnd));
2151 if (
SM.onInteger(FieldInfo.
Offset, ErrMsg))
2152 return Error(
SM.getErrorLoc(IdentLoc), ErrMsg);
2156 if (getParser().parsePrimaryExpr(Val, End, &FieldInfo.
Type)) {
2157 return Error(Tok.
getLoc(),
"Unexpected identifier!");
2158 }
else if (
SM.onIdentifierExpr(Val, Identifier, Info, FieldInfo.
Type,
2160 return Error(
SM.getErrorLoc(IdentLoc), ErrMsg);
2166 SMLoc Loc = getTok().getLoc();
2167 int64_t
IntVal = getTok().getIntVal();
2168 End = consumeToken();
2169 UpdateLocLex =
false;
2171 StringRef IDVal = getTok().getString();
2172 if (IDVal ==
"f" || IDVal ==
"b") {
2174 getContext().getDirectionalLocalSymbol(IntVal, IDVal ==
"b");
2179 return Error(Loc,
"invalid reference to undefined symbol");
2181 InlineAsmIdentifierInfo
Info;
2183 if (
SM.onIdentifierExpr(Val, Identifier, Info,
Type,
2184 isParsingMSInlineAsm(), ErrMsg))
2185 return Error(
SM.getErrorLoc(Loc), ErrMsg);
2186 End = consumeToken();
2188 if (
SM.onInteger(IntVal, ErrMsg))
2189 return Error(
SM.getErrorLoc(Loc), ErrMsg);
2192 if (
SM.onInteger(IntVal, ErrMsg))
2193 return Error(
SM.getErrorLoc(Loc), ErrMsg);
2198 if (
SM.onPlus(ErrMsg))
2199 return Error(getTok().getLoc(), ErrMsg);
2202 if (
SM.onMinus(getTok().getLoc(), ErrMsg))
2203 return Error(
SM.getErrorLoc(getTok().getLoc()), ErrMsg);
2213 SM.onLShift();
break;
2215 SM.onRShift();
break;
2218 return Error(Tok.
getLoc(),
"unexpected bracket encountered");
2219 tryParseOperandIdx(PrevTK,
SM);
2222 if (
SM.onRBrac(ErrMsg)) {
2228 if (
SM.onRParen(ErrMsg)) {
2234 return Error(Tok.
getLoc(),
"unknown token in expression");
2236 if (!
Done && UpdateLocLex)
2237 End = consumeToken();
2244void X86AsmParser::RewriteIntelExpression(IntelExprStateMachine &
SM,
2245 SMLoc Start, SMLoc End) {
2249 if (
SM.getSym() && !
SM.isOffsetOperator()) {
2250 StringRef SymName =
SM.getSymName();
2251 if (
unsigned Len = SymName.
data() -
Start.getPointer())
2257 if (!(
SM.getBaseReg() ||
SM.getIndexReg() ||
SM.getImm())) {
2264 StringRef BaseRegStr;
2265 StringRef IndexRegStr;
2266 StringRef OffsetNameStr;
2267 if (
SM.getBaseReg())
2269 if (
SM.getIndexReg())
2271 if (
SM.isOffsetOperator())
2272 OffsetNameStr =
SM.getSymName();
2274 IntelExpr Expr(BaseRegStr, IndexRegStr,
SM.getScale(), OffsetNameStr,
2275 SM.getImm(),
SM.isMemExpr());
2276 InstInfo->
AsmRewrites->emplace_back(Loc, ExprLen, Expr);
2280bool X86AsmParser::ParseIntelInlineAsmIdentifier(
2281 const MCExpr *&Val, StringRef &Identifier, InlineAsmIdentifierInfo &Info,
2282 bool IsUnevaluatedOperand, SMLoc &End,
bool IsParsingOffsetOperator) {
2283 MCAsmParser &Parser = getParser();
2284 assert(isParsingMSInlineAsm() &&
"Expected to be parsing inline assembly.");
2288 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);
2290 const AsmToken &Tok = Parser.
getTok();
2291 SMLoc Loc = Tok.
getLoc();
2306 "frontend claimed part of a token?");
2311 StringRef InternalName =
2312 SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(),
2314 assert(InternalName.
size() &&
"We should have an internal name here.");
2317 if (!IsParsingOffsetOperator)
2332bool X86AsmParser::ParseRoundingModeOp(SMLoc Start,
OperandVector &Operands) {
2333 MCAsmParser &Parser = getParser();
2334 const AsmToken &Tok = Parser.
getTok();
2336 const SMLoc consumedToken = consumeToken();
2338 return Error(Tok.
getLoc(),
"Expected an identifier after {");
2341 .Case(
"rn", X86::STATIC_ROUNDING::TO_NEAREST_INT)
2342 .Case(
"rd", X86::STATIC_ROUNDING::TO_NEG_INF)
2343 .Case(
"ru", X86::STATIC_ROUNDING::TO_POS_INF)
2344 .Case(
"rz", X86::STATIC_ROUNDING::TO_ZERO)
2347 return Error(Tok.
getLoc(),
"Invalid rounding mode.");
2350 return Error(Tok.
getLoc(),
"Expected - at this point");
2354 return Error(Tok.
getLoc(),
"Expected } at this point");
2357 const MCExpr *RndModeOp =
2365 return Error(Tok.
getLoc(),
"Expected } at this point");
2370 return Error(Tok.
getLoc(),
"unknown token in expression");
2376 MCAsmParser &Parser = getParser();
2377 AsmToken Tok = Parser.
getTok();
2380 return Error(Tok.
getLoc(),
"Expected { at this point");
2384 return Error(Tok.
getLoc(),
"Expected dfv at this point");
2388 return Error(Tok.
getLoc(),
"Expected = at this point");
2400 unsigned CFlags = 0;
2401 for (
unsigned I = 0;
I < 4; ++
I) {
2410 return Error(Tok.
getLoc(),
"Invalid conditional flags");
2413 return Error(Tok.
getLoc(),
"Duplicated conditional flag");
2424 }
else if (
I == 3) {
2425 return Error(Tok.
getLoc(),
"Expected } at this point");
2427 return Error(Tok.
getLoc(),
"Expected } or , at this point");
2435bool X86AsmParser::ParseIntelDotOperator(IntelExprStateMachine &
SM,
2437 const AsmToken &Tok = getTok();
2443 bool TrailingDot =
false;
2451 }
else if ((isParsingMSInlineAsm() || getParser().isParsingMasm()) &&
2454 const std::pair<StringRef, StringRef> BaseMember = DotDispStr.
split(
'.');
2455 const StringRef
Base = BaseMember.first,
Member = BaseMember.second;
2456 if (getParser().lookUpField(
SM.getType(), DotDispStr, Info) &&
2457 getParser().lookUpField(
SM.getSymName(), DotDispStr, Info) &&
2458 getParser().lookUpField(DotDispStr, Info) &&
2460 SemaCallback->LookupInlineAsmField(
Base, Member,
Info.Offset)))
2461 return Error(Tok.
getLoc(),
"Unable to lookup field reference!");
2463 return Error(Tok.
getLoc(),
"Unexpected token type!");
2468 const char *DotExprEndLoc = DotDispStr.
data() + DotDispStr.
size();
2474 SM.setTypeInfo(
Info.Type);
2480bool X86AsmParser::ParseIntelOffsetOperator(
const MCExpr *&Val, StringRef &
ID,
2481 InlineAsmIdentifierInfo &Info,
2484 SMLoc
Start = Lex().getLoc();
2485 ID = getTok().getString();
2486 if (!isParsingMSInlineAsm()) {
2489 getParser().parsePrimaryExpr(Val, End,
nullptr))
2490 return Error(Start,
"unexpected token!");
2491 }
else if (ParseIntelInlineAsmIdentifier(Val,
ID, Info,
false, End,
true)) {
2492 return Error(Start,
"unable to lookup expression");
2494 return Error(Start,
"offset operator cannot yet handle constants");
2501unsigned X86AsmParser::IdentifyIntelInlineAsmOperator(StringRef Name) {
2502 return StringSwitch<unsigned>(Name)
2503 .Cases({
"TYPE",
"type"}, IOK_TYPE)
2504 .Cases({
"SIZE",
"size"}, IOK_SIZE)
2505 .Cases({
"LENGTH",
"length"}, IOK_LENGTH)
2515unsigned X86AsmParser::ParseIntelInlineAsmOperator(
unsigned OpKind) {
2516 MCAsmParser &Parser = getParser();
2517 const AsmToken &Tok = Parser.
getTok();
2520 const MCExpr *Val =
nullptr;
2521 InlineAsmIdentifierInfo
Info;
2524 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
2529 Error(Start,
"unable to lookup expression");
2536 case IOK_LENGTH: CVal =
Info.Var.Length;
break;
2537 case IOK_SIZE: CVal =
Info.Var.Size;
break;
2538 case IOK_TYPE: CVal =
Info.Var.Type;
break;
2546unsigned X86AsmParser::IdentifyMasmOperator(StringRef Name) {
2547 return StringSwitch<unsigned>(
Name.lower())
2548 .Case(
"type", MOK_TYPE)
2549 .Cases({
"size",
"sizeof"}, MOK_SIZEOF)
2550 .Cases({
"length",
"lengthof"}, MOK_LENGTHOF)
2560bool X86AsmParser::ParseMasmOperator(
unsigned OpKind, int64_t &Val) {
2561 MCAsmParser &Parser = getParser();
2566 if (OpKind == MOK_SIZEOF || OpKind == MOK_TYPE) {
2569 const AsmToken &IDTok = InParens ? getLexer().peekTok() : Parser.
getTok();
2585 IntelExprStateMachine
SM;
2587 if (ParseIntelExpression(
SM, End))
2597 Val =
SM.getLength();
2600 Val =
SM.getElementSize();
2605 return Error(OpLoc,
"expression has unknown type", SMRange(Start, End));
2611bool X86AsmParser::ParseIntelMemoryOperandSize(
unsigned &
Size,
2612 StringRef *SizeStr) {
2613 Size = StringSwitch<unsigned>(getTok().getString())
2614 .Cases({
"BYTE",
"byte"}, 8)
2615 .Cases({
"WORD",
"word"}, 16)
2616 .Cases({
"DWORD",
"dword"}, 32)
2617 .Cases({
"FLOAT",
"float"}, 32)
2618 .Cases({
"LONG",
"long"}, 32)
2619 .Cases({
"FWORD",
"fword"}, 48)
2620 .Cases({
"DOUBLE",
"double"}, 64)
2621 .Cases({
"QWORD",
"qword"}, 64)
2622 .Cases({
"MMWORD",
"mmword"}, 64)
2623 .Cases({
"XWORD",
"xword"}, 80)
2624 .Cases({
"TBYTE",
"tbyte"}, 80)
2625 .Cases({
"XMMWORD",
"xmmword"}, 128)
2626 .Cases({
"YMMWORD",
"ymmword"}, 256)
2627 .Cases({
"ZMMWORD",
"zmmword"}, 512)
2631 *SizeStr = getTok().getString();
2632 const AsmToken &Tok = Lex();
2634 return Error(Tok.
getLoc(),
"Expected 'PTR' or 'ptr' token!");
2641 if (X86MCRegisterClasses[X86::GR8RegClassID].
contains(RegNo))
2643 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(RegNo))
2645 if (X86MCRegisterClasses[X86::GR32RegClassID].
contains(RegNo))
2647 if (X86MCRegisterClasses[X86::GR64RegClassID].
contains(RegNo))
2653bool X86AsmParser::parseIntelOperand(
OperandVector &Operands, StringRef Name) {
2654 MCAsmParser &Parser = getParser();
2655 const AsmToken &Tok = Parser.
getTok();
2661 if (ParseIntelMemoryOperandSize(
Size, &SizeStr))
2663 bool PtrInOperand = bool(
Size);
2669 return ParseRoundingModeOp(Start, Operands);
2674 if (RegNo == X86::RIP)
2675 return Error(Start,
"rip can only be used as a base register");
2680 return Error(Start,
"expected memory operand after 'ptr', "
2681 "found register operand instead");
2690 "cannot cast register '" +
2692 "'; its size is not easily defined.");
2696 std::to_string(
RegSize) +
"-bit register '" +
2698 "' cannot be used as a " + std::to_string(
Size) +
"-bit " +
2705 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].
contains(RegNo))
2706 return Error(Start,
"invalid segment register");
2708 Start = Lex().getLoc();
2712 IntelExprStateMachine
SM;
2713 if (ParseIntelExpression(
SM, End))
2716 if (isParsingMSInlineAsm())
2717 RewriteIntelExpression(
SM, Start, Tok.
getLoc());
2719 int64_t
Imm =
SM.getImm();
2720 const MCExpr *Disp =
SM.getSym();
2729 if (!
SM.isMemExpr() && !RegNo) {
2730 if (isParsingMSInlineAsm() &&
SM.isOffsetOperator()) {
2731 const InlineAsmIdentifierInfo &
Info =
SM.getIdentifierInfo();
2736 SM.getSymName(),
Info.Var.Decl,
2737 Info.Var.IsGlobalLV));
2748 MCRegister IndexReg =
SM.getIndexReg();
2749 if (IndexReg && BaseReg == X86::RIP)
2751 unsigned Scale =
SM.getScale();
2753 Size =
SM.getElementSize() << 3;
2755 if (Scale == 0 && BaseReg != X86::ESP && BaseReg != X86::RSP &&
2756 (IndexReg == X86::ESP || IndexReg == X86::RSP))
2762 !(X86MCRegisterClasses[X86::VR128XRegClassID].
contains(IndexReg) ||
2763 X86MCRegisterClasses[X86::VR256XRegClassID].
contains(IndexReg) ||
2764 X86MCRegisterClasses[X86::VR512RegClassID].
contains(IndexReg)) &&
2765 (X86MCRegisterClasses[X86::VR128XRegClassID].
contains(BaseReg) ||
2766 X86MCRegisterClasses[X86::VR256XRegClassID].
contains(BaseReg) ||
2767 X86MCRegisterClasses[X86::VR512RegClassID].
contains(BaseReg)))
2771 X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg))
2772 return Error(Start,
"16-bit addresses cannot have a scale");
2781 if ((BaseReg == X86::SI || BaseReg == X86::DI) &&
2782 (IndexReg == X86::BX || IndexReg == X86::BP))
2785 if ((BaseReg || IndexReg) &&
2788 return Error(Start, ErrMsg);
2789 bool IsUnconditionalBranch =
2790 Name.equals_insensitive(
"jmp") ||
Name.equals_insensitive(
"call");
2791 if (isParsingMSInlineAsm())
2792 return CreateMemForMSInlineAsm(RegNo, Disp, BaseReg, IndexReg, Scale,
2793 IsUnconditionalBranch && is64BitMode(),
2794 Start, End,
Size,
SM.getSymName(),
2795 SM.getIdentifierInfo(), Operands);
2799 MCRegister DefaultBaseReg;
2800 bool MaybeDirectBranchDest =
true;
2803 if (is64BitMode() &&
2804 ((PtrInOperand && !IndexReg) ||
SM.getElementSize() > 0)) {
2805 DefaultBaseReg = X86::RIP;
2807 if (IsUnconditionalBranch) {
2809 MaybeDirectBranchDest =
false;
2811 DefaultBaseReg = X86::RIP;
2812 }
else if (!BaseReg && !IndexReg && Disp &&
2814 if (is64BitMode()) {
2815 if (
SM.getSize() == 8) {
2816 MaybeDirectBranchDest =
false;
2817 DefaultBaseReg = X86::RIP;
2820 if (
SM.getSize() == 4 ||
SM.getSize() == 2)
2821 MaybeDirectBranchDest =
false;
2825 }
else if (IsUnconditionalBranch) {
2827 if (!PtrInOperand &&
SM.isOffsetOperator())
2829 Start,
"`OFFSET` operator cannot be used in an unconditional branch");
2830 if (PtrInOperand ||
SM.isBracketUsed())
2831 MaybeDirectBranchDest =
false;
2834 if (CheckDispOverflow(BaseReg, IndexReg, Disp, Start))
2837 if ((BaseReg || IndexReg || RegNo || DefaultBaseReg))
2839 getPointerWidth(), RegNo, Disp, BaseReg, IndexReg, Scale, Start, End,
2840 Size, DefaultBaseReg, StringRef(),
nullptr,
2841 0,
false, MaybeDirectBranchDest));
2844 getPointerWidth(), Disp, Start, End,
Size, StringRef(),
2846 MaybeDirectBranchDest));
2850bool X86AsmParser::parseATTOperand(
OperandVector &Operands) {
2851 MCAsmParser &Parser = getParser();
2852 switch (getLexer().getKind()) {
2862 "expected immediate expression") ||
2863 getParser().parseExpression(Val, End) ||
2871 return ParseRoundingModeOp(Start, Operands);
2880 const MCExpr *Expr =
nullptr;
2892 if (
Reg == X86::EIZ ||
Reg == X86::RIZ)
2894 Loc,
"%eiz and %riz can only be used as index registers",
2895 SMRange(Loc, EndLoc));
2896 if (
Reg == X86::RIP)
2897 return Error(Loc,
"%rip can only be used as a base register",
2898 SMRange(Loc, EndLoc));
2904 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].
contains(
Reg))
2905 return Error(Loc,
"invalid segment register");
2913 return ParseMemOperand(
Reg, Expr, Loc, EndLoc, Operands);
2920X86::CondCode X86AsmParser::ParseConditionCode(StringRef CC) {
2921 return StringSwitch<X86::CondCode>(CC)
2943bool X86AsmParser::ParseZ(std::unique_ptr<X86Operand> &Z, SMLoc StartLoc) {
2944 MCAsmParser &Parser = getParser();
2949 (getLexer().getTok().getIdentifier() ==
"z")))
2954 return Error(getLexer().getLoc(),
"Expected } at this point");
2962bool X86AsmParser::HandleAVX512Operand(
OperandVector &Operands) {
2963 MCAsmParser &Parser = getParser();
2966 const SMLoc consumedToken = consumeToken();
2970 if (getLexer().getTok().getIntVal() != 1)
2971 return TokError(
"Expected 1to<NUM> at this point");
2972 StringRef
Prefix = getLexer().getTok().getString();
2975 return TokError(
"Expected 1to<NUM> at this point");
2978 StringRef BroadcastString = (
Prefix + getLexer().getTok().getIdentifier())
2981 return TokError(
"Expected 1to<NUM> at this point");
2982 const char *BroadcastPrimitive =
2983 StringSwitch<const char *>(BroadcastString)
2984 .Case(
"1to2",
"{1to2}")
2985 .Case(
"1to4",
"{1to4}")
2986 .Case(
"1to8",
"{1to8}")
2987 .Case(
"1to16",
"{1to16}")
2988 .Case(
"1to32",
"{1to32}")
2990 if (!BroadcastPrimitive)
2991 return TokError(
"Invalid memory broadcast primitive.");
2994 return TokError(
"Expected } at this point");
3005 std::unique_ptr<X86Operand>
Z;
3006 if (ParseZ(Z, consumedToken))
3012 SMLoc StartLoc =
Z ? consumeToken() : consumedToken;
3017 if (!parseRegister(RegNo, RegLoc, StartLoc) &&
3018 X86MCRegisterClasses[X86::VK1RegClassID].
contains(RegNo)) {
3019 if (RegNo == X86::K0)
3020 return Error(RegLoc,
"Register k0 can't be used as write mask");
3022 return Error(getLexer().getLoc(),
"Expected } at this point");
3028 return Error(getLexer().getLoc(),
3029 "Expected an op-mask register at this point");
3034 if (ParseZ(Z, consumeToken()) || !Z)
3035 return Error(getLexer().getLoc(),
3036 "Expected a {z} mark at this point");
3051bool X86AsmParser::CheckDispOverflow(MCRegister BaseReg, MCRegister IndexReg,
3052 const MCExpr *Disp, SMLoc Loc) {
3058 if (BaseReg || IndexReg) {
3060 auto Imm =
CE->getValue();
3061 bool Is64 = X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) ||
3062 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg);
3063 bool Is16 = X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg);
3066 return Error(Loc,
"displacement " + Twine(Imm) +
3067 " is not within [-2147483648, 2147483647]");
3069 if (!
isUInt<32>(Imm < 0 ? -uint64_t(Imm) : uint64_t(Imm))) {
3070 Warning(Loc,
"displacement " + Twine(Imm) +
3071 " shortened to 32-bit signed " +
3072 Twine(
static_cast<int32_t
>(Imm)));
3074 }
else if (!
isUInt<16>(Imm < 0 ? -uint64_t(Imm) : uint64_t(Imm))) {
3075 Warning(Loc,
"displacement " + Twine(Imm) +
3076 " shortened to 16-bit signed " +
3077 Twine(
static_cast<int16_t
>(Imm)));
3086bool X86AsmParser::ParseMemOperand(MCRegister SegReg,
const MCExpr *Disp,
3087 SMLoc StartLoc, SMLoc EndLoc,
3089 MCAsmParser &Parser = getParser();
3107 auto isAtMemOperand = [
this]() {
3112 auto TokCount = this->getLexer().peekTokens(Buf,
true);
3115 switch (Buf[0].getKind()) {
3122 if ((TokCount > 1) &&
3126 Buf[1].getIdentifier().
size() + 1);
3148 if (!isAtMemOperand()) {
3167 0, 0, 1, StartLoc, EndLoc));
3175 SMLoc BaseLoc = getLexer().getLoc();
3187 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ)
3188 return Error(BaseLoc,
"eiz and riz can only be used as index registers",
3189 SMRange(BaseLoc, EndLoc));
3207 if (!
E->evaluateAsAbsolute(ScaleVal, getStreamer().getAssemblerPtr()))
3208 return Error(Loc,
"expected absolute expression");
3210 Warning(Loc,
"scale factor without index register is ignored");
3215 if (BaseReg == X86::RIP)
3217 "%rip as base register can not have an index register");
3218 if (IndexReg == X86::RIP)
3219 return Error(Loc,
"%rip is not allowed as an index register");
3230 return Error(Loc,
"expected scale expression");
3231 Scale = (unsigned)ScaleVal;
3233 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg) &&
3235 return Error(Loc,
"scale factor in 16-bit address must be 1");
3237 return Error(Loc, ErrMsg);
3251 if (BaseReg == X86::DX && !IndexReg && Scale == 1 && !SegReg &&
3260 return Error(BaseLoc, ErrMsg);
3262 if (CheckDispOverflow(BaseReg, IndexReg, Disp, BaseLoc))
3265 if (SegReg || BaseReg || IndexReg)
3267 BaseReg, IndexReg, Scale, StartLoc,
3276bool X86AsmParser::parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
3277 MCAsmParser &Parser = getParser();
3284 if (parseRegister(RegNo, StartLoc, EndLoc))
3292bool X86AsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
3294 MCAsmParser &Parser = getParser();
3298 ForcedOpcodePrefix = OpcodePrefix_Default;
3299 ForcedDispEncoding = DispEncoding_Default;
3300 UseApxExtendedReg =
false;
3301 ForcedNoFlag =
false;
3314 if (Prefix ==
"rex")
3315 ForcedOpcodePrefix = OpcodePrefix_REX;
3316 else if (Prefix ==
"rex2")
3317 ForcedOpcodePrefix = OpcodePrefix_REX2;
3318 else if (Prefix ==
"vex")
3319 ForcedOpcodePrefix = OpcodePrefix_VEX;
3320 else if (Prefix ==
"vex2")
3321 ForcedOpcodePrefix = OpcodePrefix_VEX2;
3322 else if (Prefix ==
"vex3")
3323 ForcedOpcodePrefix = OpcodePrefix_VEX3;
3324 else if (Prefix ==
"evex")
3325 ForcedOpcodePrefix = OpcodePrefix_EVEX;
3326 else if (Prefix ==
"disp8")
3327 ForcedDispEncoding = DispEncoding_Disp8;
3328 else if (Prefix ==
"disp32")
3329 ForcedDispEncoding = DispEncoding_Disp32;
3330 else if (Prefix ==
"nf")
3331 ForcedNoFlag =
true;
3333 return Error(NameLoc,
"unknown prefix");
3349 if (isParsingMSInlineAsm()) {
3350 if (
Name.equals_insensitive(
"vex"))
3351 ForcedOpcodePrefix = OpcodePrefix_VEX;
3352 else if (
Name.equals_insensitive(
"vex2"))
3353 ForcedOpcodePrefix = OpcodePrefix_VEX2;
3354 else if (
Name.equals_insensitive(
"vex3"))
3355 ForcedOpcodePrefix = OpcodePrefix_VEX3;
3356 else if (
Name.equals_insensitive(
"evex"))
3357 ForcedOpcodePrefix = OpcodePrefix_EVEX;
3359 if (ForcedOpcodePrefix != OpcodePrefix_Default) {
3372 if (
Name.consume_back(
".d32")) {
3373 ForcedDispEncoding = DispEncoding_Disp32;
3374 }
else if (
Name.consume_back(
".d8")) {
3375 ForcedDispEncoding = DispEncoding_Disp8;
3378 StringRef PatchedName =
Name;
3381 if (isParsingIntelSyntax() &&
3382 (PatchedName ==
"jmp" || PatchedName ==
"jc" || PatchedName ==
"jnc" ||
3383 PatchedName ==
"jcxz" || PatchedName ==
"jecxz" ||
3388 : NextTok ==
"short") {
3397 NextTok.
size() + 1);
3403 PatchedName !=
"setzub" && PatchedName !=
"setzunb" &&
3404 PatchedName !=
"setb" && PatchedName !=
"setnb")
3405 PatchedName = PatchedName.
substr(0,
Name.size()-1);
3407 unsigned ComparisonPredicate = ~0
U;
3415 bool IsVCMP = PatchedName[0] ==
'v';
3416 unsigned CCIdx =
IsVCMP ? 4 : 3;
3417 unsigned suffixLength = PatchedName.
ends_with(
"bf16") ? 5 : 2;
3418 unsigned CC = StringSwitch<unsigned>(
3419 PatchedName.
slice(CCIdx, PatchedName.
size() - suffixLength))
3421 .Case(
"eq_oq", 0x00)
3423 .Case(
"lt_os", 0x01)
3425 .Case(
"le_os", 0x02)
3426 .Case(
"unord", 0x03)
3427 .Case(
"unord_q", 0x03)
3429 .Case(
"neq_uq", 0x04)
3431 .Case(
"nlt_us", 0x05)
3433 .Case(
"nle_us", 0x06)
3435 .Case(
"ord_q", 0x07)
3437 .Case(
"eq_uq", 0x08)
3439 .Case(
"nge_us", 0x09)
3441 .Case(
"ngt_us", 0x0A)
3442 .Case(
"false", 0x0B)
3443 .Case(
"false_oq", 0x0B)
3444 .Case(
"neq_oq", 0x0C)
3446 .Case(
"ge_os", 0x0D)
3448 .Case(
"gt_os", 0x0E)
3450 .Case(
"true_uq", 0x0F)
3451 .Case(
"eq_os", 0x10)
3452 .Case(
"lt_oq", 0x11)
3453 .Case(
"le_oq", 0x12)
3454 .Case(
"unord_s", 0x13)
3455 .Case(
"neq_us", 0x14)
3456 .Case(
"nlt_uq", 0x15)
3457 .Case(
"nle_uq", 0x16)
3458 .Case(
"ord_s", 0x17)
3459 .Case(
"eq_us", 0x18)
3460 .Case(
"nge_uq", 0x19)
3461 .Case(
"ngt_uq", 0x1A)
3462 .Case(
"false_os", 0x1B)
3463 .Case(
"neq_os", 0x1C)
3464 .Case(
"ge_oq", 0x1D)
3465 .Case(
"gt_oq", 0x1E)
3466 .Case(
"true_us", 0x1F)
3468 if (CC != ~0U && (
IsVCMP || CC < 8) &&
3471 PatchedName =
IsVCMP ?
"vcmpss" :
"cmpss";
3473 PatchedName =
IsVCMP ?
"vcmpsd" :
"cmpsd";
3475 PatchedName =
IsVCMP ?
"vcmpps" :
"cmpps";
3477 PatchedName =
IsVCMP ?
"vcmppd" :
"cmppd";
3479 PatchedName =
"vcmpsh";
3481 PatchedName =
"vcmpph";
3483 PatchedName =
"vcmpbf16";
3487 ComparisonPredicate = CC;
3493 (PatchedName.
back() ==
'b' || PatchedName.
back() ==
'w' ||
3494 PatchedName.
back() ==
'd' || PatchedName.
back() ==
'q')) {
3495 unsigned SuffixSize = PatchedName.
drop_back().
back() ==
'u' ? 2 : 1;
3496 unsigned CC = StringSwitch<unsigned>(
3497 PatchedName.
slice(5, PatchedName.
size() - SuffixSize))
3507 if (CC != ~0U && (CC != 0 || SuffixSize == 2)) {
3508 switch (PatchedName.
back()) {
3510 case 'b': PatchedName = SuffixSize == 2 ?
"vpcmpub" :
"vpcmpb";
break;
3511 case 'w': PatchedName = SuffixSize == 2 ?
"vpcmpuw" :
"vpcmpw";
break;
3512 case 'd': PatchedName = SuffixSize == 2 ?
"vpcmpud" :
"vpcmpd";
break;
3513 case 'q': PatchedName = SuffixSize == 2 ?
"vpcmpuq" :
"vpcmpq";
break;
3516 ComparisonPredicate = CC;
3522 (PatchedName.
back() ==
'b' || PatchedName.
back() ==
'w' ||
3523 PatchedName.
back() ==
'd' || PatchedName.
back() ==
'q')) {
3524 unsigned SuffixSize = PatchedName.
drop_back().
back() ==
'u' ? 2 : 1;
3525 unsigned CC = StringSwitch<unsigned>(
3526 PatchedName.
slice(5, PatchedName.
size() - SuffixSize))
3537 switch (PatchedName.
back()) {
3539 case 'b': PatchedName = SuffixSize == 2 ?
"vpcomub" :
"vpcomb";
break;
3540 case 'w': PatchedName = SuffixSize == 2 ?
"vpcomuw" :
"vpcomw";
break;
3541 case 'd': PatchedName = SuffixSize == 2 ?
"vpcomud" :
"vpcomd";
break;
3542 case 'q': PatchedName = SuffixSize == 2 ?
"vpcomuq" :
"vpcomq";
break;
3545 ComparisonPredicate = CC;
3557 StringSwitch<bool>(Name)
3558 .Cases({
"cs",
"ds",
"es",
"fs",
"gs",
"ss"},
true)
3559 .Cases({
"rex64",
"data32",
"data16",
"addr32",
"addr16"},
true)
3560 .Cases({
"xacquire",
"xrelease"},
true)
3561 .Cases({
"acquire",
"release"}, isParsingIntelSyntax())
3564 auto isLockRepeatNtPrefix = [](StringRef
N) {
3565 return StringSwitch<bool>(
N)
3566 .Cases({
"lock",
"rep",
"repe",
"repz",
"repne",
"repnz",
"notrack"},
3571 bool CurlyAsEndOfStatement =
false;
3574 while (isLockRepeatNtPrefix(
Name.lower())) {
3576 StringSwitch<unsigned>(Name)
3595 while (
Name.starts_with(
";") ||
Name.starts_with(
"\n") ||
3596 Name.starts_with(
"#") ||
Name.starts_with(
"\t") ||
3597 Name.starts_with(
"/")) {
3608 if (PatchedName ==
"data16" && is16BitMode()) {
3609 return Error(NameLoc,
"redundant data16 prefix");
3611 if (PatchedName ==
"data32") {
3613 return Error(NameLoc,
"redundant data32 prefix");
3615 return Error(NameLoc,
"'data32' is not supported in 64-bit mode");
3617 PatchedName =
"data16";
3624 if (
Next ==
"callw")
3626 if (
Next ==
"ljmpw")
3631 ForcedDataPrefix = X86::Is32Bit;
3639 if (ComparisonPredicate != ~0U && !isParsingIntelSyntax()) {
3646 if ((
Name.starts_with(
"ccmp") ||
Name.starts_with(
"ctest")) &&
3647 parseCFlagsOp(Operands))
3661 if (parseOperand(Operands, Name))
3663 if (HandleAVX512Operand(Operands))
3675 CurlyAsEndOfStatement =
3676 isParsingIntelSyntax() && isParsingMSInlineAsm() &&
3679 return TokError(
"unexpected token in argument list");
3683 if (ComparisonPredicate != ~0U && isParsingIntelSyntax()) {
3693 else if (CurlyAsEndOfStatement)
3696 getLexer().getTok().getLoc(), 0);
3703 if (IsFp && Operands.
size() == 1) {
3704 const char *Repl = StringSwitch<const char *>(Name)
3705 .Case(
"fsub",
"fsubp")
3706 .Case(
"fdiv",
"fdivp")
3707 .Case(
"fsubr",
"fsubrp")
3708 .Case(
"fdivr",
"fdivrp");
3709 static_cast<X86Operand &
>(*Operands[0]).setTokenValue(Repl);
3712 if ((Name ==
"mov" || Name ==
"movw" || Name ==
"movl") &&
3713 (Operands.
size() == 3)) {
3714 X86Operand &Op1 = (X86Operand &)*Operands[1];
3715 X86Operand &Op2 = (X86Operand &)*Operands[2];
3720 X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(
3722 (X86MCRegisterClasses[X86::GR16RegClassID].contains(Op1.
getReg()) ||
3723 X86MCRegisterClasses[X86::GR32RegClassID].contains(Op1.
getReg()))) {
3725 if (Name !=
"mov" && Name[3] == (is16BitMode() ?
'l' :
'w')) {
3726 Name = is16BitMode() ?
"movw" :
"movl";
3739 if ((Name ==
"outb" || Name ==
"outsb" || Name ==
"outw" || Name ==
"outsw" ||
3740 Name ==
"outl" || Name ==
"outsl" || Name ==
"out" || Name ==
"outs") &&
3741 Operands.
size() == 3) {
3742 X86Operand &
Op = (X86Operand &)*Operands.
back();
3748 if ((Name ==
"inb" || Name ==
"insb" || Name ==
"inw" || Name ==
"insw" ||
3749 Name ==
"inl" || Name ==
"insl" || Name ==
"in" || Name ==
"ins") &&
3750 Operands.
size() == 3) {
3751 X86Operand &
Op = (X86Operand &)*Operands[1];
3758 bool HadVerifyError =
false;
3761 if (
Name.starts_with(
"ins") &&
3762 (Operands.
size() == 1 || Operands.
size() == 3) &&
3763 (Name ==
"insb" || Name ==
"insw" || Name ==
"insl" || Name ==
"insd" ||
3766 AddDefaultSrcDestOperands(TmpOperands,
3768 DefaultMemDIOperand(NameLoc));
3769 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3773 if (
Name.starts_with(
"outs") &&
3774 (Operands.
size() == 1 || Operands.
size() == 3) &&
3775 (Name ==
"outsb" || Name ==
"outsw" || Name ==
"outsl" ||
3776 Name ==
"outsd" || Name ==
"outs")) {
3777 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
3779 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3785 if (
Name.starts_with(
"lods") &&
3786 (Operands.
size() == 1 || Operands.
size() == 2) &&
3787 (Name ==
"lods" || Name ==
"lodsb" || Name ==
"lodsw" ||
3788 Name ==
"lodsl" || Name ==
"lodsd" || Name ==
"lodsq")) {
3789 TmpOperands.
push_back(DefaultMemSIOperand(NameLoc));
3790 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3796 if (
Name.starts_with(
"stos") &&
3797 (Operands.
size() == 1 || Operands.
size() == 2) &&
3798 (Name ==
"stos" || Name ==
"stosb" || Name ==
"stosw" ||
3799 Name ==
"stosl" || Name ==
"stosd" || Name ==
"stosq")) {
3800 TmpOperands.
push_back(DefaultMemDIOperand(NameLoc));
3801 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3807 if (
Name.starts_with(
"scas") &&
3808 (Operands.
size() == 1 || Operands.
size() == 2) &&
3809 (Name ==
"scas" || Name ==
"scasb" || Name ==
"scasw" ||
3810 Name ==
"scasl" || Name ==
"scasd" || Name ==
"scasq")) {
3811 TmpOperands.
push_back(DefaultMemDIOperand(NameLoc));
3812 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3816 if (
Name.starts_with(
"cmps") &&
3817 (Operands.
size() == 1 || Operands.
size() == 3) &&
3818 (Name ==
"cmps" || Name ==
"cmpsb" || Name ==
"cmpsw" ||
3819 Name ==
"cmpsl" || Name ==
"cmpsd" || Name ==
"cmpsq")) {
3820 AddDefaultSrcDestOperands(TmpOperands, DefaultMemDIOperand(NameLoc),
3821 DefaultMemSIOperand(NameLoc));
3822 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3826 if (((
Name.starts_with(
"movs") &&
3827 (Name ==
"movs" || Name ==
"movsb" || Name ==
"movsw" ||
3828 Name ==
"movsl" || Name ==
"movsd" || Name ==
"movsq")) ||
3829 (
Name.starts_with(
"smov") &&
3830 (Name ==
"smov" || Name ==
"smovb" || Name ==
"smovw" ||
3831 Name ==
"smovl" || Name ==
"smovd" || Name ==
"smovq"))) &&
3832 (Operands.
size() == 1 || Operands.
size() == 3)) {
3833 if (Name ==
"movsd" && Operands.
size() == 1 && !isParsingIntelSyntax())
3835 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
3836 DefaultMemDIOperand(NameLoc));
3837 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3841 if (HadVerifyError) {
3842 return HadVerifyError;
3846 if ((Name ==
"xlat" || Name ==
"xlatb") && Operands.
size() == 2) {
3847 X86Operand &Op1 =
static_cast<X86Operand &
>(*Operands[1]);
3850 "size, (R|E)BX will be used for the location");
3852 static_cast<X86Operand &
>(*Operands[0]).setTokenValue(
"xlatb");
3865 if (
I == Table.
end() ||
I->OldOpc != Opcode)
3871 if (X86::isBLENDVPD(Opcode) || X86::isBLENDVPS(Opcode) ||
3872 X86::isPBLENDVB(Opcode))
3878bool X86AsmParser::processInstruction(MCInst &Inst,
const OperandVector &
Ops) {
3882 if (ForcedOpcodePrefix != OpcodePrefix_VEX3 &&
3889 auto replaceWithCCMPCTEST = [&](
unsigned Opcode) ->
bool {
3890 if (ForcedOpcodePrefix == OpcodePrefix_EVEX) {
3901 default:
return false;
3906 if (ForcedDispEncoding == DispEncoding_Disp32) {
3907 Inst.
setOpcode(is16BitMode() ? X86::JMP_2 : X86::JMP_4);
3916 if (ForcedDispEncoding == DispEncoding_Disp32) {
3917 Inst.
setOpcode(is16BitMode() ? X86::JCC_2 : X86::JCC_4);
3933#define FROM_TO(FROM, TO) \
3935 return replaceWithCCMPCTEST(X86::TO);
3937 FROM_TO(CMP64mi32, CCMP64mi32)
3940 FROM_TO(CMP64ri32, CCMP64ri32)
3967 FROM_TO(TEST64mi32, CTEST64mi32)
3969 FROM_TO(TEST64ri32, CTEST64ri32)
3989bool X86AsmParser::validateInstruction(MCInst &Inst,
const OperandVector &
Ops) {
3990 using namespace X86;
3991 const MCRegisterInfo *MRI =
getContext().getRegisterInfo();
3993 uint64_t TSFlags = MII.get(Opcode).TSFlags;
3994 if (isVFCMADDCPH(Opcode) || isVFCMADDCSH(Opcode) || isVFMADDCPH(Opcode) ||
3995 isVFMADDCSH(Opcode)) {
3999 return Warning(
Ops[0]->getStartLoc(),
"Destination register should be "
4000 "distinct from source registers");
4001 }
else if (isVFCMULCPH(Opcode) || isVFCMULCSH(Opcode) || isVFMULCPH(Opcode) ||
4002 isVFMULCSH(Opcode)) {
4012 return Warning(
Ops[0]->getStartLoc(),
"Destination register should be "
4013 "distinct from source registers");
4014 }
else if (isV4FMADDPS(Opcode) || isV4FMADDSS(Opcode) ||
4015 isV4FNMADDPS(Opcode) || isV4FNMADDSS(Opcode) ||
4016 isVP4DPWSSDS(Opcode) || isVP4DPWSSD(Opcode)) {
4021 if (Src2Enc % 4 != 0) {
4023 unsigned GroupStart = (Src2Enc / 4) * 4;
4024 unsigned GroupEnd = GroupStart + 3;
4026 "source register '" +
RegName +
"' implicitly denotes '" +
4027 RegName.take_front(3) + Twine(GroupStart) +
"' to '" +
4028 RegName.take_front(3) + Twine(GroupEnd) +
4031 }
else if (isVGATHERDPD(Opcode) || isVGATHERDPS(Opcode) ||
4032 isVGATHERQPD(Opcode) || isVGATHERQPS(Opcode) ||
4033 isVPGATHERDD(Opcode) || isVPGATHERDQ(Opcode) ||
4034 isVPGATHERQD(Opcode) || isVPGATHERQQ(Opcode)) {
4041 return Warning(
Ops[0]->getStartLoc(),
"index and destination registers "
4042 "should be distinct");
4048 if (Dest == Mask || Dest == Index || Mask == Index)
4049 return Warning(
Ops[0]->getStartLoc(),
"mask, index, and destination "
4050 "registers should be distinct");
4052 }
else if (isTCMMIMFP16PS(Opcode) || isTCMMRLFP16PS(Opcode) ||
4053 isTDPBF16PS(Opcode) || isTDPFP16PS(Opcode) || isTDPBSSD(Opcode) ||
4054 isTDPBSUD(Opcode) || isTDPBUSD(Opcode) || isTDPBUUD(Opcode)) {
4058 if (SrcDest == Src1 || SrcDest == Src2 || Src1 == Src2)
4059 return Error(
Ops[0]->getStartLoc(),
"all tmm registers must be distinct");
4073 for (
unsigned i = 0; i !=
NumOps; ++i) {
4078 if (
Reg == X86::AH ||
Reg == X86::BH ||
Reg == X86::CH ||
Reg == X86::DH)
4086 (Enc ==
X86II::EVEX || ForcedOpcodePrefix == OpcodePrefix_REX2 ||
4087 ForcedOpcodePrefix == OpcodePrefix_REX || UsesRex)) {
4089 return Error(
Ops[0]->getStartLoc(),
4090 "can't encode '" +
RegName.str() +
4091 "' in an instruction requiring EVEX/REX2/REX prefix");
4095 if ((Opcode == X86::PREFETCHIT0 || Opcode == X86::PREFETCHIT1)) {
4099 Ops[0]->getStartLoc(),
4100 Twine((Inst.
getOpcode() == X86::PREFETCHIT0 ?
"'prefetchit0'"
4101 :
"'prefetchit1'")) +
4102 " only supports RIP-relative address");
4107void X86AsmParser::emitWarningForSpecialLVIInstruction(SMLoc Loc) {
4108 Warning(Loc,
"Instruction may be vulnerable to LVI and "
4109 "requires manual mitigation");
4110 Note(SMLoc(),
"See https://software.intel.com/"
4111 "security-software-guidance/insights/"
4112 "deep-dive-load-value-injection#specialinstructions"
4113 " for more information");
4125void X86AsmParser::applyLVICFIMitigation(MCInst &Inst, MCStreamer &Out) {
4136 MCInst ShlInst, FenceInst;
4137 bool Parse32 = is32BitMode() || Code16GCC;
4138 MCRegister Basereg =
4139 is64BitMode() ? X86::RSP : (Parse32 ? X86::ESP : X86::SP);
4143 1, SMLoc{}, SMLoc{}, 0);
4145 ShlMemOp->addMemOperands(ShlInst, 5);
4158 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4170void X86AsmParser::applyLVILoadHardeningMitigation(MCInst &Inst,
4187 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4190 }
else if (Opcode == X86::REP_PREFIX || Opcode == X86::REPNE_PREFIX) {
4193 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4197 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
4212void X86AsmParser::emitInstruction(MCInst &Inst,
OperandVector &Operands,
4215 getSTI().hasFeature(X86::FeatureLVIControlFlowIntegrity))
4216 applyLVICFIMitigation(Inst, Out);
4221 getSTI().hasFeature(X86::FeatureLVILoadHardening))
4222 applyLVILoadHardeningMitigation(Inst, Out);
4226 unsigned Result = 0;
4228 if (Prefix.isPrefix()) {
4229 Result = Prefix.getPrefix();
4235bool X86AsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
4237 MCStreamer &Out, uint64_t &ErrorInfo,
4238 bool MatchingInlineAsm) {
4239 assert(!Operands.
empty() &&
"Unexpect empty operand list!");
4240 assert((*Operands[0]).isToken() &&
"Leading operand should always be a mnemonic!");
4243 MatchFPUWaitAlias(IDLoc,
static_cast<X86Operand &
>(*Operands[0]), Operands,
4244 Out, MatchingInlineAsm);
4251 if (ForcedOpcodePrefix == OpcodePrefix_REX)
4253 else if (ForcedOpcodePrefix == OpcodePrefix_REX2)
4255 else if (ForcedOpcodePrefix == OpcodePrefix_VEX)
4257 else if (ForcedOpcodePrefix == OpcodePrefix_VEX2)
4259 else if (ForcedOpcodePrefix == OpcodePrefix_VEX3)
4261 else if (ForcedOpcodePrefix == OpcodePrefix_EVEX)
4265 if (ForcedDispEncoding == DispEncoding_Disp8)
4267 else if (ForcedDispEncoding == DispEncoding_Disp32)
4273 return isParsingIntelSyntax()
4274 ? matchAndEmitIntelInstruction(IDLoc, Opcode, Inst, Operands, Out,
4275 ErrorInfo, MatchingInlineAsm)
4276 : matchAndEmitATTInstruction(IDLoc, Opcode, Inst, Operands, Out,
4277 ErrorInfo, MatchingInlineAsm);
4280void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &
Op,
4282 bool MatchingInlineAsm) {
4286 const char *Repl = StringSwitch<const char *>(
Op.getToken())
4287 .Case(
"finit",
"fninit")
4288 .Case(
"fsave",
"fnsave")
4289 .Case(
"fstcw",
"fnstcw")
4290 .Case(
"fstcww",
"fnstcw")
4291 .Case(
"fstenv",
"fnstenv")
4292 .Case(
"fstsw",
"fnstsw")
4293 .Case(
"fstsww",
"fnstsw")
4294 .Case(
"fclex",
"fnclex")
4300 if (!MatchingInlineAsm)
4306bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc,
4307 const FeatureBitset &MissingFeatures,
4308 bool MatchingInlineAsm) {
4309 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
4310 SmallString<126> Msg;
4311 raw_svector_ostream OS(Msg);
4312 OS <<
"instruction requires:";
4313 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
4314 if (MissingFeatures[i])
4317 return Error(IDLoc, OS.str(), SMRange(), MatchingInlineAsm);
4320unsigned X86AsmParser::checkTargetMatchPredicate(MCInst &Inst) {
4322 const MCInstrDesc &MCID = MII.get(
Opc);
4323 uint64_t TSFlags = MCID.
TSFlags;
4326 return Match_Unsupported;
4328 return Match_Unsupported;
4330 switch (ForcedOpcodePrefix) {
4331 case OpcodePrefix_Default:
4333 case OpcodePrefix_REX:
4334 case OpcodePrefix_REX2:
4336 return Match_Unsupported;
4338 case OpcodePrefix_VEX:
4339 case OpcodePrefix_VEX2:
4340 case OpcodePrefix_VEX3:
4342 return Match_Unsupported;
4344 case OpcodePrefix_EVEX:
4346 !X86::isCMP(
Opc) && !X86::isTEST(
Opc))
4347 return Match_Unsupported;
4349 return Match_Unsupported;
4354 (ForcedOpcodePrefix != OpcodePrefix_VEX &&
4355 ForcedOpcodePrefix != OpcodePrefix_VEX2 &&
4356 ForcedOpcodePrefix != OpcodePrefix_VEX3))
4357 return Match_Unsupported;
4359 return Match_Success;
4362bool X86AsmParser::matchAndEmitATTInstruction(
4363 SMLoc IDLoc,
unsigned &Opcode, MCInst &Inst,
OperandVector &Operands,
4364 MCStreamer &Out, uint64_t &ErrorInfo,
bool MatchingInlineAsm) {
4365 X86Operand &
Op =
static_cast<X86Operand &
>(*Operands[0]);
4369 if (ForcedDataPrefix == X86::Is32Bit)
4370 SwitchMode(X86::Is32Bit);
4372 FeatureBitset MissingFeatures;
4373 unsigned OriginalError = MatchInstruction(Operands, Inst, ErrorInfo,
4374 MissingFeatures, MatchingInlineAsm,
4375 isParsingIntelSyntax());
4376 if (ForcedDataPrefix == X86::Is32Bit) {
4377 SwitchMode(X86::Is16Bit);
4378 ForcedDataPrefix = 0;
4380 switch (OriginalError) {
4383 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
4388 if (!MatchingInlineAsm)
4389 while (processInstruction(Inst, Operands))
4393 if (!MatchingInlineAsm)
4397 case Match_InvalidImmUnsignedi4: {
4398 SMLoc ErrorLoc = ((X86Operand &)*Operands[ErrorInfo]).getStartLoc();
4399 if (ErrorLoc == SMLoc())
4401 return Error(ErrorLoc,
"immediate must be an integer in range [0, 15]",
4402 EmptyRange, MatchingInlineAsm);
4404 case Match_InvalidImmUnsignedi6: {
4405 SMLoc ErrorLoc = ((X86Operand &)*Operands[ErrorInfo]).getStartLoc();
4406 if (ErrorLoc == SMLoc())
4408 return Error(ErrorLoc,
"immediate must be an integer in range [0, 63]",
4409 EmptyRange, MatchingInlineAsm);
4411 case Match_MissingFeature:
4412 return ErrorMissingFeature(IDLoc, MissingFeatures, MatchingInlineAsm);
4413 case Match_InvalidOperand:
4414 case Match_MnemonicFail:
4415 case Match_Unsupported:
4418 if (
Op.getToken().empty()) {
4419 Error(IDLoc,
"instruction must have size higher than 0", EmptyRange,
4430 StringRef
Base =
Op.getToken();
4431 SmallString<16> Tmp;
4434 Op.setTokenValue(Tmp);
4442 const char *Suffixes =
Base[0] !=
'f' ?
"bwlq" :
"slt\0";
4444 const char *MemSize =
Base[0] !=
'f' ?
"\x08\x10\x20\x40" :
"\x20\x40\x50\0";
4447 uint64_t ErrorInfoIgnore;
4448 FeatureBitset ErrorInfoMissingFeatures;
4456 bool HasVectorReg =
false;
4457 X86Operand *MemOp =
nullptr;
4458 for (
const auto &
Op : Operands) {
4459 X86Operand *X86Op =
static_cast<X86Operand *
>(
Op.get());
4461 HasVectorReg =
true;
4462 else if (X86Op->
isMem()) {
4464 assert(MemOp->Mem.Size == 0 &&
"Memory size always 0 under ATT syntax");
4471 for (
unsigned I = 0,
E = std::size(Match);
I !=
E; ++
I) {
4472 Tmp.
back() = Suffixes[
I];
4473 if (MemOp && HasVectorReg)
4474 MemOp->Mem.Size = MemSize[
I];
4475 Match[
I] = Match_MnemonicFail;
4476 if (MemOp || !HasVectorReg) {
4478 MatchInstruction(Operands, Inst, ErrorInfoIgnore, MissingFeatures,
4479 MatchingInlineAsm, isParsingIntelSyntax());
4481 if (Match[
I] == Match_MissingFeature)
4482 ErrorInfoMissingFeatures = MissingFeatures;
4492 unsigned NumSuccessfulMatches =
llvm::count(Match, Match_Success);
4493 if (NumSuccessfulMatches == 1) {
4494 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
4499 if (!MatchingInlineAsm)
4500 while (processInstruction(Inst, Operands))
4504 if (!MatchingInlineAsm)
4514 if (NumSuccessfulMatches > 1) {
4516 unsigned NumMatches = 0;
4517 for (
unsigned I = 0,
E = std::size(Match);
I !=
E; ++
I)
4518 if (Match[
I] == Match_Success)
4519 MatchChars[NumMatches++] = Suffixes[
I];
4521 SmallString<126> Msg;
4522 raw_svector_ostream OS(Msg);
4523 OS <<
"ambiguous instructions require an explicit suffix (could be ";
4524 for (
unsigned i = 0; i != NumMatches; ++i) {
4527 if (i + 1 == NumMatches)
4529 OS <<
"'" <<
Base << MatchChars[i] <<
"'";
4532 Error(IDLoc, OS.str(), EmptyRange, MatchingInlineAsm);
4540 if (
llvm::count(Match, Match_MnemonicFail) == 4) {
4541 if (OriginalError == Match_MnemonicFail)
4542 return Error(IDLoc,
"invalid instruction mnemonic '" +
Base +
"'",
4543 Op.getLocRange(), MatchingInlineAsm);
4545 if (OriginalError == Match_Unsupported)
4546 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4549 assert(OriginalError == Match_InvalidOperand &&
"Unexpected error");
4551 if (ErrorInfo != ~0ULL) {
4552 if (ErrorInfo >= Operands.size())
4553 return Error(IDLoc,
"too few operands for instruction", EmptyRange,
4556 X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo];
4560 OperandRange, MatchingInlineAsm);
4564 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4570 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4576 if (
llvm::count(Match, Match_MissingFeature) == 1) {
4577 ErrorInfo = Match_MissingFeature;
4578 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
4584 if (
llvm::count(Match, Match_InvalidOperand) == 1) {
4585 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4590 Error(IDLoc,
"unknown use of instruction mnemonic without a size suffix",
4591 EmptyRange, MatchingInlineAsm);
4595bool X86AsmParser::matchAndEmitIntelInstruction(
4596 SMLoc IDLoc,
unsigned &Opcode, MCInst &Inst,
OperandVector &Operands,
4597 MCStreamer &Out, uint64_t &ErrorInfo,
bool MatchingInlineAsm) {
4598 X86Operand &
Op =
static_cast<X86Operand &
>(*Operands[0]);
4601 X86Operand *UnsizedMemOp =
nullptr;
4602 for (
const auto &
Op : Operands) {
4603 X86Operand *X86Op =
static_cast<X86Operand *
>(
Op.get());
4605 UnsizedMemOp = X86Op;
4614 StringRef Mnemonic = (
static_cast<X86Operand &
>(*Operands[0])).
getToken();
4616 static const char *
const PtrSizedInstrs[] = {
"call",
"jmp",
"push",
"pop"};
4617 for (
const char *Instr : PtrSizedInstrs) {
4618 if (Mnemonic == Instr) {
4619 UnsizedMemOp->
Mem.
Size = getPointerWidth();
4625 SmallVector<unsigned, 8> Match;
4626 FeatureBitset ErrorInfoMissingFeatures;
4627 FeatureBitset MissingFeatures;
4628 StringRef
Base = (
static_cast<X86Operand &
>(*Operands[0])).
getToken();
4632 if (Mnemonic ==
"push" && Operands.size() == 2) {
4633 auto *X86Op =
static_cast<X86Operand *
>(Operands[1].get());
4634 if (X86Op->
isImm()) {
4637 unsigned Size = getPointerWidth();
4640 SmallString<16> Tmp;
4642 Tmp += (is64BitMode())
4644 : (is32BitMode()) ?
"l" : (is16BitMode()) ?
"w" :
" ";
4645 Op.setTokenValue(Tmp);
4647 Match.
push_back(MatchInstruction(Operands, Inst, ErrorInfo,
4648 MissingFeatures, MatchingInlineAsm,
4659 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
4660 for (
unsigned Size : MopSizes) {
4662 uint64_t ErrorInfoIgnore;
4664 unsigned M = MatchInstruction(Operands, Inst, ErrorInfoIgnore,
4665 MissingFeatures, MatchingInlineAsm,
4666 isParsingIntelSyntax());
4671 if (Match.
back() == Match_MissingFeature)
4672 ErrorInfoMissingFeatures = MissingFeatures;
4682 if (Match.
empty()) {
4684 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,
4685 isParsingIntelSyntax()));
4687 if (Match.
back() == Match_MissingFeature)
4688 ErrorInfoMissingFeatures = MissingFeatures;
4696 if (Match.
back() == Match_MnemonicFail) {
4697 return Error(IDLoc,
"invalid instruction mnemonic '" + Mnemonic +
"'",
4698 Op.getLocRange(), MatchingInlineAsm);
4701 unsigned NumSuccessfulMatches =
llvm::count(Match, Match_Success);
4705 if (UnsizedMemOp && NumSuccessfulMatches > 1 &&
4708 unsigned M = MatchInstruction(
4709 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,
4710 isParsingIntelSyntax());
4711 if (M == Match_Success)
4712 NumSuccessfulMatches = 1;
4724 if (NumSuccessfulMatches == 1) {
4725 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
4730 if (!MatchingInlineAsm)
4731 while (processInstruction(Inst, Operands))
4734 if (!MatchingInlineAsm)
4738 }
else if (NumSuccessfulMatches > 1) {
4740 "multiple matches only possible with unsized memory operands");
4742 "ambiguous operand size for instruction '" + Mnemonic +
"\'",
4748 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4754 if (
llvm::count(Match, Match_MissingFeature) == 1) {
4755 ErrorInfo = Match_MissingFeature;
4756 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
4762 if (
llvm::count(Match, Match_InvalidOperand) == 1) {
4763 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4767 if (
llvm::count(Match, Match_InvalidImmUnsignedi4) == 1) {
4768 SMLoc ErrorLoc = ((X86Operand &)*Operands[ErrorInfo]).getStartLoc();
4769 if (ErrorLoc == SMLoc())
4771 return Error(ErrorLoc,
"immediate must be an integer in range [0, 15]",
4772 EmptyRange, MatchingInlineAsm);
4775 if (
llvm::count(Match, Match_InvalidImmUnsignedi6) == 1) {
4776 SMLoc ErrorLoc = ((X86Operand &)*Operands[ErrorInfo]).getStartLoc();
4777 if (ErrorLoc == SMLoc())
4779 return Error(ErrorLoc,
"immediate must be an integer in range [0, 63]",
4780 EmptyRange, MatchingInlineAsm);
4784 return Error(IDLoc,
"unknown instruction mnemonic", EmptyRange,
4788bool X86AsmParser::omitRegisterFromClobberLists(MCRegister
Reg) {
4789 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(
Reg);
4792bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
4793 MCAsmParser &Parser = getParser();
4796 return parseDirectiveArch();
4798 return ParseDirectiveCode(IDVal, DirectiveID.
getLoc());
4804 return Error(DirectiveID.
getLoc(),
"'.att_syntax noprefix' is not "
4805 "supported: registers must have a "
4806 "'%' prefix in .att_syntax");
4808 getParser().setAssemblerDialect(0);
4811 getParser().setAssemblerDialect(1);
4816 return Error(DirectiveID.
getLoc(),
"'.intel_syntax prefix' is not "
4817 "supported: registers must not have "
4818 "a '%' prefix in .intel_syntax");
4821 }
else if (IDVal ==
".nops")
4822 return parseDirectiveNops(DirectiveID.
getLoc());
4823 else if (IDVal ==
".even")
4824 return parseDirectiveEven(DirectiveID.
getLoc());
4825 else if (IDVal ==
".cv_fpo_proc")
4826 return parseDirectiveFPOProc(DirectiveID.
getLoc());
4827 else if (IDVal ==
".cv_fpo_setframe")
4828 return parseDirectiveFPOSetFrame(DirectiveID.
getLoc());
4829 else if (IDVal ==
".cv_fpo_pushreg")
4830 return parseDirectiveFPOPushReg(DirectiveID.
getLoc());
4831 else if (IDVal ==
".cv_fpo_stackalloc")
4832 return parseDirectiveFPOStackAlloc(DirectiveID.
getLoc());
4833 else if (IDVal ==
".cv_fpo_stackalign")
4834 return parseDirectiveFPOStackAlign(DirectiveID.
getLoc());
4835 else if (IDVal ==
".cv_fpo_endprologue")
4836 return parseDirectiveFPOEndPrologue(DirectiveID.
getLoc());
4837 else if (IDVal ==
".cv_fpo_endproc")
4838 return parseDirectiveFPOEndProc(DirectiveID.
getLoc());
4839 else if (IDVal ==
".seh_pushreg" ||
4841 return parseDirectiveSEHPushReg(DirectiveID.
getLoc());
4842 else if (IDVal ==
".seh_setframe" ||
4844 return parseDirectiveSEHSetFrame(DirectiveID.
getLoc());
4845 else if (IDVal ==
".seh_savereg" ||
4847 return parseDirectiveSEHSaveReg(DirectiveID.
getLoc());
4848 else if (IDVal ==
".seh_savexmm" ||
4850 return parseDirectiveSEHSaveXMM(DirectiveID.
getLoc());
4851 else if (IDVal ==
".seh_pushframe" ||
4853 return parseDirectiveSEHPushFrame(DirectiveID.
getLoc());
4858bool X86AsmParser::parseDirectiveArch() {
4860 getParser().parseStringToEndOfStatement();
4866bool X86AsmParser::parseDirectiveNops(SMLoc L) {
4867 int64_t NumBytes = 0, Control = 0;
4868 SMLoc NumBytesLoc, ControlLoc;
4869 const MCSubtargetInfo& STI = getSTI();
4870 NumBytesLoc = getTok().getLoc();
4871 if (getParser().checkForValidSection() ||
4872 getParser().parseAbsoluteExpression(NumBytes))
4876 ControlLoc = getTok().getLoc();
4877 if (getParser().parseAbsoluteExpression(Control))
4880 if (getParser().parseEOL())
4883 if (NumBytes <= 0) {
4884 Error(NumBytesLoc,
"'.nops' directive with non-positive size");
4889 Error(ControlLoc,
"'.nops' directive with negative NOP size");
4894 getParser().getStreamer().emitNops(NumBytes, Control, L, STI);
4901bool X86AsmParser::parseDirectiveEven(SMLoc L) {
4905 const MCSection *
Section = getStreamer().getCurrentSectionOnly();
4907 getStreamer().initSections(getSTI());
4908 Section = getStreamer().getCurrentSectionOnly();
4910 if (
getContext().getAsmInfo().useCodeAlign(*Section))
4911 getStreamer().emitCodeAlignment(
Align(2), &getSTI(), 0);
4913 getStreamer().emitValueToAlignment(
Align(2), 0, 1, 0);
4919bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
4920 MCAsmParser &Parser = getParser();
4922 if (IDVal ==
".code16") {
4924 if (!is16BitMode()) {
4925 SwitchMode(X86::Is16Bit);
4926 getTargetStreamer().emitCode16();
4928 }
else if (IDVal ==
".code16gcc") {
4932 if (!is16BitMode()) {
4933 SwitchMode(X86::Is16Bit);
4934 getTargetStreamer().emitCode16();
4936 }
else if (IDVal ==
".code32") {
4938 if (!is32BitMode()) {
4939 SwitchMode(X86::Is32Bit);
4940 getTargetStreamer().emitCode32();
4942 }
else if (IDVal ==
".code64") {
4944 if (!is64BitMode()) {
4945 SwitchMode(X86::Is64Bit);
4946 getTargetStreamer().emitCode64();
4949 Error(L,
"unknown directive " + IDVal);
4957bool X86AsmParser::parseDirectiveFPOProc(SMLoc L) {
4958 MCAsmParser &Parser = getParser();
4962 return Parser.
TokError(
"expected symbol name");
4963 if (Parser.
parseIntToken(ParamsSize,
"expected parameter byte count"))
4966 return Parser.
TokError(
"parameters size out of range");
4970 return getTargetStreamer().emitFPOProc(ProcSym, ParamsSize, L);
4974bool X86AsmParser::parseDirectiveFPOSetFrame(SMLoc L) {
4977 if (parseRegister(
Reg, DummyLoc, DummyLoc) || parseEOL())
4979 return getTargetStreamer().emitFPOSetFrame(
Reg, L);
4983bool X86AsmParser::parseDirectiveFPOPushReg(SMLoc L) {
4986 if (parseRegister(
Reg, DummyLoc, DummyLoc) || parseEOL())
4988 return getTargetStreamer().emitFPOPushReg(
Reg, L);
4992bool X86AsmParser::parseDirectiveFPOStackAlloc(SMLoc L) {
4993 MCAsmParser &Parser = getParser();
4997 return getTargetStreamer().emitFPOStackAlloc(
Offset, L);
5001bool X86AsmParser::parseDirectiveFPOStackAlign(SMLoc L) {
5002 MCAsmParser &Parser = getParser();
5006 return getTargetStreamer().emitFPOStackAlign(
Offset, L);
5010bool X86AsmParser::parseDirectiveFPOEndPrologue(SMLoc L) {
5011 MCAsmParser &Parser = getParser();
5014 return getTargetStreamer().emitFPOEndPrologue(L);
5018bool X86AsmParser::parseDirectiveFPOEndProc(SMLoc L) {
5019 MCAsmParser &Parser = getParser();
5022 return getTargetStreamer().emitFPOEndProc(L);
5025bool X86AsmParser::parseSEHRegisterNumber(
unsigned RegClassID,
5026 MCRegister &RegNo) {
5027 SMLoc startLoc = getLexer().getLoc();
5028 const MCRegisterInfo *MRI =
getContext().getRegisterInfo();
5033 if (parseRegister(RegNo, startLoc, endLoc))
5036 if (!X86MCRegisterClasses[RegClassID].
contains(RegNo)) {
5037 return Error(startLoc,
5038 "register is not supported for use with this directive");
5044 if (getParser().parseAbsoluteExpression(EncodedReg))
5049 RegNo = MCRegister();
5050 for (
MCPhysReg Reg : X86MCRegisterClasses[RegClassID]) {
5057 return Error(startLoc,
5058 "incorrect register number for use with this directive");
5065bool X86AsmParser::parseDirectiveSEHPushReg(SMLoc Loc) {
5067 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5071 return TokError(
"expected end of directive");
5074 getStreamer().emitWinCFIPushReg(
Reg, Loc);
5078bool X86AsmParser::parseDirectiveSEHSetFrame(SMLoc Loc) {
5081 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5084 return TokError(
"you must specify a stack pointer offset");
5087 if (getParser().parseAbsoluteExpression(Off))
5091 return TokError(
"expected end of directive");
5094 getStreamer().emitWinCFISetFrame(
Reg, Off, Loc);
5098bool X86AsmParser::parseDirectiveSEHSaveReg(SMLoc Loc) {
5101 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5104 return TokError(
"you must specify an offset on the stack");
5107 if (getParser().parseAbsoluteExpression(Off))
5111 return TokError(
"expected end of directive");
5114 getStreamer().emitWinCFISaveReg(
Reg, Off, Loc);
5118bool X86AsmParser::parseDirectiveSEHSaveXMM(SMLoc Loc) {
5121 if (parseSEHRegisterNumber(X86::VR128XRegClassID,
Reg))
5124 return TokError(
"you must specify an offset on the stack");
5127 if (getParser().parseAbsoluteExpression(Off))
5131 return TokError(
"expected end of directive");
5134 getStreamer().emitWinCFISaveXMM(
Reg, Off, Loc);
5138bool X86AsmParser::parseDirectiveSEHPushFrame(SMLoc Loc) {
5142 SMLoc startLoc = getLexer().getLoc();
5144 if (!getParser().parseIdentifier(CodeID)) {
5145 if (CodeID !=
"code")
5146 return Error(startLoc,
"expected @code");
5152 return TokError(
"expected end of directive");
5155 getStreamer().emitWinCFIPushFrame(Code, Loc);
5165#define GET_MATCHER_IMPLEMENTATION
5166#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 IsVCMP(unsigned Opcode)
static constexpr unsigned SM(unsigned Version)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
OptimizedStructLayoutField Field
static StringRef getName(Value *V)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallString class.
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static SymbolRef::Type getType(const Symbol *Sym)
#define LLVM_C_ABI
LLVM_C_ABI is the export/visibility macro used to mark symbols declared in llvm-c as exported when bu...
static cl::opt< bool > LVIInlineAsmHardening("x86-experimental-lvi-inline-asm-hardening", cl::desc("Harden inline assembly code that may be vulnerable to Load Value" " Injection (LVI). This feature is experimental."), cl::Hidden)
static bool checkScale(unsigned Scale, StringRef &ErrMsg)
LLVM_C_ABI void LLVMInitializeX86AsmParser()
static bool convertSSEToAVX(MCInst &Inst)
static unsigned getPrefixes(OperandVector &Operands)
static bool CheckBaseRegAndIndexRegAndScale(MCRegister BaseReg, MCRegister IndexReg, unsigned Scale, bool Is64BitMode, StringRef &ErrMsg)
#define FROM_TO(FROM, TO)
uint16_t RegSizeInBits(const MCRegisterInfo &MRI, MCRegister RegNo)
static unsigned getSize(unsigned Kind)
uint64_t getZExtValue() const
Get zero extended value.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
void UnLex(AsmToken const &Token)
bool isNot(AsmToken::TokenKind K) const
Check if the current token has kind K.
LLVM_ABI SMLoc getLoc() const
int64_t getIntVal() const
bool isNot(TokenKind K) const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
bool is(TokenKind K) const
TokenKind getKind() const
LLVM_ABI SMLoc getEndLoc() const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
constexpr size_t size() const
bool Error(SMLoc L, const Twine &Msg, SMRange Range={})
Return an error at the location L, with the message Msg.
bool parseIntToken(int64_t &V, const Twine &ErrMsg="expected integer")
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual bool isParsingMasm() const
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents.
bool parseOptionalToken(AsmToken::TokenKind T)
Attempt to parse and consume token, returning true on success.
virtual bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc, AsmTypeInfo *TypeInfo=nullptr)=0
Parse a primary expression.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
bool TokError(const Twine &Msg, SMRange Range={})
Report an error at the current lexer location.
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
virtual bool lookUpType(StringRef Name, AsmTypeInfo &Info) const
virtual bool parseAbsoluteExpression(int64_t &Res)=0
Parse an expression which must evaluate to an absolute value.
virtual bool lookUpField(StringRef Name, AsmFieldInfo &Info) const
bool parseTokenLoc(SMLoc &Loc)
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
@ SymbolRef
References to labels and assigned expressions.
Instances of this class represent a single low-level machine instruction.
unsigned getNumOperands() const
unsigned getFlags() const
unsigned getOpcode() const
void setFlags(unsigned F)
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
const MCOperand & getOperand(unsigned i) const
bool mayLoad() const
Return true if this instruction could possibly read memory.
bool isCall() const
Return true if the instruction is a call.
bool isTerminator() const
Returns true if this instruction part of the terminator for a basic block.
static MCOperand createImm(int64_t Val)
MCRegister getReg() const
Returns the register number.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
uint16_t getEncodingValue(MCRegister Reg) const
Returns the encoding for Reg.
Wrapper class representing physical registers. Should be passed by value.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
const FeatureBitset & getFeatureBits() const
const FeatureBitset & ToggleFeature(uint64_t FB)
Toggle a feature and return the re-computed feature bits.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
bool isUndefined() const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
StringRef getName() const
getName - Get the symbol name.
bool isVariable() const
isVariable - Check if this is a variable symbol.
const MCExpr * getVariableValue() const
Get the expression of the variable symbol.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
static constexpr StatusTy Failure
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
constexpr unsigned id() const
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
constexpr bool isValid() const
void push_back(const T &Elt)
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.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
std::variant< std::monostate, Loc::Single, Loc::Multi, Loc::MMI, Loc::EntryValue > Variant
Alias for the std::variant specialization base class of DbgVariable.
@ CE
Windows NT (Windows on ARM)
@ X86
Windows x64, Windows Itanium (IA-64)
bool isX86_64NonExtLowByteReg(MCRegister Reg)
@ EVEX
EVEX - Specifies that this instruction use EVEX form which provides syntax support up to 32 512-bit r...
@ VEX
VEX - encoding using 0xC4/0xC5.
@ XOP
XOP - Opcode prefix used by XOP instructions.
@ ExplicitVEXPrefix
For instructions that use VEX encoding only when {vex}, {vex2} or {vex3} is present.
bool canUseApxExtendedReg(const MCInstrDesc &Desc)
bool isX86_64ExtendedReg(MCRegister Reg)
bool isApxExtendedReg(MCRegister Reg)
void emitInstruction(MCObjectStreamer &, const MCInst &Inst, const MCSubtargetInfo &STI)
bool optimizeShiftRotateWithImmediateOne(MCInst &MI)
bool optimizeInstFromVEX3ToVEX2(MCInst &MI, const MCInstrDesc &Desc)
NodeAddr< CodeNode * > Code
Context & getContext() const
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
MCRegister getX86SubSuperRegister(MCRegister Reg, unsigned Size, bool High=false)
Target & getTheX86_32Target()
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
FunctionAddr VTableAddr Next
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
Target & getTheX86_64Target()
StringRef toStringRef(bool B)
Construct a string ref from a boolean.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
bool isKind(IdKind kind) const
SmallVectorImpl< AsmRewrite > * AsmRewrites
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
X86Operand - Instances of this class represent a parsed X86 machine instruction.
SMLoc getStartLoc() const override
getStartLoc - Get the location of the first token of this operand.
bool isImm() const override
isImm - Is this an immediate operand?
static std::unique_ptr< X86Operand > CreateImm(const MCExpr *Val, SMLoc StartLoc, SMLoc EndLoc, StringRef SymName=StringRef(), void *OpDecl=nullptr, bool GlobalRef=true)
static std::unique_ptr< X86Operand > CreatePrefix(unsigned Prefixes, SMLoc StartLoc, SMLoc EndLoc)
static std::unique_ptr< X86Operand > CreateDXReg(SMLoc StartLoc, SMLoc EndLoc)
static std::unique_ptr< X86Operand > CreateReg(MCRegister Reg, SMLoc StartLoc, SMLoc EndLoc, bool AddressOf=false, SMLoc OffsetOfLoc=SMLoc(), StringRef SymName=StringRef(), void *OpDecl=nullptr)
SMRange getLocRange() const
getLocRange - Get the range between the first and last token of this operand.
SMLoc getEndLoc() const override
getEndLoc - Get the location of the last token of this operand.
bool isReg() const override
isReg - Is this a register operand?
bool isMem() const override
isMem - Is this a memory operand?
static std::unique_ptr< X86Operand > CreateMem(unsigned ModeSize, const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc, unsigned Size=0, StringRef SymName=StringRef(), void *OpDecl=nullptr, unsigned FrontendSize=0, bool UseUpRegs=false, bool MaybeDirectBranchDest=true)
Create an absolute memory operand.
static std::unique_ptr< X86Operand > CreateToken(StringRef Str, SMLoc Loc)
bool isMemUnsized() const
const MCExpr * getImm() const
unsigned getMemFrontendSize() const
MCRegister getReg() const override