53 "x86-experimental-lvi-inline-asm-hardening",
54 cl::desc(
"Harden inline assembly code that may be vulnerable to Load Value"
55 " Injection (LVI). This feature is experimental."),
cl::Hidden);
58 if (Scale != 1 && Scale != 2 && Scale != 4 && Scale != 8) {
59 ErrMsg =
"scale factor in address must be 1, 2, 4 or 8";
68#define GET_X86_SSE2AVX_TABLE
69#include "X86GenInstrMapping.inc"
71static const char OpPrecedence[] = {
97 ParseInstructionInfo *InstInfo;
99 unsigned ForcedDataPrefix = 0;
102 OpcodePrefix_Default,
111 OpcodePrefix ForcedOpcodePrefix = OpcodePrefix_Default;
114 DispEncoding_Default,
119 DispEncoding ForcedDispEncoding = DispEncoding_Default;
122 bool UseApxExtendedReg =
false;
124 bool ForcedNoFlag =
false;
127 SMLoc consumeToken() {
128 MCAsmParser &Parser = getParser();
138 X86TargetStreamer &getTargetStreamer() {
139 assert(getParser().getStreamer().getTargetStreamer() &&
140 "do not have a target streamer");
141 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
142 return static_cast<X86TargetStreamer &
>(TS);
146 uint64_t &ErrorInfo, FeatureBitset &MissingFeatures,
147 bool matchingInlineAsm,
unsigned VariantID = 0) {
150 SwitchMode(X86::Is32Bit);
151 unsigned rv = MatchInstructionImpl(
Operands, Inst, ErrorInfo,
152 MissingFeatures, matchingInlineAsm,
155 SwitchMode(X86::Is16Bit);
159 enum InfixCalculatorTok {
184 enum IntelOperatorKind {
191 enum MasmOperatorKind {
198 class InfixCalculator {
199 typedef std::pair< InfixCalculatorTok, int64_t > ICToken;
203 bool isUnaryOperator(InfixCalculatorTok
Op)
const {
204 return Op == IC_NEG ||
Op == IC_NOT;
208 int64_t popOperand() {
209 assert (!PostfixStack.empty() &&
"Poped an empty stack!");
210 ICToken
Op = PostfixStack.pop_back_val();
211 if (!(
Op.first == IC_IMM ||
Op.first == IC_REGISTER))
215 void pushOperand(InfixCalculatorTok
Op, int64_t Val = 0) {
216 assert ((
Op == IC_IMM ||
Op == IC_REGISTER) &&
217 "Unexpected operand!");
218 PostfixStack.push_back(std::make_pair(
Op, Val));
221 void popOperator() { InfixOperatorStack.pop_back(); }
222 void pushOperator(InfixCalculatorTok
Op) {
224 if (InfixOperatorStack.empty()) {
225 InfixOperatorStack.push_back(
Op);
232 unsigned Idx = InfixOperatorStack.size() - 1;
233 InfixCalculatorTok StackOp = InfixOperatorStack[Idx];
234 if (OpPrecedence[
Op] > OpPrecedence[StackOp] || StackOp == IC_LPAREN) {
235 InfixOperatorStack.push_back(
Op);
241 unsigned ParenCount = 0;
244 if (InfixOperatorStack.empty())
247 Idx = InfixOperatorStack.size() - 1;
248 StackOp = InfixOperatorStack[Idx];
249 if (!(OpPrecedence[StackOp] >= OpPrecedence[
Op] || ParenCount))
254 if (!ParenCount && StackOp == IC_LPAREN)
257 if (StackOp == IC_RPAREN) {
259 InfixOperatorStack.pop_back();
260 }
else if (StackOp == IC_LPAREN) {
262 InfixOperatorStack.pop_back();
264 InfixOperatorStack.pop_back();
265 PostfixStack.push_back(std::make_pair(StackOp, 0));
269 InfixOperatorStack.push_back(
Op);
274 while (!InfixOperatorStack.empty()) {
275 InfixCalculatorTok StackOp = InfixOperatorStack.pop_back_val();
276 if (StackOp != IC_LPAREN && StackOp != IC_RPAREN)
277 PostfixStack.push_back(std::make_pair(StackOp, 0));
280 if (PostfixStack.empty())
284 for (
const ICToken &
Op : PostfixStack) {
285 if (
Op.first == IC_IMM ||
Op.first == IC_REGISTER) {
287 }
else if (isUnaryOperator(
Op.first)) {
288 assert (OperandStack.
size() > 0 &&
"Too few operands.");
290 assert (Operand.first == IC_IMM &&
291 "Unary operation with a register!");
297 OperandStack.
push_back(std::make_pair(IC_IMM, -Operand.second));
300 OperandStack.
push_back(std::make_pair(IC_IMM, ~Operand.second));
304 assert (OperandStack.
size() > 1 &&
"Too few operands.");
313 Val = Op1.second + Op2.second;
314 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
317 Val = Op1.second - Op2.second;
318 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
321 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
322 "Multiply operation with an immediate and a register!");
323 Val = Op1.second * Op2.second;
324 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
327 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
328 "Divide operation with an immediate and a register!");
329 assert (Op2.second != 0 &&
"Division by zero!");
330 Val = Op1.second / Op2.second;
331 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
334 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
335 "Modulo operation with an immediate and a register!");
336 Val = Op1.second % Op2.second;
337 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
340 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
341 "Or operation with an immediate and a register!");
342 Val = Op1.second | Op2.second;
343 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
346 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
347 "Xor operation with an immediate and a register!");
348 Val = Op1.second ^ Op2.second;
349 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
352 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
353 "And operation with an immediate and a register!");
354 Val = Op1.second & Op2.second;
355 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
358 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
359 "Left shift operation with an immediate and a register!");
360 Val = Op1.second << Op2.second;
361 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
364 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
365 "Right shift operation with an immediate and a register!");
366 Val = Op1.second >> Op2.second;
367 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
370 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
371 "Equals operation with an immediate and a register!");
372 Val = (Op1.second == Op2.second) ? -1 : 0;
373 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
376 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
377 "Not-equals operation with an immediate and a register!");
378 Val = (Op1.second != Op2.second) ? -1 : 0;
379 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
382 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
383 "Less-than operation with an immediate and a register!");
384 Val = (Op1.second < Op2.second) ? -1 : 0;
385 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
388 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
389 "Less-than-or-equal operation with an immediate and a "
391 Val = (Op1.second <= Op2.second) ? -1 : 0;
392 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
395 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
396 "Greater-than operation with an immediate and a register!");
397 Val = (Op1.second > Op2.second) ? -1 : 0;
398 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
401 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
402 "Greater-than-or-equal operation with an immediate and a "
404 Val = (Op1.second >= Op2.second) ? -1 : 0;
405 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
410 assert (OperandStack.
size() == 1 &&
"Expected a single result.");
415 enum IntelExprState {
445 class IntelExprStateMachine {
446 IntelExprState State = IES_INIT, PrevState = IES_ERROR;
447 MCRegister BaseReg, IndexReg, TmpReg;
449 std::optional<unsigned> TmpScale = {};
451 const MCExpr *Sym =
nullptr;
454 InlineAsmIdentifierInfo Info;
456 short ParenCount = 0;
458 bool MemExpr =
false;
459 bool BracketUsed =
false;
460 bool NegativeAdditiveTerm =
false;
461 SMLoc NegativeAdditiveTermLoc;
462 bool OffsetOperator =
false;
463 bool AttachToOperandIdx =
false;
467 bool setSymRef(
const MCExpr *Val, StringRef ID, StringRef &ErrMsg) {
469 ErrMsg =
"cannot use more than one symbol in memory operand";
478 IntelExprStateMachine() =
default;
480 void addImm(int64_t imm) { Imm += imm; }
481 short getBracCount()
const {
return BracCount; }
482 bool isMemExpr()
const {
return MemExpr; }
483 bool isBracketUsed()
const {
return BracketUsed; }
484 bool isOffsetOperator()
const {
return OffsetOperator; }
485 MCRegister getBaseReg()
const {
return BaseReg; }
486 MCRegister getIndexReg()
const {
return IndexReg; }
487 unsigned getScale()
const {
return Scale; }
488 const MCExpr *
getSym()
const {
return Sym; }
489 StringRef getSymName()
const {
return SymName; }
490 StringRef
getType()
const {
return CurType.Name; }
491 unsigned getSize()
const {
return CurType.Size; }
492 unsigned getElementSize()
const {
return CurType.ElementSize; }
493 unsigned getLength()
const {
return CurType.Length; }
494 int64_t
getImm() {
return Imm + IC.execute(); }
495 bool isValidEndState()
const {
496 return State == IES_RBRAC || State == IES_RPAREN ||
497 State == IES_INTEGER || State == IES_REGISTER ||
500 bool hasUnmatchedParen()
const {
return ParenCount != 0; }
501 SMLoc getLParenLoc()
const {
return LParenLoc; }
507 void setAppendAfterOperand() { AttachToOperandIdx =
true; }
509 bool isPIC()
const {
return IsPIC; }
510 void setPIC() { IsPIC =
true; }
512 bool hadError()
const {
return State == IES_ERROR; }
513 SMLoc getErrorLoc(SMLoc DefaultLoc)
const {
514 return NegativeAdditiveTerm ? NegativeAdditiveTermLoc : DefaultLoc;
516 const InlineAsmIdentifierInfo &getIdentifierInfo()
const {
return Info; }
518 bool regsUseUpError(StringRef &ErrMsg) {
521 if (IsPIC && AttachToOperandIdx)
522 ErrMsg =
"Don't use 2 or more regs for mem offset in PIC model!";
524 ErrMsg =
"BaseReg/IndexReg already set!";
529 IntelExprState CurrState = State;
538 IC.pushOperator(IC_OR);
541 PrevState = CurrState;
544 IntelExprState CurrState = State;
553 IC.pushOperator(IC_XOR);
556 PrevState = CurrState;
559 IntelExprState CurrState = State;
568 IC.pushOperator(IC_AND);
571 PrevState = CurrState;
574 IntelExprState CurrState = State;
583 IC.pushOperator(IC_EQ);
586 PrevState = CurrState;
589 IntelExprState CurrState = State;
598 IC.pushOperator(IC_NE);
601 PrevState = CurrState;
604 IntelExprState CurrState = State;
613 IC.pushOperator(IC_LT);
616 PrevState = CurrState;
619 IntelExprState CurrState = State;
628 IC.pushOperator(IC_LE);
631 PrevState = CurrState;
634 IntelExprState CurrState = State;
643 IC.pushOperator(IC_GT);
646 PrevState = CurrState;
649 IntelExprState CurrState = State;
658 IC.pushOperator(IC_GE);
661 PrevState = CurrState;
664 IntelExprState CurrState = State;
673 IC.pushOperator(IC_LSHIFT);
676 PrevState = CurrState;
679 IntelExprState CurrState = State;
688 IC.pushOperator(IC_RSHIFT);
691 PrevState = CurrState;
693 bool onPlus(StringRef &ErrMsg) {
694 IntelExprState CurrState = State;
704 IC.pushOperator(IC_PLUS);
708 if (!BaseReg && !TmpScale.has_value()) {
713 return regsUseUpError(ErrMsg);
716 if (NegativeAdditiveTerm) {
717 ErrMsg =
"Scale can't be negative";
720 if (TmpScale.has_value() &&
checkScale(TmpScale.value(), ErrMsg)) {
723 Scale = TmpScale.value_or(0);
728 NegativeAdditiveTerm =
false;
729 NegativeAdditiveTermLoc = SMLoc();
732 PrevState = CurrState;
735 bool onMinus(SMLoc MinusLoc, StringRef &ErrMsg) {
736 IntelExprState CurrState = State;
766 NegativeAdditiveTerm =
true;
767 NegativeAdditiveTermLoc = MinusLoc;
769 if (CurrState == IES_REGISTER || CurrState == IES_RPAREN ||
770 CurrState == IES_INTEGER || CurrState == IES_RBRAC ||
771 CurrState == IES_OFFSET) {
772 IC.pushOperator(IC_MINUS);
776 if (!BaseReg && !TmpScale.has_value()) {
781 return regsUseUpError(ErrMsg);
784 if (TmpScale.has_value() &&
788 Scale = TmpScale.value_or(0);
791 }
else if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
793 ErrMsg =
"Scale can't be negative";
796 IC.pushOperator(IC_NEG);
801 PrevState = CurrState;
805 IntelExprState CurrState = State;
831 IC.pushOperator(IC_NOT);
834 PrevState = CurrState;
836 bool onRegister(MCRegister
Reg, StringRef &ErrMsg) {
837 IntelExprState CurrState = State;
845 State = IES_REGISTER;
847 IC.pushOperand(IC_REGISTER);
848 if (NegativeAdditiveTerm) {
849 ErrMsg =
"Scale can't be negative";
857 ErrMsg =
"Register can't be multiplied with register!";
860 State = IES_REGISTER;
865 if (TmpScale.has_value()) {
867 return regsUseUpError(ErrMsg);
868 if (NegativeAdditiveTerm) {
869 ErrMsg =
"Scale can't be negative";
874 IC.pushOperand(IC_IMM);
876 IC.pushOperand(IC_REGISTER);
880 PrevState = CurrState;
883 bool onIdentifierExpr(
const MCExpr *SymRef, StringRef SymRefName,
884 const InlineAsmIdentifierInfo &IDInfo,
885 const AsmTypeInfo &
Type,
bool ParsingMSInlineAsm,
888 if (ParsingMSInlineAsm)
893 return onInteger(
CE->getValue(), ErrMsg);
906 if (setSymRef(SymRef, SymRefName, ErrMsg))
912 IC.pushOperand(IC_IMM);
913 if (ParsingMSInlineAsm)
920 bool onInteger(int64_t TmpInt, StringRef &ErrMsg) {
921 IntelExprState CurrState = State;
928 ErrMsg =
"division by zero in assembly expression";
935 ErrMsg =
"modulo by zero in assembly expression";
960 if (TmpScale.has_value()) {
961 TmpScale.value() *= TmpInt;
966 if (TmpReg && NegativeAdditiveTerm) {
967 ErrMsg =
"Scale can't be negative";
970 if (TmpReg &&
checkScale(TmpScale.value(), ErrMsg))
972 IC.pushOperand(IC_IMM, TmpInt);
975 PrevState = CurrState;
985 State = IES_MULTIPLY;
986 IC.pushOperator(IC_MULTIPLY);
993 if (TmpReg && (!TmpScale.has_value())) {
995 IC.pushOperand(IC_IMM);
997 State = IES_MULTIPLY;
998 IC.pushOperator(IC_MULTIPLY);
1011 IC.pushOperator(IC_DIVIDE);
1024 IC.pushOperator(IC_MOD);
1040 IC.pushOperator(IC_PLUS);
1042 CurType.Size = CurType.ElementSize;
1046 assert(!BracCount &&
"BracCount should be zero on parsing's start");
1050 NegativeAdditiveTerm =
false;
1051 NegativeAdditiveTermLoc = SMLoc();
1059 bool onRBrac(StringRef &ErrMsg) {
1060 IntelExprState CurrState = State;
1069 if (BracCount-- != 1) {
1070 ErrMsg =
"unexpected bracket encountered";
1078 if (!BaseReg && !TmpScale.has_value()) {
1081 }
else if (!IndexReg) {
1082 if (NegativeAdditiveTerm) {
1083 ErrMsg =
"Scale can't be negative";
1088 if (TmpScale.has_value() &&
checkScale(TmpScale.value(), ErrMsg)) {
1091 Scale = TmpScale.value_or(0);
1093 return regsUseUpError(ErrMsg);
1096 NegativeAdditiveTerm =
false;
1097 NegativeAdditiveTermLoc = SMLoc();
1102 PrevState = CurrState;
1105 void onLParen(SMLoc Loc) {
1106 IntelExprState CurrState = State;
1134 IC.pushOperator(IC_LPAREN);
1137 PrevState = CurrState;
1139 bool onRParen(StringRef &ErrMsg) {
1140 IntelExprState CurrState = State;
1150 if (ParenCount == 0) {
1151 ErrMsg =
"unmatched parenthesis";
1156 IC.pushOperator(IC_RPAREN);
1159 PrevState = CurrState;
1162 bool onOffset(
const MCExpr *Val, StringRef ID,
1163 const InlineAsmIdentifierInfo &IDInfo,
1164 bool ParsingMSInlineAsm, StringRef &ErrMsg) {
1168 ErrMsg =
"unexpected offset operator expression";
1173 if (setSymRef(Val, ID, ErrMsg))
1175 OffsetOperator =
true;
1179 IC.pushOperand(IC_IMM);
1180 if (ParsingMSInlineAsm) {
1190 bool onImagerel(
const MCExpr *Val, StringRef ID, StringRef &ErrMsg) {
1196 if (setSymRef(Val, ID, ErrMsg))
1199 IC.pushOperand(IC_IMM);
1202 ErrMsg =
"unexpected imagerel operator expression";
1206 void onCast(AsmTypeInfo Info) {
1218 void setTypeInfo(AsmTypeInfo
Type) { CurType =
Type; }
1222 bool MatchingInlineAsm =
false) {
1223 MCAsmParser &Parser = getParser();
1224 if (MatchingInlineAsm) {
1230 bool MatchRegisterByName(MCRegister &RegNo, StringRef
RegName, SMLoc StartLoc,
1232 bool ParseRegister(MCRegister &RegNo, SMLoc &StartLoc, SMLoc &EndLoc,
1233 bool RestoreOnFailure);
1235 std::unique_ptr<X86Operand> DefaultMemSIOperand(SMLoc Loc);
1236 std::unique_ptr<X86Operand> DefaultMemDIOperand(SMLoc Loc);
1237 bool IsSIReg(MCRegister
Reg);
1238 MCRegister GetSIDIForRegClass(
unsigned RegClassID,
bool IsSIReg);
1241 std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
1242 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst);
1248 bool ParseIntelOffsetOperator(
const MCExpr *&Val, StringRef &ID,
1249 InlineAsmIdentifierInfo &Info, SMLoc &End);
1250 bool ParseIntelImagerelOperator(
const MCExpr *&Val, StringRef &ID,
1251 InlineAsmIdentifierInfo &Info, SMLoc &End);
1252 bool ParseIntelDotOperator(IntelExprStateMachine &SM, SMLoc &End);
1253 unsigned IdentifyIntelInlineAsmOperator(StringRef Name);
1254 unsigned ParseIntelInlineAsmOperator(
unsigned OpKind);
1255 unsigned IdentifyMasmOperator(StringRef Name);
1256 bool ParseMasmOperator(
unsigned OpKind, int64_t &Val);
1259 bool ParseIntelNamedOperator(StringRef Name, IntelExprStateMachine &SM,
1260 bool &ParseError, SMLoc &End);
1261 bool ParseMasmNamedOperator(StringRef Name, IntelExprStateMachine &SM,
1262 bool &ParseError, SMLoc &End);
1263 void RewriteIntelExpression(IntelExprStateMachine &SM, SMLoc Start,
1265 bool ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End);
1266 bool ParseIntelInlineAsmIdentifier(
const MCExpr *&Val, StringRef &Identifier,
1267 InlineAsmIdentifierInfo &Info,
1268 bool IsUnevaluatedOperand, SMLoc &End,
1269 bool IsParsingOffsetOperator =
false);
1271 IntelExprStateMachine &SM);
1273 bool CheckDispOverflow(MCRegister BaseReg, MCRegister IndexReg,
1274 const MCExpr *Disp, SMLoc Loc);
1276 bool ParseMemOperand(MCRegister SegReg,
const MCExpr *Disp, SMLoc StartLoc,
1281 bool ParseIntelMemoryOperandSize(
unsigned &
Size, StringRef *SizeStr);
1282 bool CreateMemForMSInlineAsm(MCRegister SegReg,
const MCExpr *Disp,
1283 MCRegister BaseReg, MCRegister IndexReg,
1284 unsigned Scale,
bool NonAbsMem, SMLoc Start,
1285 SMLoc End,
unsigned Size, StringRef Identifier,
1286 const InlineAsmIdentifierInfo &Info,
1289 bool parseDirectiveArch();
1290 bool parseDirectiveNops(SMLoc L);
1291 bool parseDirectiveEven(SMLoc L);
1292 bool ParseDirectiveCode(StringRef IDVal, SMLoc L);
1295 bool parseDirectiveFPOProc(SMLoc L);
1296 bool parseDirectiveFPOSetFrame(SMLoc L);
1297 bool parseDirectiveFPOPushReg(SMLoc L);
1298 bool parseDirectiveFPOStackAlloc(SMLoc L);
1299 bool parseDirectiveFPOStackAlign(SMLoc L);
1300 bool parseDirectiveFPOEndPrologue(SMLoc L);
1301 bool parseDirectiveFPOEndProc(SMLoc L);
1304 bool parseSEHRegisterNumber(
unsigned RegClassID, MCRegister &RegNo);
1305 bool parseDirectiveSEHPushReg(SMLoc);
1306 bool parseDirectiveSEHPush2Regs(SMLoc,
bool SwapRegs =
false);
1307 bool parseDirectiveSEHSetFrame(SMLoc);
1308 bool parseDirectiveSEHSaveReg(SMLoc);
1309 bool parseDirectiveSEHSaveXMM(SMLoc);
1310 bool parseDirectiveSEHPushFrame(SMLoc);
1312 bool ensureMasmEpilogContext(SMLoc Loc);
1313 bool ensureMasmPrologContext(SMLoc Loc);
1315 unsigned checkTargetMatchPredicate(MCInst &Inst)
override;
1321 void emitWarningForSpecialLVIInstruction(SMLoc Loc);
1322 void applyLVICFIMitigation(MCInst &Inst, MCStreamer &Out);
1323 void applyLVILoadHardeningMitigation(MCInst &Inst, MCStreamer &Out);
1329 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1332 bool MatchingInlineAsm)
override;
1335 MCStreamer &Out,
bool MatchingInlineAsm);
1337 bool ErrorMissingFeature(SMLoc IDLoc,
const FeatureBitset &MissingFeatures,
1338 bool MatchingInlineAsm);
1340 bool matchAndEmitATTInstruction(SMLoc IDLoc,
unsigned &Opcode, MCInst &Inst,
1342 uint64_t &ErrorInfo,
bool MatchingInlineAsm);
1344 bool matchAndEmitIntelInstruction(SMLoc IDLoc,
unsigned &Opcode, MCInst &Inst,
1347 bool MatchingInlineAsm);
1349 bool omitRegisterFromClobberLists(MCRegister
Reg)
override;
1356 bool ParseZ(std::unique_ptr<X86Operand> &Z, SMLoc StartLoc);
1358 bool is64BitMode()
const {
1360 return getSTI().hasFeature(X86::Is64Bit);
1362 bool is32BitMode()
const {
1364 return getSTI().hasFeature(X86::Is32Bit);
1366 bool is16BitMode()
const {
1368 return getSTI().hasFeature(X86::Is16Bit);
1370 void SwitchMode(
unsigned mode) {
1371 MCSubtargetInfo &STI = copySTI();
1372 FeatureBitset AllModes({X86::Is64Bit, X86::Is32Bit, X86::Is16Bit});
1374 FeatureBitset FB = ComputeAvailableFeatures(
1376 setAvailableFeatures(FB);
1381 unsigned getPointerWidth() {
1382 if (is16BitMode())
return 16;
1383 if (is32BitMode())
return 32;
1384 if (is64BitMode())
return 64;
1388 bool isParsingIntelSyntax() {
1389 return getParser().getAssemblerDialect();
1395#define GET_ASSEMBLER_HEADER
1396#include "X86GenAsmMatcher.inc"
1401 enum X86MatchResultTy {
1402 Match_Unsupported = FIRST_TARGET_MATCH_RESULT_TY,
1403#define GET_OPERAND_DIAGNOSTIC_TYPES
1404#include "X86GenAsmMatcher.inc"
1407 X86AsmParser(
const MCSubtargetInfo &sti, MCAsmParser &Parser,
1408 const MCInstrInfo &mii)
1409 : MCTargetAsmParser(sti, mii), InstInfo(nullptr), Code16GCC(
false) {
1414 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
1417 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
1418 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1419 SMLoc &EndLoc)
override;
1421 bool parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc)
override;
1423 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
1426 bool ParseDirective(AsmToken DirectiveID)
override;
1430#define GET_REGISTER_MATCHER
1431#define GET_SUBTARGET_FEATURE_NAME
1432#include "X86GenAsmMatcher.inc"
1443 !(BaseReg == X86::RIP || BaseReg == X86::EIP ||
1444 getX86MCRegisterClass(X86::GR16RegClassID).
contains(BaseReg) ||
1445 getX86MCRegisterClass(X86::GR32RegClassID).
contains(BaseReg) ||
1446 getX86MCRegisterClass(X86::GR64RegClassID).
contains(BaseReg))) {
1447 ErrMsg =
"invalid base+index expression";
1452 !(IndexReg == X86::EIZ || IndexReg == X86::RIZ ||
1453 getX86MCRegisterClass(X86::GR16RegClassID).
contains(IndexReg) ||
1454 getX86MCRegisterClass(X86::GR32RegClassID).
contains(IndexReg) ||
1455 getX86MCRegisterClass(X86::GR64RegClassID).
contains(IndexReg) ||
1456 getX86MCRegisterClass(X86::VR128XRegClassID).
contains(IndexReg) ||
1457 getX86MCRegisterClass(X86::VR256XRegClassID).
contains(IndexReg) ||
1458 getX86MCRegisterClass(X86::VR512RegClassID).
contains(IndexReg))) {
1459 ErrMsg =
"invalid base+index expression";
1463 if (((BaseReg == X86::RIP || BaseReg == X86::EIP) && IndexReg) ||
1464 IndexReg == X86::EIP || IndexReg == X86::RIP || IndexReg == X86::ESP ||
1465 IndexReg == X86::RSP) {
1466 ErrMsg =
"invalid base+index expression";
1472 if (getX86MCRegisterClass(X86::GR16RegClassID).
contains(BaseReg) &&
1473 (Is64BitMode || (BaseReg != X86::BX && BaseReg != X86::BP &&
1474 BaseReg != X86::SI && BaseReg != X86::DI))) {
1475 ErrMsg =
"invalid 16-bit base register";
1480 getX86MCRegisterClass(X86::GR16RegClassID).
contains(IndexReg)) {
1481 ErrMsg =
"16-bit memory operand may not include only index register";
1485 if (BaseReg && IndexReg) {
1486 if (getX86MCRegisterClass(X86::GR64RegClassID).
contains(BaseReg) &&
1487 (getX86MCRegisterClass(X86::GR16RegClassID).
contains(IndexReg) ||
1488 getX86MCRegisterClass(X86::GR32RegClassID).
contains(IndexReg) ||
1489 IndexReg == X86::EIZ)) {
1490 ErrMsg =
"base register is 64-bit, but index register is not";
1493 if (getX86MCRegisterClass(X86::GR32RegClassID).
contains(BaseReg) &&
1494 (getX86MCRegisterClass(X86::GR16RegClassID).
contains(IndexReg) ||
1495 getX86MCRegisterClass(X86::GR64RegClassID).
contains(IndexReg) ||
1496 IndexReg == X86::RIZ)) {
1497 ErrMsg =
"base register is 32-bit, but index register is not";
1500 if (getX86MCRegisterClass(X86::GR16RegClassID).
contains(BaseReg)) {
1501 if (getX86MCRegisterClass(X86::GR32RegClassID).
contains(IndexReg) ||
1502 getX86MCRegisterClass(X86::GR64RegClassID).
contains(IndexReg)) {
1503 ErrMsg =
"base register is 16-bit, but index register is not";
1506 if ((BaseReg != X86::BX && BaseReg != X86::BP) ||
1507 (IndexReg != X86::SI && IndexReg != X86::DI)) {
1508 ErrMsg =
"invalid 16-bit base/index register combination";
1515 if (!Is64BitMode && (BaseReg == X86::RIP || BaseReg == X86::EIP)) {
1516 ErrMsg =
"IP-relative addressing requires 64-bit mode";
1537 if (isParsingMSInlineAsm() && isParsingIntelSyntax() &&
1538 (RegNo == X86::EFLAGS || RegNo == X86::MXCSR))
1539 RegNo = MCRegister();
1541 if (!is64BitMode()) {
1545 if (RegNo == X86::RIZ || RegNo == X86::RIP ||
1546 getX86MCRegisterClass(X86::GR64RegClassID).
contains(RegNo) ||
1549 return Error(StartLoc,
1550 "register %" +
RegName +
" is only available in 64-bit mode",
1551 SMRange(StartLoc, EndLoc));
1556 UseApxExtendedReg =
true;
1560 if (!RegNo &&
RegName.starts_with(
"db")) {
1619 if (isParsingIntelSyntax())
1621 return Error(StartLoc,
"invalid register name", SMRange(StartLoc, EndLoc));
1626bool X86AsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
1627 SMLoc &EndLoc,
bool RestoreOnFailure) {
1628 MCAsmParser &Parser = getParser();
1629 AsmLexer &Lexer = getLexer();
1630 RegNo = MCRegister();
1633 auto OnFailure = [RestoreOnFailure, &Lexer, &Tokens]() {
1634 if (RestoreOnFailure) {
1635 while (!Tokens.
empty()) {
1641 const AsmToken &PercentTok = Parser.
getTok();
1642 StartLoc = PercentTok.
getLoc();
1651 const AsmToken &Tok = Parser.
getTok();
1656 if (isParsingIntelSyntax())
return true;
1657 return Error(StartLoc,
"invalid register name",
1658 SMRange(StartLoc, EndLoc));
1661 if (MatchRegisterByName(RegNo, Tok.
getString(), StartLoc, EndLoc)) {
1667 if (RegNo == X86::ST0) {
1678 const AsmToken &IntTok = Parser.
getTok();
1681 return Error(IntTok.
getLoc(),
"expected stack index");
1684 case 0: RegNo = X86::ST0;
break;
1685 case 1: RegNo = X86::ST1;
break;
1686 case 2: RegNo = X86::ST2;
break;
1687 case 3: RegNo = X86::ST3;
break;
1688 case 4: RegNo = X86::ST4;
break;
1689 case 5: RegNo = X86::ST5;
break;
1690 case 6: RegNo = X86::ST6;
break;
1691 case 7: RegNo = X86::ST7;
break;
1694 return Error(IntTok.
getLoc(),
"invalid stack index");
1714 if (isParsingIntelSyntax())
return true;
1715 return Error(StartLoc,
"invalid register name",
1716 SMRange(StartLoc, EndLoc));
1723bool X86AsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1725 return ParseRegister(
Reg, StartLoc, EndLoc,
false);
1728ParseStatus X86AsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1730 bool Result = ParseRegister(
Reg, StartLoc, EndLoc,
true);
1731 bool PendingErrors = getParser().hasPendingError();
1732 getParser().clearPendingErrors();
1740std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(SMLoc Loc) {
1741 bool Parse32 = is32BitMode() || Code16GCC;
1742 MCRegister Basereg =
1743 is64BitMode() ? X86::RSI : (Parse32 ? X86::ESI : X86::SI);
1750std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand(SMLoc Loc) {
1751 bool Parse32 = is32BitMode() || Code16GCC;
1752 MCRegister Basereg =
1753 is64BitMode() ? X86::RDI : (Parse32 ? X86::EDI : X86::DI);
1760bool X86AsmParser::IsSIReg(MCRegister
Reg) {
1774MCRegister X86AsmParser::GetSIDIForRegClass(
unsigned RegClassID,
bool IsSIReg) {
1775 switch (RegClassID) {
1777 case X86::GR64RegClassID:
1778 return IsSIReg ? X86::RSI : X86::RDI;
1779 case X86::GR32RegClassID:
1780 return IsSIReg ? X86::ESI : X86::EDI;
1781 case X86::GR16RegClassID:
1782 return IsSIReg ? X86::SI : X86::DI;
1786void X86AsmParser::AddDefaultSrcDestOperands(
1788 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst) {
1789 if (isParsingIntelSyntax()) {
1790 Operands.push_back(std::move(Dst));
1791 Operands.push_back(std::move(Src));
1794 Operands.push_back(std::move(Src));
1795 Operands.push_back(std::move(Dst));
1799bool X86AsmParser::VerifyAndAdjustOperands(
OperandVector &OrigOperands,
1802 if (OrigOperands.
size() > 1) {
1805 "Operand size mismatch");
1809 int RegClassID = -1;
1810 for (
unsigned int i = 0; i < FinalOperands.
size(); ++i) {
1811 X86Operand &OrigOp =
static_cast<X86Operand &
>(*OrigOperands[i + 1]);
1812 X86Operand &FinalOp =
static_cast<X86Operand &
>(*FinalOperands[i]);
1814 if (FinalOp.
isReg() &&
1819 if (FinalOp.
isMem()) {
1821 if (!OrigOp.
isMem())
1830 if (RegClassID != -1 &&
1831 !getX86MCRegisterClass(RegClassID).
contains(OrigReg)) {
1833 "mismatching source and destination index registers");
1836 if (getX86MCRegisterClass(X86::GR64RegClassID).
contains(OrigReg))
1837 RegClassID = X86::GR64RegClassID;
1838 else if (getX86MCRegisterClass(X86::GR32RegClassID).
contains(OrigReg))
1839 RegClassID = X86::GR32RegClassID;
1840 else if (getX86MCRegisterClass(X86::GR16RegClassID).
contains(OrigReg))
1841 RegClassID = X86::GR16RegClassID;
1847 bool IsSI = IsSIReg(FinalReg);
1848 FinalReg = GetSIDIForRegClass(RegClassID, IsSI);
1850 if (FinalReg != OrigReg) {
1851 std::string
RegName = IsSI ?
"ES:(R|E)SI" :
"ES:(R|E)DI";
1854 "memory operand is only for determining the size, " +
RegName +
1855 " will be used for the location"));
1866 for (
auto &WarningMsg : Warnings) {
1867 Warning(WarningMsg.first, WarningMsg.second);
1871 for (
unsigned int i = 0; i < FinalOperands.
size(); ++i)
1875 for (
auto &
Op : FinalOperands)
1882 if (isParsingIntelSyntax())
1883 return parseIntelOperand(
Operands, Name);
1888bool X86AsmParser::CreateMemForMSInlineAsm(
1889 MCRegister SegReg,
const MCExpr *Disp, MCRegister BaseReg,
1890 MCRegister IndexReg,
unsigned Scale,
bool NonAbsMem, SMLoc Start, SMLoc End,
1891 unsigned Size, StringRef Identifier,
const InlineAsmIdentifierInfo &Info,
1899 End,
Size, Identifier,
1906 unsigned FrontendSize = 0;
1907 void *Decl =
nullptr;
1908 bool IsGlobalLV =
false;
1911 FrontendSize =
Info.Var.Type * 8;
1912 Decl =
Info.Var.Decl;
1913 IsGlobalLV =
Info.Var.IsGlobalLV;
1918 if (BaseReg || IndexReg) {
1920 End,
Size, Identifier, Decl, 0,
1921 BaseReg && IndexReg));
1928 getPointerWidth(), SegReg, Disp, BaseReg, IndexReg, Scale, Start, End,
1930 X86::RIP, Identifier, Decl, FrontendSize));
1937bool X86AsmParser::ParseIntelNamedOperator(StringRef Name,
1938 IntelExprStateMachine &SM,
1939 bool &ParseError, SMLoc &End) {
1942 if (Name !=
Name.lower() && Name !=
Name.upper() &&
1943 !getParser().isParsingMasm())
1947 bool AlreadyConsumed =
false;
1948 if (
Name.equals_insensitive(
"not")) {
1950 }
else if (
Name.equals_insensitive(
"or")) {
1952 }
else if (
Name.equals_insensitive(
"shl")) {
1954 }
else if (
Name.equals_insensitive(
"shr")) {
1956 }
else if (
Name.equals_insensitive(
"xor")) {
1958 }
else if (
Name.equals_insensitive(
"and")) {
1960 }
else if (
Name.equals_insensitive(
"mod")) {
1962 }
else if (
Name.equals_insensitive(
"offset")) {
1963 const MCExpr *Val =
nullptr;
1965 InlineAsmIdentifierInfo
Info;
1966 ParseError = ParseIntelOffsetOperator(Val, ID, Info, End);
1970 ParseError = SM.onOffset(Val, ID, Info, isParsingMSInlineAsm(), ErrMsg);
1973 AlreadyConsumed =
true;
1974 }
else if (
Name.equals_insensitive(
"imagerel")) {
1977 InlineAsmIdentifierInfo
Info;
1978 ParseError = ParseIntelImagerelOperator(Val, ID, Info, End);
1985 AlreadyConsumed =
true;
1989 if (!AlreadyConsumed)
1990 End = consumeToken();
1993bool X86AsmParser::ParseMasmNamedOperator(StringRef Name,
1994 IntelExprStateMachine &SM,
1995 bool &ParseError, SMLoc &End) {
1996 if (
Name.equals_insensitive(
"eq")) {
1998 }
else if (
Name.equals_insensitive(
"ne")) {
2000 }
else if (
Name.equals_insensitive(
"lt")) {
2002 }
else if (
Name.equals_insensitive(
"le")) {
2004 }
else if (
Name.equals_insensitive(
"gt")) {
2006 }
else if (
Name.equals_insensitive(
"ge")) {
2011 End = consumeToken();
2018 IntelExprStateMachine &SM) {
2022 SM.setAppendAfterOperand();
2025bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
2026 MCAsmParser &Parser = getParser();
2031 if (
getContext().getObjectFileInfo()->isPositionIndependent())
2038 const AsmToken &Tok = Parser.
getTok();
2040 bool UpdateLocLex =
true;
2045 if ((
Done = SM.isValidEndState()))
2047 return Error(Tok.
getLoc(),
"unknown token in expression");
2049 return Error(getLexer().getErrLoc(), getLexer().getErr());
2053 UpdateLocLex =
false;
2054 if (ParseIntelDotOperator(SM, End))
2059 if ((
Done = SM.isValidEndState()))
2061 return Error(Tok.
getLoc(),
"unknown token in expression");
2065 UpdateLocLex =
false;
2066 if (ParseIntelDotOperator(SM, End))
2071 if ((
Done = SM.isValidEndState()))
2073 return Error(Tok.
getLoc(),
"unknown token in expression");
2079 SMLoc ValueLoc = Tok.
getLoc();
2084 UpdateLocLex =
false;
2085 if (!Val->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
2086 return Error(ValueLoc,
"expected absolute value");
2087 if (SM.onInteger(Res, ErrMsg))
2088 return Error(SM.getErrorLoc(ValueLoc), ErrMsg);
2095 SMLoc IdentLoc = Tok.
getLoc();
2097 UpdateLocLex =
false;
2099 size_t DotOffset =
Identifier.find_first_of(
'.');
2103 StringRef Dot =
Identifier.substr(DotOffset, 1);
2117 const AsmToken &NextTok = getLexer().peekTok();
2126 End = consumeToken();
2133 if (!ParseRegister(
Reg, IdentLoc, End,
true)) {
2134 if (SM.onRegister(
Reg, ErrMsg))
2135 return Error(SM.getErrorLoc(IdentLoc), ErrMsg);
2139 const std::pair<StringRef, StringRef> IDField =
2141 const StringRef
ID = IDField.first,
Field = IDField.second;
2143 if (!
Field.empty() &&
2144 !MatchRegisterByName(
Reg, ID, IdentLoc, IDEndLoc)) {
2145 if (SM.onRegister(
Reg, ErrMsg))
2146 return Error(SM.getErrorLoc(IdentLoc), ErrMsg);
2151 return Error(FieldStartLoc,
"unknown offset");
2152 else if (SM.onPlus(ErrMsg))
2153 return Error(getTok().getLoc(), ErrMsg);
2154 else if (SM.onInteger(
Info.Offset, ErrMsg))
2155 return Error(SM.getErrorLoc(IdentLoc), ErrMsg);
2156 SM.setTypeInfo(
Info.Type);
2158 End = consumeToken();
2165 if (ParseIntelNamedOperator(Identifier, SM, ParseError, End)) {
2171 ParseMasmNamedOperator(Identifier, SM, ParseError, End)) {
2177 InlineAsmIdentifierInfo
Info;
2178 AsmFieldInfo FieldInfo;
2184 if (ParseIntelDotOperator(SM, End))
2189 if (isParsingMSInlineAsm()) {
2191 if (
unsigned OpKind = IdentifyIntelInlineAsmOperator(Identifier)) {
2192 if (int64_t Val = ParseIntelInlineAsmOperator(OpKind)) {
2193 if (SM.onInteger(Val, ErrMsg))
2194 return Error(SM.getErrorLoc(IdentLoc), ErrMsg);
2203 return Error(IdentLoc,
"expected identifier");
2204 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
false, End))
2206 else if (SM.onIdentifierExpr(Val, Identifier, Info, FieldInfo.
Type,
2208 return Error(SM.getErrorLoc(IdentLoc), ErrMsg);
2212 if (
unsigned OpKind = IdentifyMasmOperator(Identifier)) {
2214 if (ParseMasmOperator(OpKind, Val))
2216 if (SM.onInteger(Val, ErrMsg))
2217 return Error(SM.getErrorLoc(IdentLoc), ErrMsg);
2220 if (!getParser().lookUpType(Identifier, FieldInfo.
Type)) {
2226 getParser().parseIdentifier(Identifier);
2230 if (getParser().lookUpField(FieldInfo.
Type.
Name, Identifier,
2234 return Error(IdentLoc,
"Unable to lookup field reference!",
2235 SMRange(IdentLoc, IDEnd));
2240 if (SM.onInteger(FieldInfo.
Offset, ErrMsg))
2241 return Error(SM.getErrorLoc(IdentLoc), ErrMsg);
2245 if (getParser().parsePrimaryExpr(Val, End, &FieldInfo.
Type)) {
2246 return Error(Tok.
getLoc(),
"Unexpected identifier!");
2247 }
else if (SM.onIdentifierExpr(Val, Identifier, Info, FieldInfo.
Type,
2249 return Error(SM.getErrorLoc(IdentLoc), ErrMsg);
2255 SMLoc Loc = getTok().getLoc();
2256 int64_t
IntVal = getTok().getIntVal();
2257 End = consumeToken();
2258 UpdateLocLex =
false;
2260 StringRef IDVal = getTok().getString();
2261 if (IDVal ==
"f" || IDVal ==
"b") {
2263 getContext().getDirectionalLocalSymbol(IntVal, IDVal ==
"b");
2268 return Error(Loc,
"invalid reference to undefined symbol");
2270 InlineAsmIdentifierInfo
Info;
2272 if (SM.onIdentifierExpr(Val, Identifier, Info,
Type,
2273 isParsingMSInlineAsm(), ErrMsg))
2274 return Error(SM.getErrorLoc(Loc), ErrMsg);
2275 End = consumeToken();
2277 if (SM.onInteger(IntVal, ErrMsg))
2278 return Error(SM.getErrorLoc(Loc), ErrMsg);
2281 if (SM.onInteger(IntVal, ErrMsg))
2282 return Error(SM.getErrorLoc(Loc), ErrMsg);
2287 if (SM.onPlus(ErrMsg))
2288 return Error(getTok().getLoc(), ErrMsg);
2291 if (SM.onMinus(getTok().getLoc(), ErrMsg))
2292 return Error(SM.getErrorLoc(getTok().getLoc()), ErrMsg);
2302 SM.onLShift();
break;
2304 SM.onRShift();
break;
2307 return Error(Tok.
getLoc(),
"unexpected bracket encountered");
2308 tryParseOperandIdx(PrevTK, SM);
2311 if (SM.onRBrac(ErrMsg)) {
2312 return Error(SM.getErrorLoc(Tok.
getLoc()), ErrMsg);
2316 SM.onLParen(Tok.
getLoc());
2319 if (SM.onRParen(ErrMsg)) {
2320 return Error(SM.getErrorLoc(Tok.
getLoc()), ErrMsg);
2325 return Error(Tok.
getLoc(),
"unknown token in expression");
2327 if (!
Done && UpdateLocLex)
2328 End = consumeToken();
2332 if (SM.hasUnmatchedParen())
2333 return Error(SM.getLParenLoc(),
"unmatched parenthesis");
2337void X86AsmParser::RewriteIntelExpression(IntelExprStateMachine &SM,
2338 SMLoc Start, SMLoc End) {
2342 if (SM.getSym() && !SM.isOffsetOperator()) {
2343 StringRef SymName = SM.getSymName();
2344 if (
unsigned Len = SymName.
data() -
Start.getPointer())
2350 if (!(SM.getBaseReg() || SM.getIndexReg() || SM.getImm())) {
2357 StringRef BaseRegStr;
2358 StringRef IndexRegStr;
2359 StringRef OffsetNameStr;
2360 if (SM.getBaseReg())
2362 if (SM.getIndexReg())
2364 if (SM.isOffsetOperator())
2365 OffsetNameStr = SM.getSymName();
2367 IntelExpr Expr(BaseRegStr, IndexRegStr, SM.getScale(), OffsetNameStr,
2368 SM.getImm(), SM.isMemExpr());
2369 InstInfo->
AsmRewrites->emplace_back(Loc, ExprLen, Expr);
2373bool X86AsmParser::ParseIntelInlineAsmIdentifier(
2374 const MCExpr *&Val, StringRef &Identifier, InlineAsmIdentifierInfo &Info,
2375 bool IsUnevaluatedOperand, SMLoc &End,
bool IsParsingOffsetOperator) {
2376 MCAsmParser &Parser = getParser();
2377 assert(isParsingMSInlineAsm() &&
"Expected to be parsing inline assembly.");
2381 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);
2383 const AsmToken &Tok = Parser.
getTok();
2384 SMLoc Loc = Tok.
getLoc();
2399 "frontend claimed part of a token?");
2404 StringRef InternalName =
2405 SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(),
2407 assert(InternalName.
size() &&
"We should have an internal name here.");
2410 if (!IsParsingOffsetOperator)
2426 MCAsmParser &Parser = getParser();
2427 const AsmToken &Tok = Parser.
getTok();
2429 const SMLoc consumedToken = consumeToken();
2431 return Error(Tok.
getLoc(),
"Expected an identifier after {");
2434 .Case(
"rn", X86::STATIC_ROUNDING::TO_NEAREST_INT)
2435 .Case(
"rd", X86::STATIC_ROUNDING::TO_NEG_INF)
2436 .Case(
"ru", X86::STATIC_ROUNDING::TO_POS_INF)
2437 .Case(
"rz", X86::STATIC_ROUNDING::TO_ZERO)
2440 return Error(Tok.
getLoc(),
"Invalid rounding mode.");
2443 return Error(Tok.
getLoc(),
"Expected - at this point");
2447 return Error(Tok.
getLoc(),
"Expected } at this point");
2450 const MCExpr *RndModeOp =
2458 return Error(Tok.
getLoc(),
"Expected } at this point");
2463 return Error(Tok.
getLoc(),
"unknown token in expression");
2469 MCAsmParser &Parser = getParser();
2470 AsmToken Tok = Parser.
getTok();
2473 return Error(Tok.
getLoc(),
"Expected { at this point");
2477 return Error(Tok.
getLoc(),
"Expected dfv at this point");
2481 return Error(Tok.
getLoc(),
"Expected = at this point");
2493 unsigned CFlags = 0;
2494 for (
unsigned I = 0;
I < 4; ++
I) {
2503 return Error(Tok.
getLoc(),
"Invalid conditional flags");
2506 return Error(Tok.
getLoc(),
"Duplicated conditional flag");
2517 }
else if (
I == 3) {
2518 return Error(Tok.
getLoc(),
"Expected } at this point");
2520 return Error(Tok.
getLoc(),
"Expected } or , at this point");
2528bool X86AsmParser::ParseIntelDotOperator(IntelExprStateMachine &SM,
2530 const AsmToken &Tok = getTok();
2536 bool TrailingDot =
false;
2544 }
else if ((isParsingMSInlineAsm() || getParser().isParsingMasm()) &&
2547 const std::pair<StringRef, StringRef> BaseMember = DotDispStr.
split(
'.');
2548 const StringRef
Base = BaseMember.first,
Member = BaseMember.second;
2549 if (getParser().lookUpField(SM.getType(), DotDispStr, Info) &&
2550 getParser().lookUpField(SM.getSymName(), DotDispStr, Info) &&
2551 getParser().lookUpField(DotDispStr, Info) &&
2553 SemaCallback->LookupInlineAsmField(
Base, Member,
Info.Offset)))
2554 return Error(Tok.
getLoc(),
"Unable to lookup field reference!");
2556 return Error(Tok.
getLoc(),
"Unexpected token type!");
2561 const char *DotExprEndLoc = DotDispStr.
data() + DotDispStr.
size();
2566 SM.addImm(
Info.Offset);
2567 SM.setTypeInfo(
Info.Type);
2573bool X86AsmParser::ParseIntelOffsetOperator(
const MCExpr *&Val, StringRef &ID,
2574 InlineAsmIdentifierInfo &Info,
2577 SMLoc
Start = Lex().getLoc();
2578 ID = getTok().getString();
2579 if (!isParsingMSInlineAsm()) {
2582 getParser().parsePrimaryExpr(Val, End,
nullptr))
2583 return Error(Start,
"unexpected token!");
2584 }
else if (ParseIntelInlineAsmIdentifier(Val, ID, Info,
false, End,
true)) {
2585 return Error(Start,
"unable to lookup expression");
2587 return Error(Start,
"offset operator cannot yet handle constants");
2594bool X86AsmParser::ParseIntelImagerelOperator(
const MCExpr *&Val, StringRef &ID,
2595 InlineAsmIdentifierInfo &Info,
2598 SMLoc
Start = Lex().getLoc();
2599 ID = getTok().getString();
2600 if (!isParsingMSInlineAsm()) {
2603 getParser().parsePrimaryExpr(Val, End,
nullptr))
2604 return Error(Start,
"unexpected token!");
2605 }
else if (ParseIntelInlineAsmIdentifier(Val, ID, Info,
false, End,
true)) {
2606 return Error(Start,
"unable to lookup expression");
2608 return Error(Start,
"imagerel operator cannot yet handle constants");
2611 const MCExpr *ModifiedVal =
2614 return Error(Start,
"cannot apply 'imagerel' to this expression");
2621unsigned X86AsmParser::IdentifyIntelInlineAsmOperator(StringRef Name) {
2622 return StringSwitch<unsigned>(Name)
2623 .Cases({
"TYPE",
"type"}, IOK_TYPE)
2624 .Cases({
"SIZE",
"size"}, IOK_SIZE)
2625 .Cases({
"LENGTH",
"length"}, IOK_LENGTH)
2635unsigned X86AsmParser::ParseIntelInlineAsmOperator(
unsigned OpKind) {
2636 MCAsmParser &Parser = getParser();
2637 const AsmToken &Tok = Parser.
getTok();
2640 const MCExpr *Val =
nullptr;
2641 InlineAsmIdentifierInfo
Info;
2644 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
2649 Error(Start,
"unable to lookup expression");
2656 case IOK_LENGTH: CVal =
Info.Var.Length;
break;
2657 case IOK_SIZE: CVal =
Info.Var.Size;
break;
2658 case IOK_TYPE: CVal =
Info.Var.Type;
break;
2666unsigned X86AsmParser::IdentifyMasmOperator(StringRef Name) {
2667 return StringSwitch<unsigned>(
Name.lower())
2668 .Case(
"type", MOK_TYPE)
2669 .Cases({
"size",
"sizeof"}, MOK_SIZEOF)
2670 .Cases({
"length",
"lengthof"}, MOK_LENGTHOF)
2680bool X86AsmParser::ParseMasmOperator(
unsigned OpKind, int64_t &Val) {
2681 MCAsmParser &Parser = getParser();
2686 if (OpKind == MOK_SIZEOF || OpKind == MOK_TYPE) {
2689 const AsmToken &IDTok = InParens ? getLexer().peekTok() : Parser.
getTok();
2705 IntelExprStateMachine SM;
2707 if (ParseIntelExpression(SM, End))
2717 Val = SM.getLength();
2720 Val = SM.getElementSize();
2725 return Error(OpLoc,
"expression has unknown type", SMRange(Start, End));
2731bool X86AsmParser::ParseIntelMemoryOperandSize(
unsigned &
Size,
2732 StringRef *SizeStr) {
2733 Size = StringSwitch<unsigned>(getTok().getString())
2734 .Cases({
"BYTE",
"byte"}, 8)
2735 .Cases({
"WORD",
"word"}, 16)
2736 .Cases({
"DWORD",
"dword"}, 32)
2737 .Cases({
"FLOAT",
"float"}, 32)
2738 .Cases({
"LONG",
"long"}, 32)
2739 .Cases({
"FWORD",
"fword"}, 48)
2740 .Cases({
"DOUBLE",
"double"}, 64)
2741 .Cases({
"QWORD",
"qword"}, 64)
2742 .Cases({
"MMWORD",
"mmword"}, 64)
2743 .Cases({
"XWORD",
"xword"}, 80)
2744 .Cases({
"TBYTE",
"tbyte"}, 80)
2745 .Cases({
"XMMWORD",
"xmmword"}, 128)
2746 .Cases({
"YMMWORD",
"ymmword"}, 256)
2747 .Cases({
"ZMMWORD",
"zmmword"}, 512)
2751 *SizeStr = getTok().getString();
2752 const AsmToken &Tok = Lex();
2754 return Error(Tok.
getLoc(),
"Expected 'PTR' or 'ptr' token!");
2761 if (getX86MCRegisterClass(X86::GR8RegClassID).
contains(RegNo))
2763 if (getX86MCRegisterClass(X86::GR16RegClassID).
contains(RegNo))
2765 if (getX86MCRegisterClass(X86::GR32RegClassID).
contains(RegNo))
2767 if (getX86MCRegisterClass(X86::GR64RegClassID).
contains(RegNo))
2774 MCAsmParser &Parser = getParser();
2775 const AsmToken &Tok = Parser.
getTok();
2781 if (ParseIntelMemoryOperandSize(
Size, &SizeStr))
2783 bool PtrInOperand = bool(
Size);
2789 return ParseRoundingModeOp(Start,
Operands);
2794 if (RegNo == X86::RIP)
2795 return Error(Start,
"rip can only be used as a base register");
2800 return Error(Start,
"expected memory operand after 'ptr', "
2801 "found register operand instead");
2810 "cannot cast register '" +
2812 "'; its size is not easily defined.");
2816 std::to_string(
RegSize) +
"-bit register '" +
2818 "' cannot be used as a " + std::to_string(
Size) +
"-bit " +
2825 if (!getX86MCRegisterClass(X86::SEGMENT_REGRegClassID).
contains(RegNo))
2826 return Error(Start,
"invalid segment register");
2828 Start = Lex().getLoc();
2832 IntelExprStateMachine SM;
2833 if (ParseIntelExpression(SM, End))
2836 if (isParsingMSInlineAsm())
2837 RewriteIntelExpression(SM, Start, Tok.
getLoc());
2839 int64_t
Imm = SM.getImm();
2840 const MCExpr *Disp = SM.getSym();
2849 if (!SM.isMemExpr() && !RegNo) {
2850 if (isParsingMSInlineAsm() && SM.isOffsetOperator()) {
2851 const InlineAsmIdentifierInfo &
Info = SM.getIdentifierInfo();
2856 SM.getSymName(),
Info.Var.Decl,
2857 Info.Var.IsGlobalLV));
2867 MCRegister
BaseReg = SM.getBaseReg();
2868 MCRegister IndexReg = SM.getIndexReg();
2869 if (IndexReg && BaseReg == X86::RIP)
2871 unsigned Scale = SM.getScale();
2873 Size = SM.getElementSize() << 3;
2875 if (Scale == 0 && BaseReg != X86::ESP && BaseReg != X86::RSP &&
2876 (IndexReg == X86::ESP || IndexReg == X86::RSP))
2882 !(getX86MCRegisterClass(X86::VR128XRegClassID).
contains(IndexReg) ||
2883 getX86MCRegisterClass(X86::VR256XRegClassID).
contains(IndexReg) ||
2884 getX86MCRegisterClass(X86::VR512RegClassID).
contains(IndexReg)) &&
2885 (getX86MCRegisterClass(X86::VR128XRegClassID).
contains(BaseReg) ||
2886 getX86MCRegisterClass(X86::VR256XRegClassID).
contains(BaseReg) ||
2887 getX86MCRegisterClass(X86::VR512RegClassID).
contains(BaseReg)))
2891 getX86MCRegisterClass(X86::GR16RegClassID).
contains(IndexReg))
2892 return Error(Start,
"16-bit addresses cannot have a scale");
2901 if ((BaseReg == X86::SI || BaseReg == X86::DI) &&
2902 (IndexReg == X86::BX || IndexReg == X86::BP))
2905 if ((BaseReg || IndexReg) &&
2908 return Error(Start, ErrMsg);
2909 bool IsUnconditionalBranch =
2910 Name.equals_insensitive(
"jmp") ||
Name.equals_insensitive(
"call");
2911 if (isParsingMSInlineAsm())
2912 return CreateMemForMSInlineAsm(RegNo, Disp, BaseReg, IndexReg, Scale,
2913 IsUnconditionalBranch && is64BitMode(),
2914 Start, End,
Size, SM.getSymName(),
2919 MCRegister DefaultBaseReg;
2920 bool MaybeDirectBranchDest =
true;
2923 if (is64BitMode() &&
2924 ((PtrInOperand && !IndexReg) || SM.getElementSize() > 0)) {
2925 DefaultBaseReg = X86::RIP;
2927 if (IsUnconditionalBranch) {
2929 MaybeDirectBranchDest =
false;
2931 DefaultBaseReg = X86::RIP;
2932 }
else if (!BaseReg && !IndexReg && Disp &&
2934 if (is64BitMode()) {
2935 if (SM.getSize() == 8) {
2936 MaybeDirectBranchDest =
false;
2937 DefaultBaseReg = X86::RIP;
2940 if (SM.getSize() == 4 || SM.getSize() == 2)
2941 MaybeDirectBranchDest =
false;
2945 }
else if (IsUnconditionalBranch) {
2947 if (!PtrInOperand && SM.isOffsetOperator())
2949 Start,
"`OFFSET` operator cannot be used in an unconditional branch");
2950 if (PtrInOperand || SM.isBracketUsed())
2951 MaybeDirectBranchDest =
false;
2954 if (CheckDispOverflow(BaseReg, IndexReg, Disp, Start))
2957 if ((BaseReg || IndexReg || RegNo || DefaultBaseReg))
2959 getPointerWidth(), RegNo, Disp, BaseReg, IndexReg, Scale, Start, End,
2960 Size, DefaultBaseReg, StringRef(),
nullptr,
2961 0,
false, MaybeDirectBranchDest));
2964 getPointerWidth(), Disp, Start, End,
Size, StringRef(),
2966 MaybeDirectBranchDest));
2971 MCAsmParser &Parser = getParser();
2972 switch (getLexer().getKind()) {
2982 "expected immediate expression") ||
2983 getParser().parseExpression(Val, End) ||
2991 return ParseRoundingModeOp(Start,
Operands);
3000 const MCExpr *Expr =
nullptr;
3012 if (
Reg == X86::EIZ ||
Reg == X86::RIZ)
3014 Loc,
"%eiz and %riz can only be used as index registers",
3015 SMRange(Loc, EndLoc));
3016 if (
Reg == X86::RIP)
3017 return Error(Loc,
"%rip can only be used as a base register",
3018 SMRange(Loc, EndLoc));
3024 if (!getX86MCRegisterClass(X86::SEGMENT_REGRegClassID).
contains(
Reg))
3025 return Error(Loc,
"invalid segment register");
3033 return ParseMemOperand(
Reg, Expr, Loc, EndLoc,
Operands);
3040X86::CondCode X86AsmParser::ParseConditionCode(StringRef CC) {
3041 return StringSwitch<X86::CondCode>(CC)
3063bool X86AsmParser::ParseZ(std::unique_ptr<X86Operand> &Z, SMLoc StartLoc) {
3064 MCAsmParser &Parser = getParser();
3069 (getLexer().getTok().getIdentifier() ==
"z")))
3074 return Error(getLexer().getLoc(),
"Expected } at this point");
3083 MCAsmParser &Parser = getParser();
3086 const SMLoc consumedToken = consumeToken();
3090 if (getLexer().getTok().getIntVal() != 1)
3091 return TokError(
"Expected 1to<NUM> at this point");
3092 StringRef
Prefix = getLexer().getTok().getString();
3095 return TokError(
"Expected 1to<NUM> at this point");
3098 StringRef BroadcastString = (
Prefix + getLexer().getTok().getIdentifier())
3101 return TokError(
"Expected 1to<NUM> at this point");
3102 const char *BroadcastPrimitive =
3103 StringSwitch<const char *>(BroadcastString)
3104 .Case(
"1to2",
"{1to2}")
3105 .Case(
"1to4",
"{1to4}")
3106 .Case(
"1to8",
"{1to8}")
3107 .Case(
"1to16",
"{1to16}")
3108 .Case(
"1to32",
"{1to32}")
3110 if (!BroadcastPrimitive)
3111 return TokError(
"Invalid memory broadcast primitive.");
3114 return TokError(
"Expected } at this point");
3125 std::unique_ptr<X86Operand>
Z;
3126 if (ParseZ(Z, consumedToken))
3132 SMLoc StartLoc =
Z ? consumeToken() : consumedToken;
3137 if (!parseRegister(RegNo, RegLoc, StartLoc) &&
3138 getX86MCRegisterClass(X86::VK1RegClassID).
contains(RegNo)) {
3139 if (RegNo == X86::K0)
3140 return Error(RegLoc,
"Register k0 can't be used as write mask");
3142 return Error(getLexer().getLoc(),
"Expected } at this point");
3148 return Error(getLexer().getLoc(),
3149 "Expected an op-mask register at this point");
3154 if (ParseZ(Z, consumeToken()) || !Z)
3155 return Error(getLexer().getLoc(),
3156 "Expected a {z} mark at this point");
3171bool X86AsmParser::CheckDispOverflow(MCRegister BaseReg, MCRegister IndexReg,
3172 const MCExpr *Disp, SMLoc Loc) {
3178 if (BaseReg || IndexReg) {
3180 auto Imm =
CE->getValue();
3182 getX86MCRegisterClass(X86::GR64RegClassID).contains(BaseReg) ||
3183 getX86MCRegisterClass(X86::GR64RegClassID).contains(IndexReg);
3184 bool Is16 = getX86MCRegisterClass(X86::GR16RegClassID).contains(BaseReg);
3187 return Error(Loc,
"displacement " + Twine(
Imm) +
3188 " is not within [-2147483648, 2147483647]");
3192 " shortened to 32-bit signed " +
3193 Twine(
static_cast<int32_t
>(
Imm)));
3197 " shortened to 16-bit signed " +
3198 Twine(
static_cast<int16_t
>(
Imm)));
3207bool X86AsmParser::ParseMemOperand(MCRegister SegReg,
const MCExpr *Disp,
3208 SMLoc StartLoc, SMLoc EndLoc,
3210 MCAsmParser &Parser = getParser();
3228 auto isAtMemOperand = [
this]() {
3233 auto TokCount = this->getLexer().peekTokens(Buf,
true);
3236 switch (Buf[0].getKind()) {
3243 if ((TokCount > 1) &&
3247 Buf[1].getIdentifier().
size() + 1);
3269 if (!isAtMemOperand()) {
3288 0, 0, 1, StartLoc, EndLoc));
3296 SMLoc BaseLoc = getLexer().getLoc();
3308 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ)
3309 return Error(BaseLoc,
"eiz and riz can only be used as index registers",
3310 SMRange(BaseLoc, EndLoc));
3328 if (!
E->evaluateAsAbsolute(ScaleVal, getStreamer().getAssemblerPtr()))
3329 return Error(Loc,
"expected absolute expression");
3331 Warning(Loc,
"scale factor without index register is ignored");
3336 if (BaseReg == X86::RIP)
3338 "%rip as base register can not have an index register");
3339 if (IndexReg == X86::RIP)
3340 return Error(Loc,
"%rip is not allowed as an index register");
3351 return Error(Loc,
"expected scale expression");
3352 Scale = (unsigned)ScaleVal;
3354 if (getX86MCRegisterClass(X86::GR16RegClassID).
contains(BaseReg) &&
3356 return Error(Loc,
"scale factor in 16-bit address must be 1");
3358 return Error(Loc, ErrMsg);
3372 if (BaseReg == X86::DX && !IndexReg && Scale == 1 && !SegReg &&
3381 return Error(BaseLoc, ErrMsg);
3383 if (CheckDispOverflow(BaseReg, IndexReg, Disp, BaseLoc))
3386 if (SegReg || BaseReg || IndexReg)
3388 BaseReg, IndexReg, Scale, StartLoc,
3397bool X86AsmParser::parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
3398 MCAsmParser &Parser = getParser();
3405 if (parseRegister(RegNo, StartLoc, EndLoc))
3413bool X86AsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
3415 MCAsmParser &Parser = getParser();
3419 ForcedOpcodePrefix = OpcodePrefix_Default;
3420 ForcedDispEncoding = DispEncoding_Default;
3421 UseApxExtendedReg =
false;
3422 ForcedNoFlag =
false;
3435 if (Prefix ==
"rex")
3436 ForcedOpcodePrefix = OpcodePrefix_REX;
3437 else if (Prefix ==
"rex2")
3438 ForcedOpcodePrefix = OpcodePrefix_REX2;
3439 else if (Prefix ==
"vex")
3440 ForcedOpcodePrefix = OpcodePrefix_VEX;
3441 else if (Prefix ==
"vex2")
3442 ForcedOpcodePrefix = OpcodePrefix_VEX2;
3443 else if (Prefix ==
"vex3")
3444 ForcedOpcodePrefix = OpcodePrefix_VEX3;
3445 else if (Prefix ==
"evex")
3446 ForcedOpcodePrefix = OpcodePrefix_EVEX;
3447 else if (Prefix ==
"disp8")
3448 ForcedDispEncoding = DispEncoding_Disp8;
3449 else if (Prefix ==
"disp32")
3450 ForcedDispEncoding = DispEncoding_Disp32;
3451 else if (Prefix ==
"nf")
3452 ForcedNoFlag =
true;
3454 return Error(NameLoc,
"unknown prefix");
3470 if (isParsingMSInlineAsm()) {
3471 if (
Name.equals_insensitive(
"vex"))
3472 ForcedOpcodePrefix = OpcodePrefix_VEX;
3473 else if (
Name.equals_insensitive(
"vex2"))
3474 ForcedOpcodePrefix = OpcodePrefix_VEX2;
3475 else if (
Name.equals_insensitive(
"vex3"))
3476 ForcedOpcodePrefix = OpcodePrefix_VEX3;
3477 else if (
Name.equals_insensitive(
"evex"))
3478 ForcedOpcodePrefix = OpcodePrefix_EVEX;
3480 if (ForcedOpcodePrefix != OpcodePrefix_Default) {
3493 if (
Name.consume_back(
".d32")) {
3494 ForcedDispEncoding = DispEncoding_Disp32;
3495 }
else if (
Name.consume_back(
".d8")) {
3496 ForcedDispEncoding = DispEncoding_Disp8;
3499 StringRef PatchedName =
Name;
3502 if (isParsingIntelSyntax() &&
3503 (PatchedName ==
"jmp" || PatchedName ==
"jc" || PatchedName ==
"jnc" ||
3504 PatchedName ==
"jcxz" || PatchedName ==
"jecxz" ||
3509 : NextTok ==
"short") {
3518 NextTok.
size() + 1);
3524 PatchedName !=
"setzub" && PatchedName !=
"setzunb" &&
3525 PatchedName !=
"setb" && PatchedName !=
"setnb")
3526 PatchedName = PatchedName.
substr(0,
Name.size()-1);
3528 unsigned ComparisonPredicate = ~0
U;
3536 bool IsVCMP = PatchedName[0] ==
'v';
3537 unsigned CCIdx =
IsVCMP ? 4 : 3;
3538 unsigned suffixLength = PatchedName.
ends_with(
"bf16") ? 5 : 2;
3539 unsigned CC = StringSwitch<unsigned>(
3540 PatchedName.
slice(CCIdx, PatchedName.
size() - suffixLength))
3542 .Case(
"eq_oq", 0x00)
3544 .Case(
"lt_os", 0x01)
3546 .Case(
"le_os", 0x02)
3547 .Case(
"unord", 0x03)
3548 .Case(
"unord_q", 0x03)
3550 .Case(
"neq_uq", 0x04)
3552 .Case(
"nlt_us", 0x05)
3554 .Case(
"nle_us", 0x06)
3556 .Case(
"ord_q", 0x07)
3558 .Case(
"eq_uq", 0x08)
3560 .Case(
"nge_us", 0x09)
3562 .Case(
"ngt_us", 0x0A)
3563 .Case(
"false", 0x0B)
3564 .Case(
"false_oq", 0x0B)
3565 .Case(
"neq_oq", 0x0C)
3567 .Case(
"ge_os", 0x0D)
3569 .Case(
"gt_os", 0x0E)
3571 .Case(
"true_uq", 0x0F)
3572 .Case(
"eq_os", 0x10)
3573 .Case(
"lt_oq", 0x11)
3574 .Case(
"le_oq", 0x12)
3575 .Case(
"unord_s", 0x13)
3576 .Case(
"neq_us", 0x14)
3577 .Case(
"nlt_uq", 0x15)
3578 .Case(
"nle_uq", 0x16)
3579 .Case(
"ord_s", 0x17)
3580 .Case(
"eq_us", 0x18)
3581 .Case(
"nge_uq", 0x19)
3582 .Case(
"ngt_uq", 0x1A)
3583 .Case(
"false_os", 0x1B)
3584 .Case(
"neq_os", 0x1C)
3585 .Case(
"ge_oq", 0x1D)
3586 .Case(
"gt_oq", 0x1E)
3587 .Case(
"true_us", 0x1F)
3589 if (CC != ~0U && (
IsVCMP || CC < 8) &&
3592 PatchedName =
IsVCMP ?
"vcmpss" :
"cmpss";
3594 PatchedName =
IsVCMP ?
"vcmpsd" :
"cmpsd";
3596 PatchedName =
IsVCMP ?
"vcmpps" :
"cmpps";
3598 PatchedName =
IsVCMP ?
"vcmppd" :
"cmppd";
3600 PatchedName =
"vcmpsh";
3602 PatchedName =
"vcmpph";
3604 PatchedName =
"vcmpbf16";
3608 ComparisonPredicate = CC;
3614 (PatchedName.
back() ==
'b' || PatchedName.
back() ==
'w' ||
3615 PatchedName.
back() ==
'd' || PatchedName.
back() ==
'q')) {
3616 unsigned SuffixSize = PatchedName.
drop_back().
back() ==
'u' ? 2 : 1;
3617 unsigned CC = StringSwitch<unsigned>(
3618 PatchedName.
slice(5, PatchedName.
size() - SuffixSize))
3628 if (CC != ~0U && (CC != 0 || SuffixSize == 2)) {
3629 switch (PatchedName.
back()) {
3631 case 'b': PatchedName = SuffixSize == 2 ?
"vpcmpub" :
"vpcmpb";
break;
3632 case 'w': PatchedName = SuffixSize == 2 ?
"vpcmpuw" :
"vpcmpw";
break;
3633 case 'd': PatchedName = SuffixSize == 2 ?
"vpcmpud" :
"vpcmpd";
break;
3634 case 'q': PatchedName = SuffixSize == 2 ?
"vpcmpuq" :
"vpcmpq";
break;
3637 ComparisonPredicate = CC;
3643 (PatchedName.
back() ==
'b' || PatchedName.
back() ==
'w' ||
3644 PatchedName.
back() ==
'd' || PatchedName.
back() ==
'q')) {
3645 unsigned SuffixSize = PatchedName.
drop_back().
back() ==
'u' ? 2 : 1;
3646 unsigned CC = StringSwitch<unsigned>(
3647 PatchedName.
slice(5, PatchedName.
size() - SuffixSize))
3658 switch (PatchedName.
back()) {
3660 case 'b': PatchedName = SuffixSize == 2 ?
"vpcomub" :
"vpcomb";
break;
3661 case 'w': PatchedName = SuffixSize == 2 ?
"vpcomuw" :
"vpcomw";
break;
3662 case 'd': PatchedName = SuffixSize == 2 ?
"vpcomud" :
"vpcomd";
break;
3663 case 'q': PatchedName = SuffixSize == 2 ?
"vpcomuq" :
"vpcomq";
break;
3666 ComparisonPredicate = CC;
3678 StringSwitch<bool>(Name)
3679 .Cases({
"cs",
"ds",
"es",
"fs",
"gs",
"ss"},
true)
3680 .Cases({
"rex64",
"data32",
"data16",
"addr32",
"addr16"},
true)
3681 .Cases({
"xacquire",
"xrelease"},
true)
3682 .Cases({
"acquire",
"release"}, isParsingIntelSyntax())
3685 auto isLockRepeatNtPrefix = [](StringRef
N) {
3686 return StringSwitch<bool>(
N)
3687 .Cases({
"lock",
"rep",
"repe",
"repz",
"repne",
"repnz",
"notrack"},
3692 bool CurlyAsEndOfStatement =
false;
3695 while (isLockRepeatNtPrefix(
Name.lower())) {
3697 StringSwitch<unsigned>(Name)
3716 while (
Name.starts_with(
";") ||
Name.starts_with(
"\n") ||
3717 Name.starts_with(
"#") ||
Name.starts_with(
"\t") ||
3718 Name.starts_with(
"/")) {
3729 if (PatchedName ==
"data16" && is16BitMode()) {
3730 return Error(NameLoc,
"redundant data16 prefix");
3732 if (PatchedName ==
"data32") {
3734 return Error(NameLoc,
"redundant data32 prefix");
3736 return Error(NameLoc,
"'data32' is not supported in 64-bit mode");
3738 PatchedName =
"data16";
3745 if (
Next ==
"callw")
3747 if (
Next ==
"ljmpw")
3752 ForcedDataPrefix = X86::Is32Bit;
3760 if (ComparisonPredicate != ~0U && !isParsingIntelSyntax()) {
3767 if ((
Name.starts_with(
"ccmp") ||
Name.starts_with(
"ctest")) &&
3796 CurlyAsEndOfStatement =
3797 isParsingIntelSyntax() && isParsingMSInlineAsm() &&
3800 return TokError(
"unexpected token in argument list");
3804 if (ComparisonPredicate != ~0U && isParsingIntelSyntax()) {
3814 else if (CurlyAsEndOfStatement)
3817 getLexer().getTok().getLoc(), 0);
3824 if (IsFp &&
Operands.size() == 1) {
3825 const char *Repl = StringSwitch<const char *>(Name)
3826 .Case(
"fsub",
"fsubp")
3827 .Case(
"fdiv",
"fdivp")
3828 .Case(
"fsubr",
"fsubrp")
3829 .Case(
"fdivr",
"fdivrp");
3830 static_cast<X86Operand &
>(*
Operands[0]).setTokenValue(Repl);
3833 if ((Name ==
"mov" || Name ==
"movw" || Name ==
"movl") &&
3835 X86Operand &Op1 = (X86Operand &)*
Operands[1];
3836 X86Operand &Op2 = (X86Operand &)*
Operands[2];
3841 getX86MCRegisterClass(X86::SEGMENT_REGRegClassID)
3843 (getX86MCRegisterClass(X86::GR16RegClassID).
contains(Op1.
getReg()) ||
3844 getX86MCRegisterClass(X86::GR32RegClassID).
contains(Op1.
getReg()))) {
3846 if (Name !=
"mov" && Name[3] == (is16BitMode() ?
'l' :
'w')) {
3847 Name = is16BitMode() ?
"movw" :
"movl";
3860 if ((Name ==
"outb" || Name ==
"outsb" || Name ==
"outw" || Name ==
"outsw" ||
3861 Name ==
"outl" || Name ==
"outsl" || Name ==
"out" || Name ==
"outs") &&
3863 X86Operand &
Op = (X86Operand &)*
Operands.back();
3869 if ((Name ==
"inb" || Name ==
"insb" || Name ==
"inw" || Name ==
"insw" ||
3870 Name ==
"inl" || Name ==
"insl" || Name ==
"in" || Name ==
"ins") &&
3879 bool HadVerifyError =
false;
3882 if (
Name.starts_with(
"ins") &&
3884 (Name ==
"insb" || Name ==
"insw" || Name ==
"insl" || Name ==
"insd" ||
3887 AddDefaultSrcDestOperands(TmpOperands,
3889 DefaultMemDIOperand(NameLoc));
3890 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3894 if (
Name.starts_with(
"outs") &&
3896 (Name ==
"outsb" || Name ==
"outsw" || Name ==
"outsl" ||
3897 Name ==
"outsd" || Name ==
"outs")) {
3898 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
3900 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3906 if (
Name.starts_with(
"lods") &&
3908 (Name ==
"lods" || Name ==
"lodsb" || Name ==
"lodsw" ||
3909 Name ==
"lodsl" || Name ==
"lodsd" || Name ==
"lodsq")) {
3910 TmpOperands.
push_back(DefaultMemSIOperand(NameLoc));
3911 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3917 if (
Name.starts_with(
"stos") &&
3919 (Name ==
"stos" || Name ==
"stosb" || Name ==
"stosw" ||
3920 Name ==
"stosl" || Name ==
"stosd" || Name ==
"stosq")) {
3921 TmpOperands.
push_back(DefaultMemDIOperand(NameLoc));
3922 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3928 if (
Name.starts_with(
"scas") &&
3930 (Name ==
"scas" || Name ==
"scasb" || Name ==
"scasw" ||
3931 Name ==
"scasl" || Name ==
"scasd" || Name ==
"scasq")) {
3932 TmpOperands.
push_back(DefaultMemDIOperand(NameLoc));
3933 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3937 if (
Name.starts_with(
"cmps") &&
3939 (Name ==
"cmps" || Name ==
"cmpsb" || Name ==
"cmpsw" ||
3940 Name ==
"cmpsl" || Name ==
"cmpsd" || Name ==
"cmpsq")) {
3941 AddDefaultSrcDestOperands(TmpOperands, DefaultMemDIOperand(NameLoc),
3942 DefaultMemSIOperand(NameLoc));
3943 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3947 if (((
Name.starts_with(
"movs") &&
3948 (Name ==
"movs" || Name ==
"movsb" || Name ==
"movsw" ||
3949 Name ==
"movsl" || Name ==
"movsd" || Name ==
"movsq")) ||
3950 (
Name.starts_with(
"smov") &&
3951 (Name ==
"smov" || Name ==
"smovb" || Name ==
"smovw" ||
3952 Name ==
"smovl" || Name ==
"smovd" || Name ==
"smovq"))) &&
3954 if (Name ==
"movsd" &&
Operands.size() == 1 && !isParsingIntelSyntax())
3956 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
3957 DefaultMemDIOperand(NameLoc));
3958 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3962 if (HadVerifyError) {
3963 return HadVerifyError;
3967 if ((Name ==
"xlat" || Name ==
"xlatb") &&
Operands.size() == 2) {
3968 X86Operand &Op1 =
static_cast<X86Operand &
>(*
Operands[1]);
3971 "size, (R|E)BX will be used for the location");
3973 static_cast<X86Operand &
>(*
Operands[0]).setTokenValue(
"xlatb");
3986 if (
I ==
Table.end() ||
I->OldOpc != Opcode)
3992 if (X86::isBLENDVPD(Opcode) || X86::isBLENDVPS(Opcode) ||
3993 X86::isPBLENDVB(Opcode))
3999bool X86AsmParser::processInstruction(MCInst &Inst,
const OperandVector &
Ops) {
4003 if (ForcedOpcodePrefix != OpcodePrefix_VEX3 &&
4010 auto replaceWithCCMPCTEST = [&](
unsigned Opcode) ->
bool {
4011 if (ForcedOpcodePrefix == OpcodePrefix_EVEX) {
4022 default:
return false;
4027 if (ForcedDispEncoding == DispEncoding_Disp32) {
4028 Inst.
setOpcode(is16BitMode() ? X86::JMP_2 : X86::JMP_4);
4037 if (ForcedDispEncoding == DispEncoding_Disp32) {
4038 Inst.
setOpcode(is16BitMode() ? X86::JCC_2 : X86::JCC_4);
4054#define FROM_TO(FROM, TO) \
4056 return replaceWithCCMPCTEST(X86::TO);
4058 FROM_TO(CMP64mi32, CCMP64mi32)
4061 FROM_TO(CMP64ri32, CCMP64ri32)
4088 FROM_TO(TEST64mi32, CTEST64mi32)
4090 FROM_TO(TEST64ri32, CTEST64ri32)
4110bool X86AsmParser::validateInstruction(MCInst &Inst,
const OperandVector &
Ops) {
4111 using namespace X86;
4112 const MCRegisterInfo *MRI =
getContext().getRegisterInfo();
4114 uint64_t TSFlags = MII.get(Opcode).TSFlags;
4115 if (isVFCMADDCPH(Opcode) || isVFCMADDCSH(Opcode) || isVFMADDCPH(Opcode) ||
4116 isVFMADDCSH(Opcode)) {
4120 return Warning(
Ops[0]->getStartLoc(),
"Destination register should be "
4121 "distinct from source registers");
4122 }
else if (isVFCMULCPH(Opcode) || isVFCMULCSH(Opcode) || isVFMULCPH(Opcode) ||
4123 isVFMULCSH(Opcode)) {
4133 return Warning(
Ops[0]->getStartLoc(),
"Destination register should be "
4134 "distinct from source registers");
4135 }
else if (isV4FMADDPS(Opcode) || isV4FMADDSS(Opcode) ||
4136 isV4FNMADDPS(Opcode) || isV4FNMADDSS(Opcode) ||
4137 isVP4DPWSSDS(Opcode) || isVP4DPWSSD(Opcode)) {
4142 if (Src2Enc % 4 != 0) {
4144 unsigned GroupStart = (Src2Enc / 4) * 4;
4145 unsigned GroupEnd = GroupStart + 3;
4147 "source register '" +
RegName +
"' implicitly denotes '" +
4148 RegName.take_front(3) + Twine(GroupStart) +
"' to '" +
4149 RegName.take_front(3) + Twine(GroupEnd) +
4152 }
else if (isVGATHERDPD(Opcode) || isVGATHERDPS(Opcode) ||
4153 isVGATHERQPD(Opcode) || isVGATHERQPS(Opcode) ||
4154 isVPGATHERDD(Opcode) || isVPGATHERDQ(Opcode) ||
4155 isVPGATHERQD(Opcode) || isVPGATHERQQ(Opcode)) {
4162 return Warning(
Ops[0]->getStartLoc(),
"index and destination registers "
4163 "should be distinct");
4169 if (Dest == Mask || Dest == Index || Mask == Index)
4170 return Warning(
Ops[0]->getStartLoc(),
"mask, index, and destination "
4171 "registers should be distinct");
4173 }
else if (isTCMMIMFP16PS(Opcode) || isTCMMRLFP16PS(Opcode) ||
4174 isTDPBF16PS(Opcode) || isTDPFP16PS(Opcode) || isTDPBSSD(Opcode) ||
4175 isTDPBSUD(Opcode) || isTDPBUSD(Opcode) || isTDPBUUD(Opcode)) {
4179 if (SrcDest == Src1 || SrcDest == Src2 || Src1 == Src2)
4180 return Error(
Ops[0]->getStartLoc(),
"all tmm registers must be distinct");
4194 for (
unsigned i = 0; i !=
NumOps; ++i) {
4199 if (
Reg == X86::AH ||
Reg == X86::BH ||
Reg == X86::CH ||
Reg == X86::DH)
4207 (Enc ==
X86II::EVEX || ForcedOpcodePrefix == OpcodePrefix_REX2 ||
4208 ForcedOpcodePrefix == OpcodePrefix_REX || UsesRex)) {
4210 return Error(
Ops[0]->getStartLoc(),
4211 "can't encode '" +
RegName.str() +
4212 "' in an instruction requiring EVEX/REX2/REX prefix");
4216 if ((Opcode == X86::PREFETCHIT0 || Opcode == X86::PREFETCHIT1)) {
4220 Ops[0]->getStartLoc(),
4221 Twine((Inst.
getOpcode() == X86::PREFETCHIT0 ?
"'prefetchit0'"
4222 :
"'prefetchit1'")) +
4223 " only supports RIP-relative address");
4228void X86AsmParser::emitWarningForSpecialLVIInstruction(SMLoc Loc) {
4229 Warning(Loc,
"Instruction may be vulnerable to LVI and "
4230 "requires manual mitigation");
4231 Note(SMLoc(),
"See https://software.intel.com/"
4232 "security-software-guidance/insights/"
4233 "deep-dive-load-value-injection#specialinstructions"
4234 " for more information");
4246void X86AsmParser::applyLVICFIMitigation(MCInst &Inst, MCStreamer &Out) {
4257 MCInst ShlInst, FenceInst;
4258 bool Parse32 = is32BitMode() || Code16GCC;
4259 MCRegister Basereg =
4260 is64BitMode() ? X86::RSP : (Parse32 ? X86::ESP : X86::SP);
4264 1, SMLoc{}, SMLoc{}, 0);
4266 ShlMemOp->addMemOperands(ShlInst, 5);
4279 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4291void X86AsmParser::applyLVILoadHardeningMitigation(MCInst &Inst,
4308 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4311 }
else if (Opcode == X86::REP_PREFIX || Opcode == X86::REPNE_PREFIX) {
4314 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4318 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
4336 getSTI().
hasFeature(X86::FeatureLVIControlFlowIntegrity))
4337 applyLVICFIMitigation(Inst, Out);
4342 getSTI().
hasFeature(X86::FeatureLVILoadHardening))
4343 applyLVILoadHardeningMitigation(Inst, Out);
4347 unsigned Result = 0;
4349 if (Prefix.isPrefix()) {
4350 Result = Prefix.getPrefix();
4356bool X86AsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
4358 MCStreamer &Out,
uint64_t &ErrorInfo,
4359 bool MatchingInlineAsm) {
4361 assert((*
Operands[0]).isToken() &&
"Leading operand should always be a mnemonic!");
4364 MatchFPUWaitAlias(IDLoc,
static_cast<X86Operand &
>(*
Operands[0]),
Operands,
4365 Out, MatchingInlineAsm);
4372 if (ForcedOpcodePrefix == OpcodePrefix_REX)
4374 else if (ForcedOpcodePrefix == OpcodePrefix_REX2)
4376 else if (ForcedOpcodePrefix == OpcodePrefix_VEX)
4378 else if (ForcedOpcodePrefix == OpcodePrefix_VEX2)
4380 else if (ForcedOpcodePrefix == OpcodePrefix_VEX3)
4382 else if (ForcedOpcodePrefix == OpcodePrefix_EVEX)
4386 if (ForcedDispEncoding == DispEncoding_Disp8)
4388 else if (ForcedDispEncoding == DispEncoding_Disp32)
4394 return isParsingIntelSyntax()
4395 ? matchAndEmitIntelInstruction(IDLoc, Opcode, Inst,
Operands, Out,
4396 ErrorInfo, MatchingInlineAsm)
4397 : matchAndEmitATTInstruction(IDLoc, Opcode, Inst,
Operands, Out,
4398 ErrorInfo, MatchingInlineAsm);
4401void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &
Op,
4403 bool MatchingInlineAsm) {
4407 const char *Repl = StringSwitch<const char *>(
Op.getToken())
4408 .Case(
"finit",
"fninit")
4409 .Case(
"fsave",
"fnsave")
4410 .Case(
"fstcw",
"fnstcw")
4411 .Case(
"fstcww",
"fnstcw")
4412 .Case(
"fstenv",
"fnstenv")
4413 .Case(
"fstsw",
"fnstsw")
4414 .Case(
"fstsww",
"fnstsw")
4415 .Case(
"fclex",
"fnclex")
4421 if (!MatchingInlineAsm)
4427bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc,
4428 const FeatureBitset &MissingFeatures,
4429 bool MatchingInlineAsm) {
4430 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
4431 SmallString<126>
Msg;
4432 raw_svector_ostream OS(
Msg);
4433 OS <<
"instruction requires:";
4434 for (
unsigned Feature : MissingFeatures)
4436 return Error(IDLoc, OS.str(), SMRange(), MatchingInlineAsm);
4439unsigned X86AsmParser::checkTargetMatchPredicate(MCInst &Inst) {
4441 const MCInstrDesc &MCID = MII.get(
Opc);
4445 return Match_Unsupported;
4447 return Match_Unsupported;
4449 switch (ForcedOpcodePrefix) {
4450 case OpcodePrefix_Default:
4452 case OpcodePrefix_REX:
4453 case OpcodePrefix_REX2:
4455 return Match_Unsupported;
4457 case OpcodePrefix_VEX:
4458 case OpcodePrefix_VEX2:
4459 case OpcodePrefix_VEX3:
4461 return Match_Unsupported;
4463 case OpcodePrefix_EVEX:
4465 !X86::isCMP(
Opc) && !X86::isTEST(
Opc))
4466 return Match_Unsupported;
4468 return Match_Unsupported;
4473 (ForcedOpcodePrefix != OpcodePrefix_VEX &&
4474 ForcedOpcodePrefix != OpcodePrefix_VEX2 &&
4475 ForcedOpcodePrefix != OpcodePrefix_VEX3))
4476 return Match_Unsupported;
4478 return Match_Success;
4481bool X86AsmParser::matchAndEmitATTInstruction(
4483 MCStreamer &Out,
uint64_t &ErrorInfo,
bool MatchingInlineAsm) {
4484 X86Operand &
Op =
static_cast<X86Operand &
>(*
Operands[0]);
4488 if (ForcedDataPrefix == X86::Is32Bit)
4489 SwitchMode(X86::Is32Bit);
4491 FeatureBitset MissingFeatures;
4492 unsigned OriginalError = MatchInstruction(
Operands, Inst, ErrorInfo,
4493 MissingFeatures, MatchingInlineAsm,
4494 isParsingIntelSyntax());
4495 if (ForcedDataPrefix == X86::Is32Bit) {
4496 SwitchMode(X86::Is16Bit);
4497 ForcedDataPrefix = 0;
4499 switch (OriginalError) {
4502 if (!MatchingInlineAsm && validateInstruction(Inst,
Operands))
4507 if (!MatchingInlineAsm)
4508 while (processInstruction(Inst,
Operands))
4512 if (!MatchingInlineAsm)
4516 case Match_InvalidImmUnsignedi4: {
4517 SMLoc ErrorLoc = ((X86Operand &)*
Operands[ErrorInfo]).getStartLoc();
4518 if (ErrorLoc == SMLoc())
4520 return Error(ErrorLoc,
"immediate must be an integer in range [0, 15]",
4521 EmptyRange, MatchingInlineAsm);
4523 case Match_InvalidImmUnsignedi6: {
4524 SMLoc ErrorLoc = ((X86Operand &)*
Operands[ErrorInfo]).getStartLoc();
4525 if (ErrorLoc == SMLoc())
4527 return Error(ErrorLoc,
"immediate must be an integer in range [0, 63]",
4528 EmptyRange, MatchingInlineAsm);
4530 case Match_MissingFeature:
4531 return ErrorMissingFeature(IDLoc, MissingFeatures, MatchingInlineAsm);
4532 case Match_InvalidOperand:
4533 case Match_MnemonicFail:
4534 case Match_Unsupported:
4537 if (
Op.getToken().empty()) {
4538 Error(IDLoc,
"instruction must have size higher than 0", EmptyRange,
4549 StringRef
Base =
Op.getToken();
4550 SmallString<16> Tmp;
4553 Op.setTokenValue(Tmp);
4561 const char *Suffixes =
Base[0] !=
'f' ?
"bwlq" :
"slt\0";
4563 const char *MemSize =
Base[0] !=
'f' ?
"\x08\x10\x20\x40" :
"\x20\x40\x50\0";
4567 FeatureBitset ErrorInfoMissingFeatures;
4575 bool HasVectorReg =
false;
4576 X86Operand *MemOp =
nullptr;
4578 X86Operand *X86Op =
static_cast<X86Operand *
>(
Op.get());
4580 HasVectorReg =
true;
4581 else if (X86Op->
isMem()) {
4583 assert(MemOp->Mem.Size == 0 &&
"Memory size always 0 under ATT syntax");
4590 for (
unsigned I = 0,
E = std::size(Match);
I !=
E; ++
I) {
4591 Tmp.
back() = Suffixes[
I];
4592 if (MemOp && HasVectorReg)
4593 MemOp->Mem.Size = MemSize[
I];
4594 Match[
I] = Match_MnemonicFail;
4595 if (MemOp || !HasVectorReg) {
4597 MatchInstruction(
Operands, Inst, ErrorInfoIgnore, MissingFeatures,
4598 MatchingInlineAsm, isParsingIntelSyntax());
4600 if (Match[
I] == Match_MissingFeature)
4601 ErrorInfoMissingFeatures = MissingFeatures;
4611 unsigned NumSuccessfulMatches =
llvm::count(Match, Match_Success);
4612 if (NumSuccessfulMatches == 1) {
4613 if (!MatchingInlineAsm && validateInstruction(Inst,
Operands))
4618 if (!MatchingInlineAsm)
4619 while (processInstruction(Inst,
Operands))
4623 if (!MatchingInlineAsm)
4633 if (NumSuccessfulMatches > 1) {
4635 unsigned NumMatches = 0;
4636 for (
unsigned I = 0,
E = std::size(Match);
I !=
E; ++
I)
4637 if (Match[
I] == Match_Success)
4638 MatchChars[NumMatches++] = Suffixes[
I];
4640 SmallString<126>
Msg;
4641 raw_svector_ostream OS(
Msg);
4642 OS <<
"ambiguous instructions require an explicit suffix (could be ";
4643 for (
unsigned i = 0; i != NumMatches; ++i) {
4646 if (i + 1 == NumMatches)
4648 OS <<
"'" <<
Base << MatchChars[i] <<
"'";
4651 Error(IDLoc, OS.str(), EmptyRange, MatchingInlineAsm);
4659 if (
llvm::count(Match, Match_MnemonicFail) == 4) {
4660 if (OriginalError == Match_MnemonicFail)
4661 return Error(IDLoc,
"invalid instruction mnemonic '" +
Base +
"'",
4662 Op.getLocRange(), MatchingInlineAsm);
4664 if (OriginalError == Match_Unsupported)
4665 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4668 assert(OriginalError == Match_InvalidOperand &&
"Unexpected error");
4670 if (ErrorInfo != ~0ULL) {
4672 return Error(IDLoc,
"too few operands for instruction", EmptyRange,
4675 X86Operand &Operand = (X86Operand &)*
Operands[ErrorInfo];
4679 OperandRange, MatchingInlineAsm);
4683 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4689 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4695 if (
llvm::count(Match, Match_MissingFeature) == 1) {
4696 ErrorInfo = Match_MissingFeature;
4697 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
4703 if (
llvm::count(Match, Match_InvalidOperand) == 1) {
4704 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4709 Error(IDLoc,
"unknown use of instruction mnemonic without a size suffix",
4710 EmptyRange, MatchingInlineAsm);
4714bool X86AsmParser::matchAndEmitIntelInstruction(
4716 MCStreamer &Out,
uint64_t &ErrorInfo,
bool MatchingInlineAsm) {
4717 X86Operand &
Op =
static_cast<X86Operand &
>(*
Operands[0]);
4722 const bool ForcedData32 = ForcedDataPrefix == X86::Is32Bit;
4723 auto RestoreMode = [&] {
4725 SwitchMode(X86::Is16Bit);
4726 ForcedDataPrefix = 0;
4730 SwitchMode(X86::Is32Bit);
4732 X86Operand *UnsizedMemOp =
nullptr;
4734 X86Operand *X86Op =
static_cast<X86Operand *
>(
Op.get());
4736 UnsizedMemOp = X86Op;
4747 static const char *
const PtrSizedInstrs[] = {
"call",
"jmp",
"push",
"pop"};
4748 for (
const char *Instr : PtrSizedInstrs) {
4749 if (Mnemonic == Instr) {
4750 UnsizedMemOp->
Mem.
Size = getPointerWidth();
4756 SmallVector<unsigned, 8> Match;
4757 FeatureBitset ErrorInfoMissingFeatures;
4758 FeatureBitset MissingFeatures;
4763 if (Mnemonic ==
"push" &&
Operands.size() == 2) {
4764 auto *X86Op =
static_cast<X86Operand *
>(
Operands[1].get());
4765 if (X86Op->
isImm()) {
4768 unsigned Size = getPointerWidth();
4771 SmallString<16> Tmp;
4773 Tmp += (is64BitMode())
4775 : (is32BitMode()) ?
"l" : (is16BitMode()) ?
"w" :
" ";
4776 Op.setTokenValue(Tmp);
4779 MissingFeatures, MatchingInlineAsm,
4790 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
4791 for (
unsigned Size : MopSizes) {
4795 unsigned M = MatchInstruction(
Operands, Inst, ErrorInfoIgnore,
4796 MissingFeatures, MatchingInlineAsm,
4797 isParsingIntelSyntax());
4802 if (Match.
back() == Match_MissingFeature)
4803 ErrorInfoMissingFeatures = MissingFeatures;
4813 if (Match.
empty()) {
4815 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,
4816 isParsingIntelSyntax()));
4818 if (Match.
back() == Match_MissingFeature)
4819 ErrorInfoMissingFeatures = MissingFeatures;
4827 if (Match.
back() == Match_MnemonicFail) {
4829 return Error(IDLoc,
"invalid instruction mnemonic '" + Mnemonic +
"'",
4830 Op.getLocRange(), MatchingInlineAsm);
4833 unsigned NumSuccessfulMatches =
llvm::count(Match, Match_Success);
4837 if (UnsizedMemOp && NumSuccessfulMatches > 1 &&
4840 unsigned M = MatchInstruction(
4841 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,
4842 isParsingIntelSyntax());
4843 if (M == Match_Success)
4844 NumSuccessfulMatches = 1;
4859 if (NumSuccessfulMatches == 1) {
4860 if (!MatchingInlineAsm && validateInstruction(Inst,
Operands))
4865 if (!MatchingInlineAsm)
4866 while (processInstruction(Inst,
Operands))
4869 if (!MatchingInlineAsm)
4873 }
else if (NumSuccessfulMatches > 1) {
4875 "multiple matches only possible with unsized memory operands");
4877 "ambiguous operand size for instruction '" + Mnemonic +
"\'",
4883 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4889 if (
llvm::count(Match, Match_MissingFeature) == 1) {
4890 ErrorInfo = Match_MissingFeature;
4891 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
4897 if (
llvm::count(Match, Match_InvalidOperand) == 1) {
4898 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4902 if (
llvm::count(Match, Match_InvalidImmUnsignedi4) == 1) {
4903 SMLoc ErrorLoc = ((X86Operand &)*
Operands[ErrorInfo]).getStartLoc();
4904 if (ErrorLoc == SMLoc())
4906 return Error(ErrorLoc,
"immediate must be an integer in range [0, 15]",
4907 EmptyRange, MatchingInlineAsm);
4910 if (
llvm::count(Match, Match_InvalidImmUnsignedi6) == 1) {
4911 SMLoc ErrorLoc = ((X86Operand &)*
Operands[ErrorInfo]).getStartLoc();
4912 if (ErrorLoc == SMLoc())
4914 return Error(ErrorLoc,
"immediate must be an integer in range [0, 63]",
4915 EmptyRange, MatchingInlineAsm);
4919 return Error(IDLoc,
"unknown instruction mnemonic", EmptyRange,
4923bool X86AsmParser::omitRegisterFromClobberLists(MCRegister
Reg) {
4924 return getX86MCRegisterClass(X86::SEGMENT_REGRegClassID).contains(
Reg);
4927bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
4928 MCAsmParser &Parser = getParser();
4931 return parseDirectiveArch();
4933 return ParseDirectiveCode(IDVal, DirectiveID.
getLoc());
4939 return Error(DirectiveID.
getLoc(),
"'.att_syntax noprefix' is not "
4940 "supported: registers must have a "
4941 "'%' prefix in .att_syntax");
4943 getParser().setAssemblerDialect(0);
4946 getParser().setAssemblerDialect(1);
4951 return Error(DirectiveID.
getLoc(),
"'.intel_syntax prefix' is not "
4952 "supported: registers must not have "
4953 "a '%' prefix in .intel_syntax");
4956 }
else if (IDVal ==
".nops")
4957 return parseDirectiveNops(DirectiveID.
getLoc());
4958 else if (IDVal ==
".even")
4959 return parseDirectiveEven(DirectiveID.
getLoc());
4960 else if (IDVal ==
".cv_fpo_proc")
4961 return parseDirectiveFPOProc(DirectiveID.
getLoc());
4962 else if (IDVal ==
".cv_fpo_setframe")
4963 return parseDirectiveFPOSetFrame(DirectiveID.
getLoc());
4964 else if (IDVal ==
".cv_fpo_pushreg")
4965 return parseDirectiveFPOPushReg(DirectiveID.
getLoc());
4966 else if (IDVal ==
".cv_fpo_stackalloc")
4967 return parseDirectiveFPOStackAlloc(DirectiveID.
getLoc());
4968 else if (IDVal ==
".cv_fpo_stackalign")
4969 return parseDirectiveFPOStackAlign(DirectiveID.
getLoc());
4970 else if (IDVal ==
".cv_fpo_endprologue")
4971 return parseDirectiveFPOEndPrologue(DirectiveID.
getLoc());
4972 else if (IDVal ==
".cv_fpo_endproc")
4973 return parseDirectiveFPOEndProc(DirectiveID.
getLoc());
4974 else if (IDVal ==
".seh_pushreg")
4975 return parseDirectiveSEHPushReg(DirectiveID.
getLoc());
4976 else if (IDVal ==
".seh_push2regs")
4977 return parseDirectiveSEHPush2Regs(DirectiveID.
getLoc());
4978 else if (IDVal ==
".seh_setframe")
4979 return parseDirectiveSEHSetFrame(DirectiveID.
getLoc());
4980 else if (IDVal ==
".seh_savereg")
4981 return parseDirectiveSEHSaveReg(DirectiveID.
getLoc());
4982 else if (IDVal ==
".seh_savexmm")
4983 return parseDirectiveSEHSaveXMM(DirectiveID.
getLoc());
4984 else if (IDVal ==
".seh_pushframe")
4985 return parseDirectiveSEHPushFrame(DirectiveID.
getLoc());
4989 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
4990 parseDirectiveSEHPushReg(DirectiveID.
getLoc());
4992 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
4993 parseDirectiveSEHPush2Regs(DirectiveID.
getLoc());
4995 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
4996 parseDirectiveSEHSetFrame(DirectiveID.
getLoc());
4998 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
4999 parseDirectiveSEHSaveReg(DirectiveID.
getLoc());
5001 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
5002 parseDirectiveSEHSaveXMM(DirectiveID.
getLoc());
5004 return ensureMasmPrologContext(DirectiveID.
getLoc()) ||
5005 parseDirectiveSEHPushFrame(DirectiveID.
getLoc());
5009 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
5010 parseDirectiveSEHPushReg(DirectiveID.
getLoc());
5014 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
5015 parseDirectiveSEHPush2Regs(DirectiveID.
getLoc(),
5018 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
5019 parseDirectiveSEHSetFrame(DirectiveID.
getLoc());
5021 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
5022 parseDirectiveSEHSaveReg(DirectiveID.
getLoc());
5024 return ensureMasmEpilogContext(DirectiveID.
getLoc()) ||
5025 parseDirectiveSEHSaveXMM(DirectiveID.
getLoc());
5032bool X86AsmParser::parseDirectiveArch() {
5034 getParser().parseStringToEndOfStatement();
5040bool X86AsmParser::parseDirectiveNops(SMLoc L) {
5041 int64_t NumBytes = 0, Control = 0;
5042 SMLoc NumBytesLoc, ControlLoc;
5043 const MCSubtargetInfo& STI = getSTI();
5044 NumBytesLoc = getTok().getLoc();
5045 if (getParser().checkForValidSection() ||
5046 getParser().parseAbsoluteExpression(NumBytes))
5050 ControlLoc = getTok().getLoc();
5051 if (getParser().parseAbsoluteExpression(Control))
5054 if (getParser().parseEOL())
5057 if (NumBytes <= 0) {
5058 Error(NumBytesLoc,
"'.nops' directive with non-positive size");
5063 Error(ControlLoc,
"'.nops' directive with negative NOP size");
5068 getParser().getStreamer().emitNops(NumBytes, Control, L, STI);
5075bool X86AsmParser::parseDirectiveEven(SMLoc L) {
5079 const MCSection *
Section = getStreamer().getCurrentSectionOnly();
5081 getStreamer().initSections(getSTI());
5082 Section = getStreamer().getCurrentSectionOnly();
5084 if (
getContext().getAsmInfo().useCodeAlign(*Section))
5085 getStreamer().emitCodeAlignment(
Align(2), getSTI(), 0);
5087 getStreamer().emitValueToAlignment(
Align(2), 0, 1, 0);
5093bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
5094 MCAsmParser &Parser = getParser();
5096 if (IDVal ==
".code16") {
5098 if (!is16BitMode()) {
5099 SwitchMode(X86::Is16Bit);
5100 getTargetStreamer().emitCode16();
5102 }
else if (IDVal ==
".code16gcc") {
5106 if (!is16BitMode()) {
5107 SwitchMode(X86::Is16Bit);
5108 getTargetStreamer().emitCode16();
5110 }
else if (IDVal ==
".code32") {
5112 if (!is32BitMode()) {
5113 SwitchMode(X86::Is32Bit);
5114 getTargetStreamer().emitCode32();
5116 }
else if (IDVal ==
".code64") {
5118 if (!is64BitMode()) {
5119 SwitchMode(X86::Is64Bit);
5120 getTargetStreamer().emitCode64();
5123 Error(L,
"unknown directive " + IDVal);
5131bool X86AsmParser::parseDirectiveFPOProc(SMLoc L) {
5132 MCAsmParser &Parser = getParser();
5136 return Parser.
TokError(
"expected symbol name");
5137 if (Parser.
parseIntToken(ParamsSize,
"expected parameter byte count"))
5140 return Parser.
TokError(
"parameters size out of range");
5144 return getTargetStreamer().emitFPOProc(ProcSym, ParamsSize, L);
5148bool X86AsmParser::parseDirectiveFPOSetFrame(SMLoc L) {
5151 if (parseRegister(
Reg, DummyLoc, DummyLoc) || parseEOL())
5153 return getTargetStreamer().emitFPOSetFrame(
Reg, L);
5157bool X86AsmParser::parseDirectiveFPOPushReg(SMLoc L) {
5160 if (parseRegister(
Reg, DummyLoc, DummyLoc) || parseEOL())
5162 return getTargetStreamer().emitFPOPushReg(
Reg, L);
5166bool X86AsmParser::parseDirectiveFPOStackAlloc(SMLoc L) {
5167 MCAsmParser &Parser = getParser();
5171 return getTargetStreamer().emitFPOStackAlloc(
Offset, L);
5175bool X86AsmParser::parseDirectiveFPOStackAlign(SMLoc L) {
5176 MCAsmParser &Parser = getParser();
5180 return getTargetStreamer().emitFPOStackAlign(
Offset, L);
5184bool X86AsmParser::parseDirectiveFPOEndPrologue(SMLoc L) {
5185 MCAsmParser &Parser = getParser();
5188 return getTargetStreamer().emitFPOEndPrologue(L);
5192bool X86AsmParser::parseDirectiveFPOEndProc(SMLoc L) {
5193 MCAsmParser &Parser = getParser();
5196 return getTargetStreamer().emitFPOEndProc(L);
5199bool X86AsmParser::parseSEHRegisterNumber(
unsigned RegClassID,
5200 MCRegister &RegNo) {
5201 SMLoc startLoc = getLexer().getLoc();
5202 const MCRegisterInfo *MRI =
getContext().getRegisterInfo();
5207 if (parseRegister(RegNo, startLoc, endLoc))
5210 if (!getX86MCRegisterClass(RegClassID).
contains(RegNo)) {
5211 return Error(startLoc,
5212 "register is not supported for use with this directive");
5218 if (getParser().parseAbsoluteExpression(EncodedReg))
5223 RegNo = MCRegister();
5224 for (
MCPhysReg Reg : getX86MCRegisterClass(RegClassID)) {
5231 return Error(startLoc,
5232 "incorrect register number for use with this directive");
5239bool X86AsmParser::parseDirectiveSEHPushReg(SMLoc Loc) {
5241 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5245 return TokError(
"expected end of directive");
5248 getStreamer().emitWinCFIPushReg(
Reg, Loc);
5252bool X86AsmParser::parseDirectiveSEHPush2Regs(SMLoc Loc,
bool SwapRegs) {
5254 if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg1))
5258 return TokError(
"expected comma between registers");
5262 if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg2))
5266 return TokError(
"expected end of directive");
5272 getStreamer().emitWinCFIPush2Regs(Reg1, Reg2, Loc);
5276bool X86AsmParser::parseDirectiveSEHSetFrame(SMLoc Loc) {
5279 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5282 return TokError(
"you must specify a stack pointer offset");
5285 if (getParser().parseAbsoluteExpression(Off))
5289 return TokError(
"expected end of directive");
5292 getStreamer().emitWinCFISetFrame(
Reg, Off, Loc);
5296bool X86AsmParser::parseDirectiveSEHSaveReg(SMLoc Loc) {
5299 if (parseSEHRegisterNumber(X86::GR64RegClassID,
Reg))
5302 return TokError(
"you must specify an offset on the stack");
5305 if (getParser().parseAbsoluteExpression(Off))
5309 return TokError(
"expected end of directive");
5312 getStreamer().emitWinCFISaveReg(
Reg, Off, Loc);
5316bool X86AsmParser::parseDirectiveSEHSaveXMM(SMLoc Loc) {
5319 if (parseSEHRegisterNumber(X86::VR128XRegClassID,
Reg))
5322 return TokError(
"you must specify an offset on the stack");
5325 if (getParser().parseAbsoluteExpression(Off))
5329 return TokError(
"expected end of directive");
5332 getStreamer().emitWinCFISaveXMM(
Reg, Off, Loc);
5336bool X86AsmParser::ensureMasmPrologContext(SMLoc Loc) {
5337 if (getStreamer().isWinCFIPrologEnded()) {
5338 return Error(Loc,
"prolog directive must be used inside a prolog");
5343bool X86AsmParser::ensureMasmEpilogContext(SMLoc Loc) {
5344 if (!getStreamer().isInEpilogCFI()) {
5345 return Error(Loc,
"epilog directive must be used inside an epilog");
5350bool X86AsmParser::parseDirectiveSEHPushFrame(SMLoc Loc) {
5354 SMLoc startLoc = getLexer().getLoc();
5356 if (!getParser().parseIdentifier(CodeID)) {
5357 if (CodeID !=
"code")
5358 return Error(startLoc,
"expected @code");
5361 }
else if (getParser().isParsingMasm() &&
5363 getTok().getString().equals_insensitive(
"code")) {
5369 return TokError(
"expected end of directive");
5372 getStreamer().emitWinCFIPushFrame(Code, Loc);
5382#define GET_MATCHER_IMPLEMENTATION
5383#include "X86GenAsmMatcher.inc"
static MCRegister MatchRegisterName(StringRef Name)
static const char * getSubtargetFeatureName(uint64_t Val)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
Function Alias Analysis false
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
amode Optimize addressing mode
Value * getPointer(Value *Ptr)
static ModuleSymbolTable::Symbol getSym(DataRefImpl &Symb)
static constexpr Value * getValue(Ty &ValueOrUse)
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static bool hasFeature(StringRef Feature, const FeatureBitset &FeatureBits, ArrayRef< SubtargetFeatureKV > ProcFeatures)
static bool IsVCMP(unsigned Opcode)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
OptimizedStructLayoutField Field
static StringRef getName(Value *V)
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallString class.
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static SymbolRef::Type getType(const Symbol *Sym)
#define LLVM_C_ABI
LLVM_C_ABI is the export/visibility macro used to mark symbols declared in llvm-c as exported when bu...
static cl::opt< bool > LVIInlineAsmHardening("x86-experimental-lvi-inline-asm-hardening", cl::desc("Harden inline assembly code that may be vulnerable to Load Value" " Injection (LVI). This feature is experimental."), cl::Hidden)
static bool checkScale(unsigned Scale, StringRef &ErrMsg)
LLVM_C_ABI void LLVMInitializeX86AsmParser()
static bool convertSSEToAVX(MCInst &Inst)
static unsigned getPrefixes(OperandVector &Operands)
static bool CheckBaseRegAndIndexRegAndScale(MCRegister BaseReg, MCRegister IndexReg, unsigned Scale, bool Is64BitMode, StringRef &ErrMsg)
#define FROM_TO(FROM, TO)
uint16_t RegSizeInBits(const MCRegisterInfo &MRI, MCRegister RegNo)
static unsigned getSize(unsigned Kind)
uint64_t getZExtValue() const
Get zero extended value.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
void UnLex(AsmToken const &Token)
bool isNot(AsmToken::TokenKind K) const
Check if the current token has kind K.
LLVM_ABI SMLoc getLoc() const
int64_t getIntVal() const
bool isNot(TokenKind K) const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
bool is(TokenKind K) const
TokenKind getKind() const
LLVM_ABI SMLoc getEndLoc() const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
bool Error(SMLoc L, const Twine &Msg, SMRange Range={})
Return an error at the location L, with the message Msg.
bool parseIntToken(int64_t &V, const Twine &ErrMsg="expected integer")
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual bool isParsingMasm() const
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents.
bool parseOptionalToken(AsmToken::TokenKind T)
Attempt to parse and consume token, returning true on success.
virtual bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc, AsmTypeInfo *TypeInfo=nullptr)=0
Parse a primary expression.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
bool TokError(const Twine &Msg, SMRange Range={})
Report an error at the current lexer location.
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
virtual bool lookUpType(StringRef Name, AsmTypeInfo &Info) const
virtual bool parseAbsoluteExpression(int64_t &Res)=0
Parse an expression which must evaluate to an absolute value.
virtual bool lookUpField(StringRef Name, AsmFieldInfo &Info) const
bool parseTokenLoc(SMLoc &Loc)
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
@ SymbolRef
References to labels and assigned expressions.
Instances of this class represent a single low-level machine instruction.
unsigned getNumOperands() const
unsigned getFlags() const
unsigned getOpcode() const
void setFlags(unsigned F)
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
const MCOperand & getOperand(unsigned i) const
bool mayLoad() const
Return true if this instruction could possibly read memory.
bool isCall() const
Return true if the instruction is a call.
bool isTerminator() const
Returns true if this instruction part of the terminator for a basic block.
static MCOperand createImm(int64_t Val)
MCRegister getReg() const
Returns the register number.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
uint16_t getEncodingValue(MCRegister Reg) const
Returns the encoding for Reg.
Wrapper class representing physical registers. Should be passed by value.
static constexpr unsigned NoRegister
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
const FeatureBitset & getFeatureBits() const
const FeatureBitset & ToggleFeature(uint64_t FB)
Toggle a feature and return the re-computed feature bits.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
bool isUndefined() const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
StringRef getName() const
getName - Get the symbol name.
bool isVariable() const
isVariable - Check if this is a variable symbol.
const MCExpr * getVariableValue() const
Get the expression of the variable symbol.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
static constexpr StatusTy Failure
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
constexpr unsigned id() const
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
constexpr bool isValid() const
void push_back(const T &Elt)
Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
static constexpr size_t npos
bool consume_back(StringRef Suffix)
Returns true if this StringRef has the given suffix and removes that suffix.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
LLVM_ABI std::string upper() const
Convert the given ASCII string to uppercase.
char back() const
Get the last character in the string.
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
constexpr size_t size() const
Get the string size.
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
LLVM_ABI std::string lower() const
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
bool consume_front(char Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
StringRef drop_back(size_t N=1) const
Return a StringRef equal to 'this' but with the last N elements dropped.
bool equals_insensitive(StringRef RHS) const
Check for string equality, ignoring case.
static const char * getRegisterName(MCRegister Reg)
static const X86MCExpr * create(MCRegister Reg, MCContext &Ctx)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
std::variant< std::monostate, Loc::Single, Loc::Multi, Loc::MMI, Loc::EntryValue > Variant
Alias for the std::variant specialization base class of DbgVariable.
@ CE
Windows NT (Windows on ARM)
@ X86
Windows x64, Windows Itanium (IA-64)
bool isX86_64NonExtLowByteReg(MCRegister Reg)
@ EVEX
EVEX - Specifies that this instruction use EVEX form which provides syntax support up to 32 512-bit r...
@ VEX
VEX - encoding using 0xC4/0xC5.
@ XOP
XOP - Opcode prefix used by XOP instructions.
@ ExplicitVEXPrefix
For instructions that use VEX encoding only when {vex}, {vex2} or {vex3} is present.
bool canUseApxExtendedReg(const MCInstrDesc &Desc)
bool isX86_64ExtendedReg(MCRegister Reg)
bool isApxExtendedReg(MCRegister Reg)
void emitInstruction(MCObjectStreamer &, const MCInst &Inst, const MCSubtargetInfo &STI)
bool optimizeShiftRotateWithImmediateOne(MCInst &MI)
bool optimizeInstFromVEX3ToVEX2(MCInst &MI, const MCInstrDesc &Desc)
NodeAddr< CodeNode * > Code
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
MCRegister getX86SubSuperRegister(MCRegister Reg, unsigned Size, bool High=false)
Target & getTheX86_32Target()
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
Target & getTheX86_64Target()
StringRef toStringRef(bool B)
Construct a string ref from a boolean.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
bool isKind(IdKind kind) const
SmallVectorImpl< AsmRewrite > * AsmRewrites
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
X86Operand - Instances of this class represent a parsed X86 machine instruction.
SMLoc getStartLoc() const override
getStartLoc - Get the location of the first token of this operand.
bool isImm() const override
isImm - Is this an immediate operand?
static std::unique_ptr< X86Operand > CreateImm(const MCExpr *Val, SMLoc StartLoc, SMLoc EndLoc, StringRef SymName=StringRef(), void *OpDecl=nullptr, bool GlobalRef=true)
static std::unique_ptr< X86Operand > CreatePrefix(unsigned Prefixes, SMLoc StartLoc, SMLoc EndLoc)
static std::unique_ptr< X86Operand > CreateDXReg(SMLoc StartLoc, SMLoc EndLoc)
static std::unique_ptr< X86Operand > CreateReg(MCRegister Reg, SMLoc StartLoc, SMLoc EndLoc, bool AddressOf=false, SMLoc OffsetOfLoc=SMLoc(), StringRef SymName=StringRef(), void *OpDecl=nullptr)
SMRange getLocRange() const
getLocRange - Get the range between the first and last token of this operand.
SMLoc getEndLoc() const override
getEndLoc - Get the location of the last token of this operand.
bool isReg() const override
isReg - Is this a register operand?
bool isMem() const override
isMem - Is this a memory operand?
static std::unique_ptr< X86Operand > CreateMem(unsigned ModeSize, const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc, unsigned Size=0, StringRef SymName=StringRef(), void *OpDecl=nullptr, unsigned FrontendSize=0, bool UseUpRegs=false, bool MaybeDirectBranchDest=true)
Create an absolute memory operand.
static std::unique_ptr< X86Operand > CreateToken(StringRef Str, SMLoc Loc)
bool isMemUnsized() const
const MCExpr * getImm() const
unsigned getMemFrontendSize() const
MCRegister getReg() const override