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,
bool SwapRegs =
false);
1236 bool parseDirectiveSEHSetFrame(SMLoc);
1237 bool parseDirectiveSEHSaveReg(SMLoc);
1238 bool parseDirectiveSEHSaveXMM(SMLoc);
1239 bool parseDirectiveSEHPushFrame(SMLoc);
1241 bool ensureMasmEpilogContext(SMLoc Loc);
1242 bool ensureMasmPrologContext(SMLoc Loc);
1244 unsigned checkTargetMatchPredicate(MCInst &Inst)
override;
1250 void emitWarningForSpecialLVIInstruction(SMLoc Loc);
1251 void applyLVICFIMitigation(MCInst &Inst, MCStreamer &Out);
1252 void applyLVILoadHardeningMitigation(MCInst &Inst, MCStreamer &Out);
1258 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1260 uint64_t &ErrorInfo,
1261 bool MatchingInlineAsm)
override;
1263 void MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &
Op,
OperandVector &Operands,
1264 MCStreamer &Out,
bool MatchingInlineAsm);
1266 bool ErrorMissingFeature(SMLoc IDLoc,
const FeatureBitset &MissingFeatures,
1267 bool MatchingInlineAsm);
1269 bool matchAndEmitATTInstruction(SMLoc IDLoc,
unsigned &Opcode, MCInst &Inst,
1271 uint64_t &ErrorInfo,
bool MatchingInlineAsm);
1273 bool matchAndEmitIntelInstruction(SMLoc IDLoc,
unsigned &Opcode, MCInst &Inst,
1275 uint64_t &ErrorInfo,
1276 bool MatchingInlineAsm);
1278 bool omitRegisterFromClobberLists(MCRegister
Reg)
override;
1285 bool ParseZ(std::unique_ptr<X86Operand> &Z, SMLoc StartLoc);
1287 bool is64BitMode()
const {
1289 return getSTI().hasFeature(X86::Is64Bit);
1291 bool is32BitMode()
const {
1293 return getSTI().hasFeature(X86::Is32Bit);
1295 bool is16BitMode()
const {
1297 return getSTI().hasFeature(X86::Is16Bit);
1299 void SwitchMode(
unsigned mode) {
1300 MCSubtargetInfo &STI = copySTI();
1301 FeatureBitset AllModes({X86::Is64Bit, X86::Is32Bit, X86::Is16Bit});
1303 FeatureBitset FB = ComputeAvailableFeatures(
1305 setAvailableFeatures(FB);
1310 unsigned getPointerWidth() {
1311 if (is16BitMode())
return 16;
1312 if (is32BitMode())
return 32;
1313 if (is64BitMode())
return 64;
1317 bool isParsingIntelSyntax() {
1318 return getParser().getAssemblerDialect();
1324#define GET_ASSEMBLER_HEADER
1325#include "X86GenAsmMatcher.inc"
1330 enum X86MatchResultTy {
1331 Match_Unsupported = FIRST_TARGET_MATCH_RESULT_TY,
1332#define GET_OPERAND_DIAGNOSTIC_TYPES
1333#include "X86GenAsmMatcher.inc"
1336 X86AsmParser(
const MCSubtargetInfo &sti, MCAsmParser &Parser,
1337 const MCInstrInfo &mii)
1338 : MCTargetAsmParser(sti, mii), InstInfo(nullptr), Code16GCC(
false) {
1343 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
1346 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
1347 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1348 SMLoc &EndLoc)
override;
1350 bool parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc)
override;
1352 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
1355 bool ParseDirective(AsmToken DirectiveID)
override;
1359#define GET_REGISTER_MATCHER
1360#define GET_SUBTARGET_FEATURE_NAME
1361#include "X86GenAsmMatcher.inc"
1372 !(BaseReg == X86::RIP || BaseReg == X86::EIP ||
1373 getX86MCRegisterClass(X86::GR16RegClassID).
contains(BaseReg) ||
1374 getX86MCRegisterClass(X86::GR32RegClassID).
contains(BaseReg) ||
1375 getX86MCRegisterClass(X86::GR64RegClassID).
contains(BaseReg))) {
1376 ErrMsg =
"invalid base+index expression";
1381 !(IndexReg == X86::EIZ || IndexReg == X86::RIZ ||
1382 getX86MCRegisterClass(X86::GR16RegClassID).
contains(IndexReg) ||
1383 getX86MCRegisterClass(X86::GR32RegClassID).
contains(IndexReg) ||
1384 getX86MCRegisterClass(X86::GR64RegClassID).
contains(IndexReg) ||
1385 getX86MCRegisterClass(X86::VR128XRegClassID).
contains(IndexReg) ||
1386 getX86MCRegisterClass(X86::VR256XRegClassID).
contains(IndexReg) ||
1387 getX86MCRegisterClass(X86::VR512RegClassID).
contains(IndexReg))) {
1388 ErrMsg =
"invalid base+index expression";
1392 if (((BaseReg == X86::RIP || BaseReg == X86::EIP) && IndexReg) ||
1393 IndexReg == X86::EIP || IndexReg == X86::RIP || IndexReg == X86::ESP ||
1394 IndexReg == X86::RSP) {
1395 ErrMsg =
"invalid base+index expression";
1401 if (getX86MCRegisterClass(X86::GR16RegClassID).
contains(BaseReg) &&
1402 (Is64BitMode || (BaseReg != X86::BX && BaseReg != X86::BP &&
1403 BaseReg != X86::SI && BaseReg != X86::DI))) {
1404 ErrMsg =
"invalid 16-bit base register";
1409 getX86MCRegisterClass(X86::GR16RegClassID).
contains(IndexReg)) {
1410 ErrMsg =
"16-bit memory operand may not include only index register";
1414 if (BaseReg && IndexReg) {
1415 if (getX86MCRegisterClass(X86::GR64RegClassID).
contains(BaseReg) &&
1416 (getX86MCRegisterClass(X86::GR16RegClassID).
contains(IndexReg) ||
1417 getX86MCRegisterClass(X86::GR32RegClassID).
contains(IndexReg) ||
1418 IndexReg == X86::EIZ)) {
1419 ErrMsg =
"base register is 64-bit, but index register is not";
1422 if (getX86MCRegisterClass(X86::GR32RegClassID).
contains(BaseReg) &&
1423 (getX86MCRegisterClass(X86::GR16RegClassID).
contains(IndexReg) ||
1424 getX86MCRegisterClass(X86::GR64RegClassID).
contains(IndexReg) ||
1425 IndexReg == X86::RIZ)) {
1426 ErrMsg =
"base register is 32-bit, but index register is not";
1429 if (getX86MCRegisterClass(X86::GR16RegClassID).
contains(BaseReg)) {
1430 if (getX86MCRegisterClass(X86::GR32RegClassID).
contains(IndexReg) ||
1431 getX86MCRegisterClass(X86::GR64RegClassID).
contains(IndexReg)) {
1432 ErrMsg =
"base register is 16-bit, but index register is not";
1435 if ((BaseReg != X86::BX && BaseReg != X86::BP) ||
1436 (IndexReg != X86::SI && IndexReg != X86::DI)) {
1437 ErrMsg =
"invalid 16-bit base/index register combination";
1444 if (!Is64BitMode && (BaseReg == X86::RIP || BaseReg == X86::EIP)) {
1445 ErrMsg =
"IP-relative addressing requires 64-bit mode";
1466 if (isParsingMSInlineAsm() && isParsingIntelSyntax() &&
1467 (RegNo == X86::EFLAGS || RegNo == X86::MXCSR))
1468 RegNo = MCRegister();
1470 if (!is64BitMode()) {
1474 if (RegNo == X86::RIZ || RegNo == X86::RIP ||
1475 getX86MCRegisterClass(X86::GR64RegClassID).
contains(RegNo) ||
1478 return Error(StartLoc,
1479 "register %" +
RegName +
" is only available in 64-bit mode",
1480 SMRange(StartLoc, EndLoc));
1485 UseApxExtendedReg =
true;
1489 if (!RegNo &&
RegName.starts_with(
"db")) {
1548 if (isParsingIntelSyntax())
1550 return Error(StartLoc,
"invalid register name", SMRange(StartLoc, EndLoc));
1555bool X86AsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
1556 SMLoc &EndLoc,
bool RestoreOnFailure) {
1557 MCAsmParser &Parser = getParser();
1558 AsmLexer &Lexer = getLexer();
1559 RegNo = MCRegister();
1562 auto OnFailure = [RestoreOnFailure, &Lexer, &Tokens]() {
1563 if (RestoreOnFailure) {
1564 while (!Tokens.
empty()) {
1570 const AsmToken &PercentTok = Parser.
getTok();
1571 StartLoc = PercentTok.
getLoc();
1580 const AsmToken &Tok = Parser.
getTok();
1585 if (isParsingIntelSyntax())
return true;
1586 return Error(StartLoc,
"invalid register name",
1587 SMRange(StartLoc, EndLoc));
1590 if (MatchRegisterByName(RegNo, Tok.
getString(), StartLoc, EndLoc)) {
1596 if (RegNo == X86::ST0) {
1607 const AsmToken &IntTok = Parser.
getTok();
1610 return Error(IntTok.
getLoc(),
"expected stack index");
1613 case 0: RegNo = X86::ST0;
break;
1614 case 1: RegNo = X86::ST1;
break;
1615 case 2: RegNo = X86::ST2;
break;
1616 case 3: RegNo = X86::ST3;
break;
1617 case 4: RegNo = X86::ST4;
break;
1618 case 5: RegNo = X86::ST5;
break;
1619 case 6: RegNo = X86::ST6;
break;
1620 case 7: RegNo = X86::ST7;
break;
1623 return Error(IntTok.
getLoc(),
"invalid stack index");
1643 if (isParsingIntelSyntax())
return true;
1644 return Error(StartLoc,
"invalid register name",
1645 SMRange(StartLoc, EndLoc));
1652bool X86AsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1654 return ParseRegister(
Reg, StartLoc, EndLoc,
false);
1657ParseStatus X86AsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1659 bool Result = ParseRegister(
Reg, StartLoc, EndLoc,
true);
1660 bool PendingErrors = getParser().hasPendingError();
1661 getParser().clearPendingErrors();
1669std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(SMLoc Loc) {
1670 bool Parse32 = is32BitMode() || Code16GCC;
1671 MCRegister Basereg =
1672 is64BitMode() ? X86::RSI : (Parse32 ? X86::ESI : X86::SI);
1679std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand(SMLoc Loc) {
1680 bool Parse32 = is32BitMode() || Code16GCC;
1681 MCRegister Basereg =
1682 is64BitMode() ? X86::RDI : (Parse32 ? X86::EDI : X86::DI);
1689bool X86AsmParser::IsSIReg(MCRegister
Reg) {
1703MCRegister X86AsmParser::GetSIDIForRegClass(
unsigned RegClassID,
bool IsSIReg) {
1704 switch (RegClassID) {
1706 case X86::GR64RegClassID:
1707 return IsSIReg ? X86::RSI : X86::RDI;
1708 case X86::GR32RegClassID:
1709 return IsSIReg ? X86::ESI : X86::EDI;
1710 case X86::GR16RegClassID:
1711 return IsSIReg ? X86::SI : X86::DI;
1715void X86AsmParser::AddDefaultSrcDestOperands(
1716 OperandVector& Operands, std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
1717 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst) {
1718 if (isParsingIntelSyntax()) {
1728bool X86AsmParser::VerifyAndAdjustOperands(
OperandVector &OrigOperands,
1731 if (OrigOperands.
size() > 1) {
1734 "Operand size mismatch");
1738 int RegClassID = -1;
1739 for (
unsigned int i = 0; i < FinalOperands.
size(); ++i) {
1740 X86Operand &OrigOp =
static_cast<X86Operand &
>(*OrigOperands[i + 1]);
1741 X86Operand &FinalOp =
static_cast<X86Operand &
>(*FinalOperands[i]);
1743 if (FinalOp.
isReg() &&
1748 if (FinalOp.
isMem()) {
1750 if (!OrigOp.
isMem())
1759 if (RegClassID != -1 &&
1760 !getX86MCRegisterClass(RegClassID).
contains(OrigReg)) {
1762 "mismatching source and destination index registers");
1765 if (getX86MCRegisterClass(X86::GR64RegClassID).
contains(OrigReg))
1766 RegClassID = X86::GR64RegClassID;
1767 else if (getX86MCRegisterClass(X86::GR32RegClassID).
contains(OrigReg))
1768 RegClassID = X86::GR32RegClassID;
1769 else if (getX86MCRegisterClass(X86::GR16RegClassID).
contains(OrigReg))
1770 RegClassID = X86::GR16RegClassID;
1776 bool IsSI = IsSIReg(FinalReg);
1777 FinalReg = GetSIDIForRegClass(RegClassID, IsSI);
1779 if (FinalReg != OrigReg) {
1780 std::string
RegName = IsSI ?
"ES:(R|E)SI" :
"ES:(R|E)DI";
1783 "memory operand is only for determining the size, " +
RegName +
1784 " will be used for the location"));
1795 for (
auto &WarningMsg : Warnings) {
1796 Warning(WarningMsg.first, WarningMsg.second);
1800 for (
unsigned int i = 0; i < FinalOperands.
size(); ++i)
1804 for (
auto &
Op : FinalOperands)
1810bool X86AsmParser::parseOperand(
OperandVector &Operands, StringRef Name) {
1811 if (isParsingIntelSyntax())
1812 return parseIntelOperand(Operands, Name);
1814 return parseATTOperand(Operands);
1817bool X86AsmParser::CreateMemForMSInlineAsm(
1818 MCRegister SegReg,
const MCExpr *Disp, MCRegister BaseReg,
1819 MCRegister IndexReg,
unsigned Scale,
bool NonAbsMem, SMLoc Start, SMLoc End,
1820 unsigned Size, StringRef Identifier,
const InlineAsmIdentifierInfo &Info,
1828 End,
Size, Identifier,
1835 unsigned FrontendSize = 0;
1836 void *Decl =
nullptr;
1837 bool IsGlobalLV =
false;
1840 FrontendSize =
Info.Var.Type * 8;
1841 Decl =
Info.Var.Decl;
1842 IsGlobalLV =
Info.Var.IsGlobalLV;
1847 if (BaseReg || IndexReg) {
1849 End,
Size, Identifier, Decl, 0,
1850 BaseReg && IndexReg));
1857 getPointerWidth(), SegReg, Disp, BaseReg, IndexReg, Scale, Start, End,
1859 X86::RIP, Identifier, Decl, FrontendSize));
1866bool X86AsmParser::ParseIntelNamedOperator(StringRef Name,
1867 IntelExprStateMachine &
SM,
1868 bool &ParseError, SMLoc &End) {
1871 if (Name !=
Name.lower() && Name !=
Name.upper() &&
1872 !getParser().isParsingMasm())
1874 if (
Name.equals_insensitive(
"not")) {
1876 }
else if (
Name.equals_insensitive(
"or")) {
1878 }
else if (
Name.equals_insensitive(
"shl")) {
1880 }
else if (
Name.equals_insensitive(
"shr")) {
1882 }
else if (
Name.equals_insensitive(
"xor")) {
1884 }
else if (
Name.equals_insensitive(
"and")) {
1886 }
else if (
Name.equals_insensitive(
"mod")) {
1888 }
else if (
Name.equals_insensitive(
"offset")) {
1889 SMLoc OffsetLoc = getTok().getLoc();
1890 const MCExpr *Val =
nullptr;
1892 InlineAsmIdentifierInfo
Info;
1893 ParseError = ParseIntelOffsetOperator(Val,
ID, Info, End);
1898 SM.onOffset(Val, OffsetLoc,
ID, Info, isParsingMSInlineAsm(), ErrMsg);
1904 if (!
Name.equals_insensitive(
"offset"))
1905 End = consumeToken();
1908bool X86AsmParser::ParseMasmNamedOperator(StringRef Name,
1909 IntelExprStateMachine &
SM,
1910 bool &ParseError, SMLoc &End) {
1911 if (
Name.equals_insensitive(
"eq")) {
1913 }
else if (
Name.equals_insensitive(
"ne")) {
1915 }
else if (
Name.equals_insensitive(
"lt")) {
1917 }
else if (
Name.equals_insensitive(
"le")) {
1919 }
else if (
Name.equals_insensitive(
"gt")) {
1921 }
else if (
Name.equals_insensitive(
"ge")) {
1926 End = consumeToken();
1933 IntelExprStateMachine &
SM) {
1937 SM.setAppendAfterOperand();
1940bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &
SM, SMLoc &End) {
1941 MCAsmParser &Parser = getParser();
1946 if (
getContext().getObjectFileInfo()->isPositionIndependent())
1953 const AsmToken &Tok = Parser.
getTok();
1955 bool UpdateLocLex =
true;
1960 if ((
Done =
SM.isValidEndState()))
1962 return Error(Tok.
getLoc(),
"unknown token in expression");
1964 return Error(getLexer().getErrLoc(), getLexer().getErr());
1968 UpdateLocLex =
false;
1969 if (ParseIntelDotOperator(
SM, End))
1974 if ((
Done =
SM.isValidEndState()))
1976 return Error(Tok.
getLoc(),
"unknown token in expression");
1980 UpdateLocLex =
false;
1981 if (ParseIntelDotOperator(
SM, End))
1986 if ((
Done =
SM.isValidEndState()))
1988 return Error(Tok.
getLoc(),
"unknown token in expression");
1994 SMLoc ValueLoc = Tok.
getLoc();
1999 UpdateLocLex =
false;
2000 if (!Val->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
2001 return Error(ValueLoc,
"expected absolute value");
2002 if (
SM.onInteger(Res, ErrMsg))
2003 return Error(
SM.getErrorLoc(ValueLoc), ErrMsg);
2010 SMLoc IdentLoc = Tok.
getLoc();
2012 UpdateLocLex =
false;
2014 size_t DotOffset =
Identifier.find_first_of(
'.');
2018 StringRef Dot =
Identifier.substr(DotOffset, 1);
2032 const AsmToken &NextTok = getLexer().peekTok();
2041 End = consumeToken();
2048 if (!ParseRegister(
Reg, IdentLoc, End,
true)) {
2049 if (
SM.onRegister(
Reg, ErrMsg))
2050 return Error(
SM.getErrorLoc(IdentLoc), ErrMsg);
2054 const std::pair<StringRef, StringRef> IDField =
2056 const StringRef
ID = IDField.first,
Field = IDField.second;
2058 if (!
Field.empty() &&
2059 !MatchRegisterByName(
Reg,
ID, IdentLoc, IDEndLoc)) {
2060 if (
SM.onRegister(
Reg, ErrMsg))
2061 return Error(
SM.getErrorLoc(IdentLoc), ErrMsg);
2066 return Error(FieldStartLoc,
"unknown offset");
2067 else if (
SM.onPlus(ErrMsg))
2068 return Error(getTok().getLoc(), ErrMsg);
2069 else if (
SM.onInteger(
Info.Offset, ErrMsg))
2070 return Error(
SM.getErrorLoc(IdentLoc), ErrMsg);
2071 SM.setTypeInfo(
Info.Type);
2073 End = consumeToken();
2080 if (ParseIntelNamedOperator(Identifier,
SM, ParseError, End)) {
2086 ParseMasmNamedOperator(Identifier,
SM, ParseError, End)) {
2092 InlineAsmIdentifierInfo
Info;
2093 AsmFieldInfo FieldInfo;
2099 if (ParseIntelDotOperator(
SM, End))
2104 if (isParsingMSInlineAsm()) {
2106 if (
unsigned OpKind = IdentifyIntelInlineAsmOperator(Identifier)) {
2107 if (int64_t Val = ParseIntelInlineAsmOperator(OpKind)) {
2108 if (
SM.onInteger(Val, ErrMsg))
2109 return Error(
SM.getErrorLoc(IdentLoc), ErrMsg);
2118 return Error(IdentLoc,
"expected identifier");
2119 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
false, End))
2121 else if (
SM.onIdentifierExpr(Val, Identifier, Info, FieldInfo.
Type,
2123 return Error(
SM.getErrorLoc(IdentLoc), ErrMsg);
2127 if (
unsigned OpKind = IdentifyMasmOperator(Identifier)) {
2129 if (ParseMasmOperator(OpKind, Val))
2131 if (
SM.onInteger(Val, ErrMsg))
2132 return Error(
SM.getErrorLoc(IdentLoc), ErrMsg);
2135 if (!getParser().lookUpType(Identifier, FieldInfo.
Type)) {
2141 getParser().parseIdentifier(Identifier);
2145 if (getParser().lookUpField(FieldInfo.
Type.
Name, Identifier,
2149 return Error(IdentLoc,
"Unable to lookup field reference!",
2150 SMRange(IdentLoc, IDEnd));
2155 if (
SM.onInteger(FieldInfo.
Offset, ErrMsg))
2156 return Error(
SM.getErrorLoc(IdentLoc), ErrMsg);
2160 if (getParser().parsePrimaryExpr(Val, End, &FieldInfo.
Type)) {
2161 return Error(Tok.
getLoc(),
"Unexpected identifier!");
2162 }
else if (
SM.onIdentifierExpr(Val, Identifier, Info, FieldInfo.
Type,
2164 return Error(
SM.getErrorLoc(IdentLoc), ErrMsg);
2170 SMLoc Loc = getTok().getLoc();
2171 int64_t
IntVal = getTok().getIntVal();
2172 End = consumeToken();
2173 UpdateLocLex =
false;
2175 StringRef IDVal = getTok().getString();
2176 if (IDVal ==
"f" || IDVal ==
"b") {
2178 getContext().getDirectionalLocalSymbol(IntVal, IDVal ==
"b");
2183 return Error(Loc,
"invalid reference to undefined symbol");
2185 InlineAsmIdentifierInfo
Info;
2187 if (
SM.onIdentifierExpr(Val, Identifier, Info,
Type,
2188 isParsingMSInlineAsm(), ErrMsg))
2189 return Error(
SM.getErrorLoc(Loc), ErrMsg);
2190 End = consumeToken();
2192 if (
SM.onInteger(IntVal, ErrMsg))
2193 return Error(
SM.getErrorLoc(Loc), ErrMsg);
2196 if (
SM.onInteger(IntVal, ErrMsg))
2197 return Error(
SM.getErrorLoc(Loc), ErrMsg);
2202 if (
SM.onPlus(ErrMsg))
2203 return Error(getTok().getLoc(), ErrMsg);
2206 if (
SM.onMinus(getTok().getLoc(), ErrMsg))
2207 return Error(
SM.getErrorLoc(getTok().getLoc()), ErrMsg);
2217 SM.onLShift();
break;
2219 SM.onRShift();
break;
2222 return Error(Tok.
getLoc(),
"unexpected bracket encountered");
2223 tryParseOperandIdx(PrevTK,
SM);
2226 if (
SM.onRBrac(ErrMsg)) {
2232 if (
SM.onRParen(ErrMsg)) {
2238 return Error(Tok.
getLoc(),
"unknown token in expression");
2240 if (!
Done && UpdateLocLex)
2241 End = consumeToken();
2248void X86AsmParser::RewriteIntelExpression(IntelExprStateMachine &
SM,
2249 SMLoc Start, SMLoc End) {
2253 if (
SM.getSym() && !
SM.isOffsetOperator()) {
2254 StringRef SymName =
SM.getSymName();
2255 if (
unsigned Len = SymName.
data() -
Start.getPointer())
2261 if (!(
SM.getBaseReg() ||
SM.getIndexReg() ||
SM.getImm())) {
2268 StringRef BaseRegStr;
2269 StringRef IndexRegStr;
2270 StringRef OffsetNameStr;
2271 if (
SM.getBaseReg())
2273 if (
SM.getIndexReg())
2275 if (
SM.isOffsetOperator())
2276 OffsetNameStr =
SM.getSymName();
2278 IntelExpr Expr(BaseRegStr, IndexRegStr,
SM.getScale(), OffsetNameStr,
2279 SM.getImm(),
SM.isMemExpr());
2280 InstInfo->
AsmRewrites->emplace_back(Loc, ExprLen, Expr);
2284bool X86AsmParser::ParseIntelInlineAsmIdentifier(
2285 const MCExpr *&Val, StringRef &Identifier, InlineAsmIdentifierInfo &Info,
2286 bool IsUnevaluatedOperand, SMLoc &End,
bool IsParsingOffsetOperator) {
2287 MCAsmParser &Parser = getParser();
2288 assert(isParsingMSInlineAsm() &&
"Expected to be parsing inline assembly.");
2292 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);
2294 const AsmToken &Tok = Parser.
getTok();
2295 SMLoc Loc = Tok.
getLoc();
2310 "frontend claimed part of a token?");
2315 StringRef InternalName =
2316 SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(),
2318 assert(InternalName.
size() &&
"We should have an internal name here.");
2321 if (!IsParsingOffsetOperator)
2336bool X86AsmParser::ParseRoundingModeOp(SMLoc Start,
OperandVector &Operands) {
2337 MCAsmParser &Parser = getParser();
2338 const AsmToken &Tok = Parser.
getTok();
2340 const SMLoc consumedToken = consumeToken();
2342 return Error(Tok.
getLoc(),
"Expected an identifier after {");
2345 .Case(
"rn", X86::STATIC_ROUNDING::TO_NEAREST_INT)
2346 .Case(
"rd", X86::STATIC_ROUNDING::TO_NEG_INF)
2347 .Case(
"ru", X86::STATIC_ROUNDING::TO_POS_INF)
2348 .Case(
"rz", X86::STATIC_ROUNDING::TO_ZERO)
2351 return Error(Tok.
getLoc(),
"Invalid rounding mode.");
2354 return Error(Tok.
getLoc(),
"Expected - at this point");
2358 return Error(Tok.
getLoc(),
"Expected } at this point");
2361 const MCExpr *RndModeOp =
2369 return Error(Tok.
getLoc(),
"Expected } at this point");
2374 return Error(Tok.
getLoc(),
"unknown token in expression");
2380 MCAsmParser &Parser = getParser();
2381 AsmToken Tok = Parser.
getTok();
2384 return Error(Tok.
getLoc(),
"Expected { at this point");
2388 return Error(Tok.
getLoc(),
"Expected dfv at this point");
2392 return Error(Tok.
getLoc(),
"Expected = at this point");
2404 unsigned CFlags = 0;
2405 for (
unsigned I = 0;
I < 4; ++
I) {
2414 return Error(Tok.
getLoc(),
"Invalid conditional flags");
2417 return Error(Tok.
getLoc(),
"Duplicated conditional flag");
2428 }
else if (
I == 3) {
2429 return Error(Tok.
getLoc(),
"Expected } at this point");
2431 return Error(Tok.
getLoc(),
"Expected } or , at this point");
2439bool X86AsmParser::ParseIntelDotOperator(IntelExprStateMachine &
SM,
2441 const AsmToken &Tok = getTok();
2447 bool TrailingDot =
false;
2455 }
else if ((isParsingMSInlineAsm() || getParser().isParsingMasm()) &&
2458 const std::pair<StringRef, StringRef> BaseMember = DotDispStr.
split(
'.');
2459 const StringRef
Base = BaseMember.first,
Member = BaseMember.second;
2460 if (getParser().lookUpField(
SM.getType(), DotDispStr, Info) &&
2461 getParser().lookUpField(
SM.getSymName(), DotDispStr, Info) &&
2462 getParser().lookUpField(DotDispStr, Info) &&
2464 SemaCallback->LookupInlineAsmField(
Base, Member,
Info.Offset)))
2465 return Error(Tok.
getLoc(),
"Unable to lookup field reference!");
2467 return Error(Tok.
getLoc(),
"Unexpected token type!");
2472 const char *DotExprEndLoc = DotDispStr.
data() + DotDispStr.
size();
2478 SM.setTypeInfo(
Info.Type);
2484bool X86AsmParser::ParseIntelOffsetOperator(
const MCExpr *&Val, StringRef &
ID,
2485 InlineAsmIdentifierInfo &Info,
2488 SMLoc
Start = Lex().getLoc();
2489 ID = getTok().getString();
2490 if (!isParsingMSInlineAsm()) {
2493 getParser().parsePrimaryExpr(Val, End,
nullptr))
2494 return Error(Start,
"unexpected token!");
2495 }
else if (ParseIntelInlineAsmIdentifier(Val,
ID, Info,
false, End,
true)) {
2496 return Error(Start,
"unable to lookup expression");
2498 return Error(Start,
"offset operator cannot yet handle constants");
2505unsigned X86AsmParser::IdentifyIntelInlineAsmOperator(StringRef Name) {
2506 return StringSwitch<unsigned>(Name)
2507 .Cases({
"TYPE",
"type"}, IOK_TYPE)
2508 .Cases({
"SIZE",
"size"}, IOK_SIZE)
2509 .Cases({
"LENGTH",
"length"}, IOK_LENGTH)
2519unsigned X86AsmParser::ParseIntelInlineAsmOperator(
unsigned OpKind) {
2520 MCAsmParser &Parser = getParser();
2521 const AsmToken &Tok = Parser.
getTok();
2524 const MCExpr *Val =
nullptr;
2525 InlineAsmIdentifierInfo
Info;
2528 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
2533 Error(Start,
"unable to lookup expression");
2540 case IOK_LENGTH: CVal =
Info.Var.Length;
break;
2541 case IOK_SIZE: CVal =
Info.Var.Size;
break;
2542 case IOK_TYPE: CVal =
Info.Var.Type;
break;
2550unsigned X86AsmParser::IdentifyMasmOperator(StringRef Name) {
2551 return StringSwitch<unsigned>(
Name.lower())
2552 .Case(
"type", MOK_TYPE)
2553 .Cases({
"size",
"sizeof"}, MOK_SIZEOF)
2554 .Cases({
"length",
"lengthof"}, MOK_LENGTHOF)
2564bool X86AsmParser::ParseMasmOperator(
unsigned OpKind, int64_t &Val) {
2565 MCAsmParser &Parser = getParser();
2570 if (OpKind == MOK_SIZEOF || OpKind == MOK_TYPE) {
2573 const AsmToken &IDTok = InParens ? getLexer().peekTok() : Parser.
getTok();
2589 IntelExprStateMachine
SM;
2591 if (ParseIntelExpression(
SM, End))
2601 Val =
SM.getLength();
2604 Val =
SM.getElementSize();
2609 return Error(OpLoc,
"expression has unknown type", SMRange(Start, End));
2615bool X86AsmParser::ParseIntelMemoryOperandSize(
unsigned &
Size,
2616 StringRef *SizeStr) {
2617 Size = StringSwitch<unsigned>(getTok().getString())
2618 .Cases({
"BYTE",
"byte"}, 8)
2619 .Cases({
"WORD",
"word"}, 16)
2620 .Cases({
"DWORD",
"dword"}, 32)
2621 .Cases({
"FLOAT",
"float"}, 32)
2622 .Cases({
"LONG",
"long"}, 32)
2623 .Cases({
"FWORD",
"fword"}, 48)
2624 .Cases({
"DOUBLE",
"double"}, 64)
2625 .Cases({
"QWORD",
"qword"}, 64)
2626 .Cases({
"MMWORD",
"mmword"}, 64)
2627 .Cases({
"XWORD",
"xword"}, 80)
2628 .Cases({
"TBYTE",
"tbyte"}, 80)
2629 .Cases({
"XMMWORD",
"xmmword"}, 128)
2630 .Cases({
"YMMWORD",
"ymmword"}, 256)
2631 .Cases({
"ZMMWORD",
"zmmword"}, 512)
2635 *SizeStr = getTok().getString();
2636 const AsmToken &Tok = Lex();
2638 return Error(Tok.
getLoc(),
"Expected 'PTR' or 'ptr' token!");
2645 if (getX86MCRegisterClass(X86::GR8RegClassID).
contains(RegNo))
2647 if (getX86MCRegisterClass(X86::GR16RegClassID).
contains(RegNo))
2649 if (getX86MCRegisterClass(X86::GR32RegClassID).
contains(RegNo))
2651 if (getX86MCRegisterClass(X86::GR64RegClassID).
contains(RegNo))
2657bool X86AsmParser::parseIntelOperand(
OperandVector &Operands, StringRef Name) {
2658 MCAsmParser &Parser = getParser();
2659 const AsmToken &Tok = Parser.
getTok();
2665 if (ParseIntelMemoryOperandSize(
Size, &SizeStr))
2667 bool PtrInOperand = bool(
Size);
2673 return ParseRoundingModeOp(Start, Operands);
2678 if (RegNo == X86::RIP)
2679 return Error(Start,
"rip can only be used as a base register");
2684 return Error(Start,
"expected memory operand after 'ptr', "
2685 "found register operand instead");
2694 "cannot cast register '" +
2696 "'; its size is not easily defined.");
2700 std::to_string(
RegSize) +
"-bit register '" +
2702 "' cannot be used as a " + std::to_string(
Size) +
"-bit " +
2709 if (!getX86MCRegisterClass(X86::SEGMENT_REGRegClassID).
contains(RegNo))
2710 return Error(Start,
"invalid segment register");
2712 Start = Lex().getLoc();
2716 IntelExprStateMachine
SM;
2717 if (ParseIntelExpression(
SM, End))
2720 if (isParsingMSInlineAsm())
2721 RewriteIntelExpression(
SM, Start, Tok.
getLoc());
2723 int64_t
Imm =
SM.getImm();
2724 const MCExpr *Disp =
SM.getSym();
2733 if (!
SM.isMemExpr() && !RegNo) {
2734 if (isParsingMSInlineAsm() &&
SM.isOffsetOperator()) {
2735 const InlineAsmIdentifierInfo &
Info =
SM.getIdentifierInfo();
2740 SM.getSymName(),
Info.Var.Decl,
2741 Info.Var.IsGlobalLV));
2752 MCRegister IndexReg =
SM.getIndexReg();
2753 if (IndexReg && BaseReg == X86::RIP)
2755 unsigned Scale =
SM.getScale();
2757 Size =
SM.getElementSize() << 3;
2759 if (Scale == 0 && BaseReg != X86::ESP && BaseReg != X86::RSP &&
2760 (IndexReg == X86::ESP || IndexReg == X86::RSP))
2766 !(getX86MCRegisterClass(X86::VR128XRegClassID).
contains(IndexReg) ||
2767 getX86MCRegisterClass(X86::VR256XRegClassID).
contains(IndexReg) ||
2768 getX86MCRegisterClass(X86::VR512RegClassID).
contains(IndexReg)) &&
2769 (getX86MCRegisterClass(X86::VR128XRegClassID).
contains(BaseReg) ||
2770 getX86MCRegisterClass(X86::VR256XRegClassID).
contains(BaseReg) ||
2771 getX86MCRegisterClass(X86::VR512RegClassID).
contains(BaseReg)))
2775 getX86MCRegisterClass(X86::GR16RegClassID).
contains(IndexReg))
2776 return Error(Start,
"16-bit addresses cannot have a scale");
2785 if ((BaseReg == X86::SI || BaseReg == X86::DI) &&
2786 (IndexReg == X86::BX || IndexReg == X86::BP))
2789 if ((BaseReg || IndexReg) &&
2792 return Error(Start, ErrMsg);
2793 bool IsUnconditionalBranch =
2794 Name.equals_insensitive(
"jmp") ||
Name.equals_insensitive(
"call");
2795 if (isParsingMSInlineAsm())
2796 return CreateMemForMSInlineAsm(RegNo, Disp, BaseReg, IndexReg, Scale,
2797 IsUnconditionalBranch && is64BitMode(),
2798 Start, End,
Size,
SM.getSymName(),
2799 SM.getIdentifierInfo(), Operands);
2803 MCRegister DefaultBaseReg;
2804 bool MaybeDirectBranchDest =
true;
2807 if (is64BitMode() &&
2808 ((PtrInOperand && !IndexReg) ||
SM.getElementSize() > 0)) {
2809 DefaultBaseReg = X86::RIP;
2811 if (IsUnconditionalBranch) {
2813 MaybeDirectBranchDest =
false;
2815 DefaultBaseReg = X86::RIP;
2816 }
else if (!BaseReg && !IndexReg && Disp &&
2818 if (is64BitMode()) {
2819 if (
SM.getSize() == 8) {
2820 MaybeDirectBranchDest =
false;
2821 DefaultBaseReg = X86::RIP;
2824 if (
SM.getSize() == 4 ||
SM.getSize() == 2)
2825 MaybeDirectBranchDest =
false;
2829 }
else if (IsUnconditionalBranch) {
2831 if (!PtrInOperand &&
SM.isOffsetOperator())
2833 Start,
"`OFFSET` operator cannot be used in an unconditional branch");
2834 if (PtrInOperand ||
SM.isBracketUsed())
2835 MaybeDirectBranchDest =
false;
2838 if (CheckDispOverflow(BaseReg, IndexReg, Disp, Start))
2841 if ((BaseReg || IndexReg || RegNo || DefaultBaseReg))
2843 getPointerWidth(), RegNo, Disp, BaseReg, IndexReg, Scale, Start, End,
2844 Size, DefaultBaseReg, StringRef(),
nullptr,
2845 0,
false, MaybeDirectBranchDest));
2848 getPointerWidth(), Disp, Start, End,
Size, StringRef(),
2850 MaybeDirectBranchDest));
2854bool X86AsmParser::parseATTOperand(
OperandVector &Operands) {
2855 MCAsmParser &Parser = getParser();
2856 switch (getLexer().getKind()) {
2866 "expected immediate expression") ||
2867 getParser().parseExpression(Val, End) ||
2875 return ParseRoundingModeOp(Start, Operands);
2884 const MCExpr *Expr =
nullptr;
2896 if (
Reg == X86::EIZ ||
Reg == X86::RIZ)
2898 Loc,
"%eiz and %riz can only be used as index registers",
2899 SMRange(Loc, EndLoc));
2900 if (
Reg == X86::RIP)
2901 return Error(Loc,
"%rip can only be used as a base register",
2902 SMRange(Loc, EndLoc));
2908 if (!getX86MCRegisterClass(X86::SEGMENT_REGRegClassID).
contains(
Reg))
2909 return Error(Loc,
"invalid segment register");
2917 return ParseMemOperand(
Reg, Expr, Loc, EndLoc, Operands);
2924X86::CondCode X86AsmParser::ParseConditionCode(StringRef CC) {
2925 return StringSwitch<X86::CondCode>(CC)
2947bool X86AsmParser::ParseZ(std::unique_ptr<X86Operand> &Z, SMLoc StartLoc) {
2948 MCAsmParser &Parser = getParser();
2953 (getLexer().getTok().getIdentifier() ==
"z")))
2958 return Error(getLexer().getLoc(),
"Expected } at this point");
2966bool X86AsmParser::HandleAVX512Operand(
OperandVector &Operands) {
2967 MCAsmParser &Parser = getParser();
2970 const SMLoc consumedToken = consumeToken();
2974 if (getLexer().getTok().getIntVal() != 1)
2975 return TokError(
"Expected 1to<NUM> at this point");
2976 StringRef
Prefix = getLexer().getTok().getString();
2979 return TokError(
"Expected 1to<NUM> at this point");
2982 StringRef BroadcastString = (
Prefix + getLexer().getTok().getIdentifier())
2985 return TokError(
"Expected 1to<NUM> at this point");
2986 const char *BroadcastPrimitive =
2987 StringSwitch<const char *>(BroadcastString)
2988 .Case(
"1to2",
"{1to2}")
2989 .Case(
"1to4",
"{1to4}")
2990 .Case(
"1to8",
"{1to8}")
2991 .Case(
"1to16",
"{1to16}")
2992 .Case(
"1to32",
"{1to32}")
2994 if (!BroadcastPrimitive)
2995 return TokError(
"Invalid memory broadcast primitive.");
2998 return TokError(
"Expected } at this point");
3009 std::unique_ptr<X86Operand>
Z;
3010 if (ParseZ(Z, consumedToken))
3016 SMLoc StartLoc =
Z ? consumeToken() : consumedToken;
3021 if (!parseRegister(RegNo, RegLoc, StartLoc) &&
3022 getX86MCRegisterClass(X86::VK1RegClassID).
contains(RegNo)) {
3023 if (RegNo == X86::K0)
3024 return Error(RegLoc,
"Register k0 can't be used as write mask");
3026 return Error(getLexer().getLoc(),
"Expected } at this point");
3032 return Error(getLexer().getLoc(),
3033 "Expected an op-mask register at this point");
3038 if (ParseZ(Z, consumeToken()) || !Z)
3039 return Error(getLexer().getLoc(),
3040 "Expected a {z} mark at this point");
3055bool X86AsmParser::CheckDispOverflow(MCRegister BaseReg, MCRegister IndexReg,
3056 const MCExpr *Disp, SMLoc Loc) {
3062 if (BaseReg || IndexReg) {
3064 auto Imm =
CE->getValue();
3066 getX86MCRegisterClass(X86::GR64RegClassID).contains(BaseReg) ||
3067 getX86MCRegisterClass(X86::GR64RegClassID).contains(IndexReg);
3068 bool Is16 = getX86MCRegisterClass(X86::GR16RegClassID).contains(BaseReg);
3071 return Error(Loc,
"displacement " + Twine(Imm) +
3072 " is not within [-2147483648, 2147483647]");
3074 if (!
isUInt<32>(Imm < 0 ? -uint64_t(Imm) : uint64_t(Imm))) {
3075 Warning(Loc,
"displacement " + Twine(Imm) +
3076 " shortened to 32-bit signed " +
3077 Twine(
static_cast<int32_t
>(Imm)));
3079 }
else if (!
isUInt<16>(Imm < 0 ? -uint64_t(Imm) : uint64_t(Imm))) {
3080 Warning(Loc,
"displacement " + Twine(Imm) +
3081 " shortened to 16-bit signed " +
3082 Twine(
static_cast<int16_t
>(Imm)));
3091bool X86AsmParser::ParseMemOperand(MCRegister SegReg,
const MCExpr *Disp,
3092 SMLoc StartLoc, SMLoc EndLoc,
3094 MCAsmParser &Parser = getParser();
3112 auto isAtMemOperand = [
this]() {
3117 auto TokCount = this->getLexer().peekTokens(Buf,
true);
3120 switch (Buf[0].getKind()) {
3127 if ((TokCount > 1) &&
3131 Buf[1].getIdentifier().
size() + 1);
3153 if (!isAtMemOperand()) {
3172 0, 0, 1, StartLoc, EndLoc));
3180 SMLoc BaseLoc = getLexer().getLoc();
3192 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ)
3193 return Error(BaseLoc,
"eiz and riz can only be used as index registers",
3194 SMRange(BaseLoc, EndLoc));
3212 if (!
E->evaluateAsAbsolute(ScaleVal, getStreamer().getAssemblerPtr()))
3213 return Error(Loc,
"expected absolute expression");
3215 Warning(Loc,
"scale factor without index register is ignored");
3220 if (BaseReg == X86::RIP)
3222 "%rip as base register can not have an index register");
3223 if (IndexReg == X86::RIP)
3224 return Error(Loc,
"%rip is not allowed as an index register");
3235 return Error(Loc,
"expected scale expression");
3236 Scale = (unsigned)ScaleVal;
3238 if (getX86MCRegisterClass(X86::GR16RegClassID).
contains(BaseReg) &&
3240 return Error(Loc,
"scale factor in 16-bit address must be 1");
3242 return Error(Loc, ErrMsg);
3256 if (BaseReg == X86::DX && !IndexReg && Scale == 1 && !SegReg &&
3265 return Error(BaseLoc, ErrMsg);
3267 if (CheckDispOverflow(BaseReg, IndexReg, Disp, BaseLoc))
3270 if (SegReg || BaseReg || IndexReg)
3272 BaseReg, IndexReg, Scale, StartLoc,
3281bool X86AsmParser::parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
3282 MCAsmParser &Parser = getParser();
3289 if (parseRegister(RegNo, StartLoc, EndLoc))
3297bool X86AsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
3299 MCAsmParser &Parser = getParser();
3303 ForcedOpcodePrefix = OpcodePrefix_Default;
3304 ForcedDispEncoding = DispEncoding_Default;
3305 UseApxExtendedReg =
false;
3306 ForcedNoFlag =
false;
3319 if (Prefix ==
"rex")
3320 ForcedOpcodePrefix = OpcodePrefix_REX;
3321 else if (Prefix ==
"rex2")
3322 ForcedOpcodePrefix = OpcodePrefix_REX2;
3323 else if (Prefix ==
"vex")
3324 ForcedOpcodePrefix = OpcodePrefix_VEX;
3325 else if (Prefix ==
"vex2")
3326 ForcedOpcodePrefix = OpcodePrefix_VEX2;
3327 else if (Prefix ==
"vex3")
3328 ForcedOpcodePrefix = OpcodePrefix_VEX3;
3329 else if (Prefix ==
"evex")
3330 ForcedOpcodePrefix = OpcodePrefix_EVEX;
3331 else if (Prefix ==
"disp8")
3332 ForcedDispEncoding = DispEncoding_Disp8;
3333 else if (Prefix ==
"disp32")
3334 ForcedDispEncoding = DispEncoding_Disp32;
3335 else if (Prefix ==
"nf")
3336 ForcedNoFlag =
true;
3338 return Error(NameLoc,
"unknown prefix");
3354 if (isParsingMSInlineAsm()) {
3355 if (
Name.equals_insensitive(
"vex"))
3356 ForcedOpcodePrefix = OpcodePrefix_VEX;
3357 else if (
Name.equals_insensitive(
"vex2"))
3358 ForcedOpcodePrefix = OpcodePrefix_VEX2;
3359 else if (
Name.equals_insensitive(
"vex3"))
3360 ForcedOpcodePrefix = OpcodePrefix_VEX3;
3361 else if (
Name.equals_insensitive(
"evex"))
3362 ForcedOpcodePrefix = OpcodePrefix_EVEX;
3364 if (ForcedOpcodePrefix != OpcodePrefix_Default) {
3377 if (
Name.consume_back(
".d32")) {
3378 ForcedDispEncoding = DispEncoding_Disp32;
3379 }
else if (
Name.consume_back(
".d8")) {
3380 ForcedDispEncoding = DispEncoding_Disp8;
3383 StringRef PatchedName =
Name;
3386 if (isParsingIntelSyntax() &&
3387 (PatchedName ==
"jmp" || PatchedName ==
"jc" || PatchedName ==
"jnc" ||
3388 PatchedName ==
"jcxz" || PatchedName ==
"jecxz" ||
3393 : NextTok ==
"short") {
3402 NextTok.
size() + 1);
3408 PatchedName !=
"setzub" && PatchedName !=
"setzunb" &&
3409 PatchedName !=
"setb" && PatchedName !=
"setnb")
3410 PatchedName = PatchedName.
substr(0,
Name.size()-1);
3412 unsigned ComparisonPredicate = ~0
U;
3420 bool IsVCMP = PatchedName[0] ==
'v';
3421 unsigned CCIdx =
IsVCMP ? 4 : 3;
3422 unsigned suffixLength = PatchedName.
ends_with(
"bf16") ? 5 : 2;
3423 unsigned CC = StringSwitch<unsigned>(
3424 PatchedName.
slice(CCIdx, PatchedName.
size() - suffixLength))
3426 .Case(
"eq_oq", 0x00)
3428 .Case(
"lt_os", 0x01)
3430 .Case(
"le_os", 0x02)
3431 .Case(
"unord", 0x03)
3432 .Case(
"unord_q", 0x03)
3434 .Case(
"neq_uq", 0x04)
3436 .Case(
"nlt_us", 0x05)
3438 .Case(
"nle_us", 0x06)
3440 .Case(
"ord_q", 0x07)
3442 .Case(
"eq_uq", 0x08)
3444 .Case(
"nge_us", 0x09)
3446 .Case(
"ngt_us", 0x0A)
3447 .Case(
"false", 0x0B)
3448 .Case(
"false_oq", 0x0B)
3449 .Case(
"neq_oq", 0x0C)
3451 .Case(
"ge_os", 0x0D)
3453 .Case(
"gt_os", 0x0E)
3455 .Case(
"true_uq", 0x0F)
3456 .Case(
"eq_os", 0x10)
3457 .Case(
"lt_oq", 0x11)
3458 .Case(
"le_oq", 0x12)
3459 .Case(
"unord_s", 0x13)
3460 .Case(
"neq_us", 0x14)
3461 .Case(
"nlt_uq", 0x15)
3462 .Case(
"nle_uq", 0x16)
3463 .Case(
"ord_s", 0x17)
3464 .Case(
"eq_us", 0x18)
3465 .Case(
"nge_uq", 0x19)
3466 .Case(
"ngt_uq", 0x1A)
3467 .Case(
"false_os", 0x1B)
3468 .Case(
"neq_os", 0x1C)
3469 .Case(
"ge_oq", 0x1D)
3470 .Case(
"gt_oq", 0x1E)
3471 .Case(
"true_us", 0x1F)
3473 if (CC != ~0U && (
IsVCMP || CC < 8) &&
3476 PatchedName =
IsVCMP ?
"vcmpss" :
"cmpss";
3478 PatchedName =
IsVCMP ?
"vcmpsd" :
"cmpsd";
3480 PatchedName =
IsVCMP ?
"vcmpps" :
"cmpps";
3482 PatchedName =
IsVCMP ?
"vcmppd" :
"cmppd";
3484 PatchedName =
"vcmpsh";
3486 PatchedName =
"vcmpph";
3488 PatchedName =
"vcmpbf16";
3492 ComparisonPredicate = CC;
3498 (PatchedName.
back() ==
'b' || PatchedName.
back() ==
'w' ||
3499 PatchedName.
back() ==
'd' || PatchedName.
back() ==
'q')) {
3500 unsigned SuffixSize = PatchedName.
drop_back().
back() ==
'u' ? 2 : 1;
3501 unsigned CC = StringSwitch<unsigned>(
3502 PatchedName.
slice(5, PatchedName.
size() - SuffixSize))
3512 if (CC != ~0U && (CC != 0 || SuffixSize == 2)) {
3513 switch (PatchedName.
back()) {
3515 case 'b': PatchedName = SuffixSize == 2 ?
"vpcmpub" :
"vpcmpb";
break;
3516 case 'w': PatchedName = SuffixSize == 2 ?
"vpcmpuw" :
"vpcmpw";
break;
3517 case 'd': PatchedName = SuffixSize == 2 ?
"vpcmpud" :
"vpcmpd";
break;
3518 case 'q': PatchedName = SuffixSize == 2 ?
"vpcmpuq" :
"vpcmpq";
break;
3521 ComparisonPredicate = CC;
3527 (PatchedName.
back() ==
'b' || PatchedName.
back() ==
'w' ||
3528 PatchedName.
back() ==
'd' || PatchedName.
back() ==
'q')) {
3529 unsigned SuffixSize = PatchedName.
drop_back().
back() ==
'u' ? 2 : 1;
3530 unsigned CC = StringSwitch<unsigned>(
3531 PatchedName.
slice(5, PatchedName.
size() - SuffixSize))
3542 switch (PatchedName.
back()) {
3544 case 'b': PatchedName = SuffixSize == 2 ?
"vpcomub" :
"vpcomb";
break;
3545 case 'w': PatchedName = SuffixSize == 2 ?
"vpcomuw" :
"vpcomw";
break;
3546 case 'd': PatchedName = SuffixSize == 2 ?
"vpcomud" :
"vpcomd";
break;
3547 case 'q': PatchedName = SuffixSize == 2 ?
"vpcomuq" :
"vpcomq";
break;
3550 ComparisonPredicate = CC;
3562 StringSwitch<bool>(Name)
3563 .Cases({
"cs",
"ds",
"es",
"fs",
"gs",
"ss"},
true)
3564 .Cases({
"rex64",
"data32",
"data16",
"addr32",
"addr16"},
true)
3565 .Cases({
"xacquire",
"xrelease"},
true)
3566 .Cases({
"acquire",
"release"}, isParsingIntelSyntax())
3569 auto isLockRepeatNtPrefix = [](StringRef
N) {
3570 return StringSwitch<bool>(
N)
3571 .Cases({
"lock",
"rep",
"repe",
"repz",
"repne",
"repnz",
"notrack"},
3576 bool CurlyAsEndOfStatement =
false;
3579 while (isLockRepeatNtPrefix(
Name.lower())) {
3581 StringSwitch<unsigned>(Name)
3600 while (
Name.starts_with(
";") ||
Name.starts_with(
"\n") ||
3601 Name.starts_with(
"#") ||
Name.starts_with(
"\t") ||
3602 Name.starts_with(
"/")) {
3613 if (PatchedName ==
"data16" && is16BitMode()) {
3614 return Error(NameLoc,
"redundant data16 prefix");
3616 if (PatchedName ==
"data32") {
3618 return Error(NameLoc,
"redundant data32 prefix");
3620 return Error(NameLoc,
"'data32' is not supported in 64-bit mode");
3622 PatchedName =
"data16";
3629 if (
Next ==
"callw")
3631 if (
Next ==
"ljmpw")
3636 ForcedDataPrefix = X86::Is32Bit;
3644 if (ComparisonPredicate != ~0U && !isParsingIntelSyntax()) {
3651 if ((
Name.starts_with(
"ccmp") ||
Name.starts_with(
"ctest")) &&
3652 parseCFlagsOp(Operands))
3666 if (parseOperand(Operands, Name))
3668 if (HandleAVX512Operand(Operands))
3680 CurlyAsEndOfStatement =
3681 isParsingIntelSyntax() && isParsingMSInlineAsm() &&
3684 return TokError(
"unexpected token in argument list");
3688 if (ComparisonPredicate != ~0U && isParsingIntelSyntax()) {
3698 else if (CurlyAsEndOfStatement)
3701 getLexer().getTok().getLoc(), 0);
3708 if (IsFp && Operands.
size() == 1) {
3709 const char *Repl = StringSwitch<const char *>(Name)
3710 .Case(
"fsub",
"fsubp")
3711 .Case(
"fdiv",
"fdivp")
3712 .Case(
"fsubr",
"fsubrp")
3713 .Case(
"fdivr",
"fdivrp");
3714 static_cast<X86Operand &
>(*Operands[0]).setTokenValue(Repl);
3717 if ((Name ==
"mov" || Name ==
"movw" || Name ==
"movl") &&
3718 (Operands.
size() == 3)) {
3719 X86Operand &Op1 = (X86Operand &)*Operands[1];
3720 X86Operand &Op2 = (X86Operand &)*Operands[2];
3725 getX86MCRegisterClass(X86::SEGMENT_REGRegClassID)
3727 (getX86MCRegisterClass(X86::GR16RegClassID).
contains(Op1.
getReg()) ||
3728 getX86MCRegisterClass(X86::GR32RegClassID).
contains(Op1.
getReg()))) {
3730 if (Name !=
"mov" && Name[3] == (is16BitMode() ?
'l' :
'w')) {
3731 Name = is16BitMode() ?
"movw" :
"movl";
3744 if ((Name ==
"outb" || Name ==
"outsb" || Name ==
"outw" || Name ==
"outsw" ||
3745 Name ==
"outl" || Name ==
"outsl" || Name ==
"out" || Name ==
"outs") &&
3746 Operands.
size() == 3) {
3747 X86Operand &
Op = (X86Operand &)*Operands.
back();
3753 if ((Name ==
"inb" || Name ==
"insb" || Name ==
"inw" || Name ==
"insw" ||
3754 Name ==
"inl" || Name ==
"insl" || Name ==
"in" || Name ==
"ins") &&
3755 Operands.
size() == 3) {
3756 X86Operand &
Op = (X86Operand &)*Operands[1];
3763 bool HadVerifyError =
false;
3766 if (
Name.starts_with(
"ins") &&
3767 (Operands.
size() == 1 || Operands.
size() == 3) &&
3768 (Name ==
"insb" || Name ==
"insw" || Name ==
"insl" || Name ==
"insd" ||
3771 AddDefaultSrcDestOperands(TmpOperands,
3773 DefaultMemDIOperand(NameLoc));
3774 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3778 if (
Name.starts_with(
"outs") &&
3779 (Operands.
size() == 1 || Operands.
size() == 3) &&
3780 (Name ==
"outsb" || Name ==
"outsw" || Name ==
"outsl" ||
3781 Name ==
"outsd" || Name ==
"outs")) {
3782 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
3784 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3790 if (
Name.starts_with(
"lods") &&
3791 (Operands.
size() == 1 || Operands.
size() == 2) &&
3792 (Name ==
"lods" || Name ==
"lodsb" || Name ==
"lodsw" ||
3793 Name ==
"lodsl" || Name ==
"lodsd" || Name ==
"lodsq")) {
3794 TmpOperands.
push_back(DefaultMemSIOperand(NameLoc));
3795 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3801 if (
Name.starts_with(
"stos") &&
3802 (Operands.
size() == 1 || Operands.
size() == 2) &&
3803 (Name ==
"stos" || Name ==
"stosb" || Name ==
"stosw" ||
3804 Name ==
"stosl" || Name ==
"stosd" || Name ==
"stosq")) {
3805 TmpOperands.
push_back(DefaultMemDIOperand(NameLoc));
3806 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3812 if (
Name.starts_with(
"scas") &&
3813 (Operands.
size() == 1 || Operands.
size() == 2) &&
3814 (Name ==
"scas" || Name ==
"scasb" || Name ==
"scasw" ||
3815 Name ==
"scasl" || Name ==
"scasd" || Name ==
"scasq")) {
3816 TmpOperands.
push_back(DefaultMemDIOperand(NameLoc));
3817 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3821 if (
Name.starts_with(
"cmps") &&
3822 (Operands.
size() == 1 || Operands.
size() == 3) &&
3823 (Name ==
"cmps" || Name ==
"cmpsb" || Name ==
"cmpsw" ||
3824 Name ==
"cmpsl" || Name ==
"cmpsd" || Name ==
"cmpsq")) {
3825 AddDefaultSrcDestOperands(TmpOperands, DefaultMemDIOperand(NameLoc),
3826 DefaultMemSIOperand(NameLoc));
3827 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3831 if (((
Name.starts_with(
"movs") &&
3832 (Name ==
"movs" || Name ==
"movsb" || Name ==
"movsw" ||
3833 Name ==
"movsl" || Name ==
"movsd" || Name ==
"movsq")) ||
3834 (
Name.starts_with(
"smov") &&
3835 (Name ==
"smov" || Name ==
"smovb" || Name ==
"smovw" ||
3836 Name ==
"smovl" || Name ==
"smovd" || Name ==
"smovq"))) &&
3837 (Operands.
size() == 1 || Operands.
size() == 3)) {
3838 if (Name ==
"movsd" && Operands.
size() == 1 && !isParsingIntelSyntax())
3840 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
3841 DefaultMemDIOperand(NameLoc));
3842 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3846 if (HadVerifyError) {
3847 return HadVerifyError;
3851 if ((Name ==
"xlat" || Name ==
"xlatb") && Operands.
size() == 2) {
3852 X86Operand &Op1 =
static_cast<X86Operand &
>(*Operands[1]);
3855 "size, (R|E)BX will be used for the location");
3857 static_cast<X86Operand &
>(*Operands[0]).setTokenValue(
"xlatb");
3870 if (
I == Table.
end() ||
I->OldOpc != Opcode)
3876 if (X86::isBLENDVPD(Opcode) || X86::isBLENDVPS(Opcode) ||
3877 X86::isPBLENDVB(Opcode))
3883bool X86AsmParser::processInstruction(MCInst &Inst,
const OperandVector &
Ops) {
3887 if (ForcedOpcodePrefix != OpcodePrefix_VEX3 &&
3894 auto replaceWithCCMPCTEST = [&](
unsigned Opcode) ->
bool {
3895 if (ForcedOpcodePrefix == OpcodePrefix_EVEX) {
3906 default:
return false;
3911 if (ForcedDispEncoding == DispEncoding_Disp32) {
3912 Inst.
setOpcode(is16BitMode() ? X86::JMP_2 : X86::JMP_4);
3921 if (ForcedDispEncoding == DispEncoding_Disp32) {
3922 Inst.
setOpcode(is16BitMode() ? X86::JCC_2 : X86::JCC_4);
3938#define FROM_TO(FROM, TO) \
3940 return replaceWithCCMPCTEST(X86::TO);
3942 FROM_TO(CMP64mi32, CCMP64mi32)
3945 FROM_TO(CMP64ri32, CCMP64ri32)
3972 FROM_TO(TEST64mi32, CTEST64mi32)
3974 FROM_TO(TEST64ri32, CTEST64ri32)
3994bool X86AsmParser::validateInstruction(MCInst &Inst,
const OperandVector &
Ops) {
3995 using namespace X86;
3996 const MCRegisterInfo *MRI =
getContext().getRegisterInfo();
3998 uint64_t TSFlags = MII.get(Opcode).TSFlags;
3999 if (isVFCMADDCPH(Opcode) || isVFCMADDCSH(Opcode) || isVFMADDCPH(Opcode) ||
4000 isVFMADDCSH(Opcode)) {
4004 return Warning(
Ops[0]->getStartLoc(),
"Destination register should be "
4005 "distinct from source registers");
4006 }
else if (isVFCMULCPH(Opcode) || isVFCMULCSH(Opcode) || isVFMULCPH(Opcode) ||
4007 isVFMULCSH(Opcode)) {
4017 return Warning(
Ops[0]->getStartLoc(),
"Destination register should be "
4018 "distinct from source registers");
4019 }
else if (isV4FMADDPS(Opcode) || isV4FMADDSS(Opcode) ||
4020 isV4FNMADDPS(Opcode) || isV4FNMADDSS(Opcode) ||
4021 isVP4DPWSSDS(Opcode) || isVP4DPWSSD(Opcode)) {
4026 if (Src2Enc % 4 != 0) {
4028 unsigned GroupStart = (Src2Enc / 4) * 4;
4029 unsigned GroupEnd = GroupStart + 3;
4031 "source register '" +
RegName +
"' implicitly denotes '" +
4032 RegName.take_front(3) + Twine(GroupStart) +
"' to '" +
4033 RegName.take_front(3) + Twine(GroupEnd) +
4036 }
else if (isVGATHERDPD(Opcode) || isVGATHERDPS(Opcode) ||
4037 isVGATHERQPD(Opcode) || isVGATHERQPS(Opcode) ||
4038 isVPGATHERDD(Opcode) || isVPGATHERDQ(Opcode) ||
4039 isVPGATHERQD(Opcode) || isVPGATHERQQ(Opcode)) {
4046 return Warning(
Ops[0]->getStartLoc(),
"index and destination registers "
4047 "should be distinct");
4053 if (Dest == Mask || Dest == Index || Mask == Index)
4054 return Warning(
Ops[0]->getStartLoc(),
"mask, index, and destination "
4055 "registers should be distinct");
4057 }
else if (isTCMMIMFP16PS(Opcode) || isTCMMRLFP16PS(Opcode) ||
4058 isTDPBF16PS(Opcode) || isTDPFP16PS(Opcode) || isTDPBSSD(Opcode) ||
4059 isTDPBSUD(Opcode) || isTDPBUSD(Opcode) || isTDPBUUD(Opcode)) {
4063 if (SrcDest == Src1 || SrcDest == Src2 || Src1 == Src2)
4064 return Error(
Ops[0]->getStartLoc(),
"all tmm registers must be distinct");
4078 for (
unsigned i = 0; i !=
NumOps; ++i) {
4083 if (
Reg == X86::AH ||
Reg == X86::BH ||
Reg == X86::CH ||
Reg == X86::DH)
4091 (Enc ==
X86II::EVEX || ForcedOpcodePrefix == OpcodePrefix_REX2 ||
4092 ForcedOpcodePrefix == OpcodePrefix_REX || UsesRex)) {
4094 return Error(
Ops[0]->getStartLoc(),
4095 "can't encode '" +
RegName.str() +
4096 "' in an instruction requiring EVEX/REX2/REX prefix");
4100 if ((Opcode == X86::PREFETCHIT0 || Opcode == X86::PREFETCHIT1)) {
4104 Ops[0]->getStartLoc(),
4105 Twine((Inst.
getOpcode() == X86::PREFETCHIT0 ?
"'prefetchit0'"
4106 :
"'prefetchit1'")) +
4107 " only supports RIP-relative address");
4112void X86AsmParser::emitWarningForSpecialLVIInstruction(SMLoc Loc) {
4113 Warning(Loc,
"Instruction may be vulnerable to LVI and "
4114 "requires manual mitigation");
4115 Note(SMLoc(),
"See https://software.intel.com/"
4116 "security-software-guidance/insights/"
4117 "deep-dive-load-value-injection#specialinstructions"
4118 " for more information");
4130void X86AsmParser::applyLVICFIMitigation(MCInst &Inst, MCStreamer &Out) {
4141 MCInst ShlInst, FenceInst;
4142 bool Parse32 = is32BitMode() || Code16GCC;
4143 MCRegister Basereg =
4144 is64BitMode() ? X86::RSP : (Parse32 ? X86::ESP : X86::SP);
4148 1, SMLoc{}, SMLoc{}, 0);
4150 ShlMemOp->addMemOperands(ShlInst, 5);
4163 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4175void X86AsmParser::applyLVILoadHardeningMitigation(MCInst &Inst,
4192 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4195 }
else if (Opcode == X86::REP_PREFIX || Opcode == X86::REPNE_PREFIX) {
4198 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4202 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
4217void X86AsmParser::emitInstruction(MCInst &Inst,
OperandVector &Operands,
4220 getSTI().
hasFeature(X86::FeatureLVIControlFlowIntegrity))
4221 applyLVICFIMitigation(Inst, Out);
4226 getSTI().
hasFeature(X86::FeatureLVILoadHardening))
4227 applyLVILoadHardeningMitigation(Inst, Out);
4231 unsigned Result = 0;
4233 if (Prefix.isPrefix()) {
4234 Result = Prefix.getPrefix();
4240bool X86AsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
4242 MCStreamer &Out, uint64_t &ErrorInfo,
4243 bool MatchingInlineAsm) {
4244 assert(!Operands.
empty() &&
"Unexpect empty operand list!");
4245 assert((*Operands[0]).isToken() &&
"Leading operand should always be a mnemonic!");
4248 MatchFPUWaitAlias(IDLoc,
static_cast<X86Operand &
>(*Operands[0]), Operands,
4249 Out, MatchingInlineAsm);
4256 if (ForcedOpcodePrefix == OpcodePrefix_REX)
4258 else if (ForcedOpcodePrefix == OpcodePrefix_REX2)
4260 else if (ForcedOpcodePrefix == OpcodePrefix_VEX)
4262 else if (ForcedOpcodePrefix == OpcodePrefix_VEX2)
4264 else if (ForcedOpcodePrefix == OpcodePrefix_VEX3)
4266 else if (ForcedOpcodePrefix == OpcodePrefix_EVEX)
4270 if (ForcedDispEncoding == DispEncoding_Disp8)
4272 else if (ForcedDispEncoding == DispEncoding_Disp32)
4278 return isParsingIntelSyntax()
4279 ? matchAndEmitIntelInstruction(IDLoc, Opcode, Inst, Operands, Out,
4280 ErrorInfo, MatchingInlineAsm)
4281 : matchAndEmitATTInstruction(IDLoc, Opcode, Inst, Operands, Out,
4282 ErrorInfo, MatchingInlineAsm);
4285void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &
Op,
4287 bool MatchingInlineAsm) {
4291 const char *Repl = StringSwitch<const char *>(
Op.getToken())
4292 .Case(
"finit",
"fninit")
4293 .Case(
"fsave",
"fnsave")
4294 .Case(
"fstcw",
"fnstcw")
4295 .Case(
"fstcww",
"fnstcw")
4296 .Case(
"fstenv",
"fnstenv")
4297 .Case(
"fstsw",
"fnstsw")
4298 .Case(
"fstsww",
"fnstsw")
4299 .Case(
"fclex",
"fnclex")
4305 if (!MatchingInlineAsm)
4311bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc,
4312 const FeatureBitset &MissingFeatures,
4313 bool MatchingInlineAsm) {
4314 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
4315 SmallString<126> Msg;
4316 raw_svector_ostream OS(Msg);
4317 OS <<
"instruction requires:";
4318 for (
unsigned Feature : MissingFeatures)
4320 return Error(IDLoc, OS.str(), SMRange(), MatchingInlineAsm);
4323unsigned X86AsmParser::checkTargetMatchPredicate(MCInst &Inst) {
4325 const MCInstrDesc &MCID = MII.get(
Opc);
4326 uint64_t TSFlags = MCID.
TSFlags;
4329 return Match_Unsupported;
4331 return Match_Unsupported;
4333 switch (ForcedOpcodePrefix) {
4334 case OpcodePrefix_Default:
4336 case OpcodePrefix_REX:
4337 case OpcodePrefix_REX2:
4339 return Match_Unsupported;
4341 case OpcodePrefix_VEX:
4342 case OpcodePrefix_VEX2:
4343 case OpcodePrefix_VEX3:
4345 return Match_Unsupported;
4347 case OpcodePrefix_EVEX:
4349 !X86::isCMP(
Opc) && !X86::isTEST(
Opc))
4350 return Match_Unsupported;
4352 return Match_Unsupported;
4357 (ForcedOpcodePrefix != OpcodePrefix_VEX &&
4358 ForcedOpcodePrefix != OpcodePrefix_VEX2 &&
4359 ForcedOpcodePrefix != OpcodePrefix_VEX3))
4360 return Match_Unsupported;
4362 return Match_Success;
4365bool X86AsmParser::matchAndEmitATTInstruction(
4366 SMLoc IDLoc,
unsigned &Opcode, MCInst &Inst,
OperandVector &Operands,
4367 MCStreamer &Out, uint64_t &ErrorInfo,
bool MatchingInlineAsm) {
4368 X86Operand &
Op =
static_cast<X86Operand &
>(*Operands[0]);
4372 if (ForcedDataPrefix == X86::Is32Bit)
4373 SwitchMode(X86::Is32Bit);
4375 FeatureBitset MissingFeatures;
4376 unsigned OriginalError = MatchInstruction(Operands, Inst, ErrorInfo,
4377 MissingFeatures, MatchingInlineAsm,
4378 isParsingIntelSyntax());
4379 if (ForcedDataPrefix == X86::Is32Bit) {
4380 SwitchMode(X86::Is16Bit);
4381 ForcedDataPrefix = 0;
4383 switch (OriginalError) {
4386 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
4391 if (!MatchingInlineAsm)
4392 while (processInstruction(Inst, Operands))
4396 if (!MatchingInlineAsm)
4400 case Match_InvalidImmUnsignedi4: {
4401 SMLoc ErrorLoc = ((X86Operand &)*Operands[ErrorInfo]).getStartLoc();
4402 if (ErrorLoc == SMLoc())
4404 return Error(ErrorLoc,
"immediate must be an integer in range [0, 15]",
4405 EmptyRange, MatchingInlineAsm);
4407 case Match_InvalidImmUnsignedi6: {
4408 SMLoc ErrorLoc = ((X86Operand &)*Operands[ErrorInfo]).getStartLoc();
4409 if (ErrorLoc == SMLoc())
4411 return Error(ErrorLoc,
"immediate must be an integer in range [0, 63]",
4412 EmptyRange, MatchingInlineAsm);
4414 case Match_MissingFeature:
4415 return ErrorMissingFeature(IDLoc, MissingFeatures, MatchingInlineAsm);
4416 case Match_InvalidOperand:
4417 case Match_MnemonicFail:
4418 case Match_Unsupported:
4421 if (
Op.getToken().empty()) {
4422 Error(IDLoc,
"instruction must have size higher than 0", EmptyRange,
4433 StringRef
Base =
Op.getToken();
4434 SmallString<16> Tmp;
4437 Op.setTokenValue(Tmp);
4445 const char *Suffixes =
Base[0] !=
'f' ?
"bwlq" :
"slt\0";
4447 const char *MemSize =
Base[0] !=
'f' ?
"\x08\x10\x20\x40" :
"\x20\x40\x50\0";
4450 uint64_t ErrorInfoIgnore;
4451 FeatureBitset ErrorInfoMissingFeatures;
4459 bool HasVectorReg =
false;
4460 X86Operand *MemOp =
nullptr;
4461 for (
const auto &
Op : Operands) {
4462 X86Operand *X86Op =
static_cast<X86Operand *
>(
Op.get());
4464 HasVectorReg =
true;
4465 else if (X86Op->
isMem()) {
4467 assert(MemOp->Mem.Size == 0 &&
"Memory size always 0 under ATT syntax");
4474 for (
unsigned I = 0,
E = std::size(Match);
I !=
E; ++
I) {
4475 Tmp.
back() = Suffixes[
I];
4476 if (MemOp && HasVectorReg)
4477 MemOp->Mem.Size = MemSize[
I];
4478 Match[
I] = Match_MnemonicFail;
4479 if (MemOp || !HasVectorReg) {
4481 MatchInstruction(Operands, Inst, ErrorInfoIgnore, MissingFeatures,
4482 MatchingInlineAsm, isParsingIntelSyntax());
4484 if (Match[
I] == Match_MissingFeature)
4485 ErrorInfoMissingFeatures = MissingFeatures;
4495 unsigned NumSuccessfulMatches =
llvm::count(Match, Match_Success);
4496 if (NumSuccessfulMatches == 1) {
4497 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
4502 if (!MatchingInlineAsm)
4503 while (processInstruction(Inst, Operands))
4507 if (!MatchingInlineAsm)
4517 if (NumSuccessfulMatches > 1) {
4519 unsigned NumMatches = 0;
4520 for (
unsigned I = 0,
E = std::size(Match);
I !=
E; ++
I)
4521 if (Match[
I] == Match_Success)
4522 MatchChars[NumMatches++] = Suffixes[
I];
4524 SmallString<126> Msg;
4525 raw_svector_ostream OS(Msg);
4526 OS <<
"ambiguous instructions require an explicit suffix (could be ";
4527 for (
unsigned i = 0; i != NumMatches; ++i) {
4530 if (i + 1 == NumMatches)
4532 OS <<
"'" <<
Base << MatchChars[i] <<
"'";
4535 Error(IDLoc, OS.str(), EmptyRange, MatchingInlineAsm);
4543 if (
llvm::count(Match, Match_MnemonicFail) == 4) {
4544 if (OriginalError == Match_MnemonicFail)
4545 return Error(IDLoc,
"invalid instruction mnemonic '" +
Base +
"'",
4546 Op.getLocRange(), MatchingInlineAsm);
4548 if (OriginalError == Match_Unsupported)
4549 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4552 assert(OriginalError == Match_InvalidOperand &&
"Unexpected error");
4554 if (ErrorInfo != ~0ULL) {
4555 if (ErrorInfo >= Operands.size())
4556 return Error(IDLoc,
"too few operands for instruction", EmptyRange,
4559 X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo];
4563 OperandRange, MatchingInlineAsm);
4567 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4573 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4579 if (
llvm::count(Match, Match_MissingFeature) == 1) {
4580 ErrorInfo = Match_MissingFeature;
4581 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
4587 if (
llvm::count(Match, Match_InvalidOperand) == 1) {
4588 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4593 Error(IDLoc,
"unknown use of instruction mnemonic without a size suffix",
4594 EmptyRange, MatchingInlineAsm);
4598bool X86AsmParser::matchAndEmitIntelInstruction(
4599 SMLoc IDLoc,
unsigned &Opcode, MCInst &Inst,
OperandVector &Operands,
4600 MCStreamer &Out, uint64_t &ErrorInfo,
bool MatchingInlineAsm) {
4601 X86Operand &
Op =
static_cast<X86Operand &
>(*Operands[0]);
4604 X86Operand *UnsizedMemOp =
nullptr;
4605 for (
const auto &
Op : Operands) {
4606 X86Operand *X86Op =
static_cast<X86Operand *
>(
Op.get());
4608 UnsizedMemOp = X86Op;
4617 StringRef Mnemonic = (
static_cast<X86Operand &
>(*Operands[0])).
getToken();
4619 static const char *
const PtrSizedInstrs[] = {
"call",
"jmp",
"push",
"pop"};
4620 for (
const char *Instr : PtrSizedInstrs) {
4621 if (Mnemonic == Instr) {
4622 UnsizedMemOp->
Mem.
Size = getPointerWidth();
4628 SmallVector<unsigned, 8> Match;
4629 FeatureBitset ErrorInfoMissingFeatures;
4630 FeatureBitset MissingFeatures;
4631 StringRef
Base = (
static_cast<X86Operand &
>(*Operands[0])).
getToken();
4635 if (Mnemonic ==
"push" && Operands.size() == 2) {
4636 auto *X86Op =
static_cast<X86Operand *
>(Operands[1].get());
4637 if (X86Op->
isImm()) {
4640 unsigned Size = getPointerWidth();
4643 SmallString<16> Tmp;
4645 Tmp += (is64BitMode())
4647 : (is32BitMode()) ?
"l" : (is16BitMode()) ?
"w" :
" ";
4648 Op.setTokenValue(Tmp);
4650 Match.
push_back(MatchInstruction(Operands, Inst, ErrorInfo,
4651 MissingFeatures, MatchingInlineAsm,
4662 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
4663 for (
unsigned Size : MopSizes) {
4665 uint64_t ErrorInfoIgnore;
4667 unsigned M = MatchInstruction(Operands, Inst, ErrorInfoIgnore,
4668 MissingFeatures, MatchingInlineAsm,
4669 isParsingIntelSyntax());
4674 if (Match.
back() == Match_MissingFeature)
4675 ErrorInfoMissingFeatures = MissingFeatures;
4685 if (Match.
empty()) {
4687 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,
4688 isParsingIntelSyntax()));
4690 if (Match.
back() == Match_MissingFeature)
4691 ErrorInfoMissingFeatures = MissingFeatures;
4699 if (Match.
back() == Match_MnemonicFail) {
4700 return Error(IDLoc,
"invalid instruction mnemonic '" + Mnemonic +
"'",
4701 Op.getLocRange(), MatchingInlineAsm);
4704 unsigned NumSuccessfulMatches =
llvm::count(Match, Match_Success);
4708 if (UnsizedMemOp && NumSuccessfulMatches > 1 &&
4711 unsigned M = MatchInstruction(
4712 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,
4713 isParsingIntelSyntax());
4714 if (M == Match_Success)
4715 NumSuccessfulMatches = 1;
4727 if (NumSuccessfulMatches == 1) {
4728 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
4733 if (!MatchingInlineAsm)
4734 while (processInstruction(Inst, Operands))
4737 if (!MatchingInlineAsm)
4741 }
else if (NumSuccessfulMatches > 1) {
4743 "multiple matches only possible with unsized memory operands");
4745 "ambiguous operand size for instruction '" + Mnemonic +
"\'",
4751 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4757 if (
llvm::count(Match, Match_MissingFeature) == 1) {
4758 ErrorInfo = Match_MissingFeature;
4759 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
4765 if (
llvm::count(Match, Match_InvalidOperand) == 1) {
4766 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4770 if (
llvm::count(Match, Match_InvalidImmUnsignedi4) == 1) {
4771 SMLoc ErrorLoc = ((X86Operand &)*Operands[ErrorInfo]).getStartLoc();
4772 if (ErrorLoc == SMLoc())
4774 return Error(ErrorLoc,
"immediate must be an integer in range [0, 15]",
4775 EmptyRange, MatchingInlineAsm);
4778 if (
llvm::count(Match, Match_InvalidImmUnsignedi6) == 1) {
4779 SMLoc ErrorLoc = ((X86Operand &)*Operands[ErrorInfo]).getStartLoc();
4780 if (ErrorLoc == SMLoc())
4782 return Error(ErrorLoc,
"immediate must be an integer in range [0, 63]",
4783 EmptyRange, MatchingInlineAsm);
4787 return Error(IDLoc,
"unknown instruction mnemonic", EmptyRange,
4791bool X86AsmParser::omitRegisterFromClobberLists(MCRegister
Reg) {
4792 return getX86MCRegisterClass(X86::SEGMENT_REGRegClassID).contains(
Reg);
4795bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
4796 MCAsmParser &Parser = getParser();
4799 return parseDirectiveArch();
4801 return ParseDirectiveCode(IDVal, DirectiveID.
getLoc());
4807 return Error(DirectiveID.
getLoc(),
"'.att_syntax noprefix' is not "
4808 "supported: registers must have a "
4809 "'%' prefix in .att_syntax");
4811 getParser().setAssemblerDialect(0);
4814 getParser().setAssemblerDialect(1);
4819 return Error(DirectiveID.
getLoc(),
"'.intel_syntax prefix' is not "
4820 "supported: registers must not have "
4821 "a '%' prefix in .intel_syntax");
4824 }
else if (IDVal ==
".nops")
4825 return parseDirectiveNops(DirectiveID.
getLoc());
4826 else if (IDVal ==
".even")
4827 return parseDirectiveEven(DirectiveID.
getLoc());
4828 else if (IDVal ==
".cv_fpo_proc")
4829 return parseDirectiveFPOProc(DirectiveID.
getLoc());
4830 else if (IDVal ==
".cv_fpo_setframe")
4831 return parseDirectiveFPOSetFrame(DirectiveID.
getLoc());
4832 else if (IDVal ==
".cv_fpo_pushreg")
4833 return parseDirectiveFPOPushReg(DirectiveID.
getLoc());
4834 else if (IDVal ==
".cv_fpo_stackalloc")
4835 return parseDirectiveFPOStackAlloc(DirectiveID.
getLoc());
4836 else if (IDVal ==
".cv_fpo_stackalign")
4837 return parseDirectiveFPOStackAlign(DirectiveID.
getLoc());
4838 else if (IDVal ==
".cv_fpo_endprologue")
4839 return parseDirectiveFPOEndPrologue(DirectiveID.
getLoc());
4840 else if (IDVal ==
".cv_fpo_endproc")
4841 return parseDirectiveFPOEndProc(DirectiveID.
getLoc());
4842 else if (IDVal ==
".seh_pushreg")
4843 return parseDirectiveSEHPushReg(DirectiveID.
getLoc());
4844 else if (IDVal ==
".seh_push2regs")
4845 return parseDirectiveSEHPush2Regs(DirectiveID.
getLoc());
4846 else if (IDVal ==
".seh_setframe")
4847 return parseDirectiveSEHSetFrame(DirectiveID.
getLoc());
4848 else if (IDVal ==
".seh_savereg")
4849 return parseDirectiveSEHSaveReg(DirectiveID.
getLoc());
4850 else if (IDVal ==
".seh_savexmm")
4851 return parseDirectiveSEHSaveXMM(DirectiveID.
getLoc());
4852 else if (IDVal ==
".seh_pushframe")
4853 return parseDirectiveSEHPushFrame(DirectiveID.
getLoc());
4857 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
4858 parseDirectiveSEHPushReg(DirectiveID.
getLoc());
4860 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
4861 parseDirectiveSEHPush2Regs(DirectiveID.
getLoc());
4863 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
4864 parseDirectiveSEHSetFrame(DirectiveID.
getLoc());
4866 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
4867 parseDirectiveSEHSaveReg(DirectiveID.
getLoc());
4869 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
4870 parseDirectiveSEHSaveXMM(DirectiveID.
getLoc());
4872 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
4873 parseDirectiveSEHPushFrame(DirectiveID.
getLoc());
4877 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
4878 parseDirectiveSEHPushReg(DirectiveID.
getLoc());
4882 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
4883 parseDirectiveSEHPush2Regs(DirectiveID.
getLoc(),
4886 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
4887 parseDirectiveSEHSetFrame(DirectiveID.
getLoc());
4889 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
4890 parseDirectiveSEHSaveReg(DirectiveID.
getLoc());
4892 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
4893 parseDirectiveSEHSaveXMM(DirectiveID.
getLoc());
4900bool X86AsmParser::parseDirectiveArch() {
4902 getParser().parseStringToEndOfStatement();
4908bool X86AsmParser::parseDirectiveNops(SMLoc L) {
4909 int64_t NumBytes = 0, Control = 0;
4910 SMLoc NumBytesLoc, ControlLoc;
4911 const MCSubtargetInfo& STI = getSTI();
4912 NumBytesLoc = getTok().getLoc();
4913 if (getParser().checkForValidSection() ||
4914 getParser().parseAbsoluteExpression(NumBytes))
4918 ControlLoc = getTok().getLoc();
4919 if (getParser().parseAbsoluteExpression(Control))
4922 if (getParser().parseEOL())
4925 if (NumBytes <= 0) {
4926 Error(NumBytesLoc,
"'.nops' directive with non-positive size");
4931 Error(ControlLoc,
"'.nops' directive with negative NOP size");
4936 getParser().getStreamer().emitNops(NumBytes, Control, L, STI);
4943bool X86AsmParser::parseDirectiveEven(SMLoc L) {
4947 const MCSection *
Section = getStreamer().getCurrentSectionOnly();
4949 getStreamer().initSections(getSTI());
4950 Section = getStreamer().getCurrentSectionOnly();
4952 if (
getContext().getAsmInfo().useCodeAlign(*Section))
4953 getStreamer().emitCodeAlignment(
Align(2), getSTI(), 0);
4955 getStreamer().emitValueToAlignment(
Align(2), 0, 1, 0);
4961bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
4962 MCAsmParser &Parser = getParser();
4964 if (IDVal ==
".code16") {
4966 if (!is16BitMode()) {
4967 SwitchMode(X86::Is16Bit);
4968 getTargetStreamer().emitCode16();
4970 }
else if (IDVal ==
".code16gcc") {
4974 if (!is16BitMode()) {
4975 SwitchMode(X86::Is16Bit);
4976 getTargetStreamer().emitCode16();
4978 }
else if (IDVal ==
".code32") {
4980 if (!is32BitMode()) {
4981 SwitchMode(X86::Is32Bit);
4982 getTargetStreamer().emitCode32();
4984 }
else if (IDVal ==
".code64") {
4986 if (!is64BitMode()) {
4987 SwitchMode(X86::Is64Bit);
4988 getTargetStreamer().emitCode64();
4991 Error(L,
"unknown directive " + IDVal);
4999bool X86AsmParser::parseDirectiveFPOProc(SMLoc L) {
5000 MCAsmParser &Parser = getParser();
5004 return Parser.
TokError(
"expected symbol name");
5005 if (Parser.
parseIntToken(ParamsSize,
"expected parameter byte count"))
5008 return Parser.
TokError(
"parameters size out of range");
5012 return getTargetStreamer().emitFPOProc(ProcSym, ParamsSize, L);
5016bool X86AsmParser::parseDirectiveFPOSetFrame(SMLoc L) {
5019 if (parseRegister(
Reg, DummyLoc, DummyLoc) || parseEOL())
5021 return getTargetStreamer().emitFPOSetFrame(
Reg, L);
5025bool X86AsmParser::parseDirectiveFPOPushReg(SMLoc L) {
5028 if (parseRegister(
Reg, DummyLoc, DummyLoc) || parseEOL())
5030 return getTargetStreamer().emitFPOPushReg(
Reg, L);
5034bool X86AsmParser::parseDirectiveFPOStackAlloc(SMLoc L) {
5035 MCAsmParser &Parser = getParser();
5039 return getTargetStreamer().emitFPOStackAlloc(
Offset, L);
5043bool X86AsmParser::parseDirectiveFPOStackAlign(SMLoc L) {
5044 MCAsmParser &Parser = getParser();
5048 return getTargetStreamer().emitFPOStackAlign(
Offset, L);
5052bool X86AsmParser::parseDirectiveFPOEndPrologue(SMLoc L) {
5053 MCAsmParser &Parser = getParser();
5056 return getTargetStreamer().emitFPOEndPrologue(L);
5060bool X86AsmParser::parseDirectiveFPOEndProc(SMLoc L) {
5061 MCAsmParser &Parser = getParser();
5064 return getTargetStreamer().emitFPOEndProc(L);
5067bool X86AsmParser::parseSEHRegisterNumber(
unsigned RegClassID,
5068 MCRegister &RegNo) {
5069 SMLoc startLoc = getLexer().getLoc();
5070 const MCRegisterInfo *MRI =
getContext().getRegisterInfo();
5075 if (parseRegister(RegNo, startLoc, endLoc))
5078 if (!getX86MCRegisterClass(RegClassID).
contains(RegNo)) {
5079 return Error(startLoc,
5080 "register is not supported for use with this directive");
5086 if (getParser().parseAbsoluteExpression(EncodedReg))
5091 RegNo = MCRegister();
5092 for (
MCPhysReg Reg : getX86MCRegisterClass(RegClassID)) {
5099 return Error(startLoc,
5100 "incorrect register number for use with this directive");
5107bool X86AsmParser::parseDirectiveSEHPushReg(SMLoc Loc) {
5109 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5113 return TokError(
"expected end of directive");
5116 getStreamer().emitWinCFIPushReg(
Reg, Loc);
5120bool X86AsmParser::parseDirectiveSEHPush2Regs(SMLoc Loc,
bool SwapRegs) {
5122 if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg1))
5126 return TokError(
"expected comma between registers");
5130 if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg2))
5134 return TokError(
"expected end of directive");
5140 getStreamer().emitWinCFIPush2Regs(Reg1, Reg2, Loc);
5144bool X86AsmParser::parseDirectiveSEHSetFrame(SMLoc Loc) {
5147 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5150 return TokError(
"you must specify a stack pointer offset");
5153 if (getParser().parseAbsoluteExpression(Off))
5157 return TokError(
"expected end of directive");
5160 getStreamer().emitWinCFISetFrame(
Reg, Off, Loc);
5164bool X86AsmParser::parseDirectiveSEHSaveReg(SMLoc Loc) {
5167 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5170 return TokError(
"you must specify an offset on the stack");
5173 if (getParser().parseAbsoluteExpression(Off))
5177 return TokError(
"expected end of directive");
5180 getStreamer().emitWinCFISaveReg(
Reg, Off, Loc);
5184bool X86AsmParser::parseDirectiveSEHSaveXMM(SMLoc Loc) {
5187 if (parseSEHRegisterNumber(X86::VR128XRegClassID,
Reg))
5190 return TokError(
"you must specify an offset on the stack");
5193 if (getParser().parseAbsoluteExpression(Off))
5197 return TokError(
"expected end of directive");
5200 getStreamer().emitWinCFISaveXMM(
Reg, Off, Loc);
5204bool X86AsmParser::ensureMasmPrologContext(SMLoc Loc) {
5205 if (getStreamer().isWinCFIPrologEnded()) {
5206 return Error(Loc,
"prolog directive must be used inside a prolog");
5211bool X86AsmParser::ensureMasmEpilogContext(SMLoc Loc) {
5212 if (!getStreamer().isInEpilogCFI()) {
5213 return Error(Loc,
"epilog directive must be used inside an epilog");
5218bool X86AsmParser::parseDirectiveSEHPushFrame(SMLoc Loc) {
5222 SMLoc startLoc = getLexer().getLoc();
5224 if (!getParser().parseIdentifier(CodeID)) {
5225 if (CodeID !=
"code")
5226 return Error(startLoc,
"expected @code");
5229 }
else if (getParser().isParsingMasm() &&
5231 getTok().getString().equals_insensitive(
"code")) {
5237 return TokError(
"expected end of directive");
5240 getStreamer().emitWinCFIPushFrame(Code, Loc);
5250#define GET_MATCHER_IMPLEMENTATION
5251#include "X86GenAsmMatcher.inc"
static MCRegister MatchRegisterName(StringRef Name)
static const char * getSubtargetFeatureName(uint64_t Val)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
Function Alias Analysis false
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
amode Optimize addressing mode
Value * getPointer(Value *Ptr)
static ModuleSymbolTable::Symbol getSym(DataRefImpl &Symb)
static constexpr Value * getValue(Ty &ValueOrUse)
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static bool hasFeature(StringRef Feature, const FeatureBitset &FeatureBits, ArrayRef< SubtargetFeatureKV > ProcFeatures)
static bool IsVCMP(unsigned Opcode)
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.
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...
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
Target & getTheX86_64Target()
StringRef toStringRef(bool B)
Construct a string ref from a boolean.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
bool isKind(IdKind kind) const
SmallVectorImpl< AsmRewrite > * AsmRewrites
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
X86Operand - Instances of this class represent a parsed X86 machine instruction.
SMLoc getStartLoc() const override
getStartLoc - Get the location of the first token of this operand.
bool isImm() const override
isImm - Is this an immediate operand?
static std::unique_ptr< X86Operand > CreateImm(const MCExpr *Val, SMLoc StartLoc, SMLoc EndLoc, StringRef SymName=StringRef(), void *OpDecl=nullptr, bool GlobalRef=true)
static std::unique_ptr< X86Operand > CreatePrefix(unsigned Prefixes, SMLoc StartLoc, SMLoc EndLoc)
static std::unique_ptr< X86Operand > CreateDXReg(SMLoc StartLoc, SMLoc EndLoc)
static std::unique_ptr< X86Operand > CreateReg(MCRegister Reg, SMLoc StartLoc, SMLoc EndLoc, bool AddressOf=false, SMLoc OffsetOfLoc=SMLoc(), StringRef SymName=StringRef(), void *OpDecl=nullptr)
SMRange getLocRange() const
getLocRange - Get the range between the first and last token of this operand.
SMLoc getEndLoc() const override
getEndLoc - Get the location of the last token of this operand.
bool isReg() const override
isReg - Is this a register operand?
bool isMem() const override
isMem - Is this a memory operand?
static std::unique_ptr< X86Operand > CreateMem(unsigned ModeSize, const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc, unsigned Size=0, StringRef SymName=StringRef(), void *OpDecl=nullptr, unsigned FrontendSize=0, bool UseUpRegs=false, bool MaybeDirectBranchDest=true)
Create an absolute memory operand.
static std::unique_ptr< X86Operand > CreateToken(StringRef Str, SMLoc Loc)
bool isMemUnsized() const
const MCExpr * getImm() const
unsigned getMemFrontendSize() const
MCRegister getReg() const override