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 parseDirectiveSEHPush2Regs(SMLoc);
1236 bool parseDirectiveSEHSetFrame(SMLoc);
1237 bool parseDirectiveSEHSaveReg(SMLoc);
1238 bool parseDirectiveSEHSaveXMM(SMLoc);
1239 bool parseDirectiveSEHPushFrame(SMLoc);
1241 unsigned checkTargetMatchPredicate(MCInst &Inst)
override;
1247 void emitWarningForSpecialLVIInstruction(SMLoc Loc);
1248 void applyLVICFIMitigation(MCInst &Inst, MCStreamer &Out);
1249 void applyLVILoadHardeningMitigation(MCInst &Inst, MCStreamer &Out);
1255 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1257 uint64_t &ErrorInfo,
1258 bool MatchingInlineAsm)
override;
1260 void MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &
Op,
OperandVector &Operands,
1261 MCStreamer &Out,
bool MatchingInlineAsm);
1263 bool ErrorMissingFeature(SMLoc IDLoc,
const FeatureBitset &MissingFeatures,
1264 bool MatchingInlineAsm);
1266 bool matchAndEmitATTInstruction(SMLoc IDLoc,
unsigned &Opcode, MCInst &Inst,
1268 uint64_t &ErrorInfo,
bool MatchingInlineAsm);
1270 bool matchAndEmitIntelInstruction(SMLoc IDLoc,
unsigned &Opcode, MCInst &Inst,
1272 uint64_t &ErrorInfo,
1273 bool MatchingInlineAsm);
1275 bool omitRegisterFromClobberLists(MCRegister
Reg)
override;
1282 bool ParseZ(std::unique_ptr<X86Operand> &Z, SMLoc StartLoc);
1284 bool is64BitMode()
const {
1286 return getSTI().hasFeature(X86::Is64Bit);
1288 bool is32BitMode()
const {
1290 return getSTI().hasFeature(X86::Is32Bit);
1292 bool is16BitMode()
const {
1294 return getSTI().hasFeature(X86::Is16Bit);
1296 void SwitchMode(
unsigned mode) {
1297 MCSubtargetInfo &STI = copySTI();
1298 FeatureBitset AllModes({X86::Is64Bit, X86::Is32Bit, X86::Is16Bit});
1300 FeatureBitset FB = ComputeAvailableFeatures(
1302 setAvailableFeatures(FB);
1307 unsigned getPointerWidth() {
1308 if (is16BitMode())
return 16;
1309 if (is32BitMode())
return 32;
1310 if (is64BitMode())
return 64;
1314 bool isParsingIntelSyntax() {
1315 return getParser().getAssemblerDialect();
1321#define GET_ASSEMBLER_HEADER
1322#include "X86GenAsmMatcher.inc"
1327 enum X86MatchResultTy {
1328 Match_Unsupported = FIRST_TARGET_MATCH_RESULT_TY,
1329#define GET_OPERAND_DIAGNOSTIC_TYPES
1330#include "X86GenAsmMatcher.inc"
1333 X86AsmParser(
const MCSubtargetInfo &sti, MCAsmParser &Parser,
1334 const MCInstrInfo &mii)
1335 : MCTargetAsmParser(sti, mii), InstInfo(nullptr), Code16GCC(
false) {
1340 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
1343 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
1344 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1345 SMLoc &EndLoc)
override;
1347 bool parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc)
override;
1349 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
1352 bool ParseDirective(AsmToken DirectiveID)
override;
1356#define GET_REGISTER_MATCHER
1357#define GET_SUBTARGET_FEATURE_NAME
1358#include "X86GenAsmMatcher.inc"
1369 !(BaseReg == X86::RIP || BaseReg == X86::EIP ||
1370 X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg) ||
1371 X86MCRegisterClasses[X86::GR32RegClassID].
contains(BaseReg) ||
1372 X86MCRegisterClasses[X86::GR64RegClassID].
contains(BaseReg))) {
1373 ErrMsg =
"invalid base+index expression";
1378 !(IndexReg == X86::EIZ || IndexReg == X86::RIZ ||
1379 X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg) ||
1380 X86MCRegisterClasses[X86::GR32RegClassID].
contains(IndexReg) ||
1381 X86MCRegisterClasses[X86::GR64RegClassID].
contains(IndexReg) ||
1382 X86MCRegisterClasses[X86::VR128XRegClassID].
contains(IndexReg) ||
1383 X86MCRegisterClasses[X86::VR256XRegClassID].
contains(IndexReg) ||
1384 X86MCRegisterClasses[X86::VR512RegClassID].
contains(IndexReg))) {
1385 ErrMsg =
"invalid base+index expression";
1389 if (((BaseReg == X86::RIP || BaseReg == X86::EIP) && IndexReg) ||
1390 IndexReg == X86::EIP || IndexReg == X86::RIP || IndexReg == X86::ESP ||
1391 IndexReg == X86::RSP) {
1392 ErrMsg =
"invalid base+index expression";
1398 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg) &&
1399 (Is64BitMode || (BaseReg != X86::BX && BaseReg != X86::BP &&
1400 BaseReg != X86::SI && BaseReg != X86::DI))) {
1401 ErrMsg =
"invalid 16-bit base register";
1406 X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg)) {
1407 ErrMsg =
"16-bit memory operand may not include only index register";
1411 if (BaseReg && IndexReg) {
1412 if (X86MCRegisterClasses[X86::GR64RegClassID].
contains(BaseReg) &&
1413 (X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg) ||
1414 X86MCRegisterClasses[X86::GR32RegClassID].
contains(IndexReg) ||
1415 IndexReg == X86::EIZ)) {
1416 ErrMsg =
"base register is 64-bit, but index register is not";
1419 if (X86MCRegisterClasses[X86::GR32RegClassID].
contains(BaseReg) &&
1420 (X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg) ||
1421 X86MCRegisterClasses[X86::GR64RegClassID].
contains(IndexReg) ||
1422 IndexReg == X86::RIZ)) {
1423 ErrMsg =
"base register is 32-bit, but index register is not";
1426 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg)) {
1427 if (X86MCRegisterClasses[X86::GR32RegClassID].
contains(IndexReg) ||
1428 X86MCRegisterClasses[X86::GR64RegClassID].
contains(IndexReg)) {
1429 ErrMsg =
"base register is 16-bit, but index register is not";
1432 if ((BaseReg != X86::BX && BaseReg != X86::BP) ||
1433 (IndexReg != X86::SI && IndexReg != X86::DI)) {
1434 ErrMsg =
"invalid 16-bit base/index register combination";
1441 if (!Is64BitMode && (BaseReg == X86::RIP || BaseReg == X86::EIP)) {
1442 ErrMsg =
"IP-relative addressing requires 64-bit mode";
1463 if (isParsingMSInlineAsm() && isParsingIntelSyntax() &&
1464 (RegNo == X86::EFLAGS || RegNo == X86::MXCSR))
1465 RegNo = MCRegister();
1467 if (!is64BitMode()) {
1471 if (RegNo == X86::RIZ || RegNo == X86::RIP ||
1472 X86MCRegisterClasses[X86::GR64RegClassID].
contains(RegNo) ||
1475 return Error(StartLoc,
1476 "register %" +
RegName +
" is only available in 64-bit mode",
1477 SMRange(StartLoc, EndLoc));
1482 UseApxExtendedReg =
true;
1486 if (!RegNo &&
RegName.starts_with(
"db")) {
1545 if (isParsingIntelSyntax())
1547 return Error(StartLoc,
"invalid register name", SMRange(StartLoc, EndLoc));
1552bool X86AsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
1553 SMLoc &EndLoc,
bool RestoreOnFailure) {
1554 MCAsmParser &Parser = getParser();
1555 AsmLexer &Lexer = getLexer();
1556 RegNo = MCRegister();
1559 auto OnFailure = [RestoreOnFailure, &Lexer, &Tokens]() {
1560 if (RestoreOnFailure) {
1561 while (!Tokens.
empty()) {
1567 const AsmToken &PercentTok = Parser.
getTok();
1568 StartLoc = PercentTok.
getLoc();
1577 const AsmToken &Tok = Parser.
getTok();
1582 if (isParsingIntelSyntax())
return true;
1583 return Error(StartLoc,
"invalid register name",
1584 SMRange(StartLoc, EndLoc));
1587 if (MatchRegisterByName(RegNo, Tok.
getString(), StartLoc, EndLoc)) {
1593 if (RegNo == X86::ST0) {
1604 const AsmToken &IntTok = Parser.
getTok();
1607 return Error(IntTok.
getLoc(),
"expected stack index");
1610 case 0: RegNo = X86::ST0;
break;
1611 case 1: RegNo = X86::ST1;
break;
1612 case 2: RegNo = X86::ST2;
break;
1613 case 3: RegNo = X86::ST3;
break;
1614 case 4: RegNo = X86::ST4;
break;
1615 case 5: RegNo = X86::ST5;
break;
1616 case 6: RegNo = X86::ST6;
break;
1617 case 7: RegNo = X86::ST7;
break;
1620 return Error(IntTok.
getLoc(),
"invalid stack index");
1640 if (isParsingIntelSyntax())
return true;
1641 return Error(StartLoc,
"invalid register name",
1642 SMRange(StartLoc, EndLoc));
1649bool X86AsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1651 return ParseRegister(
Reg, StartLoc, EndLoc,
false);
1654ParseStatus X86AsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1656 bool Result = ParseRegister(
Reg, StartLoc, EndLoc,
true);
1657 bool PendingErrors = getParser().hasPendingError();
1658 getParser().clearPendingErrors();
1666std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(SMLoc Loc) {
1667 bool Parse32 = is32BitMode() || Code16GCC;
1668 MCRegister Basereg =
1669 is64BitMode() ? X86::RSI : (Parse32 ? X86::ESI : X86::SI);
1676std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand(SMLoc Loc) {
1677 bool Parse32 = is32BitMode() || Code16GCC;
1678 MCRegister Basereg =
1679 is64BitMode() ? X86::RDI : (Parse32 ? X86::EDI : X86::DI);
1686bool X86AsmParser::IsSIReg(MCRegister
Reg) {
1700MCRegister X86AsmParser::GetSIDIForRegClass(
unsigned RegClassID,
bool IsSIReg) {
1701 switch (RegClassID) {
1703 case X86::GR64RegClassID:
1704 return IsSIReg ? X86::RSI : X86::RDI;
1705 case X86::GR32RegClassID:
1706 return IsSIReg ? X86::ESI : X86::EDI;
1707 case X86::GR16RegClassID:
1708 return IsSIReg ? X86::SI : X86::DI;
1712void X86AsmParser::AddDefaultSrcDestOperands(
1713 OperandVector& Operands, std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
1714 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst) {
1715 if (isParsingIntelSyntax()) {
1725bool X86AsmParser::VerifyAndAdjustOperands(
OperandVector &OrigOperands,
1728 if (OrigOperands.
size() > 1) {
1731 "Operand size mismatch");
1735 int RegClassID = -1;
1736 for (
unsigned int i = 0; i < FinalOperands.
size(); ++i) {
1737 X86Operand &OrigOp =
static_cast<X86Operand &
>(*OrigOperands[i + 1]);
1738 X86Operand &FinalOp =
static_cast<X86Operand &
>(*FinalOperands[i]);
1740 if (FinalOp.
isReg() &&
1745 if (FinalOp.
isMem()) {
1747 if (!OrigOp.
isMem())
1756 if (RegClassID != -1 &&
1757 !X86MCRegisterClasses[RegClassID].
contains(OrigReg)) {
1759 "mismatching source and destination index registers");
1762 if (X86MCRegisterClasses[X86::GR64RegClassID].
contains(OrigReg))
1763 RegClassID = X86::GR64RegClassID;
1764 else if (X86MCRegisterClasses[X86::GR32RegClassID].
contains(OrigReg))
1765 RegClassID = X86::GR32RegClassID;
1766 else if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(OrigReg))
1767 RegClassID = X86::GR16RegClassID;
1773 bool IsSI = IsSIReg(FinalReg);
1774 FinalReg = GetSIDIForRegClass(RegClassID, IsSI);
1776 if (FinalReg != OrigReg) {
1777 std::string
RegName = IsSI ?
"ES:(R|E)SI" :
"ES:(R|E)DI";
1780 "memory operand is only for determining the size, " +
RegName +
1781 " will be used for the location"));
1792 for (
auto &WarningMsg : Warnings) {
1793 Warning(WarningMsg.first, WarningMsg.second);
1797 for (
unsigned int i = 0; i < FinalOperands.
size(); ++i)
1801 for (
auto &
Op : FinalOperands)
1807bool X86AsmParser::parseOperand(
OperandVector &Operands, StringRef Name) {
1808 if (isParsingIntelSyntax())
1809 return parseIntelOperand(Operands, Name);
1811 return parseATTOperand(Operands);
1814bool X86AsmParser::CreateMemForMSInlineAsm(
1815 MCRegister SegReg,
const MCExpr *Disp, MCRegister BaseReg,
1816 MCRegister IndexReg,
unsigned Scale,
bool NonAbsMem, SMLoc Start, SMLoc End,
1817 unsigned Size, StringRef Identifier,
const InlineAsmIdentifierInfo &Info,
1825 End,
Size, Identifier,
1832 unsigned FrontendSize = 0;
1833 void *Decl =
nullptr;
1834 bool IsGlobalLV =
false;
1837 FrontendSize =
Info.Var.Type * 8;
1838 Decl =
Info.Var.Decl;
1839 IsGlobalLV =
Info.Var.IsGlobalLV;
1844 if (BaseReg || IndexReg) {
1846 End,
Size, Identifier, Decl, 0,
1847 BaseReg && IndexReg));
1854 getPointerWidth(), SegReg, Disp, BaseReg, IndexReg, Scale, Start, End,
1856 X86::RIP, Identifier, Decl, FrontendSize));
1863bool X86AsmParser::ParseIntelNamedOperator(StringRef Name,
1864 IntelExprStateMachine &
SM,
1865 bool &ParseError, SMLoc &End) {
1868 if (Name !=
Name.lower() && Name !=
Name.upper() &&
1869 !getParser().isParsingMasm())
1871 if (
Name.equals_insensitive(
"not")) {
1873 }
else if (
Name.equals_insensitive(
"or")) {
1875 }
else if (
Name.equals_insensitive(
"shl")) {
1877 }
else if (
Name.equals_insensitive(
"shr")) {
1879 }
else if (
Name.equals_insensitive(
"xor")) {
1881 }
else if (
Name.equals_insensitive(
"and")) {
1883 }
else if (
Name.equals_insensitive(
"mod")) {
1885 }
else if (
Name.equals_insensitive(
"offset")) {
1886 SMLoc OffsetLoc = getTok().getLoc();
1887 const MCExpr *Val =
nullptr;
1889 InlineAsmIdentifierInfo
Info;
1890 ParseError = ParseIntelOffsetOperator(Val,
ID, Info, End);
1895 SM.onOffset(Val, OffsetLoc,
ID, Info, isParsingMSInlineAsm(), ErrMsg);
1901 if (!
Name.equals_insensitive(
"offset"))
1902 End = consumeToken();
1905bool X86AsmParser::ParseMasmNamedOperator(StringRef Name,
1906 IntelExprStateMachine &
SM,
1907 bool &ParseError, SMLoc &End) {
1908 if (
Name.equals_insensitive(
"eq")) {
1910 }
else if (
Name.equals_insensitive(
"ne")) {
1912 }
else if (
Name.equals_insensitive(
"lt")) {
1914 }
else if (
Name.equals_insensitive(
"le")) {
1916 }
else if (
Name.equals_insensitive(
"gt")) {
1918 }
else if (
Name.equals_insensitive(
"ge")) {
1923 End = consumeToken();
1930 IntelExprStateMachine &
SM) {
1934 SM.setAppendAfterOperand();
1937bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &
SM, SMLoc &End) {
1938 MCAsmParser &Parser = getParser();
1943 if (
getContext().getObjectFileInfo()->isPositionIndependent())
1950 const AsmToken &Tok = Parser.
getTok();
1952 bool UpdateLocLex =
true;
1957 if ((
Done =
SM.isValidEndState()))
1959 return Error(Tok.
getLoc(),
"unknown token in expression");
1961 return Error(getLexer().getErrLoc(), getLexer().getErr());
1965 UpdateLocLex =
false;
1966 if (ParseIntelDotOperator(
SM, End))
1971 if ((
Done =
SM.isValidEndState()))
1973 return Error(Tok.
getLoc(),
"unknown token in expression");
1977 UpdateLocLex =
false;
1978 if (ParseIntelDotOperator(
SM, End))
1983 if ((
Done =
SM.isValidEndState()))
1985 return Error(Tok.
getLoc(),
"unknown token in expression");
1991 SMLoc ValueLoc = Tok.
getLoc();
1996 UpdateLocLex =
false;
1997 if (!Val->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
1998 return Error(ValueLoc,
"expected absolute value");
1999 if (
SM.onInteger(Res, ErrMsg))
2000 return Error(
SM.getErrorLoc(ValueLoc), ErrMsg);
2007 SMLoc IdentLoc = Tok.
getLoc();
2009 UpdateLocLex =
false;
2011 size_t DotOffset =
Identifier.find_first_of(
'.');
2015 StringRef Dot =
Identifier.substr(DotOffset, 1);
2029 const AsmToken &NextTok = getLexer().peekTok();
2038 End = consumeToken();
2045 if (!ParseRegister(
Reg, IdentLoc, End,
true)) {
2046 if (
SM.onRegister(
Reg, ErrMsg))
2047 return Error(
SM.getErrorLoc(IdentLoc), ErrMsg);
2051 const std::pair<StringRef, StringRef> IDField =
2053 const StringRef
ID = IDField.first,
Field = IDField.second;
2055 if (!
Field.empty() &&
2056 !MatchRegisterByName(
Reg,
ID, IdentLoc, IDEndLoc)) {
2057 if (
SM.onRegister(
Reg, ErrMsg))
2058 return Error(
SM.getErrorLoc(IdentLoc), ErrMsg);
2063 return Error(FieldStartLoc,
"unknown offset");
2064 else if (
SM.onPlus(ErrMsg))
2065 return Error(getTok().getLoc(), ErrMsg);
2066 else if (
SM.onInteger(
Info.Offset, ErrMsg))
2067 return Error(
SM.getErrorLoc(IdentLoc), ErrMsg);
2068 SM.setTypeInfo(
Info.Type);
2070 End = consumeToken();
2077 if (ParseIntelNamedOperator(Identifier,
SM, ParseError, End)) {
2083 ParseMasmNamedOperator(Identifier,
SM, ParseError, End)) {
2089 InlineAsmIdentifierInfo
Info;
2090 AsmFieldInfo FieldInfo;
2096 if (ParseIntelDotOperator(
SM, End))
2101 if (isParsingMSInlineAsm()) {
2103 if (
unsigned OpKind = IdentifyIntelInlineAsmOperator(Identifier)) {
2104 if (int64_t Val = ParseIntelInlineAsmOperator(OpKind)) {
2105 if (
SM.onInteger(Val, ErrMsg))
2106 return Error(
SM.getErrorLoc(IdentLoc), ErrMsg);
2115 return Error(IdentLoc,
"expected identifier");
2116 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
false, End))
2118 else if (
SM.onIdentifierExpr(Val, Identifier, Info, FieldInfo.
Type,
2120 return Error(
SM.getErrorLoc(IdentLoc), ErrMsg);
2124 if (
unsigned OpKind = IdentifyMasmOperator(Identifier)) {
2126 if (ParseMasmOperator(OpKind, Val))
2128 if (
SM.onInteger(Val, ErrMsg))
2129 return Error(
SM.getErrorLoc(IdentLoc), ErrMsg);
2132 if (!getParser().lookUpType(Identifier, FieldInfo.
Type)) {
2138 getParser().parseIdentifier(Identifier);
2142 if (getParser().lookUpField(FieldInfo.
Type.
Name, Identifier,
2146 return Error(IdentLoc,
"Unable to lookup field reference!",
2147 SMRange(IdentLoc, IDEnd));
2152 if (
SM.onInteger(FieldInfo.
Offset, ErrMsg))
2153 return Error(
SM.getErrorLoc(IdentLoc), ErrMsg);
2157 if (getParser().parsePrimaryExpr(Val, End, &FieldInfo.
Type)) {
2158 return Error(Tok.
getLoc(),
"Unexpected identifier!");
2159 }
else if (
SM.onIdentifierExpr(Val, Identifier, Info, FieldInfo.
Type,
2161 return Error(
SM.getErrorLoc(IdentLoc), ErrMsg);
2167 SMLoc Loc = getTok().getLoc();
2168 int64_t
IntVal = getTok().getIntVal();
2169 End = consumeToken();
2170 UpdateLocLex =
false;
2172 StringRef IDVal = getTok().getString();
2173 if (IDVal ==
"f" || IDVal ==
"b") {
2175 getContext().getDirectionalLocalSymbol(IntVal, IDVal ==
"b");
2180 return Error(Loc,
"invalid reference to undefined symbol");
2182 InlineAsmIdentifierInfo
Info;
2184 if (
SM.onIdentifierExpr(Val, Identifier, Info,
Type,
2185 isParsingMSInlineAsm(), ErrMsg))
2186 return Error(
SM.getErrorLoc(Loc), ErrMsg);
2187 End = consumeToken();
2189 if (
SM.onInteger(IntVal, ErrMsg))
2190 return Error(
SM.getErrorLoc(Loc), ErrMsg);
2193 if (
SM.onInteger(IntVal, ErrMsg))
2194 return Error(
SM.getErrorLoc(Loc), ErrMsg);
2199 if (
SM.onPlus(ErrMsg))
2200 return Error(getTok().getLoc(), ErrMsg);
2203 if (
SM.onMinus(getTok().getLoc(), ErrMsg))
2204 return Error(
SM.getErrorLoc(getTok().getLoc()), ErrMsg);
2214 SM.onLShift();
break;
2216 SM.onRShift();
break;
2219 return Error(Tok.
getLoc(),
"unexpected bracket encountered");
2220 tryParseOperandIdx(PrevTK,
SM);
2223 if (
SM.onRBrac(ErrMsg)) {
2229 if (
SM.onRParen(ErrMsg)) {
2235 return Error(Tok.
getLoc(),
"unknown token in expression");
2237 if (!
Done && UpdateLocLex)
2238 End = consumeToken();
2245void X86AsmParser::RewriteIntelExpression(IntelExprStateMachine &
SM,
2246 SMLoc Start, SMLoc End) {
2250 if (
SM.getSym() && !
SM.isOffsetOperator()) {
2251 StringRef SymName =
SM.getSymName();
2252 if (
unsigned Len = SymName.
data() -
Start.getPointer())
2258 if (!(
SM.getBaseReg() ||
SM.getIndexReg() ||
SM.getImm())) {
2265 StringRef BaseRegStr;
2266 StringRef IndexRegStr;
2267 StringRef OffsetNameStr;
2268 if (
SM.getBaseReg())
2270 if (
SM.getIndexReg())
2272 if (
SM.isOffsetOperator())
2273 OffsetNameStr =
SM.getSymName();
2275 IntelExpr Expr(BaseRegStr, IndexRegStr,
SM.getScale(), OffsetNameStr,
2276 SM.getImm(),
SM.isMemExpr());
2277 InstInfo->
AsmRewrites->emplace_back(Loc, ExprLen, Expr);
2281bool X86AsmParser::ParseIntelInlineAsmIdentifier(
2282 const MCExpr *&Val, StringRef &Identifier, InlineAsmIdentifierInfo &Info,
2283 bool IsUnevaluatedOperand, SMLoc &End,
bool IsParsingOffsetOperator) {
2284 MCAsmParser &Parser = getParser();
2285 assert(isParsingMSInlineAsm() &&
"Expected to be parsing inline assembly.");
2289 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);
2291 const AsmToken &Tok = Parser.
getTok();
2292 SMLoc Loc = Tok.
getLoc();
2307 "frontend claimed part of a token?");
2312 StringRef InternalName =
2313 SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(),
2315 assert(InternalName.
size() &&
"We should have an internal name here.");
2318 if (!IsParsingOffsetOperator)
2333bool X86AsmParser::ParseRoundingModeOp(SMLoc Start,
OperandVector &Operands) {
2334 MCAsmParser &Parser = getParser();
2335 const AsmToken &Tok = Parser.
getTok();
2337 const SMLoc consumedToken = consumeToken();
2339 return Error(Tok.
getLoc(),
"Expected an identifier after {");
2342 .Case(
"rn", X86::STATIC_ROUNDING::TO_NEAREST_INT)
2343 .Case(
"rd", X86::STATIC_ROUNDING::TO_NEG_INF)
2344 .Case(
"ru", X86::STATIC_ROUNDING::TO_POS_INF)
2345 .Case(
"rz", X86::STATIC_ROUNDING::TO_ZERO)
2348 return Error(Tok.
getLoc(),
"Invalid rounding mode.");
2351 return Error(Tok.
getLoc(),
"Expected - at this point");
2355 return Error(Tok.
getLoc(),
"Expected } at this point");
2358 const MCExpr *RndModeOp =
2366 return Error(Tok.
getLoc(),
"Expected } at this point");
2371 return Error(Tok.
getLoc(),
"unknown token in expression");
2377 MCAsmParser &Parser = getParser();
2378 AsmToken Tok = Parser.
getTok();
2381 return Error(Tok.
getLoc(),
"Expected { at this point");
2385 return Error(Tok.
getLoc(),
"Expected dfv at this point");
2389 return Error(Tok.
getLoc(),
"Expected = at this point");
2401 unsigned CFlags = 0;
2402 for (
unsigned I = 0;
I < 4; ++
I) {
2411 return Error(Tok.
getLoc(),
"Invalid conditional flags");
2414 return Error(Tok.
getLoc(),
"Duplicated conditional flag");
2425 }
else if (
I == 3) {
2426 return Error(Tok.
getLoc(),
"Expected } at this point");
2428 return Error(Tok.
getLoc(),
"Expected } or , at this point");
2436bool X86AsmParser::ParseIntelDotOperator(IntelExprStateMachine &
SM,
2438 const AsmToken &Tok = getTok();
2444 bool TrailingDot =
false;
2452 }
else if ((isParsingMSInlineAsm() || getParser().isParsingMasm()) &&
2455 const std::pair<StringRef, StringRef> BaseMember = DotDispStr.
split(
'.');
2456 const StringRef
Base = BaseMember.first,
Member = BaseMember.second;
2457 if (getParser().lookUpField(
SM.getType(), DotDispStr, Info) &&
2458 getParser().lookUpField(
SM.getSymName(), DotDispStr, Info) &&
2459 getParser().lookUpField(DotDispStr, Info) &&
2461 SemaCallback->LookupInlineAsmField(
Base, Member,
Info.Offset)))
2462 return Error(Tok.
getLoc(),
"Unable to lookup field reference!");
2464 return Error(Tok.
getLoc(),
"Unexpected token type!");
2469 const char *DotExprEndLoc = DotDispStr.
data() + DotDispStr.
size();
2475 SM.setTypeInfo(
Info.Type);
2481bool X86AsmParser::ParseIntelOffsetOperator(
const MCExpr *&Val, StringRef &
ID,
2482 InlineAsmIdentifierInfo &Info,
2485 SMLoc
Start = Lex().getLoc();
2486 ID = getTok().getString();
2487 if (!isParsingMSInlineAsm()) {
2490 getParser().parsePrimaryExpr(Val, End,
nullptr))
2491 return Error(Start,
"unexpected token!");
2492 }
else if (ParseIntelInlineAsmIdentifier(Val,
ID, Info,
false, End,
true)) {
2493 return Error(Start,
"unable to lookup expression");
2495 return Error(Start,
"offset operator cannot yet handle constants");
2502unsigned X86AsmParser::IdentifyIntelInlineAsmOperator(StringRef Name) {
2503 return StringSwitch<unsigned>(Name)
2504 .Cases({
"TYPE",
"type"}, IOK_TYPE)
2505 .Cases({
"SIZE",
"size"}, IOK_SIZE)
2506 .Cases({
"LENGTH",
"length"}, IOK_LENGTH)
2516unsigned X86AsmParser::ParseIntelInlineAsmOperator(
unsigned OpKind) {
2517 MCAsmParser &Parser = getParser();
2518 const AsmToken &Tok = Parser.
getTok();
2521 const MCExpr *Val =
nullptr;
2522 InlineAsmIdentifierInfo
Info;
2525 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
2530 Error(Start,
"unable to lookup expression");
2537 case IOK_LENGTH: CVal =
Info.Var.Length;
break;
2538 case IOK_SIZE: CVal =
Info.Var.Size;
break;
2539 case IOK_TYPE: CVal =
Info.Var.Type;
break;
2547unsigned X86AsmParser::IdentifyMasmOperator(StringRef Name) {
2548 return StringSwitch<unsigned>(
Name.lower())
2549 .Case(
"type", MOK_TYPE)
2550 .Cases({
"size",
"sizeof"}, MOK_SIZEOF)
2551 .Cases({
"length",
"lengthof"}, MOK_LENGTHOF)
2561bool X86AsmParser::ParseMasmOperator(
unsigned OpKind, int64_t &Val) {
2562 MCAsmParser &Parser = getParser();
2567 if (OpKind == MOK_SIZEOF || OpKind == MOK_TYPE) {
2570 const AsmToken &IDTok = InParens ? getLexer().peekTok() : Parser.
getTok();
2586 IntelExprStateMachine
SM;
2588 if (ParseIntelExpression(
SM, End))
2598 Val =
SM.getLength();
2601 Val =
SM.getElementSize();
2606 return Error(OpLoc,
"expression has unknown type", SMRange(Start, End));
2612bool X86AsmParser::ParseIntelMemoryOperandSize(
unsigned &
Size,
2613 StringRef *SizeStr) {
2614 Size = StringSwitch<unsigned>(getTok().getString())
2615 .Cases({
"BYTE",
"byte"}, 8)
2616 .Cases({
"WORD",
"word"}, 16)
2617 .Cases({
"DWORD",
"dword"}, 32)
2618 .Cases({
"FLOAT",
"float"}, 32)
2619 .Cases({
"LONG",
"long"}, 32)
2620 .Cases({
"FWORD",
"fword"}, 48)
2621 .Cases({
"DOUBLE",
"double"}, 64)
2622 .Cases({
"QWORD",
"qword"}, 64)
2623 .Cases({
"MMWORD",
"mmword"}, 64)
2624 .Cases({
"XWORD",
"xword"}, 80)
2625 .Cases({
"TBYTE",
"tbyte"}, 80)
2626 .Cases({
"XMMWORD",
"xmmword"}, 128)
2627 .Cases({
"YMMWORD",
"ymmword"}, 256)
2628 .Cases({
"ZMMWORD",
"zmmword"}, 512)
2632 *SizeStr = getTok().getString();
2633 const AsmToken &Tok = Lex();
2635 return Error(Tok.
getLoc(),
"Expected 'PTR' or 'ptr' token!");
2642 if (X86MCRegisterClasses[X86::GR8RegClassID].
contains(RegNo))
2644 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(RegNo))
2646 if (X86MCRegisterClasses[X86::GR32RegClassID].
contains(RegNo))
2648 if (X86MCRegisterClasses[X86::GR64RegClassID].
contains(RegNo))
2654bool X86AsmParser::parseIntelOperand(
OperandVector &Operands, StringRef Name) {
2655 MCAsmParser &Parser = getParser();
2656 const AsmToken &Tok = Parser.
getTok();
2662 if (ParseIntelMemoryOperandSize(
Size, &SizeStr))
2664 bool PtrInOperand = bool(
Size);
2670 return ParseRoundingModeOp(Start, Operands);
2675 if (RegNo == X86::RIP)
2676 return Error(Start,
"rip can only be used as a base register");
2681 return Error(Start,
"expected memory operand after 'ptr', "
2682 "found register operand instead");
2691 "cannot cast register '" +
2693 "'; its size is not easily defined.");
2697 std::to_string(
RegSize) +
"-bit register '" +
2699 "' cannot be used as a " + std::to_string(
Size) +
"-bit " +
2706 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].
contains(RegNo))
2707 return Error(Start,
"invalid segment register");
2709 Start = Lex().getLoc();
2713 IntelExprStateMachine
SM;
2714 if (ParseIntelExpression(
SM, End))
2717 if (isParsingMSInlineAsm())
2718 RewriteIntelExpression(
SM, Start, Tok.
getLoc());
2720 int64_t
Imm =
SM.getImm();
2721 const MCExpr *Disp =
SM.getSym();
2730 if (!
SM.isMemExpr() && !RegNo) {
2731 if (isParsingMSInlineAsm() &&
SM.isOffsetOperator()) {
2732 const InlineAsmIdentifierInfo &
Info =
SM.getIdentifierInfo();
2737 SM.getSymName(),
Info.Var.Decl,
2738 Info.Var.IsGlobalLV));
2749 MCRegister IndexReg =
SM.getIndexReg();
2750 if (IndexReg && BaseReg == X86::RIP)
2752 unsigned Scale =
SM.getScale();
2754 Size =
SM.getElementSize() << 3;
2756 if (Scale == 0 && BaseReg != X86::ESP && BaseReg != X86::RSP &&
2757 (IndexReg == X86::ESP || IndexReg == X86::RSP))
2763 !(X86MCRegisterClasses[X86::VR128XRegClassID].
contains(IndexReg) ||
2764 X86MCRegisterClasses[X86::VR256XRegClassID].
contains(IndexReg) ||
2765 X86MCRegisterClasses[X86::VR512RegClassID].
contains(IndexReg)) &&
2766 (X86MCRegisterClasses[X86::VR128XRegClassID].
contains(BaseReg) ||
2767 X86MCRegisterClasses[X86::VR256XRegClassID].
contains(BaseReg) ||
2768 X86MCRegisterClasses[X86::VR512RegClassID].
contains(BaseReg)))
2772 X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg))
2773 return Error(Start,
"16-bit addresses cannot have a scale");
2782 if ((BaseReg == X86::SI || BaseReg == X86::DI) &&
2783 (IndexReg == X86::BX || IndexReg == X86::BP))
2786 if ((BaseReg || IndexReg) &&
2789 return Error(Start, ErrMsg);
2790 bool IsUnconditionalBranch =
2791 Name.equals_insensitive(
"jmp") ||
Name.equals_insensitive(
"call");
2792 if (isParsingMSInlineAsm())
2793 return CreateMemForMSInlineAsm(RegNo, Disp, BaseReg, IndexReg, Scale,
2794 IsUnconditionalBranch && is64BitMode(),
2795 Start, End,
Size,
SM.getSymName(),
2796 SM.getIdentifierInfo(), Operands);
2800 MCRegister DefaultBaseReg;
2801 bool MaybeDirectBranchDest =
true;
2804 if (is64BitMode() &&
2805 ((PtrInOperand && !IndexReg) ||
SM.getElementSize() > 0)) {
2806 DefaultBaseReg = X86::RIP;
2808 if (IsUnconditionalBranch) {
2810 MaybeDirectBranchDest =
false;
2812 DefaultBaseReg = X86::RIP;
2813 }
else if (!BaseReg && !IndexReg && Disp &&
2815 if (is64BitMode()) {
2816 if (
SM.getSize() == 8) {
2817 MaybeDirectBranchDest =
false;
2818 DefaultBaseReg = X86::RIP;
2821 if (
SM.getSize() == 4 ||
SM.getSize() == 2)
2822 MaybeDirectBranchDest =
false;
2826 }
else if (IsUnconditionalBranch) {
2828 if (!PtrInOperand &&
SM.isOffsetOperator())
2830 Start,
"`OFFSET` operator cannot be used in an unconditional branch");
2831 if (PtrInOperand ||
SM.isBracketUsed())
2832 MaybeDirectBranchDest =
false;
2835 if (CheckDispOverflow(BaseReg, IndexReg, Disp, Start))
2838 if ((BaseReg || IndexReg || RegNo || DefaultBaseReg))
2840 getPointerWidth(), RegNo, Disp, BaseReg, IndexReg, Scale, Start, End,
2841 Size, DefaultBaseReg, StringRef(),
nullptr,
2842 0,
false, MaybeDirectBranchDest));
2845 getPointerWidth(), Disp, Start, End,
Size, StringRef(),
2847 MaybeDirectBranchDest));
2851bool X86AsmParser::parseATTOperand(
OperandVector &Operands) {
2852 MCAsmParser &Parser = getParser();
2853 switch (getLexer().getKind()) {
2863 "expected immediate expression") ||
2864 getParser().parseExpression(Val, End) ||
2872 return ParseRoundingModeOp(Start, Operands);
2881 const MCExpr *Expr =
nullptr;
2893 if (
Reg == X86::EIZ ||
Reg == X86::RIZ)
2895 Loc,
"%eiz and %riz can only be used as index registers",
2896 SMRange(Loc, EndLoc));
2897 if (
Reg == X86::RIP)
2898 return Error(Loc,
"%rip can only be used as a base register",
2899 SMRange(Loc, EndLoc));
2905 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].
contains(
Reg))
2906 return Error(Loc,
"invalid segment register");
2914 return ParseMemOperand(
Reg, Expr, Loc, EndLoc, Operands);
2921X86::CondCode X86AsmParser::ParseConditionCode(StringRef CC) {
2922 return StringSwitch<X86::CondCode>(CC)
2944bool X86AsmParser::ParseZ(std::unique_ptr<X86Operand> &Z, SMLoc StartLoc) {
2945 MCAsmParser &Parser = getParser();
2950 (getLexer().getTok().getIdentifier() ==
"z")))
2955 return Error(getLexer().getLoc(),
"Expected } at this point");
2963bool X86AsmParser::HandleAVX512Operand(
OperandVector &Operands) {
2964 MCAsmParser &Parser = getParser();
2967 const SMLoc consumedToken = consumeToken();
2971 if (getLexer().getTok().getIntVal() != 1)
2972 return TokError(
"Expected 1to<NUM> at this point");
2973 StringRef
Prefix = getLexer().getTok().getString();
2976 return TokError(
"Expected 1to<NUM> at this point");
2979 StringRef BroadcastString = (
Prefix + getLexer().getTok().getIdentifier())
2982 return TokError(
"Expected 1to<NUM> at this point");
2983 const char *BroadcastPrimitive =
2984 StringSwitch<const char *>(BroadcastString)
2985 .Case(
"1to2",
"{1to2}")
2986 .Case(
"1to4",
"{1to4}")
2987 .Case(
"1to8",
"{1to8}")
2988 .Case(
"1to16",
"{1to16}")
2989 .Case(
"1to32",
"{1to32}")
2991 if (!BroadcastPrimitive)
2992 return TokError(
"Invalid memory broadcast primitive.");
2995 return TokError(
"Expected } at this point");
3006 std::unique_ptr<X86Operand>
Z;
3007 if (ParseZ(Z, consumedToken))
3013 SMLoc StartLoc =
Z ? consumeToken() : consumedToken;
3018 if (!parseRegister(RegNo, RegLoc, StartLoc) &&
3019 X86MCRegisterClasses[X86::VK1RegClassID].
contains(RegNo)) {
3020 if (RegNo == X86::K0)
3021 return Error(RegLoc,
"Register k0 can't be used as write mask");
3023 return Error(getLexer().getLoc(),
"Expected } at this point");
3029 return Error(getLexer().getLoc(),
3030 "Expected an op-mask register at this point");
3035 if (ParseZ(Z, consumeToken()) || !Z)
3036 return Error(getLexer().getLoc(),
3037 "Expected a {z} mark at this point");
3052bool X86AsmParser::CheckDispOverflow(MCRegister BaseReg, MCRegister IndexReg,
3053 const MCExpr *Disp, SMLoc Loc) {
3059 if (BaseReg || IndexReg) {
3061 auto Imm =
CE->getValue();
3062 bool Is64 = X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) ||
3063 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg);
3064 bool Is16 = X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg);
3067 return Error(Loc,
"displacement " + Twine(Imm) +
3068 " is not within [-2147483648, 2147483647]");
3070 if (!
isUInt<32>(Imm < 0 ? -uint64_t(Imm) : uint64_t(Imm))) {
3071 Warning(Loc,
"displacement " + Twine(Imm) +
3072 " shortened to 32-bit signed " +
3073 Twine(
static_cast<int32_t
>(Imm)));
3075 }
else if (!
isUInt<16>(Imm < 0 ? -uint64_t(Imm) : uint64_t(Imm))) {
3076 Warning(Loc,
"displacement " + Twine(Imm) +
3077 " shortened to 16-bit signed " +
3078 Twine(
static_cast<int16_t
>(Imm)));
3087bool X86AsmParser::ParseMemOperand(MCRegister SegReg,
const MCExpr *Disp,
3088 SMLoc StartLoc, SMLoc EndLoc,
3090 MCAsmParser &Parser = getParser();
3108 auto isAtMemOperand = [
this]() {
3113 auto TokCount = this->getLexer().peekTokens(Buf,
true);
3116 switch (Buf[0].getKind()) {
3123 if ((TokCount > 1) &&
3127 Buf[1].getIdentifier().
size() + 1);
3149 if (!isAtMemOperand()) {
3168 0, 0, 1, StartLoc, EndLoc));
3176 SMLoc BaseLoc = getLexer().getLoc();
3188 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ)
3189 return Error(BaseLoc,
"eiz and riz can only be used as index registers",
3190 SMRange(BaseLoc, EndLoc));
3208 if (!
E->evaluateAsAbsolute(ScaleVal, getStreamer().getAssemblerPtr()))
3209 return Error(Loc,
"expected absolute expression");
3211 Warning(Loc,
"scale factor without index register is ignored");
3216 if (BaseReg == X86::RIP)
3218 "%rip as base register can not have an index register");
3219 if (IndexReg == X86::RIP)
3220 return Error(Loc,
"%rip is not allowed as an index register");
3231 return Error(Loc,
"expected scale expression");
3232 Scale = (unsigned)ScaleVal;
3234 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg) &&
3236 return Error(Loc,
"scale factor in 16-bit address must be 1");
3238 return Error(Loc, ErrMsg);
3252 if (BaseReg == X86::DX && !IndexReg && Scale == 1 && !SegReg &&
3261 return Error(BaseLoc, ErrMsg);
3263 if (CheckDispOverflow(BaseReg, IndexReg, Disp, BaseLoc))
3266 if (SegReg || BaseReg || IndexReg)
3268 BaseReg, IndexReg, Scale, StartLoc,
3277bool X86AsmParser::parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
3278 MCAsmParser &Parser = getParser();
3285 if (parseRegister(RegNo, StartLoc, EndLoc))
3293bool X86AsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
3295 MCAsmParser &Parser = getParser();
3299 ForcedOpcodePrefix = OpcodePrefix_Default;
3300 ForcedDispEncoding = DispEncoding_Default;
3301 UseApxExtendedReg =
false;
3302 ForcedNoFlag =
false;
3315 if (Prefix ==
"rex")
3316 ForcedOpcodePrefix = OpcodePrefix_REX;
3317 else if (Prefix ==
"rex2")
3318 ForcedOpcodePrefix = OpcodePrefix_REX2;
3319 else if (Prefix ==
"vex")
3320 ForcedOpcodePrefix = OpcodePrefix_VEX;
3321 else if (Prefix ==
"vex2")
3322 ForcedOpcodePrefix = OpcodePrefix_VEX2;
3323 else if (Prefix ==
"vex3")
3324 ForcedOpcodePrefix = OpcodePrefix_VEX3;
3325 else if (Prefix ==
"evex")
3326 ForcedOpcodePrefix = OpcodePrefix_EVEX;
3327 else if (Prefix ==
"disp8")
3328 ForcedDispEncoding = DispEncoding_Disp8;
3329 else if (Prefix ==
"disp32")
3330 ForcedDispEncoding = DispEncoding_Disp32;
3331 else if (Prefix ==
"nf")
3332 ForcedNoFlag =
true;
3334 return Error(NameLoc,
"unknown prefix");
3350 if (isParsingMSInlineAsm()) {
3351 if (
Name.equals_insensitive(
"vex"))
3352 ForcedOpcodePrefix = OpcodePrefix_VEX;
3353 else if (
Name.equals_insensitive(
"vex2"))
3354 ForcedOpcodePrefix = OpcodePrefix_VEX2;
3355 else if (
Name.equals_insensitive(
"vex3"))
3356 ForcedOpcodePrefix = OpcodePrefix_VEX3;
3357 else if (
Name.equals_insensitive(
"evex"))
3358 ForcedOpcodePrefix = OpcodePrefix_EVEX;
3360 if (ForcedOpcodePrefix != OpcodePrefix_Default) {
3373 if (
Name.consume_back(
".d32")) {
3374 ForcedDispEncoding = DispEncoding_Disp32;
3375 }
else if (
Name.consume_back(
".d8")) {
3376 ForcedDispEncoding = DispEncoding_Disp8;
3379 StringRef PatchedName =
Name;
3382 if (isParsingIntelSyntax() &&
3383 (PatchedName ==
"jmp" || PatchedName ==
"jc" || PatchedName ==
"jnc" ||
3384 PatchedName ==
"jcxz" || PatchedName ==
"jecxz" ||
3389 : NextTok ==
"short") {
3398 NextTok.
size() + 1);
3404 PatchedName !=
"setzub" && PatchedName !=
"setzunb" &&
3405 PatchedName !=
"setb" && PatchedName !=
"setnb")
3406 PatchedName = PatchedName.
substr(0,
Name.size()-1);
3408 unsigned ComparisonPredicate = ~0
U;
3416 bool IsVCMP = PatchedName[0] ==
'v';
3417 unsigned CCIdx =
IsVCMP ? 4 : 3;
3418 unsigned suffixLength = PatchedName.
ends_with(
"bf16") ? 5 : 2;
3419 unsigned CC = StringSwitch<unsigned>(
3420 PatchedName.
slice(CCIdx, PatchedName.
size() - suffixLength))
3422 .Case(
"eq_oq", 0x00)
3424 .Case(
"lt_os", 0x01)
3426 .Case(
"le_os", 0x02)
3427 .Case(
"unord", 0x03)
3428 .Case(
"unord_q", 0x03)
3430 .Case(
"neq_uq", 0x04)
3432 .Case(
"nlt_us", 0x05)
3434 .Case(
"nle_us", 0x06)
3436 .Case(
"ord_q", 0x07)
3438 .Case(
"eq_uq", 0x08)
3440 .Case(
"nge_us", 0x09)
3442 .Case(
"ngt_us", 0x0A)
3443 .Case(
"false", 0x0B)
3444 .Case(
"false_oq", 0x0B)
3445 .Case(
"neq_oq", 0x0C)
3447 .Case(
"ge_os", 0x0D)
3449 .Case(
"gt_os", 0x0E)
3451 .Case(
"true_uq", 0x0F)
3452 .Case(
"eq_os", 0x10)
3453 .Case(
"lt_oq", 0x11)
3454 .Case(
"le_oq", 0x12)
3455 .Case(
"unord_s", 0x13)
3456 .Case(
"neq_us", 0x14)
3457 .Case(
"nlt_uq", 0x15)
3458 .Case(
"nle_uq", 0x16)
3459 .Case(
"ord_s", 0x17)
3460 .Case(
"eq_us", 0x18)
3461 .Case(
"nge_uq", 0x19)
3462 .Case(
"ngt_uq", 0x1A)
3463 .Case(
"false_os", 0x1B)
3464 .Case(
"neq_os", 0x1C)
3465 .Case(
"ge_oq", 0x1D)
3466 .Case(
"gt_oq", 0x1E)
3467 .Case(
"true_us", 0x1F)
3469 if (CC != ~0U && (
IsVCMP || CC < 8) &&
3472 PatchedName =
IsVCMP ?
"vcmpss" :
"cmpss";
3474 PatchedName =
IsVCMP ?
"vcmpsd" :
"cmpsd";
3476 PatchedName =
IsVCMP ?
"vcmpps" :
"cmpps";
3478 PatchedName =
IsVCMP ?
"vcmppd" :
"cmppd";
3480 PatchedName =
"vcmpsh";
3482 PatchedName =
"vcmpph";
3484 PatchedName =
"vcmpbf16";
3488 ComparisonPredicate = CC;
3494 (PatchedName.
back() ==
'b' || PatchedName.
back() ==
'w' ||
3495 PatchedName.
back() ==
'd' || PatchedName.
back() ==
'q')) {
3496 unsigned SuffixSize = PatchedName.
drop_back().
back() ==
'u' ? 2 : 1;
3497 unsigned CC = StringSwitch<unsigned>(
3498 PatchedName.
slice(5, PatchedName.
size() - SuffixSize))
3508 if (CC != ~0U && (CC != 0 || SuffixSize == 2)) {
3509 switch (PatchedName.
back()) {
3511 case 'b': PatchedName = SuffixSize == 2 ?
"vpcmpub" :
"vpcmpb";
break;
3512 case 'w': PatchedName = SuffixSize == 2 ?
"vpcmpuw" :
"vpcmpw";
break;
3513 case 'd': PatchedName = SuffixSize == 2 ?
"vpcmpud" :
"vpcmpd";
break;
3514 case 'q': PatchedName = SuffixSize == 2 ?
"vpcmpuq" :
"vpcmpq";
break;
3517 ComparisonPredicate = CC;
3523 (PatchedName.
back() ==
'b' || PatchedName.
back() ==
'w' ||
3524 PatchedName.
back() ==
'd' || PatchedName.
back() ==
'q')) {
3525 unsigned SuffixSize = PatchedName.
drop_back().
back() ==
'u' ? 2 : 1;
3526 unsigned CC = StringSwitch<unsigned>(
3527 PatchedName.
slice(5, PatchedName.
size() - SuffixSize))
3538 switch (PatchedName.
back()) {
3540 case 'b': PatchedName = SuffixSize == 2 ?
"vpcomub" :
"vpcomb";
break;
3541 case 'w': PatchedName = SuffixSize == 2 ?
"vpcomuw" :
"vpcomw";
break;
3542 case 'd': PatchedName = SuffixSize == 2 ?
"vpcomud" :
"vpcomd";
break;
3543 case 'q': PatchedName = SuffixSize == 2 ?
"vpcomuq" :
"vpcomq";
break;
3546 ComparisonPredicate = CC;
3558 StringSwitch<bool>(Name)
3559 .Cases({
"cs",
"ds",
"es",
"fs",
"gs",
"ss"},
true)
3560 .Cases({
"rex64",
"data32",
"data16",
"addr32",
"addr16"},
true)
3561 .Cases({
"xacquire",
"xrelease"},
true)
3562 .Cases({
"acquire",
"release"}, isParsingIntelSyntax())
3565 auto isLockRepeatNtPrefix = [](StringRef
N) {
3566 return StringSwitch<bool>(
N)
3567 .Cases({
"lock",
"rep",
"repe",
"repz",
"repne",
"repnz",
"notrack"},
3572 bool CurlyAsEndOfStatement =
false;
3575 while (isLockRepeatNtPrefix(
Name.lower())) {
3577 StringSwitch<unsigned>(Name)
3596 while (
Name.starts_with(
";") ||
Name.starts_with(
"\n") ||
3597 Name.starts_with(
"#") ||
Name.starts_with(
"\t") ||
3598 Name.starts_with(
"/")) {
3609 if (PatchedName ==
"data16" && is16BitMode()) {
3610 return Error(NameLoc,
"redundant data16 prefix");
3612 if (PatchedName ==
"data32") {
3614 return Error(NameLoc,
"redundant data32 prefix");
3616 return Error(NameLoc,
"'data32' is not supported in 64-bit mode");
3618 PatchedName =
"data16";
3625 if (
Next ==
"callw")
3627 if (
Next ==
"ljmpw")
3632 ForcedDataPrefix = X86::Is32Bit;
3640 if (ComparisonPredicate != ~0U && !isParsingIntelSyntax()) {
3647 if ((
Name.starts_with(
"ccmp") ||
Name.starts_with(
"ctest")) &&
3648 parseCFlagsOp(Operands))
3662 if (parseOperand(Operands, Name))
3664 if (HandleAVX512Operand(Operands))
3676 CurlyAsEndOfStatement =
3677 isParsingIntelSyntax() && isParsingMSInlineAsm() &&
3680 return TokError(
"unexpected token in argument list");
3684 if (ComparisonPredicate != ~0U && isParsingIntelSyntax()) {
3694 else if (CurlyAsEndOfStatement)
3697 getLexer().getTok().getLoc(), 0);
3704 if (IsFp && Operands.
size() == 1) {
3705 const char *Repl = StringSwitch<const char *>(Name)
3706 .Case(
"fsub",
"fsubp")
3707 .Case(
"fdiv",
"fdivp")
3708 .Case(
"fsubr",
"fsubrp")
3709 .Case(
"fdivr",
"fdivrp");
3710 static_cast<X86Operand &
>(*Operands[0]).setTokenValue(Repl);
3713 if ((Name ==
"mov" || Name ==
"movw" || Name ==
"movl") &&
3714 (Operands.
size() == 3)) {
3715 X86Operand &Op1 = (X86Operand &)*Operands[1];
3716 X86Operand &Op2 = (X86Operand &)*Operands[2];
3721 X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(
3723 (X86MCRegisterClasses[X86::GR16RegClassID].contains(Op1.
getReg()) ||
3724 X86MCRegisterClasses[X86::GR32RegClassID].contains(Op1.
getReg()))) {
3726 if (Name !=
"mov" && Name[3] == (is16BitMode() ?
'l' :
'w')) {
3727 Name = is16BitMode() ?
"movw" :
"movl";
3740 if ((Name ==
"outb" || Name ==
"outsb" || Name ==
"outw" || Name ==
"outsw" ||
3741 Name ==
"outl" || Name ==
"outsl" || Name ==
"out" || Name ==
"outs") &&
3742 Operands.
size() == 3) {
3743 X86Operand &
Op = (X86Operand &)*Operands.
back();
3749 if ((Name ==
"inb" || Name ==
"insb" || Name ==
"inw" || Name ==
"insw" ||
3750 Name ==
"inl" || Name ==
"insl" || Name ==
"in" || Name ==
"ins") &&
3751 Operands.
size() == 3) {
3752 X86Operand &
Op = (X86Operand &)*Operands[1];
3759 bool HadVerifyError =
false;
3762 if (
Name.starts_with(
"ins") &&
3763 (Operands.
size() == 1 || Operands.
size() == 3) &&
3764 (Name ==
"insb" || Name ==
"insw" || Name ==
"insl" || Name ==
"insd" ||
3767 AddDefaultSrcDestOperands(TmpOperands,
3769 DefaultMemDIOperand(NameLoc));
3770 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3774 if (
Name.starts_with(
"outs") &&
3775 (Operands.
size() == 1 || Operands.
size() == 3) &&
3776 (Name ==
"outsb" || Name ==
"outsw" || Name ==
"outsl" ||
3777 Name ==
"outsd" || Name ==
"outs")) {
3778 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
3780 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3786 if (
Name.starts_with(
"lods") &&
3787 (Operands.
size() == 1 || Operands.
size() == 2) &&
3788 (Name ==
"lods" || Name ==
"lodsb" || Name ==
"lodsw" ||
3789 Name ==
"lodsl" || Name ==
"lodsd" || Name ==
"lodsq")) {
3790 TmpOperands.
push_back(DefaultMemSIOperand(NameLoc));
3791 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3797 if (
Name.starts_with(
"stos") &&
3798 (Operands.
size() == 1 || Operands.
size() == 2) &&
3799 (Name ==
"stos" || Name ==
"stosb" || Name ==
"stosw" ||
3800 Name ==
"stosl" || Name ==
"stosd" || Name ==
"stosq")) {
3801 TmpOperands.
push_back(DefaultMemDIOperand(NameLoc));
3802 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3808 if (
Name.starts_with(
"scas") &&
3809 (Operands.
size() == 1 || Operands.
size() == 2) &&
3810 (Name ==
"scas" || Name ==
"scasb" || Name ==
"scasw" ||
3811 Name ==
"scasl" || Name ==
"scasd" || Name ==
"scasq")) {
3812 TmpOperands.
push_back(DefaultMemDIOperand(NameLoc));
3813 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3817 if (
Name.starts_with(
"cmps") &&
3818 (Operands.
size() == 1 || Operands.
size() == 3) &&
3819 (Name ==
"cmps" || Name ==
"cmpsb" || Name ==
"cmpsw" ||
3820 Name ==
"cmpsl" || Name ==
"cmpsd" || Name ==
"cmpsq")) {
3821 AddDefaultSrcDestOperands(TmpOperands, DefaultMemDIOperand(NameLoc),
3822 DefaultMemSIOperand(NameLoc));
3823 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3827 if (((
Name.starts_with(
"movs") &&
3828 (Name ==
"movs" || Name ==
"movsb" || Name ==
"movsw" ||
3829 Name ==
"movsl" || Name ==
"movsd" || Name ==
"movsq")) ||
3830 (
Name.starts_with(
"smov") &&
3831 (Name ==
"smov" || Name ==
"smovb" || Name ==
"smovw" ||
3832 Name ==
"smovl" || Name ==
"smovd" || Name ==
"smovq"))) &&
3833 (Operands.
size() == 1 || Operands.
size() == 3)) {
3834 if (Name ==
"movsd" && Operands.
size() == 1 && !isParsingIntelSyntax())
3836 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
3837 DefaultMemDIOperand(NameLoc));
3838 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3842 if (HadVerifyError) {
3843 return HadVerifyError;
3847 if ((Name ==
"xlat" || Name ==
"xlatb") && Operands.
size() == 2) {
3848 X86Operand &Op1 =
static_cast<X86Operand &
>(*Operands[1]);
3851 "size, (R|E)BX will be used for the location");
3853 static_cast<X86Operand &
>(*Operands[0]).setTokenValue(
"xlatb");
3866 if (
I == Table.
end() ||
I->OldOpc != Opcode)
3872 if (X86::isBLENDVPD(Opcode) || X86::isBLENDVPS(Opcode) ||
3873 X86::isPBLENDVB(Opcode))
3879bool X86AsmParser::processInstruction(MCInst &Inst,
const OperandVector &
Ops) {
3883 if (ForcedOpcodePrefix != OpcodePrefix_VEX3 &&
3890 auto replaceWithCCMPCTEST = [&](
unsigned Opcode) ->
bool {
3891 if (ForcedOpcodePrefix == OpcodePrefix_EVEX) {
3902 default:
return false;
3907 if (ForcedDispEncoding == DispEncoding_Disp32) {
3908 Inst.
setOpcode(is16BitMode() ? X86::JMP_2 : X86::JMP_4);
3917 if (ForcedDispEncoding == DispEncoding_Disp32) {
3918 Inst.
setOpcode(is16BitMode() ? X86::JCC_2 : X86::JCC_4);
3934#define FROM_TO(FROM, TO) \
3936 return replaceWithCCMPCTEST(X86::TO);
3938 FROM_TO(CMP64mi32, CCMP64mi32)
3941 FROM_TO(CMP64ri32, CCMP64ri32)
3968 FROM_TO(TEST64mi32, CTEST64mi32)
3970 FROM_TO(TEST64ri32, CTEST64ri32)
3990bool X86AsmParser::validateInstruction(MCInst &Inst,
const OperandVector &
Ops) {
3991 using namespace X86;
3992 const MCRegisterInfo *MRI =
getContext().getRegisterInfo();
3994 uint64_t TSFlags = MII.get(Opcode).TSFlags;
3995 if (isVFCMADDCPH(Opcode) || isVFCMADDCSH(Opcode) || isVFMADDCPH(Opcode) ||
3996 isVFMADDCSH(Opcode)) {
4000 return Warning(
Ops[0]->getStartLoc(),
"Destination register should be "
4001 "distinct from source registers");
4002 }
else if (isVFCMULCPH(Opcode) || isVFCMULCSH(Opcode) || isVFMULCPH(Opcode) ||
4003 isVFMULCSH(Opcode)) {
4013 return Warning(
Ops[0]->getStartLoc(),
"Destination register should be "
4014 "distinct from source registers");
4015 }
else if (isV4FMADDPS(Opcode) || isV4FMADDSS(Opcode) ||
4016 isV4FNMADDPS(Opcode) || isV4FNMADDSS(Opcode) ||
4017 isVP4DPWSSDS(Opcode) || isVP4DPWSSD(Opcode)) {
4022 if (Src2Enc % 4 != 0) {
4024 unsigned GroupStart = (Src2Enc / 4) * 4;
4025 unsigned GroupEnd = GroupStart + 3;
4027 "source register '" +
RegName +
"' implicitly denotes '" +
4028 RegName.take_front(3) + Twine(GroupStart) +
"' to '" +
4029 RegName.take_front(3) + Twine(GroupEnd) +
4032 }
else if (isVGATHERDPD(Opcode) || isVGATHERDPS(Opcode) ||
4033 isVGATHERQPD(Opcode) || isVGATHERQPS(Opcode) ||
4034 isVPGATHERDD(Opcode) || isVPGATHERDQ(Opcode) ||
4035 isVPGATHERQD(Opcode) || isVPGATHERQQ(Opcode)) {
4042 return Warning(
Ops[0]->getStartLoc(),
"index and destination registers "
4043 "should be distinct");
4049 if (Dest == Mask || Dest == Index || Mask == Index)
4050 return Warning(
Ops[0]->getStartLoc(),
"mask, index, and destination "
4051 "registers should be distinct");
4053 }
else if (isTCMMIMFP16PS(Opcode) || isTCMMRLFP16PS(Opcode) ||
4054 isTDPBF16PS(Opcode) || isTDPFP16PS(Opcode) || isTDPBSSD(Opcode) ||
4055 isTDPBSUD(Opcode) || isTDPBUSD(Opcode) || isTDPBUUD(Opcode)) {
4059 if (SrcDest == Src1 || SrcDest == Src2 || Src1 == Src2)
4060 return Error(
Ops[0]->getStartLoc(),
"all tmm registers must be distinct");
4074 for (
unsigned i = 0; i !=
NumOps; ++i) {
4079 if (
Reg == X86::AH ||
Reg == X86::BH ||
Reg == X86::CH ||
Reg == X86::DH)
4087 (Enc ==
X86II::EVEX || ForcedOpcodePrefix == OpcodePrefix_REX2 ||
4088 ForcedOpcodePrefix == OpcodePrefix_REX || UsesRex)) {
4090 return Error(
Ops[0]->getStartLoc(),
4091 "can't encode '" +
RegName.str() +
4092 "' in an instruction requiring EVEX/REX2/REX prefix");
4096 if ((Opcode == X86::PREFETCHIT0 || Opcode == X86::PREFETCHIT1)) {
4100 Ops[0]->getStartLoc(),
4101 Twine((Inst.
getOpcode() == X86::PREFETCHIT0 ?
"'prefetchit0'"
4102 :
"'prefetchit1'")) +
4103 " only supports RIP-relative address");
4108void X86AsmParser::emitWarningForSpecialLVIInstruction(SMLoc Loc) {
4109 Warning(Loc,
"Instruction may be vulnerable to LVI and "
4110 "requires manual mitigation");
4111 Note(SMLoc(),
"See https://software.intel.com/"
4112 "security-software-guidance/insights/"
4113 "deep-dive-load-value-injection#specialinstructions"
4114 " for more information");
4126void X86AsmParser::applyLVICFIMitigation(MCInst &Inst, MCStreamer &Out) {
4137 MCInst ShlInst, FenceInst;
4138 bool Parse32 = is32BitMode() || Code16GCC;
4139 MCRegister Basereg =
4140 is64BitMode() ? X86::RSP : (Parse32 ? X86::ESP : X86::SP);
4144 1, SMLoc{}, SMLoc{}, 0);
4146 ShlMemOp->addMemOperands(ShlInst, 5);
4159 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4171void X86AsmParser::applyLVILoadHardeningMitigation(MCInst &Inst,
4188 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4191 }
else if (Opcode == X86::REP_PREFIX || Opcode == X86::REPNE_PREFIX) {
4194 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4198 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
4213void X86AsmParser::emitInstruction(MCInst &Inst,
OperandVector &Operands,
4216 getSTI().hasFeature(X86::FeatureLVIControlFlowIntegrity))
4217 applyLVICFIMitigation(Inst, Out);
4222 getSTI().hasFeature(X86::FeatureLVILoadHardening))
4223 applyLVILoadHardeningMitigation(Inst, Out);
4227 unsigned Result = 0;
4229 if (Prefix.isPrefix()) {
4230 Result = Prefix.getPrefix();
4236bool X86AsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
4238 MCStreamer &Out, uint64_t &ErrorInfo,
4239 bool MatchingInlineAsm) {
4240 assert(!Operands.
empty() &&
"Unexpect empty operand list!");
4241 assert((*Operands[0]).isToken() &&
"Leading operand should always be a mnemonic!");
4244 MatchFPUWaitAlias(IDLoc,
static_cast<X86Operand &
>(*Operands[0]), Operands,
4245 Out, MatchingInlineAsm);
4252 if (ForcedOpcodePrefix == OpcodePrefix_REX)
4254 else if (ForcedOpcodePrefix == OpcodePrefix_REX2)
4256 else if (ForcedOpcodePrefix == OpcodePrefix_VEX)
4258 else if (ForcedOpcodePrefix == OpcodePrefix_VEX2)
4260 else if (ForcedOpcodePrefix == OpcodePrefix_VEX3)
4262 else if (ForcedOpcodePrefix == OpcodePrefix_EVEX)
4266 if (ForcedDispEncoding == DispEncoding_Disp8)
4268 else if (ForcedDispEncoding == DispEncoding_Disp32)
4274 return isParsingIntelSyntax()
4275 ? matchAndEmitIntelInstruction(IDLoc, Opcode, Inst, Operands, Out,
4276 ErrorInfo, MatchingInlineAsm)
4277 : matchAndEmitATTInstruction(IDLoc, Opcode, Inst, Operands, Out,
4278 ErrorInfo, MatchingInlineAsm);
4281void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &
Op,
4283 bool MatchingInlineAsm) {
4287 const char *Repl = StringSwitch<const char *>(
Op.getToken())
4288 .Case(
"finit",
"fninit")
4289 .Case(
"fsave",
"fnsave")
4290 .Case(
"fstcw",
"fnstcw")
4291 .Case(
"fstcww",
"fnstcw")
4292 .Case(
"fstenv",
"fnstenv")
4293 .Case(
"fstsw",
"fnstsw")
4294 .Case(
"fstsww",
"fnstsw")
4295 .Case(
"fclex",
"fnclex")
4301 if (!MatchingInlineAsm)
4307bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc,
4308 const FeatureBitset &MissingFeatures,
4309 bool MatchingInlineAsm) {
4310 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
4311 SmallString<126> Msg;
4312 raw_svector_ostream OS(Msg);
4313 OS <<
"instruction requires:";
4314 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
4315 if (MissingFeatures[i])
4318 return Error(IDLoc, OS.str(), SMRange(), MatchingInlineAsm);
4321unsigned X86AsmParser::checkTargetMatchPredicate(MCInst &Inst) {
4323 const MCInstrDesc &MCID = MII.get(
Opc);
4324 uint64_t TSFlags = MCID.
TSFlags;
4327 return Match_Unsupported;
4329 return Match_Unsupported;
4331 switch (ForcedOpcodePrefix) {
4332 case OpcodePrefix_Default:
4334 case OpcodePrefix_REX:
4335 case OpcodePrefix_REX2:
4337 return Match_Unsupported;
4339 case OpcodePrefix_VEX:
4340 case OpcodePrefix_VEX2:
4341 case OpcodePrefix_VEX3:
4343 return Match_Unsupported;
4345 case OpcodePrefix_EVEX:
4347 !X86::isCMP(
Opc) && !X86::isTEST(
Opc))
4348 return Match_Unsupported;
4350 return Match_Unsupported;
4355 (ForcedOpcodePrefix != OpcodePrefix_VEX &&
4356 ForcedOpcodePrefix != OpcodePrefix_VEX2 &&
4357 ForcedOpcodePrefix != OpcodePrefix_VEX3))
4358 return Match_Unsupported;
4360 return Match_Success;
4363bool X86AsmParser::matchAndEmitATTInstruction(
4364 SMLoc IDLoc,
unsigned &Opcode, MCInst &Inst,
OperandVector &Operands,
4365 MCStreamer &Out, uint64_t &ErrorInfo,
bool MatchingInlineAsm) {
4366 X86Operand &
Op =
static_cast<X86Operand &
>(*Operands[0]);
4370 if (ForcedDataPrefix == X86::Is32Bit)
4371 SwitchMode(X86::Is32Bit);
4373 FeatureBitset MissingFeatures;
4374 unsigned OriginalError = MatchInstruction(Operands, Inst, ErrorInfo,
4375 MissingFeatures, MatchingInlineAsm,
4376 isParsingIntelSyntax());
4377 if (ForcedDataPrefix == X86::Is32Bit) {
4378 SwitchMode(X86::Is16Bit);
4379 ForcedDataPrefix = 0;
4381 switch (OriginalError) {
4384 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
4389 if (!MatchingInlineAsm)
4390 while (processInstruction(Inst, Operands))
4394 if (!MatchingInlineAsm)
4398 case Match_InvalidImmUnsignedi4: {
4399 SMLoc ErrorLoc = ((X86Operand &)*Operands[ErrorInfo]).getStartLoc();
4400 if (ErrorLoc == SMLoc())
4402 return Error(ErrorLoc,
"immediate must be an integer in range [0, 15]",
4403 EmptyRange, MatchingInlineAsm);
4405 case Match_InvalidImmUnsignedi6: {
4406 SMLoc ErrorLoc = ((X86Operand &)*Operands[ErrorInfo]).getStartLoc();
4407 if (ErrorLoc == SMLoc())
4409 return Error(ErrorLoc,
"immediate must be an integer in range [0, 63]",
4410 EmptyRange, MatchingInlineAsm);
4412 case Match_MissingFeature:
4413 return ErrorMissingFeature(IDLoc, MissingFeatures, MatchingInlineAsm);
4414 case Match_InvalidOperand:
4415 case Match_MnemonicFail:
4416 case Match_Unsupported:
4419 if (
Op.getToken().empty()) {
4420 Error(IDLoc,
"instruction must have size higher than 0", EmptyRange,
4431 StringRef
Base =
Op.getToken();
4432 SmallString<16> Tmp;
4435 Op.setTokenValue(Tmp);
4443 const char *Suffixes =
Base[0] !=
'f' ?
"bwlq" :
"slt\0";
4445 const char *MemSize =
Base[0] !=
'f' ?
"\x08\x10\x20\x40" :
"\x20\x40\x50\0";
4448 uint64_t ErrorInfoIgnore;
4449 FeatureBitset ErrorInfoMissingFeatures;
4457 bool HasVectorReg =
false;
4458 X86Operand *MemOp =
nullptr;
4459 for (
const auto &
Op : Operands) {
4460 X86Operand *X86Op =
static_cast<X86Operand *
>(
Op.get());
4462 HasVectorReg =
true;
4463 else if (X86Op->
isMem()) {
4465 assert(MemOp->Mem.Size == 0 &&
"Memory size always 0 under ATT syntax");
4472 for (
unsigned I = 0,
E = std::size(Match);
I !=
E; ++
I) {
4473 Tmp.
back() = Suffixes[
I];
4474 if (MemOp && HasVectorReg)
4475 MemOp->Mem.Size = MemSize[
I];
4476 Match[
I] = Match_MnemonicFail;
4477 if (MemOp || !HasVectorReg) {
4479 MatchInstruction(Operands, Inst, ErrorInfoIgnore, MissingFeatures,
4480 MatchingInlineAsm, isParsingIntelSyntax());
4482 if (Match[
I] == Match_MissingFeature)
4483 ErrorInfoMissingFeatures = MissingFeatures;
4493 unsigned NumSuccessfulMatches =
llvm::count(Match, Match_Success);
4494 if (NumSuccessfulMatches == 1) {
4495 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
4500 if (!MatchingInlineAsm)
4501 while (processInstruction(Inst, Operands))
4505 if (!MatchingInlineAsm)
4515 if (NumSuccessfulMatches > 1) {
4517 unsigned NumMatches = 0;
4518 for (
unsigned I = 0,
E = std::size(Match);
I !=
E; ++
I)
4519 if (Match[
I] == Match_Success)
4520 MatchChars[NumMatches++] = Suffixes[
I];
4522 SmallString<126> Msg;
4523 raw_svector_ostream OS(Msg);
4524 OS <<
"ambiguous instructions require an explicit suffix (could be ";
4525 for (
unsigned i = 0; i != NumMatches; ++i) {
4528 if (i + 1 == NumMatches)
4530 OS <<
"'" <<
Base << MatchChars[i] <<
"'";
4533 Error(IDLoc, OS.str(), EmptyRange, MatchingInlineAsm);
4541 if (
llvm::count(Match, Match_MnemonicFail) == 4) {
4542 if (OriginalError == Match_MnemonicFail)
4543 return Error(IDLoc,
"invalid instruction mnemonic '" +
Base +
"'",
4544 Op.getLocRange(), MatchingInlineAsm);
4546 if (OriginalError == Match_Unsupported)
4547 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4550 assert(OriginalError == Match_InvalidOperand &&
"Unexpected error");
4552 if (ErrorInfo != ~0ULL) {
4553 if (ErrorInfo >= Operands.size())
4554 return Error(IDLoc,
"too few operands for instruction", EmptyRange,
4557 X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo];
4561 OperandRange, MatchingInlineAsm);
4565 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4571 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4577 if (
llvm::count(Match, Match_MissingFeature) == 1) {
4578 ErrorInfo = Match_MissingFeature;
4579 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
4585 if (
llvm::count(Match, Match_InvalidOperand) == 1) {
4586 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4591 Error(IDLoc,
"unknown use of instruction mnemonic without a size suffix",
4592 EmptyRange, MatchingInlineAsm);
4596bool X86AsmParser::matchAndEmitIntelInstruction(
4597 SMLoc IDLoc,
unsigned &Opcode, MCInst &Inst,
OperandVector &Operands,
4598 MCStreamer &Out, uint64_t &ErrorInfo,
bool MatchingInlineAsm) {
4599 X86Operand &
Op =
static_cast<X86Operand &
>(*Operands[0]);
4602 X86Operand *UnsizedMemOp =
nullptr;
4603 for (
const auto &
Op : Operands) {
4604 X86Operand *X86Op =
static_cast<X86Operand *
>(
Op.get());
4606 UnsizedMemOp = X86Op;
4615 StringRef Mnemonic = (
static_cast<X86Operand &
>(*Operands[0])).
getToken();
4617 static const char *
const PtrSizedInstrs[] = {
"call",
"jmp",
"push",
"pop"};
4618 for (
const char *Instr : PtrSizedInstrs) {
4619 if (Mnemonic == Instr) {
4620 UnsizedMemOp->
Mem.
Size = getPointerWidth();
4626 SmallVector<unsigned, 8> Match;
4627 FeatureBitset ErrorInfoMissingFeatures;
4628 FeatureBitset MissingFeatures;
4629 StringRef
Base = (
static_cast<X86Operand &
>(*Operands[0])).
getToken();
4633 if (Mnemonic ==
"push" && Operands.size() == 2) {
4634 auto *X86Op =
static_cast<X86Operand *
>(Operands[1].get());
4635 if (X86Op->
isImm()) {
4638 unsigned Size = getPointerWidth();
4641 SmallString<16> Tmp;
4643 Tmp += (is64BitMode())
4645 : (is32BitMode()) ?
"l" : (is16BitMode()) ?
"w" :
" ";
4646 Op.setTokenValue(Tmp);
4648 Match.
push_back(MatchInstruction(Operands, Inst, ErrorInfo,
4649 MissingFeatures, MatchingInlineAsm,
4660 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
4661 for (
unsigned Size : MopSizes) {
4663 uint64_t ErrorInfoIgnore;
4665 unsigned M = MatchInstruction(Operands, Inst, ErrorInfoIgnore,
4666 MissingFeatures, MatchingInlineAsm,
4667 isParsingIntelSyntax());
4672 if (Match.
back() == Match_MissingFeature)
4673 ErrorInfoMissingFeatures = MissingFeatures;
4683 if (Match.
empty()) {
4685 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,
4686 isParsingIntelSyntax()));
4688 if (Match.
back() == Match_MissingFeature)
4689 ErrorInfoMissingFeatures = MissingFeatures;
4697 if (Match.
back() == Match_MnemonicFail) {
4698 return Error(IDLoc,
"invalid instruction mnemonic '" + Mnemonic +
"'",
4699 Op.getLocRange(), MatchingInlineAsm);
4702 unsigned NumSuccessfulMatches =
llvm::count(Match, Match_Success);
4706 if (UnsizedMemOp && NumSuccessfulMatches > 1 &&
4709 unsigned M = MatchInstruction(
4710 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,
4711 isParsingIntelSyntax());
4712 if (M == Match_Success)
4713 NumSuccessfulMatches = 1;
4725 if (NumSuccessfulMatches == 1) {
4726 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
4731 if (!MatchingInlineAsm)
4732 while (processInstruction(Inst, Operands))
4735 if (!MatchingInlineAsm)
4739 }
else if (NumSuccessfulMatches > 1) {
4741 "multiple matches only possible with unsized memory operands");
4743 "ambiguous operand size for instruction '" + Mnemonic +
"\'",
4749 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4755 if (
llvm::count(Match, Match_MissingFeature) == 1) {
4756 ErrorInfo = Match_MissingFeature;
4757 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
4763 if (
llvm::count(Match, Match_InvalidOperand) == 1) {
4764 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4768 if (
llvm::count(Match, Match_InvalidImmUnsignedi4) == 1) {
4769 SMLoc ErrorLoc = ((X86Operand &)*Operands[ErrorInfo]).getStartLoc();
4770 if (ErrorLoc == SMLoc())
4772 return Error(ErrorLoc,
"immediate must be an integer in range [0, 15]",
4773 EmptyRange, MatchingInlineAsm);
4776 if (
llvm::count(Match, Match_InvalidImmUnsignedi6) == 1) {
4777 SMLoc ErrorLoc = ((X86Operand &)*Operands[ErrorInfo]).getStartLoc();
4778 if (ErrorLoc == SMLoc())
4780 return Error(ErrorLoc,
"immediate must be an integer in range [0, 63]",
4781 EmptyRange, MatchingInlineAsm);
4785 return Error(IDLoc,
"unknown instruction mnemonic", EmptyRange,
4789bool X86AsmParser::omitRegisterFromClobberLists(MCRegister
Reg) {
4790 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(
Reg);
4793bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
4794 MCAsmParser &Parser = getParser();
4797 return parseDirectiveArch();
4799 return ParseDirectiveCode(IDVal, DirectiveID.
getLoc());
4805 return Error(DirectiveID.
getLoc(),
"'.att_syntax noprefix' is not "
4806 "supported: registers must have a "
4807 "'%' prefix in .att_syntax");
4809 getParser().setAssemblerDialect(0);
4812 getParser().setAssemblerDialect(1);
4817 return Error(DirectiveID.
getLoc(),
"'.intel_syntax prefix' is not "
4818 "supported: registers must not have "
4819 "a '%' prefix in .intel_syntax");
4822 }
else if (IDVal ==
".nops")
4823 return parseDirectiveNops(DirectiveID.
getLoc());
4824 else if (IDVal ==
".even")
4825 return parseDirectiveEven(DirectiveID.
getLoc());
4826 else if (IDVal ==
".cv_fpo_proc")
4827 return parseDirectiveFPOProc(DirectiveID.
getLoc());
4828 else if (IDVal ==
".cv_fpo_setframe")
4829 return parseDirectiveFPOSetFrame(DirectiveID.
getLoc());
4830 else if (IDVal ==
".cv_fpo_pushreg")
4831 return parseDirectiveFPOPushReg(DirectiveID.
getLoc());
4832 else if (IDVal ==
".cv_fpo_stackalloc")
4833 return parseDirectiveFPOStackAlloc(DirectiveID.
getLoc());
4834 else if (IDVal ==
".cv_fpo_stackalign")
4835 return parseDirectiveFPOStackAlign(DirectiveID.
getLoc());
4836 else if (IDVal ==
".cv_fpo_endprologue")
4837 return parseDirectiveFPOEndPrologue(DirectiveID.
getLoc());
4838 else if (IDVal ==
".cv_fpo_endproc")
4839 return parseDirectiveFPOEndProc(DirectiveID.
getLoc());
4840 else if (IDVal ==
".seh_pushreg" ||
4842 return parseDirectiveSEHPushReg(DirectiveID.
getLoc());
4843 else if (IDVal ==
".seh_push2regs")
4844 return parseDirectiveSEHPush2Regs(DirectiveID.
getLoc());
4845 else if (IDVal ==
".seh_setframe" ||
4847 return parseDirectiveSEHSetFrame(DirectiveID.
getLoc());
4848 else if (IDVal ==
".seh_savereg" ||
4850 return parseDirectiveSEHSaveReg(DirectiveID.
getLoc());
4851 else if (IDVal ==
".seh_savexmm" ||
4853 return parseDirectiveSEHSaveXMM(DirectiveID.
getLoc());
4854 else if (IDVal ==
".seh_pushframe" ||
4856 return parseDirectiveSEHPushFrame(DirectiveID.
getLoc());
4861bool X86AsmParser::parseDirectiveArch() {
4863 getParser().parseStringToEndOfStatement();
4869bool X86AsmParser::parseDirectiveNops(SMLoc L) {
4870 int64_t NumBytes = 0, Control = 0;
4871 SMLoc NumBytesLoc, ControlLoc;
4872 const MCSubtargetInfo& STI = getSTI();
4873 NumBytesLoc = getTok().getLoc();
4874 if (getParser().checkForValidSection() ||
4875 getParser().parseAbsoluteExpression(NumBytes))
4879 ControlLoc = getTok().getLoc();
4880 if (getParser().parseAbsoluteExpression(Control))
4883 if (getParser().parseEOL())
4886 if (NumBytes <= 0) {
4887 Error(NumBytesLoc,
"'.nops' directive with non-positive size");
4892 Error(ControlLoc,
"'.nops' directive with negative NOP size");
4897 getParser().getStreamer().emitNops(NumBytes, Control, L, STI);
4904bool X86AsmParser::parseDirectiveEven(SMLoc L) {
4908 const MCSection *
Section = getStreamer().getCurrentSectionOnly();
4910 getStreamer().initSections(getSTI());
4911 Section = getStreamer().getCurrentSectionOnly();
4913 if (
getContext().getAsmInfo().useCodeAlign(*Section))
4914 getStreamer().emitCodeAlignment(
Align(2), &getSTI(), 0);
4916 getStreamer().emitValueToAlignment(
Align(2), 0, 1, 0);
4922bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
4923 MCAsmParser &Parser = getParser();
4925 if (IDVal ==
".code16") {
4927 if (!is16BitMode()) {
4928 SwitchMode(X86::Is16Bit);
4929 getTargetStreamer().emitCode16();
4931 }
else if (IDVal ==
".code16gcc") {
4935 if (!is16BitMode()) {
4936 SwitchMode(X86::Is16Bit);
4937 getTargetStreamer().emitCode16();
4939 }
else if (IDVal ==
".code32") {
4941 if (!is32BitMode()) {
4942 SwitchMode(X86::Is32Bit);
4943 getTargetStreamer().emitCode32();
4945 }
else if (IDVal ==
".code64") {
4947 if (!is64BitMode()) {
4948 SwitchMode(X86::Is64Bit);
4949 getTargetStreamer().emitCode64();
4952 Error(L,
"unknown directive " + IDVal);
4960bool X86AsmParser::parseDirectiveFPOProc(SMLoc L) {
4961 MCAsmParser &Parser = getParser();
4965 return Parser.
TokError(
"expected symbol name");
4966 if (Parser.
parseIntToken(ParamsSize,
"expected parameter byte count"))
4969 return Parser.
TokError(
"parameters size out of range");
4973 return getTargetStreamer().emitFPOProc(ProcSym, ParamsSize, L);
4977bool X86AsmParser::parseDirectiveFPOSetFrame(SMLoc L) {
4980 if (parseRegister(
Reg, DummyLoc, DummyLoc) || parseEOL())
4982 return getTargetStreamer().emitFPOSetFrame(
Reg, L);
4986bool X86AsmParser::parseDirectiveFPOPushReg(SMLoc L) {
4989 if (parseRegister(
Reg, DummyLoc, DummyLoc) || parseEOL())
4991 return getTargetStreamer().emitFPOPushReg(
Reg, L);
4995bool X86AsmParser::parseDirectiveFPOStackAlloc(SMLoc L) {
4996 MCAsmParser &Parser = getParser();
5000 return getTargetStreamer().emitFPOStackAlloc(
Offset, L);
5004bool X86AsmParser::parseDirectiveFPOStackAlign(SMLoc L) {
5005 MCAsmParser &Parser = getParser();
5009 return getTargetStreamer().emitFPOStackAlign(
Offset, L);
5013bool X86AsmParser::parseDirectiveFPOEndPrologue(SMLoc L) {
5014 MCAsmParser &Parser = getParser();
5017 return getTargetStreamer().emitFPOEndPrologue(L);
5021bool X86AsmParser::parseDirectiveFPOEndProc(SMLoc L) {
5022 MCAsmParser &Parser = getParser();
5025 return getTargetStreamer().emitFPOEndProc(L);
5028bool X86AsmParser::parseSEHRegisterNumber(
unsigned RegClassID,
5029 MCRegister &RegNo) {
5030 SMLoc startLoc = getLexer().getLoc();
5031 const MCRegisterInfo *MRI =
getContext().getRegisterInfo();
5036 if (parseRegister(RegNo, startLoc, endLoc))
5039 if (!X86MCRegisterClasses[RegClassID].
contains(RegNo)) {
5040 return Error(startLoc,
5041 "register is not supported for use with this directive");
5047 if (getParser().parseAbsoluteExpression(EncodedReg))
5052 RegNo = MCRegister();
5053 for (
MCPhysReg Reg : X86MCRegisterClasses[RegClassID]) {
5060 return Error(startLoc,
5061 "incorrect register number for use with this directive");
5068bool X86AsmParser::parseDirectiveSEHPushReg(SMLoc Loc) {
5070 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5074 return TokError(
"expected end of directive");
5077 getStreamer().emitWinCFIPushReg(
Reg, Loc);
5081bool X86AsmParser::parseDirectiveSEHPush2Regs(SMLoc Loc) {
5083 if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg1))
5087 return TokError(
"expected comma between registers");
5091 if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg2))
5095 return TokError(
"expected end of directive");
5098 getStreamer().emitWinCFIPush2Regs(Reg1, Reg2, Loc);
5102bool X86AsmParser::parseDirectiveSEHSetFrame(SMLoc Loc) {
5105 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5108 return TokError(
"you must specify a stack pointer offset");
5111 if (getParser().parseAbsoluteExpression(Off))
5115 return TokError(
"expected end of directive");
5118 getStreamer().emitWinCFISetFrame(
Reg, Off, Loc);
5122bool X86AsmParser::parseDirectiveSEHSaveReg(SMLoc Loc) {
5125 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5128 return TokError(
"you must specify an offset on the stack");
5131 if (getParser().parseAbsoluteExpression(Off))
5135 return TokError(
"expected end of directive");
5138 getStreamer().emitWinCFISaveReg(
Reg, Off, Loc);
5142bool X86AsmParser::parseDirectiveSEHSaveXMM(SMLoc Loc) {
5145 if (parseSEHRegisterNumber(X86::VR128XRegClassID,
Reg))
5148 return TokError(
"you must specify an offset on the stack");
5151 if (getParser().parseAbsoluteExpression(Off))
5155 return TokError(
"expected end of directive");
5158 getStreamer().emitWinCFISaveXMM(
Reg, Off, Loc);
5162bool X86AsmParser::parseDirectiveSEHPushFrame(SMLoc Loc) {
5166 SMLoc startLoc = getLexer().getLoc();
5168 if (!getParser().parseIdentifier(CodeID)) {
5169 if (CodeID !=
"code")
5170 return Error(startLoc,
"expected @code");
5176 return TokError(
"expected end of directive");
5179 getStreamer().emitWinCFIPushFrame(Code, Loc);
5189#define GET_MATCHER_IMPLEMENTATION
5190#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