47 "x86-experimental-lvi-inline-asm-hardening",
48 cl::desc(
"Harden inline assembly code that may be vulnerable to Load Value"
49 " Injection (LVI). This feature is experimental."),
cl::Hidden);
52 if (Scale != 1 && Scale != 2 && Scale != 4 && Scale != 8) {
53 ErrMsg =
"scale factor in address must be 1, 2, 4 or 8";
61static const char OpPrecedence[] = {
89 unsigned ForcedDataPrefix = 0;
99 VEXEncoding ForcedVEXEncoding = VEXEncoding_Default;
102 DispEncoding_Default,
107 DispEncoding ForcedDispEncoding = DispEncoding_Default;
110 bool UseApxExtendedReg =
false;
112 bool ForcedNoFlag =
false;
115 SMLoc consumeToken() {
124 "do not have a target streamer");
131 bool matchingInlineAsm,
unsigned VariantID = 0) {
134 SwitchMode(X86::Is32Bit);
136 MissingFeatures, matchingInlineAsm,
139 SwitchMode(X86::Is16Bit);
143 enum InfixCalculatorTok {
168 enum IntelOperatorKind {
175 enum MasmOperatorKind {
182 class InfixCalculator {
183 typedef std::pair< InfixCalculatorTok, int64_t > ICToken;
187 bool isUnaryOperator(InfixCalculatorTok
Op)
const {
188 return Op == IC_NEG ||
Op == IC_NOT;
192 int64_t popOperand() {
193 assert (!PostfixStack.
empty() &&
"Poped an empty stack!");
195 if (!(
Op.first == IC_IMM ||
Op.first == IC_REGISTER))
199 void pushOperand(InfixCalculatorTok
Op, int64_t Val = 0) {
200 assert ((
Op == IC_IMM ||
Op == IC_REGISTER) &&
201 "Unexpected operand!");
205 void popOperator() { InfixOperatorStack.
pop_back(); }
206 void pushOperator(InfixCalculatorTok
Op) {
208 if (InfixOperatorStack.
empty()) {
216 unsigned Idx = InfixOperatorStack.
size() - 1;
217 InfixCalculatorTok StackOp = InfixOperatorStack[
Idx];
218 if (OpPrecedence[
Op] > OpPrecedence[StackOp] || StackOp == IC_LPAREN) {
225 unsigned ParenCount = 0;
228 if (InfixOperatorStack.
empty())
231 Idx = InfixOperatorStack.
size() - 1;
232 StackOp = InfixOperatorStack[
Idx];
233 if (!(OpPrecedence[StackOp] >= OpPrecedence[
Op] || ParenCount))
238 if (!ParenCount && StackOp == IC_LPAREN)
241 if (StackOp == IC_RPAREN) {
244 }
else if (StackOp == IC_LPAREN) {
249 PostfixStack.
push_back(std::make_pair(StackOp, 0));
258 while (!InfixOperatorStack.
empty()) {
259 InfixCalculatorTok StackOp = InfixOperatorStack.
pop_back_val();
260 if (StackOp != IC_LPAREN && StackOp != IC_RPAREN)
261 PostfixStack.
push_back(std::make_pair(StackOp, 0));
264 if (PostfixStack.
empty())
268 for (
const ICToken &
Op : PostfixStack) {
269 if (
Op.first == IC_IMM ||
Op.first == IC_REGISTER) {
271 }
else if (isUnaryOperator(
Op.first)) {
272 assert (OperandStack.
size() > 0 &&
"Too few operands.");
274 assert (Operand.first == IC_IMM &&
275 "Unary operation with a register!");
281 OperandStack.
push_back(std::make_pair(IC_IMM, -Operand.second));
284 OperandStack.
push_back(std::make_pair(IC_IMM, ~Operand.second));
288 assert (OperandStack.
size() > 1 &&
"Too few operands.");
297 Val = Op1.second + Op2.second;
298 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
301 Val = Op1.second - Op2.second;
302 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
305 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
306 "Multiply operation with an immediate and a register!");
307 Val = Op1.second * Op2.second;
308 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
311 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
312 "Divide operation with an immediate and a register!");
313 assert (Op2.second != 0 &&
"Division by zero!");
314 Val = Op1.second / Op2.second;
315 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
318 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
319 "Modulo operation with an immediate and a register!");
320 Val = Op1.second % Op2.second;
321 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
324 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
325 "Or operation with an immediate and a register!");
326 Val = Op1.second | Op2.second;
327 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
330 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
331 "Xor operation with an immediate and a register!");
332 Val = Op1.second ^ Op2.second;
333 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
336 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
337 "And operation with an immediate and a register!");
338 Val = Op1.second & Op2.second;
339 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
342 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
343 "Left shift operation with an immediate and a register!");
344 Val = Op1.second << Op2.second;
345 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
348 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
349 "Right shift operation with an immediate and a register!");
350 Val = Op1.second >> Op2.second;
351 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
354 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
355 "Equals operation with an immediate and a register!");
356 Val = (Op1.second == Op2.second) ? -1 : 0;
357 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
360 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
361 "Not-equals operation with an immediate and a register!");
362 Val = (Op1.second != Op2.second) ? -1 : 0;
363 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
366 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
367 "Less-than operation with an immediate and a register!");
368 Val = (Op1.second < Op2.second) ? -1 : 0;
369 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
372 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
373 "Less-than-or-equal operation with an immediate and a "
375 Val = (Op1.second <= Op2.second) ? -1 : 0;
376 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
379 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
380 "Greater-than operation with an immediate and a register!");
381 Val = (Op1.second > Op2.second) ? -1 : 0;
382 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
385 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
386 "Greater-than-or-equal operation with an immediate and a "
388 Val = (Op1.second >= Op2.second) ? -1 : 0;
389 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
394 assert (OperandStack.
size() == 1 &&
"Expected a single result.");
399 enum IntelExprState {
429 class IntelExprStateMachine {
430 IntelExprState State = IES_INIT, PrevState = IES_ERROR;
431 unsigned BaseReg = 0, IndexReg = 0, TmpReg = 0, Scale = 0;
438 bool MemExpr =
false;
439 bool BracketUsed =
false;
440 bool OffsetOperator =
false;
441 bool AttachToOperandIdx =
false;
443 SMLoc OffsetOperatorLoc;
448 ErrMsg =
"cannot use more than one symbol in memory operand";
457 IntelExprStateMachine() =
default;
459 void addImm(int64_t imm) {
Imm += imm; }
460 short getBracCount()
const {
return BracCount; }
461 bool isMemExpr()
const {
return MemExpr; }
462 bool isBracketUsed()
const {
return BracketUsed; }
463 bool isOffsetOperator()
const {
return OffsetOperator; }
464 SMLoc getOffsetLoc()
const {
return OffsetOperatorLoc; }
465 unsigned getBaseReg()
const {
return BaseReg; }
466 unsigned getIndexReg()
const {
return IndexReg; }
467 unsigned getScale()
const {
return Scale; }
469 StringRef getSymName()
const {
return SymName; }
472 unsigned getElementSize()
const {
return CurType.
ElementSize; }
473 unsigned getLength()
const {
return CurType.
Length; }
474 int64_t getImm() {
return Imm + IC.execute(); }
475 bool isValidEndState()
const {
476 return State == IES_RBRAC || State == IES_INTEGER;
483 void setAppendAfterOperand() { AttachToOperandIdx =
true; }
485 bool isPIC()
const {
return IsPIC; }
486 void setPIC() { IsPIC =
true; }
488 bool hadError()
const {
return State == IES_ERROR; }
494 if (IsPIC && AttachToOperandIdx)
495 ErrMsg =
"Don't use 2 or more regs for mem offset in PIC model!";
497 ErrMsg =
"BaseReg/IndexReg already set!";
502 IntelExprState CurrState = State;
511 IC.pushOperator(IC_OR);
514 PrevState = CurrState;
517 IntelExprState CurrState = State;
526 IC.pushOperator(IC_XOR);
529 PrevState = CurrState;
532 IntelExprState CurrState = State;
541 IC.pushOperator(IC_AND);
544 PrevState = CurrState;
547 IntelExprState CurrState = State;
556 IC.pushOperator(IC_EQ);
559 PrevState = CurrState;
562 IntelExprState CurrState = State;
571 IC.pushOperator(IC_NE);
574 PrevState = CurrState;
577 IntelExprState CurrState = State;
586 IC.pushOperator(IC_LT);
589 PrevState = CurrState;
592 IntelExprState CurrState = State;
601 IC.pushOperator(IC_LE);
604 PrevState = CurrState;
607 IntelExprState CurrState = State;
616 IC.pushOperator(IC_GT);
619 PrevState = CurrState;
622 IntelExprState CurrState = State;
631 IC.pushOperator(IC_GE);
634 PrevState = CurrState;
637 IntelExprState CurrState = State;
646 IC.pushOperator(IC_LSHIFT);
649 PrevState = CurrState;
652 IntelExprState CurrState = State;
661 IC.pushOperator(IC_RSHIFT);
664 PrevState = CurrState;
667 IntelExprState CurrState = State;
677 IC.pushOperator(IC_PLUS);
678 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
685 return regsUseUpError(ErrMsg);
692 PrevState = CurrState;
696 IntelExprState CurrState = State;
727 if (CurrState == IES_REGISTER || CurrState == IES_RPAREN ||
728 CurrState == IES_INTEGER || CurrState == IES_RBRAC ||
729 CurrState == IES_OFFSET)
730 IC.pushOperator(IC_MINUS);
731 else if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
733 ErrMsg =
"Scale can't be negative";
736 IC.pushOperator(IC_NEG);
737 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
744 return regsUseUpError(ErrMsg);
751 PrevState = CurrState;
755 IntelExprState CurrState = State;
781 IC.pushOperator(IC_NOT);
784 PrevState = CurrState;
786 bool onRegister(
unsigned Reg,
StringRef &ErrMsg) {
787 IntelExprState CurrState = State;
795 State = IES_REGISTER;
797 IC.pushOperand(IC_REGISTER);
801 if (PrevState == IES_INTEGER) {
803 return regsUseUpError(ErrMsg);
804 State = IES_REGISTER;
807 Scale = IC.popOperand();
810 IC.pushOperand(IC_IMM);
817 PrevState = CurrState;
825 if (ParsingMSInlineAsm)
829 if (
auto *CE = dyn_cast<MCConstantExpr>(SymRef))
830 return onInteger(
CE->getValue(), ErrMsg);
843 if (setSymRef(SymRef, SymRefName, ErrMsg))
847 IC.pushOperand(IC_IMM);
848 if (ParsingMSInlineAsm)
855 bool onInteger(int64_t TmpInt,
StringRef &ErrMsg) {
856 IntelExprState CurrState = State;
882 if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
885 return regsUseUpError(ErrMsg);
893 IC.pushOperand(IC_IMM, TmpInt);
897 PrevState = CurrState;
909 State = IES_MULTIPLY;
910 IC.pushOperator(IC_MULTIPLY);
923 IC.pushOperator(IC_DIVIDE);
936 IC.pushOperator(IC_MOD);
952 IC.pushOperator(IC_PLUS);
958 assert(!BracCount &&
"BracCount should be zero on parsing's start");
968 IntelExprState CurrState = State;
977 if (BracCount-- != 1) {
978 ErrMsg =
"unexpected bracket encountered";
982 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
989 return regsUseUpError(ErrMsg);
996 PrevState = CurrState;
1000 IntelExprState CurrState = State;
1026 IC.pushOperator(IC_LPAREN);
1029 PrevState = CurrState;
1043 IC.pushOperator(IC_RPAREN);
1049 bool ParsingMSInlineAsm,
StringRef &ErrMsg) {
1053 ErrMsg =
"unexpected offset operator expression";
1058 if (setSymRef(Val,
ID, ErrMsg))
1060 OffsetOperator =
true;
1061 OffsetOperatorLoc = OffsetLoc;
1065 IC.pushOperand(IC_IMM);
1066 if (ParsingMSInlineAsm) {
1089 bool MatchingInlineAsm =
false) {
1091 if (MatchingInlineAsm) {
1092 if (!
getLexer().isAtStartOfStatement())
1096 return Parser.
Error(L, Msg, Range);
1102 bool RestoreOnFailure);
1104 std::unique_ptr<X86Operand> DefaultMemSIOperand(
SMLoc Loc);
1105 std::unique_ptr<X86Operand> DefaultMemDIOperand(
SMLoc Loc);
1106 bool IsSIReg(
unsigned Reg);
1107 unsigned GetSIDIForRegClass(
unsigned RegClassID,
unsigned Reg,
bool IsSIReg);
1110 std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
1111 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst);
1119 bool ParseIntelDotOperator(IntelExprStateMachine &SM,
SMLoc &
End);
1121 unsigned ParseIntelInlineAsmOperator(
unsigned OpKind);
1123 bool ParseMasmOperator(
unsigned OpKind, int64_t &Val);
1126 bool ParseIntelNamedOperator(
StringRef Name, IntelExprStateMachine &SM,
1128 bool ParseMasmNamedOperator(
StringRef Name, IntelExprStateMachine &SM,
1130 void RewriteIntelExpression(IntelExprStateMachine &SM,
SMLoc Start,
1132 bool ParseIntelExpression(IntelExprStateMachine &SM,
SMLoc &
End);
1133 bool ParseIntelInlineAsmIdentifier(
const MCExpr *&Val,
StringRef &Identifier,
1135 bool IsUnevaluatedOperand,
SMLoc &
End,
1136 bool IsParsingOffsetOperator =
false);
1138 IntelExprStateMachine &SM);
1140 bool ParseMemOperand(
unsigned SegReg,
const MCExpr *Disp,
SMLoc StartLoc,
1145 bool ParseIntelMemoryOperandSize(
unsigned &
Size);
1146 bool CreateMemForMSInlineAsm(
unsigned SegReg,
const MCExpr *Disp,
1147 unsigned BaseReg,
unsigned IndexReg,
1148 unsigned Scale,
bool NonAbsMem,
SMLoc Start,
1153 bool parseDirectiveArch();
1154 bool parseDirectiveNops(
SMLoc L);
1155 bool parseDirectiveEven(
SMLoc L);
1159 bool parseDirectiveFPOProc(
SMLoc L);
1160 bool parseDirectiveFPOSetFrame(
SMLoc L);
1161 bool parseDirectiveFPOPushReg(
SMLoc L);
1162 bool parseDirectiveFPOStackAlloc(
SMLoc L);
1163 bool parseDirectiveFPOStackAlign(
SMLoc L);
1164 bool parseDirectiveFPOEndPrologue(
SMLoc L);
1165 bool parseDirectiveFPOEndProc(
SMLoc L);
1168 bool parseSEHRegisterNumber(
unsigned RegClassID,
MCRegister &RegNo);
1169 bool parseDirectiveSEHPushReg(
SMLoc);
1170 bool parseDirectiveSEHSetFrame(
SMLoc);
1171 bool parseDirectiveSEHSaveReg(
SMLoc);
1172 bool parseDirectiveSEHSaveXMM(
SMLoc);
1173 bool parseDirectiveSEHPushFrame(
SMLoc);
1181 void emitWarningForSpecialLVIInstruction(
SMLoc Loc);
1192 bool MatchingInlineAsm)
override;
1198 bool MatchingInlineAsm);
1200 bool MatchAndEmitATTInstruction(
SMLoc IDLoc,
unsigned &Opcode,
1203 bool MatchingInlineAsm);
1205 bool MatchAndEmitIntelInstruction(
SMLoc IDLoc,
unsigned &Opcode,
1208 bool MatchingInlineAsm);
1217 bool ParseZ(std::unique_ptr<X86Operand> &Z,
const SMLoc &StartLoc);
1219 bool is64BitMode()
const {
1223 bool is32BitMode()
const {
1227 bool is16BitMode()
const {
1231 void SwitchMode(
unsigned mode) {
1233 FeatureBitset AllModes({X86::Is64Bit, X86::Is32Bit, X86::Is16Bit});
1242 unsigned getPointerWidth() {
1243 if (is16BitMode())
return 16;
1244 if (is32BitMode())
return 32;
1245 if (is64BitMode())
return 64;
1249 bool isParsingIntelSyntax() {
1256#define GET_ASSEMBLER_HEADER
1257#include "X86GenAsmMatcher.inc"
1262 enum X86MatchResultTy {
1264#define GET_OPERAND_DIAGNOSTIC_TYPES
1265#include "X86GenAsmMatcher.inc"
1281 SMLoc &EndLoc)
override;
1292#define GET_REGISTER_MATCHER
1293#define GET_SUBTARGET_FEATURE_NAME
1294#include "X86GenAsmMatcher.inc"
1297 unsigned Scale,
bool Is64BitMode,
1304 !(BaseReg == X86::RIP || BaseReg == X86::EIP ||
1305 X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg) ||
1306 X86MCRegisterClasses[X86::GR32RegClassID].
contains(BaseReg) ||
1307 X86MCRegisterClasses[X86::GR64RegClassID].
contains(BaseReg))) {
1308 ErrMsg =
"invalid base+index expression";
1312 if (IndexReg != 0 &&
1313 !(IndexReg == X86::EIZ || IndexReg == X86::RIZ ||
1314 X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg) ||
1315 X86MCRegisterClasses[X86::GR32RegClassID].
contains(IndexReg) ||
1316 X86MCRegisterClasses[X86::GR64RegClassID].
contains(IndexReg) ||
1317 X86MCRegisterClasses[X86::VR128XRegClassID].
contains(IndexReg) ||
1318 X86MCRegisterClasses[X86::VR256XRegClassID].
contains(IndexReg) ||
1319 X86MCRegisterClasses[X86::VR512RegClassID].
contains(IndexReg))) {
1320 ErrMsg =
"invalid base+index expression";
1324 if (((BaseReg == X86::RIP || BaseReg == X86::EIP) && IndexReg != 0) ||
1325 IndexReg == X86::EIP || IndexReg == X86::RIP ||
1326 IndexReg == X86::ESP || IndexReg == X86::RSP) {
1327 ErrMsg =
"invalid base+index expression";
1333 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg) &&
1334 (Is64BitMode || (BaseReg != X86::BX && BaseReg != X86::BP &&
1335 BaseReg != X86::SI && BaseReg != X86::DI))) {
1336 ErrMsg =
"invalid 16-bit base register";
1341 X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg)) {
1342 ErrMsg =
"16-bit memory operand may not include only index register";
1346 if (BaseReg != 0 && IndexReg != 0) {
1347 if (X86MCRegisterClasses[X86::GR64RegClassID].
contains(BaseReg) &&
1348 (X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg) ||
1349 X86MCRegisterClasses[X86::GR32RegClassID].
contains(IndexReg) ||
1350 IndexReg == X86::EIZ)) {
1351 ErrMsg =
"base register is 64-bit, but index register is not";
1354 if (X86MCRegisterClasses[X86::GR32RegClassID].
contains(BaseReg) &&
1355 (X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg) ||
1356 X86MCRegisterClasses[X86::GR64RegClassID].
contains(IndexReg) ||
1357 IndexReg == X86::RIZ)) {
1358 ErrMsg =
"base register is 32-bit, but index register is not";
1361 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg)) {
1362 if (X86MCRegisterClasses[X86::GR32RegClassID].
contains(IndexReg) ||
1363 X86MCRegisterClasses[X86::GR64RegClassID].
contains(IndexReg)) {
1364 ErrMsg =
"base register is 16-bit, but index register is not";
1367 if ((BaseReg != X86::BX && BaseReg != X86::BP) ||
1368 (IndexReg != X86::SI && IndexReg != X86::DI)) {
1369 ErrMsg =
"invalid 16-bit base/index register combination";
1376 if (!Is64BitMode && BaseReg != 0 &&
1377 (BaseReg == X86::RIP || BaseReg == X86::EIP)) {
1378 ErrMsg =
"IP-relative addressing requires 64-bit mode";
1399 if (isParsingMSInlineAsm() && isParsingIntelSyntax() &&
1400 (RegNo == X86::EFLAGS || RegNo == X86::MXCSR))
1403 if (!is64BitMode()) {
1407 if (RegNo == X86::RIZ || RegNo == X86::RIP ||
1408 X86MCRegisterClasses[X86::GR64RegClassID].
contains(RegNo) ||
1411 return Error(StartLoc,
1412 "register %" +
RegName +
" is only available in 64-bit mode",
1418 UseApxExtendedReg =
true;
1422 if (RegNo == 0 &&
RegName.starts_with(
"db")) {
1481 if (isParsingIntelSyntax())
1483 return Error(StartLoc,
"invalid register name",
SMRange(StartLoc, EndLoc));
1489 SMLoc &EndLoc,
bool RestoreOnFailure) {
1495 auto OnFailure = [RestoreOnFailure, &Lexer, &Tokens]() {
1496 if (RestoreOnFailure) {
1497 while (!Tokens.
empty()) {
1504 StartLoc = PercentTok.
getLoc();
1518 if (isParsingIntelSyntax())
return true;
1519 return Error(StartLoc,
"invalid register name",
1523 if (MatchRegisterByName(RegNo, Tok.
getString(), StartLoc, EndLoc)) {
1529 if (RegNo == X86::ST0) {
1543 return Error(IntTok.
getLoc(),
"expected stack index");
1546 case 0: RegNo = X86::ST0;
break;
1547 case 1: RegNo = X86::ST1;
break;
1548 case 2: RegNo = X86::ST2;
break;
1549 case 3: RegNo = X86::ST3;
break;
1550 case 4: RegNo = X86::ST4;
break;
1551 case 5: RegNo = X86::ST5;
break;
1552 case 6: RegNo = X86::ST6;
break;
1553 case 7: RegNo = X86::ST7;
break;
1556 return Error(IntTok.
getLoc(),
"invalid stack index");
1576 if (isParsingIntelSyntax())
return true;
1577 return Error(StartLoc,
"invalid register name",
1587 return ParseRegister(Reg, StartLoc, EndLoc,
false);
1592 bool Result = ParseRegister(Reg, StartLoc, EndLoc,
true);
1593 bool PendingErrors = getParser().hasPendingError();
1594 getParser().clearPendingErrors();
1602std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(
SMLoc Loc) {
1603 bool Parse32 = is32BitMode() || Code16GCC;
1604 unsigned Basereg = is64BitMode() ? X86::RSI : (Parse32 ? X86::ESI : X86::SI);
1611std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand(
SMLoc Loc) {
1612 bool Parse32 = is32BitMode() || Code16GCC;
1613 unsigned Basereg = is64BitMode() ? X86::RDI : (Parse32 ? X86::EDI : X86::DI);
1620bool X86AsmParser::IsSIReg(
unsigned Reg) {
1634unsigned X86AsmParser::GetSIDIForRegClass(
unsigned RegClassID,
unsigned Reg,
1636 switch (RegClassID) {
1638 case X86::GR64RegClassID:
1639 return IsSIReg ? X86::RSI : X86::RDI;
1640 case X86::GR32RegClassID:
1641 return IsSIReg ? X86::ESI : X86::EDI;
1642 case X86::GR16RegClassID:
1643 return IsSIReg ? X86::SI : X86::DI;
1647void X86AsmParser::AddDefaultSrcDestOperands(
1649 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst) {
1650 if (isParsingIntelSyntax()) {
1651 Operands.push_back(std::move(Dst));
1652 Operands.push_back(std::move(Src));
1655 Operands.push_back(std::move(Src));
1656 Operands.push_back(std::move(Dst));
1660bool X86AsmParser::VerifyAndAdjustOperands(
OperandVector &OrigOperands,
1663 if (OrigOperands.
size() > 1) {
1666 "Operand size mismatch");
1670 int RegClassID = -1;
1671 for (
unsigned int i = 0; i < FinalOperands.
size(); ++i) {
1675 if (FinalOp.
isReg() &&
1680 if (FinalOp.
isMem()) {
1682 if (!OrigOp.
isMem())
1691 if (RegClassID != -1 &&
1692 !X86MCRegisterClasses[RegClassID].
contains(OrigReg)) {
1694 "mismatching source and destination index registers");
1697 if (X86MCRegisterClasses[X86::GR64RegClassID].
contains(OrigReg))
1698 RegClassID = X86::GR64RegClassID;
1699 else if (X86MCRegisterClasses[X86::GR32RegClassID].
contains(OrigReg))
1700 RegClassID = X86::GR32RegClassID;
1701 else if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(OrigReg))
1702 RegClassID = X86::GR16RegClassID;
1708 bool IsSI = IsSIReg(FinalReg);
1709 FinalReg = GetSIDIForRegClass(RegClassID, FinalReg, IsSI);
1711 if (FinalReg != OrigReg) {
1712 std::string
RegName = IsSI ?
"ES:(R|E)SI" :
"ES:(R|E)DI";
1715 "memory operand is only for determining the size, " +
RegName +
1716 " will be used for the location"));
1727 for (
auto &WarningMsg : Warnings) {
1728 Warning(WarningMsg.first, WarningMsg.second);
1732 for (
unsigned int i = 0; i < FinalOperands.
size(); ++i)
1736 for (
auto &
Op : FinalOperands)
1743 if (isParsingIntelSyntax())
1749bool X86AsmParser::CreateMemForMSInlineAsm(
unsigned SegReg,
const MCExpr *Disp,
1750 unsigned BaseReg,
unsigned IndexReg,
1751 unsigned Scale,
bool NonAbsMem,
1769 unsigned FrontendSize = 0;
1770 void *Decl =
nullptr;
1771 bool IsGlobalLV =
false;
1774 FrontendSize =
Info.Var.Type * 8;
1775 Decl =
Info.Var.Decl;
1776 IsGlobalLV =
Info.Var.IsGlobalLV;
1781 if (BaseReg || IndexReg) {
1783 End,
Size, Identifier, Decl, 0,
1784 BaseReg && IndexReg));
1791 getPointerWidth(), SegReg, Disp, BaseReg, IndexReg, Scale, Start,
End,
1793 X86::RIP, Identifier, Decl, FrontendSize));
1801 IntelExprStateMachine &SM,
1806 !getParser().isParsingMasm())
1808 if (
Name.equals_insensitive(
"not")) {
1810 }
else if (
Name.equals_insensitive(
"or")) {
1812 }
else if (
Name.equals_insensitive(
"shl")) {
1814 }
else if (
Name.equals_insensitive(
"shr")) {
1816 }
else if (
Name.equals_insensitive(
"xor")) {
1818 }
else if (
Name.equals_insensitive(
"and")) {
1820 }
else if (
Name.equals_insensitive(
"mod")) {
1822 }
else if (
Name.equals_insensitive(
"offset")) {
1823 SMLoc OffsetLoc = getTok().getLoc();
1824 const MCExpr *Val =
nullptr;
1827 ParseError = ParseIntelOffsetOperator(Val,
ID, Info,
End);
1832 SM.onOffset(Val, OffsetLoc,
ID, Info, isParsingMSInlineAsm(), ErrMsg);
1838 if (!
Name.equals_insensitive(
"offset"))
1839 End = consumeToken();
1843 IntelExprStateMachine &SM,
1845 if (
Name.equals_insensitive(
"eq")) {
1847 }
else if (
Name.equals_insensitive(
"ne")) {
1849 }
else if (
Name.equals_insensitive(
"lt")) {
1851 }
else if (
Name.equals_insensitive(
"le")) {
1853 }
else if (
Name.equals_insensitive(
"gt")) {
1855 }
else if (
Name.equals_insensitive(
"ge")) {
1860 End = consumeToken();
1867 IntelExprStateMachine &SM) {
1871 SM.setAppendAfterOperand();
1874bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM,
SMLoc &
End) {
1880 if (getContext().getObjectFileInfo()->isPositionIndependent())
1889 bool UpdateLocLex =
true;
1894 if ((
Done = SM.isValidEndState()))
1896 return Error(Tok.
getLoc(),
"unknown token in expression");
1898 return Error(getLexer().getErrLoc(), getLexer().getErr());
1905 UpdateLocLex =
false;
1906 if (ParseIntelDotOperator(SM,
End))
1911 if ((
Done = SM.isValidEndState()))
1913 return Error(Tok.
getLoc(),
"unknown token in expression");
1917 UpdateLocLex =
false;
1918 if (ParseIntelDotOperator(SM,
End))
1923 if ((
Done = SM.isValidEndState()))
1925 return Error(Tok.
getLoc(),
"unknown token in expression");
1936 UpdateLocLex =
false;
1937 if (!Val->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
1938 return Error(ValueLoc,
"expected absolute value");
1939 if (SM.onInteger(Res, ErrMsg))
1940 return Error(ValueLoc, ErrMsg);
1949 UpdateLocLex =
false;
1951 size_t DotOffset =
Identifier.find_first_of(
'.');
1969 const AsmToken &NextTok = getLexer().peekTok();
1978 End = consumeToken();
1985 if (!ParseRegister(Reg, IdentLoc,
End,
true)) {
1986 if (SM.onRegister(Reg, ErrMsg))
1987 return Error(IdentLoc, ErrMsg);
1991 const std::pair<StringRef, StringRef> IDField =
1995 if (!
Field.empty() &&
1996 !MatchRegisterByName(Reg,
ID, IdentLoc, IDEndLoc)) {
1997 if (SM.onRegister(Reg, ErrMsg))
1998 return Error(IdentLoc, ErrMsg);
2003 return Error(FieldStartLoc,
"unknown offset");
2004 else if (SM.onPlus(ErrMsg))
2005 return Error(getTok().getLoc(), ErrMsg);
2006 else if (SM.onInteger(
Info.Offset, ErrMsg))
2007 return Error(IdentLoc, ErrMsg);
2008 SM.setTypeInfo(
Info.Type);
2010 End = consumeToken();
2016 bool ParseError =
false;
2017 if (ParseIntelNamedOperator(Identifier, SM, ParseError,
End)) {
2023 ParseMasmNamedOperator(Identifier, SM, ParseError,
End)) {
2036 if (ParseIntelDotOperator(SM,
End))
2041 if (isParsingMSInlineAsm()) {
2043 if (
unsigned OpKind = IdentifyIntelInlineAsmOperator(Identifier)) {
2044 if (int64_t Val = ParseIntelInlineAsmOperator(OpKind)) {
2045 if (SM.onInteger(Val, ErrMsg))
2046 return Error(IdentLoc, ErrMsg);
2055 return Error(IdentLoc,
"expected identifier");
2056 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
false,
End))
2058 else if (SM.onIdentifierExpr(Val, Identifier, Info, FieldInfo.
Type,
2060 return Error(IdentLoc, ErrMsg);
2064 if (
unsigned OpKind = IdentifyMasmOperator(Identifier)) {
2066 if (ParseMasmOperator(OpKind, Val))
2068 if (SM.onInteger(Val, ErrMsg))
2069 return Error(IdentLoc, ErrMsg);
2072 if (!getParser().lookUpType(Identifier, FieldInfo.
Type)) {
2078 getParser().parseIdentifier(Identifier);
2082 if (getParser().lookUpField(FieldInfo.
Type.
Name, Identifier,
2086 return Error(IdentLoc,
"Unable to lookup field reference!",
2092 if (SM.onInteger(FieldInfo.
Offset, ErrMsg))
2093 return Error(IdentLoc, ErrMsg);
2097 if (getParser().parsePrimaryExpr(Val,
End, &FieldInfo.
Type)) {
2098 return Error(Tok.
getLoc(),
"Unexpected identifier!");
2099 }
else if (SM.onIdentifierExpr(Val, Identifier, Info, FieldInfo.
Type,
2101 return Error(IdentLoc, ErrMsg);
2107 SMLoc Loc = getTok().getLoc();
2108 int64_t
IntVal = getTok().getIntVal();
2109 End = consumeToken();
2110 UpdateLocLex =
false;
2113 if (IDVal ==
"f" || IDVal ==
"b") {
2115 getContext().getDirectionalLocalSymbol(IntVal, IDVal ==
"b");
2119 if (IDVal ==
"b" &&
Sym->isUndefined())
2120 return Error(Loc,
"invalid reference to undefined symbol");
2124 if (SM.onIdentifierExpr(Val, Identifier, Info,
Type,
2125 isParsingMSInlineAsm(), ErrMsg))
2126 return Error(Loc, ErrMsg);
2127 End = consumeToken();
2129 if (SM.onInteger(IntVal, ErrMsg))
2130 return Error(Loc, ErrMsg);
2133 if (SM.onInteger(IntVal, ErrMsg))
2134 return Error(Loc, ErrMsg);
2139 if (SM.onPlus(ErrMsg))
2140 return Error(getTok().getLoc(), ErrMsg);
2143 if (SM.onMinus(ErrMsg))
2144 return Error(getTok().getLoc(), ErrMsg);
2154 SM.onLShift();
break;
2156 SM.onRShift();
break;
2159 return Error(Tok.
getLoc(),
"unexpected bracket encountered");
2160 tryParseOperandIdx(PrevTK, SM);
2163 if (SM.onRBrac(ErrMsg)) {
2171 return Error(Tok.
getLoc(),
"unknown token in expression");
2173 if (!
Done && UpdateLocLex)
2174 End = consumeToken();
2181void X86AsmParser::RewriteIntelExpression(IntelExprStateMachine &SM,
2184 unsigned ExprLen =
End.getPointer() - Start.getPointer();
2186 if (SM.getSym() && !SM.isOffsetOperator()) {
2188 if (
unsigned Len = SymName.
data() - Start.getPointer())
2191 ExprLen =
End.getPointer() - (SymName.
data() + SymName.
size());
2194 if (!(SM.getBaseReg() || SM.getIndexReg() || SM.getImm())) {
2204 if (SM.getBaseReg())
2206 if (SM.getIndexReg())
2208 if (SM.isOffsetOperator())
2209 OffsetNameStr = SM.getSymName();
2211 IntelExpr Expr(BaseRegStr, IndexRegStr, SM.getScale(), OffsetNameStr,
2212 SM.getImm(), SM.isMemExpr());
2213 InstInfo->
AsmRewrites->emplace_back(Loc, ExprLen, Expr);
2217bool X86AsmParser::ParseIntelInlineAsmIdentifier(
2219 bool IsUnevaluatedOperand,
SMLoc &
End,
bool IsParsingOffsetOperator) {
2221 assert(isParsingMSInlineAsm() &&
"Expected to be parsing inline assembly.");
2225 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);
2236 }
while (
End.getPointer() < EndPtr);
2243 "frontend claimed part of a token?");
2249 SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(),
2251 assert(InternalName.
size() &&
"We should have an internal name here.");
2254 if (!IsParsingOffsetOperator)
2262 MCSymbol *
Sym = getContext().getOrCreateSymbol(Identifier);
2273 const SMLoc consumedToken = consumeToken();
2275 return Error(Tok.
getLoc(),
"Expected an identifier after {");
2278 .
Case(
"rn", X86::STATIC_ROUNDING::TO_NEAREST_INT)
2279 .
Case(
"rd", X86::STATIC_ROUNDING::TO_NEG_INF)
2280 .
Case(
"ru", X86::STATIC_ROUNDING::TO_POS_INF)
2281 .
Case(
"rz", X86::STATIC_ROUNDING::TO_ZERO)
2284 return Error(Tok.
getLoc(),
"Invalid rounding mode.");
2287 return Error(Tok.
getLoc(),
"Expected - at this point");
2291 return Error(Tok.
getLoc(),
"Expected } at this point");
2294 const MCExpr *RndModeOp =
2302 return Error(Tok.
getLoc(),
"Expected } at this point");
2307 return Error(Tok.
getLoc(),
"unknown token in expression");
2317 return Error(Tok.
getLoc(),
"Expected { at this point");
2321 return Error(Tok.
getLoc(),
"Expected dfv at this point");
2325 return Error(Tok.
getLoc(),
"Expected = at this point");
2337 unsigned CFlags = 0;
2338 for (
unsigned I = 0;
I < 4; ++
I) {
2347 return Error(Tok.
getLoc(),
"Invalid conditional flags");
2350 return Error(Tok.
getLoc(),
"Duplicated conditional flag");
2361 }
else if (
I == 3) {
2362 return Error(Tok.
getLoc(),
"Expected } at this point");
2364 return Error(Tok.
getLoc(),
"Expected } or , at this point");
2372bool X86AsmParser::ParseIntelDotOperator(IntelExprStateMachine &SM,
2388 }
else if ((isParsingMSInlineAsm() || getParser().isParsingMasm()) &&
2391 TrailingDot = DotDispStr.
substr(DotDispStr.
size() - 1);
2394 const std::pair<StringRef, StringRef> BaseMember = DotDispStr.
split(
'.');
2396 if (getParser().lookUpField(SM.getType(), DotDispStr, Info) &&
2397 getParser().lookUpField(SM.getSymName(), DotDispStr, Info) &&
2398 getParser().lookUpField(DotDispStr, Info) &&
2400 SemaCallback->LookupInlineAsmField(
Base, Member,
Info.Offset)))
2401 return Error(Tok.
getLoc(),
"Unable to lookup field reference!");
2403 return Error(Tok.
getLoc(),
"Unexpected token type!");
2408 const char *DotExprEndLoc = DotDispStr.
data() + DotDispStr.
size();
2411 if (!TrailingDot.
empty())
2413 SM.addImm(
Info.Offset);
2414 SM.setTypeInfo(
Info.Type);
2424 SMLoc Start = Lex().getLoc();
2425 ID = getTok().getString();
2426 if (!isParsingMSInlineAsm()) {
2429 getParser().parsePrimaryExpr(Val,
End,
nullptr))
2430 return Error(Start,
"unexpected token!");
2431 }
else if (ParseIntelInlineAsmIdentifier(Val,
ID, Info,
false,
End,
true)) {
2432 return Error(Start,
"unable to lookup expression");
2434 return Error(Start,
"offset operator cannot yet handle constants");
2441unsigned X86AsmParser::IdentifyIntelInlineAsmOperator(
StringRef Name) {
2443 .
Cases(
"TYPE",
"type",IOK_TYPE)
2444 .
Cases(
"SIZE",
"size",IOK_SIZE)
2445 .
Cases(
"LENGTH",
"length",IOK_LENGTH)
2455unsigned X86AsmParser::ParseIntelInlineAsmOperator(
unsigned OpKind) {
2460 const MCExpr *Val =
nullptr;
2464 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
2469 Error(Start,
"unable to lookup expression");
2476 case IOK_LENGTH: CVal =
Info.Var.Length;
break;
2477 case IOK_SIZE: CVal =
Info.Var.Size;
break;
2478 case IOK_TYPE: CVal =
Info.Var.Type;
break;
2486unsigned X86AsmParser::IdentifyMasmOperator(
StringRef Name) {
2488 .
Case(
"type", MOK_TYPE)
2489 .
Cases(
"size",
"sizeof", MOK_SIZEOF)
2490 .
Cases(
"length",
"lengthof", MOK_LENGTHOF)
2500bool X86AsmParser::ParseMasmOperator(
unsigned OpKind, int64_t &Val) {
2506 if (OpKind == MOK_SIZEOF || OpKind == MOK_TYPE) {
2509 const AsmToken &IDTok = InParens ? getLexer().peekTok() : Parser.
getTok();
2525 IntelExprStateMachine SM;
2527 if (ParseIntelExpression(SM,
End))
2537 Val = SM.getLength();
2540 Val = SM.getElementSize();
2545 return Error(OpLoc,
"expression has unknown type",
SMRange(Start,
End));
2551bool X86AsmParser::ParseIntelMemoryOperandSize(
unsigned &
Size) {
2553 .
Cases(
"BYTE",
"byte", 8)
2554 .
Cases(
"WORD",
"word", 16)
2555 .
Cases(
"DWORD",
"dword", 32)
2556 .
Cases(
"FLOAT",
"float", 32)
2557 .
Cases(
"LONG",
"long", 32)
2558 .
Cases(
"FWORD",
"fword", 48)
2559 .
Cases(
"DOUBLE",
"double", 64)
2560 .
Cases(
"QWORD",
"qword", 64)
2561 .
Cases(
"MMWORD",
"mmword", 64)
2562 .
Cases(
"XWORD",
"xword", 80)
2563 .
Cases(
"TBYTE",
"tbyte", 80)
2564 .
Cases(
"XMMWORD",
"xmmword", 128)
2565 .
Cases(
"YMMWORD",
"ymmword", 256)
2566 .
Cases(
"ZMMWORD",
"zmmword", 512)
2571 return Error(Tok.
getLoc(),
"Expected 'PTR' or 'ptr' token!");
2584 if (ParseIntelMemoryOperandSize(
Size))
2592 return ParseRoundingModeOp(Start,
Operands);
2597 if (RegNo == X86::RIP)
2598 return Error(Start,
"rip can only be used as a base register");
2602 return Error(Start,
"expected memory operand after 'ptr', "
2603 "found register operand instead");
2608 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].
contains(RegNo))
2609 return Error(Start,
"invalid segment register");
2611 Start = Lex().getLoc();
2615 IntelExprStateMachine SM;
2616 if (ParseIntelExpression(SM,
End))
2619 if (isParsingMSInlineAsm())
2620 RewriteIntelExpression(SM, Start, Tok.
getLoc());
2622 int64_t
Imm = SM.getImm();
2623 const MCExpr *Disp = SM.getSym();
2632 if (!SM.isMemExpr() && !RegNo) {
2633 if (isParsingMSInlineAsm() && SM.isOffsetOperator()) {
2639 SM.getSymName(),
Info.Var.Decl,
2640 Info.Var.IsGlobalLV));
2650 unsigned BaseReg = SM.getBaseReg();
2651 unsigned IndexReg = SM.getIndexReg();
2652 if (IndexReg && BaseReg == X86::RIP)
2654 unsigned Scale = SM.getScale();
2656 Size = SM.getElementSize() << 3;
2658 if (Scale == 0 && BaseReg != X86::ESP && BaseReg != X86::RSP &&
2659 (IndexReg == X86::ESP || IndexReg == X86::RSP))
2665 !(X86MCRegisterClasses[X86::VR128XRegClassID].
contains(IndexReg) ||
2666 X86MCRegisterClasses[X86::VR256XRegClassID].
contains(IndexReg) ||
2667 X86MCRegisterClasses[X86::VR512RegClassID].
contains(IndexReg)) &&
2668 (X86MCRegisterClasses[X86::VR128XRegClassID].
contains(BaseReg) ||
2669 X86MCRegisterClasses[X86::VR256XRegClassID].
contains(BaseReg) ||
2670 X86MCRegisterClasses[X86::VR512RegClassID].
contains(BaseReg)))
2674 X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg))
2675 return Error(Start,
"16-bit addresses cannot have a scale");
2684 if ((BaseReg == X86::SI || BaseReg == X86::DI) &&
2685 (IndexReg == X86::BX || IndexReg == X86::BP))
2688 if ((BaseReg || IndexReg) &&
2691 return Error(Start, ErrMsg);
2692 bool IsUnconditionalBranch =
2693 Name.equals_insensitive(
"jmp") ||
Name.equals_insensitive(
"call");
2694 if (isParsingMSInlineAsm())
2695 return CreateMemForMSInlineAsm(RegNo, Disp, BaseReg, IndexReg, Scale,
2696 IsUnconditionalBranch && is64BitMode(),
2697 Start,
End,
Size, SM.getSymName(),
2702 unsigned DefaultBaseReg = X86::NoRegister;
2703 bool MaybeDirectBranchDest =
true;
2706 if (is64BitMode() && SM.getElementSize() > 0) {
2707 DefaultBaseReg = X86::RIP;
2709 if (IsUnconditionalBranch) {
2711 MaybeDirectBranchDest =
false;
2713 DefaultBaseReg = X86::RIP;
2714 }
else if (!BaseReg && !IndexReg && Disp &&
2716 if (is64BitMode()) {
2717 if (SM.getSize() == 8) {
2718 MaybeDirectBranchDest =
false;
2719 DefaultBaseReg = X86::RIP;
2722 if (SM.getSize() == 4 || SM.getSize() == 2)
2723 MaybeDirectBranchDest =
false;
2727 }
else if (IsUnconditionalBranch) {
2729 if (!PtrInOperand && SM.isOffsetOperator())
2731 Start,
"`OFFSET` operator cannot be used in an unconditional branch");
2732 if (PtrInOperand || SM.isBracketUsed())
2733 MaybeDirectBranchDest =
false;
2736 if ((BaseReg || IndexReg || RegNo || DefaultBaseReg != X86::NoRegister))
2738 getPointerWidth(), RegNo, Disp, BaseReg, IndexReg, Scale, Start,
End,
2740 0,
false, MaybeDirectBranchDest));
2745 MaybeDirectBranchDest));
2751 switch (getLexer().getKind()) {
2761 "expected immediate expression") ||
2762 getParser().parseExpression(Val,
End) ||
2763 check(isa<X86MCExpr>(Val), L,
"expected immediate expression"))
2770 return ParseRoundingModeOp(Start,
Operands);
2779 const MCExpr *Expr =
nullptr;
2785 if (
auto *RE = dyn_cast<X86MCExpr>(Expr)) {
2788 Reg = RE->getRegNo();
2791 if (Reg == X86::EIZ || Reg == X86::RIZ)
2793 Loc,
"%eiz and %riz can only be used as index registers",
2795 if (Reg == X86::RIP)
2796 return Error(Loc,
"%rip can only be used as a base register",
2803 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].
contains(Reg))
2804 return Error(Loc,
"invalid segment register");
2812 return ParseMemOperand(Reg, Expr, Loc, EndLoc,
Operands);
2842bool X86AsmParser::ParseZ(std::unique_ptr<X86Operand> &Z,
2843 const SMLoc &StartLoc) {
2849 (getLexer().getTok().getIdentifier() ==
"z")))
2854 return Error(getLexer().getLoc(),
"Expected } at this point");
2866 const SMLoc consumedToken = consumeToken();
2870 if (getLexer().getTok().getIntVal() != 1)
2871 return TokError(
"Expected 1to<NUM> at this point");
2875 return TokError(
"Expected 1to<NUM> at this point");
2878 StringRef BroadcastString = (
Prefix + getLexer().getTok().getIdentifier())
2881 return TokError(
"Expected 1to<NUM> at this point");
2882 const char *BroadcastPrimitive =
2884 .
Case(
"1to2",
"{1to2}")
2885 .
Case(
"1to4",
"{1to4}")
2886 .
Case(
"1to8",
"{1to8}")
2887 .
Case(
"1to16",
"{1to16}")
2888 .
Case(
"1to32",
"{1to32}")
2890 if (!BroadcastPrimitive)
2891 return TokError(
"Invalid memory broadcast primitive.");
2894 return TokError(
"Expected } at this point");
2905 std::unique_ptr<X86Operand>
Z;
2906 if (ParseZ(Z, consumedToken))
2912 SMLoc StartLoc =
Z ? consumeToken() : consumedToken;
2917 if (!parseRegister(RegNo, RegLoc, StartLoc) &&
2918 X86MCRegisterClasses[X86::VK1RegClassID].
contains(RegNo)) {
2919 if (RegNo == X86::K0)
2920 return Error(RegLoc,
"Register k0 can't be used as write mask");
2922 return Error(getLexer().getLoc(),
"Expected } at this point");
2928 return Error(getLexer().getLoc(),
2929 "Expected an op-mask register at this point");
2934 if (ParseZ(Z, consumeToken()) || !Z)
2935 return Error(getLexer().getLoc(),
2936 "Expected a {z} mark at this point");
2952bool X86AsmParser::ParseMemOperand(
unsigned SegReg,
const MCExpr *Disp,
2973 auto isAtMemOperand = [
this]() {
2978 auto TokCount = this->getLexer().peekTokens(Buf,
true);
2981 switch (Buf[0].getKind()) {
2988 if ((TokCount > 1) &&
2990 (Buf[0].getLoc().getPointer() + 1 == Buf[1].getLoc().getPointer()))
2992 Buf[1].getIdentifier().
size() + 1);
3003 MCSymbol *
Sym = this->getContext().getOrCreateSymbol(Id);
3004 if (
Sym->isVariable()) {
3005 auto V =
Sym->getVariableValue(
false);
3006 return isa<X86MCExpr>(V);
3014 if (!isAtMemOperand()) {
3017 assert(!isa<X86MCExpr>(Disp) &&
"Expected non-register here.");
3033 0, 0, 1, StartLoc, EndLoc));
3039 unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
3040 SMLoc BaseLoc = getLexer().getLoc();
3047 check(!isa<X86MCExpr>(E), BaseLoc,
"expected register here"))
3051 BaseReg = cast<X86MCExpr>(E)->getRegNo();
3052 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ)
3053 return Error(BaseLoc,
"eiz and riz can only be used as index registers",
3068 if (!isa<X86MCExpr>(E)) {
3072 if (!E->evaluateAsAbsolute(ScaleVal, getStreamer().getAssemblerPtr()))
3073 return Error(Loc,
"expected absolute expression");
3075 Warning(Loc,
"scale factor without index register is ignored");
3078 IndexReg = cast<X86MCExpr>(E)->getRegNo();
3080 if (BaseReg == X86::RIP)
3082 "%rip as base register can not have an index register");
3083 if (IndexReg == X86::RIP)
3084 return Error(Loc,
"%rip is not allowed as an index register");
3095 return Error(Loc,
"expected scale expression");
3098 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg) &&
3100 return Error(Loc,
"scale factor in 16-bit address must be 1");
3102 return Error(Loc, ErrMsg);
3116 if (BaseReg == X86::DX && IndexReg == 0 && Scale == 1 && SegReg == 0 &&
3117 isa<MCConstantExpr>(Disp) &&
3118 cast<MCConstantExpr>(Disp)->getValue() == 0) {
3125 return Error(BaseLoc, ErrMsg);
3132 if (BaseReg || IndexReg) {
3133 if (
auto CE = dyn_cast<MCConstantExpr>(Disp)) {
3134 auto Imm =
CE->getValue();
3135 bool Is64 = X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) ||
3136 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg);
3137 bool Is16 = X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg);
3139 if (!isInt<32>(Imm))
3140 return Error(BaseLoc,
"displacement " +
Twine(Imm) +
3141 " is not within [-2147483648, 2147483647]");
3145 " shortened to 32-bit signed " +
3146 Twine(
static_cast<int32_t
>(Imm)));
3150 " shortened to 16-bit signed " +
3151 Twine(
static_cast<int16_t
>(Imm)));
3156 if (SegReg || BaseReg || IndexReg)
3158 BaseReg, IndexReg, Scale, StartLoc,
3167bool X86AsmParser::parsePrimaryExpr(
const MCExpr *&Res,
SMLoc &EndLoc) {
3175 if (parseRegister(RegNo, StartLoc, EndLoc))
3189 ForcedVEXEncoding = VEXEncoding_Default;
3190 ForcedDispEncoding = DispEncoding_Default;
3191 UseApxExtendedReg =
false;
3192 ForcedNoFlag =
false;
3205 if (Prefix ==
"vex")
3206 ForcedVEXEncoding = VEXEncoding_VEX;
3207 else if (Prefix ==
"vex2")
3208 ForcedVEXEncoding = VEXEncoding_VEX2;
3209 else if (Prefix ==
"vex3")
3210 ForcedVEXEncoding = VEXEncoding_VEX3;
3211 else if (Prefix ==
"evex")
3212 ForcedVEXEncoding = VEXEncoding_EVEX;
3213 else if (Prefix ==
"disp8")
3214 ForcedDispEncoding = DispEncoding_Disp8;
3215 else if (Prefix ==
"disp32")
3216 ForcedDispEncoding = DispEncoding_Disp32;
3217 else if (Prefix ==
"nf")
3218 ForcedNoFlag =
true;
3220 return Error(NameLoc,
"unknown prefix");
3236 if (isParsingMSInlineAsm()) {
3237 if (
Name.equals_insensitive(
"vex"))
3238 ForcedVEXEncoding = VEXEncoding_VEX;
3239 else if (
Name.equals_insensitive(
"vex2"))
3240 ForcedVEXEncoding = VEXEncoding_VEX2;
3241 else if (
Name.equals_insensitive(
"vex3"))
3242 ForcedVEXEncoding = VEXEncoding_VEX3;
3243 else if (
Name.equals_insensitive(
"evex"))
3244 ForcedVEXEncoding = VEXEncoding_EVEX;
3246 if (ForcedVEXEncoding != VEXEncoding_Default) {
3259 if (
Name.consume_back(
".d32")) {
3260 ForcedDispEncoding = DispEncoding_Disp32;
3261 }
else if (
Name.consume_back(
".d8")) {
3262 ForcedDispEncoding = DispEncoding_Disp8;
3268 if (isParsingIntelSyntax() &&
3269 (PatchedName ==
"jmp" || PatchedName ==
"jc" || PatchedName ==
"jnc" ||
3270 PatchedName ==
"jcxz" || PatchedName ==
"jecxz" ||
3275 : NextTok ==
"short") {
3284 NextTok.
size() + 1);
3290 PatchedName !=
"setb" && PatchedName !=
"setnb")
3291 PatchedName = PatchedName.
substr(0,
Name.size()-1);
3293 unsigned ComparisonPredicate = ~0
U;
3300 bool IsVCMP = PatchedName[0] ==
'v';
3301 unsigned CCIdx =
IsVCMP ? 4 : 3;
3303 PatchedName.
slice(CCIdx, PatchedName.
size() - 2))
3305 .
Case(
"eq_oq", 0x00)
3307 .
Case(
"lt_os", 0x01)
3309 .
Case(
"le_os", 0x02)
3310 .
Case(
"unord", 0x03)
3311 .
Case(
"unord_q", 0x03)
3313 .
Case(
"neq_uq", 0x04)
3315 .
Case(
"nlt_us", 0x05)
3317 .
Case(
"nle_us", 0x06)
3319 .
Case(
"ord_q", 0x07)
3321 .
Case(
"eq_uq", 0x08)
3323 .
Case(
"nge_us", 0x09)
3325 .
Case(
"ngt_us", 0x0A)
3326 .
Case(
"false", 0x0B)
3327 .
Case(
"false_oq", 0x0B)
3328 .
Case(
"neq_oq", 0x0C)
3330 .
Case(
"ge_os", 0x0D)
3332 .
Case(
"gt_os", 0x0E)
3334 .
Case(
"true_uq", 0x0F)
3335 .
Case(
"eq_os", 0x10)
3336 .
Case(
"lt_oq", 0x11)
3337 .
Case(
"le_oq", 0x12)
3338 .
Case(
"unord_s", 0x13)
3339 .
Case(
"neq_us", 0x14)
3340 .
Case(
"nlt_uq", 0x15)
3341 .
Case(
"nle_uq", 0x16)
3342 .
Case(
"ord_s", 0x17)
3343 .
Case(
"eq_us", 0x18)
3344 .
Case(
"nge_uq", 0x19)
3345 .
Case(
"ngt_uq", 0x1A)
3346 .
Case(
"false_os", 0x1B)
3347 .
Case(
"neq_os", 0x1C)
3348 .
Case(
"ge_oq", 0x1D)
3349 .
Case(
"gt_oq", 0x1E)
3350 .
Case(
"true_us", 0x1F)
3355 PatchedName =
IsVCMP ?
"vcmpss" :
"cmpss";
3357 PatchedName =
IsVCMP ?
"vcmpsd" :
"cmpsd";
3359 PatchedName =
IsVCMP ?
"vcmpps" :
"cmpps";
3361 PatchedName =
IsVCMP ?
"vcmppd" :
"cmppd";
3363 PatchedName =
"vcmpsh";
3365 PatchedName =
"vcmpph";
3369 ComparisonPredicate =
CC;
3375 (PatchedName.
back() ==
'b' || PatchedName.
back() ==
'w' ||
3376 PatchedName.
back() ==
'd' || PatchedName.
back() ==
'q')) {
3377 unsigned SuffixSize = PatchedName.
drop_back().
back() ==
'u' ? 2 : 1;
3379 PatchedName.
slice(5, PatchedName.
size() - SuffixSize))
3389 if (
CC != ~0U && (
CC != 0 || SuffixSize == 2)) {
3390 switch (PatchedName.
back()) {
3392 case 'b': PatchedName = SuffixSize == 2 ?
"vpcmpub" :
"vpcmpb";
break;
3393 case 'w': PatchedName = SuffixSize == 2 ?
"vpcmpuw" :
"vpcmpw";
break;
3394 case 'd': PatchedName = SuffixSize == 2 ?
"vpcmpud" :
"vpcmpd";
break;
3395 case 'q': PatchedName = SuffixSize == 2 ?
"vpcmpuq" :
"vpcmpq";
break;
3398 ComparisonPredicate =
CC;
3404 (PatchedName.
back() ==
'b' || PatchedName.
back() ==
'w' ||
3405 PatchedName.
back() ==
'd' || PatchedName.
back() ==
'q')) {
3406 unsigned SuffixSize = PatchedName.
drop_back().
back() ==
'u' ? 2 : 1;
3408 PatchedName.
slice(5, PatchedName.
size() - SuffixSize))
3419 switch (PatchedName.
back()) {
3421 case 'b': PatchedName = SuffixSize == 2 ?
"vpcomub" :
"vpcomb";
break;
3422 case 'w': PatchedName = SuffixSize == 2 ?
"vpcomuw" :
"vpcomw";
break;
3423 case 'd': PatchedName = SuffixSize == 2 ?
"vpcomud" :
"vpcomd";
break;
3424 case 'q': PatchedName = SuffixSize == 2 ?
"vpcomuq" :
"vpcomq";
break;
3427 ComparisonPredicate =
CC;
3440 .
Cases(
"cs",
"ds",
"es",
"fs",
"gs",
"ss",
true)
3441 .
Cases(
"rex64",
"data32",
"data16",
"addr32",
"addr16",
true)
3442 .
Cases(
"xacquire",
"xrelease",
true)
3443 .
Cases(
"acquire",
"release", isParsingIntelSyntax())
3446 auto isLockRepeatNtPrefix = [](
StringRef N) {
3448 .
Cases(
"lock",
"rep",
"repe",
"repz",
"repne",
"repnz",
"notrack",
true)
3452 bool CurlyAsEndOfStatement =
false;
3455 while (isLockRepeatNtPrefix(
Name.lower())) {
3476 while (
Name.starts_with(
";") ||
Name.starts_with(
"\n") ||
3477 Name.starts_with(
"#") ||
Name.starts_with(
"\t") ||
3478 Name.starts_with(
"/")) {
3489 if (PatchedName ==
"data16" && is16BitMode()) {
3490 return Error(NameLoc,
"redundant data16 prefix");
3492 if (PatchedName ==
"data32") {
3494 return Error(NameLoc,
"redundant data32 prefix");
3496 return Error(NameLoc,
"'data32' is not supported in 64-bit mode");
3498 PatchedName =
"data16";
3505 if (Next ==
"callw")
3507 if (Next ==
"ljmpw")
3512 ForcedDataPrefix = X86::Is32Bit;
3520 if (ComparisonPredicate != ~0U && !isParsingIntelSyntax()) {
3522 getParser().getContext());
3527 if ((
Name.starts_with(
"ccmp") ||
Name.starts_with(
"ctest")) &&
3556 CurlyAsEndOfStatement =
3557 isParsingIntelSyntax() && isParsingMSInlineAsm() &&
3560 return TokError(
"unexpected token in argument list");
3564 if (ComparisonPredicate != ~0U && isParsingIntelSyntax()) {
3566 getParser().getContext());
3574 else if (CurlyAsEndOfStatement)
3577 getLexer().getTok().getLoc(), 0);
3584 if (IsFp &&
Operands.size() == 1) {
3586 .
Case(
"fsub",
"fsubp")
3587 .
Case(
"fdiv",
"fdivp")
3588 .
Case(
"fsubr",
"fsubrp")
3589 .
Case(
"fdivr",
"fdivrp");
3593 if ((
Name ==
"mov" ||
Name ==
"movw" ||
Name ==
"movl") &&
3601 X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(
3603 (X86MCRegisterClasses[X86::GR16RegClassID].
contains(Op1.
getReg()) ||
3604 X86MCRegisterClasses[X86::GR32RegClassID].
contains(Op1.
getReg()))) {
3606 if (
Name !=
"mov" &&
Name[3] == (is16BitMode() ?
'l' :
'w')) {
3607 Name = is16BitMode() ?
"movw" :
"movl";
3620 if ((
Name ==
"outb" ||
Name ==
"outsb" ||
Name ==
"outw" ||
Name ==
"outsw" ||
3639 bool HadVerifyError =
false;
3642 if (
Name.starts_with(
"ins") &&
3647 AddDefaultSrcDestOperands(TmpOperands,
3649 DefaultMemDIOperand(NameLoc));
3650 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3654 if (
Name.starts_with(
"outs") &&
3656 (
Name ==
"outsb" ||
Name ==
"outsw" ||
Name ==
"outsl" ||
3657 Name ==
"outsd" ||
Name ==
"outs")) {
3658 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
3660 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3666 if (
Name.starts_with(
"lods") &&
3668 (
Name ==
"lods" ||
Name ==
"lodsb" ||
Name ==
"lodsw" ||
3669 Name ==
"lodsl" ||
Name ==
"lodsd" ||
Name ==
"lodsq")) {
3670 TmpOperands.
push_back(DefaultMemSIOperand(NameLoc));
3671 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3677 if (
Name.starts_with(
"stos") &&
3679 (
Name ==
"stos" ||
Name ==
"stosb" ||
Name ==
"stosw" ||
3680 Name ==
"stosl" ||
Name ==
"stosd" ||
Name ==
"stosq")) {
3681 TmpOperands.
push_back(DefaultMemDIOperand(NameLoc));
3682 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3688 if (
Name.starts_with(
"scas") &&
3690 (
Name ==
"scas" ||
Name ==
"scasb" ||
Name ==
"scasw" ||
3691 Name ==
"scasl" ||
Name ==
"scasd" ||
Name ==
"scasq")) {
3692 TmpOperands.
push_back(DefaultMemDIOperand(NameLoc));
3693 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3697 if (
Name.starts_with(
"cmps") &&
3699 (
Name ==
"cmps" ||
Name ==
"cmpsb" ||
Name ==
"cmpsw" ||
3700 Name ==
"cmpsl" ||
Name ==
"cmpsd" ||
Name ==
"cmpsq")) {
3701 AddDefaultSrcDestOperands(TmpOperands, DefaultMemDIOperand(NameLoc),
3702 DefaultMemSIOperand(NameLoc));
3703 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3707 if (((
Name.starts_with(
"movs") &&
3708 (
Name ==
"movs" ||
Name ==
"movsb" ||
Name ==
"movsw" ||
3709 Name ==
"movsl" ||
Name ==
"movsd" ||
Name ==
"movsq")) ||
3710 (
Name.starts_with(
"smov") &&
3711 (
Name ==
"smov" ||
Name ==
"smovb" ||
Name ==
"smovw" ||
3712 Name ==
"smovl" ||
Name ==
"smovd" ||
Name ==
"smovq"))) &&
3714 if (
Name ==
"movsd" &&
Operands.size() == 1 && !isParsingIntelSyntax())
3716 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
3717 DefaultMemDIOperand(NameLoc));
3718 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3722 if (HadVerifyError) {
3723 return HadVerifyError;
3731 "size, (R|E)BX will be used for the location");
3743 if (ForcedVEXEncoding != VEXEncoding_VEX3 &&
3751 default:
return false;
3756 if (ForcedDispEncoding == DispEncoding_Disp32) {
3757 Inst.
setOpcode(is16BitMode() ? X86::JMP_2 : X86::JMP_4);
3766 if (ForcedDispEncoding == DispEncoding_Disp32) {
3767 Inst.
setOpcode(is16BitMode() ? X86::JCC_2 : X86::JCC_4);
3785 using namespace X86;
3788 uint64_t TSFlags = MII.get(Opcode).TSFlags;
3789 if (isVFCMADDCPH(Opcode) || isVFCMADDCSH(Opcode) || isVFMADDCPH(Opcode) ||
3790 isVFMADDCSH(Opcode)) {
3794 return Warning(Ops[0]->getStartLoc(),
"Destination register should be "
3795 "distinct from source registers");
3796 }
else if (isVFCMULCPH(Opcode) || isVFCMULCSH(Opcode) || isVFMULCPH(Opcode) ||
3797 isVFMULCSH(Opcode)) {
3807 return Warning(Ops[0]->getStartLoc(),
"Destination register should be "
3808 "distinct from source registers");
3809 }
else if (isV4FMADDPS(Opcode) || isV4FMADDSS(Opcode) ||
3810 isV4FNMADDPS(Opcode) || isV4FNMADDSS(Opcode) ||
3811 isVP4DPWSSDS(Opcode) || isVP4DPWSSD(Opcode)) {
3814 unsigned Src2Enc =
MRI->getEncodingValue(Src2);
3815 if (Src2Enc % 4 != 0) {
3817 unsigned GroupStart = (Src2Enc / 4) * 4;
3818 unsigned GroupEnd = GroupStart + 3;
3819 return Warning(Ops[0]->getStartLoc(),
3820 "source register '" +
RegName +
"' implicitly denotes '" +
3825 }
else if (isVGATHERDPD(Opcode) || isVGATHERDPS(Opcode) ||
3826 isVGATHERQPD(Opcode) || isVGATHERQPS(Opcode) ||
3827 isVPGATHERDD(Opcode) || isVPGATHERDQ(Opcode) ||
3828 isVPGATHERQD(Opcode) || isVPGATHERQQ(Opcode)) {
3832 unsigned Index =
MRI->getEncodingValue(
3835 return Warning(Ops[0]->getStartLoc(),
"index and destination registers "
3836 "should be distinct");
3840 unsigned Index =
MRI->getEncodingValue(
3842 if (Dest == Mask || Dest ==
Index || Mask ==
Index)
3843 return Warning(Ops[0]->getStartLoc(),
"mask, index, and destination "
3844 "registers should be distinct");
3854 for (
unsigned i = 0; i != NumOps; ++i) {
3859 if (Reg == X86::AH || Reg == X86::BH || Reg == X86::CH || Reg == X86::DH)
3866 if (UsesRex && HReg != X86::NoRegister) {
3868 return Error(Ops[0]->getStartLoc(),
3869 "can't encode '" +
RegName +
"' in an instruction requiring "
3874 if ((Opcode == X86::PREFETCHIT0 || Opcode == X86::PREFETCHIT1)) {
3878 Ops[0]->getStartLoc(),
3880 :
"'prefetchit1'")) +
3881 " only supports RIP-relative address");
3886void X86AsmParser::emitWarningForSpecialLVIInstruction(
SMLoc Loc) {
3887 Warning(Loc,
"Instruction may be vulnerable to LVI and "
3888 "requires manual mitigation");
3889 Note(
SMLoc(),
"See https://software.intel.com/"
3890 "security-software-guidance/insights/"
3891 "deep-dive-load-value-injection#specialinstructions"
3892 " for more information");
3916 bool Parse32 = is32BitMode() || Code16GCC;
3918 is64BitMode() ? X86::RSP : (Parse32 ? X86::ESP : X86::SP);
3924 ShlMemOp->addMemOperands(ShlInst, 5);
3937 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
3949void X86AsmParser::applyLVILoadHardeningMitigation(
MCInst &Inst,
3966 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
3969 }
else if (Opcode == X86::REP_PREFIX || Opcode == X86::REPNE_PREFIX) {
3972 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
3994 getSTI().hasFeature(X86::FeatureLVIControlFlowIntegrity))
3995 applyLVICFIMitigation(Inst, Out);
4000 getSTI().hasFeature(X86::FeatureLVILoadHardening))
4001 applyLVILoadHardeningMitigation(Inst, Out);
4004bool X86AsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
4007 bool MatchingInlineAsm) {
4008 if (isParsingIntelSyntax())
4017 bool MatchingInlineAsm) {
4022 .
Case(
"finit",
"fninit")
4023 .
Case(
"fsave",
"fnsave")
4024 .
Case(
"fstcw",
"fnstcw")
4025 .
Case(
"fstcww",
"fnstcw")
4026 .
Case(
"fstenv",
"fnstenv")
4027 .
Case(
"fstsw",
"fnstsw")
4028 .
Case(
"fstsww",
"fnstsw")
4029 .
Case(
"fclex",
"fnclex")
4035 if (!MatchingInlineAsm)
4036 emitInstruction(Inst,
Operands, Out);
4041bool X86AsmParser::ErrorMissingFeature(
SMLoc IDLoc,
4043 bool MatchingInlineAsm) {
4044 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
4047 OS <<
"instruction requires:";
4048 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
4049 if (MissingFeatures[i])
4056 unsigned Result = 0;
4058 if (Prefix.isPrefix()) {
4059 Result = Prefix.getPrefix();
4065unsigned X86AsmParser::checkTargetMatchPredicate(
MCInst &Inst) {
4070 return Match_Unsupported;
4072 return Match_Unsupported;
4074 if (ForcedVEXEncoding == VEXEncoding_EVEX &&
4076 return Match_Unsupported;
4078 if ((ForcedVEXEncoding == VEXEncoding_VEX ||
4079 ForcedVEXEncoding == VEXEncoding_VEX2 ||
4080 ForcedVEXEncoding == VEXEncoding_VEX3) &&
4082 return Match_Unsupported;
4086 (ForcedVEXEncoding != VEXEncoding_VEX &&
4087 ForcedVEXEncoding != VEXEncoding_VEX2 &&
4088 ForcedVEXEncoding != VEXEncoding_VEX3))
4089 return Match_Unsupported;
4091 return Match_Success;
4094bool X86AsmParser::MatchAndEmitATTInstruction(
SMLoc IDLoc,
unsigned &Opcode,
4098 bool MatchingInlineAsm) {
4100 assert((*
Operands[0]).isToken() &&
"Leading operand should always be a mnemonic!");
4101 SMRange EmptyRange = std::nullopt;
4105 Out, MatchingInlineAsm);
4113 if (ForcedVEXEncoding == VEXEncoding_VEX)
4115 else if (ForcedVEXEncoding == VEXEncoding_VEX2)
4117 else if (ForcedVEXEncoding == VEXEncoding_VEX3)
4119 else if (ForcedVEXEncoding == VEXEncoding_EVEX)
4123 if (ForcedDispEncoding == DispEncoding_Disp8)
4125 else if (ForcedDispEncoding == DispEncoding_Disp32)
4133 if (ForcedDataPrefix == X86::Is32Bit)
4134 SwitchMode(X86::Is32Bit);
4138 MissingFeatures, MatchingInlineAsm,
4139 isParsingIntelSyntax());
4140 if (ForcedDataPrefix == X86::Is32Bit) {
4141 SwitchMode(X86::Is16Bit);
4142 ForcedDataPrefix = 0;
4144 switch (OriginalError) {
4147 if (!MatchingInlineAsm && validateInstruction(Inst,
Operands))
4152 if (!MatchingInlineAsm)
4153 while (processInstruction(Inst,
Operands))
4157 if (!MatchingInlineAsm)
4158 emitInstruction(Inst,
Operands, Out);
4161 case Match_InvalidImmUnsignedi4: {
4163 if (ErrorLoc ==
SMLoc())
4165 return Error(ErrorLoc,
"immediate must be an integer in range [0, 15]",
4166 EmptyRange, MatchingInlineAsm);
4168 case Match_MissingFeature:
4169 return ErrorMissingFeature(IDLoc, MissingFeatures, MatchingInlineAsm);
4170 case Match_InvalidOperand:
4171 case Match_MnemonicFail:
4172 case Match_Unsupported:
4175 if (
Op.getToken().empty()) {
4176 Error(IDLoc,
"instruction must have size higher than 0", EmptyRange,
4191 Op.setTokenValue(Tmp);
4199 const char *Suffixes =
Base[0] !=
'f' ?
"bwlq" :
"slt\0";
4201 const char *MemSize =
Base[0] !=
'f' ?
"\x08\x10\x20\x40" :
"\x20\x40\x50\0";
4213 bool HasVectorReg =
false;
4218 HasVectorReg =
true;
4219 else if (X86Op->
isMem()) {
4221 assert(
MemOp->Mem.Size == 0 &&
"Memory size always 0 under ATT syntax");
4228 for (
unsigned I = 0, E = std::size(
Match);
I != E; ++
I) {
4229 Tmp.
back() = Suffixes[
I];
4230 if (
MemOp && HasVectorReg)
4231 MemOp->Mem.Size = MemSize[
I];
4232 Match[
I] = Match_MnemonicFail;
4233 if (
MemOp || !HasVectorReg) {
4235 MatchInstruction(
Operands, Inst, ErrorInfoIgnore, MissingFeatures,
4236 MatchingInlineAsm, isParsingIntelSyntax());
4238 if (
Match[
I] == Match_MissingFeature)
4239 ErrorInfoMissingFeatures = MissingFeatures;
4250 if (NumSuccessfulMatches == 1) {
4251 if (!MatchingInlineAsm && validateInstruction(Inst,
Operands))
4256 if (!MatchingInlineAsm)
4257 while (processInstruction(Inst,
Operands))
4261 if (!MatchingInlineAsm)
4262 emitInstruction(Inst,
Operands, Out);
4271 if (NumSuccessfulMatches > 1) {
4273 unsigned NumMatches = 0;
4274 for (
unsigned I = 0, E = std::size(
Match);
I != E; ++
I)
4275 if (
Match[
I] == Match_Success)
4276 MatchChars[NumMatches++] = Suffixes[
I];
4280 OS <<
"ambiguous instructions require an explicit suffix (could be ";
4281 for (
unsigned i = 0; i != NumMatches; ++i) {
4284 if (i + 1 == NumMatches)
4286 OS <<
"'" <<
Base << MatchChars[i] <<
"'";
4289 Error(IDLoc,
OS.str(), EmptyRange, MatchingInlineAsm);
4298 if (OriginalError == Match_MnemonicFail)
4299 return Error(IDLoc,
"invalid instruction mnemonic '" +
Base +
"'",
4300 Op.getLocRange(), MatchingInlineAsm);
4302 if (OriginalError == Match_Unsupported)
4303 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4306 assert(OriginalError == Match_InvalidOperand &&
"Unexpected error");
4310 return Error(IDLoc,
"too few operands for instruction", EmptyRange,
4317 OperandRange, MatchingInlineAsm);
4321 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4327 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4335 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
4342 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4347 Error(IDLoc,
"unknown use of instruction mnemonic without a size suffix",
4348 EmptyRange, MatchingInlineAsm);
4352bool X86AsmParser::MatchAndEmitIntelInstruction(
SMLoc IDLoc,
unsigned &Opcode,
4356 bool MatchingInlineAsm) {
4358 assert((*
Operands[0]).isToken() &&
"Leading operand should always be a mnemonic!");
4360 SMRange EmptyRange = std::nullopt;
4372 if (ForcedVEXEncoding == VEXEncoding_VEX)
4374 else if (ForcedVEXEncoding == VEXEncoding_VEX2)
4376 else if (ForcedVEXEncoding == VEXEncoding_VEX3)
4378 else if (ForcedVEXEncoding == VEXEncoding_EVEX)
4382 if (ForcedDispEncoding == DispEncoding_Disp8)
4384 else if (ForcedDispEncoding == DispEncoding_Disp32)
4395 UnsizedMemOp = X86Op;
4405 static const char *
const PtrSizedInstrs[] = {
"call",
"jmp",
"push"};
4406 for (
const char *Instr : PtrSizedInstrs) {
4407 if (Mnemonic == Instr) {
4408 UnsizedMemOp->
Mem.
Size = getPointerWidth();
4420 if (Mnemonic ==
"push" &&
Operands.size() == 2) {
4422 if (X86Op->
isImm()) {
4424 const auto *
CE = dyn_cast<MCConstantExpr>(X86Op->
getImm());
4425 unsigned Size = getPointerWidth();
4430 Tmp += (is64BitMode())
4432 : (is32BitMode()) ?
"l" : (is16BitMode()) ?
"w" :
" ";
4433 Op.setTokenValue(Tmp);
4436 MissingFeatures, MatchingInlineAsm,
4447 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
4448 for (
unsigned Size : MopSizes) {
4452 unsigned M = MatchInstruction(
Operands, Inst, ErrorInfoIgnore,
4453 MissingFeatures, MatchingInlineAsm,
4454 isParsingIntelSyntax());
4459 if (
Match.back() == Match_MissingFeature)
4460 ErrorInfoMissingFeatures = MissingFeatures;
4470 if (
Match.empty()) {
4471 Match.push_back(MatchInstruction(
4473 isParsingIntelSyntax()));
4475 if (
Match.back() == Match_MissingFeature)
4476 ErrorInfoMissingFeatures = MissingFeatures;
4484 if (
Match.back() == Match_MnemonicFail) {
4485 return Error(IDLoc,
"invalid instruction mnemonic '" + Mnemonic +
"'",
4486 Op.getLocRange(), MatchingInlineAsm);
4493 if (UnsizedMemOp && NumSuccessfulMatches > 1 &&
4496 unsigned M = MatchInstruction(
4498 isParsingIntelSyntax());
4499 if (M == Match_Success)
4500 NumSuccessfulMatches = 1;
4512 if (NumSuccessfulMatches == 1) {
4513 if (!MatchingInlineAsm && validateInstruction(Inst,
Operands))
4518 if (!MatchingInlineAsm)
4519 while (processInstruction(Inst,
Operands))
4522 if (!MatchingInlineAsm)
4523 emitInstruction(Inst,
Operands, Out);
4526 }
else if (NumSuccessfulMatches > 1) {
4528 "multiple matches only possible with unsized memory operands");
4530 "ambiguous operand size for instruction '" + Mnemonic +
"\'",
4536 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4544 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
4551 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4557 if (ErrorLoc ==
SMLoc())
4559 return Error(ErrorLoc,
"immediate must be an integer in range [0, 15]",
4560 EmptyRange, MatchingInlineAsm);
4564 return Error(IDLoc,
"unknown instruction mnemonic", EmptyRange,
4568bool X86AsmParser::OmitRegisterFromClobberLists(
unsigned RegNo) {
4569 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo);
4572bool X86AsmParser::ParseDirective(
AsmToken DirectiveID) {
4576 return parseDirectiveArch();
4578 return ParseDirectiveCode(IDVal, DirectiveID.
getLoc());
4584 return Error(DirectiveID.
getLoc(),
"'.att_syntax noprefix' is not "
4585 "supported: registers must have a "
4586 "'%' prefix in .att_syntax");
4588 getParser().setAssemblerDialect(0);
4591 getParser().setAssemblerDialect(1);
4596 return Error(DirectiveID.
getLoc(),
"'.intel_syntax prefix' is not "
4597 "supported: registers must not have "
4598 "a '%' prefix in .intel_syntax");
4601 }
else if (IDVal ==
".nops")
4602 return parseDirectiveNops(DirectiveID.
getLoc());
4603 else if (IDVal ==
".even")
4604 return parseDirectiveEven(DirectiveID.
getLoc());
4605 else if (IDVal ==
".cv_fpo_proc")
4606 return parseDirectiveFPOProc(DirectiveID.
getLoc());
4607 else if (IDVal ==
".cv_fpo_setframe")
4608 return parseDirectiveFPOSetFrame(DirectiveID.
getLoc());
4609 else if (IDVal ==
".cv_fpo_pushreg")
4610 return parseDirectiveFPOPushReg(DirectiveID.
getLoc());
4611 else if (IDVal ==
".cv_fpo_stackalloc")
4612 return parseDirectiveFPOStackAlloc(DirectiveID.
getLoc());
4613 else if (IDVal ==
".cv_fpo_stackalign")
4614 return parseDirectiveFPOStackAlign(DirectiveID.
getLoc());
4615 else if (IDVal ==
".cv_fpo_endprologue")
4616 return parseDirectiveFPOEndPrologue(DirectiveID.
getLoc());
4617 else if (IDVal ==
".cv_fpo_endproc")
4618 return parseDirectiveFPOEndProc(DirectiveID.
getLoc());
4619 else if (IDVal ==
".seh_pushreg" ||
4621 return parseDirectiveSEHPushReg(DirectiveID.
getLoc());
4622 else if (IDVal ==
".seh_setframe" ||
4624 return parseDirectiveSEHSetFrame(DirectiveID.
getLoc());
4625 else if (IDVal ==
".seh_savereg" ||
4627 return parseDirectiveSEHSaveReg(DirectiveID.
getLoc());
4628 else if (IDVal ==
".seh_savexmm" ||
4630 return parseDirectiveSEHSaveXMM(DirectiveID.
getLoc());
4631 else if (IDVal ==
".seh_pushframe" ||
4633 return parseDirectiveSEHPushFrame(DirectiveID.
getLoc());
4638bool X86AsmParser::parseDirectiveArch() {
4640 getParser().parseStringToEndOfStatement();
4646bool X86AsmParser::parseDirectiveNops(
SMLoc L) {
4647 int64_t NumBytes = 0, Control = 0;
4648 SMLoc NumBytesLoc, ControlLoc;
4650 NumBytesLoc = getTok().getLoc();
4651 if (getParser().checkForValidSection() ||
4652 getParser().parseAbsoluteExpression(NumBytes))
4656 ControlLoc = getTok().getLoc();
4657 if (getParser().parseAbsoluteExpression(Control))
4660 if (getParser().parseEOL())
4663 if (NumBytes <= 0) {
4664 Error(NumBytesLoc,
"'.nops' directive with non-positive size");
4669 Error(ControlLoc,
"'.nops' directive with negative NOP size");
4674 getParser().getStreamer().emitNops(NumBytes, Control, L, STI);
4681bool X86AsmParser::parseDirectiveEven(
SMLoc L) {
4687 getStreamer().initSections(
false, getSTI());
4688 Section = getStreamer().getCurrentSectionOnly();
4691 getStreamer().emitCodeAlignment(
Align(2), &getSTI(), 0);
4693 getStreamer().emitValueToAlignment(
Align(2), 0, 1, 0);
4702 if (IDVal ==
".code16") {
4704 if (!is16BitMode()) {
4705 SwitchMode(X86::Is16Bit);
4706 getParser().getStreamer().emitAssemblerFlag(
MCAF_Code16);
4708 }
else if (IDVal ==
".code16gcc") {
4712 if (!is16BitMode()) {
4713 SwitchMode(X86::Is16Bit);
4714 getParser().getStreamer().emitAssemblerFlag(
MCAF_Code16);
4716 }
else if (IDVal ==
".code32") {
4718 if (!is32BitMode()) {
4719 SwitchMode(X86::Is32Bit);
4720 getParser().getStreamer().emitAssemblerFlag(
MCAF_Code32);
4722 }
else if (IDVal ==
".code64") {
4724 if (!is64BitMode()) {
4725 SwitchMode(X86::Is64Bit);
4726 getParser().getStreamer().emitAssemblerFlag(
MCAF_Code64);
4729 Error(L,
"unknown directive " + IDVal);
4737bool X86AsmParser::parseDirectiveFPOProc(
SMLoc L) {
4742 return Parser.
TokError(
"expected symbol name");
4743 if (Parser.
parseIntToken(ParamsSize,
"expected parameter byte count"))
4746 return Parser.
TokError(
"parameters size out of range");
4749 MCSymbol *ProcSym = getContext().getOrCreateSymbol(ProcName);
4750 return getTargetStreamer().emitFPOProc(ProcSym, ParamsSize, L);
4754bool X86AsmParser::parseDirectiveFPOSetFrame(
SMLoc L) {
4757 if (parseRegister(Reg, DummyLoc, DummyLoc) || parseEOL())
4759 return getTargetStreamer().emitFPOSetFrame(Reg, L);
4763bool X86AsmParser::parseDirectiveFPOPushReg(
SMLoc L) {
4766 if (parseRegister(Reg, DummyLoc, DummyLoc) || parseEOL())
4768 return getTargetStreamer().emitFPOPushReg(Reg, L);
4772bool X86AsmParser::parseDirectiveFPOStackAlloc(
SMLoc L) {
4777 return getTargetStreamer().emitFPOStackAlloc(
Offset, L);
4781bool X86AsmParser::parseDirectiveFPOStackAlign(
SMLoc L) {
4786 return getTargetStreamer().emitFPOStackAlign(
Offset, L);
4790bool X86AsmParser::parseDirectiveFPOEndPrologue(
SMLoc L) {
4794 return getTargetStreamer().emitFPOEndPrologue(L);
4798bool X86AsmParser::parseDirectiveFPOEndProc(
SMLoc L) {
4802 return getTargetStreamer().emitFPOEndProc(L);
4805bool X86AsmParser::parseSEHRegisterNumber(
unsigned RegClassID,
4807 SMLoc startLoc = getLexer().getLoc();
4813 if (parseRegister(RegNo, startLoc, endLoc))
4816 if (!X86MCRegisterClasses[RegClassID].
contains(RegNo)) {
4817 return Error(startLoc,
4818 "register is not supported for use with this directive");
4824 if (getParser().parseAbsoluteExpression(EncodedReg))
4830 for (
MCPhysReg Reg : X86MCRegisterClasses[RegClassID]) {
4831 if (
MRI->getEncodingValue(Reg) == EncodedReg) {
4837 return Error(startLoc,
4838 "incorrect register number for use with this directive");
4845bool X86AsmParser::parseDirectiveSEHPushReg(
SMLoc Loc) {
4847 if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg))
4851 return TokError(
"expected end of directive");
4854 getStreamer().emitWinCFIPushReg(Reg, Loc);
4858bool X86AsmParser::parseDirectiveSEHSetFrame(
SMLoc Loc) {
4861 if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg))
4864 return TokError(
"you must specify a stack pointer offset");
4867 if (getParser().parseAbsoluteExpression(Off))
4871 return TokError(
"expected end of directive");
4874 getStreamer().emitWinCFISetFrame(Reg, Off, Loc);
4878bool X86AsmParser::parseDirectiveSEHSaveReg(
SMLoc Loc) {
4881 if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg))
4884 return TokError(
"you must specify an offset on the stack");
4887 if (getParser().parseAbsoluteExpression(Off))
4891 return TokError(
"expected end of directive");
4894 getStreamer().emitWinCFISaveReg(Reg, Off, Loc);
4898bool X86AsmParser::parseDirectiveSEHSaveXMM(
SMLoc Loc) {
4901 if (parseSEHRegisterNumber(X86::VR128XRegClassID, Reg))
4904 return TokError(
"you must specify an offset on the stack");
4907 if (getParser().parseAbsoluteExpression(Off))
4911 return TokError(
"expected end of directive");
4914 getStreamer().emitWinCFISaveXMM(Reg, Off, Loc);
4918bool X86AsmParser::parseDirectiveSEHPushFrame(
SMLoc Loc) {
4922 SMLoc startLoc = getLexer().getLoc();
4924 if (!getParser().parseIdentifier(CodeID)) {
4925 if (CodeID !=
"code")
4926 return Error(startLoc,
"expected @code");
4932 return TokError(
"expected end of directive");
4935 getStreamer().emitWinCFIPushFrame(Code, Loc);
4945#define GET_MATCHER_IMPLEMENTATION
4946#include "X86GenAsmMatcher.inc"
unsigned const MachineRegisterInfo * MRI
static MCRegister MatchRegisterName(StringRef Name)
static const char * getSubtargetFeatureName(uint64_t Val)
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
Analysis containing CSE Info
#define LLVM_EXTERNAL_VISIBILITY
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
amode Optimize addressing mode
static ModuleSymbolTable::Symbol getSym(DataRefImpl &Symb)
mir Rename Register Operands
static bool IsVCMP(unsigned Opcode)
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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 SymbolRef::Type getType(const Symbol *Sym)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
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_EXTERNAL_VISIBILITY void LLVMInitializeX86AsmParser()
static unsigned getPrefixes(OperandVector &Operands)
static bool CheckBaseRegAndIndexRegAndScale(unsigned BaseReg, unsigned IndexReg, unsigned Scale, bool Is64BitMode, StringRef &ErrMsg)
static unsigned getSize(unsigned Kind)
Class for arbitrary precision integers.
uint64_t getZExtValue() const
Get zero extended value.
Target independent representation for an assembler token.
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
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
This class represents an Operation in the Expression.
Base class for user error types.
Lightweight error class with error context and mandatory checking.
Container class for subtarget features.
constexpr size_t size() const
An instruction for ordering other memory operations.
Generic assembler lexer interface, for use by target specific assembly lexers.
void UnLex(AsmToken const &Token)
bool isNot(AsmToken::TokenKind K) const
Check if the current token has kind K.
MCStreamer & getStreamer()
MCAsmParser & getParser()
Generic assembler parser interface, for use by target specific assembly parsers.
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
virtual MCStreamer & getStreamer()=0
Return the output streamer for the assembler.
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
virtual bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc, AsmTypeInfo *TypeInfo)=0
Parse a primary 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.
bool parseIntToken(int64_t &V, const Twine &ErrMsg)
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
virtual unsigned getAssemblerDialect()
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
virtual bool lookUpType(StringRef Name, AsmTypeInfo &Info) const
bool TokError(const Twine &Msg, SMRange Range=std::nullopt)
Report an error at the current lexer location.
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)
virtual MCContext & getContext()=0
bool Error(SMLoc L, const Twine &Msg, SMRange Range=std::nullopt)
Return an error at the location L, with the message Msg.
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Base class for the full range of assembler expressions which are needed for parsing.
@ 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
Describe properties that are true of each instruction in the target description file.
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.
Interface to description of machine instruction set.
Instances of this class represent operands of the MCInst class.
static MCOperand createImm(int64_t Val)
unsigned getReg() const
Returns the register number.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Wrapper class representing physical registers. Should be passed by value.
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Streaming machine code generation interface.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
MCTargetStreamer * getTargetStreamer()
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
const FeatureBitset & getFeatureBits() 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)
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
MCTargetAsmParser - Generic interface to target specific assembly parsers.
MCSubtargetInfo & copySTI()
Create a copy of STI and return a non-const reference to it.
@ FIRST_TARGET_MATCH_RESULT_TY
virtual bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
virtual bool ParseDirective(AsmToken DirectiveID)
ParseDirective - Parse a target specific assembler directive This method is deprecated,...
virtual bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc)
virtual ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
tryParseRegister - parse one register if possible
void setAvailableFeatures(const FeatureBitset &Value)
const MCSubtargetInfo & getSTI() const
virtual bool OmitRegisterFromClobberLists(unsigned RegNo)
Allows targets to let registers opt out of clobber lists.
virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands)=0
ParseInstruction - Parse one assembly instruction.
virtual unsigned checkTargetMatchPredicate(MCInst &Inst)
checkTargetMatchPredicate - Validate the instruction match against any complex target predicates not ...
virtual bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm)=0
MatchAndEmitInstruction - Recognize a series of operands of a parsed instruction as an actual MCInst ...
Target specific streamer interface.
Ternary parse status returned by various parse* methods.
static constexpr StatusTy Failure
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
constexpr bool isValid() const
Represents a range in source code.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - 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.
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.
constexpr bool empty() const
empty - Check if the string is empty.
char back() const
back - 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
size - Get the string size.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
bool consume_front(StringRef Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
bool equals(StringRef RHS) const
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
std::string lower() const
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
static constexpr size_t npos
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.
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
StringSwitch & Cases(StringLiteral S0, StringLiteral S1, T Value)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
static const char * getRegisterName(MCRegister Reg)
static const X86MCExpr * create(int64_t RegNo, MCContext &Ctx)
X86 target streamer implementing x86-only assembly directives.
A raw_ostream that writes to an SmallVector or SmallString.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const CustomOperand< const MCSubtargetInfo & > Msg[]
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
std::variant< std::monostate, Loc::Single, Loc::Multi, Loc::MMI, Loc::EntryValue > Variant
Alias for the std::variant specialization base class of DbgVariable.
@ CE
Windows NT (Windows on ARM)
@ X86
Windows x64, Windows Itanium (IA-64)
Reg
All possible values of the reg field in the ModR/M byte.
bool isX86_64ExtendedReg(unsigned RegNo)
@ 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.
@ ExplicitVEXPrefix
For instructions that use VEX encoding only when {vex}, {vex2} or {vex3} is present.
bool isX86_64NonExtLowByteReg(unsigned reg)
bool canUseApxExtendedReg(const MCInstrDesc &Desc)
bool isApxExtendedReg(unsigned RegNo)
bool optimizeShiftRotateWithImmediateOne(MCInst &MI)
bool optimizeInstFromVEX3ToVEX2(MCInst &MI, const MCInstrDesc &Desc)
StringRef toStringRef(const std::optional< DWARFFormValue > &V, StringRef Default={})
Take an optional DWARFFormValue and try to extract a string value from it.
NodeAddr< CodeNode * > Code
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.
bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
MCRegister getX86SubSuperRegister(MCRegister Reg, unsigned Size, bool High=false)
Target & getTheX86_32Target()
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
@ MCAF_Code64
.code64 (X86)
@ MCAF_Code16
.code16 (X86) / .code 16 (ARM)
@ MCAF_Code32
.code32 (X86) / .code 32 (ARM)
bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
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...
Target & getTheX86_64Target()
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
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)
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
static std::unique_ptr< X86Operand > CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc, bool AddressOf=false, SMLoc OffsetOfLoc=SMLoc(), StringRef SymName=StringRef(), void *OpDecl=nullptr)