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),
1406 InstInfo(nullptr), Code16GCC(
false) {
1411 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
1414 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
1415 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1416 SMLoc &EndLoc)
override;
1418 bool parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc)
override;
1420 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
1423 bool ParseDirective(AsmToken DirectiveID)
override;
1427#define GET_REGISTER_MATCHER
1428#define GET_SUBTARGET_FEATURE_NAME
1429#include "X86GenAsmMatcher.inc"
1440 !(BaseReg == X86::RIP || BaseReg == X86::EIP ||
1441 getX86MCRegisterClass(X86::GR16RegClassID).
contains(BaseReg) ||
1442 getX86MCRegisterClass(X86::GR32RegClassID).
contains(BaseReg) ||
1443 getX86MCRegisterClass(X86::GR64RegClassID).
contains(BaseReg))) {
1444 ErrMsg =
"invalid base+index expression";
1449 !(IndexReg == X86::EIZ || IndexReg == X86::RIZ ||
1450 getX86MCRegisterClass(X86::GR16RegClassID).
contains(IndexReg) ||
1451 getX86MCRegisterClass(X86::GR32RegClassID).
contains(IndexReg) ||
1452 getX86MCRegisterClass(X86::GR64RegClassID).
contains(IndexReg) ||
1453 getX86MCRegisterClass(X86::VR128XRegClassID).
contains(IndexReg) ||
1454 getX86MCRegisterClass(X86::VR256XRegClassID).
contains(IndexReg) ||
1455 getX86MCRegisterClass(X86::VR512RegClassID).
contains(IndexReg))) {
1456 ErrMsg =
"invalid base+index expression";
1460 if (((BaseReg == X86::RIP || BaseReg == X86::EIP) && IndexReg) ||
1461 IndexReg == X86::EIP || IndexReg == X86::RIP || IndexReg == X86::ESP ||
1462 IndexReg == X86::RSP) {
1463 ErrMsg =
"invalid base+index expression";
1469 if (getX86MCRegisterClass(X86::GR16RegClassID).
contains(BaseReg) &&
1470 (Is64BitMode || (BaseReg != X86::BX && BaseReg != X86::BP &&
1471 BaseReg != X86::SI && BaseReg != X86::DI))) {
1472 ErrMsg =
"invalid 16-bit base register";
1477 getX86MCRegisterClass(X86::GR16RegClassID).
contains(IndexReg)) {
1478 ErrMsg =
"16-bit memory operand may not include only index register";
1482 if (BaseReg && IndexReg) {
1483 if (getX86MCRegisterClass(X86::GR64RegClassID).
contains(BaseReg) &&
1484 (getX86MCRegisterClass(X86::GR16RegClassID).
contains(IndexReg) ||
1485 getX86MCRegisterClass(X86::GR32RegClassID).
contains(IndexReg) ||
1486 IndexReg == X86::EIZ)) {
1487 ErrMsg =
"base register is 64-bit, but index register is not";
1490 if (getX86MCRegisterClass(X86::GR32RegClassID).
contains(BaseReg) &&
1491 (getX86MCRegisterClass(X86::GR16RegClassID).
contains(IndexReg) ||
1492 getX86MCRegisterClass(X86::GR64RegClassID).
contains(IndexReg) ||
1493 IndexReg == X86::RIZ)) {
1494 ErrMsg =
"base register is 32-bit, but index register is not";
1497 if (getX86MCRegisterClass(X86::GR16RegClassID).
contains(BaseReg)) {
1498 if (getX86MCRegisterClass(X86::GR32RegClassID).
contains(IndexReg) ||
1499 getX86MCRegisterClass(X86::GR64RegClassID).
contains(IndexReg)) {
1500 ErrMsg =
"base register is 16-bit, but index register is not";
1503 if ((BaseReg != X86::BX && BaseReg != X86::BP) ||
1504 (IndexReg != X86::SI && IndexReg != X86::DI)) {
1505 ErrMsg =
"invalid 16-bit base/index register combination";
1512 if (!Is64BitMode && (BaseReg == X86::RIP || BaseReg == X86::EIP)) {
1513 ErrMsg =
"IP-relative addressing requires 64-bit mode";
1534 if (isParsingMSInlineAsm() && isParsingIntelSyntax() &&
1535 (RegNo == X86::EFLAGS || RegNo == X86::MXCSR))
1536 RegNo = MCRegister();
1538 if (!is64BitMode()) {
1542 if (RegNo == X86::RIZ || RegNo == X86::RIP ||
1543 getX86MCRegisterClass(X86::GR64RegClassID).
contains(RegNo) ||
1546 return Error(StartLoc,
1547 "register %" +
RegName +
" is only available in 64-bit mode",
1548 SMRange(StartLoc, EndLoc));
1553 UseApxExtendedReg =
true;
1557 if (!RegNo &&
RegName.starts_with(
"db")) {
1616 if (isParsingIntelSyntax())
1618 return Error(StartLoc,
"invalid register name", SMRange(StartLoc, EndLoc));
1623bool X86AsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
1624 SMLoc &EndLoc,
bool RestoreOnFailure) {
1625 MCAsmParser &Parser = getParser();
1626 AsmLexer &Lexer = getLexer();
1627 RegNo = MCRegister();
1630 auto OnFailure = [RestoreOnFailure, &Lexer, &Tokens]() {
1631 if (RestoreOnFailure) {
1632 while (!Tokens.
empty()) {
1638 const AsmToken &PercentTok = Parser.
getTok();
1639 StartLoc = PercentTok.
getLoc();
1648 const AsmToken &Tok = Parser.
getTok();
1653 if (isParsingIntelSyntax())
return true;
1654 return Error(StartLoc,
"invalid register name",
1655 SMRange(StartLoc, EndLoc));
1658 if (MatchRegisterByName(RegNo, Tok.
getString(), StartLoc, EndLoc)) {
1664 if (RegNo == X86::ST0) {
1675 const AsmToken &IntTok = Parser.
getTok();
1678 return Error(IntTok.
getLoc(),
"expected stack index");
1681 case 0: RegNo = X86::ST0;
break;
1682 case 1: RegNo = X86::ST1;
break;
1683 case 2: RegNo = X86::ST2;
break;
1684 case 3: RegNo = X86::ST3;
break;
1685 case 4: RegNo = X86::ST4;
break;
1686 case 5: RegNo = X86::ST5;
break;
1687 case 6: RegNo = X86::ST6;
break;
1688 case 7: RegNo = X86::ST7;
break;
1691 return Error(IntTok.
getLoc(),
"invalid stack index");
1711 if (isParsingIntelSyntax())
return true;
1712 return Error(StartLoc,
"invalid register name",
1713 SMRange(StartLoc, EndLoc));
1720bool X86AsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1722 return ParseRegister(
Reg, StartLoc, EndLoc,
false);
1725ParseStatus X86AsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1727 bool Result = ParseRegister(
Reg, StartLoc, EndLoc,
true);
1728 bool PendingErrors = getParser().hasPendingError();
1729 getParser().clearPendingErrors();
1737std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(SMLoc Loc) {
1738 bool Parse32 = is32BitMode() || Code16GCC;
1739 MCRegister Basereg =
1740 is64BitMode() ? X86::RSI : (Parse32 ? X86::ESI : X86::SI);
1747std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand(SMLoc Loc) {
1748 bool Parse32 = is32BitMode() || Code16GCC;
1749 MCRegister Basereg =
1750 is64BitMode() ? X86::RDI : (Parse32 ? X86::EDI : X86::DI);
1757bool X86AsmParser::IsSIReg(MCRegister
Reg) {
1771MCRegister X86AsmParser::GetSIDIForRegClass(
unsigned RegClassID,
bool IsSIReg) {
1772 switch (RegClassID) {
1774 case X86::GR64RegClassID:
1775 return IsSIReg ? X86::RSI : X86::RDI;
1776 case X86::GR32RegClassID:
1777 return IsSIReg ? X86::ESI : X86::EDI;
1778 case X86::GR16RegClassID:
1779 return IsSIReg ? X86::SI : X86::DI;
1783void X86AsmParser::AddDefaultSrcDestOperands(
1785 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst) {
1786 if (isParsingIntelSyntax()) {
1787 Operands.push_back(std::move(Dst));
1788 Operands.push_back(std::move(Src));
1791 Operands.push_back(std::move(Src));
1792 Operands.push_back(std::move(Dst));
1796bool X86AsmParser::VerifyAndAdjustOperands(
OperandVector &OrigOperands,
1799 if (OrigOperands.
size() > 1) {
1802 "Operand size mismatch");
1806 int RegClassID = -1;
1807 for (
unsigned int i = 0; i < FinalOperands.
size(); ++i) {
1808 X86Operand &OrigOp =
static_cast<X86Operand &
>(*OrigOperands[i + 1]);
1809 X86Operand &FinalOp =
static_cast<X86Operand &
>(*FinalOperands[i]);
1811 if (FinalOp.
isReg() &&
1816 if (FinalOp.
isMem()) {
1818 if (!OrigOp.
isMem())
1827 if (RegClassID != -1 &&
1828 !getX86MCRegisterClass(RegClassID).
contains(OrigReg)) {
1830 "mismatching source and destination index registers");
1833 if (getX86MCRegisterClass(X86::GR64RegClassID).
contains(OrigReg))
1834 RegClassID = X86::GR64RegClassID;
1835 else if (getX86MCRegisterClass(X86::GR32RegClassID).
contains(OrigReg))
1836 RegClassID = X86::GR32RegClassID;
1837 else if (getX86MCRegisterClass(X86::GR16RegClassID).
contains(OrigReg))
1838 RegClassID = X86::GR16RegClassID;
1844 bool IsSI = IsSIReg(FinalReg);
1845 FinalReg = GetSIDIForRegClass(RegClassID, IsSI);
1847 if (FinalReg != OrigReg) {
1848 std::string
RegName = IsSI ?
"ES:(R|E)SI" :
"ES:(R|E)DI";
1851 "memory operand is only for determining the size, " +
RegName +
1852 " will be used for the location"));
1863 for (
auto &WarningMsg : Warnings) {
1864 Warning(WarningMsg.first, WarningMsg.second);
1868 for (
unsigned int i = 0; i < FinalOperands.
size(); ++i)
1872 for (
auto &
Op : FinalOperands)
1879 if (isParsingIntelSyntax())
1880 return parseIntelOperand(
Operands, Name);
1885bool X86AsmParser::CreateMemForMSInlineAsm(
1886 MCRegister SegReg,
const MCExpr *Disp, MCRegister BaseReg,
1887 MCRegister IndexReg,
unsigned Scale,
bool NonAbsMem, SMLoc Start, SMLoc
End,
1888 unsigned Size, StringRef Identifier,
const InlineAsmIdentifierInfo &Info,
1903 unsigned FrontendSize = 0;
1904 void *Decl =
nullptr;
1905 bool IsGlobalLV =
false;
1908 FrontendSize =
Info.Var.Type * 8;
1909 Decl =
Info.Var.Decl;
1910 IsGlobalLV =
Info.Var.IsGlobalLV;
1915 if (BaseReg || IndexReg) {
1917 End,
Size, Identifier, Decl, 0,
1918 BaseReg && IndexReg));
1925 getPointerWidth(), SegReg, Disp, BaseReg, IndexReg, Scale, Start,
End,
1927 X86::RIP, Identifier, Decl, FrontendSize));
1934bool X86AsmParser::ParseIntelNamedOperator(StringRef Name,
1935 IntelExprStateMachine &SM,
1936 bool &ParseError, SMLoc &
End) {
1939 if (Name !=
Name.lower() && Name !=
Name.upper() &&
1940 !getParser().isParsingMasm())
1944 bool AlreadyConsumed =
false;
1945 if (
Name.equals_insensitive(
"not")) {
1947 }
else if (
Name.equals_insensitive(
"or")) {
1949 }
else if (
Name.equals_insensitive(
"shl")) {
1951 }
else if (
Name.equals_insensitive(
"shr")) {
1953 }
else if (
Name.equals_insensitive(
"xor")) {
1955 }
else if (
Name.equals_insensitive(
"and")) {
1957 }
else if (
Name.equals_insensitive(
"mod")) {
1959 }
else if (
Name.equals_insensitive(
"offset")) {
1960 const MCExpr *Val =
nullptr;
1962 InlineAsmIdentifierInfo
Info;
1967 ParseError = SM.onOffset(Val, ID, Info, isParsingMSInlineAsm(), ErrMsg);
1970 AlreadyConsumed =
true;
1971 }
else if (
Name.equals_insensitive(
"imagerel")) {
1974 InlineAsmIdentifierInfo
Info;
1975 ParseError = ParseIntelImagerelOperator(Val, ID, Info,
End);
1982 AlreadyConsumed =
true;
1986 if (!AlreadyConsumed)
1987 End = consumeToken();
1990bool X86AsmParser::ParseMasmNamedOperator(StringRef Name,
1991 IntelExprStateMachine &SM,
1992 bool &ParseError, SMLoc &
End) {
1993 if (
Name.equals_insensitive(
"eq")) {
1995 }
else if (
Name.equals_insensitive(
"ne")) {
1997 }
else if (
Name.equals_insensitive(
"lt")) {
1999 }
else if (
Name.equals_insensitive(
"le")) {
2001 }
else if (
Name.equals_insensitive(
"gt")) {
2003 }
else if (
Name.equals_insensitive(
"ge")) {
2008 End = consumeToken();
2015 IntelExprStateMachine &SM) {
2019 SM.setAppendAfterOperand();
2022bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &
End) {
2023 MCAsmParser &Parser = getParser();
2028 if (
getContext().getObjectFileInfo()->isPositionIndependent())
2035 const AsmToken &Tok = Parser.
getTok();
2037 bool UpdateLocLex =
true;
2042 if ((
Done = SM.isValidEndState()))
2044 return Error(Tok.
getLoc(),
"unknown token in expression");
2046 return Error(getLexer().getErrLoc(), getLexer().getErr());
2050 UpdateLocLex =
false;
2051 if (ParseIntelDotOperator(SM,
End))
2056 if ((
Done = SM.isValidEndState()))
2058 return Error(Tok.
getLoc(),
"unknown token in expression");
2062 UpdateLocLex =
false;
2063 if (ParseIntelDotOperator(SM,
End))
2068 if ((
Done = SM.isValidEndState()))
2070 return Error(Tok.
getLoc(),
"unknown token in expression");
2076 SMLoc ValueLoc = Tok.
getLoc();
2081 UpdateLocLex =
false;
2082 if (!Val->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
2083 return Error(ValueLoc,
"expected absolute value");
2084 if (SM.onInteger(Res, ErrMsg))
2085 return Error(SM.getErrorLoc(ValueLoc), ErrMsg);
2092 SMLoc IdentLoc = Tok.
getLoc();
2094 UpdateLocLex =
false;
2096 size_t DotOffset =
Identifier.find_first_of(
'.');
2100 StringRef Dot =
Identifier.substr(DotOffset, 1);
2114 const AsmToken &NextTok = getLexer().peekTok();
2123 End = consumeToken();
2130 if (!ParseRegister(
Reg, IdentLoc,
End,
true)) {
2131 if (SM.onRegister(
Reg, ErrMsg))
2132 return Error(SM.getErrorLoc(IdentLoc), ErrMsg);
2136 const std::pair<StringRef, StringRef> IDField =
2138 const StringRef
ID = IDField.first,
Field = IDField.second;
2140 if (!
Field.empty() &&
2141 !MatchRegisterByName(
Reg, ID, IdentLoc, IDEndLoc)) {
2142 if (SM.onRegister(
Reg, ErrMsg))
2143 return Error(SM.getErrorLoc(IdentLoc), ErrMsg);
2148 return Error(FieldStartLoc,
"unknown offset");
2149 else if (SM.onPlus(ErrMsg))
2150 return Error(getTok().getLoc(), ErrMsg);
2151 else if (SM.onInteger(
Info.Offset, ErrMsg))
2152 return Error(SM.getErrorLoc(IdentLoc), ErrMsg);
2153 SM.setTypeInfo(
Info.Type);
2155 End = consumeToken();
2162 if (ParseIntelNamedOperator(Identifier, SM, ParseError,
End)) {
2168 ParseMasmNamedOperator(Identifier, SM, ParseError,
End)) {
2174 InlineAsmIdentifierInfo
Info;
2175 AsmFieldInfo FieldInfo;
2181 if (ParseIntelDotOperator(SM,
End))
2186 if (isParsingMSInlineAsm()) {
2188 if (
unsigned OpKind = IdentifyIntelInlineAsmOperator(Identifier)) {
2189 if (int64_t Val = ParseIntelInlineAsmOperator(OpKind)) {
2190 if (SM.onInteger(Val, ErrMsg))
2191 return Error(SM.getErrorLoc(IdentLoc), ErrMsg);
2200 return Error(IdentLoc,
"expected identifier");
2201 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
false,
End))
2203 else if (SM.onIdentifierExpr(Val, Identifier, Info, FieldInfo.
Type,
2205 return Error(SM.getErrorLoc(IdentLoc), ErrMsg);
2209 if (
unsigned OpKind = IdentifyMasmOperator(Identifier)) {
2211 if (ParseMasmOperator(OpKind, Val))
2213 if (SM.onInteger(Val, ErrMsg))
2214 return Error(SM.getErrorLoc(IdentLoc), ErrMsg);
2217 if (!getParser().lookUpType(Identifier, FieldInfo.
Type)) {
2223 getParser().parseIdentifier(Identifier);
2227 if (getParser().lookUpField(FieldInfo.
Type.
Name, Identifier,
2231 return Error(IdentLoc,
"Unable to lookup field reference!",
2232 SMRange(IdentLoc, IDEnd));
2237 if (SM.onInteger(FieldInfo.
Offset, ErrMsg))
2238 return Error(SM.getErrorLoc(IdentLoc), ErrMsg);
2242 if (getParser().parsePrimaryExpr(Val,
End, &FieldInfo.
Type)) {
2243 return Error(Tok.
getLoc(),
"Unexpected identifier!");
2244 }
else if (SM.onIdentifierExpr(Val, Identifier, Info, FieldInfo.
Type,
2246 return Error(SM.getErrorLoc(IdentLoc), ErrMsg);
2252 SMLoc Loc = getTok().getLoc();
2253 int64_t
IntVal = getTok().getIntVal();
2254 End = consumeToken();
2255 UpdateLocLex =
false;
2257 StringRef IDVal = getTok().getString();
2258 if (IDVal ==
"f" || IDVal ==
"b") {
2260 getContext().getDirectionalLocalSymbol(IntVal, IDVal ==
"b");
2265 return Error(Loc,
"invalid reference to undefined symbol");
2267 InlineAsmIdentifierInfo
Info;
2269 if (SM.onIdentifierExpr(Val, Identifier, Info,
Type,
2270 isParsingMSInlineAsm(), ErrMsg))
2271 return Error(SM.getErrorLoc(Loc), ErrMsg);
2272 End = consumeToken();
2274 if (SM.onInteger(IntVal, ErrMsg))
2275 return Error(SM.getErrorLoc(Loc), ErrMsg);
2278 if (SM.onInteger(IntVal, ErrMsg))
2279 return Error(SM.getErrorLoc(Loc), ErrMsg);
2284 if (SM.onPlus(ErrMsg))
2285 return Error(getTok().getLoc(), ErrMsg);
2288 if (SM.onMinus(getTok().getLoc(), ErrMsg))
2289 return Error(SM.getErrorLoc(getTok().getLoc()), ErrMsg);
2299 SM.onLShift();
break;
2301 SM.onRShift();
break;
2304 return Error(Tok.
getLoc(),
"unexpected bracket encountered");
2305 tryParseOperandIdx(PrevTK, SM);
2308 if (SM.onRBrac(ErrMsg)) {
2309 return Error(SM.getErrorLoc(Tok.
getLoc()), ErrMsg);
2313 SM.onLParen(Tok.
getLoc());
2316 if (SM.onRParen(ErrMsg)) {
2317 return Error(SM.getErrorLoc(Tok.
getLoc()), ErrMsg);
2322 return Error(Tok.
getLoc(),
"unknown token in expression");
2324 if (!
Done && UpdateLocLex)
2325 End = consumeToken();
2329 if (SM.hasUnmatchedParen())
2330 return Error(SM.getLParenLoc(),
"unmatched parenthesis");
2334void X86AsmParser::RewriteIntelExpression(IntelExprStateMachine &SM,
2335 SMLoc Start, SMLoc
End) {
2337 unsigned ExprLen =
End.getPointer() -
Start.getPointer();
2339 if (SM.getSym() && !SM.isOffsetOperator()) {
2340 StringRef SymName = SM.getSymName();
2341 if (
unsigned Len = SymName.
data() -
Start.getPointer())
2344 ExprLen =
End.getPointer() - (SymName.
data() + SymName.
size());
2347 if (!(SM.getBaseReg() || SM.getIndexReg() || SM.getImm())) {
2354 StringRef BaseRegStr;
2355 StringRef IndexRegStr;
2356 StringRef OffsetNameStr;
2357 if (SM.getBaseReg())
2359 if (SM.getIndexReg())
2361 if (SM.isOffsetOperator())
2362 OffsetNameStr = SM.getSymName();
2364 IntelExpr Expr(BaseRegStr, IndexRegStr, SM.getScale(), OffsetNameStr,
2365 SM.getImm(), SM.isMemExpr());
2366 InstInfo->
AsmRewrites->emplace_back(Loc, ExprLen, Expr);
2370bool X86AsmParser::ParseIntelInlineAsmIdentifier(
2371 const MCExpr *&Val, StringRef &Identifier, InlineAsmIdentifierInfo &Info,
2372 bool IsUnevaluatedOperand, SMLoc &
End,
bool IsParsingOffsetOperator) {
2373 MCAsmParser &Parser = getParser();
2374 assert(isParsingMSInlineAsm() &&
"Expected to be parsing inline assembly.");
2378 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);
2380 const AsmToken &Tok = Parser.
getTok();
2381 SMLoc Loc = Tok.
getLoc();
2389 }
while (
End.getPointer() < EndPtr);
2396 "frontend claimed part of a token?");
2401 StringRef InternalName =
2402 SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(),
2404 assert(InternalName.
size() &&
"We should have an internal name here.");
2407 if (!IsParsingOffsetOperator)
2423 MCAsmParser &Parser = getParser();
2424 const AsmToken &Tok = Parser.
getTok();
2426 const SMLoc consumedToken = consumeToken();
2428 return Error(Tok.
getLoc(),
"Expected an identifier after {");
2431 .Case(
"rn", X86::STATIC_ROUNDING::TO_NEAREST_INT)
2432 .Case(
"rd", X86::STATIC_ROUNDING::TO_NEG_INF)
2433 .Case(
"ru", X86::STATIC_ROUNDING::TO_POS_INF)
2434 .Case(
"rz", X86::STATIC_ROUNDING::TO_ZERO)
2437 return Error(Tok.
getLoc(),
"Invalid rounding mode.");
2440 return Error(Tok.
getLoc(),
"Expected - at this point");
2444 return Error(Tok.
getLoc(),
"Expected } at this point");
2447 const MCExpr *RndModeOp =
2455 return Error(Tok.
getLoc(),
"Expected } at this point");
2460 return Error(Tok.
getLoc(),
"unknown token in expression");
2466 MCAsmParser &Parser = getParser();
2467 AsmToken Tok = Parser.
getTok();
2470 return Error(Tok.
getLoc(),
"Expected { at this point");
2474 return Error(Tok.
getLoc(),
"Expected dfv at this point");
2478 return Error(Tok.
getLoc(),
"Expected = at this point");
2490 unsigned CFlags = 0;
2491 for (
unsigned I = 0;
I < 4; ++
I) {
2500 return Error(Tok.
getLoc(),
"Invalid conditional flags");
2503 return Error(Tok.
getLoc(),
"Duplicated conditional flag");
2514 }
else if (
I == 3) {
2515 return Error(Tok.
getLoc(),
"Expected } at this point");
2517 return Error(Tok.
getLoc(),
"Expected } or , at this point");
2525bool X86AsmParser::ParseIntelDotOperator(IntelExprStateMachine &SM,
2527 const AsmToken &Tok = getTok();
2533 bool TrailingDot =
false;
2541 }
else if ((isParsingMSInlineAsm() || getParser().isParsingMasm()) &&
2544 const std::pair<StringRef, StringRef> BaseMember = DotDispStr.
split(
'.');
2545 const StringRef
Base = BaseMember.first,
Member = BaseMember.second;
2546 if (getParser().lookUpField(SM.getType(), DotDispStr, Info) &&
2547 getParser().lookUpField(SM.getSymName(), DotDispStr, Info) &&
2548 getParser().lookUpField(DotDispStr, Info) &&
2550 SemaCallback->LookupInlineAsmField(
Base, Member,
Info.Offset)))
2551 return Error(Tok.
getLoc(),
"Unable to lookup field reference!");
2553 return Error(Tok.
getLoc(),
"Unexpected token type!");
2558 const char *DotExprEndLoc = DotDispStr.
data() + DotDispStr.
size();
2563 SM.addImm(
Info.Offset);
2564 SM.setTypeInfo(
Info.Type);
2570bool X86AsmParser::ParseIntelOffsetOperator(
const MCExpr *&Val, StringRef &ID,
2571 InlineAsmIdentifierInfo &Info,
2574 SMLoc
Start = Lex().getLoc();
2575 ID = getTok().getString();
2576 if (!isParsingMSInlineAsm()) {
2579 getParser().parsePrimaryExpr(Val,
End,
nullptr))
2580 return Error(Start,
"unexpected token!");
2581 }
else if (ParseIntelInlineAsmIdentifier(Val, ID, Info,
false,
End,
true)) {
2582 return Error(Start,
"unable to lookup expression");
2584 return Error(Start,
"offset operator cannot yet handle constants");
2591bool X86AsmParser::ParseIntelImagerelOperator(
const MCExpr *&Val, StringRef &ID,
2592 InlineAsmIdentifierInfo &Info,
2595 SMLoc
Start = Lex().getLoc();
2596 ID = getTok().getString();
2597 if (!isParsingMSInlineAsm()) {
2600 getParser().parsePrimaryExpr(Val,
End,
nullptr))
2601 return Error(Start,
"unexpected token!");
2602 }
else if (ParseIntelInlineAsmIdentifier(Val, ID, Info,
false,
End,
true)) {
2603 return Error(Start,
"unable to lookup expression");
2605 return Error(Start,
"imagerel operator cannot yet handle constants");
2608 const MCExpr *ModifiedVal =
2611 return Error(Start,
"cannot apply 'imagerel' to this expression");
2618unsigned X86AsmParser::IdentifyIntelInlineAsmOperator(StringRef Name) {
2619 return StringSwitch<unsigned>(Name)
2620 .Cases({
"TYPE",
"type"}, IOK_TYPE)
2621 .Cases({
"SIZE",
"size"}, IOK_SIZE)
2622 .Cases({
"LENGTH",
"length"}, IOK_LENGTH)
2632unsigned X86AsmParser::ParseIntelInlineAsmOperator(
unsigned OpKind) {
2633 MCAsmParser &Parser = getParser();
2634 const AsmToken &Tok = Parser.
getTok();
2637 const MCExpr *Val =
nullptr;
2638 InlineAsmIdentifierInfo
Info;
2641 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
2646 Error(Start,
"unable to lookup expression");
2653 case IOK_LENGTH: CVal =
Info.Var.Length;
break;
2654 case IOK_SIZE: CVal =
Info.Var.Size;
break;
2655 case IOK_TYPE: CVal =
Info.Var.Type;
break;
2663unsigned X86AsmParser::IdentifyMasmOperator(StringRef Name) {
2664 return StringSwitch<unsigned>(
Name.lower())
2665 .Case(
"type", MOK_TYPE)
2666 .Cases({
"size",
"sizeof"}, MOK_SIZEOF)
2667 .Cases({
"length",
"lengthof"}, MOK_LENGTHOF)
2677bool X86AsmParser::ParseMasmOperator(
unsigned OpKind, int64_t &Val) {
2678 MCAsmParser &Parser = getParser();
2683 if (OpKind == MOK_SIZEOF || OpKind == MOK_TYPE) {
2686 const AsmToken &IDTok = InParens ? getLexer().peekTok() : Parser.
getTok();
2702 IntelExprStateMachine SM;
2704 if (ParseIntelExpression(SM,
End))
2714 Val = SM.getLength();
2717 Val = SM.getElementSize();
2722 return Error(OpLoc,
"expression has unknown type", SMRange(Start,
End));
2728bool X86AsmParser::ParseIntelMemoryOperandSize(
unsigned &
Size,
2729 StringRef *SizeStr) {
2730 Size = StringSwitch<unsigned>(getTok().getString())
2731 .Cases({
"BYTE",
"byte"}, 8)
2732 .Cases({
"WORD",
"word"}, 16)
2733 .Cases({
"DWORD",
"dword"}, 32)
2734 .Cases({
"FLOAT",
"float"}, 32)
2735 .Cases({
"LONG",
"long"}, 32)
2736 .Cases({
"FWORD",
"fword"}, 48)
2737 .Cases({
"DOUBLE",
"double"}, 64)
2738 .Cases({
"QWORD",
"qword"}, 64)
2739 .Cases({
"MMWORD",
"mmword"}, 64)
2740 .Cases({
"XWORD",
"xword"}, 80)
2741 .Cases({
"TBYTE",
"tbyte"}, 80)
2742 .Cases({
"XMMWORD",
"xmmword"}, 128)
2743 .Cases({
"YMMWORD",
"ymmword"}, 256)
2744 .Cases({
"ZMMWORD",
"zmmword"}, 512)
2748 *SizeStr = getTok().getString();
2749 const AsmToken &Tok = Lex();
2751 return Error(Tok.
getLoc(),
"Expected 'PTR' or 'ptr' token!");
2758 if (getX86MCRegisterClass(X86::GR8RegClassID).
contains(RegNo))
2760 if (getX86MCRegisterClass(X86::GR16RegClassID).
contains(RegNo))
2762 if (getX86MCRegisterClass(X86::GR32RegClassID).
contains(RegNo))
2764 if (getX86MCRegisterClass(X86::GR64RegClassID).
contains(RegNo))
2771 MCAsmParser &Parser = getParser();
2772 const AsmToken &Tok = Parser.
getTok();
2778 if (ParseIntelMemoryOperandSize(
Size, &SizeStr))
2780 bool PtrInOperand = bool(
Size);
2786 return ParseRoundingModeOp(Start,
Operands);
2791 if (RegNo == X86::RIP)
2792 return Error(Start,
"rip can only be used as a base register");
2797 return Error(Start,
"expected memory operand after 'ptr', "
2798 "found register operand instead");
2807 "cannot cast register '" +
2809 "'; its size is not easily defined.");
2813 std::to_string(
RegSize) +
"-bit register '" +
2815 "' cannot be used as a " + std::to_string(
Size) +
"-bit " +
2822 if (!getX86MCRegisterClass(X86::SEGMENT_REGRegClassID).
contains(RegNo))
2823 return Error(Start,
"invalid segment register");
2825 Start = Lex().getLoc();
2829 IntelExprStateMachine SM;
2830 if (ParseIntelExpression(SM,
End))
2833 if (isParsingMSInlineAsm())
2834 RewriteIntelExpression(SM, Start, Tok.
getLoc());
2836 int64_t
Imm = SM.getImm();
2837 const MCExpr *Disp = SM.getSym();
2846 if (!SM.isMemExpr() && !RegNo) {
2847 if (isParsingMSInlineAsm() && SM.isOffsetOperator()) {
2848 const InlineAsmIdentifierInfo &
Info = SM.getIdentifierInfo();
2853 SM.getSymName(),
Info.Var.Decl,
2854 Info.Var.IsGlobalLV));
2864 MCRegister
BaseReg = SM.getBaseReg();
2865 MCRegister IndexReg = SM.getIndexReg();
2866 if (IndexReg && BaseReg == X86::RIP)
2868 unsigned Scale = SM.getScale();
2870 Size = SM.getElementSize() << 3;
2872 if (Scale == 0 && BaseReg != X86::ESP && BaseReg != X86::RSP &&
2873 (IndexReg == X86::ESP || IndexReg == X86::RSP))
2879 !(getX86MCRegisterClass(X86::VR128XRegClassID).
contains(IndexReg) ||
2880 getX86MCRegisterClass(X86::VR256XRegClassID).
contains(IndexReg) ||
2881 getX86MCRegisterClass(X86::VR512RegClassID).
contains(IndexReg)) &&
2882 (getX86MCRegisterClass(X86::VR128XRegClassID).
contains(BaseReg) ||
2883 getX86MCRegisterClass(X86::VR256XRegClassID).
contains(BaseReg) ||
2884 getX86MCRegisterClass(X86::VR512RegClassID).
contains(BaseReg)))
2888 getX86MCRegisterClass(X86::GR16RegClassID).
contains(IndexReg))
2889 return Error(Start,
"16-bit addresses cannot have a scale");
2898 if ((BaseReg == X86::SI || BaseReg == X86::DI) &&
2899 (IndexReg == X86::BX || IndexReg == X86::BP))
2902 if ((BaseReg || IndexReg) &&
2905 return Error(Start, ErrMsg);
2906 bool IsUnconditionalBranch =
2907 Name.equals_insensitive(
"jmp") ||
Name.equals_insensitive(
"call");
2908 if (isParsingMSInlineAsm())
2909 return CreateMemForMSInlineAsm(RegNo, Disp, BaseReg, IndexReg, Scale,
2910 IsUnconditionalBranch && is64BitMode(),
2911 Start,
End,
Size, SM.getSymName(),
2916 MCRegister DefaultBaseReg;
2917 bool MaybeDirectBranchDest =
true;
2920 if (is64BitMode() &&
2921 ((PtrInOperand && !IndexReg) || SM.getElementSize() > 0)) {
2922 DefaultBaseReg = X86::RIP;
2924 if (IsUnconditionalBranch) {
2926 MaybeDirectBranchDest =
false;
2928 DefaultBaseReg = X86::RIP;
2929 }
else if (!BaseReg && !IndexReg && Disp &&
2931 if (is64BitMode()) {
2932 if (SM.getSize() == 8) {
2933 MaybeDirectBranchDest =
false;
2934 DefaultBaseReg = X86::RIP;
2937 if (SM.getSize() == 4 || SM.getSize() == 2)
2938 MaybeDirectBranchDest =
false;
2942 }
else if (IsUnconditionalBranch) {
2944 if (!PtrInOperand && SM.isOffsetOperator())
2946 Start,
"`OFFSET` operator cannot be used in an unconditional branch");
2947 if (PtrInOperand || SM.isBracketUsed())
2948 MaybeDirectBranchDest =
false;
2951 if (CheckDispOverflow(BaseReg, IndexReg, Disp, Start))
2954 if ((BaseReg || IndexReg || RegNo || DefaultBaseReg))
2956 getPointerWidth(), RegNo, Disp, BaseReg, IndexReg, Scale, Start,
End,
2957 Size, DefaultBaseReg, StringRef(),
nullptr,
2958 0,
false, MaybeDirectBranchDest));
2961 getPointerWidth(), Disp, Start,
End,
Size, StringRef(),
2963 MaybeDirectBranchDest));
2968 MCAsmParser &Parser = getParser();
2969 switch (getLexer().getKind()) {
2979 "expected immediate expression") ||
2980 getParser().parseExpression(Val,
End) ||
2988 return ParseRoundingModeOp(Start,
Operands);
2997 const MCExpr *Expr =
nullptr;
3009 if (
Reg == X86::EIZ ||
Reg == X86::RIZ)
3011 Loc,
"%eiz and %riz can only be used as index registers",
3012 SMRange(Loc, EndLoc));
3013 if (
Reg == X86::RIP)
3014 return Error(Loc,
"%rip can only be used as a base register",
3015 SMRange(Loc, EndLoc));
3021 if (!getX86MCRegisterClass(X86::SEGMENT_REGRegClassID).
contains(
Reg))
3022 return Error(Loc,
"invalid segment register");
3030 return ParseMemOperand(
Reg, Expr, Loc, EndLoc,
Operands);
3037X86::CondCode X86AsmParser::ParseConditionCode(StringRef CC) {
3038 return StringSwitch<X86::CondCode>(CC)
3060bool X86AsmParser::ParseZ(std::unique_ptr<X86Operand> &Z, SMLoc StartLoc) {
3061 MCAsmParser &Parser = getParser();
3066 (getLexer().getTok().getIdentifier() ==
"z")))
3071 return Error(getLexer().getLoc(),
"Expected } at this point");
3080 MCAsmParser &Parser = getParser();
3083 const SMLoc consumedToken = consumeToken();
3087 if (getLexer().getTok().getIntVal() != 1)
3088 return TokError(
"Expected 1to<NUM> at this point");
3089 StringRef
Prefix = getLexer().getTok().getString();
3092 return TokError(
"Expected 1to<NUM> at this point");
3095 StringRef BroadcastString = (
Prefix + getLexer().getTok().getIdentifier())
3098 return TokError(
"Expected 1to<NUM> at this point");
3099 const char *BroadcastPrimitive =
3100 StringSwitch<const char *>(BroadcastString)
3101 .Case(
"1to2",
"{1to2}")
3102 .Case(
"1to4",
"{1to4}")
3103 .Case(
"1to8",
"{1to8}")
3104 .Case(
"1to16",
"{1to16}")
3105 .Case(
"1to32",
"{1to32}")
3107 if (!BroadcastPrimitive)
3108 return TokError(
"Invalid memory broadcast primitive.");
3111 return TokError(
"Expected } at this point");
3122 std::unique_ptr<X86Operand>
Z;
3123 if (ParseZ(Z, consumedToken))
3129 SMLoc StartLoc =
Z ? consumeToken() : consumedToken;
3134 if (!parseRegister(RegNo, RegLoc, StartLoc) &&
3135 getX86MCRegisterClass(X86::VK1RegClassID).
contains(RegNo)) {
3136 if (RegNo == X86::K0)
3137 return Error(RegLoc,
"Register k0 can't be used as write mask");
3139 return Error(getLexer().getLoc(),
"Expected } at this point");
3145 return Error(getLexer().getLoc(),
3146 "Expected an op-mask register at this point");
3151 if (ParseZ(Z, consumeToken()) || !Z)
3152 return Error(getLexer().getLoc(),
3153 "Expected a {z} mark at this point");
3168bool X86AsmParser::CheckDispOverflow(MCRegister BaseReg, MCRegister IndexReg,
3169 const MCExpr *Disp, SMLoc Loc) {
3175 if (BaseReg || IndexReg) {
3177 auto Imm =
CE->getValue();
3179 getX86MCRegisterClass(X86::GR64RegClassID).contains(BaseReg) ||
3180 getX86MCRegisterClass(X86::GR64RegClassID).contains(IndexReg);
3181 bool Is16 = getX86MCRegisterClass(X86::GR16RegClassID).contains(BaseReg);
3184 return Error(Loc,
"displacement " + Twine(
Imm) +
3185 " is not within [-2147483648, 2147483647]");
3189 " shortened to 32-bit signed " +
3190 Twine(
static_cast<int32_t
>(
Imm)));
3194 " shortened to 16-bit signed " +
3195 Twine(
static_cast<int16_t
>(
Imm)));
3204bool X86AsmParser::ParseMemOperand(MCRegister SegReg,
const MCExpr *Disp,
3205 SMLoc StartLoc, SMLoc EndLoc,
3207 MCAsmParser &Parser = getParser();
3225 auto isAtMemOperand = [
this]() {
3230 auto TokCount = this->getLexer().peekTokens(Buf,
true);
3233 switch (Buf[0].getKind()) {
3240 if ((TokCount > 1) &&
3244 Buf[1].getIdentifier().
size() + 1);
3266 if (!isAtMemOperand()) {
3272 return Error(Loc,
"unexpected register in memory operand",
3273 SMRange(Loc, EndLoc));
3289 0, 0, 1, StartLoc, EndLoc));
3297 SMLoc BaseLoc = getLexer().getLoc();
3309 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ)
3310 return Error(BaseLoc,
"eiz and riz can only be used as index registers",
3311 SMRange(BaseLoc, EndLoc));
3329 if (!
E->evaluateAsAbsolute(ScaleVal, getStreamer().getAssemblerPtr()))
3330 return Error(Loc,
"expected absolute expression");
3332 Warning(Loc,
"scale factor without index register is ignored");
3337 if (BaseReg == X86::RIP)
3339 "%rip as base register can not have an index register");
3340 if (IndexReg == X86::RIP)
3341 return Error(Loc,
"%rip is not allowed as an index register");
3352 return Error(Loc,
"expected scale expression");
3353 Scale = (unsigned)ScaleVal;
3355 if (getX86MCRegisterClass(X86::GR16RegClassID).
contains(BaseReg) &&
3357 return Error(Loc,
"scale factor in 16-bit address must be 1");
3359 return Error(Loc, ErrMsg);
3373 if (BaseReg == X86::DX && !IndexReg && Scale == 1 && !SegReg &&
3382 return Error(BaseLoc, ErrMsg);
3384 if (CheckDispOverflow(BaseReg, IndexReg, Disp, BaseLoc))
3387 if (SegReg || BaseReg || IndexReg)
3389 BaseReg, IndexReg, Scale, StartLoc,
3398bool X86AsmParser::parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
3399 MCAsmParser &Parser = getParser();
3406 if (parseRegister(RegNo, StartLoc, EndLoc))
3414bool X86AsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
3416 MCAsmParser &Parser = getParser();
3420 ForcedOpcodePrefix = OpcodePrefix_Default;
3421 ForcedDispEncoding = DispEncoding_Default;
3422 UseApxExtendedReg =
false;
3423 ForcedNoFlag =
false;
3436 if (Prefix ==
"rex")
3437 ForcedOpcodePrefix = OpcodePrefix_REX;
3438 else if (Prefix ==
"rex2")
3439 ForcedOpcodePrefix = OpcodePrefix_REX2;
3440 else if (Prefix ==
"vex")
3441 ForcedOpcodePrefix = OpcodePrefix_VEX;
3442 else if (Prefix ==
"vex2")
3443 ForcedOpcodePrefix = OpcodePrefix_VEX2;
3444 else if (Prefix ==
"vex3")
3445 ForcedOpcodePrefix = OpcodePrefix_VEX3;
3446 else if (Prefix ==
"evex")
3447 ForcedOpcodePrefix = OpcodePrefix_EVEX;
3448 else if (Prefix ==
"disp8")
3449 ForcedDispEncoding = DispEncoding_Disp8;
3450 else if (Prefix ==
"disp32")
3451 ForcedDispEncoding = DispEncoding_Disp32;
3452 else if (Prefix ==
"nf")
3453 ForcedNoFlag =
true;
3455 return Error(NameLoc,
"unknown prefix");
3471 if (isParsingMSInlineAsm()) {
3472 if (
Name.equals_insensitive(
"vex"))
3473 ForcedOpcodePrefix = OpcodePrefix_VEX;
3474 else if (
Name.equals_insensitive(
"vex2"))
3475 ForcedOpcodePrefix = OpcodePrefix_VEX2;
3476 else if (
Name.equals_insensitive(
"vex3"))
3477 ForcedOpcodePrefix = OpcodePrefix_VEX3;
3478 else if (
Name.equals_insensitive(
"evex"))
3479 ForcedOpcodePrefix = OpcodePrefix_EVEX;
3481 if (ForcedOpcodePrefix != OpcodePrefix_Default) {
3494 if (
Name.consume_back(
".d32")) {
3495 ForcedDispEncoding = DispEncoding_Disp32;
3496 }
else if (
Name.consume_back(
".d8")) {
3497 ForcedDispEncoding = DispEncoding_Disp8;
3500 StringRef PatchedName =
Name;
3503 if (isParsingIntelSyntax() &&
3504 (PatchedName ==
"jmp" || PatchedName ==
"jc" || PatchedName ==
"jnc" ||
3505 PatchedName ==
"jcxz" || PatchedName ==
"jecxz" ||
3510 : NextTok ==
"short") {
3519 NextTok.
size() + 1);
3525 PatchedName !=
"setzub" && PatchedName !=
"setzunb" &&
3526 PatchedName !=
"setb" && PatchedName !=
"setnb")
3527 PatchedName = PatchedName.
substr(0,
Name.size()-1);
3529 unsigned ComparisonPredicate = ~0
U;
3537 bool IsVCMP = PatchedName[0] ==
'v';
3538 unsigned CCIdx =
IsVCMP ? 4 : 3;
3539 unsigned suffixLength = PatchedName.
ends_with(
"bf16") ? 5 : 2;
3540 unsigned CC = StringSwitch<unsigned>(
3541 PatchedName.
slice(CCIdx, PatchedName.
size() - suffixLength))
3543 .Case(
"eq_oq", 0x00)
3545 .Case(
"lt_os", 0x01)
3547 .Case(
"le_os", 0x02)
3548 .Case(
"unord", 0x03)
3549 .Case(
"unord_q", 0x03)
3551 .Case(
"neq_uq", 0x04)
3553 .Case(
"nlt_us", 0x05)
3555 .Case(
"nle_us", 0x06)
3557 .Case(
"ord_q", 0x07)
3559 .Case(
"eq_uq", 0x08)
3561 .Case(
"nge_us", 0x09)
3563 .Case(
"ngt_us", 0x0A)
3564 .Case(
"false", 0x0B)
3565 .Case(
"false_oq", 0x0B)
3566 .Case(
"neq_oq", 0x0C)
3568 .Case(
"ge_os", 0x0D)
3570 .Case(
"gt_os", 0x0E)
3572 .Case(
"true_uq", 0x0F)
3573 .Case(
"eq_os", 0x10)
3574 .Case(
"lt_oq", 0x11)
3575 .Case(
"le_oq", 0x12)
3576 .Case(
"unord_s", 0x13)
3577 .Case(
"neq_us", 0x14)
3578 .Case(
"nlt_uq", 0x15)
3579 .Case(
"nle_uq", 0x16)
3580 .Case(
"ord_s", 0x17)
3581 .Case(
"eq_us", 0x18)
3582 .Case(
"nge_uq", 0x19)
3583 .Case(
"ngt_uq", 0x1A)
3584 .Case(
"false_os", 0x1B)
3585 .Case(
"neq_os", 0x1C)
3586 .Case(
"ge_oq", 0x1D)
3587 .Case(
"gt_oq", 0x1E)
3588 .Case(
"true_us", 0x1F)
3590 if (CC != ~0U && (
IsVCMP || CC < 8) &&
3593 PatchedName =
IsVCMP ?
"vcmpss" :
"cmpss";
3595 PatchedName =
IsVCMP ?
"vcmpsd" :
"cmpsd";
3597 PatchedName =
IsVCMP ?
"vcmpps" :
"cmpps";
3599 PatchedName =
IsVCMP ?
"vcmppd" :
"cmppd";
3601 PatchedName =
"vcmpsh";
3603 PatchedName =
"vcmpph";
3605 PatchedName =
"vcmpbf16";
3609 ComparisonPredicate = CC;
3615 (PatchedName.
back() ==
'b' || PatchedName.
back() ==
'w' ||
3616 PatchedName.
back() ==
'd' || PatchedName.
back() ==
'q')) {
3617 unsigned SuffixSize = PatchedName.
drop_back().
back() ==
'u' ? 2 : 1;
3618 unsigned CC = StringSwitch<unsigned>(
3619 PatchedName.
slice(5, PatchedName.
size() - SuffixSize))
3629 if (CC != ~0U && (CC != 0 || SuffixSize == 2)) {
3630 switch (PatchedName.
back()) {
3632 case 'b': PatchedName = SuffixSize == 2 ?
"vpcmpub" :
"vpcmpb";
break;
3633 case 'w': PatchedName = SuffixSize == 2 ?
"vpcmpuw" :
"vpcmpw";
break;
3634 case 'd': PatchedName = SuffixSize == 2 ?
"vpcmpud" :
"vpcmpd";
break;
3635 case 'q': PatchedName = SuffixSize == 2 ?
"vpcmpuq" :
"vpcmpq";
break;
3638 ComparisonPredicate = CC;
3644 (PatchedName.
back() ==
'b' || PatchedName.
back() ==
'w' ||
3645 PatchedName.
back() ==
'd' || PatchedName.
back() ==
'q')) {
3646 unsigned SuffixSize = PatchedName.
drop_back().
back() ==
'u' ? 2 : 1;
3647 unsigned CC = StringSwitch<unsigned>(
3648 PatchedName.
slice(5, PatchedName.
size() - SuffixSize))
3659 switch (PatchedName.
back()) {
3661 case 'b': PatchedName = SuffixSize == 2 ?
"vpcomub" :
"vpcomb";
break;
3662 case 'w': PatchedName = SuffixSize == 2 ?
"vpcomuw" :
"vpcomw";
break;
3663 case 'd': PatchedName = SuffixSize == 2 ?
"vpcomud" :
"vpcomd";
break;
3664 case 'q': PatchedName = SuffixSize == 2 ?
"vpcomuq" :
"vpcomq";
break;
3667 ComparisonPredicate = CC;
3679 StringSwitch<bool>(Name)
3680 .Cases({
"cs",
"ds",
"es",
"fs",
"gs",
"ss"},
true)
3681 .Cases({
"rex64",
"data32",
"data16",
"addr32",
"addr16"},
true)
3682 .Cases({
"xacquire",
"xrelease"},
true)
3683 .Cases({
"acquire",
"release"}, isParsingIntelSyntax())
3686 auto isLockRepeatNtPrefix = [](StringRef
N) {
3687 return StringSwitch<bool>(
N)
3688 .Cases({
"lock",
"rep",
"repe",
"repz",
"repne",
"repnz",
"notrack"},
3693 bool CurlyAsEndOfStatement =
false;
3696 while (isLockRepeatNtPrefix(
Name.lower())) {
3698 StringSwitch<unsigned>(Name)
3717 while (
Name.starts_with(
";") ||
Name.starts_with(
"\n") ||
3718 Name.starts_with(
"#") ||
Name.starts_with(
"\t") ||
3719 Name.starts_with(
"/")) {
3730 if (PatchedName ==
"data16" && is16BitMode()) {
3731 return Error(NameLoc,
"redundant data16 prefix");
3733 if (PatchedName ==
"data32") {
3735 return Error(NameLoc,
"redundant data32 prefix");
3737 return Error(NameLoc,
"'data32' is not supported in 64-bit mode");
3739 PatchedName =
"data16";
3746 if (
Next ==
"callw")
3748 if (
Next ==
"ljmpw")
3753 ForcedDataPrefix = X86::Is32Bit;
3761 if (ComparisonPredicate != ~0U && !isParsingIntelSyntax()) {
3768 if ((
Name.starts_with(
"ccmp") ||
Name.starts_with(
"ctest")) &&
3797 CurlyAsEndOfStatement =
3798 isParsingIntelSyntax() && isParsingMSInlineAsm() &&
3801 return TokError(
"unexpected token in argument list");
3805 if (ComparisonPredicate != ~0U && isParsingIntelSyntax()) {
3815 else if (CurlyAsEndOfStatement)
3818 getLexer().getTok().getLoc(), 0);
3825 if (IsFp &&
Operands.size() == 1) {
3826 const char *Repl = StringSwitch<const char *>(Name)
3827 .Case(
"fsub",
"fsubp")
3828 .Case(
"fdiv",
"fdivp")
3829 .Case(
"fsubr",
"fsubrp")
3830 .Case(
"fdivr",
"fdivrp");
3831 static_cast<X86Operand &
>(*
Operands[0]).setTokenValue(Repl);
3834 if ((Name ==
"mov" || Name ==
"movw" || Name ==
"movl") &&
3836 X86Operand &Op1 = (X86Operand &)*
Operands[1];
3837 X86Operand &Op2 = (X86Operand &)*
Operands[2];
3842 getX86MCRegisterClass(X86::SEGMENT_REGRegClassID)
3844 (getX86MCRegisterClass(X86::GR16RegClassID).
contains(Op1.
getReg()) ||
3845 getX86MCRegisterClass(X86::GR32RegClassID).
contains(Op1.
getReg()))) {
3847 if (Name !=
"mov" && Name[3] == (is16BitMode() ?
'l' :
'w')) {
3848 Name = is16BitMode() ?
"movw" :
"movl";
3861 if ((Name ==
"outb" || Name ==
"outsb" || Name ==
"outw" || Name ==
"outsw" ||
3862 Name ==
"outl" || Name ==
"outsl" || Name ==
"out" || Name ==
"outs") &&
3864 X86Operand &
Op = (X86Operand &)*
Operands.back();
3870 if ((Name ==
"inb" || Name ==
"insb" || Name ==
"inw" || Name ==
"insw" ||
3871 Name ==
"inl" || Name ==
"insl" || Name ==
"in" || Name ==
"ins") &&
3880 bool HadVerifyError =
false;
3883 if (
Name.starts_with(
"ins") &&
3885 (Name ==
"insb" || Name ==
"insw" || Name ==
"insl" || Name ==
"insd" ||
3888 AddDefaultSrcDestOperands(TmpOperands,
3890 DefaultMemDIOperand(NameLoc));
3891 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3895 if (
Name.starts_with(
"outs") &&
3897 (Name ==
"outsb" || Name ==
"outsw" || Name ==
"outsl" ||
3898 Name ==
"outsd" || Name ==
"outs")) {
3899 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
3901 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3907 if (
Name.starts_with(
"lods") &&
3909 (Name ==
"lods" || Name ==
"lodsb" || Name ==
"lodsw" ||
3910 Name ==
"lodsl" || Name ==
"lodsd" || Name ==
"lodsq")) {
3911 TmpOperands.
push_back(DefaultMemSIOperand(NameLoc));
3912 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3918 if (
Name.starts_with(
"stos") &&
3920 (Name ==
"stos" || Name ==
"stosb" || Name ==
"stosw" ||
3921 Name ==
"stosl" || Name ==
"stosd" || Name ==
"stosq")) {
3922 TmpOperands.
push_back(DefaultMemDIOperand(NameLoc));
3923 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3929 if (
Name.starts_with(
"scas") &&
3931 (Name ==
"scas" || Name ==
"scasb" || Name ==
"scasw" ||
3932 Name ==
"scasl" || Name ==
"scasd" || Name ==
"scasq")) {
3933 TmpOperands.
push_back(DefaultMemDIOperand(NameLoc));
3934 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3938 if (
Name.starts_with(
"cmps") &&
3940 (Name ==
"cmps" || Name ==
"cmpsb" || Name ==
"cmpsw" ||
3941 Name ==
"cmpsl" || Name ==
"cmpsd" || Name ==
"cmpsq")) {
3942 AddDefaultSrcDestOperands(TmpOperands, DefaultMemDIOperand(NameLoc),
3943 DefaultMemSIOperand(NameLoc));
3944 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3948 if (((
Name.starts_with(
"movs") &&
3949 (Name ==
"movs" || Name ==
"movsb" || Name ==
"movsw" ||
3950 Name ==
"movsl" || Name ==
"movsd" || Name ==
"movsq")) ||
3951 (
Name.starts_with(
"smov") &&
3952 (Name ==
"smov" || Name ==
"smovb" || Name ==
"smovw" ||
3953 Name ==
"smovl" || Name ==
"smovd" || Name ==
"smovq"))) &&
3955 if (Name ==
"movsd" &&
Operands.size() == 1 && !isParsingIntelSyntax())
3957 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
3958 DefaultMemDIOperand(NameLoc));
3959 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3963 if (HadVerifyError) {
3964 return HadVerifyError;
3968 if ((Name ==
"xlat" || Name ==
"xlatb") &&
Operands.size() == 2) {
3969 X86Operand &Op1 =
static_cast<X86Operand &
>(*
Operands[1]);
3972 "size, (R|E)BX will be used for the location");
3974 static_cast<X86Operand &
>(*
Operands[0]).setTokenValue(
"xlatb");
3987 if (
I ==
Table.end() ||
I->OldOpc != Opcode)
3993 if (X86::isBLENDVPD(Opcode) || X86::isBLENDVPS(Opcode) ||
3994 X86::isPBLENDVB(Opcode))
4000bool X86AsmParser::processInstruction(MCInst &Inst,
const OperandVector &
Ops) {
4004 if (ForcedOpcodePrefix != OpcodePrefix_VEX3 &&
4011 auto replaceWithCCMPCTEST = [&](
unsigned Opcode) ->
bool {
4012 if (ForcedOpcodePrefix == OpcodePrefix_EVEX) {
4023 default:
return false;
4028 if (ForcedDispEncoding == DispEncoding_Disp32) {
4029 Inst.
setOpcode(is16BitMode() ? X86::JMP_2 : X86::JMP_4);
4038 if (ForcedDispEncoding == DispEncoding_Disp32) {
4039 Inst.
setOpcode(is16BitMode() ? X86::JCC_2 : X86::JCC_4);
4055#define FROM_TO(FROM, TO) \
4057 return replaceWithCCMPCTEST(X86::TO);
4059 FROM_TO(CMP64mi32, CCMP64mi32)
4062 FROM_TO(CMP64ri32, CCMP64ri32)
4089 FROM_TO(TEST64mi32, CTEST64mi32)
4091 FROM_TO(TEST64ri32, CTEST64ri32)
4111bool X86AsmParser::validateInstruction(MCInst &Inst,
const OperandVector &
Ops) {
4112 using namespace X86;
4113 const MCRegisterInfo *MRI =
getContext().getRegisterInfo();
4115 uint64_t TSFlags = MII.get(Opcode).TSFlags;
4116 if (isVFCMADDCPH(Opcode) || isVFCMADDCSH(Opcode) || isVFMADDCPH(Opcode) ||
4117 isVFMADDCSH(Opcode)) {
4121 return Warning(
Ops[0]->getStartLoc(),
"Destination register should be "
4122 "distinct from source registers");
4123 }
else if (isVFCMULCPH(Opcode) || isVFCMULCSH(Opcode) || isVFMULCPH(Opcode) ||
4124 isVFMULCSH(Opcode)) {
4134 return Warning(
Ops[0]->getStartLoc(),
"Destination register should be "
4135 "distinct from source registers");
4136 }
else if (isV4FMADDPS(Opcode) || isV4FMADDSS(Opcode) ||
4137 isV4FNMADDPS(Opcode) || isV4FNMADDSS(Opcode) ||
4138 isVP4DPWSSDS(Opcode) || isVP4DPWSSD(Opcode)) {
4143 if (Src2Enc % 4 != 0) {
4145 unsigned GroupStart = (Src2Enc / 4) * 4;
4146 unsigned GroupEnd = GroupStart + 3;
4148 "source register '" +
RegName +
"' implicitly denotes '" +
4149 RegName.take_front(3) + Twine(GroupStart) +
"' to '" +
4150 RegName.take_front(3) + Twine(GroupEnd) +
4153 }
else if (isVGATHERDPD(Opcode) || isVGATHERDPS(Opcode) ||
4154 isVGATHERQPD(Opcode) || isVGATHERQPS(Opcode) ||
4155 isVPGATHERDD(Opcode) || isVPGATHERDQ(Opcode) ||
4156 isVPGATHERQD(Opcode) || isVPGATHERQQ(Opcode)) {
4163 return Warning(
Ops[0]->getStartLoc(),
"index and destination registers "
4164 "should be distinct");
4170 if (Dest == Mask || Dest == Index || Mask == Index)
4171 return Warning(
Ops[0]->getStartLoc(),
"mask, index, and destination "
4172 "registers should be distinct");
4174 }
else if (isTCMMIMFP16PS(Opcode) || isTCMMRLFP16PS(Opcode) ||
4175 isTDPBF16PS(Opcode) || isTDPFP16PS(Opcode) || isTDPBSSD(Opcode) ||
4176 isTDPBSUD(Opcode) || isTDPBUSD(Opcode) || isTDPBUUD(Opcode)) {
4180 if (SrcDest == Src1 || SrcDest == Src2 || Src1 == Src2)
4181 return Error(
Ops[0]->getStartLoc(),
"all tmm registers must be distinct");
4195 for (
unsigned i = 0; i !=
NumOps; ++i) {
4200 if (
Reg == X86::AH ||
Reg == X86::BH ||
Reg == X86::CH ||
Reg == X86::DH)
4208 (Enc ==
X86II::EVEX || ForcedOpcodePrefix == OpcodePrefix_REX2 ||
4209 ForcedOpcodePrefix == OpcodePrefix_REX || UsesRex)) {
4211 return Error(
Ops[0]->getStartLoc(),
4212 "can't encode '" +
RegName.str() +
4213 "' in an instruction requiring EVEX/REX2/REX prefix");
4217 if ((Opcode == X86::PREFETCHIT0 || Opcode == X86::PREFETCHIT1)) {
4221 Ops[0]->getStartLoc(),
4222 Twine((Inst.
getOpcode() == X86::PREFETCHIT0 ?
"'prefetchit0'"
4223 :
"'prefetchit1'")) +
4224 " only supports RIP-relative address");
4229void X86AsmParser::emitWarningForSpecialLVIInstruction(SMLoc Loc) {
4230 Warning(Loc,
"Instruction may be vulnerable to LVI and "
4231 "requires manual mitigation");
4232 Note(SMLoc(),
"See https://software.intel.com/"
4233 "security-software-guidance/insights/"
4234 "deep-dive-load-value-injection#specialinstructions"
4235 " for more information");
4247void X86AsmParser::applyLVICFIMitigation(MCInst &Inst, MCStreamer &Out) {
4258 MCInst ShlInst, FenceInst;
4259 bool Parse32 = is32BitMode() || Code16GCC;
4260 MCRegister Basereg =
4261 is64BitMode() ? X86::RSP : (Parse32 ? X86::ESP : X86::SP);
4265 1, SMLoc{}, SMLoc{}, 0);
4267 ShlMemOp->addMemOperands(ShlInst, 5);
4270 Out.emitInstruction(ShlInst, getSTI());
4271 Out.emitInstruction(FenceInst, getSTI());
4280 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4292void X86AsmParser::applyLVILoadHardeningMitigation(MCInst &Inst,
4309 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4312 }
else if (Opcode == X86::REP_PREFIX || Opcode == X86::REPNE_PREFIX) {
4315 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4319 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
4330 Out.emitInstruction(FenceInst, getSTI());
4336 if (CLOpts.experimental_lvi_inline_asm_hardening &&
4337 getSTI().
hasFeature(X86::FeatureLVIControlFlowIntegrity))
4338 applyLVICFIMitigation(Inst, Out);
4340 Out.emitInstruction(Inst, getSTI());
4342 if (CLOpts.experimental_lvi_inline_asm_hardening &&
4343 getSTI().
hasFeature(X86::FeatureLVILoadHardening))
4344 applyLVILoadHardeningMitigation(Inst, Out);
4348 unsigned Result = 0;
4350 if (Prefix.isPrefix()) {
4351 Result = Prefix.getPrefix();
4357bool X86AsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
4359 MCStreamer &Out,
uint64_t &ErrorInfo,
4360 bool MatchingInlineAsm) {
4362 assert((*
Operands[0]).isToken() &&
"Leading operand should always be a mnemonic!");
4365 MatchFPUWaitAlias(IDLoc,
static_cast<X86Operand &
>(*
Operands[0]),
Operands,
4366 Out, MatchingInlineAsm);
4373 if (ForcedOpcodePrefix == OpcodePrefix_REX)
4375 else if (ForcedOpcodePrefix == OpcodePrefix_REX2)
4377 else if (ForcedOpcodePrefix == OpcodePrefix_VEX)
4379 else if (ForcedOpcodePrefix == OpcodePrefix_VEX2)
4381 else if (ForcedOpcodePrefix == OpcodePrefix_VEX3)
4383 else if (ForcedOpcodePrefix == OpcodePrefix_EVEX)
4387 if (ForcedDispEncoding == DispEncoding_Disp8)
4389 else if (ForcedDispEncoding == DispEncoding_Disp32)
4395 return isParsingIntelSyntax()
4396 ? matchAndEmitIntelInstruction(IDLoc, Opcode, Inst,
Operands, Out,
4397 ErrorInfo, MatchingInlineAsm)
4398 : matchAndEmitATTInstruction(IDLoc, Opcode, Inst,
Operands,
Out,
4399 ErrorInfo, MatchingInlineAsm);
4402void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &
Op,
4404 bool MatchingInlineAsm) {
4408 const char *Repl = StringSwitch<const char *>(
Op.getToken())
4409 .Case(
"finit",
"fninit")
4410 .Case(
"fsave",
"fnsave")
4411 .Case(
"fstcw",
"fnstcw")
4412 .Case(
"fstcww",
"fnstcw")
4413 .Case(
"fstenv",
"fnstenv")
4414 .Case(
"fstsw",
"fnstsw")
4415 .Case(
"fstsww",
"fnstsw")
4416 .Case(
"fclex",
"fnclex")
4422 if (!MatchingInlineAsm)
4428bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc,
4429 const FeatureBitset &MissingFeatures,
4430 bool MatchingInlineAsm) {
4431 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
4432 SmallString<126>
Msg;
4433 raw_svector_ostream OS(
Msg);
4434 OS <<
"instruction requires:";
4435 for (
unsigned Feature : MissingFeatures)
4437 return Error(IDLoc, OS.str(), SMRange(), MatchingInlineAsm);
4440unsigned X86AsmParser::checkTargetMatchPredicate(MCInst &Inst) {
4442 const MCInstrDesc &MCID = MII.get(
Opc);
4446 return Match_Unsupported;
4448 return Match_Unsupported;
4450 switch (ForcedOpcodePrefix) {
4451 case OpcodePrefix_Default:
4453 case OpcodePrefix_REX:
4454 case OpcodePrefix_REX2:
4456 return Match_Unsupported;
4458 case OpcodePrefix_VEX:
4459 case OpcodePrefix_VEX2:
4460 case OpcodePrefix_VEX3:
4462 return Match_Unsupported;
4464 case OpcodePrefix_EVEX:
4466 !X86::isCMP(
Opc) && !X86::isTEST(
Opc))
4467 return Match_Unsupported;
4469 return Match_Unsupported;
4474 (ForcedOpcodePrefix != OpcodePrefix_VEX &&
4475 ForcedOpcodePrefix != OpcodePrefix_VEX2 &&
4476 ForcedOpcodePrefix != OpcodePrefix_VEX3))
4477 return Match_Unsupported;
4479 return Match_Success;
4482bool X86AsmParser::matchAndEmitATTInstruction(
4484 MCStreamer &Out,
uint64_t &ErrorInfo,
bool MatchingInlineAsm) {
4485 X86Operand &
Op =
static_cast<X86Operand &
>(*
Operands[0]);
4489 if (ForcedDataPrefix == X86::Is32Bit)
4490 SwitchMode(X86::Is32Bit);
4492 FeatureBitset MissingFeatures;
4493 unsigned OriginalError = MatchInstruction(
Operands, Inst, ErrorInfo,
4494 MissingFeatures, MatchingInlineAsm,
4495 isParsingIntelSyntax());
4496 if (ForcedDataPrefix == X86::Is32Bit) {
4497 SwitchMode(X86::Is16Bit);
4498 ForcedDataPrefix = 0;
4500 switch (OriginalError) {
4503 if (!MatchingInlineAsm && validateInstruction(Inst,
Operands))
4508 if (!MatchingInlineAsm)
4509 while (processInstruction(Inst,
Operands))
4513 if (!MatchingInlineAsm)
4517 case Match_InvalidImmUnsignedi4: {
4518 SMLoc ErrorLoc = ((X86Operand &)*
Operands[ErrorInfo]).getStartLoc();
4519 if (ErrorLoc == SMLoc())
4521 return Error(ErrorLoc,
"immediate must be an integer in range [0, 15]",
4522 EmptyRange, MatchingInlineAsm);
4524 case Match_InvalidImmUnsignedi6: {
4525 SMLoc ErrorLoc = ((X86Operand &)*
Operands[ErrorInfo]).getStartLoc();
4526 if (ErrorLoc == SMLoc())
4528 return Error(ErrorLoc,
"immediate must be an integer in range [0, 63]",
4529 EmptyRange, MatchingInlineAsm);
4531 case Match_MissingFeature:
4532 return ErrorMissingFeature(IDLoc, MissingFeatures, MatchingInlineAsm);
4533 case Match_InvalidOperand:
4534 case Match_MnemonicFail:
4535 case Match_Unsupported:
4538 if (
Op.getToken().empty()) {
4539 Error(IDLoc,
"instruction must have size higher than 0", EmptyRange,
4550 StringRef
Base =
Op.getToken();
4551 SmallString<16> Tmp;
4554 Op.setTokenValue(Tmp);
4562 const char *Suffixes =
Base[0] !=
'f' ?
"bwlq" :
"slt\0";
4564 const char *MemSize =
Base[0] !=
'f' ?
"\x08\x10\x20\x40" :
"\x20\x40\x50\0";
4568 FeatureBitset ErrorInfoMissingFeatures;
4576 bool HasVectorReg =
false;
4577 X86Operand *MemOp =
nullptr;
4579 X86Operand *X86Op =
static_cast<X86Operand *
>(
Op.get());
4581 HasVectorReg =
true;
4582 else if (X86Op->
isMem()) {
4584 assert(MemOp->Mem.Size == 0 &&
"Memory size always 0 under ATT syntax");
4591 for (
unsigned I = 0,
E = std::size(Match);
I !=
E; ++
I) {
4592 Tmp.
back() = Suffixes[
I];
4593 if (MemOp && HasVectorReg)
4594 MemOp->Mem.Size = MemSize[
I];
4595 Match[
I] = Match_MnemonicFail;
4596 if (MemOp || !HasVectorReg) {
4598 MatchInstruction(
Operands, Inst, ErrorInfoIgnore, MissingFeatures,
4599 MatchingInlineAsm, isParsingIntelSyntax());
4601 if (Match[
I] == Match_MissingFeature)
4602 ErrorInfoMissingFeatures = MissingFeatures;
4612 unsigned NumSuccessfulMatches =
llvm::count(Match, Match_Success);
4613 if (NumSuccessfulMatches == 1) {
4614 if (!MatchingInlineAsm && validateInstruction(Inst,
Operands))
4619 if (!MatchingInlineAsm)
4620 while (processInstruction(Inst,
Operands))
4624 if (!MatchingInlineAsm)
4634 if (NumSuccessfulMatches > 1) {
4636 unsigned NumMatches = 0;
4637 for (
unsigned I = 0,
E = std::size(Match);
I !=
E; ++
I)
4638 if (Match[
I] == Match_Success)
4639 MatchChars[NumMatches++] = Suffixes[
I];
4641 SmallString<126>
Msg;
4642 raw_svector_ostream OS(
Msg);
4643 OS <<
"ambiguous instructions require an explicit suffix (could be ";
4644 for (
unsigned i = 0; i != NumMatches; ++i) {
4647 if (i + 1 == NumMatches)
4649 OS <<
"'" <<
Base << MatchChars[i] <<
"'";
4652 Error(IDLoc, OS.str(), EmptyRange, MatchingInlineAsm);
4660 if (
llvm::count(Match, Match_MnemonicFail) == 4) {
4661 if (OriginalError == Match_MnemonicFail)
4662 return Error(IDLoc,
"invalid instruction mnemonic '" +
Base +
"'",
4663 Op.getLocRange(), MatchingInlineAsm);
4665 if (OriginalError == Match_Unsupported)
4666 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4669 assert(OriginalError == Match_InvalidOperand &&
"Unexpected error");
4671 if (ErrorInfo != ~0ULL) {
4673 return Error(IDLoc,
"too few operands for instruction", EmptyRange,
4676 X86Operand &Operand = (X86Operand &)*
Operands[ErrorInfo];
4680 OperandRange, MatchingInlineAsm);
4684 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4690 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4696 if (
llvm::count(Match, Match_MissingFeature) == 1) {
4697 ErrorInfo = Match_MissingFeature;
4698 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
4704 if (
llvm::count(Match, Match_InvalidOperand) == 1) {
4705 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4710 Error(IDLoc,
"unknown use of instruction mnemonic without a size suffix",
4711 EmptyRange, MatchingInlineAsm);
4715bool X86AsmParser::matchAndEmitIntelInstruction(
4717 MCStreamer &Out,
uint64_t &ErrorInfo,
bool MatchingInlineAsm) {
4718 X86Operand &
Op =
static_cast<X86Operand &
>(*
Operands[0]);
4723 const bool ForcedData32 = ForcedDataPrefix == X86::Is32Bit;
4724 auto RestoreMode = [&] {
4726 SwitchMode(X86::Is16Bit);
4727 ForcedDataPrefix = 0;
4731 SwitchMode(X86::Is32Bit);
4733 X86Operand *UnsizedMemOp =
nullptr;
4735 X86Operand *X86Op =
static_cast<X86Operand *
>(
Op.get());
4737 UnsizedMemOp = X86Op;
4748 static const char *
const PtrSizedInstrs[] = {
"call",
"jmp",
"push",
"pop"};
4749 for (
const char *Instr : PtrSizedInstrs) {
4750 if (Mnemonic == Instr) {
4751 UnsizedMemOp->
Mem.
Size = getPointerWidth();
4757 SmallVector<unsigned, 8> Match;
4758 FeatureBitset ErrorInfoMissingFeatures;
4759 FeatureBitset MissingFeatures;
4764 if (Mnemonic ==
"push" &&
Operands.size() == 2) {
4765 auto *X86Op =
static_cast<X86Operand *
>(
Operands[1].get());
4766 if (X86Op->
isImm()) {
4769 unsigned Size = getPointerWidth();
4772 SmallString<16> Tmp;
4774 Tmp += (is64BitMode())
4776 : (is32BitMode()) ?
"l" : (is16BitMode()) ?
"w" :
" ";
4777 Op.setTokenValue(Tmp);
4780 MissingFeatures, MatchingInlineAsm,
4791 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
4792 for (
unsigned Size : MopSizes) {
4796 unsigned M = MatchInstruction(
Operands, Inst, ErrorInfoIgnore,
4797 MissingFeatures, MatchingInlineAsm,
4798 isParsingIntelSyntax());
4803 if (Match.
back() == Match_MissingFeature)
4804 ErrorInfoMissingFeatures = MissingFeatures;
4814 if (Match.
empty()) {
4816 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,
4817 isParsingIntelSyntax()));
4819 if (Match.
back() == Match_MissingFeature)
4820 ErrorInfoMissingFeatures = MissingFeatures;
4828 if (Match.
back() == Match_MnemonicFail) {
4830 return Error(IDLoc,
"invalid instruction mnemonic '" + Mnemonic +
"'",
4831 Op.getLocRange(), MatchingInlineAsm);
4834 unsigned NumSuccessfulMatches =
llvm::count(Match, Match_Success);
4838 if (UnsizedMemOp && NumSuccessfulMatches > 1 &&
4841 unsigned M = MatchInstruction(
4842 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,
4843 isParsingIntelSyntax());
4844 if (M == Match_Success)
4845 NumSuccessfulMatches = 1;
4860 if (NumSuccessfulMatches == 1) {
4861 if (!MatchingInlineAsm && validateInstruction(Inst,
Operands))
4866 if (!MatchingInlineAsm)
4867 while (processInstruction(Inst,
Operands))
4870 if (!MatchingInlineAsm)
4874 }
else if (NumSuccessfulMatches > 1) {
4876 "multiple matches only possible with unsized memory operands");
4878 "ambiguous operand size for instruction '" + Mnemonic +
"\'",
4884 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4890 if (
llvm::count(Match, Match_MissingFeature) == 1) {
4891 ErrorInfo = Match_MissingFeature;
4892 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
4898 if (
llvm::count(Match, Match_InvalidOperand) == 1) {
4899 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4903 if (
llvm::count(Match, Match_InvalidImmUnsignedi4) == 1) {
4904 SMLoc ErrorLoc = ((X86Operand &)*
Operands[ErrorInfo]).getStartLoc();
4905 if (ErrorLoc == SMLoc())
4907 return Error(ErrorLoc,
"immediate must be an integer in range [0, 15]",
4908 EmptyRange, MatchingInlineAsm);
4911 if (
llvm::count(Match, Match_InvalidImmUnsignedi6) == 1) {
4912 SMLoc ErrorLoc = ((X86Operand &)*
Operands[ErrorInfo]).getStartLoc();
4913 if (ErrorLoc == SMLoc())
4915 return Error(ErrorLoc,
"immediate must be an integer in range [0, 63]",
4916 EmptyRange, MatchingInlineAsm);
4920 return Error(IDLoc,
"unknown instruction mnemonic", EmptyRange,
4924bool X86AsmParser::omitRegisterFromClobberLists(MCRegister
Reg) {
4925 return getX86MCRegisterClass(X86::SEGMENT_REGRegClassID).contains(
Reg);
4928bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
4929 MCAsmParser &Parser = getParser();
4932 return parseDirectiveArch();
4934 return ParseDirectiveCode(IDVal, DirectiveID.
getLoc());
4940 return Error(DirectiveID.
getLoc(),
"'.att_syntax noprefix' is not "
4941 "supported: registers must have a "
4942 "'%' prefix in .att_syntax");
4944 getParser().setAssemblerDialect(0);
4947 getParser().setAssemblerDialect(1);
4952 return Error(DirectiveID.
getLoc(),
"'.intel_syntax prefix' is not "
4953 "supported: registers must not have "
4954 "a '%' prefix in .intel_syntax");
4957 }
else if (IDVal ==
".nops")
4958 return parseDirectiveNops(DirectiveID.
getLoc());
4959 else if (IDVal ==
".even")
4960 return parseDirectiveEven(DirectiveID.
getLoc());
4961 else if (IDVal ==
".cv_fpo_proc")
4962 return parseDirectiveFPOProc(DirectiveID.
getLoc());
4963 else if (IDVal ==
".cv_fpo_setframe")
4964 return parseDirectiveFPOSetFrame(DirectiveID.
getLoc());
4965 else if (IDVal ==
".cv_fpo_pushreg")
4966 return parseDirectiveFPOPushReg(DirectiveID.
getLoc());
4967 else if (IDVal ==
".cv_fpo_stackalloc")
4968 return parseDirectiveFPOStackAlloc(DirectiveID.
getLoc());
4969 else if (IDVal ==
".cv_fpo_stackalign")
4970 return parseDirectiveFPOStackAlign(DirectiveID.
getLoc());
4971 else if (IDVal ==
".cv_fpo_endprologue")
4972 return parseDirectiveFPOEndPrologue(DirectiveID.
getLoc());
4973 else if (IDVal ==
".cv_fpo_endproc")
4974 return parseDirectiveFPOEndProc(DirectiveID.
getLoc());
4975 else if (IDVal ==
".seh_pushreg")
4976 return parseDirectiveSEHPushReg(DirectiveID.
getLoc());
4977 else if (IDVal ==
".seh_push2regs")
4978 return parseDirectiveSEHPush2Regs(DirectiveID.
getLoc());
4979 else if (IDVal ==
".seh_setframe")
4980 return parseDirectiveSEHSetFrame(DirectiveID.
getLoc());
4981 else if (IDVal ==
".seh_savereg")
4982 return parseDirectiveSEHSaveReg(DirectiveID.
getLoc());
4983 else if (IDVal ==
".seh_savexmm")
4984 return parseDirectiveSEHSaveXMM(DirectiveID.
getLoc());
4985 else if (IDVal ==
".seh_pushframe")
4986 return parseDirectiveSEHPushFrame(DirectiveID.
getLoc());
4990 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
4991 parseDirectiveSEHPushReg(DirectiveID.
getLoc());
4993 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
4994 parseDirectiveSEHPush2Regs(DirectiveID.
getLoc());
4996 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
4997 parseDirectiveSEHSetFrame(DirectiveID.
getLoc());
4999 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
5000 parseDirectiveSEHSaveReg(DirectiveID.
getLoc());
5002 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
5003 parseDirectiveSEHSaveXMM(DirectiveID.
getLoc());
5005 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
5006 parseDirectiveSEHPushFrame(DirectiveID.
getLoc());
5010 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
5011 parseDirectiveSEHPushReg(DirectiveID.
getLoc());
5015 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
5016 parseDirectiveSEHPush2Regs(DirectiveID.
getLoc(),
5019 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
5020 parseDirectiveSEHSetFrame(DirectiveID.
getLoc());
5022 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
5023 parseDirectiveSEHSaveReg(DirectiveID.
getLoc());
5025 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
5026 parseDirectiveSEHSaveXMM(DirectiveID.
getLoc());
5033bool X86AsmParser::parseDirectiveArch() {
5035 getParser().parseStringToEndOfStatement();
5041bool X86AsmParser::parseDirectiveNops(SMLoc L) {
5042 int64_t NumBytes = 0, Control = 0;
5043 SMLoc NumBytesLoc, ControlLoc;
5044 const MCSubtargetInfo& STI = getSTI();
5045 NumBytesLoc = getTok().getLoc();
5046 if (getParser().checkForValidSection() ||
5047 getParser().parseAbsoluteExpression(NumBytes))
5051 ControlLoc = getTok().getLoc();
5052 if (getParser().parseAbsoluteExpression(Control))
5055 if (getParser().parseEOL())
5058 if (NumBytes <= 0) {
5059 Error(NumBytesLoc,
"'.nops' directive with non-positive size");
5064 Error(ControlLoc,
"'.nops' directive with negative NOP size");
5069 getParser().getStreamer().emitNops(NumBytes, Control, L, STI);
5076bool X86AsmParser::parseDirectiveEven(SMLoc L) {
5080 const MCSection *
Section = getStreamer().getCurrentSectionOnly();
5082 getStreamer().initSections(getSTI());
5083 Section = getStreamer().getCurrentSectionOnly();
5085 if (
getContext().getAsmInfo().useCodeAlign(*Section))
5086 getStreamer().emitCodeAlignment(
Align(2), getSTI(), 0);
5088 getStreamer().emitValueToAlignment(
Align(2), 0, 1, 0);
5094bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
5095 MCAsmParser &Parser = getParser();
5097 if (IDVal ==
".code16") {
5099 if (!is16BitMode()) {
5100 SwitchMode(X86::Is16Bit);
5101 getTargetStreamer().emitCode16();
5103 }
else if (IDVal ==
".code16gcc") {
5107 if (!is16BitMode()) {
5108 SwitchMode(X86::Is16Bit);
5109 getTargetStreamer().emitCode16();
5111 }
else if (IDVal ==
".code32") {
5113 if (!is32BitMode()) {
5114 SwitchMode(X86::Is32Bit);
5115 getTargetStreamer().emitCode32();
5117 }
else if (IDVal ==
".code64") {
5119 if (!is64BitMode()) {
5120 SwitchMode(X86::Is64Bit);
5121 getTargetStreamer().emitCode64();
5124 Error(L,
"unknown directive " + IDVal);
5132bool X86AsmParser::parseDirectiveFPOProc(SMLoc L) {
5133 MCAsmParser &Parser = getParser();
5137 return Parser.
TokError(
"expected symbol name");
5138 if (Parser.
parseIntToken(ParamsSize,
"expected parameter byte count"))
5141 return Parser.
TokError(
"parameters size out of range");
5145 return getTargetStreamer().emitFPOProc(ProcSym, ParamsSize, L);
5149bool X86AsmParser::parseDirectiveFPOSetFrame(SMLoc L) {
5152 if (parseRegister(
Reg, DummyLoc, DummyLoc) || parseEOL())
5154 return getTargetStreamer().emitFPOSetFrame(
Reg, L);
5158bool X86AsmParser::parseDirectiveFPOPushReg(SMLoc L) {
5161 if (parseRegister(
Reg, DummyLoc, DummyLoc) || parseEOL())
5163 return getTargetStreamer().emitFPOPushReg(
Reg, L);
5167bool X86AsmParser::parseDirectiveFPOStackAlloc(SMLoc L) {
5168 MCAsmParser &Parser = getParser();
5172 return getTargetStreamer().emitFPOStackAlloc(
Offset, L);
5176bool X86AsmParser::parseDirectiveFPOStackAlign(SMLoc L) {
5177 MCAsmParser &Parser = getParser();
5181 return getTargetStreamer().emitFPOStackAlign(
Offset, L);
5185bool X86AsmParser::parseDirectiveFPOEndPrologue(SMLoc L) {
5186 MCAsmParser &Parser = getParser();
5189 return getTargetStreamer().emitFPOEndPrologue(L);
5193bool X86AsmParser::parseDirectiveFPOEndProc(SMLoc L) {
5194 MCAsmParser &Parser = getParser();
5197 return getTargetStreamer().emitFPOEndProc(L);
5200bool X86AsmParser::parseSEHRegisterNumber(
unsigned RegClassID,
5201 MCRegister &RegNo) {
5202 SMLoc startLoc = getLexer().getLoc();
5203 const MCRegisterInfo *MRI =
getContext().getRegisterInfo();
5208 if (parseRegister(RegNo, startLoc, endLoc))
5211 if (!getX86MCRegisterClass(RegClassID).
contains(RegNo)) {
5212 return Error(startLoc,
5213 "register is not supported for use with this directive");
5219 if (getParser().parseAbsoluteExpression(EncodedReg))
5224 RegNo = MCRegister();
5225 for (
MCPhysReg Reg : getX86MCRegisterClass(RegClassID)) {
5232 return Error(startLoc,
5233 "incorrect register number for use with this directive");
5240bool X86AsmParser::parseDirectiveSEHPushReg(SMLoc Loc) {
5242 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5246 return TokError(
"expected end of directive");
5249 getStreamer().emitWinCFIPushReg(
Reg, Loc);
5253bool X86AsmParser::parseDirectiveSEHPush2Regs(SMLoc Loc,
bool SwapRegs) {
5255 if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg1))
5259 return TokError(
"expected comma between registers");
5263 if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg2))
5267 return TokError(
"expected end of directive");
5273 getStreamer().emitWinCFIPush2Regs(Reg1, Reg2, Loc);
5277bool X86AsmParser::parseDirectiveSEHSetFrame(SMLoc Loc) {
5280 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5283 return TokError(
"you must specify a stack pointer offset");
5286 if (getParser().parseAbsoluteExpression(
Off))
5290 return TokError(
"expected end of directive");
5293 getStreamer().emitWinCFISetFrame(
Reg,
Off, Loc);
5297bool X86AsmParser::parseDirectiveSEHSaveReg(SMLoc Loc) {
5300 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5303 return TokError(
"you must specify an offset on the stack");
5306 if (getParser().parseAbsoluteExpression(
Off))
5310 return TokError(
"expected end of directive");
5313 getStreamer().emitWinCFISaveReg(
Reg,
Off, Loc);
5317bool X86AsmParser::parseDirectiveSEHSaveXMM(SMLoc Loc) {
5320 if (parseSEHRegisterNumber(X86::VR128XRegClassID,
Reg))
5323 return TokError(
"you must specify an offset on the stack");
5326 if (getParser().parseAbsoluteExpression(
Off))
5330 return TokError(
"expected end of directive");
5333 getStreamer().emitWinCFISaveXMM(
Reg,
Off, Loc);
5337bool X86AsmParser::ensureMasmPrologContext(SMLoc Loc) {
5338 if (getStreamer().isWinCFIPrologEnded()) {
5339 return Error(Loc,
"prolog directive must be used inside a prolog");
5344bool X86AsmParser::ensureMasmEpilogContext(SMLoc Loc) {
5345 if (!getStreamer().isInEpilogCFI()) {
5346 return Error(Loc,
"epilog directive must be used inside an epilog");
5351bool X86AsmParser::parseDirectiveSEHPushFrame(SMLoc Loc) {
5355 SMLoc startLoc = getLexer().getLoc();
5357 if (!getParser().parseIdentifier(CodeID)) {
5358 if (CodeID !=
"code")
5359 return Error(startLoc,
"expected @code");
5362 }
else if (getParser().isParsingMasm() &&
5364 getTok().getString().equals_insensitive(
"code")) {
5370 return TokError(
"expected end of directive");
5373 getStreamer().emitWinCFIPushFrame(Code, Loc);
5383#define GET_MATCHER_IMPLEMENTATION
5384#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.
const AArch64MCOptions & getCLOpts(const MCTargetOptions &Options)
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
std::variant< std::monostate, Loc::Single, Loc::Multi, Loc::MMI, Loc::EntryValue > Variant
Alias for the std::variant specialization base class of DbgVariable.
@ CE
Windows NT (Windows on ARM)
@ X86
Windows x64, Windows Itanium (IA-64)
bool isX86_64NonExtLowByteReg(MCRegister Reg)
@ EVEX
EVEX - Specifies that this instruction use EVEX form which provides syntax support up to 32 512-bit r...
@ VEX
VEX - encoding using 0xC4/0xC5.
@ XOP
XOP - Opcode prefix used by XOP instructions.
@ ExplicitVEXPrefix
For instructions that use VEX encoding only when {vex}, {vex2} or {vex3} is present.
bool canUseApxExtendedReg(const MCInstrDesc &Desc)
bool isX86_64ExtendedReg(MCRegister Reg)
bool isApxExtendedReg(MCRegister Reg)
void emitInstruction(MCObjectStreamer &, const MCInst &Inst, const MCSubtargetInfo &STI)
bool optimizeShiftRotateWithImmediateOne(MCInst &MI)
bool optimizeInstFromVEX3ToVEX2(MCInst &MI, const MCInstrDesc &Desc)
NodeAddr< CodeNode * > Code
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
MCRegister getX86SubSuperRegister(MCRegister Reg, unsigned Size, bool High=false)
Target & getTheX86_32Target()
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
@ End
Run the machine verifier once, at the end of the pipeline.
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