52 if (Scale != 1 && Scale != 2 && Scale != 4 && Scale != 8) {
53 ErrMsg =
"scale factor in address must be 1, 2, 4 or 8";
62#define GET_X86_SSE2AVX_TABLE
63#include "X86GenInstrMapping.inc"
65static const char OpPrecedence[] = {
91 const X86MCOptions &CLOpts;
92 ParseInstructionInfo *InstInfo;
94 unsigned ForcedDataPrefix = 0;
106 OpcodePrefix ForcedOpcodePrefix = OpcodePrefix_Default;
109 DispEncoding_Default,
114 DispEncoding ForcedDispEncoding = DispEncoding_Default;
117 bool UseApxExtendedReg =
false;
119 bool ForcedNoFlag =
false;
122 SMLoc consumeToken() {
123 MCAsmParser &Parser = getParser();
133 X86TargetStreamer &getTargetStreamer() {
134 assert(getParser().getStreamer().getTargetStreamer() &&
135 "do not have a target streamer");
136 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
137 return static_cast<X86TargetStreamer &
>(TS);
141 uint64_t &ErrorInfo, FeatureBitset &MissingFeatures,
142 bool matchingInlineAsm,
unsigned VariantID = 0) {
145 SwitchMode(X86::Is32Bit);
146 unsigned rv = MatchInstructionImpl(
Operands, Inst, ErrorInfo,
147 MissingFeatures, matchingInlineAsm,
150 SwitchMode(X86::Is16Bit);
154 enum InfixCalculatorTok {
179 enum IntelOperatorKind {
186 enum MasmOperatorKind {
193 class InfixCalculator {
194 typedef std::pair< InfixCalculatorTok, int64_t > ICToken;
198 bool isUnaryOperator(InfixCalculatorTok
Op)
const {
199 return Op == IC_NEG ||
Op == IC_NOT;
203 int64_t popOperand() {
204 assert (!PostfixStack.empty() &&
"Poped an empty stack!");
205 ICToken
Op = PostfixStack.pop_back_val();
206 if (!(
Op.first == IC_IMM ||
Op.first == IC_REGISTER))
210 void pushOperand(InfixCalculatorTok
Op, int64_t Val = 0) {
211 assert ((
Op == IC_IMM ||
Op == IC_REGISTER) &&
212 "Unexpected operand!");
213 PostfixStack.push_back(std::make_pair(
Op, Val));
216 void popOperator() { InfixOperatorStack.pop_back(); }
217 void pushOperator(InfixCalculatorTok
Op) {
219 if (InfixOperatorStack.empty()) {
220 InfixOperatorStack.push_back(
Op);
227 unsigned Idx = InfixOperatorStack.size() - 1;
228 InfixCalculatorTok StackOp = InfixOperatorStack[Idx];
229 if (OpPrecedence[
Op] > OpPrecedence[StackOp] || StackOp == IC_LPAREN) {
230 InfixOperatorStack.push_back(
Op);
236 unsigned ParenCount = 0;
239 if (InfixOperatorStack.empty())
242 Idx = InfixOperatorStack.size() - 1;
243 StackOp = InfixOperatorStack[Idx];
244 if (!(OpPrecedence[StackOp] >= OpPrecedence[
Op] || ParenCount))
249 if (!ParenCount && StackOp == IC_LPAREN)
252 if (StackOp == IC_RPAREN) {
254 InfixOperatorStack.pop_back();
255 }
else if (StackOp == IC_LPAREN) {
257 InfixOperatorStack.pop_back();
259 InfixOperatorStack.pop_back();
260 PostfixStack.push_back(std::make_pair(StackOp, 0));
264 InfixOperatorStack.push_back(
Op);
269 while (!InfixOperatorStack.empty()) {
270 InfixCalculatorTok StackOp = InfixOperatorStack.pop_back_val();
271 if (StackOp != IC_LPAREN && StackOp != IC_RPAREN)
272 PostfixStack.push_back(std::make_pair(StackOp, 0));
275 if (PostfixStack.empty())
279 for (
const ICToken &
Op : PostfixStack) {
280 if (
Op.first == IC_IMM ||
Op.first == IC_REGISTER) {
282 }
else if (isUnaryOperator(
Op.first)) {
283 assert (OperandStack.
size() > 0 &&
"Too few operands.");
285 assert (Operand.first == IC_IMM &&
286 "Unary operation with a register!");
292 OperandStack.
push_back(std::make_pair(IC_IMM, -Operand.second));
295 OperandStack.
push_back(std::make_pair(IC_IMM, ~Operand.second));
299 assert (OperandStack.
size() > 1 &&
"Too few operands.");
308 Val = Op1.second + Op2.second;
309 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
312 Val = Op1.second - Op2.second;
313 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
316 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
317 "Multiply operation with an immediate and a register!");
318 Val = Op1.second * Op2.second;
319 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
322 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
323 "Divide operation with an immediate and a register!");
324 assert (Op2.second != 0 &&
"Division by zero!");
325 Val = Op1.second / Op2.second;
326 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
329 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
330 "Modulo operation with an immediate and a register!");
331 Val = Op1.second % Op2.second;
332 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
335 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
336 "Or operation with an immediate and a register!");
337 Val = Op1.second | Op2.second;
338 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
341 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
342 "Xor operation with an immediate and a register!");
343 Val = Op1.second ^ Op2.second;
344 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
347 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
348 "And operation with an immediate and a register!");
349 Val = Op1.second & Op2.second;
350 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
353 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
354 "Left shift operation with an immediate and a register!");
355 Val = Op1.second << Op2.second;
356 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
359 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
360 "Right shift operation with an immediate and a register!");
361 Val = Op1.second >> Op2.second;
362 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
365 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
366 "Equals operation with an immediate and a register!");
367 Val = (Op1.second == Op2.second) ? -1 : 0;
368 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
371 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
372 "Not-equals operation with an immediate and a register!");
373 Val = (Op1.second != Op2.second) ? -1 : 0;
374 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
377 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
378 "Less-than operation with an immediate and a register!");
379 Val = (Op1.second < Op2.second) ? -1 : 0;
380 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
383 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
384 "Less-than-or-equal operation with an immediate and a "
386 Val = (Op1.second <= Op2.second) ? -1 : 0;
387 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
390 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
391 "Greater-than operation with an immediate and a register!");
392 Val = (Op1.second > Op2.second) ? -1 : 0;
393 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
396 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
397 "Greater-than-or-equal operation with an immediate and a "
399 Val = (Op1.second >= Op2.second) ? -1 : 0;
400 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
405 assert (OperandStack.
size() == 1 &&
"Expected a single result.");
410 enum IntelExprState {
440 class IntelExprStateMachine {
441 IntelExprState State = IES_INIT, PrevState = IES_ERROR;
442 MCRegister BaseReg, IndexReg, TmpReg;
444 std::optional<unsigned> TmpScale = {};
446 const MCExpr *Sym =
nullptr;
449 InlineAsmIdentifierInfo Info;
451 short ParenCount = 0;
453 bool MemExpr =
false;
454 bool BracketUsed =
false;
455 bool NegativeAdditiveTerm =
false;
456 SMLoc NegativeAdditiveTermLoc;
457 bool OffsetOperator =
false;
458 bool AttachToOperandIdx =
false;
462 bool setSymRef(
const MCExpr *Val, StringRef ID, StringRef &ErrMsg) {
464 ErrMsg =
"cannot use more than one symbol in memory operand";
473 IntelExprStateMachine() =
default;
475 void addImm(int64_t imm) { Imm += imm; }
476 short getBracCount()
const {
return BracCount; }
477 bool isMemExpr()
const {
return MemExpr; }
478 bool isBracketUsed()
const {
return BracketUsed; }
479 bool isOffsetOperator()
const {
return OffsetOperator; }
480 MCRegister getBaseReg()
const {
return BaseReg; }
481 MCRegister getIndexReg()
const {
return IndexReg; }
482 unsigned getScale()
const {
return Scale; }
483 const MCExpr *
getSym()
const {
return Sym; }
484 StringRef getSymName()
const {
return SymName; }
485 StringRef
getType()
const {
return CurType.Name; }
486 unsigned getSize()
const {
return CurType.Size; }
487 unsigned getElementSize()
const {
return CurType.ElementSize; }
488 unsigned getLength()
const {
return CurType.Length; }
489 int64_t
getImm() {
return Imm + IC.execute(); }
490 bool isValidEndState()
const {
491 return State == IES_RBRAC || State == IES_RPAREN ||
492 State == IES_INTEGER || State == IES_REGISTER ||
495 bool hasUnmatchedParen()
const {
return ParenCount != 0; }
496 SMLoc getLParenLoc()
const {
return LParenLoc; }
502 void setAppendAfterOperand() { AttachToOperandIdx =
true; }
504 bool isPIC()
const {
return IsPIC; }
505 void setPIC() { IsPIC =
true; }
507 bool hadError()
const {
return State == IES_ERROR; }
508 SMLoc getErrorLoc(SMLoc DefaultLoc)
const {
509 return NegativeAdditiveTerm ? NegativeAdditiveTermLoc : DefaultLoc;
511 const InlineAsmIdentifierInfo &getIdentifierInfo()
const {
return Info; }
513 bool regsUseUpError(StringRef &ErrMsg) {
516 if (IsPIC && AttachToOperandIdx)
517 ErrMsg =
"Don't use 2 or more regs for mem offset in PIC model!";
519 ErrMsg =
"BaseReg/IndexReg already set!";
524 IntelExprState CurrState = State;
533 IC.pushOperator(IC_OR);
536 PrevState = CurrState;
539 IntelExprState CurrState = State;
548 IC.pushOperator(IC_XOR);
551 PrevState = CurrState;
554 IntelExprState CurrState = State;
563 IC.pushOperator(IC_AND);
566 PrevState = CurrState;
569 IntelExprState CurrState = State;
578 IC.pushOperator(IC_EQ);
581 PrevState = CurrState;
584 IntelExprState CurrState = State;
593 IC.pushOperator(IC_NE);
596 PrevState = CurrState;
599 IntelExprState CurrState = State;
608 IC.pushOperator(IC_LT);
611 PrevState = CurrState;
614 IntelExprState CurrState = State;
623 IC.pushOperator(IC_LE);
626 PrevState = CurrState;
629 IntelExprState CurrState = State;
638 IC.pushOperator(IC_GT);
641 PrevState = CurrState;
644 IntelExprState CurrState = State;
653 IC.pushOperator(IC_GE);
656 PrevState = CurrState;
659 IntelExprState CurrState = State;
668 IC.pushOperator(IC_LSHIFT);
671 PrevState = CurrState;
674 IntelExprState CurrState = State;
683 IC.pushOperator(IC_RSHIFT);
686 PrevState = CurrState;
688 bool onPlus(StringRef &ErrMsg) {
689 IntelExprState CurrState = State;
699 IC.pushOperator(IC_PLUS);
703 if (!BaseReg && !TmpScale.has_value()) {
708 return regsUseUpError(ErrMsg);
711 if (NegativeAdditiveTerm) {
712 ErrMsg =
"Scale can't be negative";
715 if (TmpScale.has_value() &&
checkScale(TmpScale.value(), ErrMsg)) {
718 Scale = TmpScale.value_or(0);
723 NegativeAdditiveTerm =
false;
724 NegativeAdditiveTermLoc = SMLoc();
727 PrevState = CurrState;
730 bool onMinus(SMLoc MinusLoc, StringRef &ErrMsg) {
731 IntelExprState CurrState = State;
761 NegativeAdditiveTerm =
true;
762 NegativeAdditiveTermLoc = MinusLoc;
764 if (CurrState == IES_REGISTER || CurrState == IES_RPAREN ||
765 CurrState == IES_INTEGER || CurrState == IES_RBRAC ||
766 CurrState == IES_OFFSET) {
767 IC.pushOperator(IC_MINUS);
771 if (!BaseReg && !TmpScale.has_value()) {
776 return regsUseUpError(ErrMsg);
779 if (TmpScale.has_value() &&
783 Scale = TmpScale.value_or(0);
786 }
else if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
788 ErrMsg =
"Scale can't be negative";
791 IC.pushOperator(IC_NEG);
796 PrevState = CurrState;
800 IntelExprState CurrState = State;
826 IC.pushOperator(IC_NOT);
829 PrevState = CurrState;
831 bool onRegister(MCRegister
Reg, StringRef &ErrMsg) {
832 IntelExprState CurrState = State;
840 State = IES_REGISTER;
842 IC.pushOperand(IC_REGISTER);
843 if (NegativeAdditiveTerm) {
844 ErrMsg =
"Scale can't be negative";
852 ErrMsg =
"Register can't be multiplied with register!";
855 State = IES_REGISTER;
860 if (TmpScale.has_value()) {
862 return regsUseUpError(ErrMsg);
863 if (NegativeAdditiveTerm) {
864 ErrMsg =
"Scale can't be negative";
869 IC.pushOperand(IC_IMM);
871 IC.pushOperand(IC_REGISTER);
875 PrevState = CurrState;
878 bool onIdentifierExpr(
const MCExpr *SymRef, StringRef SymRefName,
879 const InlineAsmIdentifierInfo &IDInfo,
880 const AsmTypeInfo &
Type,
bool ParsingMSInlineAsm,
883 if (ParsingMSInlineAsm)
888 return onInteger(
CE->getValue(), ErrMsg);
901 if (setSymRef(SymRef, SymRefName, ErrMsg))
907 IC.pushOperand(IC_IMM);
908 if (ParsingMSInlineAsm)
915 bool onInteger(int64_t TmpInt, StringRef &ErrMsg) {
916 IntelExprState CurrState = State;
923 ErrMsg =
"division by zero in assembly expression";
930 ErrMsg =
"modulo by zero in assembly expression";
955 if (TmpScale.has_value()) {
956 TmpScale.value() *= TmpInt;
961 if (TmpReg && NegativeAdditiveTerm) {
962 ErrMsg =
"Scale can't be negative";
965 if (TmpReg &&
checkScale(TmpScale.value(), ErrMsg))
967 IC.pushOperand(IC_IMM, TmpInt);
970 PrevState = CurrState;
980 State = IES_MULTIPLY;
981 IC.pushOperator(IC_MULTIPLY);
988 if (TmpReg && (!TmpScale.has_value())) {
990 IC.pushOperand(IC_IMM);
992 State = IES_MULTIPLY;
993 IC.pushOperator(IC_MULTIPLY);
1006 IC.pushOperator(IC_DIVIDE);
1019 IC.pushOperator(IC_MOD);
1035 IC.pushOperator(IC_PLUS);
1037 CurType.Size = CurType.ElementSize;
1041 assert(!BracCount &&
"BracCount should be zero on parsing's start");
1045 NegativeAdditiveTerm =
false;
1046 NegativeAdditiveTermLoc = SMLoc();
1054 bool onRBrac(StringRef &ErrMsg) {
1055 IntelExprState CurrState = State;
1064 if (BracCount-- != 1) {
1065 ErrMsg =
"unexpected bracket encountered";
1073 if (!BaseReg && !TmpScale.has_value()) {
1076 }
else if (!IndexReg) {
1077 if (NegativeAdditiveTerm) {
1078 ErrMsg =
"Scale can't be negative";
1083 if (TmpScale.has_value() &&
checkScale(TmpScale.value(), ErrMsg)) {
1086 Scale = TmpScale.value_or(0);
1088 return regsUseUpError(ErrMsg);
1091 NegativeAdditiveTerm =
false;
1092 NegativeAdditiveTermLoc = SMLoc();
1097 PrevState = CurrState;
1100 void onLParen(SMLoc Loc) {
1101 IntelExprState CurrState = State;
1129 IC.pushOperator(IC_LPAREN);
1132 PrevState = CurrState;
1134 bool onRParen(StringRef &ErrMsg) {
1135 IntelExprState CurrState = State;
1145 if (ParenCount == 0) {
1146 ErrMsg =
"unmatched parenthesis";
1151 IC.pushOperator(IC_RPAREN);
1154 PrevState = CurrState;
1157 bool onOffset(
const MCExpr *Val, StringRef ID,
1158 const InlineAsmIdentifierInfo &IDInfo,
1159 bool ParsingMSInlineAsm, StringRef &ErrMsg) {
1163 ErrMsg =
"unexpected offset operator expression";
1168 if (setSymRef(Val, ID, ErrMsg))
1170 OffsetOperator =
true;
1174 IC.pushOperand(IC_IMM);
1175 if (ParsingMSInlineAsm) {
1185 bool onImagerel(
const MCExpr *Val, StringRef ID, StringRef &ErrMsg) {
1191 if (setSymRef(Val, ID, ErrMsg))
1194 IC.pushOperand(IC_IMM);
1197 ErrMsg =
"unexpected imagerel operator expression";
1201 void onCast(AsmTypeInfo Info) {
1213 void setTypeInfo(AsmTypeInfo
Type) { CurType =
Type; }
1217 bool MatchingInlineAsm =
false) {
1218 MCAsmParser &Parser = getParser();
1219 if (MatchingInlineAsm) {
1225 bool MatchRegisterByName(MCRegister &RegNo, StringRef
RegName, SMLoc StartLoc,
1227 bool ParseRegister(MCRegister &RegNo, SMLoc &StartLoc, SMLoc &EndLoc,
1228 bool RestoreOnFailure);
1230 std::unique_ptr<X86Operand> DefaultMemSIOperand(SMLoc Loc);
1231 std::unique_ptr<X86Operand> DefaultMemDIOperand(SMLoc Loc);
1232 bool IsSIReg(MCRegister
Reg);
1233 MCRegister GetSIDIForRegClass(
unsigned RegClassID,
bool IsSIReg);
1236 std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
1237 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst);
1243 bool ParseIntelOffsetOperator(
const MCExpr *&Val, StringRef &ID,
1244 InlineAsmIdentifierInfo &Info, SMLoc &End);
1245 bool ParseIntelImagerelOperator(
const MCExpr *&Val, StringRef &ID,
1246 InlineAsmIdentifierInfo &Info, SMLoc &End);
1247 bool ParseIntelDotOperator(IntelExprStateMachine &SM, SMLoc &End);
1248 unsigned IdentifyIntelInlineAsmOperator(StringRef Name);
1249 unsigned ParseIntelInlineAsmOperator(
unsigned OpKind);
1250 unsigned IdentifyMasmOperator(StringRef Name);
1251 bool ParseMasmOperator(
unsigned OpKind, int64_t &Val);
1254 bool ParseIntelNamedOperator(StringRef Name, IntelExprStateMachine &SM,
1255 bool &ParseError, SMLoc &End);
1256 bool ParseMasmNamedOperator(StringRef Name, IntelExprStateMachine &SM,
1257 bool &ParseError, SMLoc &End);
1258 void RewriteIntelExpression(IntelExprStateMachine &SM, SMLoc Start,
1260 bool ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End);
1261 bool ParseIntelInlineAsmIdentifier(
const MCExpr *&Val, StringRef &Identifier,
1262 InlineAsmIdentifierInfo &Info,
1263 bool IsUnevaluatedOperand, SMLoc &End,
1264 bool IsParsingOffsetOperator =
false);
1266 IntelExprStateMachine &SM);
1268 bool CheckDispOverflow(MCRegister BaseReg, MCRegister IndexReg,
1269 const MCExpr *Disp, SMLoc Loc);
1271 bool ParseMemOperand(MCRegister SegReg,
const MCExpr *Disp, SMLoc StartLoc,
1276 bool ParseIntelMemoryOperandSize(
unsigned &
Size, StringRef *SizeStr);
1277 bool CreateMemForMSInlineAsm(MCRegister SegReg,
const MCExpr *Disp,
1278 MCRegister BaseReg, MCRegister IndexReg,
1279 unsigned Scale,
bool NonAbsMem, SMLoc Start,
1280 SMLoc End,
unsigned Size, StringRef Identifier,
1281 const InlineAsmIdentifierInfo &Info,
1284 bool parseDirectiveArch();
1285 bool parseDirectiveNops(SMLoc L);
1286 bool parseDirectiveEven(SMLoc L);
1287 bool ParseDirectiveCode(StringRef IDVal, SMLoc L);
1290 bool parseDirectiveFPOProc(SMLoc L);
1291 bool parseDirectiveFPOSetFrame(SMLoc L);
1292 bool parseDirectiveFPOPushReg(SMLoc L);
1293 bool parseDirectiveFPOStackAlloc(SMLoc L);
1294 bool parseDirectiveFPOStackAlign(SMLoc L);
1295 bool parseDirectiveFPOEndPrologue(SMLoc L);
1296 bool parseDirectiveFPOEndProc(SMLoc L);
1299 bool parseSEHRegisterNumber(
unsigned RegClassID, MCRegister &RegNo);
1300 bool parseDirectiveSEHPushReg(SMLoc);
1301 bool parseDirectiveSEHPush2Regs(SMLoc,
bool SwapRegs =
false);
1302 bool parseDirectiveSEHSetFrame(SMLoc);
1303 bool parseDirectiveSEHSaveReg(SMLoc);
1304 bool parseDirectiveSEHSaveXMM(SMLoc);
1305 bool parseDirectiveSEHPushFrame(SMLoc);
1307 bool ensureMasmEpilogContext(SMLoc Loc);
1308 bool ensureMasmPrologContext(SMLoc Loc);
1310 unsigned checkTargetMatchPredicate(MCInst &Inst)
override;
1316 void emitWarningForSpecialLVIInstruction(SMLoc Loc);
1317 void applyLVICFIMitigation(MCInst &Inst, MCStreamer &Out);
1318 void applyLVILoadHardeningMitigation(MCInst &Inst, MCStreamer &Out);
1324 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1327 bool MatchingInlineAsm)
override;
1330 MCStreamer &Out,
bool MatchingInlineAsm);
1332 bool ErrorMissingFeature(SMLoc IDLoc,
const FeatureBitset &MissingFeatures,
1333 bool MatchingInlineAsm);
1335 bool matchAndEmitATTInstruction(SMLoc IDLoc,
unsigned &Opcode, MCInst &Inst,
1337 uint64_t &ErrorInfo,
bool MatchingInlineAsm);
1339 bool matchAndEmitIntelInstruction(SMLoc IDLoc,
unsigned &Opcode, MCInst &Inst,
1342 bool MatchingInlineAsm);
1344 bool omitRegisterFromClobberLists(MCRegister
Reg)
override;
1351 bool ParseZ(std::unique_ptr<X86Operand> &Z, SMLoc StartLoc);
1353 bool is64BitMode()
const {
1355 return getSTI().hasFeature(X86::Is64Bit);
1357 bool is32BitMode()
const {
1359 return getSTI().hasFeature(X86::Is32Bit);
1361 bool is16BitMode()
const {
1363 return getSTI().hasFeature(X86::Is16Bit);
1365 void SwitchMode(
unsigned mode) {
1366 MCSubtargetInfo &STI = copySTI();
1367 FeatureBitset AllModes({X86::Is64Bit, X86::Is32Bit, X86::Is16Bit});
1369 FeatureBitset FB = ComputeAvailableFeatures(
1371 setAvailableFeatures(FB);
1376 unsigned getPointerWidth() {
1377 if (is16BitMode())
return 16;
1378 if (is32BitMode())
return 32;
1379 if (is64BitMode())
return 64;
1383 bool isParsingIntelSyntax() {
1384 return getParser().getAssemblerDialect();
1390#define GET_ASSEMBLER_HEADER
1391#include "X86GenAsmMatcher.inc"
1396 enum X86MatchResultTy {
1397 Match_Unsupported = FIRST_TARGET_MATCH_RESULT_TY,
1398#define GET_OPERAND_DIAGNOSTIC_TYPES
1399#include "X86GenAsmMatcher.inc"
1402 X86AsmParser(
const MCSubtargetInfo &sti, MCAsmParser &Parser,
1403 const MCInstrInfo &mii)
1404 : MCTargetAsmParser(sti, mii), CLOpts(X86MCOptions::
Global),
1405 InstInfo(nullptr), Code16GCC(
false) {
1410 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
1413 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
1414 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1415 SMLoc &EndLoc)
override;
1417 bool parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc)
override;
1419 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
1422 bool ParseDirective(AsmToken DirectiveID)
override;
1426#define GET_REGISTER_MATCHER
1427#define GET_SUBTARGET_FEATURE_NAME
1428#include "X86GenAsmMatcher.inc"
1439 !(BaseReg == X86::RIP || BaseReg == X86::EIP ||
1440 getX86MCRegisterClass(X86::GR16RegClassID).
contains(BaseReg) ||
1441 getX86MCRegisterClass(X86::GR32RegClassID).
contains(BaseReg) ||
1442 getX86MCRegisterClass(X86::GR64RegClassID).
contains(BaseReg))) {
1443 ErrMsg =
"invalid base+index expression";
1448 !(IndexReg == X86::EIZ || IndexReg == X86::RIZ ||
1449 getX86MCRegisterClass(X86::GR16RegClassID).
contains(IndexReg) ||
1450 getX86MCRegisterClass(X86::GR32RegClassID).
contains(IndexReg) ||
1451 getX86MCRegisterClass(X86::GR64RegClassID).
contains(IndexReg) ||
1452 getX86MCRegisterClass(X86::VR128XRegClassID).
contains(IndexReg) ||
1453 getX86MCRegisterClass(X86::VR256XRegClassID).
contains(IndexReg) ||
1454 getX86MCRegisterClass(X86::VR512RegClassID).
contains(IndexReg))) {
1455 ErrMsg =
"invalid base+index expression";
1459 if (((BaseReg == X86::RIP || BaseReg == X86::EIP) && IndexReg) ||
1460 IndexReg == X86::EIP || IndexReg == X86::RIP || IndexReg == X86::ESP ||
1461 IndexReg == X86::RSP) {
1462 ErrMsg =
"invalid base+index expression";
1468 if (getX86MCRegisterClass(X86::GR16RegClassID).
contains(BaseReg) &&
1469 (Is64BitMode || (BaseReg != X86::BX && BaseReg != X86::BP &&
1470 BaseReg != X86::SI && BaseReg != X86::DI))) {
1471 ErrMsg =
"invalid 16-bit base register";
1476 getX86MCRegisterClass(X86::GR16RegClassID).
contains(IndexReg)) {
1477 ErrMsg =
"16-bit memory operand may not include only index register";
1481 if (BaseReg && IndexReg) {
1482 if (getX86MCRegisterClass(X86::GR64RegClassID).
contains(BaseReg) &&
1483 (getX86MCRegisterClass(X86::GR16RegClassID).
contains(IndexReg) ||
1484 getX86MCRegisterClass(X86::GR32RegClassID).
contains(IndexReg) ||
1485 IndexReg == X86::EIZ)) {
1486 ErrMsg =
"base register is 64-bit, but index register is not";
1489 if (getX86MCRegisterClass(X86::GR32RegClassID).
contains(BaseReg) &&
1490 (getX86MCRegisterClass(X86::GR16RegClassID).
contains(IndexReg) ||
1491 getX86MCRegisterClass(X86::GR64RegClassID).
contains(IndexReg) ||
1492 IndexReg == X86::RIZ)) {
1493 ErrMsg =
"base register is 32-bit, but index register is not";
1496 if (getX86MCRegisterClass(X86::GR16RegClassID).
contains(BaseReg)) {
1497 if (getX86MCRegisterClass(X86::GR32RegClassID).
contains(IndexReg) ||
1498 getX86MCRegisterClass(X86::GR64RegClassID).
contains(IndexReg)) {
1499 ErrMsg =
"base register is 16-bit, but index register is not";
1502 if ((BaseReg != X86::BX && BaseReg != X86::BP) ||
1503 (IndexReg != X86::SI && IndexReg != X86::DI)) {
1504 ErrMsg =
"invalid 16-bit base/index register combination";
1511 if (!Is64BitMode && (BaseReg == X86::RIP || BaseReg == X86::EIP)) {
1512 ErrMsg =
"IP-relative addressing requires 64-bit mode";
1533 if (isParsingMSInlineAsm() && isParsingIntelSyntax() &&
1534 (RegNo == X86::EFLAGS || RegNo == X86::MXCSR))
1535 RegNo = MCRegister();
1537 if (!is64BitMode()) {
1541 if (RegNo == X86::RIZ || RegNo == X86::RIP ||
1542 getX86MCRegisterClass(X86::GR64RegClassID).
contains(RegNo) ||
1545 return Error(StartLoc,
1546 "register %" +
RegName +
" is only available in 64-bit mode",
1547 SMRange(StartLoc, EndLoc));
1552 UseApxExtendedReg =
true;
1556 if (!RegNo &&
RegName.starts_with(
"db")) {
1615 if (isParsingIntelSyntax())
1617 return Error(StartLoc,
"invalid register name", SMRange(StartLoc, EndLoc));
1622bool X86AsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
1623 SMLoc &EndLoc,
bool RestoreOnFailure) {
1624 MCAsmParser &Parser = getParser();
1625 AsmLexer &Lexer = getLexer();
1626 RegNo = MCRegister();
1629 auto OnFailure = [RestoreOnFailure, &Lexer, &Tokens]() {
1630 if (RestoreOnFailure) {
1631 while (!Tokens.
empty()) {
1637 const AsmToken &PercentTok = Parser.
getTok();
1638 StartLoc = PercentTok.
getLoc();
1647 const AsmToken &Tok = Parser.
getTok();
1652 if (isParsingIntelSyntax())
return true;
1653 return Error(StartLoc,
"invalid register name",
1654 SMRange(StartLoc, EndLoc));
1657 if (MatchRegisterByName(RegNo, Tok.
getString(), StartLoc, EndLoc)) {
1663 if (RegNo == X86::ST0) {
1674 const AsmToken &IntTok = Parser.
getTok();
1677 return Error(IntTok.
getLoc(),
"expected stack index");
1680 case 0: RegNo = X86::ST0;
break;
1681 case 1: RegNo = X86::ST1;
break;
1682 case 2: RegNo = X86::ST2;
break;
1683 case 3: RegNo = X86::ST3;
break;
1684 case 4: RegNo = X86::ST4;
break;
1685 case 5: RegNo = X86::ST5;
break;
1686 case 6: RegNo = X86::ST6;
break;
1687 case 7: RegNo = X86::ST7;
break;
1690 return Error(IntTok.
getLoc(),
"invalid stack index");
1710 if (isParsingIntelSyntax())
return true;
1711 return Error(StartLoc,
"invalid register name",
1712 SMRange(StartLoc, EndLoc));
1719bool X86AsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1721 return ParseRegister(
Reg, StartLoc, EndLoc,
false);
1724ParseStatus X86AsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1726 bool Result = ParseRegister(
Reg, StartLoc, EndLoc,
true);
1727 bool PendingErrors = getParser().hasPendingError();
1728 getParser().clearPendingErrors();
1736std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(SMLoc Loc) {
1737 bool Parse32 = is32BitMode() || Code16GCC;
1738 MCRegister Basereg =
1739 is64BitMode() ? X86::RSI : (Parse32 ? X86::ESI : X86::SI);
1746std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand(SMLoc Loc) {
1747 bool Parse32 = is32BitMode() || Code16GCC;
1748 MCRegister Basereg =
1749 is64BitMode() ? X86::RDI : (Parse32 ? X86::EDI : X86::DI);
1756bool X86AsmParser::IsSIReg(MCRegister
Reg) {
1770MCRegister X86AsmParser::GetSIDIForRegClass(
unsigned RegClassID,
bool IsSIReg) {
1771 switch (RegClassID) {
1773 case X86::GR64RegClassID:
1774 return IsSIReg ? X86::RSI : X86::RDI;
1775 case X86::GR32RegClassID:
1776 return IsSIReg ? X86::ESI : X86::EDI;
1777 case X86::GR16RegClassID:
1778 return IsSIReg ? X86::SI : X86::DI;
1782void X86AsmParser::AddDefaultSrcDestOperands(
1784 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst) {
1785 if (isParsingIntelSyntax()) {
1786 Operands.push_back(std::move(Dst));
1787 Operands.push_back(std::move(Src));
1790 Operands.push_back(std::move(Src));
1791 Operands.push_back(std::move(Dst));
1795bool X86AsmParser::VerifyAndAdjustOperands(
OperandVector &OrigOperands,
1798 if (OrigOperands.
size() > 1) {
1801 "Operand size mismatch");
1805 int RegClassID = -1;
1806 for (
unsigned int i = 0; i < FinalOperands.
size(); ++i) {
1807 X86Operand &OrigOp =
static_cast<X86Operand &
>(*OrigOperands[i + 1]);
1808 X86Operand &FinalOp =
static_cast<X86Operand &
>(*FinalOperands[i]);
1810 if (FinalOp.
isReg() &&
1815 if (FinalOp.
isMem()) {
1817 if (!OrigOp.
isMem())
1826 if (RegClassID != -1 &&
1827 !getX86MCRegisterClass(RegClassID).
contains(OrigReg)) {
1829 "mismatching source and destination index registers");
1832 if (getX86MCRegisterClass(X86::GR64RegClassID).
contains(OrigReg))
1833 RegClassID = X86::GR64RegClassID;
1834 else if (getX86MCRegisterClass(X86::GR32RegClassID).
contains(OrigReg))
1835 RegClassID = X86::GR32RegClassID;
1836 else if (getX86MCRegisterClass(X86::GR16RegClassID).
contains(OrigReg))
1837 RegClassID = X86::GR16RegClassID;
1843 bool IsSI = IsSIReg(FinalReg);
1844 FinalReg = GetSIDIForRegClass(RegClassID, IsSI);
1846 if (FinalReg != OrigReg) {
1847 std::string
RegName = IsSI ?
"ES:(R|E)SI" :
"ES:(R|E)DI";
1850 "memory operand is only for determining the size, " +
RegName +
1851 " will be used for the location"));
1862 for (
auto &WarningMsg : Warnings) {
1863 Warning(WarningMsg.first, WarningMsg.second);
1867 for (
unsigned int i = 0; i < FinalOperands.
size(); ++i)
1871 for (
auto &
Op : FinalOperands)
1878 if (isParsingIntelSyntax())
1879 return parseIntelOperand(
Operands, Name);
1884bool X86AsmParser::CreateMemForMSInlineAsm(
1885 MCRegister SegReg,
const MCExpr *Disp, MCRegister BaseReg,
1886 MCRegister IndexReg,
unsigned Scale,
bool NonAbsMem, SMLoc Start, SMLoc End,
1887 unsigned Size, StringRef Identifier,
const InlineAsmIdentifierInfo &Info,
1895 End,
Size, Identifier,
1902 unsigned FrontendSize = 0;
1903 void *Decl =
nullptr;
1904 bool IsGlobalLV =
false;
1907 FrontendSize =
Info.Var.Type * 8;
1908 Decl =
Info.Var.Decl;
1909 IsGlobalLV =
Info.Var.IsGlobalLV;
1914 if (BaseReg || IndexReg) {
1916 End,
Size, Identifier, Decl, 0,
1917 BaseReg && IndexReg));
1924 getPointerWidth(), SegReg, Disp, BaseReg, IndexReg, Scale, Start, End,
1926 X86::RIP, Identifier, Decl, FrontendSize));
1933bool X86AsmParser::ParseIntelNamedOperator(StringRef Name,
1934 IntelExprStateMachine &SM,
1935 bool &ParseError, SMLoc &End) {
1938 if (Name !=
Name.lower() && Name !=
Name.upper() &&
1939 !getParser().isParsingMasm())
1943 bool AlreadyConsumed =
false;
1944 if (
Name.equals_insensitive(
"not")) {
1946 }
else if (
Name.equals_insensitive(
"or")) {
1948 }
else if (
Name.equals_insensitive(
"shl")) {
1950 }
else if (
Name.equals_insensitive(
"shr")) {
1952 }
else if (
Name.equals_insensitive(
"xor")) {
1954 }
else if (
Name.equals_insensitive(
"and")) {
1956 }
else if (
Name.equals_insensitive(
"mod")) {
1958 }
else if (
Name.equals_insensitive(
"offset")) {
1959 const MCExpr *Val =
nullptr;
1961 InlineAsmIdentifierInfo
Info;
1962 ParseError = ParseIntelOffsetOperator(Val, ID, Info, End);
1966 ParseError = SM.onOffset(Val, ID, Info, isParsingMSInlineAsm(), ErrMsg);
1969 AlreadyConsumed =
true;
1970 }
else if (
Name.equals_insensitive(
"imagerel")) {
1973 InlineAsmIdentifierInfo
Info;
1974 ParseError = ParseIntelImagerelOperator(Val, ID, Info, End);
1981 AlreadyConsumed =
true;
1985 if (!AlreadyConsumed)
1986 End = consumeToken();
1989bool X86AsmParser::ParseMasmNamedOperator(StringRef Name,
1990 IntelExprStateMachine &SM,
1991 bool &ParseError, SMLoc &End) {
1992 if (
Name.equals_insensitive(
"eq")) {
1994 }
else if (
Name.equals_insensitive(
"ne")) {
1996 }
else if (
Name.equals_insensitive(
"lt")) {
1998 }
else if (
Name.equals_insensitive(
"le")) {
2000 }
else if (
Name.equals_insensitive(
"gt")) {
2002 }
else if (
Name.equals_insensitive(
"ge")) {
2007 End = consumeToken();
2014 IntelExprStateMachine &SM) {
2018 SM.setAppendAfterOperand();
2021bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
2022 MCAsmParser &Parser = getParser();
2027 if (
getContext().getObjectFileInfo()->isPositionIndependent())
2034 const AsmToken &Tok = Parser.
getTok();
2036 bool UpdateLocLex =
true;
2041 if ((
Done = SM.isValidEndState()))
2043 return Error(Tok.
getLoc(),
"unknown token in expression");
2045 return Error(getLexer().getErrLoc(), getLexer().getErr());
2049 UpdateLocLex =
false;
2050 if (ParseIntelDotOperator(SM, End))
2055 if ((
Done = SM.isValidEndState()))
2057 return Error(Tok.
getLoc(),
"unknown token in expression");
2061 UpdateLocLex =
false;
2062 if (ParseIntelDotOperator(SM, End))
2067 if ((
Done = SM.isValidEndState()))
2069 return Error(Tok.
getLoc(),
"unknown token in expression");
2075 SMLoc ValueLoc = Tok.
getLoc();
2080 UpdateLocLex =
false;
2081 if (!Val->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
2082 return Error(ValueLoc,
"expected absolute value");
2083 if (SM.onInteger(Res, ErrMsg))
2084 return Error(SM.getErrorLoc(ValueLoc), ErrMsg);
2091 SMLoc IdentLoc = Tok.
getLoc();
2093 UpdateLocLex =
false;
2095 size_t DotOffset =
Identifier.find_first_of(
'.');
2099 StringRef Dot =
Identifier.substr(DotOffset, 1);
2113 const AsmToken &NextTok = getLexer().peekTok();
2122 End = consumeToken();
2129 if (!ParseRegister(
Reg, IdentLoc, End,
true)) {
2130 if (SM.onRegister(
Reg, ErrMsg))
2131 return Error(SM.getErrorLoc(IdentLoc), ErrMsg);
2135 const std::pair<StringRef, StringRef> IDField =
2137 const StringRef
ID = IDField.first,
Field = IDField.second;
2139 if (!
Field.empty() &&
2140 !MatchRegisterByName(
Reg, ID, IdentLoc, IDEndLoc)) {
2141 if (SM.onRegister(
Reg, ErrMsg))
2142 return Error(SM.getErrorLoc(IdentLoc), ErrMsg);
2147 return Error(FieldStartLoc,
"unknown offset");
2148 else if (SM.onPlus(ErrMsg))
2149 return Error(getTok().getLoc(), ErrMsg);
2150 else if (SM.onInteger(
Info.Offset, ErrMsg))
2151 return Error(SM.getErrorLoc(IdentLoc), ErrMsg);
2152 SM.setTypeInfo(
Info.Type);
2154 End = consumeToken();
2161 if (ParseIntelNamedOperator(Identifier, SM, ParseError, End)) {
2167 ParseMasmNamedOperator(Identifier, SM, ParseError, End)) {
2173 InlineAsmIdentifierInfo
Info;
2174 AsmFieldInfo FieldInfo;
2180 if (ParseIntelDotOperator(SM, End))
2185 if (isParsingMSInlineAsm()) {
2187 if (
unsigned OpKind = IdentifyIntelInlineAsmOperator(Identifier)) {
2188 if (int64_t Val = ParseIntelInlineAsmOperator(OpKind)) {
2189 if (SM.onInteger(Val, ErrMsg))
2190 return Error(SM.getErrorLoc(IdentLoc), ErrMsg);
2199 return Error(IdentLoc,
"expected identifier");
2200 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
false, End))
2202 else if (SM.onIdentifierExpr(Val, Identifier, Info, FieldInfo.
Type,
2204 return Error(SM.getErrorLoc(IdentLoc), ErrMsg);
2208 if (
unsigned OpKind = IdentifyMasmOperator(Identifier)) {
2210 if (ParseMasmOperator(OpKind, Val))
2212 if (SM.onInteger(Val, ErrMsg))
2213 return Error(SM.getErrorLoc(IdentLoc), ErrMsg);
2216 if (!getParser().lookUpType(Identifier, FieldInfo.
Type)) {
2222 getParser().parseIdentifier(Identifier);
2226 if (getParser().lookUpField(FieldInfo.
Type.
Name, Identifier,
2230 return Error(IdentLoc,
"Unable to lookup field reference!",
2231 SMRange(IdentLoc, IDEnd));
2236 if (SM.onInteger(FieldInfo.
Offset, ErrMsg))
2237 return Error(SM.getErrorLoc(IdentLoc), ErrMsg);
2241 if (getParser().parsePrimaryExpr(Val, End, &FieldInfo.
Type)) {
2242 return Error(Tok.
getLoc(),
"Unexpected identifier!");
2243 }
else if (SM.onIdentifierExpr(Val, Identifier, Info, FieldInfo.
Type,
2245 return Error(SM.getErrorLoc(IdentLoc), ErrMsg);
2251 SMLoc Loc = getTok().getLoc();
2252 int64_t
IntVal = getTok().getIntVal();
2253 End = consumeToken();
2254 UpdateLocLex =
false;
2256 StringRef IDVal = getTok().getString();
2257 if (IDVal ==
"f" || IDVal ==
"b") {
2259 getContext().getDirectionalLocalSymbol(IntVal, IDVal ==
"b");
2264 return Error(Loc,
"invalid reference to undefined symbol");
2266 InlineAsmIdentifierInfo
Info;
2268 if (SM.onIdentifierExpr(Val, Identifier, Info,
Type,
2269 isParsingMSInlineAsm(), ErrMsg))
2270 return Error(SM.getErrorLoc(Loc), ErrMsg);
2271 End = consumeToken();
2273 if (SM.onInteger(IntVal, ErrMsg))
2274 return Error(SM.getErrorLoc(Loc), ErrMsg);
2277 if (SM.onInteger(IntVal, ErrMsg))
2278 return Error(SM.getErrorLoc(Loc), ErrMsg);
2283 if (SM.onPlus(ErrMsg))
2284 return Error(getTok().getLoc(), ErrMsg);
2287 if (SM.onMinus(getTok().getLoc(), ErrMsg))
2288 return Error(SM.getErrorLoc(getTok().getLoc()), ErrMsg);
2298 SM.onLShift();
break;
2300 SM.onRShift();
break;
2303 return Error(Tok.
getLoc(),
"unexpected bracket encountered");
2304 tryParseOperandIdx(PrevTK, SM);
2307 if (SM.onRBrac(ErrMsg)) {
2308 return Error(SM.getErrorLoc(Tok.
getLoc()), ErrMsg);
2312 SM.onLParen(Tok.
getLoc());
2315 if (SM.onRParen(ErrMsg)) {
2316 return Error(SM.getErrorLoc(Tok.
getLoc()), ErrMsg);
2321 return Error(Tok.
getLoc(),
"unknown token in expression");
2323 if (!
Done && UpdateLocLex)
2324 End = consumeToken();
2328 if (SM.hasUnmatchedParen())
2329 return Error(SM.getLParenLoc(),
"unmatched parenthesis");
2333void X86AsmParser::RewriteIntelExpression(IntelExprStateMachine &SM,
2334 SMLoc Start, SMLoc End) {
2338 if (SM.getSym() && !SM.isOffsetOperator()) {
2339 StringRef SymName = SM.getSymName();
2340 if (
unsigned Len = SymName.
data() -
Start.getPointer())
2346 if (!(SM.getBaseReg() || SM.getIndexReg() || SM.getImm())) {
2353 StringRef BaseRegStr;
2354 StringRef IndexRegStr;
2355 StringRef OffsetNameStr;
2356 if (SM.getBaseReg())
2358 if (SM.getIndexReg())
2360 if (SM.isOffsetOperator())
2361 OffsetNameStr = SM.getSymName();
2363 IntelExpr Expr(BaseRegStr, IndexRegStr, SM.getScale(), OffsetNameStr,
2364 SM.getImm(), SM.isMemExpr());
2365 InstInfo->
AsmRewrites->emplace_back(Loc, ExprLen, Expr);
2369bool X86AsmParser::ParseIntelInlineAsmIdentifier(
2370 const MCExpr *&Val, StringRef &Identifier, InlineAsmIdentifierInfo &Info,
2371 bool IsUnevaluatedOperand, SMLoc &End,
bool IsParsingOffsetOperator) {
2372 MCAsmParser &Parser = getParser();
2373 assert(isParsingMSInlineAsm() &&
"Expected to be parsing inline assembly.");
2377 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);
2379 const AsmToken &Tok = Parser.
getTok();
2380 SMLoc Loc = Tok.
getLoc();
2395 "frontend claimed part of a token?");
2400 StringRef InternalName =
2401 SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(),
2403 assert(InternalName.
size() &&
"We should have an internal name here.");
2406 if (!IsParsingOffsetOperator)
2422 MCAsmParser &Parser = getParser();
2423 const AsmToken &Tok = Parser.
getTok();
2425 const SMLoc consumedToken = consumeToken();
2427 return Error(Tok.
getLoc(),
"Expected an identifier after {");
2430 .Case(
"rn", X86::STATIC_ROUNDING::TO_NEAREST_INT)
2431 .Case(
"rd", X86::STATIC_ROUNDING::TO_NEG_INF)
2432 .Case(
"ru", X86::STATIC_ROUNDING::TO_POS_INF)
2433 .Case(
"rz", X86::STATIC_ROUNDING::TO_ZERO)
2436 return Error(Tok.
getLoc(),
"Invalid rounding mode.");
2439 return Error(Tok.
getLoc(),
"Expected - at this point");
2443 return Error(Tok.
getLoc(),
"Expected } at this point");
2446 const MCExpr *RndModeOp =
2454 return Error(Tok.
getLoc(),
"Expected } at this point");
2459 return Error(Tok.
getLoc(),
"unknown token in expression");
2465 MCAsmParser &Parser = getParser();
2466 AsmToken Tok = Parser.
getTok();
2469 return Error(Tok.
getLoc(),
"Expected { at this point");
2473 return Error(Tok.
getLoc(),
"Expected dfv at this point");
2477 return Error(Tok.
getLoc(),
"Expected = at this point");
2489 unsigned CFlags = 0;
2490 for (
unsigned I = 0;
I < 4; ++
I) {
2499 return Error(Tok.
getLoc(),
"Invalid conditional flags");
2502 return Error(Tok.
getLoc(),
"Duplicated conditional flag");
2513 }
else if (
I == 3) {
2514 return Error(Tok.
getLoc(),
"Expected } at this point");
2516 return Error(Tok.
getLoc(),
"Expected } or , at this point");
2524bool X86AsmParser::ParseIntelDotOperator(IntelExprStateMachine &SM,
2526 const AsmToken &Tok = getTok();
2532 bool TrailingDot =
false;
2540 }
else if ((isParsingMSInlineAsm() || getParser().isParsingMasm()) &&
2543 const std::pair<StringRef, StringRef> BaseMember = DotDispStr.
split(
'.');
2544 const StringRef
Base = BaseMember.first,
Member = BaseMember.second;
2545 if (getParser().lookUpField(SM.getType(), DotDispStr, Info) &&
2546 getParser().lookUpField(SM.getSymName(), DotDispStr, Info) &&
2547 getParser().lookUpField(DotDispStr, Info) &&
2549 SemaCallback->LookupInlineAsmField(
Base, Member,
Info.Offset)))
2550 return Error(Tok.
getLoc(),
"Unable to lookup field reference!");
2552 return Error(Tok.
getLoc(),
"Unexpected token type!");
2557 const char *DotExprEndLoc = DotDispStr.
data() + DotDispStr.
size();
2562 SM.addImm(
Info.Offset);
2563 SM.setTypeInfo(
Info.Type);
2569bool X86AsmParser::ParseIntelOffsetOperator(
const MCExpr *&Val, StringRef &ID,
2570 InlineAsmIdentifierInfo &Info,
2573 SMLoc
Start = Lex().getLoc();
2574 ID = getTok().getString();
2575 if (!isParsingMSInlineAsm()) {
2578 getParser().parsePrimaryExpr(Val, End,
nullptr))
2579 return Error(Start,
"unexpected token!");
2580 }
else if (ParseIntelInlineAsmIdentifier(Val, ID, Info,
false, End,
true)) {
2581 return Error(Start,
"unable to lookup expression");
2583 return Error(Start,
"offset operator cannot yet handle constants");
2590bool X86AsmParser::ParseIntelImagerelOperator(
const MCExpr *&Val, StringRef &ID,
2591 InlineAsmIdentifierInfo &Info,
2594 SMLoc
Start = Lex().getLoc();
2595 ID = getTok().getString();
2596 if (!isParsingMSInlineAsm()) {
2599 getParser().parsePrimaryExpr(Val, End,
nullptr))
2600 return Error(Start,
"unexpected token!");
2601 }
else if (ParseIntelInlineAsmIdentifier(Val, ID, Info,
false, End,
true)) {
2602 return Error(Start,
"unable to lookup expression");
2604 return Error(Start,
"imagerel operator cannot yet handle constants");
2607 const MCExpr *ModifiedVal =
2610 return Error(Start,
"cannot apply 'imagerel' to this expression");
2617unsigned X86AsmParser::IdentifyIntelInlineAsmOperator(StringRef Name) {
2618 return StringSwitch<unsigned>(Name)
2619 .Cases({
"TYPE",
"type"}, IOK_TYPE)
2620 .Cases({
"SIZE",
"size"}, IOK_SIZE)
2621 .Cases({
"LENGTH",
"length"}, IOK_LENGTH)
2631unsigned X86AsmParser::ParseIntelInlineAsmOperator(
unsigned OpKind) {
2632 MCAsmParser &Parser = getParser();
2633 const AsmToken &Tok = Parser.
getTok();
2636 const MCExpr *Val =
nullptr;
2637 InlineAsmIdentifierInfo
Info;
2640 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
2645 Error(Start,
"unable to lookup expression");
2652 case IOK_LENGTH: CVal =
Info.Var.Length;
break;
2653 case IOK_SIZE: CVal =
Info.Var.Size;
break;
2654 case IOK_TYPE: CVal =
Info.Var.Type;
break;
2662unsigned X86AsmParser::IdentifyMasmOperator(StringRef Name) {
2663 return StringSwitch<unsigned>(
Name.lower())
2664 .Case(
"type", MOK_TYPE)
2665 .Cases({
"size",
"sizeof"}, MOK_SIZEOF)
2666 .Cases({
"length",
"lengthof"}, MOK_LENGTHOF)
2676bool X86AsmParser::ParseMasmOperator(
unsigned OpKind, int64_t &Val) {
2677 MCAsmParser &Parser = getParser();
2682 if (OpKind == MOK_SIZEOF || OpKind == MOK_TYPE) {
2685 const AsmToken &IDTok = InParens ? getLexer().peekTok() : Parser.
getTok();
2701 IntelExprStateMachine SM;
2703 if (ParseIntelExpression(SM, End))
2713 Val = SM.getLength();
2716 Val = SM.getElementSize();
2721 return Error(OpLoc,
"expression has unknown type", SMRange(Start, End));
2727bool X86AsmParser::ParseIntelMemoryOperandSize(
unsigned &
Size,
2728 StringRef *SizeStr) {
2729 Size = StringSwitch<unsigned>(getTok().getString())
2730 .Cases({
"BYTE",
"byte"}, 8)
2731 .Cases({
"WORD",
"word"}, 16)
2732 .Cases({
"DWORD",
"dword"}, 32)
2733 .Cases({
"FLOAT",
"float"}, 32)
2734 .Cases({
"LONG",
"long"}, 32)
2735 .Cases({
"FWORD",
"fword"}, 48)
2736 .Cases({
"DOUBLE",
"double"}, 64)
2737 .Cases({
"QWORD",
"qword"}, 64)
2738 .Cases({
"MMWORD",
"mmword"}, 64)
2739 .Cases({
"XWORD",
"xword"}, 80)
2740 .Cases({
"TBYTE",
"tbyte"}, 80)
2741 .Cases({
"XMMWORD",
"xmmword"}, 128)
2742 .Cases({
"YMMWORD",
"ymmword"}, 256)
2743 .Cases({
"ZMMWORD",
"zmmword"}, 512)
2747 *SizeStr = getTok().getString();
2748 const AsmToken &Tok = Lex();
2750 return Error(Tok.
getLoc(),
"Expected 'PTR' or 'ptr' token!");
2757 if (getX86MCRegisterClass(X86::GR8RegClassID).
contains(RegNo))
2759 if (getX86MCRegisterClass(X86::GR16RegClassID).
contains(RegNo))
2761 if (getX86MCRegisterClass(X86::GR32RegClassID).
contains(RegNo))
2763 if (getX86MCRegisterClass(X86::GR64RegClassID).
contains(RegNo))
2770 MCAsmParser &Parser = getParser();
2771 const AsmToken &Tok = Parser.
getTok();
2777 if (ParseIntelMemoryOperandSize(
Size, &SizeStr))
2779 bool PtrInOperand = bool(
Size);
2785 return ParseRoundingModeOp(Start,
Operands);
2790 if (RegNo == X86::RIP)
2791 return Error(Start,
"rip can only be used as a base register");
2796 return Error(Start,
"expected memory operand after 'ptr', "
2797 "found register operand instead");
2806 "cannot cast register '" +
2808 "'; its size is not easily defined.");
2812 std::to_string(
RegSize) +
"-bit register '" +
2814 "' cannot be used as a " + std::to_string(
Size) +
"-bit " +
2821 if (!getX86MCRegisterClass(X86::SEGMENT_REGRegClassID).
contains(RegNo))
2822 return Error(Start,
"invalid segment register");
2824 Start = Lex().getLoc();
2828 IntelExprStateMachine SM;
2829 if (ParseIntelExpression(SM, End))
2832 if (isParsingMSInlineAsm())
2833 RewriteIntelExpression(SM, Start, Tok.
getLoc());
2835 int64_t
Imm = SM.getImm();
2836 const MCExpr *Disp = SM.getSym();
2845 if (!SM.isMemExpr() && !RegNo) {
2846 if (isParsingMSInlineAsm() && SM.isOffsetOperator()) {
2847 const InlineAsmIdentifierInfo &
Info = SM.getIdentifierInfo();
2852 SM.getSymName(),
Info.Var.Decl,
2853 Info.Var.IsGlobalLV));
2863 MCRegister
BaseReg = SM.getBaseReg();
2864 MCRegister IndexReg = SM.getIndexReg();
2865 if (IndexReg && BaseReg == X86::RIP)
2867 unsigned Scale = SM.getScale();
2869 Size = SM.getElementSize() << 3;
2871 if (Scale == 0 && BaseReg != X86::ESP && BaseReg != X86::RSP &&
2872 (IndexReg == X86::ESP || IndexReg == X86::RSP))
2878 !(getX86MCRegisterClass(X86::VR128XRegClassID).
contains(IndexReg) ||
2879 getX86MCRegisterClass(X86::VR256XRegClassID).
contains(IndexReg) ||
2880 getX86MCRegisterClass(X86::VR512RegClassID).
contains(IndexReg)) &&
2881 (getX86MCRegisterClass(X86::VR128XRegClassID).
contains(BaseReg) ||
2882 getX86MCRegisterClass(X86::VR256XRegClassID).
contains(BaseReg) ||
2883 getX86MCRegisterClass(X86::VR512RegClassID).
contains(BaseReg)))
2887 getX86MCRegisterClass(X86::GR16RegClassID).
contains(IndexReg))
2888 return Error(Start,
"16-bit addresses cannot have a scale");
2897 if ((BaseReg == X86::SI || BaseReg == X86::DI) &&
2898 (IndexReg == X86::BX || IndexReg == X86::BP))
2901 if ((BaseReg || IndexReg) &&
2904 return Error(Start, ErrMsg);
2905 bool IsUnconditionalBranch =
2906 Name.equals_insensitive(
"jmp") ||
Name.equals_insensitive(
"call");
2907 if (isParsingMSInlineAsm())
2908 return CreateMemForMSInlineAsm(RegNo, Disp, BaseReg, IndexReg, Scale,
2909 IsUnconditionalBranch && is64BitMode(),
2910 Start, End,
Size, SM.getSymName(),
2915 MCRegister DefaultBaseReg;
2916 bool MaybeDirectBranchDest =
true;
2919 if (is64BitMode() &&
2920 ((PtrInOperand && !IndexReg) || SM.getElementSize() > 0)) {
2921 DefaultBaseReg = X86::RIP;
2923 if (IsUnconditionalBranch) {
2925 MaybeDirectBranchDest =
false;
2927 DefaultBaseReg = X86::RIP;
2928 }
else if (!BaseReg && !IndexReg && Disp &&
2930 if (is64BitMode()) {
2931 if (SM.getSize() == 8) {
2932 MaybeDirectBranchDest =
false;
2933 DefaultBaseReg = X86::RIP;
2936 if (SM.getSize() == 4 || SM.getSize() == 2)
2937 MaybeDirectBranchDest =
false;
2941 }
else if (IsUnconditionalBranch) {
2943 if (!PtrInOperand && SM.isOffsetOperator())
2945 Start,
"`OFFSET` operator cannot be used in an unconditional branch");
2946 if (PtrInOperand || SM.isBracketUsed())
2947 MaybeDirectBranchDest =
false;
2950 if (CheckDispOverflow(BaseReg, IndexReg, Disp, Start))
2953 if ((BaseReg || IndexReg || RegNo || DefaultBaseReg))
2955 getPointerWidth(), RegNo, Disp, BaseReg, IndexReg, Scale, Start, End,
2956 Size, DefaultBaseReg, StringRef(),
nullptr,
2957 0,
false, MaybeDirectBranchDest));
2960 getPointerWidth(), Disp, Start, End,
Size, StringRef(),
2962 MaybeDirectBranchDest));
2967 MCAsmParser &Parser = getParser();
2968 switch (getLexer().getKind()) {
2978 "expected immediate expression") ||
2979 getParser().parseExpression(Val, End) ||
2987 return ParseRoundingModeOp(Start,
Operands);
2996 const MCExpr *Expr =
nullptr;
3008 if (
Reg == X86::EIZ ||
Reg == X86::RIZ)
3010 Loc,
"%eiz and %riz can only be used as index registers",
3011 SMRange(Loc, EndLoc));
3012 if (
Reg == X86::RIP)
3013 return Error(Loc,
"%rip can only be used as a base register",
3014 SMRange(Loc, EndLoc));
3020 if (!getX86MCRegisterClass(X86::SEGMENT_REGRegClassID).
contains(
Reg))
3021 return Error(Loc,
"invalid segment register");
3029 return ParseMemOperand(
Reg, Expr, Loc, EndLoc,
Operands);
3036X86::CondCode X86AsmParser::ParseConditionCode(StringRef CC) {
3037 return StringSwitch<X86::CondCode>(CC)
3059bool X86AsmParser::ParseZ(std::unique_ptr<X86Operand> &Z, SMLoc StartLoc) {
3060 MCAsmParser &Parser = getParser();
3065 (getLexer().getTok().getIdentifier() ==
"z")))
3070 return Error(getLexer().getLoc(),
"Expected } at this point");
3079 MCAsmParser &Parser = getParser();
3082 const SMLoc consumedToken = consumeToken();
3086 if (getLexer().getTok().getIntVal() != 1)
3087 return TokError(
"Expected 1to<NUM> at this point");
3088 StringRef
Prefix = getLexer().getTok().getString();
3091 return TokError(
"Expected 1to<NUM> at this point");
3094 StringRef BroadcastString = (
Prefix + getLexer().getTok().getIdentifier())
3097 return TokError(
"Expected 1to<NUM> at this point");
3098 const char *BroadcastPrimitive =
3099 StringSwitch<const char *>(BroadcastString)
3100 .Case(
"1to2",
"{1to2}")
3101 .Case(
"1to4",
"{1to4}")
3102 .Case(
"1to8",
"{1to8}")
3103 .Case(
"1to16",
"{1to16}")
3104 .Case(
"1to32",
"{1to32}")
3106 if (!BroadcastPrimitive)
3107 return TokError(
"Invalid memory broadcast primitive.");
3110 return TokError(
"Expected } at this point");
3121 std::unique_ptr<X86Operand>
Z;
3122 if (ParseZ(Z, consumedToken))
3128 SMLoc StartLoc =
Z ? consumeToken() : consumedToken;
3133 if (!parseRegister(RegNo, RegLoc, StartLoc) &&
3134 getX86MCRegisterClass(X86::VK1RegClassID).
contains(RegNo)) {
3135 if (RegNo == X86::K0)
3136 return Error(RegLoc,
"Register k0 can't be used as write mask");
3138 return Error(getLexer().getLoc(),
"Expected } at this point");
3144 return Error(getLexer().getLoc(),
3145 "Expected an op-mask register at this point");
3150 if (ParseZ(Z, consumeToken()) || !Z)
3151 return Error(getLexer().getLoc(),
3152 "Expected a {z} mark at this point");
3167bool X86AsmParser::CheckDispOverflow(MCRegister BaseReg, MCRegister IndexReg,
3168 const MCExpr *Disp, SMLoc Loc) {
3174 if (BaseReg || IndexReg) {
3176 auto Imm =
CE->getValue();
3178 getX86MCRegisterClass(X86::GR64RegClassID).contains(BaseReg) ||
3179 getX86MCRegisterClass(X86::GR64RegClassID).contains(IndexReg);
3180 bool Is16 = getX86MCRegisterClass(X86::GR16RegClassID).contains(BaseReg);
3183 return Error(Loc,
"displacement " + Twine(
Imm) +
3184 " is not within [-2147483648, 2147483647]");
3188 " shortened to 32-bit signed " +
3189 Twine(
static_cast<int32_t
>(
Imm)));
3193 " shortened to 16-bit signed " +
3194 Twine(
static_cast<int16_t
>(
Imm)));
3203bool X86AsmParser::ParseMemOperand(MCRegister SegReg,
const MCExpr *Disp,
3204 SMLoc StartLoc, SMLoc EndLoc,
3206 MCAsmParser &Parser = getParser();
3224 auto isAtMemOperand = [
this]() {
3229 auto TokCount = this->getLexer().peekTokens(Buf,
true);
3232 switch (Buf[0].getKind()) {
3239 if ((TokCount > 1) &&
3243 Buf[1].getIdentifier().
size() + 1);
3265 if (!isAtMemOperand()) {
3271 return Error(Loc,
"unexpected register in memory operand",
3272 SMRange(Loc, EndLoc));
3288 0, 0, 1, StartLoc, EndLoc));
3296 SMLoc BaseLoc = getLexer().getLoc();
3308 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ)
3309 return Error(BaseLoc,
"eiz and riz can only be used as index registers",
3310 SMRange(BaseLoc, EndLoc));
3328 if (!
E->evaluateAsAbsolute(ScaleVal, getStreamer().getAssemblerPtr()))
3329 return Error(Loc,
"expected absolute expression");
3331 Warning(Loc,
"scale factor without index register is ignored");
3336 if (BaseReg == X86::RIP)
3338 "%rip as base register can not have an index register");
3339 if (IndexReg == X86::RIP)
3340 return Error(Loc,
"%rip is not allowed as an index register");
3351 return Error(Loc,
"expected scale expression");
3352 Scale = (unsigned)ScaleVal;
3354 if (getX86MCRegisterClass(X86::GR16RegClassID).
contains(BaseReg) &&
3356 return Error(Loc,
"scale factor in 16-bit address must be 1");
3358 return Error(Loc, ErrMsg);
3372 if (BaseReg == X86::DX && !IndexReg && Scale == 1 && !SegReg &&
3381 return Error(BaseLoc, ErrMsg);
3383 if (CheckDispOverflow(BaseReg, IndexReg, Disp, BaseLoc))
3386 if (SegReg || BaseReg || IndexReg)
3388 BaseReg, IndexReg, Scale, StartLoc,
3397bool X86AsmParser::parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
3398 MCAsmParser &Parser = getParser();
3405 if (parseRegister(RegNo, StartLoc, EndLoc))
3413bool X86AsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
3415 MCAsmParser &Parser = getParser();
3419 ForcedOpcodePrefix = OpcodePrefix_Default;
3420 ForcedDispEncoding = DispEncoding_Default;
3421 UseApxExtendedReg =
false;
3422 ForcedNoFlag =
false;
3435 if (Prefix ==
"rex")
3436 ForcedOpcodePrefix = OpcodePrefix_REX;
3437 else if (Prefix ==
"rex2")
3438 ForcedOpcodePrefix = OpcodePrefix_REX2;
3439 else if (Prefix ==
"vex")
3440 ForcedOpcodePrefix = OpcodePrefix_VEX;
3441 else if (Prefix ==
"vex2")
3442 ForcedOpcodePrefix = OpcodePrefix_VEX2;
3443 else if (Prefix ==
"vex3")
3444 ForcedOpcodePrefix = OpcodePrefix_VEX3;
3445 else if (Prefix ==
"evex")
3446 ForcedOpcodePrefix = OpcodePrefix_EVEX;
3447 else if (Prefix ==
"disp8")
3448 ForcedDispEncoding = DispEncoding_Disp8;
3449 else if (Prefix ==
"disp32")
3450 ForcedDispEncoding = DispEncoding_Disp32;
3451 else if (Prefix ==
"nf")
3452 ForcedNoFlag =
true;
3454 return Error(NameLoc,
"unknown prefix");
3470 if (isParsingMSInlineAsm()) {
3471 if (
Name.equals_insensitive(
"vex"))
3472 ForcedOpcodePrefix = OpcodePrefix_VEX;
3473 else if (
Name.equals_insensitive(
"vex2"))
3474 ForcedOpcodePrefix = OpcodePrefix_VEX2;
3475 else if (
Name.equals_insensitive(
"vex3"))
3476 ForcedOpcodePrefix = OpcodePrefix_VEX3;
3477 else if (
Name.equals_insensitive(
"evex"))
3478 ForcedOpcodePrefix = OpcodePrefix_EVEX;
3480 if (ForcedOpcodePrefix != OpcodePrefix_Default) {
3493 if (
Name.consume_back(
".d32")) {
3494 ForcedDispEncoding = DispEncoding_Disp32;
3495 }
else if (
Name.consume_back(
".d8")) {
3496 ForcedDispEncoding = DispEncoding_Disp8;
3499 StringRef PatchedName =
Name;
3502 if (isParsingIntelSyntax() &&
3503 (PatchedName ==
"jmp" || PatchedName ==
"jc" || PatchedName ==
"jnc" ||
3504 PatchedName ==
"jcxz" || PatchedName ==
"jecxz" ||
3509 : NextTok ==
"short") {
3518 NextTok.
size() + 1);
3524 PatchedName !=
"setzub" && PatchedName !=
"setzunb" &&
3525 PatchedName !=
"setb" && PatchedName !=
"setnb")
3526 PatchedName = PatchedName.
substr(0,
Name.size()-1);
3528 unsigned ComparisonPredicate = ~0
U;
3536 bool IsVCMP = PatchedName[0] ==
'v';
3537 unsigned CCIdx =
IsVCMP ? 4 : 3;
3538 unsigned suffixLength = PatchedName.
ends_with(
"bf16") ? 5 : 2;
3539 unsigned CC = StringSwitch<unsigned>(
3540 PatchedName.
slice(CCIdx, PatchedName.
size() - suffixLength))
3542 .Case(
"eq_oq", 0x00)
3544 .Case(
"lt_os", 0x01)
3546 .Case(
"le_os", 0x02)
3547 .Case(
"unord", 0x03)
3548 .Case(
"unord_q", 0x03)
3550 .Case(
"neq_uq", 0x04)
3552 .Case(
"nlt_us", 0x05)
3554 .Case(
"nle_us", 0x06)
3556 .Case(
"ord_q", 0x07)
3558 .Case(
"eq_uq", 0x08)
3560 .Case(
"nge_us", 0x09)
3562 .Case(
"ngt_us", 0x0A)
3563 .Case(
"false", 0x0B)
3564 .Case(
"false_oq", 0x0B)
3565 .Case(
"neq_oq", 0x0C)
3567 .Case(
"ge_os", 0x0D)
3569 .Case(
"gt_os", 0x0E)
3571 .Case(
"true_uq", 0x0F)
3572 .Case(
"eq_os", 0x10)
3573 .Case(
"lt_oq", 0x11)
3574 .Case(
"le_oq", 0x12)
3575 .Case(
"unord_s", 0x13)
3576 .Case(
"neq_us", 0x14)
3577 .Case(
"nlt_uq", 0x15)
3578 .Case(
"nle_uq", 0x16)
3579 .Case(
"ord_s", 0x17)
3580 .Case(
"eq_us", 0x18)
3581 .Case(
"nge_uq", 0x19)
3582 .Case(
"ngt_uq", 0x1A)
3583 .Case(
"false_os", 0x1B)
3584 .Case(
"neq_os", 0x1C)
3585 .Case(
"ge_oq", 0x1D)
3586 .Case(
"gt_oq", 0x1E)
3587 .Case(
"true_us", 0x1F)
3589 if (CC != ~0U && (
IsVCMP || CC < 8) &&
3592 PatchedName =
IsVCMP ?
"vcmpss" :
"cmpss";
3594 PatchedName =
IsVCMP ?
"vcmpsd" :
"cmpsd";
3596 PatchedName =
IsVCMP ?
"vcmpps" :
"cmpps";
3598 PatchedName =
IsVCMP ?
"vcmppd" :
"cmppd";
3600 PatchedName =
"vcmpsh";
3602 PatchedName =
"vcmpph";
3604 PatchedName =
"vcmpbf16";
3608 ComparisonPredicate = CC;
3614 (PatchedName.
back() ==
'b' || PatchedName.
back() ==
'w' ||
3615 PatchedName.
back() ==
'd' || PatchedName.
back() ==
'q')) {
3616 unsigned SuffixSize = PatchedName.
drop_back().
back() ==
'u' ? 2 : 1;
3617 unsigned CC = StringSwitch<unsigned>(
3618 PatchedName.
slice(5, PatchedName.
size() - SuffixSize))
3628 if (CC != ~0U && (CC != 0 || SuffixSize == 2)) {
3629 switch (PatchedName.
back()) {
3631 case 'b': PatchedName = SuffixSize == 2 ?
"vpcmpub" :
"vpcmpb";
break;
3632 case 'w': PatchedName = SuffixSize == 2 ?
"vpcmpuw" :
"vpcmpw";
break;
3633 case 'd': PatchedName = SuffixSize == 2 ?
"vpcmpud" :
"vpcmpd";
break;
3634 case 'q': PatchedName = SuffixSize == 2 ?
"vpcmpuq" :
"vpcmpq";
break;
3637 ComparisonPredicate = CC;
3643 (PatchedName.
back() ==
'b' || PatchedName.
back() ==
'w' ||
3644 PatchedName.
back() ==
'd' || PatchedName.
back() ==
'q')) {
3645 unsigned SuffixSize = PatchedName.
drop_back().
back() ==
'u' ? 2 : 1;
3646 unsigned CC = StringSwitch<unsigned>(
3647 PatchedName.
slice(5, PatchedName.
size() - SuffixSize))
3658 switch (PatchedName.
back()) {
3660 case 'b': PatchedName = SuffixSize == 2 ?
"vpcomub" :
"vpcomb";
break;
3661 case 'w': PatchedName = SuffixSize == 2 ?
"vpcomuw" :
"vpcomw";
break;
3662 case 'd': PatchedName = SuffixSize == 2 ?
"vpcomud" :
"vpcomd";
break;
3663 case 'q': PatchedName = SuffixSize == 2 ?
"vpcomuq" :
"vpcomq";
break;
3666 ComparisonPredicate = CC;
3678 StringSwitch<bool>(Name)
3679 .Cases({
"cs",
"ds",
"es",
"fs",
"gs",
"ss"},
true)
3680 .Cases({
"rex64",
"data32",
"data16",
"addr32",
"addr16"},
true)
3681 .Cases({
"xacquire",
"xrelease"},
true)
3682 .Cases({
"acquire",
"release"}, isParsingIntelSyntax())
3685 auto isLockRepeatNtPrefix = [](StringRef
N) {
3686 return StringSwitch<bool>(
N)
3687 .Cases({
"lock",
"rep",
"repe",
"repz",
"repne",
"repnz",
"notrack"},
3692 bool CurlyAsEndOfStatement =
false;
3695 while (isLockRepeatNtPrefix(
Name.lower())) {
3697 StringSwitch<unsigned>(Name)
3716 while (
Name.starts_with(
";") ||
Name.starts_with(
"\n") ||
3717 Name.starts_with(
"#") ||
Name.starts_with(
"\t") ||
3718 Name.starts_with(
"/")) {
3729 if (PatchedName ==
"data16" && is16BitMode()) {
3730 return Error(NameLoc,
"redundant data16 prefix");
3732 if (PatchedName ==
"data32") {
3734 return Error(NameLoc,
"redundant data32 prefix");
3736 return Error(NameLoc,
"'data32' is not supported in 64-bit mode");
3738 PatchedName =
"data16";
3745 if (
Next ==
"callw")
3747 if (
Next ==
"ljmpw")
3752 ForcedDataPrefix = X86::Is32Bit;
3760 if (ComparisonPredicate != ~0U && !isParsingIntelSyntax()) {
3767 if ((
Name.starts_with(
"ccmp") ||
Name.starts_with(
"ctest")) &&
3796 CurlyAsEndOfStatement =
3797 isParsingIntelSyntax() && isParsingMSInlineAsm() &&
3800 return TokError(
"unexpected token in argument list");
3804 if (ComparisonPredicate != ~0U && isParsingIntelSyntax()) {
3814 else if (CurlyAsEndOfStatement)
3817 getLexer().getTok().getLoc(), 0);
3824 if (IsFp &&
Operands.size() == 1) {
3825 const char *Repl = StringSwitch<const char *>(Name)
3826 .Case(
"fsub",
"fsubp")
3827 .Case(
"fdiv",
"fdivp")
3828 .Case(
"fsubr",
"fsubrp")
3829 .Case(
"fdivr",
"fdivrp");
3830 static_cast<X86Operand &
>(*
Operands[0]).setTokenValue(Repl);
3833 if ((Name ==
"mov" || Name ==
"movw" || Name ==
"movl") &&
3835 X86Operand &Op1 = (X86Operand &)*
Operands[1];
3836 X86Operand &Op2 = (X86Operand &)*
Operands[2];
3841 getX86MCRegisterClass(X86::SEGMENT_REGRegClassID)
3843 (getX86MCRegisterClass(X86::GR16RegClassID).
contains(Op1.
getReg()) ||
3844 getX86MCRegisterClass(X86::GR32RegClassID).
contains(Op1.
getReg()))) {
3846 if (Name !=
"mov" && Name[3] == (is16BitMode() ?
'l' :
'w')) {
3847 Name = is16BitMode() ?
"movw" :
"movl";
3860 if ((Name ==
"outb" || Name ==
"outsb" || Name ==
"outw" || Name ==
"outsw" ||
3861 Name ==
"outl" || Name ==
"outsl" || Name ==
"out" || Name ==
"outs") &&
3863 X86Operand &
Op = (X86Operand &)*
Operands.back();
3869 if ((Name ==
"inb" || Name ==
"insb" || Name ==
"inw" || Name ==
"insw" ||
3870 Name ==
"inl" || Name ==
"insl" || Name ==
"in" || Name ==
"ins") &&
3879 bool HadVerifyError =
false;
3882 if (
Name.starts_with(
"ins") &&
3884 (Name ==
"insb" || Name ==
"insw" || Name ==
"insl" || Name ==
"insd" ||
3887 AddDefaultSrcDestOperands(TmpOperands,
3889 DefaultMemDIOperand(NameLoc));
3890 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3894 if (
Name.starts_with(
"outs") &&
3896 (Name ==
"outsb" || Name ==
"outsw" || Name ==
"outsl" ||
3897 Name ==
"outsd" || Name ==
"outs")) {
3898 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
3900 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3906 if (
Name.starts_with(
"lods") &&
3908 (Name ==
"lods" || Name ==
"lodsb" || Name ==
"lodsw" ||
3909 Name ==
"lodsl" || Name ==
"lodsd" || Name ==
"lodsq")) {
3910 TmpOperands.
push_back(DefaultMemSIOperand(NameLoc));
3911 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3917 if (
Name.starts_with(
"stos") &&
3919 (Name ==
"stos" || Name ==
"stosb" || Name ==
"stosw" ||
3920 Name ==
"stosl" || Name ==
"stosd" || Name ==
"stosq")) {
3921 TmpOperands.
push_back(DefaultMemDIOperand(NameLoc));
3922 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3928 if (
Name.starts_with(
"scas") &&
3930 (Name ==
"scas" || Name ==
"scasb" || Name ==
"scasw" ||
3931 Name ==
"scasl" || Name ==
"scasd" || Name ==
"scasq")) {
3932 TmpOperands.
push_back(DefaultMemDIOperand(NameLoc));
3933 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3937 if (
Name.starts_with(
"cmps") &&
3939 (Name ==
"cmps" || Name ==
"cmpsb" || Name ==
"cmpsw" ||
3940 Name ==
"cmpsl" || Name ==
"cmpsd" || Name ==
"cmpsq")) {
3941 AddDefaultSrcDestOperands(TmpOperands, DefaultMemDIOperand(NameLoc),
3942 DefaultMemSIOperand(NameLoc));
3943 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3947 if (((
Name.starts_with(
"movs") &&
3948 (Name ==
"movs" || Name ==
"movsb" || Name ==
"movsw" ||
3949 Name ==
"movsl" || Name ==
"movsd" || Name ==
"movsq")) ||
3950 (
Name.starts_with(
"smov") &&
3951 (Name ==
"smov" || Name ==
"smovb" || Name ==
"smovw" ||
3952 Name ==
"smovl" || Name ==
"smovd" || Name ==
"smovq"))) &&
3954 if (Name ==
"movsd" &&
Operands.size() == 1 && !isParsingIntelSyntax())
3956 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
3957 DefaultMemDIOperand(NameLoc));
3958 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3962 if (HadVerifyError) {
3963 return HadVerifyError;
3967 if ((Name ==
"xlat" || Name ==
"xlatb") &&
Operands.size() == 2) {
3968 X86Operand &Op1 =
static_cast<X86Operand &
>(*
Operands[1]);
3971 "size, (R|E)BX will be used for the location");
3973 static_cast<X86Operand &
>(*
Operands[0]).setTokenValue(
"xlatb");
3986 if (
I ==
Table.end() ||
I->OldOpc != Opcode)
3992 if (X86::isBLENDVPD(Opcode) || X86::isBLENDVPS(Opcode) ||
3993 X86::isPBLENDVB(Opcode))
3999bool X86AsmParser::processInstruction(MCInst &Inst,
const OperandVector &
Ops) {
4003 if (ForcedOpcodePrefix != OpcodePrefix_VEX3 &&
4010 auto replaceWithCCMPCTEST = [&](
unsigned Opcode) ->
bool {
4011 if (ForcedOpcodePrefix == OpcodePrefix_EVEX) {
4022 default:
return false;
4027 if (ForcedDispEncoding == DispEncoding_Disp32) {
4028 Inst.
setOpcode(is16BitMode() ? X86::JMP_2 : X86::JMP_4);
4037 if (ForcedDispEncoding == DispEncoding_Disp32) {
4038 Inst.
setOpcode(is16BitMode() ? X86::JCC_2 : X86::JCC_4);
4054#define FROM_TO(FROM, TO) \
4056 return replaceWithCCMPCTEST(X86::TO);
4058 FROM_TO(CMP64mi32, CCMP64mi32)
4061 FROM_TO(CMP64ri32, CCMP64ri32)
4088 FROM_TO(TEST64mi32, CTEST64mi32)
4090 FROM_TO(TEST64ri32, CTEST64ri32)
4110bool X86AsmParser::validateInstruction(MCInst &Inst,
const OperandVector &
Ops) {
4111 using namespace X86;
4112 const MCRegisterInfo *MRI =
getContext().getRegisterInfo();
4114 uint64_t TSFlags = MII.get(Opcode).TSFlags;
4115 if (isVFCMADDCPH(Opcode) || isVFCMADDCSH(Opcode) || isVFMADDCPH(Opcode) ||
4116 isVFMADDCSH(Opcode)) {
4120 return Warning(
Ops[0]->getStartLoc(),
"Destination register should be "
4121 "distinct from source registers");
4122 }
else if (isVFCMULCPH(Opcode) || isVFCMULCSH(Opcode) || isVFMULCPH(Opcode) ||
4123 isVFMULCSH(Opcode)) {
4133 return Warning(
Ops[0]->getStartLoc(),
"Destination register should be "
4134 "distinct from source registers");
4135 }
else if (isV4FMADDPS(Opcode) || isV4FMADDSS(Opcode) ||
4136 isV4FNMADDPS(Opcode) || isV4FNMADDSS(Opcode) ||
4137 isVP4DPWSSDS(Opcode) || isVP4DPWSSD(Opcode)) {
4142 if (Src2Enc % 4 != 0) {
4144 unsigned GroupStart = (Src2Enc / 4) * 4;
4145 unsigned GroupEnd = GroupStart + 3;
4147 "source register '" +
RegName +
"' implicitly denotes '" +
4148 RegName.take_front(3) + Twine(GroupStart) +
"' to '" +
4149 RegName.take_front(3) + Twine(GroupEnd) +
4152 }
else if (isVGATHERDPD(Opcode) || isVGATHERDPS(Opcode) ||
4153 isVGATHERQPD(Opcode) || isVGATHERQPS(Opcode) ||
4154 isVPGATHERDD(Opcode) || isVPGATHERDQ(Opcode) ||
4155 isVPGATHERQD(Opcode) || isVPGATHERQQ(Opcode)) {
4162 return Warning(
Ops[0]->getStartLoc(),
"index and destination registers "
4163 "should be distinct");
4169 if (Dest == Mask || Dest == Index || Mask == Index)
4170 return Warning(
Ops[0]->getStartLoc(),
"mask, index, and destination "
4171 "registers should be distinct");
4173 }
else if (isTCMMIMFP16PS(Opcode) || isTCMMRLFP16PS(Opcode) ||
4174 isTDPBF16PS(Opcode) || isTDPFP16PS(Opcode) || isTDPBSSD(Opcode) ||
4175 isTDPBSUD(Opcode) || isTDPBUSD(Opcode) || isTDPBUUD(Opcode)) {
4179 if (SrcDest == Src1 || SrcDest == Src2 || Src1 == Src2)
4180 return Error(
Ops[0]->getStartLoc(),
"all tmm registers must be distinct");
4194 for (
unsigned i = 0; i !=
NumOps; ++i) {
4199 if (
Reg == X86::AH ||
Reg == X86::BH ||
Reg == X86::CH ||
Reg == X86::DH)
4207 (Enc ==
X86II::EVEX || ForcedOpcodePrefix == OpcodePrefix_REX2 ||
4208 ForcedOpcodePrefix == OpcodePrefix_REX || UsesRex)) {
4210 return Error(
Ops[0]->getStartLoc(),
4211 "can't encode '" +
RegName.str() +
4212 "' in an instruction requiring EVEX/REX2/REX prefix");
4216 if ((Opcode == X86::PREFETCHIT0 || Opcode == X86::PREFETCHIT1)) {
4220 Ops[0]->getStartLoc(),
4221 Twine((Inst.
getOpcode() == X86::PREFETCHIT0 ?
"'prefetchit0'"
4222 :
"'prefetchit1'")) +
4223 " only supports RIP-relative address");
4228void X86AsmParser::emitWarningForSpecialLVIInstruction(SMLoc Loc) {
4229 Warning(Loc,
"Instruction may be vulnerable to LVI and "
4230 "requires manual mitigation");
4231 Note(SMLoc(),
"See https://software.intel.com/"
4232 "security-software-guidance/insights/"
4233 "deep-dive-load-value-injection#specialinstructions"
4234 " for more information");
4246void X86AsmParser::applyLVICFIMitigation(MCInst &Inst, MCStreamer &Out) {
4257 MCInst ShlInst, FenceInst;
4258 bool Parse32 = is32BitMode() || Code16GCC;
4259 MCRegister Basereg =
4260 is64BitMode() ? X86::RSP : (Parse32 ? X86::ESP : X86::SP);
4264 1, SMLoc{}, SMLoc{}, 0);
4266 ShlMemOp->addMemOperands(ShlInst, 5);
4269 Out.emitInstruction(ShlInst, getSTI());
4270 Out.emitInstruction(FenceInst, getSTI());
4279 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4291void X86AsmParser::applyLVILoadHardeningMitigation(MCInst &Inst,
4308 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4311 }
else if (Opcode == X86::REP_PREFIX || Opcode == X86::REPNE_PREFIX) {
4314 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4318 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
4329 Out.emitInstruction(FenceInst, getSTI());
4335 if (CLOpts.experimental_lvi_inline_asm_hardening &&
4336 getSTI().
hasFeature(X86::FeatureLVIControlFlowIntegrity))
4337 applyLVICFIMitigation(Inst, Out);
4339 Out.emitInstruction(Inst, getSTI());
4341 if (CLOpts.experimental_lvi_inline_asm_hardening &&
4342 getSTI().
hasFeature(X86::FeatureLVILoadHardening))
4343 applyLVILoadHardeningMitigation(Inst, Out);
4347 unsigned Result = 0;
4349 if (Prefix.isPrefix()) {
4350 Result = Prefix.getPrefix();
4356bool X86AsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
4358 MCStreamer &Out,
uint64_t &ErrorInfo,
4359 bool MatchingInlineAsm) {
4361 assert((*
Operands[0]).isToken() &&
"Leading operand should always be a mnemonic!");
4364 MatchFPUWaitAlias(IDLoc,
static_cast<X86Operand &
>(*
Operands[0]),
Operands,
4365 Out, MatchingInlineAsm);
4372 if (ForcedOpcodePrefix == OpcodePrefix_REX)
4374 else if (ForcedOpcodePrefix == OpcodePrefix_REX2)
4376 else if (ForcedOpcodePrefix == OpcodePrefix_VEX)
4378 else if (ForcedOpcodePrefix == OpcodePrefix_VEX2)
4380 else if (ForcedOpcodePrefix == OpcodePrefix_VEX3)
4382 else if (ForcedOpcodePrefix == OpcodePrefix_EVEX)
4386 if (ForcedDispEncoding == DispEncoding_Disp8)
4388 else if (ForcedDispEncoding == DispEncoding_Disp32)
4394 return isParsingIntelSyntax()
4395 ? matchAndEmitIntelInstruction(IDLoc, Opcode, Inst,
Operands, Out,
4396 ErrorInfo, MatchingInlineAsm)
4397 : matchAndEmitATTInstruction(IDLoc, Opcode, Inst,
Operands,
Out,
4398 ErrorInfo, MatchingInlineAsm);
4401void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &
Op,
4403 bool MatchingInlineAsm) {
4407 const char *Repl = StringSwitch<const char *>(
Op.getToken())
4408 .Case(
"finit",
"fninit")
4409 .Case(
"fsave",
"fnsave")
4410 .Case(
"fstcw",
"fnstcw")
4411 .Case(
"fstcww",
"fnstcw")
4412 .Case(
"fstenv",
"fnstenv")
4413 .Case(
"fstsw",
"fnstsw")
4414 .Case(
"fstsww",
"fnstsw")
4415 .Case(
"fclex",
"fnclex")
4421 if (!MatchingInlineAsm)
4427bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc,
4428 const FeatureBitset &MissingFeatures,
4429 bool MatchingInlineAsm) {
4430 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
4431 SmallString<126>
Msg;
4432 raw_svector_ostream OS(
Msg);
4433 OS <<
"instruction requires:";
4434 for (
unsigned Feature : MissingFeatures)
4436 return Error(IDLoc, OS.str(), SMRange(), MatchingInlineAsm);
4439unsigned X86AsmParser::checkTargetMatchPredicate(MCInst &Inst) {
4441 const MCInstrDesc &MCID = MII.get(
Opc);
4445 return Match_Unsupported;
4447 return Match_Unsupported;
4449 switch (ForcedOpcodePrefix) {
4450 case OpcodePrefix_Default:
4452 case OpcodePrefix_REX:
4453 case OpcodePrefix_REX2:
4455 return Match_Unsupported;
4457 case OpcodePrefix_VEX:
4458 case OpcodePrefix_VEX2:
4459 case OpcodePrefix_VEX3:
4461 return Match_Unsupported;
4463 case OpcodePrefix_EVEX:
4465 !X86::isCMP(
Opc) && !X86::isTEST(
Opc))
4466 return Match_Unsupported;
4468 return Match_Unsupported;
4473 (ForcedOpcodePrefix != OpcodePrefix_VEX &&
4474 ForcedOpcodePrefix != OpcodePrefix_VEX2 &&
4475 ForcedOpcodePrefix != OpcodePrefix_VEX3))
4476 return Match_Unsupported;
4478 return Match_Success;
4481bool X86AsmParser::matchAndEmitATTInstruction(
4483 MCStreamer &Out,
uint64_t &ErrorInfo,
bool MatchingInlineAsm) {
4484 X86Operand &
Op =
static_cast<X86Operand &
>(*
Operands[0]);
4488 if (ForcedDataPrefix == X86::Is32Bit)
4489 SwitchMode(X86::Is32Bit);
4491 FeatureBitset MissingFeatures;
4492 unsigned OriginalError = MatchInstruction(
Operands, Inst, ErrorInfo,
4493 MissingFeatures, MatchingInlineAsm,
4494 isParsingIntelSyntax());
4495 if (ForcedDataPrefix == X86::Is32Bit) {
4496 SwitchMode(X86::Is16Bit);
4497 ForcedDataPrefix = 0;
4499 switch (OriginalError) {
4502 if (!MatchingInlineAsm && validateInstruction(Inst,
Operands))
4507 if (!MatchingInlineAsm)
4508 while (processInstruction(Inst,
Operands))
4512 if (!MatchingInlineAsm)
4516 case Match_InvalidImmUnsignedi4: {
4517 SMLoc ErrorLoc = ((X86Operand &)*
Operands[ErrorInfo]).getStartLoc();
4518 if (ErrorLoc == SMLoc())
4520 return Error(ErrorLoc,
"immediate must be an integer in range [0, 15]",
4521 EmptyRange, MatchingInlineAsm);
4523 case Match_InvalidImmUnsignedi6: {
4524 SMLoc ErrorLoc = ((X86Operand &)*
Operands[ErrorInfo]).getStartLoc();
4525 if (ErrorLoc == SMLoc())
4527 return Error(ErrorLoc,
"immediate must be an integer in range [0, 63]",
4528 EmptyRange, MatchingInlineAsm);
4530 case Match_MissingFeature:
4531 return ErrorMissingFeature(IDLoc, MissingFeatures, MatchingInlineAsm);
4532 case Match_InvalidOperand:
4533 case Match_MnemonicFail:
4534 case Match_Unsupported:
4537 if (
Op.getToken().empty()) {
4538 Error(IDLoc,
"instruction must have size higher than 0", EmptyRange,
4549 StringRef
Base =
Op.getToken();
4550 SmallString<16> Tmp;
4553 Op.setTokenValue(Tmp);
4561 const char *Suffixes =
Base[0] !=
'f' ?
"bwlq" :
"slt\0";
4563 const char *MemSize =
Base[0] !=
'f' ?
"\x08\x10\x20\x40" :
"\x20\x40\x50\0";
4567 FeatureBitset ErrorInfoMissingFeatures;
4575 bool HasVectorReg =
false;
4576 X86Operand *MemOp =
nullptr;
4578 X86Operand *X86Op =
static_cast<X86Operand *
>(
Op.get());
4580 HasVectorReg =
true;
4581 else if (X86Op->
isMem()) {
4583 assert(MemOp->Mem.Size == 0 &&
"Memory size always 0 under ATT syntax");
4590 for (
unsigned I = 0,
E = std::size(Match);
I !=
E; ++
I) {
4591 Tmp.
back() = Suffixes[
I];
4592 if (MemOp && HasVectorReg)
4593 MemOp->Mem.Size = MemSize[
I];
4594 Match[
I] = Match_MnemonicFail;
4595 if (MemOp || !HasVectorReg) {
4597 MatchInstruction(
Operands, Inst, ErrorInfoIgnore, MissingFeatures,
4598 MatchingInlineAsm, isParsingIntelSyntax());
4600 if (Match[
I] == Match_MissingFeature)
4601 ErrorInfoMissingFeatures = MissingFeatures;
4611 unsigned NumSuccessfulMatches =
llvm::count(Match, Match_Success);
4612 if (NumSuccessfulMatches == 1) {
4613 if (!MatchingInlineAsm && validateInstruction(Inst,
Operands))
4618 if (!MatchingInlineAsm)
4619 while (processInstruction(Inst,
Operands))
4623 if (!MatchingInlineAsm)
4633 if (NumSuccessfulMatches > 1) {
4635 unsigned NumMatches = 0;
4636 for (
unsigned I = 0,
E = std::size(Match);
I !=
E; ++
I)
4637 if (Match[
I] == Match_Success)
4638 MatchChars[NumMatches++] = Suffixes[
I];
4640 SmallString<126>
Msg;
4641 raw_svector_ostream OS(
Msg);
4642 OS <<
"ambiguous instructions require an explicit suffix (could be ";
4643 for (
unsigned i = 0; i != NumMatches; ++i) {
4646 if (i + 1 == NumMatches)
4648 OS <<
"'" <<
Base << MatchChars[i] <<
"'";
4651 Error(IDLoc, OS.str(), EmptyRange, MatchingInlineAsm);
4659 if (
llvm::count(Match, Match_MnemonicFail) == 4) {
4660 if (OriginalError == Match_MnemonicFail)
4661 return Error(IDLoc,
"invalid instruction mnemonic '" +
Base +
"'",
4662 Op.getLocRange(), MatchingInlineAsm);
4664 if (OriginalError == Match_Unsupported)
4665 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4668 assert(OriginalError == Match_InvalidOperand &&
"Unexpected error");
4670 if (ErrorInfo != ~0ULL) {
4672 return Error(IDLoc,
"too few operands for instruction", EmptyRange,
4675 X86Operand &Operand = (X86Operand &)*
Operands[ErrorInfo];
4679 OperandRange, MatchingInlineAsm);
4683 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4689 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4695 if (
llvm::count(Match, Match_MissingFeature) == 1) {
4696 ErrorInfo = Match_MissingFeature;
4697 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
4703 if (
llvm::count(Match, Match_InvalidOperand) == 1) {
4704 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4709 Error(IDLoc,
"unknown use of instruction mnemonic without a size suffix",
4710 EmptyRange, MatchingInlineAsm);
4714bool X86AsmParser::matchAndEmitIntelInstruction(
4716 MCStreamer &Out,
uint64_t &ErrorInfo,
bool MatchingInlineAsm) {
4717 X86Operand &
Op =
static_cast<X86Operand &
>(*
Operands[0]);
4722 const bool ForcedData32 = ForcedDataPrefix == X86::Is32Bit;
4723 auto RestoreMode = [&] {
4725 SwitchMode(X86::Is16Bit);
4726 ForcedDataPrefix = 0;
4730 SwitchMode(X86::Is32Bit);
4732 X86Operand *UnsizedMemOp =
nullptr;
4734 X86Operand *X86Op =
static_cast<X86Operand *
>(
Op.get());
4736 UnsizedMemOp = X86Op;
4747 static const char *
const PtrSizedInstrs[] = {
"call",
"jmp",
"push",
"pop"};
4748 for (
const char *Instr : PtrSizedInstrs) {
4749 if (Mnemonic == Instr) {
4750 UnsizedMemOp->
Mem.
Size = getPointerWidth();
4756 SmallVector<unsigned, 8> Match;
4757 FeatureBitset ErrorInfoMissingFeatures;
4758 FeatureBitset MissingFeatures;
4763 if (Mnemonic ==
"push" &&
Operands.size() == 2) {
4764 auto *X86Op =
static_cast<X86Operand *
>(
Operands[1].get());
4765 if (X86Op->
isImm()) {
4768 unsigned Size = getPointerWidth();
4771 SmallString<16> Tmp;
4773 Tmp += (is64BitMode())
4775 : (is32BitMode()) ?
"l" : (is16BitMode()) ?
"w" :
" ";
4776 Op.setTokenValue(Tmp);
4779 MissingFeatures, MatchingInlineAsm,
4790 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
4791 for (
unsigned Size : MopSizes) {
4795 unsigned M = MatchInstruction(
Operands, Inst, ErrorInfoIgnore,
4796 MissingFeatures, MatchingInlineAsm,
4797 isParsingIntelSyntax());
4802 if (Match.
back() == Match_MissingFeature)
4803 ErrorInfoMissingFeatures = MissingFeatures;
4813 if (Match.
empty()) {
4815 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,
4816 isParsingIntelSyntax()));
4818 if (Match.
back() == Match_MissingFeature)
4819 ErrorInfoMissingFeatures = MissingFeatures;
4827 if (Match.
back() == Match_MnemonicFail) {
4829 return Error(IDLoc,
"invalid instruction mnemonic '" + Mnemonic +
"'",
4830 Op.getLocRange(), MatchingInlineAsm);
4833 unsigned NumSuccessfulMatches =
llvm::count(Match, Match_Success);
4837 if (UnsizedMemOp && NumSuccessfulMatches > 1 &&
4840 unsigned M = MatchInstruction(
4841 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,
4842 isParsingIntelSyntax());
4843 if (M == Match_Success)
4844 NumSuccessfulMatches = 1;
4859 if (NumSuccessfulMatches == 1) {
4860 if (!MatchingInlineAsm && validateInstruction(Inst,
Operands))
4865 if (!MatchingInlineAsm)
4866 while (processInstruction(Inst,
Operands))
4869 if (!MatchingInlineAsm)
4873 }
else if (NumSuccessfulMatches > 1) {
4875 "multiple matches only possible with unsized memory operands");
4877 "ambiguous operand size for instruction '" + Mnemonic +
"\'",
4883 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4889 if (
llvm::count(Match, Match_MissingFeature) == 1) {
4890 ErrorInfo = Match_MissingFeature;
4891 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
4897 if (
llvm::count(Match, Match_InvalidOperand) == 1) {
4898 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4902 if (
llvm::count(Match, Match_InvalidImmUnsignedi4) == 1) {
4903 SMLoc ErrorLoc = ((X86Operand &)*
Operands[ErrorInfo]).getStartLoc();
4904 if (ErrorLoc == SMLoc())
4906 return Error(ErrorLoc,
"immediate must be an integer in range [0, 15]",
4907 EmptyRange, MatchingInlineAsm);
4910 if (
llvm::count(Match, Match_InvalidImmUnsignedi6) == 1) {
4911 SMLoc ErrorLoc = ((X86Operand &)*
Operands[ErrorInfo]).getStartLoc();
4912 if (ErrorLoc == SMLoc())
4914 return Error(ErrorLoc,
"immediate must be an integer in range [0, 63]",
4915 EmptyRange, MatchingInlineAsm);
4919 return Error(IDLoc,
"unknown instruction mnemonic", EmptyRange,
4923bool X86AsmParser::omitRegisterFromClobberLists(MCRegister
Reg) {
4924 return getX86MCRegisterClass(X86::SEGMENT_REGRegClassID).contains(
Reg);
4927bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
4928 MCAsmParser &Parser = getParser();
4931 return parseDirectiveArch();
4933 return ParseDirectiveCode(IDVal, DirectiveID.
getLoc());
4939 return Error(DirectiveID.
getLoc(),
"'.att_syntax noprefix' is not "
4940 "supported: registers must have a "
4941 "'%' prefix in .att_syntax");
4943 getParser().setAssemblerDialect(0);
4946 getParser().setAssemblerDialect(1);
4951 return Error(DirectiveID.
getLoc(),
"'.intel_syntax prefix' is not "
4952 "supported: registers must not have "
4953 "a '%' prefix in .intel_syntax");
4956 }
else if (IDVal ==
".nops")
4957 return parseDirectiveNops(DirectiveID.
getLoc());
4958 else if (IDVal ==
".even")
4959 return parseDirectiveEven(DirectiveID.
getLoc());
4960 else if (IDVal ==
".cv_fpo_proc")
4961 return parseDirectiveFPOProc(DirectiveID.
getLoc());
4962 else if (IDVal ==
".cv_fpo_setframe")
4963 return parseDirectiveFPOSetFrame(DirectiveID.
getLoc());
4964 else if (IDVal ==
".cv_fpo_pushreg")
4965 return parseDirectiveFPOPushReg(DirectiveID.
getLoc());
4966 else if (IDVal ==
".cv_fpo_stackalloc")
4967 return parseDirectiveFPOStackAlloc(DirectiveID.
getLoc());
4968 else if (IDVal ==
".cv_fpo_stackalign")
4969 return parseDirectiveFPOStackAlign(DirectiveID.
getLoc());
4970 else if (IDVal ==
".cv_fpo_endprologue")
4971 return parseDirectiveFPOEndPrologue(DirectiveID.
getLoc());
4972 else if (IDVal ==
".cv_fpo_endproc")
4973 return parseDirectiveFPOEndProc(DirectiveID.
getLoc());
4974 else if (IDVal ==
".seh_pushreg")
4975 return parseDirectiveSEHPushReg(DirectiveID.
getLoc());
4976 else if (IDVal ==
".seh_push2regs")
4977 return parseDirectiveSEHPush2Regs(DirectiveID.
getLoc());
4978 else if (IDVal ==
".seh_setframe")
4979 return parseDirectiveSEHSetFrame(DirectiveID.
getLoc());
4980 else if (IDVal ==
".seh_savereg")
4981 return parseDirectiveSEHSaveReg(DirectiveID.
getLoc());
4982 else if (IDVal ==
".seh_savexmm")
4983 return parseDirectiveSEHSaveXMM(DirectiveID.
getLoc());
4984 else if (IDVal ==
".seh_pushframe")
4985 return parseDirectiveSEHPushFrame(DirectiveID.
getLoc());
4989 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
4990 parseDirectiveSEHPushReg(DirectiveID.
getLoc());
4992 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
4993 parseDirectiveSEHPush2Regs(DirectiveID.
getLoc());
4995 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
4996 parseDirectiveSEHSetFrame(DirectiveID.
getLoc());
4998 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
4999 parseDirectiveSEHSaveReg(DirectiveID.
getLoc());
5001 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
5002 parseDirectiveSEHSaveXMM(DirectiveID.
getLoc());
5004 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
5005 parseDirectiveSEHPushFrame(DirectiveID.
getLoc());
5009 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
5010 parseDirectiveSEHPushReg(DirectiveID.
getLoc());
5014 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
5015 parseDirectiveSEHPush2Regs(DirectiveID.
getLoc(),
5018 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
5019 parseDirectiveSEHSetFrame(DirectiveID.
getLoc());
5021 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
5022 parseDirectiveSEHSaveReg(DirectiveID.
getLoc());
5024 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
5025 parseDirectiveSEHSaveXMM(DirectiveID.
getLoc());
5032bool X86AsmParser::parseDirectiveArch() {
5034 getParser().parseStringToEndOfStatement();
5040bool X86AsmParser::parseDirectiveNops(SMLoc L) {
5041 int64_t NumBytes = 0, Control = 0;
5042 SMLoc NumBytesLoc, ControlLoc;
5043 const MCSubtargetInfo& STI = getSTI();
5044 NumBytesLoc = getTok().getLoc();
5045 if (getParser().checkForValidSection() ||
5046 getParser().parseAbsoluteExpression(NumBytes))
5050 ControlLoc = getTok().getLoc();
5051 if (getParser().parseAbsoluteExpression(Control))
5054 if (getParser().parseEOL())
5057 if (NumBytes <= 0) {
5058 Error(NumBytesLoc,
"'.nops' directive with non-positive size");
5063 Error(ControlLoc,
"'.nops' directive with negative NOP size");
5068 getParser().getStreamer().emitNops(NumBytes, Control, L, STI);
5075bool X86AsmParser::parseDirectiveEven(SMLoc L) {
5079 const MCSection *
Section = getStreamer().getCurrentSectionOnly();
5081 getStreamer().initSections(getSTI());
5082 Section = getStreamer().getCurrentSectionOnly();
5084 if (
getContext().getAsmInfo().useCodeAlign(*Section))
5085 getStreamer().emitCodeAlignment(
Align(2), getSTI(), 0);
5087 getStreamer().emitValueToAlignment(
Align(2), 0, 1, 0);
5093bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
5094 MCAsmParser &Parser = getParser();
5096 if (IDVal ==
".code16") {
5098 if (!is16BitMode()) {
5099 SwitchMode(X86::Is16Bit);
5100 getTargetStreamer().emitCode16();
5102 }
else if (IDVal ==
".code16gcc") {
5106 if (!is16BitMode()) {
5107 SwitchMode(X86::Is16Bit);
5108 getTargetStreamer().emitCode16();
5110 }
else if (IDVal ==
".code32") {
5112 if (!is32BitMode()) {
5113 SwitchMode(X86::Is32Bit);
5114 getTargetStreamer().emitCode32();
5116 }
else if (IDVal ==
".code64") {
5118 if (!is64BitMode()) {
5119 SwitchMode(X86::Is64Bit);
5120 getTargetStreamer().emitCode64();
5123 Error(L,
"unknown directive " + IDVal);
5131bool X86AsmParser::parseDirectiveFPOProc(SMLoc L) {
5132 MCAsmParser &Parser = getParser();
5136 return Parser.
TokError(
"expected symbol name");
5137 if (Parser.
parseIntToken(ParamsSize,
"expected parameter byte count"))
5140 return Parser.
TokError(
"parameters size out of range");
5144 return getTargetStreamer().emitFPOProc(ProcSym, ParamsSize, L);
5148bool X86AsmParser::parseDirectiveFPOSetFrame(SMLoc L) {
5151 if (parseRegister(
Reg, DummyLoc, DummyLoc) || parseEOL())
5153 return getTargetStreamer().emitFPOSetFrame(
Reg, L);
5157bool X86AsmParser::parseDirectiveFPOPushReg(SMLoc L) {
5160 if (parseRegister(
Reg, DummyLoc, DummyLoc) || parseEOL())
5162 return getTargetStreamer().emitFPOPushReg(
Reg, L);
5166bool X86AsmParser::parseDirectiveFPOStackAlloc(SMLoc L) {
5167 MCAsmParser &Parser = getParser();
5171 return getTargetStreamer().emitFPOStackAlloc(
Offset, L);
5175bool X86AsmParser::parseDirectiveFPOStackAlign(SMLoc L) {
5176 MCAsmParser &Parser = getParser();
5180 return getTargetStreamer().emitFPOStackAlign(
Offset, L);
5184bool X86AsmParser::parseDirectiveFPOEndPrologue(SMLoc L) {
5185 MCAsmParser &Parser = getParser();
5188 return getTargetStreamer().emitFPOEndPrologue(L);
5192bool X86AsmParser::parseDirectiveFPOEndProc(SMLoc L) {
5193 MCAsmParser &Parser = getParser();
5196 return getTargetStreamer().emitFPOEndProc(L);
5199bool X86AsmParser::parseSEHRegisterNumber(
unsigned RegClassID,
5200 MCRegister &RegNo) {
5201 SMLoc startLoc = getLexer().getLoc();
5202 const MCRegisterInfo *MRI =
getContext().getRegisterInfo();
5207 if (parseRegister(RegNo, startLoc, endLoc))
5210 if (!getX86MCRegisterClass(RegClassID).
contains(RegNo)) {
5211 return Error(startLoc,
5212 "register is not supported for use with this directive");
5218 if (getParser().parseAbsoluteExpression(EncodedReg))
5223 RegNo = MCRegister();
5224 for (
MCPhysReg Reg : getX86MCRegisterClass(RegClassID)) {
5231 return Error(startLoc,
5232 "incorrect register number for use with this directive");
5239bool X86AsmParser::parseDirectiveSEHPushReg(SMLoc Loc) {
5241 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5245 return TokError(
"expected end of directive");
5248 getStreamer().emitWinCFIPushReg(
Reg, Loc);
5252bool X86AsmParser::parseDirectiveSEHPush2Regs(SMLoc Loc,
bool SwapRegs) {
5254 if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg1))
5258 return TokError(
"expected comma between registers");
5262 if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg2))
5266 return TokError(
"expected end of directive");
5272 getStreamer().emitWinCFIPush2Regs(Reg1, Reg2, Loc);
5276bool X86AsmParser::parseDirectiveSEHSetFrame(SMLoc Loc) {
5279 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5282 return TokError(
"you must specify a stack pointer offset");
5285 if (getParser().parseAbsoluteExpression(
Off))
5289 return TokError(
"expected end of directive");
5292 getStreamer().emitWinCFISetFrame(
Reg,
Off, Loc);
5296bool X86AsmParser::parseDirectiveSEHSaveReg(SMLoc Loc) {
5299 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5302 return TokError(
"you must specify an offset on the stack");
5305 if (getParser().parseAbsoluteExpression(
Off))
5309 return TokError(
"expected end of directive");
5312 getStreamer().emitWinCFISaveReg(
Reg,
Off, Loc);
5316bool X86AsmParser::parseDirectiveSEHSaveXMM(SMLoc Loc) {
5319 if (parseSEHRegisterNumber(X86::VR128XRegClassID,
Reg))
5322 return TokError(
"you must specify an offset on the stack");
5325 if (getParser().parseAbsoluteExpression(
Off))
5329 return TokError(
"expected end of directive");
5332 getStreamer().emitWinCFISaveXMM(
Reg,
Off, Loc);
5336bool X86AsmParser::ensureMasmPrologContext(SMLoc Loc) {
5337 if (getStreamer().isWinCFIPrologEnded()) {
5338 return Error(Loc,
"prolog directive must be used inside a prolog");
5343bool X86AsmParser::ensureMasmEpilogContext(SMLoc Loc) {
5344 if (!getStreamer().isInEpilogCFI()) {
5345 return Error(Loc,
"epilog directive must be used inside an epilog");
5350bool X86AsmParser::parseDirectiveSEHPushFrame(SMLoc Loc) {
5354 SMLoc startLoc = getLexer().getLoc();
5356 if (!getParser().parseIdentifier(CodeID)) {
5357 if (CodeID !=
"code")
5358 return Error(startLoc,
"expected @code");
5361 }
else if (getParser().isParsingMasm() &&
5363 getTok().getString().equals_insensitive(
"code")) {
5369 return TokError(
"expected end of directive");
5372 getStreamer().emitWinCFIPushFrame(Code, Loc);
5382#define GET_MATCHER_IMPLEMENTATION
5383#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)
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 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.
static constexpr unsigned NoRegister
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...
@ Global
Append to llvm.global_dtors.
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