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 X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg) ||
1374 X86MCRegisterClasses[X86::GR32RegClassID].
contains(BaseReg) ||
1375 X86MCRegisterClasses[X86::GR64RegClassID].
contains(BaseReg))) {
1376 ErrMsg =
"invalid base+index expression";
1381 !(IndexReg == X86::EIZ || IndexReg == X86::RIZ ||
1382 X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg) ||
1383 X86MCRegisterClasses[X86::GR32RegClassID].
contains(IndexReg) ||
1384 X86MCRegisterClasses[X86::GR64RegClassID].
contains(IndexReg) ||
1385 X86MCRegisterClasses[X86::VR128XRegClassID].
contains(IndexReg) ||
1386 X86MCRegisterClasses[X86::VR256XRegClassID].
contains(IndexReg) ||
1387 X86MCRegisterClasses[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 (X86MCRegisterClasses[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 X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg)) {
1410 ErrMsg =
"16-bit memory operand may not include only index register";
1414 if (BaseReg && IndexReg) {
1415 if (X86MCRegisterClasses[X86::GR64RegClassID].
contains(BaseReg) &&
1416 (X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg) ||
1417 X86MCRegisterClasses[X86::GR32RegClassID].
contains(IndexReg) ||
1418 IndexReg == X86::EIZ)) {
1419 ErrMsg =
"base register is 64-bit, but index register is not";
1422 if (X86MCRegisterClasses[X86::GR32RegClassID].
contains(BaseReg) &&
1423 (X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg) ||
1424 X86MCRegisterClasses[X86::GR64RegClassID].
contains(IndexReg) ||
1425 IndexReg == X86::RIZ)) {
1426 ErrMsg =
"base register is 32-bit, but index register is not";
1429 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg)) {
1430 if (X86MCRegisterClasses[X86::GR32RegClassID].
contains(IndexReg) ||
1431 X86MCRegisterClasses[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 X86MCRegisterClasses[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 !X86MCRegisterClasses[RegClassID].
contains(OrigReg)) {
1762 "mismatching source and destination index registers");
1765 if (X86MCRegisterClasses[X86::GR64RegClassID].
contains(OrigReg))
1766 RegClassID = X86::GR64RegClassID;
1767 else if (X86MCRegisterClasses[X86::GR32RegClassID].
contains(OrigReg))
1768 RegClassID = X86::GR32RegClassID;
1769 else if (X86MCRegisterClasses[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 (X86MCRegisterClasses[X86::GR8RegClassID].
contains(RegNo))
2647 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(RegNo))
2649 if (X86MCRegisterClasses[X86::GR32RegClassID].
contains(RegNo))
2651 if (X86MCRegisterClasses[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 (!X86MCRegisterClasses[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 !(X86MCRegisterClasses[X86::VR128XRegClassID].
contains(IndexReg) ||
2767 X86MCRegisterClasses[X86::VR256XRegClassID].
contains(IndexReg) ||
2768 X86MCRegisterClasses[X86::VR512RegClassID].
contains(IndexReg)) &&
2769 (X86MCRegisterClasses[X86::VR128XRegClassID].
contains(BaseReg) ||
2770 X86MCRegisterClasses[X86::VR256XRegClassID].
contains(BaseReg) ||
2771 X86MCRegisterClasses[X86::VR512RegClassID].
contains(BaseReg)))
2775 X86MCRegisterClasses[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 (!X86MCRegisterClasses[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 X86MCRegisterClasses[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();
3065 bool Is64 = X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) ||
3066 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg);
3067 bool Is16 = X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg);
3070 return Error(Loc,
"displacement " + Twine(Imm) +
3071 " is not within [-2147483648, 2147483647]");
3073 if (!
isUInt<32>(Imm < 0 ? -uint64_t(Imm) : uint64_t(Imm))) {
3074 Warning(Loc,
"displacement " + Twine(Imm) +
3075 " shortened to 32-bit signed " +
3076 Twine(
static_cast<int32_t
>(Imm)));
3078 }
else if (!
isUInt<16>(Imm < 0 ? -uint64_t(Imm) : uint64_t(Imm))) {
3079 Warning(Loc,
"displacement " + Twine(Imm) +
3080 " shortened to 16-bit signed " +
3081 Twine(
static_cast<int16_t
>(Imm)));
3090bool X86AsmParser::ParseMemOperand(MCRegister SegReg,
const MCExpr *Disp,
3091 SMLoc StartLoc, SMLoc EndLoc,
3093 MCAsmParser &Parser = getParser();
3111 auto isAtMemOperand = [
this]() {
3116 auto TokCount = this->getLexer().peekTokens(Buf,
true);
3119 switch (Buf[0].getKind()) {
3126 if ((TokCount > 1) &&
3130 Buf[1].getIdentifier().
size() + 1);
3152 if (!isAtMemOperand()) {
3171 0, 0, 1, StartLoc, EndLoc));
3179 SMLoc BaseLoc = getLexer().getLoc();
3191 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ)
3192 return Error(BaseLoc,
"eiz and riz can only be used as index registers",
3193 SMRange(BaseLoc, EndLoc));
3211 if (!
E->evaluateAsAbsolute(ScaleVal, getStreamer().getAssemblerPtr()))
3212 return Error(Loc,
"expected absolute expression");
3214 Warning(Loc,
"scale factor without index register is ignored");
3219 if (BaseReg == X86::RIP)
3221 "%rip as base register can not have an index register");
3222 if (IndexReg == X86::RIP)
3223 return Error(Loc,
"%rip is not allowed as an index register");
3234 return Error(Loc,
"expected scale expression");
3235 Scale = (unsigned)ScaleVal;
3237 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg) &&
3239 return Error(Loc,
"scale factor in 16-bit address must be 1");
3241 return Error(Loc, ErrMsg);
3255 if (BaseReg == X86::DX && !IndexReg && Scale == 1 && !SegReg &&
3264 return Error(BaseLoc, ErrMsg);
3266 if (CheckDispOverflow(BaseReg, IndexReg, Disp, BaseLoc))
3269 if (SegReg || BaseReg || IndexReg)
3271 BaseReg, IndexReg, Scale, StartLoc,
3280bool X86AsmParser::parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
3281 MCAsmParser &Parser = getParser();
3288 if (parseRegister(RegNo, StartLoc, EndLoc))
3296bool X86AsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
3298 MCAsmParser &Parser = getParser();
3302 ForcedOpcodePrefix = OpcodePrefix_Default;
3303 ForcedDispEncoding = DispEncoding_Default;
3304 UseApxExtendedReg =
false;
3305 ForcedNoFlag =
false;
3318 if (Prefix ==
"rex")
3319 ForcedOpcodePrefix = OpcodePrefix_REX;
3320 else if (Prefix ==
"rex2")
3321 ForcedOpcodePrefix = OpcodePrefix_REX2;
3322 else if (Prefix ==
"vex")
3323 ForcedOpcodePrefix = OpcodePrefix_VEX;
3324 else if (Prefix ==
"vex2")
3325 ForcedOpcodePrefix = OpcodePrefix_VEX2;
3326 else if (Prefix ==
"vex3")
3327 ForcedOpcodePrefix = OpcodePrefix_VEX3;
3328 else if (Prefix ==
"evex")
3329 ForcedOpcodePrefix = OpcodePrefix_EVEX;
3330 else if (Prefix ==
"disp8")
3331 ForcedDispEncoding = DispEncoding_Disp8;
3332 else if (Prefix ==
"disp32")
3333 ForcedDispEncoding = DispEncoding_Disp32;
3334 else if (Prefix ==
"nf")
3335 ForcedNoFlag =
true;
3337 return Error(NameLoc,
"unknown prefix");
3353 if (isParsingMSInlineAsm()) {
3354 if (
Name.equals_insensitive(
"vex"))
3355 ForcedOpcodePrefix = OpcodePrefix_VEX;
3356 else if (
Name.equals_insensitive(
"vex2"))
3357 ForcedOpcodePrefix = OpcodePrefix_VEX2;
3358 else if (
Name.equals_insensitive(
"vex3"))
3359 ForcedOpcodePrefix = OpcodePrefix_VEX3;
3360 else if (
Name.equals_insensitive(
"evex"))
3361 ForcedOpcodePrefix = OpcodePrefix_EVEX;
3363 if (ForcedOpcodePrefix != OpcodePrefix_Default) {
3376 if (
Name.consume_back(
".d32")) {
3377 ForcedDispEncoding = DispEncoding_Disp32;
3378 }
else if (
Name.consume_back(
".d8")) {
3379 ForcedDispEncoding = DispEncoding_Disp8;
3382 StringRef PatchedName =
Name;
3385 if (isParsingIntelSyntax() &&
3386 (PatchedName ==
"jmp" || PatchedName ==
"jc" || PatchedName ==
"jnc" ||
3387 PatchedName ==
"jcxz" || PatchedName ==
"jecxz" ||
3392 : NextTok ==
"short") {
3401 NextTok.
size() + 1);
3407 PatchedName !=
"setzub" && PatchedName !=
"setzunb" &&
3408 PatchedName !=
"setb" && PatchedName !=
"setnb")
3409 PatchedName = PatchedName.
substr(0,
Name.size()-1);
3411 unsigned ComparisonPredicate = ~0
U;
3419 bool IsVCMP = PatchedName[0] ==
'v';
3420 unsigned CCIdx =
IsVCMP ? 4 : 3;
3421 unsigned suffixLength = PatchedName.
ends_with(
"bf16") ? 5 : 2;
3422 unsigned CC = StringSwitch<unsigned>(
3423 PatchedName.
slice(CCIdx, PatchedName.
size() - suffixLength))
3425 .Case(
"eq_oq", 0x00)
3427 .Case(
"lt_os", 0x01)
3429 .Case(
"le_os", 0x02)
3430 .Case(
"unord", 0x03)
3431 .Case(
"unord_q", 0x03)
3433 .Case(
"neq_uq", 0x04)
3435 .Case(
"nlt_us", 0x05)
3437 .Case(
"nle_us", 0x06)
3439 .Case(
"ord_q", 0x07)
3441 .Case(
"eq_uq", 0x08)
3443 .Case(
"nge_us", 0x09)
3445 .Case(
"ngt_us", 0x0A)
3446 .Case(
"false", 0x0B)
3447 .Case(
"false_oq", 0x0B)
3448 .Case(
"neq_oq", 0x0C)
3450 .Case(
"ge_os", 0x0D)
3452 .Case(
"gt_os", 0x0E)
3454 .Case(
"true_uq", 0x0F)
3455 .Case(
"eq_os", 0x10)
3456 .Case(
"lt_oq", 0x11)
3457 .Case(
"le_oq", 0x12)
3458 .Case(
"unord_s", 0x13)
3459 .Case(
"neq_us", 0x14)
3460 .Case(
"nlt_uq", 0x15)
3461 .Case(
"nle_uq", 0x16)
3462 .Case(
"ord_s", 0x17)
3463 .Case(
"eq_us", 0x18)
3464 .Case(
"nge_uq", 0x19)
3465 .Case(
"ngt_uq", 0x1A)
3466 .Case(
"false_os", 0x1B)
3467 .Case(
"neq_os", 0x1C)
3468 .Case(
"ge_oq", 0x1D)
3469 .Case(
"gt_oq", 0x1E)
3470 .Case(
"true_us", 0x1F)
3472 if (CC != ~0U && (
IsVCMP || CC < 8) &&
3475 PatchedName =
IsVCMP ?
"vcmpss" :
"cmpss";
3477 PatchedName =
IsVCMP ?
"vcmpsd" :
"cmpsd";
3479 PatchedName =
IsVCMP ?
"vcmpps" :
"cmpps";
3481 PatchedName =
IsVCMP ?
"vcmppd" :
"cmppd";
3483 PatchedName =
"vcmpsh";
3485 PatchedName =
"vcmpph";
3487 PatchedName =
"vcmpbf16";
3491 ComparisonPredicate = CC;
3497 (PatchedName.
back() ==
'b' || PatchedName.
back() ==
'w' ||
3498 PatchedName.
back() ==
'd' || PatchedName.
back() ==
'q')) {
3499 unsigned SuffixSize = PatchedName.
drop_back().
back() ==
'u' ? 2 : 1;
3500 unsigned CC = StringSwitch<unsigned>(
3501 PatchedName.
slice(5, PatchedName.
size() - SuffixSize))
3511 if (CC != ~0U && (CC != 0 || SuffixSize == 2)) {
3512 switch (PatchedName.
back()) {
3514 case 'b': PatchedName = SuffixSize == 2 ?
"vpcmpub" :
"vpcmpb";
break;
3515 case 'w': PatchedName = SuffixSize == 2 ?
"vpcmpuw" :
"vpcmpw";
break;
3516 case 'd': PatchedName = SuffixSize == 2 ?
"vpcmpud" :
"vpcmpd";
break;
3517 case 'q': PatchedName = SuffixSize == 2 ?
"vpcmpuq" :
"vpcmpq";
break;
3520 ComparisonPredicate = CC;
3526 (PatchedName.
back() ==
'b' || PatchedName.
back() ==
'w' ||
3527 PatchedName.
back() ==
'd' || PatchedName.
back() ==
'q')) {
3528 unsigned SuffixSize = PatchedName.
drop_back().
back() ==
'u' ? 2 : 1;
3529 unsigned CC = StringSwitch<unsigned>(
3530 PatchedName.
slice(5, PatchedName.
size() - SuffixSize))
3541 switch (PatchedName.
back()) {
3543 case 'b': PatchedName = SuffixSize == 2 ?
"vpcomub" :
"vpcomb";
break;
3544 case 'w': PatchedName = SuffixSize == 2 ?
"vpcomuw" :
"vpcomw";
break;
3545 case 'd': PatchedName = SuffixSize == 2 ?
"vpcomud" :
"vpcomd";
break;
3546 case 'q': PatchedName = SuffixSize == 2 ?
"vpcomuq" :
"vpcomq";
break;
3549 ComparisonPredicate = CC;
3561 StringSwitch<bool>(Name)
3562 .Cases({
"cs",
"ds",
"es",
"fs",
"gs",
"ss"},
true)
3563 .Cases({
"rex64",
"data32",
"data16",
"addr32",
"addr16"},
true)
3564 .Cases({
"xacquire",
"xrelease"},
true)
3565 .Cases({
"acquire",
"release"}, isParsingIntelSyntax())
3568 auto isLockRepeatNtPrefix = [](StringRef
N) {
3569 return StringSwitch<bool>(
N)
3570 .Cases({
"lock",
"rep",
"repe",
"repz",
"repne",
"repnz",
"notrack"},
3575 bool CurlyAsEndOfStatement =
false;
3578 while (isLockRepeatNtPrefix(
Name.lower())) {
3580 StringSwitch<unsigned>(Name)
3599 while (
Name.starts_with(
";") ||
Name.starts_with(
"\n") ||
3600 Name.starts_with(
"#") ||
Name.starts_with(
"\t") ||
3601 Name.starts_with(
"/")) {
3612 if (PatchedName ==
"data16" && is16BitMode()) {
3613 return Error(NameLoc,
"redundant data16 prefix");
3615 if (PatchedName ==
"data32") {
3617 return Error(NameLoc,
"redundant data32 prefix");
3619 return Error(NameLoc,
"'data32' is not supported in 64-bit mode");
3621 PatchedName =
"data16";
3628 if (
Next ==
"callw")
3630 if (
Next ==
"ljmpw")
3635 ForcedDataPrefix = X86::Is32Bit;
3643 if (ComparisonPredicate != ~0U && !isParsingIntelSyntax()) {
3650 if ((
Name.starts_with(
"ccmp") ||
Name.starts_with(
"ctest")) &&
3651 parseCFlagsOp(Operands))
3665 if (parseOperand(Operands, Name))
3667 if (HandleAVX512Operand(Operands))
3679 CurlyAsEndOfStatement =
3680 isParsingIntelSyntax() && isParsingMSInlineAsm() &&
3683 return TokError(
"unexpected token in argument list");
3687 if (ComparisonPredicate != ~0U && isParsingIntelSyntax()) {
3697 else if (CurlyAsEndOfStatement)
3700 getLexer().getTok().getLoc(), 0);
3707 if (IsFp && Operands.
size() == 1) {
3708 const char *Repl = StringSwitch<const char *>(Name)
3709 .Case(
"fsub",
"fsubp")
3710 .Case(
"fdiv",
"fdivp")
3711 .Case(
"fsubr",
"fsubrp")
3712 .Case(
"fdivr",
"fdivrp");
3713 static_cast<X86Operand &
>(*Operands[0]).setTokenValue(Repl);
3716 if ((Name ==
"mov" || Name ==
"movw" || Name ==
"movl") &&
3717 (Operands.
size() == 3)) {
3718 X86Operand &Op1 = (X86Operand &)*Operands[1];
3719 X86Operand &Op2 = (X86Operand &)*Operands[2];
3724 X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(
3726 (X86MCRegisterClasses[X86::GR16RegClassID].contains(Op1.
getReg()) ||
3727 X86MCRegisterClasses[X86::GR32RegClassID].contains(Op1.
getReg()))) {
3729 if (Name !=
"mov" && Name[3] == (is16BitMode() ?
'l' :
'w')) {
3730 Name = is16BitMode() ?
"movw" :
"movl";
3743 if ((Name ==
"outb" || Name ==
"outsb" || Name ==
"outw" || Name ==
"outsw" ||
3744 Name ==
"outl" || Name ==
"outsl" || Name ==
"out" || Name ==
"outs") &&
3745 Operands.
size() == 3) {
3746 X86Operand &
Op = (X86Operand &)*Operands.
back();
3752 if ((Name ==
"inb" || Name ==
"insb" || Name ==
"inw" || Name ==
"insw" ||
3753 Name ==
"inl" || Name ==
"insl" || Name ==
"in" || Name ==
"ins") &&
3754 Operands.
size() == 3) {
3755 X86Operand &
Op = (X86Operand &)*Operands[1];
3762 bool HadVerifyError =
false;
3765 if (
Name.starts_with(
"ins") &&
3766 (Operands.
size() == 1 || Operands.
size() == 3) &&
3767 (Name ==
"insb" || Name ==
"insw" || Name ==
"insl" || Name ==
"insd" ||
3770 AddDefaultSrcDestOperands(TmpOperands,
3772 DefaultMemDIOperand(NameLoc));
3773 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3777 if (
Name.starts_with(
"outs") &&
3778 (Operands.
size() == 1 || Operands.
size() == 3) &&
3779 (Name ==
"outsb" || Name ==
"outsw" || Name ==
"outsl" ||
3780 Name ==
"outsd" || Name ==
"outs")) {
3781 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
3783 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3789 if (
Name.starts_with(
"lods") &&
3790 (Operands.
size() == 1 || Operands.
size() == 2) &&
3791 (Name ==
"lods" || Name ==
"lodsb" || Name ==
"lodsw" ||
3792 Name ==
"lodsl" || Name ==
"lodsd" || Name ==
"lodsq")) {
3793 TmpOperands.
push_back(DefaultMemSIOperand(NameLoc));
3794 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3800 if (
Name.starts_with(
"stos") &&
3801 (Operands.
size() == 1 || Operands.
size() == 2) &&
3802 (Name ==
"stos" || Name ==
"stosb" || Name ==
"stosw" ||
3803 Name ==
"stosl" || Name ==
"stosd" || Name ==
"stosq")) {
3804 TmpOperands.
push_back(DefaultMemDIOperand(NameLoc));
3805 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3811 if (
Name.starts_with(
"scas") &&
3812 (Operands.
size() == 1 || Operands.
size() == 2) &&
3813 (Name ==
"scas" || Name ==
"scasb" || Name ==
"scasw" ||
3814 Name ==
"scasl" || Name ==
"scasd" || Name ==
"scasq")) {
3815 TmpOperands.
push_back(DefaultMemDIOperand(NameLoc));
3816 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3820 if (
Name.starts_with(
"cmps") &&
3821 (Operands.
size() == 1 || Operands.
size() == 3) &&
3822 (Name ==
"cmps" || Name ==
"cmpsb" || Name ==
"cmpsw" ||
3823 Name ==
"cmpsl" || Name ==
"cmpsd" || Name ==
"cmpsq")) {
3824 AddDefaultSrcDestOperands(TmpOperands, DefaultMemDIOperand(NameLoc),
3825 DefaultMemSIOperand(NameLoc));
3826 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3830 if (((
Name.starts_with(
"movs") &&
3831 (Name ==
"movs" || Name ==
"movsb" || Name ==
"movsw" ||
3832 Name ==
"movsl" || Name ==
"movsd" || Name ==
"movsq")) ||
3833 (
Name.starts_with(
"smov") &&
3834 (Name ==
"smov" || Name ==
"smovb" || Name ==
"smovw" ||
3835 Name ==
"smovl" || Name ==
"smovd" || Name ==
"smovq"))) &&
3836 (Operands.
size() == 1 || Operands.
size() == 3)) {
3837 if (Name ==
"movsd" && Operands.
size() == 1 && !isParsingIntelSyntax())
3839 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
3840 DefaultMemDIOperand(NameLoc));
3841 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3845 if (HadVerifyError) {
3846 return HadVerifyError;
3850 if ((Name ==
"xlat" || Name ==
"xlatb") && Operands.
size() == 2) {
3851 X86Operand &Op1 =
static_cast<X86Operand &
>(*Operands[1]);
3854 "size, (R|E)BX will be used for the location");
3856 static_cast<X86Operand &
>(*Operands[0]).setTokenValue(
"xlatb");
3869 if (
I == Table.
end() ||
I->OldOpc != Opcode)
3875 if (X86::isBLENDVPD(Opcode) || X86::isBLENDVPS(Opcode) ||
3876 X86::isPBLENDVB(Opcode))
3882bool X86AsmParser::processInstruction(MCInst &Inst,
const OperandVector &
Ops) {
3886 if (ForcedOpcodePrefix != OpcodePrefix_VEX3 &&
3893 auto replaceWithCCMPCTEST = [&](
unsigned Opcode) ->
bool {
3894 if (ForcedOpcodePrefix == OpcodePrefix_EVEX) {
3905 default:
return false;
3910 if (ForcedDispEncoding == DispEncoding_Disp32) {
3911 Inst.
setOpcode(is16BitMode() ? X86::JMP_2 : X86::JMP_4);
3920 if (ForcedDispEncoding == DispEncoding_Disp32) {
3921 Inst.
setOpcode(is16BitMode() ? X86::JCC_2 : X86::JCC_4);
3937#define FROM_TO(FROM, TO) \
3939 return replaceWithCCMPCTEST(X86::TO);
3941 FROM_TO(CMP64mi32, CCMP64mi32)
3944 FROM_TO(CMP64ri32, CCMP64ri32)
3971 FROM_TO(TEST64mi32, CTEST64mi32)
3973 FROM_TO(TEST64ri32, CTEST64ri32)
3993bool X86AsmParser::validateInstruction(MCInst &Inst,
const OperandVector &
Ops) {
3994 using namespace X86;
3995 const MCRegisterInfo *MRI =
getContext().getRegisterInfo();
3997 uint64_t TSFlags = MII.get(Opcode).TSFlags;
3998 if (isVFCMADDCPH(Opcode) || isVFCMADDCSH(Opcode) || isVFMADDCPH(Opcode) ||
3999 isVFMADDCSH(Opcode)) {
4003 return Warning(
Ops[0]->getStartLoc(),
"Destination register should be "
4004 "distinct from source registers");
4005 }
else if (isVFCMULCPH(Opcode) || isVFCMULCSH(Opcode) || isVFMULCPH(Opcode) ||
4006 isVFMULCSH(Opcode)) {
4016 return Warning(
Ops[0]->getStartLoc(),
"Destination register should be "
4017 "distinct from source registers");
4018 }
else if (isV4FMADDPS(Opcode) || isV4FMADDSS(Opcode) ||
4019 isV4FNMADDPS(Opcode) || isV4FNMADDSS(Opcode) ||
4020 isVP4DPWSSDS(Opcode) || isVP4DPWSSD(Opcode)) {
4025 if (Src2Enc % 4 != 0) {
4027 unsigned GroupStart = (Src2Enc / 4) * 4;
4028 unsigned GroupEnd = GroupStart + 3;
4030 "source register '" +
RegName +
"' implicitly denotes '" +
4031 RegName.take_front(3) + Twine(GroupStart) +
"' to '" +
4032 RegName.take_front(3) + Twine(GroupEnd) +
4035 }
else if (isVGATHERDPD(Opcode) || isVGATHERDPS(Opcode) ||
4036 isVGATHERQPD(Opcode) || isVGATHERQPS(Opcode) ||
4037 isVPGATHERDD(Opcode) || isVPGATHERDQ(Opcode) ||
4038 isVPGATHERQD(Opcode) || isVPGATHERQQ(Opcode)) {
4045 return Warning(
Ops[0]->getStartLoc(),
"index and destination registers "
4046 "should be distinct");
4052 if (Dest == Mask || Dest == Index || Mask == Index)
4053 return Warning(
Ops[0]->getStartLoc(),
"mask, index, and destination "
4054 "registers should be distinct");
4056 }
else if (isTCMMIMFP16PS(Opcode) || isTCMMRLFP16PS(Opcode) ||
4057 isTDPBF16PS(Opcode) || isTDPFP16PS(Opcode) || isTDPBSSD(Opcode) ||
4058 isTDPBSUD(Opcode) || isTDPBUSD(Opcode) || isTDPBUUD(Opcode)) {
4062 if (SrcDest == Src1 || SrcDest == Src2 || Src1 == Src2)
4063 return Error(
Ops[0]->getStartLoc(),
"all tmm registers must be distinct");
4077 for (
unsigned i = 0; i !=
NumOps; ++i) {
4082 if (
Reg == X86::AH ||
Reg == X86::BH ||
Reg == X86::CH ||
Reg == X86::DH)
4090 (Enc ==
X86II::EVEX || ForcedOpcodePrefix == OpcodePrefix_REX2 ||
4091 ForcedOpcodePrefix == OpcodePrefix_REX || UsesRex)) {
4093 return Error(
Ops[0]->getStartLoc(),
4094 "can't encode '" +
RegName.str() +
4095 "' in an instruction requiring EVEX/REX2/REX prefix");
4099 if ((Opcode == X86::PREFETCHIT0 || Opcode == X86::PREFETCHIT1)) {
4103 Ops[0]->getStartLoc(),
4104 Twine((Inst.
getOpcode() == X86::PREFETCHIT0 ?
"'prefetchit0'"
4105 :
"'prefetchit1'")) +
4106 " only supports RIP-relative address");
4111void X86AsmParser::emitWarningForSpecialLVIInstruction(SMLoc Loc) {
4112 Warning(Loc,
"Instruction may be vulnerable to LVI and "
4113 "requires manual mitigation");
4114 Note(SMLoc(),
"See https://software.intel.com/"
4115 "security-software-guidance/insights/"
4116 "deep-dive-load-value-injection#specialinstructions"
4117 " for more information");
4129void X86AsmParser::applyLVICFIMitigation(MCInst &Inst, MCStreamer &Out) {
4140 MCInst ShlInst, FenceInst;
4141 bool Parse32 = is32BitMode() || Code16GCC;
4142 MCRegister Basereg =
4143 is64BitMode() ? X86::RSP : (Parse32 ? X86::ESP : X86::SP);
4147 1, SMLoc{}, SMLoc{}, 0);
4149 ShlMemOp->addMemOperands(ShlInst, 5);
4162 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4174void X86AsmParser::applyLVILoadHardeningMitigation(MCInst &Inst,
4191 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4194 }
else if (Opcode == X86::REP_PREFIX || Opcode == X86::REPNE_PREFIX) {
4197 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4201 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
4216void X86AsmParser::emitInstruction(MCInst &Inst,
OperandVector &Operands,
4219 getSTI().hasFeature(X86::FeatureLVIControlFlowIntegrity))
4220 applyLVICFIMitigation(Inst, Out);
4225 getSTI().hasFeature(X86::FeatureLVILoadHardening))
4226 applyLVILoadHardeningMitigation(Inst, Out);
4230 unsigned Result = 0;
4232 if (Prefix.isPrefix()) {
4233 Result = Prefix.getPrefix();
4239bool X86AsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
4241 MCStreamer &Out, uint64_t &ErrorInfo,
4242 bool MatchingInlineAsm) {
4243 assert(!Operands.
empty() &&
"Unexpect empty operand list!");
4244 assert((*Operands[0]).isToken() &&
"Leading operand should always be a mnemonic!");
4247 MatchFPUWaitAlias(IDLoc,
static_cast<X86Operand &
>(*Operands[0]), Operands,
4248 Out, MatchingInlineAsm);
4255 if (ForcedOpcodePrefix == OpcodePrefix_REX)
4257 else if (ForcedOpcodePrefix == OpcodePrefix_REX2)
4259 else if (ForcedOpcodePrefix == OpcodePrefix_VEX)
4261 else if (ForcedOpcodePrefix == OpcodePrefix_VEX2)
4263 else if (ForcedOpcodePrefix == OpcodePrefix_VEX3)
4265 else if (ForcedOpcodePrefix == OpcodePrefix_EVEX)
4269 if (ForcedDispEncoding == DispEncoding_Disp8)
4271 else if (ForcedDispEncoding == DispEncoding_Disp32)
4277 return isParsingIntelSyntax()
4278 ? matchAndEmitIntelInstruction(IDLoc, Opcode, Inst, Operands, Out,
4279 ErrorInfo, MatchingInlineAsm)
4280 : matchAndEmitATTInstruction(IDLoc, Opcode, Inst, Operands, Out,
4281 ErrorInfo, MatchingInlineAsm);
4284void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &
Op,
4286 bool MatchingInlineAsm) {
4290 const char *Repl = StringSwitch<const char *>(
Op.getToken())
4291 .Case(
"finit",
"fninit")
4292 .Case(
"fsave",
"fnsave")
4293 .Case(
"fstcw",
"fnstcw")
4294 .Case(
"fstcww",
"fnstcw")
4295 .Case(
"fstenv",
"fnstenv")
4296 .Case(
"fstsw",
"fnstsw")
4297 .Case(
"fstsww",
"fnstsw")
4298 .Case(
"fclex",
"fnclex")
4304 if (!MatchingInlineAsm)
4310bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc,
4311 const FeatureBitset &MissingFeatures,
4312 bool MatchingInlineAsm) {
4313 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
4314 SmallString<126> Msg;
4315 raw_svector_ostream OS(Msg);
4316 OS <<
"instruction requires:";
4317 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
4318 if (MissingFeatures[i])
4321 return Error(IDLoc, OS.str(), SMRange(), MatchingInlineAsm);
4324unsigned X86AsmParser::checkTargetMatchPredicate(MCInst &Inst) {
4326 const MCInstrDesc &MCID = MII.get(
Opc);
4327 uint64_t TSFlags = MCID.
TSFlags;
4330 return Match_Unsupported;
4332 return Match_Unsupported;
4334 switch (ForcedOpcodePrefix) {
4335 case OpcodePrefix_Default:
4337 case OpcodePrefix_REX:
4338 case OpcodePrefix_REX2:
4340 return Match_Unsupported;
4342 case OpcodePrefix_VEX:
4343 case OpcodePrefix_VEX2:
4344 case OpcodePrefix_VEX3:
4346 return Match_Unsupported;
4348 case OpcodePrefix_EVEX:
4350 !X86::isCMP(
Opc) && !X86::isTEST(
Opc))
4351 return Match_Unsupported;
4353 return Match_Unsupported;
4358 (ForcedOpcodePrefix != OpcodePrefix_VEX &&
4359 ForcedOpcodePrefix != OpcodePrefix_VEX2 &&
4360 ForcedOpcodePrefix != OpcodePrefix_VEX3))
4361 return Match_Unsupported;
4363 return Match_Success;
4366bool X86AsmParser::matchAndEmitATTInstruction(
4367 SMLoc IDLoc,
unsigned &Opcode, MCInst &Inst,
OperandVector &Operands,
4368 MCStreamer &Out, uint64_t &ErrorInfo,
bool MatchingInlineAsm) {
4369 X86Operand &
Op =
static_cast<X86Operand &
>(*Operands[0]);
4373 if (ForcedDataPrefix == X86::Is32Bit)
4374 SwitchMode(X86::Is32Bit);
4376 FeatureBitset MissingFeatures;
4377 unsigned OriginalError = MatchInstruction(Operands, Inst, ErrorInfo,
4378 MissingFeatures, MatchingInlineAsm,
4379 isParsingIntelSyntax());
4380 if (ForcedDataPrefix == X86::Is32Bit) {
4381 SwitchMode(X86::Is16Bit);
4382 ForcedDataPrefix = 0;
4384 switch (OriginalError) {
4387 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
4392 if (!MatchingInlineAsm)
4393 while (processInstruction(Inst, Operands))
4397 if (!MatchingInlineAsm)
4401 case Match_InvalidImmUnsignedi4: {
4402 SMLoc ErrorLoc = ((X86Operand &)*Operands[ErrorInfo]).getStartLoc();
4403 if (ErrorLoc == SMLoc())
4405 return Error(ErrorLoc,
"immediate must be an integer in range [0, 15]",
4406 EmptyRange, MatchingInlineAsm);
4408 case Match_InvalidImmUnsignedi6: {
4409 SMLoc ErrorLoc = ((X86Operand &)*Operands[ErrorInfo]).getStartLoc();
4410 if (ErrorLoc == SMLoc())
4412 return Error(ErrorLoc,
"immediate must be an integer in range [0, 63]",
4413 EmptyRange, MatchingInlineAsm);
4415 case Match_MissingFeature:
4416 return ErrorMissingFeature(IDLoc, MissingFeatures, MatchingInlineAsm);
4417 case Match_InvalidOperand:
4418 case Match_MnemonicFail:
4419 case Match_Unsupported:
4422 if (
Op.getToken().empty()) {
4423 Error(IDLoc,
"instruction must have size higher than 0", EmptyRange,
4434 StringRef
Base =
Op.getToken();
4435 SmallString<16> Tmp;
4438 Op.setTokenValue(Tmp);
4446 const char *Suffixes =
Base[0] !=
'f' ?
"bwlq" :
"slt\0";
4448 const char *MemSize =
Base[0] !=
'f' ?
"\x08\x10\x20\x40" :
"\x20\x40\x50\0";
4451 uint64_t ErrorInfoIgnore;
4452 FeatureBitset ErrorInfoMissingFeatures;
4460 bool HasVectorReg =
false;
4461 X86Operand *MemOp =
nullptr;
4462 for (
const auto &
Op : Operands) {
4463 X86Operand *X86Op =
static_cast<X86Operand *
>(
Op.get());
4465 HasVectorReg =
true;
4466 else if (X86Op->
isMem()) {
4468 assert(MemOp->Mem.Size == 0 &&
"Memory size always 0 under ATT syntax");
4475 for (
unsigned I = 0,
E = std::size(Match);
I !=
E; ++
I) {
4476 Tmp.
back() = Suffixes[
I];
4477 if (MemOp && HasVectorReg)
4478 MemOp->Mem.Size = MemSize[
I];
4479 Match[
I] = Match_MnemonicFail;
4480 if (MemOp || !HasVectorReg) {
4482 MatchInstruction(Operands, Inst, ErrorInfoIgnore, MissingFeatures,
4483 MatchingInlineAsm, isParsingIntelSyntax());
4485 if (Match[
I] == Match_MissingFeature)
4486 ErrorInfoMissingFeatures = MissingFeatures;
4496 unsigned NumSuccessfulMatches =
llvm::count(Match, Match_Success);
4497 if (NumSuccessfulMatches == 1) {
4498 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
4503 if (!MatchingInlineAsm)
4504 while (processInstruction(Inst, Operands))
4508 if (!MatchingInlineAsm)
4518 if (NumSuccessfulMatches > 1) {
4520 unsigned NumMatches = 0;
4521 for (
unsigned I = 0,
E = std::size(Match);
I !=
E; ++
I)
4522 if (Match[
I] == Match_Success)
4523 MatchChars[NumMatches++] = Suffixes[
I];
4525 SmallString<126> Msg;
4526 raw_svector_ostream OS(Msg);
4527 OS <<
"ambiguous instructions require an explicit suffix (could be ";
4528 for (
unsigned i = 0; i != NumMatches; ++i) {
4531 if (i + 1 == NumMatches)
4533 OS <<
"'" <<
Base << MatchChars[i] <<
"'";
4536 Error(IDLoc, OS.str(), EmptyRange, MatchingInlineAsm);
4544 if (
llvm::count(Match, Match_MnemonicFail) == 4) {
4545 if (OriginalError == Match_MnemonicFail)
4546 return Error(IDLoc,
"invalid instruction mnemonic '" +
Base +
"'",
4547 Op.getLocRange(), MatchingInlineAsm);
4549 if (OriginalError == Match_Unsupported)
4550 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4553 assert(OriginalError == Match_InvalidOperand &&
"Unexpected error");
4555 if (ErrorInfo != ~0ULL) {
4556 if (ErrorInfo >= Operands.size())
4557 return Error(IDLoc,
"too few operands for instruction", EmptyRange,
4560 X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo];
4564 OperandRange, MatchingInlineAsm);
4568 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4574 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4580 if (
llvm::count(Match, Match_MissingFeature) == 1) {
4581 ErrorInfo = Match_MissingFeature;
4582 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
4588 if (
llvm::count(Match, Match_InvalidOperand) == 1) {
4589 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4594 Error(IDLoc,
"unknown use of instruction mnemonic without a size suffix",
4595 EmptyRange, MatchingInlineAsm);
4599bool X86AsmParser::matchAndEmitIntelInstruction(
4600 SMLoc IDLoc,
unsigned &Opcode, MCInst &Inst,
OperandVector &Operands,
4601 MCStreamer &Out, uint64_t &ErrorInfo,
bool MatchingInlineAsm) {
4602 X86Operand &
Op =
static_cast<X86Operand &
>(*Operands[0]);
4605 X86Operand *UnsizedMemOp =
nullptr;
4606 for (
const auto &
Op : Operands) {
4607 X86Operand *X86Op =
static_cast<X86Operand *
>(
Op.get());
4609 UnsizedMemOp = X86Op;
4618 StringRef Mnemonic = (
static_cast<X86Operand &
>(*Operands[0])).
getToken();
4620 static const char *
const PtrSizedInstrs[] = {
"call",
"jmp",
"push",
"pop"};
4621 for (
const char *Instr : PtrSizedInstrs) {
4622 if (Mnemonic == Instr) {
4623 UnsizedMemOp->
Mem.
Size = getPointerWidth();
4629 SmallVector<unsigned, 8> Match;
4630 FeatureBitset ErrorInfoMissingFeatures;
4631 FeatureBitset MissingFeatures;
4632 StringRef
Base = (
static_cast<X86Operand &
>(*Operands[0])).
getToken();
4636 if (Mnemonic ==
"push" && Operands.size() == 2) {
4637 auto *X86Op =
static_cast<X86Operand *
>(Operands[1].get());
4638 if (X86Op->
isImm()) {
4641 unsigned Size = getPointerWidth();
4644 SmallString<16> Tmp;
4646 Tmp += (is64BitMode())
4648 : (is32BitMode()) ?
"l" : (is16BitMode()) ?
"w" :
" ";
4649 Op.setTokenValue(Tmp);
4651 Match.
push_back(MatchInstruction(Operands, Inst, ErrorInfo,
4652 MissingFeatures, MatchingInlineAsm,
4663 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
4664 for (
unsigned Size : MopSizes) {
4666 uint64_t ErrorInfoIgnore;
4668 unsigned M = MatchInstruction(Operands, Inst, ErrorInfoIgnore,
4669 MissingFeatures, MatchingInlineAsm,
4670 isParsingIntelSyntax());
4675 if (Match.
back() == Match_MissingFeature)
4676 ErrorInfoMissingFeatures = MissingFeatures;
4686 if (Match.
empty()) {
4688 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,
4689 isParsingIntelSyntax()));
4691 if (Match.
back() == Match_MissingFeature)
4692 ErrorInfoMissingFeatures = MissingFeatures;
4700 if (Match.
back() == Match_MnemonicFail) {
4701 return Error(IDLoc,
"invalid instruction mnemonic '" + Mnemonic +
"'",
4702 Op.getLocRange(), MatchingInlineAsm);
4705 unsigned NumSuccessfulMatches =
llvm::count(Match, Match_Success);
4709 if (UnsizedMemOp && NumSuccessfulMatches > 1 &&
4712 unsigned M = MatchInstruction(
4713 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,
4714 isParsingIntelSyntax());
4715 if (M == Match_Success)
4716 NumSuccessfulMatches = 1;
4728 if (NumSuccessfulMatches == 1) {
4729 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
4734 if (!MatchingInlineAsm)
4735 while (processInstruction(Inst, Operands))
4738 if (!MatchingInlineAsm)
4742 }
else if (NumSuccessfulMatches > 1) {
4744 "multiple matches only possible with unsized memory operands");
4746 "ambiguous operand size for instruction '" + Mnemonic +
"\'",
4752 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4758 if (
llvm::count(Match, Match_MissingFeature) == 1) {
4759 ErrorInfo = Match_MissingFeature;
4760 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
4766 if (
llvm::count(Match, Match_InvalidOperand) == 1) {
4767 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4771 if (
llvm::count(Match, Match_InvalidImmUnsignedi4) == 1) {
4772 SMLoc ErrorLoc = ((X86Operand &)*Operands[ErrorInfo]).getStartLoc();
4773 if (ErrorLoc == SMLoc())
4775 return Error(ErrorLoc,
"immediate must be an integer in range [0, 15]",
4776 EmptyRange, MatchingInlineAsm);
4779 if (
llvm::count(Match, Match_InvalidImmUnsignedi6) == 1) {
4780 SMLoc ErrorLoc = ((X86Operand &)*Operands[ErrorInfo]).getStartLoc();
4781 if (ErrorLoc == SMLoc())
4783 return Error(ErrorLoc,
"immediate must be an integer in range [0, 63]",
4784 EmptyRange, MatchingInlineAsm);
4788 return Error(IDLoc,
"unknown instruction mnemonic", EmptyRange,
4792bool X86AsmParser::omitRegisterFromClobberLists(MCRegister
Reg) {
4793 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(
Reg);
4796bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
4797 MCAsmParser &Parser = getParser();
4800 return parseDirectiveArch();
4802 return ParseDirectiveCode(IDVal, DirectiveID.
getLoc());
4808 return Error(DirectiveID.
getLoc(),
"'.att_syntax noprefix' is not "
4809 "supported: registers must have a "
4810 "'%' prefix in .att_syntax");
4812 getParser().setAssemblerDialect(0);
4815 getParser().setAssemblerDialect(1);
4820 return Error(DirectiveID.
getLoc(),
"'.intel_syntax prefix' is not "
4821 "supported: registers must not have "
4822 "a '%' prefix in .intel_syntax");
4825 }
else if (IDVal ==
".nops")
4826 return parseDirectiveNops(DirectiveID.
getLoc());
4827 else if (IDVal ==
".even")
4828 return parseDirectiveEven(DirectiveID.
getLoc());
4829 else if (IDVal ==
".cv_fpo_proc")
4830 return parseDirectiveFPOProc(DirectiveID.
getLoc());
4831 else if (IDVal ==
".cv_fpo_setframe")
4832 return parseDirectiveFPOSetFrame(DirectiveID.
getLoc());
4833 else if (IDVal ==
".cv_fpo_pushreg")
4834 return parseDirectiveFPOPushReg(DirectiveID.
getLoc());
4835 else if (IDVal ==
".cv_fpo_stackalloc")
4836 return parseDirectiveFPOStackAlloc(DirectiveID.
getLoc());
4837 else if (IDVal ==
".cv_fpo_stackalign")
4838 return parseDirectiveFPOStackAlign(DirectiveID.
getLoc());
4839 else if (IDVal ==
".cv_fpo_endprologue")
4840 return parseDirectiveFPOEndPrologue(DirectiveID.
getLoc());
4841 else if (IDVal ==
".cv_fpo_endproc")
4842 return parseDirectiveFPOEndProc(DirectiveID.
getLoc());
4843 else if (IDVal ==
".seh_pushreg")
4844 return parseDirectiveSEHPushReg(DirectiveID.
getLoc());
4845 else if (IDVal ==
".seh_push2regs")
4846 return parseDirectiveSEHPush2Regs(DirectiveID.
getLoc());
4847 else if (IDVal ==
".seh_setframe")
4848 return parseDirectiveSEHSetFrame(DirectiveID.
getLoc());
4849 else if (IDVal ==
".seh_savereg")
4850 return parseDirectiveSEHSaveReg(DirectiveID.
getLoc());
4851 else if (IDVal ==
".seh_savexmm")
4852 return parseDirectiveSEHSaveXMM(DirectiveID.
getLoc());
4853 else if (IDVal ==
".seh_pushframe")
4854 return parseDirectiveSEHPushFrame(DirectiveID.
getLoc());
4858 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
4859 parseDirectiveSEHPushReg(DirectiveID.
getLoc());
4861 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
4862 parseDirectiveSEHPush2Regs(DirectiveID.
getLoc());
4864 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
4865 parseDirectiveSEHSetFrame(DirectiveID.
getLoc());
4867 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
4868 parseDirectiveSEHSaveReg(DirectiveID.
getLoc());
4870 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
4871 parseDirectiveSEHSaveXMM(DirectiveID.
getLoc());
4873 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
4874 parseDirectiveSEHPushFrame(DirectiveID.
getLoc());
4878 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
4879 parseDirectiveSEHPushReg(DirectiveID.
getLoc());
4883 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
4884 parseDirectiveSEHPush2Regs(DirectiveID.
getLoc(),
4887 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
4888 parseDirectiveSEHSetFrame(DirectiveID.
getLoc());
4890 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
4891 parseDirectiveSEHSaveReg(DirectiveID.
getLoc());
4893 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
4894 parseDirectiveSEHSaveXMM(DirectiveID.
getLoc());
4901bool X86AsmParser::parseDirectiveArch() {
4903 getParser().parseStringToEndOfStatement();
4909bool X86AsmParser::parseDirectiveNops(SMLoc L) {
4910 int64_t NumBytes = 0, Control = 0;
4911 SMLoc NumBytesLoc, ControlLoc;
4912 const MCSubtargetInfo& STI = getSTI();
4913 NumBytesLoc = getTok().getLoc();
4914 if (getParser().checkForValidSection() ||
4915 getParser().parseAbsoluteExpression(NumBytes))
4919 ControlLoc = getTok().getLoc();
4920 if (getParser().parseAbsoluteExpression(Control))
4923 if (getParser().parseEOL())
4926 if (NumBytes <= 0) {
4927 Error(NumBytesLoc,
"'.nops' directive with non-positive size");
4932 Error(ControlLoc,
"'.nops' directive with negative NOP size");
4937 getParser().getStreamer().emitNops(NumBytes, Control, L, STI);
4944bool X86AsmParser::parseDirectiveEven(SMLoc L) {
4948 const MCSection *
Section = getStreamer().getCurrentSectionOnly();
4950 getStreamer().initSections(getSTI());
4951 Section = getStreamer().getCurrentSectionOnly();
4953 if (
getContext().getAsmInfo().useCodeAlign(*Section))
4954 getStreamer().emitCodeAlignment(
Align(2), &getSTI(), 0);
4956 getStreamer().emitValueToAlignment(
Align(2), 0, 1, 0);
4962bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
4963 MCAsmParser &Parser = getParser();
4965 if (IDVal ==
".code16") {
4967 if (!is16BitMode()) {
4968 SwitchMode(X86::Is16Bit);
4969 getTargetStreamer().emitCode16();
4971 }
else if (IDVal ==
".code16gcc") {
4975 if (!is16BitMode()) {
4976 SwitchMode(X86::Is16Bit);
4977 getTargetStreamer().emitCode16();
4979 }
else if (IDVal ==
".code32") {
4981 if (!is32BitMode()) {
4982 SwitchMode(X86::Is32Bit);
4983 getTargetStreamer().emitCode32();
4985 }
else if (IDVal ==
".code64") {
4987 if (!is64BitMode()) {
4988 SwitchMode(X86::Is64Bit);
4989 getTargetStreamer().emitCode64();
4992 Error(L,
"unknown directive " + IDVal);
5000bool X86AsmParser::parseDirectiveFPOProc(SMLoc L) {
5001 MCAsmParser &Parser = getParser();
5005 return Parser.
TokError(
"expected symbol name");
5006 if (Parser.
parseIntToken(ParamsSize,
"expected parameter byte count"))
5009 return Parser.
TokError(
"parameters size out of range");
5013 return getTargetStreamer().emitFPOProc(ProcSym, ParamsSize, L);
5017bool X86AsmParser::parseDirectiveFPOSetFrame(SMLoc L) {
5020 if (parseRegister(
Reg, DummyLoc, DummyLoc) || parseEOL())
5022 return getTargetStreamer().emitFPOSetFrame(
Reg, L);
5026bool X86AsmParser::parseDirectiveFPOPushReg(SMLoc L) {
5029 if (parseRegister(
Reg, DummyLoc, DummyLoc) || parseEOL())
5031 return getTargetStreamer().emitFPOPushReg(
Reg, L);
5035bool X86AsmParser::parseDirectiveFPOStackAlloc(SMLoc L) {
5036 MCAsmParser &Parser = getParser();
5040 return getTargetStreamer().emitFPOStackAlloc(
Offset, L);
5044bool X86AsmParser::parseDirectiveFPOStackAlign(SMLoc L) {
5045 MCAsmParser &Parser = getParser();
5049 return getTargetStreamer().emitFPOStackAlign(
Offset, L);
5053bool X86AsmParser::parseDirectiveFPOEndPrologue(SMLoc L) {
5054 MCAsmParser &Parser = getParser();
5057 return getTargetStreamer().emitFPOEndPrologue(L);
5061bool X86AsmParser::parseDirectiveFPOEndProc(SMLoc L) {
5062 MCAsmParser &Parser = getParser();
5065 return getTargetStreamer().emitFPOEndProc(L);
5068bool X86AsmParser::parseSEHRegisterNumber(
unsigned RegClassID,
5069 MCRegister &RegNo) {
5070 SMLoc startLoc = getLexer().getLoc();
5071 const MCRegisterInfo *MRI =
getContext().getRegisterInfo();
5076 if (parseRegister(RegNo, startLoc, endLoc))
5079 if (!X86MCRegisterClasses[RegClassID].
contains(RegNo)) {
5080 return Error(startLoc,
5081 "register is not supported for use with this directive");
5087 if (getParser().parseAbsoluteExpression(EncodedReg))
5092 RegNo = MCRegister();
5093 for (
MCPhysReg Reg : X86MCRegisterClasses[RegClassID]) {
5100 return Error(startLoc,
5101 "incorrect register number for use with this directive");
5108bool X86AsmParser::parseDirectiveSEHPushReg(SMLoc Loc) {
5110 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5114 return TokError(
"expected end of directive");
5117 getStreamer().emitWinCFIPushReg(
Reg, Loc);
5121bool X86AsmParser::parseDirectiveSEHPush2Regs(SMLoc Loc,
bool SwapRegs) {
5123 if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg1))
5127 return TokError(
"expected comma between registers");
5131 if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg2))
5135 return TokError(
"expected end of directive");
5141 getStreamer().emitWinCFIPush2Regs(Reg1, Reg2, Loc);
5145bool X86AsmParser::parseDirectiveSEHSetFrame(SMLoc Loc) {
5148 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5151 return TokError(
"you must specify a stack pointer offset");
5154 if (getParser().parseAbsoluteExpression(Off))
5158 return TokError(
"expected end of directive");
5161 getStreamer().emitWinCFISetFrame(
Reg, Off, Loc);
5165bool X86AsmParser::parseDirectiveSEHSaveReg(SMLoc Loc) {
5168 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5171 return TokError(
"you must specify an offset on the stack");
5174 if (getParser().parseAbsoluteExpression(Off))
5178 return TokError(
"expected end of directive");
5181 getStreamer().emitWinCFISaveReg(
Reg, Off, Loc);
5185bool X86AsmParser::parseDirectiveSEHSaveXMM(SMLoc Loc) {
5188 if (parseSEHRegisterNumber(X86::VR128XRegClassID,
Reg))
5191 return TokError(
"you must specify an offset on the stack");
5194 if (getParser().parseAbsoluteExpression(Off))
5198 return TokError(
"expected end of directive");
5201 getStreamer().emitWinCFISaveXMM(
Reg, Off, Loc);
5205bool X86AsmParser::ensureMasmPrologContext(SMLoc Loc) {
5206 if (getStreamer().isWinCFIPrologEnded()) {
5207 return Error(Loc,
"prolog directive must be used inside a prolog");
5212bool X86AsmParser::ensureMasmEpilogContext(SMLoc Loc) {
5213 if (!getStreamer().isInEpilogCFI()) {
5214 return Error(Loc,
"epilog directive must be used inside an epilog");
5219bool X86AsmParser::parseDirectiveSEHPushFrame(SMLoc Loc) {
5223 SMLoc startLoc = getLexer().getLoc();
5225 if (!getParser().parseIdentifier(CodeID)) {
5226 if (CodeID !=
"code")
5227 return Error(startLoc,
"expected @code");
5230 }
else if (getParser().isParsingMasm() &&
5232 getTok().getString().equals_insensitive(
"code")) {
5238 return TokError(
"expected end of directive");
5241 getStreamer().emitWinCFIPushFrame(Code, Loc);
5251#define GET_MATCHER_IMPLEMENTATION
5252#include "X86GenAsmMatcher.inc"
static MCRegister MatchRegisterName(StringRef Name)
static const char * getSubtargetFeatureName(uint64_t Val)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
Function Alias Analysis false
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
amode Optimize addressing mode
Value * getPointer(Value *Ptr)
static ModuleSymbolTable::Symbol getSym(DataRefImpl &Symb)
static constexpr Value * getValue(Ty &ValueOrUse)
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static bool IsVCMP(unsigned Opcode)
static constexpr unsigned SM(unsigned Version)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
OptimizedStructLayoutField Field
static StringRef getName(Value *V)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallString class.
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static SymbolRef::Type getType(const Symbol *Sym)
#define LLVM_C_ABI
LLVM_C_ABI is the export/visibility macro used to mark symbols declared in llvm-c as exported when bu...
static cl::opt< bool > LVIInlineAsmHardening("x86-experimental-lvi-inline-asm-hardening", cl::desc("Harden inline assembly code that may be vulnerable to Load Value" " Injection (LVI). This feature is experimental."), cl::Hidden)
static bool checkScale(unsigned Scale, StringRef &ErrMsg)
LLVM_C_ABI void LLVMInitializeX86AsmParser()
static bool convertSSEToAVX(MCInst &Inst)
static unsigned getPrefixes(OperandVector &Operands)
static bool CheckBaseRegAndIndexRegAndScale(MCRegister BaseReg, MCRegister IndexReg, unsigned Scale, bool Is64BitMode, StringRef &ErrMsg)
#define FROM_TO(FROM, TO)
uint16_t RegSizeInBits(const MCRegisterInfo &MRI, MCRegister RegNo)
static unsigned getSize(unsigned Kind)
uint64_t getZExtValue() const
Get zero extended value.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
void UnLex(AsmToken const &Token)
bool isNot(AsmToken::TokenKind K) const
Check if the current token has kind K.
LLVM_ABI SMLoc getLoc() const
int64_t getIntVal() const
bool isNot(TokenKind K) const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
bool is(TokenKind K) const
TokenKind getKind() const
LLVM_ABI SMLoc getEndLoc() const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
constexpr size_t size() const
bool Error(SMLoc L, const Twine &Msg, SMRange Range={})
Return an error at the location L, with the message Msg.
bool parseIntToken(int64_t &V, const Twine &ErrMsg="expected integer")
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual bool isParsingMasm() const
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents.
bool parseOptionalToken(AsmToken::TokenKind T)
Attempt to parse and consume token, returning true on success.
virtual bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc, AsmTypeInfo *TypeInfo=nullptr)=0
Parse a primary expression.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
bool TokError(const Twine &Msg, SMRange Range={})
Report an error at the current lexer location.
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
virtual bool lookUpType(StringRef Name, AsmTypeInfo &Info) const
virtual bool parseAbsoluteExpression(int64_t &Res)=0
Parse an expression which must evaluate to an absolute value.
virtual bool lookUpField(StringRef Name, AsmFieldInfo &Info) const
bool parseTokenLoc(SMLoc &Loc)
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
@ SymbolRef
References to labels and assigned expressions.
Instances of this class represent a single low-level machine instruction.
unsigned getNumOperands() const
unsigned getFlags() const
unsigned getOpcode() const
void setFlags(unsigned F)
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
const MCOperand & getOperand(unsigned i) const
bool mayLoad() const
Return true if this instruction could possibly read memory.
bool isCall() const
Return true if the instruction is a call.
bool isTerminator() const
Returns true if this instruction part of the terminator for a basic block.
static MCOperand createImm(int64_t Val)
MCRegister getReg() const
Returns the register number.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
uint16_t getEncodingValue(MCRegister Reg) const
Returns the encoding for Reg.
Wrapper class representing physical registers. Should be passed by value.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
const FeatureBitset & getFeatureBits() const
const FeatureBitset & ToggleFeature(uint64_t FB)
Toggle a feature and return the re-computed feature bits.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
bool isUndefined() const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
StringRef getName() const
getName - Get the symbol name.
bool isVariable() const
isVariable - Check if this is a variable symbol.
const MCExpr * getVariableValue() const
Get the expression of the variable symbol.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
static constexpr StatusTy Failure
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
constexpr unsigned id() const
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
constexpr bool isValid() const
void push_back(const T &Elt)
Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
static constexpr size_t npos
bool consume_back(StringRef Suffix)
Returns true if this StringRef has the given suffix and removes that suffix.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
LLVM_ABI std::string upper() const
Convert the given ASCII string to uppercase.
char back() const
Get the last character in the string.
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
constexpr size_t size() const
Get the string size.
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
LLVM_ABI std::string lower() const
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
bool consume_front(char Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
StringRef drop_back(size_t N=1) const
Return a StringRef equal to 'this' but with the last N elements dropped.
bool equals_insensitive(StringRef RHS) const
Check for string equality, ignoring case.
static const char * getRegisterName(MCRegister Reg)
static const X86MCExpr * create(MCRegister Reg, MCContext &Ctx)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
std::variant< std::monostate, Loc::Single, Loc::Multi, Loc::MMI, Loc::EntryValue > Variant
Alias for the std::variant specialization base class of DbgVariable.
@ CE
Windows NT (Windows on ARM)
@ X86
Windows x64, Windows Itanium (IA-64)
bool isX86_64NonExtLowByteReg(MCRegister Reg)
@ EVEX
EVEX - Specifies that this instruction use EVEX form which provides syntax support up to 32 512-bit r...
@ VEX
VEX - encoding using 0xC4/0xC5.
@ XOP
XOP - Opcode prefix used by XOP instructions.
@ ExplicitVEXPrefix
For instructions that use VEX encoding only when {vex}, {vex2} or {vex3} is present.
bool canUseApxExtendedReg(const MCInstrDesc &Desc)
bool isX86_64ExtendedReg(MCRegister Reg)
bool isApxExtendedReg(MCRegister Reg)
void emitInstruction(MCObjectStreamer &, const MCInst &Inst, const MCSubtargetInfo &STI)
bool optimizeShiftRotateWithImmediateOne(MCInst &MI)
bool optimizeInstFromVEX3ToVEX2(MCInst &MI, const MCInstrDesc &Desc)
NodeAddr< CodeNode * > Code
Context & getContext() const
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
MCRegister getX86SubSuperRegister(MCRegister Reg, unsigned Size, bool High=false)
Target & getTheX86_32Target()
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
FunctionAddr VTableAddr Next
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
Target & getTheX86_64Target()
StringRef toStringRef(bool B)
Construct a string ref from a boolean.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
bool isKind(IdKind kind) const
SmallVectorImpl< AsmRewrite > * AsmRewrites
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
X86Operand - Instances of this class represent a parsed X86 machine instruction.
SMLoc getStartLoc() const override
getStartLoc - Get the location of the first token of this operand.
bool isImm() const override
isImm - Is this an immediate operand?
static std::unique_ptr< X86Operand > CreateImm(const MCExpr *Val, SMLoc StartLoc, SMLoc EndLoc, StringRef SymName=StringRef(), void *OpDecl=nullptr, bool GlobalRef=true)
static std::unique_ptr< X86Operand > CreatePrefix(unsigned Prefixes, SMLoc StartLoc, SMLoc EndLoc)
static std::unique_ptr< X86Operand > CreateDXReg(SMLoc StartLoc, SMLoc EndLoc)
static std::unique_ptr< X86Operand > CreateReg(MCRegister Reg, SMLoc StartLoc, SMLoc EndLoc, bool AddressOf=false, SMLoc OffsetOfLoc=SMLoc(), StringRef SymName=StringRef(), void *OpDecl=nullptr)
SMRange getLocRange() const
getLocRange - Get the range between the first and last token of this operand.
SMLoc getEndLoc() const override
getEndLoc - Get the location of the last token of this operand.
bool isReg() const override
isReg - Is this a register operand?
bool isMem() const override
isMem - Is this a memory operand?
static std::unique_ptr< X86Operand > CreateMem(unsigned ModeSize, const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc, unsigned Size=0, StringRef SymName=StringRef(), void *OpDecl=nullptr, unsigned FrontendSize=0, bool UseUpRegs=false, bool MaybeDirectBranchDest=true)
Create an absolute memory operand.
static std::unique_ptr< X86Operand > CreateToken(StringRef Str, SMLoc Loc)
bool isMemUnsized() const
const MCExpr * getImm() const
unsigned getMemFrontendSize() const
MCRegister getReg() const override