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;
895 ErrMsg =
"division by zero in assembly expression";
902 ErrMsg =
"modulo by zero in assembly expression";
926 if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
929 return regsUseUpError(ErrMsg);
930 if (NegativeAdditiveTerm) {
931 ErrMsg =
"Scale can't be negative";
941 IC.pushOperand(IC_IMM, TmpInt);
945 PrevState = CurrState;
957 State = IES_MULTIPLY;
958 IC.pushOperator(IC_MULTIPLY);
971 IC.pushOperator(IC_DIVIDE);
984 IC.pushOperator(IC_MOD);
1000 IC.pushOperator(IC_PLUS);
1002 CurType.Size = CurType.ElementSize;
1006 assert(!BracCount &&
"BracCount should be zero on parsing's start");
1015 bool onRBrac(StringRef &ErrMsg) {
1016 IntelExprState CurrState = State;
1025 if (BracCount-- != 1) {
1026 ErrMsg =
"unexpected bracket encountered";
1030 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
1037 return regsUseUpError(ErrMsg);
1038 if (NegativeAdditiveTerm) {
1039 ErrMsg =
"Scale can't be negative";
1046 NegativeAdditiveTerm =
false;
1047 NegativeAdditiveTermLoc = SMLoc();
1050 PrevState = CurrState;
1054 IntelExprState CurrState = State;
1080 IC.pushOperator(IC_LPAREN);
1083 PrevState = CurrState;
1085 bool onRParen(StringRef &ErrMsg) {
1086 IntelExprState CurrState = State;
1101 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
1108 return regsUseUpError(ErrMsg);
1109 if (NegativeAdditiveTerm) {
1110 ErrMsg =
"Scale can't be negative";
1117 IC.pushOperator(IC_RPAREN);
1120 PrevState = CurrState;
1123 bool onOffset(
const MCExpr *Val, SMLoc OffsetLoc, StringRef ID,
1124 const InlineAsmIdentifierInfo &IDInfo,
1125 bool ParsingMSInlineAsm, StringRef &ErrMsg) {
1129 ErrMsg =
"unexpected offset operator expression";
1134 if (setSymRef(Val, ID, ErrMsg))
1136 OffsetOperator =
true;
1137 OffsetOperatorLoc = OffsetLoc;
1141 IC.pushOperand(IC_IMM);
1142 if (ParsingMSInlineAsm) {
1149 void onCast(AsmTypeInfo Info) {
1161 void setTypeInfo(AsmTypeInfo
Type) { CurType =
Type; }
1165 bool MatchingInlineAsm =
false) {
1166 MCAsmParser &Parser = getParser();
1167 if (MatchingInlineAsm) {
1173 bool MatchRegisterByName(MCRegister &RegNo, StringRef
RegName, SMLoc StartLoc,
1175 bool ParseRegister(MCRegister &RegNo, SMLoc &StartLoc, SMLoc &EndLoc,
1176 bool RestoreOnFailure);
1178 std::unique_ptr<X86Operand> DefaultMemSIOperand(SMLoc Loc);
1179 std::unique_ptr<X86Operand> DefaultMemDIOperand(SMLoc Loc);
1180 bool IsSIReg(MCRegister
Reg);
1181 MCRegister GetSIDIForRegClass(
unsigned RegClassID,
bool IsSIReg);
1184 std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
1185 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst);
1190 bool parseIntelOperand(
OperandVector &Operands, StringRef Name);
1191 bool ParseIntelOffsetOperator(
const MCExpr *&Val, StringRef &ID,
1192 InlineAsmIdentifierInfo &Info, SMLoc &End);
1193 bool ParseIntelDotOperator(IntelExprStateMachine &
SM, SMLoc &End);
1194 unsigned IdentifyIntelInlineAsmOperator(StringRef Name);
1195 unsigned ParseIntelInlineAsmOperator(
unsigned OpKind);
1196 unsigned IdentifyMasmOperator(StringRef Name);
1197 bool ParseMasmOperator(
unsigned OpKind, int64_t &Val);
1198 bool ParseRoundingModeOp(SMLoc Start,
OperandVector &Operands);
1200 bool ParseIntelNamedOperator(StringRef Name, IntelExprStateMachine &
SM,
1201 bool &ParseError, SMLoc &End);
1202 bool ParseMasmNamedOperator(StringRef Name, IntelExprStateMachine &
SM,
1203 bool &ParseError, SMLoc &End);
1204 void RewriteIntelExpression(IntelExprStateMachine &
SM, SMLoc Start,
1206 bool ParseIntelExpression(IntelExprStateMachine &
SM, SMLoc &End);
1207 bool ParseIntelInlineAsmIdentifier(
const MCExpr *&Val, StringRef &Identifier,
1208 InlineAsmIdentifierInfo &Info,
1209 bool IsUnevaluatedOperand, SMLoc &End,
1210 bool IsParsingOffsetOperator =
false);
1212 IntelExprStateMachine &
SM);
1214 bool CheckDispOverflow(MCRegister BaseReg, MCRegister IndexReg,
1215 const MCExpr *Disp, SMLoc Loc);
1217 bool ParseMemOperand(MCRegister SegReg,
const MCExpr *Disp, SMLoc StartLoc,
1222 bool ParseIntelMemoryOperandSize(
unsigned &
Size, StringRef *SizeStr);
1223 bool CreateMemForMSInlineAsm(MCRegister SegReg,
const MCExpr *Disp,
1224 MCRegister BaseReg, MCRegister IndexReg,
1225 unsigned Scale,
bool NonAbsMem, SMLoc Start,
1226 SMLoc End,
unsigned Size, StringRef Identifier,
1227 const InlineAsmIdentifierInfo &Info,
1230 bool parseDirectiveArch();
1231 bool parseDirectiveNops(SMLoc L);
1232 bool parseDirectiveEven(SMLoc L);
1233 bool ParseDirectiveCode(StringRef IDVal, SMLoc L);
1236 bool parseDirectiveFPOProc(SMLoc L);
1237 bool parseDirectiveFPOSetFrame(SMLoc L);
1238 bool parseDirectiveFPOPushReg(SMLoc L);
1239 bool parseDirectiveFPOStackAlloc(SMLoc L);
1240 bool parseDirectiveFPOStackAlign(SMLoc L);
1241 bool parseDirectiveFPOEndPrologue(SMLoc L);
1242 bool parseDirectiveFPOEndProc(SMLoc L);
1245 bool parseSEHRegisterNumber(
unsigned RegClassID, MCRegister &RegNo);
1246 bool parseDirectiveSEHPushReg(SMLoc);
1247 bool parseDirectiveSEHPush2Regs(SMLoc,
bool SwapRegs =
false);
1248 bool parseDirectiveSEHSetFrame(SMLoc);
1249 bool parseDirectiveSEHSaveReg(SMLoc);
1250 bool parseDirectiveSEHSaveXMM(SMLoc);
1251 bool parseDirectiveSEHPushFrame(SMLoc);
1253 bool ensureMasmEpilogContext(SMLoc Loc);
1254 bool ensureMasmPrologContext(SMLoc Loc);
1256 unsigned checkTargetMatchPredicate(MCInst &Inst)
override;
1262 void emitWarningForSpecialLVIInstruction(SMLoc Loc);
1263 void applyLVICFIMitigation(MCInst &Inst, MCStreamer &Out);
1264 void applyLVILoadHardeningMitigation(MCInst &Inst, MCStreamer &Out);
1270 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1272 uint64_t &ErrorInfo,
1273 bool MatchingInlineAsm)
override;
1275 void MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &
Op,
OperandVector &Operands,
1276 MCStreamer &Out,
bool MatchingInlineAsm);
1278 bool ErrorMissingFeature(SMLoc IDLoc,
const FeatureBitset &MissingFeatures,
1279 bool MatchingInlineAsm);
1281 bool matchAndEmitATTInstruction(SMLoc IDLoc,
unsigned &Opcode, MCInst &Inst,
1283 uint64_t &ErrorInfo,
bool MatchingInlineAsm);
1285 bool matchAndEmitIntelInstruction(SMLoc IDLoc,
unsigned &Opcode, MCInst &Inst,
1287 uint64_t &ErrorInfo,
1288 bool MatchingInlineAsm);
1290 bool omitRegisterFromClobberLists(MCRegister
Reg)
override;
1297 bool ParseZ(std::unique_ptr<X86Operand> &Z, SMLoc StartLoc);
1299 bool is64BitMode()
const {
1301 return getSTI().hasFeature(X86::Is64Bit);
1303 bool is32BitMode()
const {
1305 return getSTI().hasFeature(X86::Is32Bit);
1307 bool is16BitMode()
const {
1309 return getSTI().hasFeature(X86::Is16Bit);
1311 void SwitchMode(
unsigned mode) {
1312 MCSubtargetInfo &STI = copySTI();
1313 FeatureBitset AllModes({X86::Is64Bit, X86::Is32Bit, X86::Is16Bit});
1315 FeatureBitset FB = ComputeAvailableFeatures(
1317 setAvailableFeatures(FB);
1322 unsigned getPointerWidth() {
1323 if (is16BitMode())
return 16;
1324 if (is32BitMode())
return 32;
1325 if (is64BitMode())
return 64;
1329 bool isParsingIntelSyntax() {
1330 return getParser().getAssemblerDialect();
1336#define GET_ASSEMBLER_HEADER
1337#include "X86GenAsmMatcher.inc"
1342 enum X86MatchResultTy {
1343 Match_Unsupported = FIRST_TARGET_MATCH_RESULT_TY,
1344#define GET_OPERAND_DIAGNOSTIC_TYPES
1345#include "X86GenAsmMatcher.inc"
1348 X86AsmParser(
const MCSubtargetInfo &sti, MCAsmParser &Parser,
1349 const MCInstrInfo &mii)
1350 : MCTargetAsmParser(sti, mii), InstInfo(nullptr), Code16GCC(
false) {
1355 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
1358 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
1359 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1360 SMLoc &EndLoc)
override;
1362 bool parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc)
override;
1364 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
1367 bool ParseDirective(AsmToken DirectiveID)
override;
1371#define GET_REGISTER_MATCHER
1372#define GET_SUBTARGET_FEATURE_NAME
1373#include "X86GenAsmMatcher.inc"
1384 !(BaseReg == X86::RIP || BaseReg == X86::EIP ||
1385 getX86MCRegisterClass(X86::GR16RegClassID).
contains(BaseReg) ||
1386 getX86MCRegisterClass(X86::GR32RegClassID).
contains(BaseReg) ||
1387 getX86MCRegisterClass(X86::GR64RegClassID).
contains(BaseReg))) {
1388 ErrMsg =
"invalid base+index expression";
1393 !(IndexReg == X86::EIZ || IndexReg == X86::RIZ ||
1394 getX86MCRegisterClass(X86::GR16RegClassID).
contains(IndexReg) ||
1395 getX86MCRegisterClass(X86::GR32RegClassID).
contains(IndexReg) ||
1396 getX86MCRegisterClass(X86::GR64RegClassID).
contains(IndexReg) ||
1397 getX86MCRegisterClass(X86::VR128XRegClassID).
contains(IndexReg) ||
1398 getX86MCRegisterClass(X86::VR256XRegClassID).
contains(IndexReg) ||
1399 getX86MCRegisterClass(X86::VR512RegClassID).
contains(IndexReg))) {
1400 ErrMsg =
"invalid base+index expression";
1404 if (((BaseReg == X86::RIP || BaseReg == X86::EIP) && IndexReg) ||
1405 IndexReg == X86::EIP || IndexReg == X86::RIP || IndexReg == X86::ESP ||
1406 IndexReg == X86::RSP) {
1407 ErrMsg =
"invalid base+index expression";
1413 if (getX86MCRegisterClass(X86::GR16RegClassID).
contains(BaseReg) &&
1414 (Is64BitMode || (BaseReg != X86::BX && BaseReg != X86::BP &&
1415 BaseReg != X86::SI && BaseReg != X86::DI))) {
1416 ErrMsg =
"invalid 16-bit base register";
1421 getX86MCRegisterClass(X86::GR16RegClassID).
contains(IndexReg)) {
1422 ErrMsg =
"16-bit memory operand may not include only index register";
1426 if (BaseReg && IndexReg) {
1427 if (getX86MCRegisterClass(X86::GR64RegClassID).
contains(BaseReg) &&
1428 (getX86MCRegisterClass(X86::GR16RegClassID).
contains(IndexReg) ||
1429 getX86MCRegisterClass(X86::GR32RegClassID).
contains(IndexReg) ||
1430 IndexReg == X86::EIZ)) {
1431 ErrMsg =
"base register is 64-bit, but index register is not";
1434 if (getX86MCRegisterClass(X86::GR32RegClassID).
contains(BaseReg) &&
1435 (getX86MCRegisterClass(X86::GR16RegClassID).
contains(IndexReg) ||
1436 getX86MCRegisterClass(X86::GR64RegClassID).
contains(IndexReg) ||
1437 IndexReg == X86::RIZ)) {
1438 ErrMsg =
"base register is 32-bit, but index register is not";
1441 if (getX86MCRegisterClass(X86::GR16RegClassID).
contains(BaseReg)) {
1442 if (getX86MCRegisterClass(X86::GR32RegClassID).
contains(IndexReg) ||
1443 getX86MCRegisterClass(X86::GR64RegClassID).
contains(IndexReg)) {
1444 ErrMsg =
"base register is 16-bit, but index register is not";
1447 if ((BaseReg != X86::BX && BaseReg != X86::BP) ||
1448 (IndexReg != X86::SI && IndexReg != X86::DI)) {
1449 ErrMsg =
"invalid 16-bit base/index register combination";
1456 if (!Is64BitMode && (BaseReg == X86::RIP || BaseReg == X86::EIP)) {
1457 ErrMsg =
"IP-relative addressing requires 64-bit mode";
1478 if (isParsingMSInlineAsm() && isParsingIntelSyntax() &&
1479 (RegNo == X86::EFLAGS || RegNo == X86::MXCSR))
1480 RegNo = MCRegister();
1482 if (!is64BitMode()) {
1486 if (RegNo == X86::RIZ || RegNo == X86::RIP ||
1487 getX86MCRegisterClass(X86::GR64RegClassID).
contains(RegNo) ||
1490 return Error(StartLoc,
1491 "register %" +
RegName +
" is only available in 64-bit mode",
1492 SMRange(StartLoc, EndLoc));
1497 UseApxExtendedReg =
true;
1501 if (!RegNo &&
RegName.starts_with(
"db")) {
1560 if (isParsingIntelSyntax())
1562 return Error(StartLoc,
"invalid register name", SMRange(StartLoc, EndLoc));
1567bool X86AsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
1568 SMLoc &EndLoc,
bool RestoreOnFailure) {
1569 MCAsmParser &Parser = getParser();
1570 AsmLexer &Lexer = getLexer();
1571 RegNo = MCRegister();
1574 auto OnFailure = [RestoreOnFailure, &Lexer, &Tokens]() {
1575 if (RestoreOnFailure) {
1576 while (!Tokens.
empty()) {
1582 const AsmToken &PercentTok = Parser.
getTok();
1583 StartLoc = PercentTok.
getLoc();
1592 const AsmToken &Tok = Parser.
getTok();
1597 if (isParsingIntelSyntax())
return true;
1598 return Error(StartLoc,
"invalid register name",
1599 SMRange(StartLoc, EndLoc));
1602 if (MatchRegisterByName(RegNo, Tok.
getString(), StartLoc, EndLoc)) {
1608 if (RegNo == X86::ST0) {
1619 const AsmToken &IntTok = Parser.
getTok();
1622 return Error(IntTok.
getLoc(),
"expected stack index");
1625 case 0: RegNo = X86::ST0;
break;
1626 case 1: RegNo = X86::ST1;
break;
1627 case 2: RegNo = X86::ST2;
break;
1628 case 3: RegNo = X86::ST3;
break;
1629 case 4: RegNo = X86::ST4;
break;
1630 case 5: RegNo = X86::ST5;
break;
1631 case 6: RegNo = X86::ST6;
break;
1632 case 7: RegNo = X86::ST7;
break;
1635 return Error(IntTok.
getLoc(),
"invalid stack index");
1655 if (isParsingIntelSyntax())
return true;
1656 return Error(StartLoc,
"invalid register name",
1657 SMRange(StartLoc, EndLoc));
1664bool X86AsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1666 return ParseRegister(
Reg, StartLoc, EndLoc,
false);
1669ParseStatus X86AsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1671 bool Result = ParseRegister(
Reg, StartLoc, EndLoc,
true);
1672 bool PendingErrors = getParser().hasPendingError();
1673 getParser().clearPendingErrors();
1681std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(SMLoc Loc) {
1682 bool Parse32 = is32BitMode() || Code16GCC;
1683 MCRegister Basereg =
1684 is64BitMode() ? X86::RSI : (Parse32 ? X86::ESI : X86::SI);
1691std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand(SMLoc Loc) {
1692 bool Parse32 = is32BitMode() || Code16GCC;
1693 MCRegister Basereg =
1694 is64BitMode() ? X86::RDI : (Parse32 ? X86::EDI : X86::DI);
1701bool X86AsmParser::IsSIReg(MCRegister
Reg) {
1715MCRegister X86AsmParser::GetSIDIForRegClass(
unsigned RegClassID,
bool IsSIReg) {
1716 switch (RegClassID) {
1718 case X86::GR64RegClassID:
1719 return IsSIReg ? X86::RSI : X86::RDI;
1720 case X86::GR32RegClassID:
1721 return IsSIReg ? X86::ESI : X86::EDI;
1722 case X86::GR16RegClassID:
1723 return IsSIReg ? X86::SI : X86::DI;
1727void X86AsmParser::AddDefaultSrcDestOperands(
1728 OperandVector& Operands, std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
1729 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst) {
1730 if (isParsingIntelSyntax()) {
1740bool X86AsmParser::VerifyAndAdjustOperands(
OperandVector &OrigOperands,
1743 if (OrigOperands.
size() > 1) {
1746 "Operand size mismatch");
1750 int RegClassID = -1;
1751 for (
unsigned int i = 0; i < FinalOperands.
size(); ++i) {
1752 X86Operand &OrigOp =
static_cast<X86Operand &
>(*OrigOperands[i + 1]);
1753 X86Operand &FinalOp =
static_cast<X86Operand &
>(*FinalOperands[i]);
1755 if (FinalOp.
isReg() &&
1760 if (FinalOp.
isMem()) {
1762 if (!OrigOp.
isMem())
1771 if (RegClassID != -1 &&
1772 !getX86MCRegisterClass(RegClassID).
contains(OrigReg)) {
1774 "mismatching source and destination index registers");
1777 if (getX86MCRegisterClass(X86::GR64RegClassID).
contains(OrigReg))
1778 RegClassID = X86::GR64RegClassID;
1779 else if (getX86MCRegisterClass(X86::GR32RegClassID).
contains(OrigReg))
1780 RegClassID = X86::GR32RegClassID;
1781 else if (getX86MCRegisterClass(X86::GR16RegClassID).
contains(OrigReg))
1782 RegClassID = X86::GR16RegClassID;
1788 bool IsSI = IsSIReg(FinalReg);
1789 FinalReg = GetSIDIForRegClass(RegClassID, IsSI);
1791 if (FinalReg != OrigReg) {
1792 std::string
RegName = IsSI ?
"ES:(R|E)SI" :
"ES:(R|E)DI";
1795 "memory operand is only for determining the size, " +
RegName +
1796 " will be used for the location"));
1807 for (
auto &WarningMsg : Warnings) {
1808 Warning(WarningMsg.first, WarningMsg.second);
1812 for (
unsigned int i = 0; i < FinalOperands.
size(); ++i)
1816 for (
auto &
Op : FinalOperands)
1822bool X86AsmParser::parseOperand(
OperandVector &Operands, StringRef Name) {
1823 if (isParsingIntelSyntax())
1824 return parseIntelOperand(Operands, Name);
1826 return parseATTOperand(Operands);
1829bool X86AsmParser::CreateMemForMSInlineAsm(
1830 MCRegister SegReg,
const MCExpr *Disp, MCRegister BaseReg,
1831 MCRegister IndexReg,
unsigned Scale,
bool NonAbsMem, SMLoc Start, SMLoc End,
1832 unsigned Size, StringRef Identifier,
const InlineAsmIdentifierInfo &Info,
1840 End,
Size, Identifier,
1847 unsigned FrontendSize = 0;
1848 void *Decl =
nullptr;
1849 bool IsGlobalLV =
false;
1852 FrontendSize =
Info.Var.Type * 8;
1853 Decl =
Info.Var.Decl;
1854 IsGlobalLV =
Info.Var.IsGlobalLV;
1859 if (BaseReg || IndexReg) {
1861 End,
Size, Identifier, Decl, 0,
1862 BaseReg && IndexReg));
1869 getPointerWidth(), SegReg, Disp, BaseReg, IndexReg, Scale, Start, End,
1871 X86::RIP, Identifier, Decl, FrontendSize));
1878bool X86AsmParser::ParseIntelNamedOperator(StringRef Name,
1879 IntelExprStateMachine &
SM,
1880 bool &ParseError, SMLoc &End) {
1883 if (Name !=
Name.lower() && Name !=
Name.upper() &&
1884 !getParser().isParsingMasm())
1886 if (
Name.equals_insensitive(
"not")) {
1888 }
else if (
Name.equals_insensitive(
"or")) {
1890 }
else if (
Name.equals_insensitive(
"shl")) {
1892 }
else if (
Name.equals_insensitive(
"shr")) {
1894 }
else if (
Name.equals_insensitive(
"xor")) {
1896 }
else if (
Name.equals_insensitive(
"and")) {
1898 }
else if (
Name.equals_insensitive(
"mod")) {
1900 }
else if (
Name.equals_insensitive(
"offset")) {
1901 SMLoc OffsetLoc = getTok().getLoc();
1902 const MCExpr *Val =
nullptr;
1904 InlineAsmIdentifierInfo
Info;
1905 ParseError = ParseIntelOffsetOperator(Val, ID, Info, End);
1910 SM.onOffset(Val, OffsetLoc, ID, Info, isParsingMSInlineAsm(), ErrMsg);
1916 if (!
Name.equals_insensitive(
"offset"))
1917 End = consumeToken();
1920bool X86AsmParser::ParseMasmNamedOperator(StringRef Name,
1921 IntelExprStateMachine &
SM,
1922 bool &ParseError, SMLoc &End) {
1923 if (
Name.equals_insensitive(
"eq")) {
1925 }
else if (
Name.equals_insensitive(
"ne")) {
1927 }
else if (
Name.equals_insensitive(
"lt")) {
1929 }
else if (
Name.equals_insensitive(
"le")) {
1931 }
else if (
Name.equals_insensitive(
"gt")) {
1933 }
else if (
Name.equals_insensitive(
"ge")) {
1938 End = consumeToken();
1945 IntelExprStateMachine &
SM) {
1949 SM.setAppendAfterOperand();
1952bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &
SM, SMLoc &End) {
1953 MCAsmParser &Parser = getParser();
1958 if (
getContext().getObjectFileInfo()->isPositionIndependent())
1965 const AsmToken &Tok = Parser.
getTok();
1967 bool UpdateLocLex =
true;
1972 if ((
Done =
SM.isValidEndState()))
1974 return Error(Tok.
getLoc(),
"unknown token in expression");
1976 return Error(getLexer().getErrLoc(), getLexer().getErr());
1980 UpdateLocLex =
false;
1981 if (ParseIntelDotOperator(
SM, End))
1986 if ((
Done =
SM.isValidEndState()))
1988 return Error(Tok.
getLoc(),
"unknown token in expression");
1992 UpdateLocLex =
false;
1993 if (ParseIntelDotOperator(
SM, End))
1998 if ((
Done =
SM.isValidEndState()))
2000 return Error(Tok.
getLoc(),
"unknown token in expression");
2006 SMLoc ValueLoc = Tok.
getLoc();
2011 UpdateLocLex =
false;
2012 if (!Val->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
2013 return Error(ValueLoc,
"expected absolute value");
2014 if (
SM.onInteger(Res, ErrMsg))
2015 return Error(
SM.getErrorLoc(ValueLoc), ErrMsg);
2022 SMLoc IdentLoc = Tok.
getLoc();
2024 UpdateLocLex =
false;
2026 size_t DotOffset =
Identifier.find_first_of(
'.');
2030 StringRef Dot =
Identifier.substr(DotOffset, 1);
2044 const AsmToken &NextTok = getLexer().peekTok();
2053 End = consumeToken();
2060 if (!ParseRegister(
Reg, IdentLoc, End,
true)) {
2061 if (
SM.onRegister(
Reg, ErrMsg))
2062 return Error(
SM.getErrorLoc(IdentLoc), ErrMsg);
2066 const std::pair<StringRef, StringRef> IDField =
2068 const StringRef
ID = IDField.first,
Field = IDField.second;
2070 if (!
Field.empty() &&
2071 !MatchRegisterByName(
Reg, ID, IdentLoc, IDEndLoc)) {
2072 if (
SM.onRegister(
Reg, ErrMsg))
2073 return Error(
SM.getErrorLoc(IdentLoc), ErrMsg);
2078 return Error(FieldStartLoc,
"unknown offset");
2079 else if (
SM.onPlus(ErrMsg))
2080 return Error(getTok().getLoc(), ErrMsg);
2081 else if (
SM.onInteger(
Info.Offset, ErrMsg))
2082 return Error(
SM.getErrorLoc(IdentLoc), ErrMsg);
2083 SM.setTypeInfo(
Info.Type);
2085 End = consumeToken();
2092 if (ParseIntelNamedOperator(Identifier,
SM, ParseError, End)) {
2098 ParseMasmNamedOperator(Identifier,
SM, ParseError, End)) {
2104 InlineAsmIdentifierInfo
Info;
2105 AsmFieldInfo FieldInfo;
2111 if (ParseIntelDotOperator(
SM, End))
2116 if (isParsingMSInlineAsm()) {
2118 if (
unsigned OpKind = IdentifyIntelInlineAsmOperator(Identifier)) {
2119 if (int64_t Val = ParseIntelInlineAsmOperator(OpKind)) {
2120 if (
SM.onInteger(Val, ErrMsg))
2121 return Error(
SM.getErrorLoc(IdentLoc), ErrMsg);
2130 return Error(IdentLoc,
"expected identifier");
2131 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
false, End))
2133 else if (
SM.onIdentifierExpr(Val, Identifier, Info, FieldInfo.
Type,
2135 return Error(
SM.getErrorLoc(IdentLoc), ErrMsg);
2139 if (
unsigned OpKind = IdentifyMasmOperator(Identifier)) {
2141 if (ParseMasmOperator(OpKind, Val))
2143 if (
SM.onInteger(Val, ErrMsg))
2144 return Error(
SM.getErrorLoc(IdentLoc), ErrMsg);
2147 if (!getParser().lookUpType(Identifier, FieldInfo.
Type)) {
2153 getParser().parseIdentifier(Identifier);
2157 if (getParser().lookUpField(FieldInfo.
Type.
Name, Identifier,
2161 return Error(IdentLoc,
"Unable to lookup field reference!",
2162 SMRange(IdentLoc, IDEnd));
2167 if (
SM.onInteger(FieldInfo.
Offset, ErrMsg))
2168 return Error(
SM.getErrorLoc(IdentLoc), ErrMsg);
2172 if (getParser().parsePrimaryExpr(Val, End, &FieldInfo.
Type)) {
2173 return Error(Tok.
getLoc(),
"Unexpected identifier!");
2174 }
else if (
SM.onIdentifierExpr(Val, Identifier, Info, FieldInfo.
Type,
2176 return Error(
SM.getErrorLoc(IdentLoc), ErrMsg);
2182 SMLoc Loc = getTok().getLoc();
2183 int64_t
IntVal = getTok().getIntVal();
2184 End = consumeToken();
2185 UpdateLocLex =
false;
2187 StringRef IDVal = getTok().getString();
2188 if (IDVal ==
"f" || IDVal ==
"b") {
2190 getContext().getDirectionalLocalSymbol(IntVal, IDVal ==
"b");
2195 return Error(Loc,
"invalid reference to undefined symbol");
2197 InlineAsmIdentifierInfo
Info;
2199 if (
SM.onIdentifierExpr(Val, Identifier, Info,
Type,
2200 isParsingMSInlineAsm(), ErrMsg))
2201 return Error(
SM.getErrorLoc(Loc), ErrMsg);
2202 End = consumeToken();
2204 if (
SM.onInteger(IntVal, ErrMsg))
2205 return Error(
SM.getErrorLoc(Loc), ErrMsg);
2208 if (
SM.onInteger(IntVal, ErrMsg))
2209 return Error(
SM.getErrorLoc(Loc), ErrMsg);
2214 if (
SM.onPlus(ErrMsg))
2215 return Error(getTok().getLoc(), ErrMsg);
2218 if (
SM.onMinus(getTok().getLoc(), ErrMsg))
2219 return Error(
SM.getErrorLoc(getTok().getLoc()), ErrMsg);
2229 SM.onLShift();
break;
2231 SM.onRShift();
break;
2234 return Error(Tok.
getLoc(),
"unexpected bracket encountered");
2235 tryParseOperandIdx(PrevTK,
SM);
2238 if (
SM.onRBrac(ErrMsg)) {
2244 if (
SM.onRParen(ErrMsg)) {
2250 return Error(Tok.
getLoc(),
"unknown token in expression");
2252 if (!
Done && UpdateLocLex)
2253 End = consumeToken();
2260void X86AsmParser::RewriteIntelExpression(IntelExprStateMachine &
SM,
2261 SMLoc Start, SMLoc End) {
2265 if (
SM.getSym() && !
SM.isOffsetOperator()) {
2266 StringRef SymName =
SM.getSymName();
2267 if (
unsigned Len = SymName.
data() -
Start.getPointer())
2273 if (!(
SM.getBaseReg() ||
SM.getIndexReg() ||
SM.getImm())) {
2280 StringRef BaseRegStr;
2281 StringRef IndexRegStr;
2282 StringRef OffsetNameStr;
2283 if (
SM.getBaseReg())
2285 if (
SM.getIndexReg())
2287 if (
SM.isOffsetOperator())
2288 OffsetNameStr =
SM.getSymName();
2290 IntelExpr Expr(BaseRegStr, IndexRegStr,
SM.getScale(), OffsetNameStr,
2291 SM.getImm(),
SM.isMemExpr());
2292 InstInfo->
AsmRewrites->emplace_back(Loc, ExprLen, Expr);
2296bool X86AsmParser::ParseIntelInlineAsmIdentifier(
2297 const MCExpr *&Val, StringRef &Identifier, InlineAsmIdentifierInfo &Info,
2298 bool IsUnevaluatedOperand, SMLoc &End,
bool IsParsingOffsetOperator) {
2299 MCAsmParser &Parser = getParser();
2300 assert(isParsingMSInlineAsm() &&
"Expected to be parsing inline assembly.");
2304 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);
2306 const AsmToken &Tok = Parser.
getTok();
2307 SMLoc Loc = Tok.
getLoc();
2322 "frontend claimed part of a token?");
2327 StringRef InternalName =
2328 SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(),
2330 assert(InternalName.
size() &&
"We should have an internal name here.");
2333 if (!IsParsingOffsetOperator)
2348bool X86AsmParser::ParseRoundingModeOp(SMLoc Start,
OperandVector &Operands) {
2349 MCAsmParser &Parser = getParser();
2350 const AsmToken &Tok = Parser.
getTok();
2352 const SMLoc consumedToken = consumeToken();
2354 return Error(Tok.
getLoc(),
"Expected an identifier after {");
2357 .Case(
"rn", X86::STATIC_ROUNDING::TO_NEAREST_INT)
2358 .Case(
"rd", X86::STATIC_ROUNDING::TO_NEG_INF)
2359 .Case(
"ru", X86::STATIC_ROUNDING::TO_POS_INF)
2360 .Case(
"rz", X86::STATIC_ROUNDING::TO_ZERO)
2363 return Error(Tok.
getLoc(),
"Invalid rounding mode.");
2366 return Error(Tok.
getLoc(),
"Expected - at this point");
2370 return Error(Tok.
getLoc(),
"Expected } at this point");
2373 const MCExpr *RndModeOp =
2381 return Error(Tok.
getLoc(),
"Expected } at this point");
2386 return Error(Tok.
getLoc(),
"unknown token in expression");
2392 MCAsmParser &Parser = getParser();
2393 AsmToken Tok = Parser.
getTok();
2396 return Error(Tok.
getLoc(),
"Expected { at this point");
2400 return Error(Tok.
getLoc(),
"Expected dfv at this point");
2404 return Error(Tok.
getLoc(),
"Expected = at this point");
2416 unsigned CFlags = 0;
2417 for (
unsigned I = 0;
I < 4; ++
I) {
2426 return Error(Tok.
getLoc(),
"Invalid conditional flags");
2429 return Error(Tok.
getLoc(),
"Duplicated conditional flag");
2440 }
else if (
I == 3) {
2441 return Error(Tok.
getLoc(),
"Expected } at this point");
2443 return Error(Tok.
getLoc(),
"Expected } or , at this point");
2451bool X86AsmParser::ParseIntelDotOperator(IntelExprStateMachine &
SM,
2453 const AsmToken &Tok = getTok();
2459 bool TrailingDot =
false;
2467 }
else if ((isParsingMSInlineAsm() || getParser().isParsingMasm()) &&
2470 const std::pair<StringRef, StringRef> BaseMember = DotDispStr.
split(
'.');
2471 const StringRef
Base = BaseMember.first,
Member = BaseMember.second;
2472 if (getParser().lookUpField(
SM.getType(), DotDispStr, Info) &&
2473 getParser().lookUpField(
SM.getSymName(), DotDispStr, Info) &&
2474 getParser().lookUpField(DotDispStr, Info) &&
2476 SemaCallback->LookupInlineAsmField(
Base, Member,
Info.Offset)))
2477 return Error(Tok.
getLoc(),
"Unable to lookup field reference!");
2479 return Error(Tok.
getLoc(),
"Unexpected token type!");
2484 const char *DotExprEndLoc = DotDispStr.
data() + DotDispStr.
size();
2490 SM.setTypeInfo(
Info.Type);
2496bool X86AsmParser::ParseIntelOffsetOperator(
const MCExpr *&Val, StringRef &ID,
2497 InlineAsmIdentifierInfo &Info,
2500 SMLoc
Start = Lex().getLoc();
2501 ID = getTok().getString();
2502 if (!isParsingMSInlineAsm()) {
2505 getParser().parsePrimaryExpr(Val, End,
nullptr))
2506 return Error(Start,
"unexpected token!");
2507 }
else if (ParseIntelInlineAsmIdentifier(Val, ID, Info,
false, End,
true)) {
2508 return Error(Start,
"unable to lookup expression");
2510 return Error(Start,
"offset operator cannot yet handle constants");
2517unsigned X86AsmParser::IdentifyIntelInlineAsmOperator(StringRef Name) {
2518 return StringSwitch<unsigned>(Name)
2519 .Cases({
"TYPE",
"type"}, IOK_TYPE)
2520 .Cases({
"SIZE",
"size"}, IOK_SIZE)
2521 .Cases({
"LENGTH",
"length"}, IOK_LENGTH)
2531unsigned X86AsmParser::ParseIntelInlineAsmOperator(
unsigned OpKind) {
2532 MCAsmParser &Parser = getParser();
2533 const AsmToken &Tok = Parser.
getTok();
2536 const MCExpr *Val =
nullptr;
2537 InlineAsmIdentifierInfo
Info;
2540 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
2545 Error(Start,
"unable to lookup expression");
2552 case IOK_LENGTH: CVal =
Info.Var.Length;
break;
2553 case IOK_SIZE: CVal =
Info.Var.Size;
break;
2554 case IOK_TYPE: CVal =
Info.Var.Type;
break;
2562unsigned X86AsmParser::IdentifyMasmOperator(StringRef Name) {
2563 return StringSwitch<unsigned>(
Name.lower())
2564 .Case(
"type", MOK_TYPE)
2565 .Cases({
"size",
"sizeof"}, MOK_SIZEOF)
2566 .Cases({
"length",
"lengthof"}, MOK_LENGTHOF)
2576bool X86AsmParser::ParseMasmOperator(
unsigned OpKind, int64_t &Val) {
2577 MCAsmParser &Parser = getParser();
2582 if (OpKind == MOK_SIZEOF || OpKind == MOK_TYPE) {
2585 const AsmToken &IDTok = InParens ? getLexer().peekTok() : Parser.
getTok();
2601 IntelExprStateMachine
SM;
2603 if (ParseIntelExpression(
SM, End))
2613 Val =
SM.getLength();
2616 Val =
SM.getElementSize();
2621 return Error(OpLoc,
"expression has unknown type", SMRange(Start, End));
2627bool X86AsmParser::ParseIntelMemoryOperandSize(
unsigned &
Size,
2628 StringRef *SizeStr) {
2629 Size = StringSwitch<unsigned>(getTok().getString())
2630 .Cases({
"BYTE",
"byte"}, 8)
2631 .Cases({
"WORD",
"word"}, 16)
2632 .Cases({
"DWORD",
"dword"}, 32)
2633 .Cases({
"FLOAT",
"float"}, 32)
2634 .Cases({
"LONG",
"long"}, 32)
2635 .Cases({
"FWORD",
"fword"}, 48)
2636 .Cases({
"DOUBLE",
"double"}, 64)
2637 .Cases({
"QWORD",
"qword"}, 64)
2638 .Cases({
"MMWORD",
"mmword"}, 64)
2639 .Cases({
"XWORD",
"xword"}, 80)
2640 .Cases({
"TBYTE",
"tbyte"}, 80)
2641 .Cases({
"XMMWORD",
"xmmword"}, 128)
2642 .Cases({
"YMMWORD",
"ymmword"}, 256)
2643 .Cases({
"ZMMWORD",
"zmmword"}, 512)
2647 *SizeStr = getTok().getString();
2648 const AsmToken &Tok = Lex();
2650 return Error(Tok.
getLoc(),
"Expected 'PTR' or 'ptr' token!");
2657 if (getX86MCRegisterClass(X86::GR8RegClassID).
contains(RegNo))
2659 if (getX86MCRegisterClass(X86::GR16RegClassID).
contains(RegNo))
2661 if (getX86MCRegisterClass(X86::GR32RegClassID).
contains(RegNo))
2663 if (getX86MCRegisterClass(X86::GR64RegClassID).
contains(RegNo))
2669bool X86AsmParser::parseIntelOperand(
OperandVector &Operands, StringRef Name) {
2670 MCAsmParser &Parser = getParser();
2671 const AsmToken &Tok = Parser.
getTok();
2677 if (ParseIntelMemoryOperandSize(
Size, &SizeStr))
2679 bool PtrInOperand = bool(
Size);
2685 return ParseRoundingModeOp(Start, Operands);
2690 if (RegNo == X86::RIP)
2691 return Error(Start,
"rip can only be used as a base register");
2696 return Error(Start,
"expected memory operand after 'ptr', "
2697 "found register operand instead");
2706 "cannot cast register '" +
2708 "'; its size is not easily defined.");
2712 std::to_string(
RegSize) +
"-bit register '" +
2714 "' cannot be used as a " + std::to_string(
Size) +
"-bit " +
2721 if (!getX86MCRegisterClass(X86::SEGMENT_REGRegClassID).
contains(RegNo))
2722 return Error(Start,
"invalid segment register");
2724 Start = Lex().getLoc();
2728 IntelExprStateMachine
SM;
2729 if (ParseIntelExpression(
SM, End))
2732 if (isParsingMSInlineAsm())
2733 RewriteIntelExpression(
SM, Start, Tok.
getLoc());
2735 int64_t
Imm =
SM.getImm();
2736 const MCExpr *Disp =
SM.getSym();
2745 if (!
SM.isMemExpr() && !RegNo) {
2746 if (isParsingMSInlineAsm() &&
SM.isOffsetOperator()) {
2747 const InlineAsmIdentifierInfo &
Info =
SM.getIdentifierInfo();
2752 SM.getSymName(),
Info.Var.Decl,
2753 Info.Var.IsGlobalLV));
2764 MCRegister IndexReg =
SM.getIndexReg();
2765 if (IndexReg && BaseReg == X86::RIP)
2767 unsigned Scale =
SM.getScale();
2769 Size =
SM.getElementSize() << 3;
2771 if (Scale == 0 && BaseReg != X86::ESP && BaseReg != X86::RSP &&
2772 (IndexReg == X86::ESP || IndexReg == X86::RSP))
2778 !(getX86MCRegisterClass(X86::VR128XRegClassID).
contains(IndexReg) ||
2779 getX86MCRegisterClass(X86::VR256XRegClassID).
contains(IndexReg) ||
2780 getX86MCRegisterClass(X86::VR512RegClassID).
contains(IndexReg)) &&
2781 (getX86MCRegisterClass(X86::VR128XRegClassID).
contains(BaseReg) ||
2782 getX86MCRegisterClass(X86::VR256XRegClassID).
contains(BaseReg) ||
2783 getX86MCRegisterClass(X86::VR512RegClassID).
contains(BaseReg)))
2787 getX86MCRegisterClass(X86::GR16RegClassID).
contains(IndexReg))
2788 return Error(Start,
"16-bit addresses cannot have a scale");
2797 if ((BaseReg == X86::SI || BaseReg == X86::DI) &&
2798 (IndexReg == X86::BX || IndexReg == X86::BP))
2801 if ((BaseReg || IndexReg) &&
2804 return Error(Start, ErrMsg);
2805 bool IsUnconditionalBranch =
2806 Name.equals_insensitive(
"jmp") ||
Name.equals_insensitive(
"call");
2807 if (isParsingMSInlineAsm())
2808 return CreateMemForMSInlineAsm(RegNo, Disp, BaseReg, IndexReg, Scale,
2809 IsUnconditionalBranch && is64BitMode(),
2810 Start, End,
Size,
SM.getSymName(),
2811 SM.getIdentifierInfo(), Operands);
2815 MCRegister DefaultBaseReg;
2816 bool MaybeDirectBranchDest =
true;
2819 if (is64BitMode() &&
2820 ((PtrInOperand && !IndexReg) ||
SM.getElementSize() > 0)) {
2821 DefaultBaseReg = X86::RIP;
2823 if (IsUnconditionalBranch) {
2825 MaybeDirectBranchDest =
false;
2827 DefaultBaseReg = X86::RIP;
2828 }
else if (!BaseReg && !IndexReg && Disp &&
2830 if (is64BitMode()) {
2831 if (
SM.getSize() == 8) {
2832 MaybeDirectBranchDest =
false;
2833 DefaultBaseReg = X86::RIP;
2836 if (
SM.getSize() == 4 ||
SM.getSize() == 2)
2837 MaybeDirectBranchDest =
false;
2841 }
else if (IsUnconditionalBranch) {
2843 if (!PtrInOperand &&
SM.isOffsetOperator())
2845 Start,
"`OFFSET` operator cannot be used in an unconditional branch");
2846 if (PtrInOperand ||
SM.isBracketUsed())
2847 MaybeDirectBranchDest =
false;
2850 if (CheckDispOverflow(BaseReg, IndexReg, Disp, Start))
2853 if ((BaseReg || IndexReg || RegNo || DefaultBaseReg))
2855 getPointerWidth(), RegNo, Disp, BaseReg, IndexReg, Scale, Start, End,
2856 Size, DefaultBaseReg, StringRef(),
nullptr,
2857 0,
false, MaybeDirectBranchDest));
2860 getPointerWidth(), Disp, Start, End,
Size, StringRef(),
2862 MaybeDirectBranchDest));
2866bool X86AsmParser::parseATTOperand(
OperandVector &Operands) {
2867 MCAsmParser &Parser = getParser();
2868 switch (getLexer().getKind()) {
2878 "expected immediate expression") ||
2879 getParser().parseExpression(Val, End) ||
2887 return ParseRoundingModeOp(Start, Operands);
2896 const MCExpr *Expr =
nullptr;
2908 if (
Reg == X86::EIZ ||
Reg == X86::RIZ)
2910 Loc,
"%eiz and %riz can only be used as index registers",
2911 SMRange(Loc, EndLoc));
2912 if (
Reg == X86::RIP)
2913 return Error(Loc,
"%rip can only be used as a base register",
2914 SMRange(Loc, EndLoc));
2920 if (!getX86MCRegisterClass(X86::SEGMENT_REGRegClassID).
contains(
Reg))
2921 return Error(Loc,
"invalid segment register");
2929 return ParseMemOperand(
Reg, Expr, Loc, EndLoc, Operands);
2936X86::CondCode X86AsmParser::ParseConditionCode(StringRef CC) {
2937 return StringSwitch<X86::CondCode>(CC)
2959bool X86AsmParser::ParseZ(std::unique_ptr<X86Operand> &Z, SMLoc StartLoc) {
2960 MCAsmParser &Parser = getParser();
2965 (getLexer().getTok().getIdentifier() ==
"z")))
2970 return Error(getLexer().getLoc(),
"Expected } at this point");
2978bool X86AsmParser::HandleAVX512Operand(
OperandVector &Operands) {
2979 MCAsmParser &Parser = getParser();
2982 const SMLoc consumedToken = consumeToken();
2986 if (getLexer().getTok().getIntVal() != 1)
2987 return TokError(
"Expected 1to<NUM> at this point");
2988 StringRef
Prefix = getLexer().getTok().getString();
2991 return TokError(
"Expected 1to<NUM> at this point");
2994 StringRef BroadcastString = (
Prefix + getLexer().getTok().getIdentifier())
2997 return TokError(
"Expected 1to<NUM> at this point");
2998 const char *BroadcastPrimitive =
2999 StringSwitch<const char *>(BroadcastString)
3000 .Case(
"1to2",
"{1to2}")
3001 .Case(
"1to4",
"{1to4}")
3002 .Case(
"1to8",
"{1to8}")
3003 .Case(
"1to16",
"{1to16}")
3004 .Case(
"1to32",
"{1to32}")
3006 if (!BroadcastPrimitive)
3007 return TokError(
"Invalid memory broadcast primitive.");
3010 return TokError(
"Expected } at this point");
3021 std::unique_ptr<X86Operand>
Z;
3022 if (ParseZ(Z, consumedToken))
3028 SMLoc StartLoc =
Z ? consumeToken() : consumedToken;
3033 if (!parseRegister(RegNo, RegLoc, StartLoc) &&
3034 getX86MCRegisterClass(X86::VK1RegClassID).
contains(RegNo)) {
3035 if (RegNo == X86::K0)
3036 return Error(RegLoc,
"Register k0 can't be used as write mask");
3038 return Error(getLexer().getLoc(),
"Expected } at this point");
3044 return Error(getLexer().getLoc(),
3045 "Expected an op-mask register at this point");
3050 if (ParseZ(Z, consumeToken()) || !Z)
3051 return Error(getLexer().getLoc(),
3052 "Expected a {z} mark at this point");
3067bool X86AsmParser::CheckDispOverflow(MCRegister BaseReg, MCRegister IndexReg,
3068 const MCExpr *Disp, SMLoc Loc) {
3074 if (BaseReg || IndexReg) {
3076 auto Imm =
CE->getValue();
3078 getX86MCRegisterClass(X86::GR64RegClassID).contains(BaseReg) ||
3079 getX86MCRegisterClass(X86::GR64RegClassID).contains(IndexReg);
3080 bool Is16 = getX86MCRegisterClass(X86::GR16RegClassID).contains(BaseReg);
3083 return Error(Loc,
"displacement " + Twine(Imm) +
3084 " is not within [-2147483648, 2147483647]");
3086 if (!
isUInt<32>(Imm < 0 ? -uint64_t(Imm) : uint64_t(Imm))) {
3087 Warning(Loc,
"displacement " + Twine(Imm) +
3088 " shortened to 32-bit signed " +
3089 Twine(
static_cast<int32_t
>(Imm)));
3091 }
else if (!
isUInt<16>(Imm < 0 ? -uint64_t(Imm) : uint64_t(Imm))) {
3092 Warning(Loc,
"displacement " + Twine(Imm) +
3093 " shortened to 16-bit signed " +
3094 Twine(
static_cast<int16_t
>(Imm)));
3103bool X86AsmParser::ParseMemOperand(MCRegister SegReg,
const MCExpr *Disp,
3104 SMLoc StartLoc, SMLoc EndLoc,
3106 MCAsmParser &Parser = getParser();
3124 auto isAtMemOperand = [
this]() {
3129 auto TokCount = this->getLexer().peekTokens(Buf,
true);
3132 switch (Buf[0].getKind()) {
3139 if ((TokCount > 1) &&
3143 Buf[1].getIdentifier().
size() + 1);
3165 if (!isAtMemOperand()) {
3184 0, 0, 1, StartLoc, EndLoc));
3192 SMLoc BaseLoc = getLexer().getLoc();
3204 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ)
3205 return Error(BaseLoc,
"eiz and riz can only be used as index registers",
3206 SMRange(BaseLoc, EndLoc));
3224 if (!
E->evaluateAsAbsolute(ScaleVal, getStreamer().getAssemblerPtr()))
3225 return Error(Loc,
"expected absolute expression");
3227 Warning(Loc,
"scale factor without index register is ignored");
3232 if (BaseReg == X86::RIP)
3234 "%rip as base register can not have an index register");
3235 if (IndexReg == X86::RIP)
3236 return Error(Loc,
"%rip is not allowed as an index register");
3247 return Error(Loc,
"expected scale expression");
3248 Scale = (unsigned)ScaleVal;
3250 if (getX86MCRegisterClass(X86::GR16RegClassID).
contains(BaseReg) &&
3252 return Error(Loc,
"scale factor in 16-bit address must be 1");
3254 return Error(Loc, ErrMsg);
3268 if (BaseReg == X86::DX && !IndexReg && Scale == 1 && !SegReg &&
3277 return Error(BaseLoc, ErrMsg);
3279 if (CheckDispOverflow(BaseReg, IndexReg, Disp, BaseLoc))
3282 if (SegReg || BaseReg || IndexReg)
3284 BaseReg, IndexReg, Scale, StartLoc,
3293bool X86AsmParser::parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
3294 MCAsmParser &Parser = getParser();
3301 if (parseRegister(RegNo, StartLoc, EndLoc))
3309bool X86AsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
3311 MCAsmParser &Parser = getParser();
3315 ForcedOpcodePrefix = OpcodePrefix_Default;
3316 ForcedDispEncoding = DispEncoding_Default;
3317 UseApxExtendedReg =
false;
3318 ForcedNoFlag =
false;
3331 if (Prefix ==
"rex")
3332 ForcedOpcodePrefix = OpcodePrefix_REX;
3333 else if (Prefix ==
"rex2")
3334 ForcedOpcodePrefix = OpcodePrefix_REX2;
3335 else if (Prefix ==
"vex")
3336 ForcedOpcodePrefix = OpcodePrefix_VEX;
3337 else if (Prefix ==
"vex2")
3338 ForcedOpcodePrefix = OpcodePrefix_VEX2;
3339 else if (Prefix ==
"vex3")
3340 ForcedOpcodePrefix = OpcodePrefix_VEX3;
3341 else if (Prefix ==
"evex")
3342 ForcedOpcodePrefix = OpcodePrefix_EVEX;
3343 else if (Prefix ==
"disp8")
3344 ForcedDispEncoding = DispEncoding_Disp8;
3345 else if (Prefix ==
"disp32")
3346 ForcedDispEncoding = DispEncoding_Disp32;
3347 else if (Prefix ==
"nf")
3348 ForcedNoFlag =
true;
3350 return Error(NameLoc,
"unknown prefix");
3366 if (isParsingMSInlineAsm()) {
3367 if (
Name.equals_insensitive(
"vex"))
3368 ForcedOpcodePrefix = OpcodePrefix_VEX;
3369 else if (
Name.equals_insensitive(
"vex2"))
3370 ForcedOpcodePrefix = OpcodePrefix_VEX2;
3371 else if (
Name.equals_insensitive(
"vex3"))
3372 ForcedOpcodePrefix = OpcodePrefix_VEX3;
3373 else if (
Name.equals_insensitive(
"evex"))
3374 ForcedOpcodePrefix = OpcodePrefix_EVEX;
3376 if (ForcedOpcodePrefix != OpcodePrefix_Default) {
3389 if (
Name.consume_back(
".d32")) {
3390 ForcedDispEncoding = DispEncoding_Disp32;
3391 }
else if (
Name.consume_back(
".d8")) {
3392 ForcedDispEncoding = DispEncoding_Disp8;
3395 StringRef PatchedName =
Name;
3398 if (isParsingIntelSyntax() &&
3399 (PatchedName ==
"jmp" || PatchedName ==
"jc" || PatchedName ==
"jnc" ||
3400 PatchedName ==
"jcxz" || PatchedName ==
"jecxz" ||
3405 : NextTok ==
"short") {
3414 NextTok.
size() + 1);
3420 PatchedName !=
"setzub" && PatchedName !=
"setzunb" &&
3421 PatchedName !=
"setb" && PatchedName !=
"setnb")
3422 PatchedName = PatchedName.
substr(0,
Name.size()-1);
3424 unsigned ComparisonPredicate = ~0
U;
3432 bool IsVCMP = PatchedName[0] ==
'v';
3433 unsigned CCIdx =
IsVCMP ? 4 : 3;
3434 unsigned suffixLength = PatchedName.
ends_with(
"bf16") ? 5 : 2;
3435 unsigned CC = StringSwitch<unsigned>(
3436 PatchedName.
slice(CCIdx, PatchedName.
size() - suffixLength))
3438 .Case(
"eq_oq", 0x00)
3440 .Case(
"lt_os", 0x01)
3442 .Case(
"le_os", 0x02)
3443 .Case(
"unord", 0x03)
3444 .Case(
"unord_q", 0x03)
3446 .Case(
"neq_uq", 0x04)
3448 .Case(
"nlt_us", 0x05)
3450 .Case(
"nle_us", 0x06)
3452 .Case(
"ord_q", 0x07)
3454 .Case(
"eq_uq", 0x08)
3456 .Case(
"nge_us", 0x09)
3458 .Case(
"ngt_us", 0x0A)
3459 .Case(
"false", 0x0B)
3460 .Case(
"false_oq", 0x0B)
3461 .Case(
"neq_oq", 0x0C)
3463 .Case(
"ge_os", 0x0D)
3465 .Case(
"gt_os", 0x0E)
3467 .Case(
"true_uq", 0x0F)
3468 .Case(
"eq_os", 0x10)
3469 .Case(
"lt_oq", 0x11)
3470 .Case(
"le_oq", 0x12)
3471 .Case(
"unord_s", 0x13)
3472 .Case(
"neq_us", 0x14)
3473 .Case(
"nlt_uq", 0x15)
3474 .Case(
"nle_uq", 0x16)
3475 .Case(
"ord_s", 0x17)
3476 .Case(
"eq_us", 0x18)
3477 .Case(
"nge_uq", 0x19)
3478 .Case(
"ngt_uq", 0x1A)
3479 .Case(
"false_os", 0x1B)
3480 .Case(
"neq_os", 0x1C)
3481 .Case(
"ge_oq", 0x1D)
3482 .Case(
"gt_oq", 0x1E)
3483 .Case(
"true_us", 0x1F)
3485 if (CC != ~0U && (
IsVCMP || CC < 8) &&
3488 PatchedName =
IsVCMP ?
"vcmpss" :
"cmpss";
3490 PatchedName =
IsVCMP ?
"vcmpsd" :
"cmpsd";
3492 PatchedName =
IsVCMP ?
"vcmpps" :
"cmpps";
3494 PatchedName =
IsVCMP ?
"vcmppd" :
"cmppd";
3496 PatchedName =
"vcmpsh";
3498 PatchedName =
"vcmpph";
3500 PatchedName =
"vcmpbf16";
3504 ComparisonPredicate = CC;
3510 (PatchedName.
back() ==
'b' || PatchedName.
back() ==
'w' ||
3511 PatchedName.
back() ==
'd' || PatchedName.
back() ==
'q')) {
3512 unsigned SuffixSize = PatchedName.
drop_back().
back() ==
'u' ? 2 : 1;
3513 unsigned CC = StringSwitch<unsigned>(
3514 PatchedName.
slice(5, PatchedName.
size() - SuffixSize))
3524 if (CC != ~0U && (CC != 0 || SuffixSize == 2)) {
3525 switch (PatchedName.
back()) {
3527 case 'b': PatchedName = SuffixSize == 2 ?
"vpcmpub" :
"vpcmpb";
break;
3528 case 'w': PatchedName = SuffixSize == 2 ?
"vpcmpuw" :
"vpcmpw";
break;
3529 case 'd': PatchedName = SuffixSize == 2 ?
"vpcmpud" :
"vpcmpd";
break;
3530 case 'q': PatchedName = SuffixSize == 2 ?
"vpcmpuq" :
"vpcmpq";
break;
3533 ComparisonPredicate = CC;
3539 (PatchedName.
back() ==
'b' || PatchedName.
back() ==
'w' ||
3540 PatchedName.
back() ==
'd' || PatchedName.
back() ==
'q')) {
3541 unsigned SuffixSize = PatchedName.
drop_back().
back() ==
'u' ? 2 : 1;
3542 unsigned CC = StringSwitch<unsigned>(
3543 PatchedName.
slice(5, PatchedName.
size() - SuffixSize))
3554 switch (PatchedName.
back()) {
3556 case 'b': PatchedName = SuffixSize == 2 ?
"vpcomub" :
"vpcomb";
break;
3557 case 'w': PatchedName = SuffixSize == 2 ?
"vpcomuw" :
"vpcomw";
break;
3558 case 'd': PatchedName = SuffixSize == 2 ?
"vpcomud" :
"vpcomd";
break;
3559 case 'q': PatchedName = SuffixSize == 2 ?
"vpcomuq" :
"vpcomq";
break;
3562 ComparisonPredicate = CC;
3574 StringSwitch<bool>(Name)
3575 .Cases({
"cs",
"ds",
"es",
"fs",
"gs",
"ss"},
true)
3576 .Cases({
"rex64",
"data32",
"data16",
"addr32",
"addr16"},
true)
3577 .Cases({
"xacquire",
"xrelease"},
true)
3578 .Cases({
"acquire",
"release"}, isParsingIntelSyntax())
3581 auto isLockRepeatNtPrefix = [](StringRef
N) {
3582 return StringSwitch<bool>(
N)
3583 .Cases({
"lock",
"rep",
"repe",
"repz",
"repne",
"repnz",
"notrack"},
3588 bool CurlyAsEndOfStatement =
false;
3591 while (isLockRepeatNtPrefix(
Name.lower())) {
3593 StringSwitch<unsigned>(Name)
3612 while (
Name.starts_with(
";") ||
Name.starts_with(
"\n") ||
3613 Name.starts_with(
"#") ||
Name.starts_with(
"\t") ||
3614 Name.starts_with(
"/")) {
3625 if (PatchedName ==
"data16" && is16BitMode()) {
3626 return Error(NameLoc,
"redundant data16 prefix");
3628 if (PatchedName ==
"data32") {
3630 return Error(NameLoc,
"redundant data32 prefix");
3632 return Error(NameLoc,
"'data32' is not supported in 64-bit mode");
3634 PatchedName =
"data16";
3641 if (
Next ==
"callw")
3643 if (
Next ==
"ljmpw")
3648 ForcedDataPrefix = X86::Is32Bit;
3656 if (ComparisonPredicate != ~0U && !isParsingIntelSyntax()) {
3663 if ((
Name.starts_with(
"ccmp") ||
Name.starts_with(
"ctest")) &&
3664 parseCFlagsOp(Operands))
3678 if (parseOperand(Operands, Name))
3680 if (HandleAVX512Operand(Operands))
3692 CurlyAsEndOfStatement =
3693 isParsingIntelSyntax() && isParsingMSInlineAsm() &&
3696 return TokError(
"unexpected token in argument list");
3700 if (ComparisonPredicate != ~0U && isParsingIntelSyntax()) {
3710 else if (CurlyAsEndOfStatement)
3713 getLexer().getTok().getLoc(), 0);
3720 if (IsFp && Operands.
size() == 1) {
3721 const char *Repl = StringSwitch<const char *>(Name)
3722 .Case(
"fsub",
"fsubp")
3723 .Case(
"fdiv",
"fdivp")
3724 .Case(
"fsubr",
"fsubrp")
3725 .Case(
"fdivr",
"fdivrp");
3726 static_cast<X86Operand &
>(*Operands[0]).setTokenValue(Repl);
3729 if ((Name ==
"mov" || Name ==
"movw" || Name ==
"movl") &&
3730 (Operands.
size() == 3)) {
3731 X86Operand &Op1 = (X86Operand &)*Operands[1];
3732 X86Operand &Op2 = (X86Operand &)*Operands[2];
3737 getX86MCRegisterClass(X86::SEGMENT_REGRegClassID)
3739 (getX86MCRegisterClass(X86::GR16RegClassID).
contains(Op1.
getReg()) ||
3740 getX86MCRegisterClass(X86::GR32RegClassID).
contains(Op1.
getReg()))) {
3742 if (Name !=
"mov" && Name[3] == (is16BitMode() ?
'l' :
'w')) {
3743 Name = is16BitMode() ?
"movw" :
"movl";
3756 if ((Name ==
"outb" || Name ==
"outsb" || Name ==
"outw" || Name ==
"outsw" ||
3757 Name ==
"outl" || Name ==
"outsl" || Name ==
"out" || Name ==
"outs") &&
3758 Operands.
size() == 3) {
3759 X86Operand &
Op = (X86Operand &)*Operands.
back();
3765 if ((Name ==
"inb" || Name ==
"insb" || Name ==
"inw" || Name ==
"insw" ||
3766 Name ==
"inl" || Name ==
"insl" || Name ==
"in" || Name ==
"ins") &&
3767 Operands.
size() == 3) {
3768 X86Operand &
Op = (X86Operand &)*Operands[1];
3775 bool HadVerifyError =
false;
3778 if (
Name.starts_with(
"ins") &&
3779 (Operands.
size() == 1 || Operands.
size() == 3) &&
3780 (Name ==
"insb" || Name ==
"insw" || Name ==
"insl" || Name ==
"insd" ||
3783 AddDefaultSrcDestOperands(TmpOperands,
3785 DefaultMemDIOperand(NameLoc));
3786 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3790 if (
Name.starts_with(
"outs") &&
3791 (Operands.
size() == 1 || Operands.
size() == 3) &&
3792 (Name ==
"outsb" || Name ==
"outsw" || Name ==
"outsl" ||
3793 Name ==
"outsd" || Name ==
"outs")) {
3794 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
3796 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3802 if (
Name.starts_with(
"lods") &&
3803 (Operands.
size() == 1 || Operands.
size() == 2) &&
3804 (Name ==
"lods" || Name ==
"lodsb" || Name ==
"lodsw" ||
3805 Name ==
"lodsl" || Name ==
"lodsd" || Name ==
"lodsq")) {
3806 TmpOperands.
push_back(DefaultMemSIOperand(NameLoc));
3807 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3813 if (
Name.starts_with(
"stos") &&
3814 (Operands.
size() == 1 || Operands.
size() == 2) &&
3815 (Name ==
"stos" || Name ==
"stosb" || Name ==
"stosw" ||
3816 Name ==
"stosl" || Name ==
"stosd" || Name ==
"stosq")) {
3817 TmpOperands.
push_back(DefaultMemDIOperand(NameLoc));
3818 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3824 if (
Name.starts_with(
"scas") &&
3825 (Operands.
size() == 1 || Operands.
size() == 2) &&
3826 (Name ==
"scas" || Name ==
"scasb" || Name ==
"scasw" ||
3827 Name ==
"scasl" || Name ==
"scasd" || Name ==
"scasq")) {
3828 TmpOperands.
push_back(DefaultMemDIOperand(NameLoc));
3829 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3833 if (
Name.starts_with(
"cmps") &&
3834 (Operands.
size() == 1 || Operands.
size() == 3) &&
3835 (Name ==
"cmps" || Name ==
"cmpsb" || Name ==
"cmpsw" ||
3836 Name ==
"cmpsl" || Name ==
"cmpsd" || Name ==
"cmpsq")) {
3837 AddDefaultSrcDestOperands(TmpOperands, DefaultMemDIOperand(NameLoc),
3838 DefaultMemSIOperand(NameLoc));
3839 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3843 if (((
Name.starts_with(
"movs") &&
3844 (Name ==
"movs" || Name ==
"movsb" || Name ==
"movsw" ||
3845 Name ==
"movsl" || Name ==
"movsd" || Name ==
"movsq")) ||
3846 (
Name.starts_with(
"smov") &&
3847 (Name ==
"smov" || Name ==
"smovb" || Name ==
"smovw" ||
3848 Name ==
"smovl" || Name ==
"smovd" || Name ==
"smovq"))) &&
3849 (Operands.
size() == 1 || Operands.
size() == 3)) {
3850 if (Name ==
"movsd" && Operands.
size() == 1 && !isParsingIntelSyntax())
3852 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
3853 DefaultMemDIOperand(NameLoc));
3854 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3858 if (HadVerifyError) {
3859 return HadVerifyError;
3863 if ((Name ==
"xlat" || Name ==
"xlatb") && Operands.
size() == 2) {
3864 X86Operand &Op1 =
static_cast<X86Operand &
>(*Operands[1]);
3867 "size, (R|E)BX will be used for the location");
3869 static_cast<X86Operand &
>(*Operands[0]).setTokenValue(
"xlatb");
3882 if (
I ==
Table.end() ||
I->OldOpc != Opcode)
3888 if (X86::isBLENDVPD(Opcode) || X86::isBLENDVPS(Opcode) ||
3889 X86::isPBLENDVB(Opcode))
3895bool X86AsmParser::processInstruction(MCInst &Inst,
const OperandVector &
Ops) {
3899 if (ForcedOpcodePrefix != OpcodePrefix_VEX3 &&
3906 auto replaceWithCCMPCTEST = [&](
unsigned Opcode) ->
bool {
3907 if (ForcedOpcodePrefix == OpcodePrefix_EVEX) {
3918 default:
return false;
3923 if (ForcedDispEncoding == DispEncoding_Disp32) {
3924 Inst.
setOpcode(is16BitMode() ? X86::JMP_2 : X86::JMP_4);
3933 if (ForcedDispEncoding == DispEncoding_Disp32) {
3934 Inst.
setOpcode(is16BitMode() ? X86::JCC_2 : X86::JCC_4);
3950#define FROM_TO(FROM, TO) \
3952 return replaceWithCCMPCTEST(X86::TO);
3954 FROM_TO(CMP64mi32, CCMP64mi32)
3957 FROM_TO(CMP64ri32, CCMP64ri32)
3984 FROM_TO(TEST64mi32, CTEST64mi32)
3986 FROM_TO(TEST64ri32, CTEST64ri32)
4006bool X86AsmParser::validateInstruction(MCInst &Inst,
const OperandVector &
Ops) {
4007 using namespace X86;
4008 const MCRegisterInfo *MRI =
getContext().getRegisterInfo();
4010 uint64_t TSFlags = MII.get(Opcode).TSFlags;
4011 if (isVFCMADDCPH(Opcode) || isVFCMADDCSH(Opcode) || isVFMADDCPH(Opcode) ||
4012 isVFMADDCSH(Opcode)) {
4016 return Warning(
Ops[0]->getStartLoc(),
"Destination register should be "
4017 "distinct from source registers");
4018 }
else if (isVFCMULCPH(Opcode) || isVFCMULCSH(Opcode) || isVFMULCPH(Opcode) ||
4019 isVFMULCSH(Opcode)) {
4029 return Warning(
Ops[0]->getStartLoc(),
"Destination register should be "
4030 "distinct from source registers");
4031 }
else if (isV4FMADDPS(Opcode) || isV4FMADDSS(Opcode) ||
4032 isV4FNMADDPS(Opcode) || isV4FNMADDSS(Opcode) ||
4033 isVP4DPWSSDS(Opcode) || isVP4DPWSSD(Opcode)) {
4038 if (Src2Enc % 4 != 0) {
4040 unsigned GroupStart = (Src2Enc / 4) * 4;
4041 unsigned GroupEnd = GroupStart + 3;
4043 "source register '" +
RegName +
"' implicitly denotes '" +
4044 RegName.take_front(3) + Twine(GroupStart) +
"' to '" +
4045 RegName.take_front(3) + Twine(GroupEnd) +
4048 }
else if (isVGATHERDPD(Opcode) || isVGATHERDPS(Opcode) ||
4049 isVGATHERQPD(Opcode) || isVGATHERQPS(Opcode) ||
4050 isVPGATHERDD(Opcode) || isVPGATHERDQ(Opcode) ||
4051 isVPGATHERQD(Opcode) || isVPGATHERQQ(Opcode)) {
4058 return Warning(
Ops[0]->getStartLoc(),
"index and destination registers "
4059 "should be distinct");
4065 if (Dest == Mask || Dest == Index || Mask == Index)
4066 return Warning(
Ops[0]->getStartLoc(),
"mask, index, and destination "
4067 "registers should be distinct");
4069 }
else if (isTCMMIMFP16PS(Opcode) || isTCMMRLFP16PS(Opcode) ||
4070 isTDPBF16PS(Opcode) || isTDPFP16PS(Opcode) || isTDPBSSD(Opcode) ||
4071 isTDPBSUD(Opcode) || isTDPBUSD(Opcode) || isTDPBUUD(Opcode)) {
4075 if (SrcDest == Src1 || SrcDest == Src2 || Src1 == Src2)
4076 return Error(
Ops[0]->getStartLoc(),
"all tmm registers must be distinct");
4090 for (
unsigned i = 0; i !=
NumOps; ++i) {
4095 if (
Reg == X86::AH ||
Reg == X86::BH ||
Reg == X86::CH ||
Reg == X86::DH)
4103 (Enc ==
X86II::EVEX || ForcedOpcodePrefix == OpcodePrefix_REX2 ||
4104 ForcedOpcodePrefix == OpcodePrefix_REX || UsesRex)) {
4106 return Error(
Ops[0]->getStartLoc(),
4107 "can't encode '" +
RegName.str() +
4108 "' in an instruction requiring EVEX/REX2/REX prefix");
4112 if ((Opcode == X86::PREFETCHIT0 || Opcode == X86::PREFETCHIT1)) {
4116 Ops[0]->getStartLoc(),
4117 Twine((Inst.
getOpcode() == X86::PREFETCHIT0 ?
"'prefetchit0'"
4118 :
"'prefetchit1'")) +
4119 " only supports RIP-relative address");
4124void X86AsmParser::emitWarningForSpecialLVIInstruction(SMLoc Loc) {
4125 Warning(Loc,
"Instruction may be vulnerable to LVI and "
4126 "requires manual mitigation");
4127 Note(SMLoc(),
"See https://software.intel.com/"
4128 "security-software-guidance/insights/"
4129 "deep-dive-load-value-injection#specialinstructions"
4130 " for more information");
4142void X86AsmParser::applyLVICFIMitigation(MCInst &Inst, MCStreamer &Out) {
4153 MCInst ShlInst, FenceInst;
4154 bool Parse32 = is32BitMode() || Code16GCC;
4155 MCRegister Basereg =
4156 is64BitMode() ? X86::RSP : (Parse32 ? X86::ESP : X86::SP);
4160 1, SMLoc{}, SMLoc{}, 0);
4162 ShlMemOp->addMemOperands(ShlInst, 5);
4175 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4187void X86AsmParser::applyLVILoadHardeningMitigation(MCInst &Inst,
4204 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4207 }
else if (Opcode == X86::REP_PREFIX || Opcode == X86::REPNE_PREFIX) {
4210 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4214 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
4229void X86AsmParser::emitInstruction(MCInst &Inst,
OperandVector &Operands,
4232 getSTI().
hasFeature(X86::FeatureLVIControlFlowIntegrity))
4233 applyLVICFIMitigation(Inst, Out);
4238 getSTI().
hasFeature(X86::FeatureLVILoadHardening))
4239 applyLVILoadHardeningMitigation(Inst, Out);
4243 unsigned Result = 0;
4245 if (Prefix.isPrefix()) {
4246 Result = Prefix.getPrefix();
4252bool X86AsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
4254 MCStreamer &Out, uint64_t &ErrorInfo,
4255 bool MatchingInlineAsm) {
4256 assert(!Operands.
empty() &&
"Unexpect empty operand list!");
4257 assert((*Operands[0]).isToken() &&
"Leading operand should always be a mnemonic!");
4260 MatchFPUWaitAlias(IDLoc,
static_cast<X86Operand &
>(*Operands[0]), Operands,
4261 Out, MatchingInlineAsm);
4268 if (ForcedOpcodePrefix == OpcodePrefix_REX)
4270 else if (ForcedOpcodePrefix == OpcodePrefix_REX2)
4272 else if (ForcedOpcodePrefix == OpcodePrefix_VEX)
4274 else if (ForcedOpcodePrefix == OpcodePrefix_VEX2)
4276 else if (ForcedOpcodePrefix == OpcodePrefix_VEX3)
4278 else if (ForcedOpcodePrefix == OpcodePrefix_EVEX)
4282 if (ForcedDispEncoding == DispEncoding_Disp8)
4284 else if (ForcedDispEncoding == DispEncoding_Disp32)
4290 return isParsingIntelSyntax()
4291 ? matchAndEmitIntelInstruction(IDLoc, Opcode, Inst, Operands, Out,
4292 ErrorInfo, MatchingInlineAsm)
4293 : matchAndEmitATTInstruction(IDLoc, Opcode, Inst, Operands, Out,
4294 ErrorInfo, MatchingInlineAsm);
4297void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &
Op,
4299 bool MatchingInlineAsm) {
4303 const char *Repl = StringSwitch<const char *>(
Op.getToken())
4304 .Case(
"finit",
"fninit")
4305 .Case(
"fsave",
"fnsave")
4306 .Case(
"fstcw",
"fnstcw")
4307 .Case(
"fstcww",
"fnstcw")
4308 .Case(
"fstenv",
"fnstenv")
4309 .Case(
"fstsw",
"fnstsw")
4310 .Case(
"fstsww",
"fnstsw")
4311 .Case(
"fclex",
"fnclex")
4317 if (!MatchingInlineAsm)
4323bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc,
4324 const FeatureBitset &MissingFeatures,
4325 bool MatchingInlineAsm) {
4326 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
4327 SmallString<126>
Msg;
4328 raw_svector_ostream OS(
Msg);
4329 OS <<
"instruction requires:";
4330 for (
unsigned Feature : MissingFeatures)
4332 return Error(IDLoc, OS.str(), SMRange(), MatchingInlineAsm);
4335unsigned X86AsmParser::checkTargetMatchPredicate(MCInst &Inst) {
4337 const MCInstrDesc &MCID = MII.get(
Opc);
4338 uint64_t TSFlags = MCID.
TSFlags;
4341 return Match_Unsupported;
4343 return Match_Unsupported;
4345 switch (ForcedOpcodePrefix) {
4346 case OpcodePrefix_Default:
4348 case OpcodePrefix_REX:
4349 case OpcodePrefix_REX2:
4351 return Match_Unsupported;
4353 case OpcodePrefix_VEX:
4354 case OpcodePrefix_VEX2:
4355 case OpcodePrefix_VEX3:
4357 return Match_Unsupported;
4359 case OpcodePrefix_EVEX:
4361 !X86::isCMP(
Opc) && !X86::isTEST(
Opc))
4362 return Match_Unsupported;
4364 return Match_Unsupported;
4369 (ForcedOpcodePrefix != OpcodePrefix_VEX &&
4370 ForcedOpcodePrefix != OpcodePrefix_VEX2 &&
4371 ForcedOpcodePrefix != OpcodePrefix_VEX3))
4372 return Match_Unsupported;
4374 return Match_Success;
4377bool X86AsmParser::matchAndEmitATTInstruction(
4378 SMLoc IDLoc,
unsigned &Opcode, MCInst &Inst,
OperandVector &Operands,
4379 MCStreamer &Out, uint64_t &ErrorInfo,
bool MatchingInlineAsm) {
4380 X86Operand &
Op =
static_cast<X86Operand &
>(*Operands[0]);
4384 if (ForcedDataPrefix == X86::Is32Bit)
4385 SwitchMode(X86::Is32Bit);
4387 FeatureBitset MissingFeatures;
4388 unsigned OriginalError = MatchInstruction(Operands, Inst, ErrorInfo,
4389 MissingFeatures, MatchingInlineAsm,
4390 isParsingIntelSyntax());
4391 if (ForcedDataPrefix == X86::Is32Bit) {
4392 SwitchMode(X86::Is16Bit);
4393 ForcedDataPrefix = 0;
4395 switch (OriginalError) {
4398 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
4403 if (!MatchingInlineAsm)
4404 while (processInstruction(Inst, Operands))
4408 if (!MatchingInlineAsm)
4412 case Match_InvalidImmUnsignedi4: {
4413 SMLoc ErrorLoc = ((X86Operand &)*Operands[ErrorInfo]).getStartLoc();
4414 if (ErrorLoc == SMLoc())
4416 return Error(ErrorLoc,
"immediate must be an integer in range [0, 15]",
4417 EmptyRange, MatchingInlineAsm);
4419 case Match_InvalidImmUnsignedi6: {
4420 SMLoc ErrorLoc = ((X86Operand &)*Operands[ErrorInfo]).getStartLoc();
4421 if (ErrorLoc == SMLoc())
4423 return Error(ErrorLoc,
"immediate must be an integer in range [0, 63]",
4424 EmptyRange, MatchingInlineAsm);
4426 case Match_MissingFeature:
4427 return ErrorMissingFeature(IDLoc, MissingFeatures, MatchingInlineAsm);
4428 case Match_InvalidOperand:
4429 case Match_MnemonicFail:
4430 case Match_Unsupported:
4433 if (
Op.getToken().empty()) {
4434 Error(IDLoc,
"instruction must have size higher than 0", EmptyRange,
4445 StringRef
Base =
Op.getToken();
4446 SmallString<16> Tmp;
4449 Op.setTokenValue(Tmp);
4457 const char *Suffixes =
Base[0] !=
'f' ?
"bwlq" :
"slt\0";
4459 const char *MemSize =
Base[0] !=
'f' ?
"\x08\x10\x20\x40" :
"\x20\x40\x50\0";
4462 uint64_t ErrorInfoIgnore;
4463 FeatureBitset ErrorInfoMissingFeatures;
4471 bool HasVectorReg =
false;
4472 X86Operand *MemOp =
nullptr;
4473 for (
const auto &
Op : Operands) {
4474 X86Operand *X86Op =
static_cast<X86Operand *
>(
Op.get());
4476 HasVectorReg =
true;
4477 else if (X86Op->
isMem()) {
4479 assert(MemOp->Mem.Size == 0 &&
"Memory size always 0 under ATT syntax");
4486 for (
unsigned I = 0,
E = std::size(Match);
I !=
E; ++
I) {
4487 Tmp.
back() = Suffixes[
I];
4488 if (MemOp && HasVectorReg)
4489 MemOp->Mem.Size = MemSize[
I];
4490 Match[
I] = Match_MnemonicFail;
4491 if (MemOp || !HasVectorReg) {
4493 MatchInstruction(Operands, Inst, ErrorInfoIgnore, MissingFeatures,
4494 MatchingInlineAsm, isParsingIntelSyntax());
4496 if (Match[
I] == Match_MissingFeature)
4497 ErrorInfoMissingFeatures = MissingFeatures;
4507 unsigned NumSuccessfulMatches =
llvm::count(Match, Match_Success);
4508 if (NumSuccessfulMatches == 1) {
4509 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
4514 if (!MatchingInlineAsm)
4515 while (processInstruction(Inst, Operands))
4519 if (!MatchingInlineAsm)
4529 if (NumSuccessfulMatches > 1) {
4531 unsigned NumMatches = 0;
4532 for (
unsigned I = 0,
E = std::size(Match);
I !=
E; ++
I)
4533 if (Match[
I] == Match_Success)
4534 MatchChars[NumMatches++] = Suffixes[
I];
4536 SmallString<126>
Msg;
4537 raw_svector_ostream OS(
Msg);
4538 OS <<
"ambiguous instructions require an explicit suffix (could be ";
4539 for (
unsigned i = 0; i != NumMatches; ++i) {
4542 if (i + 1 == NumMatches)
4544 OS <<
"'" <<
Base << MatchChars[i] <<
"'";
4547 Error(IDLoc, OS.str(), EmptyRange, MatchingInlineAsm);
4555 if (
llvm::count(Match, Match_MnemonicFail) == 4) {
4556 if (OriginalError == Match_MnemonicFail)
4557 return Error(IDLoc,
"invalid instruction mnemonic '" +
Base +
"'",
4558 Op.getLocRange(), MatchingInlineAsm);
4560 if (OriginalError == Match_Unsupported)
4561 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4564 assert(OriginalError == Match_InvalidOperand &&
"Unexpected error");
4566 if (ErrorInfo != ~0ULL) {
4567 if (ErrorInfo >= Operands.size())
4568 return Error(IDLoc,
"too few operands for instruction", EmptyRange,
4571 X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo];
4575 OperandRange, MatchingInlineAsm);
4579 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4585 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4591 if (
llvm::count(Match, Match_MissingFeature) == 1) {
4592 ErrorInfo = Match_MissingFeature;
4593 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
4599 if (
llvm::count(Match, Match_InvalidOperand) == 1) {
4600 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4605 Error(IDLoc,
"unknown use of instruction mnemonic without a size suffix",
4606 EmptyRange, MatchingInlineAsm);
4610bool X86AsmParser::matchAndEmitIntelInstruction(
4611 SMLoc IDLoc,
unsigned &Opcode, MCInst &Inst,
OperandVector &Operands,
4612 MCStreamer &Out, uint64_t &ErrorInfo,
bool MatchingInlineAsm) {
4613 X86Operand &
Op =
static_cast<X86Operand &
>(*Operands[0]);
4618 const bool ForcedData32 = ForcedDataPrefix == X86::Is32Bit;
4619 auto RestoreMode = [&] {
4621 SwitchMode(X86::Is16Bit);
4622 ForcedDataPrefix = 0;
4626 SwitchMode(X86::Is32Bit);
4628 X86Operand *UnsizedMemOp =
nullptr;
4629 for (
const auto &
Op : Operands) {
4630 X86Operand *X86Op =
static_cast<X86Operand *
>(
Op.get());
4632 UnsizedMemOp = X86Op;
4641 StringRef Mnemonic = (
static_cast<X86Operand &
>(*Operands[0])).
getToken();
4643 static const char *
const PtrSizedInstrs[] = {
"call",
"jmp",
"push",
"pop"};
4644 for (
const char *Instr : PtrSizedInstrs) {
4645 if (Mnemonic == Instr) {
4646 UnsizedMemOp->
Mem.
Size = getPointerWidth();
4652 SmallVector<unsigned, 8> Match;
4653 FeatureBitset ErrorInfoMissingFeatures;
4654 FeatureBitset MissingFeatures;
4655 StringRef
Base = (
static_cast<X86Operand &
>(*Operands[0])).
getToken();
4659 if (Mnemonic ==
"push" && Operands.size() == 2) {
4660 auto *X86Op =
static_cast<X86Operand *
>(Operands[1].get());
4661 if (X86Op->
isImm()) {
4664 unsigned Size = getPointerWidth();
4667 SmallString<16> Tmp;
4669 Tmp += (is64BitMode())
4671 : (is32BitMode()) ?
"l" : (is16BitMode()) ?
"w" :
" ";
4672 Op.setTokenValue(Tmp);
4674 Match.
push_back(MatchInstruction(Operands, Inst, ErrorInfo,
4675 MissingFeatures, MatchingInlineAsm,
4686 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
4687 for (
unsigned Size : MopSizes) {
4689 uint64_t ErrorInfoIgnore;
4691 unsigned M = MatchInstruction(Operands, Inst, ErrorInfoIgnore,
4692 MissingFeatures, MatchingInlineAsm,
4693 isParsingIntelSyntax());
4698 if (Match.
back() == Match_MissingFeature)
4699 ErrorInfoMissingFeatures = MissingFeatures;
4709 if (Match.
empty()) {
4711 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,
4712 isParsingIntelSyntax()));
4714 if (Match.
back() == Match_MissingFeature)
4715 ErrorInfoMissingFeatures = MissingFeatures;
4723 if (Match.
back() == Match_MnemonicFail) {
4725 return Error(IDLoc,
"invalid instruction mnemonic '" + Mnemonic +
"'",
4726 Op.getLocRange(), MatchingInlineAsm);
4729 unsigned NumSuccessfulMatches =
llvm::count(Match, Match_Success);
4733 if (UnsizedMemOp && NumSuccessfulMatches > 1 &&
4736 unsigned M = MatchInstruction(
4737 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,
4738 isParsingIntelSyntax());
4739 if (M == Match_Success)
4740 NumSuccessfulMatches = 1;
4755 if (NumSuccessfulMatches == 1) {
4756 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
4761 if (!MatchingInlineAsm)
4762 while (processInstruction(Inst, Operands))
4765 if (!MatchingInlineAsm)
4769 }
else if (NumSuccessfulMatches > 1) {
4771 "multiple matches only possible with unsized memory operands");
4773 "ambiguous operand size for instruction '" + Mnemonic +
"\'",
4779 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4785 if (
llvm::count(Match, Match_MissingFeature) == 1) {
4786 ErrorInfo = Match_MissingFeature;
4787 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
4793 if (
llvm::count(Match, Match_InvalidOperand) == 1) {
4794 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4798 if (
llvm::count(Match, Match_InvalidImmUnsignedi4) == 1) {
4799 SMLoc ErrorLoc = ((X86Operand &)*Operands[ErrorInfo]).getStartLoc();
4800 if (ErrorLoc == SMLoc())
4802 return Error(ErrorLoc,
"immediate must be an integer in range [0, 15]",
4803 EmptyRange, MatchingInlineAsm);
4806 if (
llvm::count(Match, Match_InvalidImmUnsignedi6) == 1) {
4807 SMLoc ErrorLoc = ((X86Operand &)*Operands[ErrorInfo]).getStartLoc();
4808 if (ErrorLoc == SMLoc())
4810 return Error(ErrorLoc,
"immediate must be an integer in range [0, 63]",
4811 EmptyRange, MatchingInlineAsm);
4815 return Error(IDLoc,
"unknown instruction mnemonic", EmptyRange,
4819bool X86AsmParser::omitRegisterFromClobberLists(MCRegister
Reg) {
4820 return getX86MCRegisterClass(X86::SEGMENT_REGRegClassID).contains(
Reg);
4823bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
4824 MCAsmParser &Parser = getParser();
4827 return parseDirectiveArch();
4829 return ParseDirectiveCode(IDVal, DirectiveID.
getLoc());
4835 return Error(DirectiveID.
getLoc(),
"'.att_syntax noprefix' is not "
4836 "supported: registers must have a "
4837 "'%' prefix in .att_syntax");
4839 getParser().setAssemblerDialect(0);
4842 getParser().setAssemblerDialect(1);
4847 return Error(DirectiveID.
getLoc(),
"'.intel_syntax prefix' is not "
4848 "supported: registers must not have "
4849 "a '%' prefix in .intel_syntax");
4852 }
else if (IDVal ==
".nops")
4853 return parseDirectiveNops(DirectiveID.
getLoc());
4854 else if (IDVal ==
".even")
4855 return parseDirectiveEven(DirectiveID.
getLoc());
4856 else if (IDVal ==
".cv_fpo_proc")
4857 return parseDirectiveFPOProc(DirectiveID.
getLoc());
4858 else if (IDVal ==
".cv_fpo_setframe")
4859 return parseDirectiveFPOSetFrame(DirectiveID.
getLoc());
4860 else if (IDVal ==
".cv_fpo_pushreg")
4861 return parseDirectiveFPOPushReg(DirectiveID.
getLoc());
4862 else if (IDVal ==
".cv_fpo_stackalloc")
4863 return parseDirectiveFPOStackAlloc(DirectiveID.
getLoc());
4864 else if (IDVal ==
".cv_fpo_stackalign")
4865 return parseDirectiveFPOStackAlign(DirectiveID.
getLoc());
4866 else if (IDVal ==
".cv_fpo_endprologue")
4867 return parseDirectiveFPOEndPrologue(DirectiveID.
getLoc());
4868 else if (IDVal ==
".cv_fpo_endproc")
4869 return parseDirectiveFPOEndProc(DirectiveID.
getLoc());
4870 else if (IDVal ==
".seh_pushreg")
4871 return parseDirectiveSEHPushReg(DirectiveID.
getLoc());
4872 else if (IDVal ==
".seh_push2regs")
4873 return parseDirectiveSEHPush2Regs(DirectiveID.
getLoc());
4874 else if (IDVal ==
".seh_setframe")
4875 return parseDirectiveSEHSetFrame(DirectiveID.
getLoc());
4876 else if (IDVal ==
".seh_savereg")
4877 return parseDirectiveSEHSaveReg(DirectiveID.
getLoc());
4878 else if (IDVal ==
".seh_savexmm")
4879 return parseDirectiveSEHSaveXMM(DirectiveID.
getLoc());
4880 else if (IDVal ==
".seh_pushframe")
4881 return parseDirectiveSEHPushFrame(DirectiveID.
getLoc());
4885 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
4886 parseDirectiveSEHPushReg(DirectiveID.
getLoc());
4888 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
4889 parseDirectiveSEHPush2Regs(DirectiveID.
getLoc());
4891 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
4892 parseDirectiveSEHSetFrame(DirectiveID.
getLoc());
4894 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
4895 parseDirectiveSEHSaveReg(DirectiveID.
getLoc());
4897 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
4898 parseDirectiveSEHSaveXMM(DirectiveID.
getLoc());
4900 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
4901 parseDirectiveSEHPushFrame(DirectiveID.
getLoc());
4905 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
4906 parseDirectiveSEHPushReg(DirectiveID.
getLoc());
4910 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
4911 parseDirectiveSEHPush2Regs(DirectiveID.
getLoc(),
4914 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
4915 parseDirectiveSEHSetFrame(DirectiveID.
getLoc());
4917 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
4918 parseDirectiveSEHSaveReg(DirectiveID.
getLoc());
4920 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
4921 parseDirectiveSEHSaveXMM(DirectiveID.
getLoc());
4928bool X86AsmParser::parseDirectiveArch() {
4930 getParser().parseStringToEndOfStatement();
4936bool X86AsmParser::parseDirectiveNops(SMLoc L) {
4937 int64_t NumBytes = 0, Control = 0;
4938 SMLoc NumBytesLoc, ControlLoc;
4939 const MCSubtargetInfo& STI = getSTI();
4940 NumBytesLoc = getTok().getLoc();
4941 if (getParser().checkForValidSection() ||
4942 getParser().parseAbsoluteExpression(NumBytes))
4946 ControlLoc = getTok().getLoc();
4947 if (getParser().parseAbsoluteExpression(Control))
4950 if (getParser().parseEOL())
4953 if (NumBytes <= 0) {
4954 Error(NumBytesLoc,
"'.nops' directive with non-positive size");
4959 Error(ControlLoc,
"'.nops' directive with negative NOP size");
4964 getParser().getStreamer().emitNops(NumBytes, Control, L, STI);
4971bool X86AsmParser::parseDirectiveEven(SMLoc L) {
4975 const MCSection *
Section = getStreamer().getCurrentSectionOnly();
4977 getStreamer().initSections(getSTI());
4978 Section = getStreamer().getCurrentSectionOnly();
4980 if (
getContext().getAsmInfo().useCodeAlign(*Section))
4981 getStreamer().emitCodeAlignment(
Align(2), getSTI(), 0);
4983 getStreamer().emitValueToAlignment(
Align(2), 0, 1, 0);
4989bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
4990 MCAsmParser &Parser = getParser();
4992 if (IDVal ==
".code16") {
4994 if (!is16BitMode()) {
4995 SwitchMode(X86::Is16Bit);
4996 getTargetStreamer().emitCode16();
4998 }
else if (IDVal ==
".code16gcc") {
5002 if (!is16BitMode()) {
5003 SwitchMode(X86::Is16Bit);
5004 getTargetStreamer().emitCode16();
5006 }
else if (IDVal ==
".code32") {
5008 if (!is32BitMode()) {
5009 SwitchMode(X86::Is32Bit);
5010 getTargetStreamer().emitCode32();
5012 }
else if (IDVal ==
".code64") {
5014 if (!is64BitMode()) {
5015 SwitchMode(X86::Is64Bit);
5016 getTargetStreamer().emitCode64();
5019 Error(L,
"unknown directive " + IDVal);
5027bool X86AsmParser::parseDirectiveFPOProc(SMLoc L) {
5028 MCAsmParser &Parser = getParser();
5032 return Parser.
TokError(
"expected symbol name");
5033 if (Parser.
parseIntToken(ParamsSize,
"expected parameter byte count"))
5036 return Parser.
TokError(
"parameters size out of range");
5040 return getTargetStreamer().emitFPOProc(ProcSym, ParamsSize, L);
5044bool X86AsmParser::parseDirectiveFPOSetFrame(SMLoc L) {
5047 if (parseRegister(
Reg, DummyLoc, DummyLoc) || parseEOL())
5049 return getTargetStreamer().emitFPOSetFrame(
Reg, L);
5053bool X86AsmParser::parseDirectiveFPOPushReg(SMLoc L) {
5056 if (parseRegister(
Reg, DummyLoc, DummyLoc) || parseEOL())
5058 return getTargetStreamer().emitFPOPushReg(
Reg, L);
5062bool X86AsmParser::parseDirectiveFPOStackAlloc(SMLoc L) {
5063 MCAsmParser &Parser = getParser();
5067 return getTargetStreamer().emitFPOStackAlloc(
Offset, L);
5071bool X86AsmParser::parseDirectiveFPOStackAlign(SMLoc L) {
5072 MCAsmParser &Parser = getParser();
5076 return getTargetStreamer().emitFPOStackAlign(
Offset, L);
5080bool X86AsmParser::parseDirectiveFPOEndPrologue(SMLoc L) {
5081 MCAsmParser &Parser = getParser();
5084 return getTargetStreamer().emitFPOEndPrologue(L);
5088bool X86AsmParser::parseDirectiveFPOEndProc(SMLoc L) {
5089 MCAsmParser &Parser = getParser();
5092 return getTargetStreamer().emitFPOEndProc(L);
5095bool X86AsmParser::parseSEHRegisterNumber(
unsigned RegClassID,
5096 MCRegister &RegNo) {
5097 SMLoc startLoc = getLexer().getLoc();
5098 const MCRegisterInfo *MRI =
getContext().getRegisterInfo();
5103 if (parseRegister(RegNo, startLoc, endLoc))
5106 if (!getX86MCRegisterClass(RegClassID).
contains(RegNo)) {
5107 return Error(startLoc,
5108 "register is not supported for use with this directive");
5114 if (getParser().parseAbsoluteExpression(EncodedReg))
5119 RegNo = MCRegister();
5120 for (
MCPhysReg Reg : getX86MCRegisterClass(RegClassID)) {
5127 return Error(startLoc,
5128 "incorrect register number for use with this directive");
5135bool X86AsmParser::parseDirectiveSEHPushReg(SMLoc Loc) {
5137 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5141 return TokError(
"expected end of directive");
5144 getStreamer().emitWinCFIPushReg(
Reg, Loc);
5148bool X86AsmParser::parseDirectiveSEHPush2Regs(SMLoc Loc,
bool SwapRegs) {
5150 if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg1))
5154 return TokError(
"expected comma between registers");
5158 if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg2))
5162 return TokError(
"expected end of directive");
5168 getStreamer().emitWinCFIPush2Regs(Reg1, Reg2, Loc);
5172bool X86AsmParser::parseDirectiveSEHSetFrame(SMLoc Loc) {
5175 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5178 return TokError(
"you must specify a stack pointer offset");
5181 if (getParser().parseAbsoluteExpression(Off))
5185 return TokError(
"expected end of directive");
5188 getStreamer().emitWinCFISetFrame(
Reg, Off, Loc);
5192bool X86AsmParser::parseDirectiveSEHSaveReg(SMLoc Loc) {
5195 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5198 return TokError(
"you must specify an offset on the stack");
5201 if (getParser().parseAbsoluteExpression(Off))
5205 return TokError(
"expected end of directive");
5208 getStreamer().emitWinCFISaveReg(
Reg, Off, Loc);
5212bool X86AsmParser::parseDirectiveSEHSaveXMM(SMLoc Loc) {
5215 if (parseSEHRegisterNumber(X86::VR128XRegClassID,
Reg))
5218 return TokError(
"you must specify an offset on the stack");
5221 if (getParser().parseAbsoluteExpression(Off))
5225 return TokError(
"expected end of directive");
5228 getStreamer().emitWinCFISaveXMM(
Reg, Off, Loc);
5232bool X86AsmParser::ensureMasmPrologContext(SMLoc Loc) {
5233 if (getStreamer().isWinCFIPrologEnded()) {
5234 return Error(Loc,
"prolog directive must be used inside a prolog");
5239bool X86AsmParser::ensureMasmEpilogContext(SMLoc Loc) {
5240 if (!getStreamer().isInEpilogCFI()) {
5241 return Error(Loc,
"epilog directive must be used inside an epilog");
5246bool X86AsmParser::parseDirectiveSEHPushFrame(SMLoc Loc) {
5250 SMLoc startLoc = getLexer().getLoc();
5252 if (!getParser().parseIdentifier(CodeID)) {
5253 if (CodeID !=
"code")
5254 return Error(startLoc,
"expected @code");
5257 }
else if (getParser().isParsingMasm() &&
5259 getTok().getString().equals_insensitive(
"code")) {
5265 return TokError(
"expected end of directive");
5268 getStreamer().emitWinCFIPushFrame(Code, Loc);
5278#define GET_MATCHER_IMPLEMENTATION
5279#include "X86GenAsmMatcher.inc"
static MCRegister MatchRegisterName(StringRef Name)
static const char * getSubtargetFeatureName(uint64_t Val)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
Function Alias Analysis false
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
amode Optimize addressing mode
Value * getPointer(Value *Ptr)
static ModuleSymbolTable::Symbol getSym(DataRefImpl &Symb)
static constexpr Value * getValue(Ty &ValueOrUse)
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static bool hasFeature(StringRef Feature, const FeatureBitset &FeatureBits, ArrayRef< SubtargetFeatureKV > ProcFeatures)
static bool IsVCMP(unsigned Opcode)
static constexpr unsigned SM(unsigned Version)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
OptimizedStructLayoutField Field
static StringRef getName(Value *V)
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallString class.
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static SymbolRef::Type getType(const Symbol *Sym)
#define LLVM_C_ABI
LLVM_C_ABI is the export/visibility macro used to mark symbols declared in llvm-c as exported when bu...
static cl::opt< bool > LVIInlineAsmHardening("x86-experimental-lvi-inline-asm-hardening", cl::desc("Harden inline assembly code that may be vulnerable to Load Value" " Injection (LVI). This feature is experimental."), cl::Hidden)
static bool checkScale(unsigned Scale, StringRef &ErrMsg)
LLVM_C_ABI void LLVMInitializeX86AsmParser()
static bool convertSSEToAVX(MCInst &Inst)
static unsigned getPrefixes(OperandVector &Operands)
static bool CheckBaseRegAndIndexRegAndScale(MCRegister BaseReg, MCRegister IndexReg, unsigned Scale, bool Is64BitMode, StringRef &ErrMsg)
#define FROM_TO(FROM, TO)
uint16_t RegSizeInBits(const MCRegisterInfo &MRI, MCRegister RegNo)
static unsigned getSize(unsigned Kind)
uint64_t getZExtValue() const
Get zero extended value.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
void UnLex(AsmToken const &Token)
bool isNot(AsmToken::TokenKind K) const
Check if the current token has kind K.
LLVM_ABI SMLoc getLoc() const
int64_t getIntVal() const
bool isNot(TokenKind K) const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
bool is(TokenKind K) const
TokenKind getKind() const
LLVM_ABI SMLoc getEndLoc() const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
bool Error(SMLoc L, const Twine &Msg, SMRange Range={})
Return an error at the location L, with the message Msg.
bool parseIntToken(int64_t &V, const Twine &ErrMsg="expected integer")
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual bool isParsingMasm() const
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents.
bool parseOptionalToken(AsmToken::TokenKind T)
Attempt to parse and consume token, returning true on success.
virtual bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc, AsmTypeInfo *TypeInfo=nullptr)=0
Parse a primary expression.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
bool TokError(const Twine &Msg, SMRange Range={})
Report an error at the current lexer location.
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
virtual bool lookUpType(StringRef Name, AsmTypeInfo &Info) const
virtual bool parseAbsoluteExpression(int64_t &Res)=0
Parse an expression which must evaluate to an absolute value.
virtual bool lookUpField(StringRef Name, AsmFieldInfo &Info) const
bool parseTokenLoc(SMLoc &Loc)
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
@ SymbolRef
References to labels and assigned expressions.
Instances of this class represent a single low-level machine instruction.
unsigned getNumOperands() const
unsigned getFlags() const
unsigned getOpcode() const
void setFlags(unsigned F)
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
const MCOperand & getOperand(unsigned i) const
bool mayLoad() const
Return true if this instruction could possibly read memory.
bool isCall() const
Return true if the instruction is a call.
bool isTerminator() const
Returns true if this instruction part of the terminator for a basic block.
static MCOperand createImm(int64_t Val)
MCRegister getReg() const
Returns the register number.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
uint16_t getEncodingValue(MCRegister Reg) const
Returns the encoding for Reg.
Wrapper class representing physical registers. Should be passed by value.
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.
std::variant< std::monostate, Loc::Single, Loc::Multi, Loc::MMI, Loc::EntryValue > Variant
Alias for the std::variant specialization base class of DbgVariable.
@ CE
Windows NT (Windows on ARM)
@ X86
Windows x64, Windows Itanium (IA-64)
bool isX86_64NonExtLowByteReg(MCRegister Reg)
@ EVEX
EVEX - Specifies that this instruction use EVEX form which provides syntax support up to 32 512-bit r...
@ VEX
VEX - encoding using 0xC4/0xC5.
@ XOP
XOP - Opcode prefix used by XOP instructions.
@ ExplicitVEXPrefix
For instructions that use VEX encoding only when {vex}, {vex2} or {vex3} is present.
bool canUseApxExtendedReg(const MCInstrDesc &Desc)
bool isX86_64ExtendedReg(MCRegister Reg)
bool isApxExtendedReg(MCRegister Reg)
void emitInstruction(MCObjectStreamer &, const MCInst &Inst, const MCSubtargetInfo &STI)
bool optimizeShiftRotateWithImmediateOne(MCInst &MI)
bool optimizeInstFromVEX3ToVEX2(MCInst &MI, const MCInstrDesc &Desc)
NodeAddr< CodeNode * > Code
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
MCRegister getX86SubSuperRegister(MCRegister Reg, unsigned Size, bool High=false)
Target & getTheX86_32Target()
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
Target & getTheX86_64Target()
StringRef toStringRef(bool B)
Construct a string ref from a boolean.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
bool isKind(IdKind kind) const
SmallVectorImpl< AsmRewrite > * AsmRewrites
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
X86Operand - Instances of this class represent a parsed X86 machine instruction.
SMLoc getStartLoc() const override
getStartLoc - Get the location of the first token of this operand.
bool isImm() const override
isImm - Is this an immediate operand?
static std::unique_ptr< X86Operand > CreateImm(const MCExpr *Val, SMLoc StartLoc, SMLoc EndLoc, StringRef SymName=StringRef(), void *OpDecl=nullptr, bool GlobalRef=true)
static std::unique_ptr< X86Operand > CreatePrefix(unsigned Prefixes, SMLoc StartLoc, SMLoc EndLoc)
static std::unique_ptr< X86Operand > CreateDXReg(SMLoc StartLoc, SMLoc EndLoc)
static std::unique_ptr< X86Operand > CreateReg(MCRegister Reg, SMLoc StartLoc, SMLoc EndLoc, bool AddressOf=false, SMLoc OffsetOfLoc=SMLoc(), StringRef SymName=StringRef(), void *OpDecl=nullptr)
SMRange getLocRange() const
getLocRange - Get the range between the first and last token of this operand.
SMLoc getEndLoc() const override
getEndLoc - Get the location of the last token of this operand.
bool isReg() const override
isReg - Is this a register operand?
bool isMem() const override
isMem - Is this a memory operand?
static std::unique_ptr< X86Operand > CreateMem(unsigned ModeSize, const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc, unsigned Size=0, StringRef SymName=StringRef(), void *OpDecl=nullptr, unsigned FrontendSize=0, bool UseUpRegs=false, bool MaybeDirectBranchDest=true)
Create an absolute memory operand.
static std::unique_ptr< X86Operand > CreateToken(StringRef Str, SMLoc Loc)
bool isMemUnsized() const
const MCExpr * getImm() const
unsigned getMemFrontendSize() const
MCRegister getReg() const override