46 "x86-experimental-lvi-inline-asm-hardening",
47 cl::desc(
"Harden inline assembly code that may be vulnerable to Load Value"
48 " Injection (LVI). This feature is experimental."),
cl::Hidden);
51 if (Scale != 1 && Scale != 2 && Scale != 4 && Scale != 8) {
52 ErrMsg =
"scale factor in address must be 1, 2, 4 or 8";
60static const char OpPrecedence[] = {
88 unsigned ForcedDataPrefix = 0;
98 VEXEncoding ForcedVEXEncoding = VEXEncoding_Default;
101 DispEncoding_Default,
106 DispEncoding ForcedDispEncoding = DispEncoding_Default;
109 SMLoc consumeToken() {
118 "do not have a target streamer");
125 bool matchingInlineAsm,
unsigned VariantID = 0) {
128 SwitchMode(X86::Is32Bit);
130 MissingFeatures, matchingInlineAsm,
133 SwitchMode(X86::Is16Bit);
137 enum InfixCalculatorTok {
162 enum IntelOperatorKind {
169 enum MasmOperatorKind {
176 class InfixCalculator {
177 typedef std::pair< InfixCalculatorTok, int64_t > ICToken;
181 bool isUnaryOperator(InfixCalculatorTok Op)
const {
182 return Op == IC_NEG ||
Op == IC_NOT;
186 int64_t popOperand() {
187 assert (!PostfixStack.
empty() &&
"Poped an empty stack!");
189 if (!(
Op.first == IC_IMM ||
Op.first == IC_REGISTER))
193 void pushOperand(InfixCalculatorTok Op, int64_t Val = 0) {
194 assert ((Op == IC_IMM || Op == IC_REGISTER) &&
195 "Unexpected operand!");
196 PostfixStack.
push_back(std::make_pair(Op, Val));
199 void popOperator() { InfixOperatorStack.
pop_back(); }
200 void pushOperator(InfixCalculatorTok Op) {
202 if (InfixOperatorStack.
empty()) {
210 unsigned Idx = InfixOperatorStack.
size() - 1;
211 InfixCalculatorTok StackOp = InfixOperatorStack[
Idx];
212 if (OpPrecedence[Op] > OpPrecedence[StackOp] || StackOp == IC_LPAREN) {
219 unsigned ParenCount = 0;
222 if (InfixOperatorStack.
empty())
225 Idx = InfixOperatorStack.
size() - 1;
226 StackOp = InfixOperatorStack[
Idx];
227 if (!(OpPrecedence[StackOp] >= OpPrecedence[Op] || ParenCount))
232 if (!ParenCount && StackOp == IC_LPAREN)
235 if (StackOp == IC_RPAREN) {
238 }
else if (StackOp == IC_LPAREN) {
243 PostfixStack.
push_back(std::make_pair(StackOp, 0));
252 while (!InfixOperatorStack.
empty()) {
253 InfixCalculatorTok StackOp = InfixOperatorStack.
pop_back_val();
254 if (StackOp != IC_LPAREN && StackOp != IC_RPAREN)
255 PostfixStack.
push_back(std::make_pair(StackOp, 0));
258 if (PostfixStack.
empty())
262 for (
unsigned i = 0, e = PostfixStack.
size(); i != e; ++i) {
263 ICToken
Op = PostfixStack[i];
264 if (
Op.first == IC_IMM ||
Op.first == IC_REGISTER) {
266 }
else if (isUnaryOperator(
Op.first)) {
267 assert (OperandStack.
size() > 0 &&
"Too few operands.");
269 assert (Operand.first == IC_IMM &&
270 "Unary operation with a register!");
276 OperandStack.
push_back(std::make_pair(IC_IMM, -Operand.second));
279 OperandStack.
push_back(std::make_pair(IC_IMM, ~Operand.second));
283 assert (OperandStack.
size() > 1 &&
"Too few operands.");
292 Val = Op1.second + Op2.second;
293 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
296 Val = Op1.second - Op2.second;
297 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
300 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
301 "Multiply operation with an immediate and a register!");
302 Val = Op1.second * Op2.second;
303 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
306 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
307 "Divide operation with an immediate and a register!");
308 assert (Op2.second != 0 &&
"Division by zero!");
309 Val = Op1.second / Op2.second;
310 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
313 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
314 "Modulo operation with an immediate and a register!");
315 Val = Op1.second % Op2.second;
316 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
319 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
320 "Or operation with an immediate and a register!");
321 Val = Op1.second | Op2.second;
322 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
325 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
326 "Xor operation with an immediate and a register!");
327 Val = Op1.second ^ Op2.second;
328 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
331 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
332 "And operation with an immediate and a register!");
333 Val = Op1.second & Op2.second;
334 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
337 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
338 "Left shift operation with an immediate and a register!");
339 Val = Op1.second << Op2.second;
340 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
343 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
344 "Right shift operation with an immediate and a register!");
345 Val = Op1.second >> Op2.second;
346 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
349 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
350 "Equals operation with an immediate and a register!");
351 Val = (Op1.second == Op2.second) ? -1 : 0;
352 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
355 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
356 "Not-equals operation with an immediate and a register!");
357 Val = (Op1.second != Op2.second) ? -1 : 0;
358 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
361 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
362 "Less-than operation with an immediate and a register!");
363 Val = (Op1.second < Op2.second) ? -1 : 0;
364 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
367 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
368 "Less-than-or-equal operation with an immediate and a "
370 Val = (Op1.second <= Op2.second) ? -1 : 0;
371 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
374 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
375 "Greater-than operation with an immediate and a register!");
376 Val = (Op1.second > Op2.second) ? -1 : 0;
377 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
380 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
381 "Greater-than-or-equal operation with an immediate and a "
383 Val = (Op1.second >= Op2.second) ? -1 : 0;
384 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
389 assert (OperandStack.
size() == 1 &&
"Expected a single result.");
394 enum IntelExprState {
425 class IntelExprStateMachine {
426 IntelExprState State = IES_INIT, PrevState = IES_ERROR;
427 unsigned BaseReg = 0, IndexReg = 0, TmpReg = 0, Scale = 0;
429 const MCExpr *Sym =
nullptr;
434 bool MemExpr =
false;
435 bool OffsetOperator =
false;
436 bool AttachToOperandIdx =
false;
438 SMLoc OffsetOperatorLoc;
443 ErrMsg =
"cannot use more than one symbol in memory operand";
452 IntelExprStateMachine() =
default;
454 void addImm(int64_t imm) {
Imm += imm; }
455 short getBracCount()
const {
return BracCount; }
456 bool isMemExpr()
const {
return MemExpr; }
457 bool isOffsetOperator()
const {
return OffsetOperator; }
458 SMLoc getOffsetLoc()
const {
return OffsetOperatorLoc; }
459 unsigned getBaseReg()
const {
return BaseReg; }
460 unsigned getIndexReg()
const {
return IndexReg; }
461 unsigned getScale()
const {
return Scale; }
463 StringRef getSymName()
const {
return SymName; }
466 unsigned getElementSize()
const {
return CurType.
ElementSize; }
467 unsigned getLength()
const {
return CurType.
Length; }
468 int64_t getImm() {
return Imm + IC.execute(); }
469 bool isValidEndState()
const {
470 return State == IES_RBRAC || State == IES_INTEGER;
477 void setAppendAfterOperand() { AttachToOperandIdx =
true; }
479 bool isPIC()
const {
return IsPIC; }
480 void setPIC() { IsPIC =
true; }
482 bool hadError()
const {
return State == IES_ERROR; }
488 if (IsPIC && AttachToOperandIdx)
489 ErrMsg =
"Don't use 2 or more regs for mem offset in PIC model!";
491 ErrMsg =
"BaseReg/IndexReg already set!";
496 IntelExprState CurrState = State;
505 IC.pushOperator(IC_OR);
508 PrevState = CurrState;
511 IntelExprState CurrState = State;
520 IC.pushOperator(IC_XOR);
523 PrevState = CurrState;
526 IntelExprState CurrState = State;
535 IC.pushOperator(IC_AND);
538 PrevState = CurrState;
541 IntelExprState CurrState = State;
550 IC.pushOperator(IC_EQ);
553 PrevState = CurrState;
556 IntelExprState CurrState = State;
565 IC.pushOperator(IC_NE);
568 PrevState = CurrState;
571 IntelExprState CurrState = State;
580 IC.pushOperator(IC_LT);
583 PrevState = CurrState;
586 IntelExprState CurrState = State;
595 IC.pushOperator(IC_LE);
598 PrevState = CurrState;
601 IntelExprState CurrState = State;
610 IC.pushOperator(IC_GT);
613 PrevState = CurrState;
616 IntelExprState CurrState = State;
625 IC.pushOperator(IC_GE);
628 PrevState = CurrState;
631 IntelExprState CurrState = State;
640 IC.pushOperator(IC_LSHIFT);
643 PrevState = CurrState;
646 IntelExprState CurrState = State;
655 IC.pushOperator(IC_RSHIFT);
658 PrevState = CurrState;
661 IntelExprState CurrState = State;
671 IC.pushOperator(IC_PLUS);
672 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
679 return regsUseUpError(ErrMsg);
686 PrevState = CurrState;
690 IntelExprState CurrState = State;
721 if (CurrState == IES_REGISTER || CurrState == IES_RPAREN ||
722 CurrState == IES_INTEGER || CurrState == IES_RBRAC ||
723 CurrState == IES_OFFSET)
724 IC.pushOperator(IC_MINUS);
725 else if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
727 ErrMsg =
"Scale can't be negative";
730 IC.pushOperator(IC_NEG);
731 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
738 return regsUseUpError(ErrMsg);
745 PrevState = CurrState;
749 IntelExprState CurrState = State;
775 IC.pushOperator(IC_NOT);
778 PrevState = CurrState;
780 bool onRegister(
unsigned Reg,
StringRef &ErrMsg) {
781 IntelExprState CurrState = State;
789 State = IES_REGISTER;
791 IC.pushOperand(IC_REGISTER);
795 if (PrevState == IES_INTEGER) {
797 return regsUseUpError(ErrMsg);
798 State = IES_REGISTER;
801 Scale = IC.popOperand();
804 IC.pushOperand(IC_IMM);
811 PrevState = CurrState;
819 if (ParsingMSInlineAsm)
823 if (
auto *CE = dyn_cast<MCConstantExpr>(SymRef))
824 return onInteger(
CE->getValue(), ErrMsg);
837 if (setSymRef(SymRef, SymRefName, ErrMsg))
841 IC.pushOperand(IC_IMM);
842 if (ParsingMSInlineAsm)
849 bool onInteger(int64_t TmpInt,
StringRef &ErrMsg) {
850 IntelExprState CurrState = State;
876 if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
879 return regsUseUpError(ErrMsg);
887 IC.pushOperand(IC_IMM, TmpInt);
891 PrevState = CurrState;
903 State = IES_MULTIPLY;
904 IC.pushOperator(IC_MULTIPLY);
917 IC.pushOperator(IC_DIVIDE);
930 IC.pushOperator(IC_MOD);
946 IC.pushOperator(IC_PLUS);
952 assert(!BracCount &&
"BracCount should be zero on parsing's start");
961 IntelExprState CurrState = State;
970 if (BracCount-- != 1) {
971 ErrMsg =
"unexpected bracket encountered";
975 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
982 return regsUseUpError(ErrMsg);
989 PrevState = CurrState;
993 IntelExprState CurrState = State;
1019 IC.pushOperator(IC_LPAREN);
1022 PrevState = CurrState;
1036 IC.pushOperator(IC_RPAREN);
1042 bool ParsingMSInlineAsm,
StringRef &ErrMsg) {
1046 ErrMsg =
"unexpected offset operator expression";
1051 if (setSymRef(Val,
ID, ErrMsg))
1053 OffsetOperator =
true;
1054 OffsetOperatorLoc = OffsetLoc;
1058 IC.pushOperand(IC_IMM);
1059 if (ParsingMSInlineAsm) {
1082 bool MatchingInlineAsm =
false) {
1084 if (MatchingInlineAsm) {
1085 if (!
getLexer().isAtStartOfStatement())
1089 return Parser.
Error(L, Msg, Range);
1095 bool RestoreOnFailure);
1097 std::unique_ptr<X86Operand> DefaultMemSIOperand(
SMLoc Loc);
1098 std::unique_ptr<X86Operand> DefaultMemDIOperand(
SMLoc Loc);
1099 bool IsSIReg(
unsigned Reg);
1100 unsigned GetSIDIForRegClass(
unsigned RegClassID,
unsigned Reg,
bool IsSIReg);
1103 std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
1104 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst);
1112 bool ParseIntelDotOperator(IntelExprStateMachine &SM,
SMLoc &End);
1114 unsigned ParseIntelInlineAsmOperator(
unsigned OpKind);
1116 bool ParseMasmOperator(
unsigned OpKind, int64_t &Val);
1118 bool ParseIntelNamedOperator(
StringRef Name, IntelExprStateMachine &SM,
1119 bool &ParseError,
SMLoc &End);
1120 bool ParseMasmNamedOperator(
StringRef Name, IntelExprStateMachine &SM,
1121 bool &ParseError,
SMLoc &End);
1122 void RewriteIntelExpression(IntelExprStateMachine &SM,
SMLoc Start,
1124 bool ParseIntelExpression(IntelExprStateMachine &SM,
SMLoc &End);
1125 bool ParseIntelInlineAsmIdentifier(
const MCExpr *&Val,
StringRef &Identifier,
1127 bool IsUnevaluatedOperand,
SMLoc &End,
1128 bool IsParsingOffsetOperator =
false);
1130 IntelExprStateMachine &SM);
1132 bool ParseMemOperand(
unsigned SegReg,
const MCExpr *Disp,
SMLoc StartLoc,
1137 bool ParseIntelMemoryOperandSize(
unsigned &
Size);
1138 bool CreateMemForMSInlineAsm(
unsigned SegReg,
const MCExpr *Disp,
1139 unsigned BaseReg,
unsigned IndexReg,
1145 bool parseDirectiveArch();
1146 bool parseDirectiveNops(
SMLoc L);
1147 bool parseDirectiveEven(
SMLoc L);
1151 bool parseDirectiveFPOProc(
SMLoc L);
1152 bool parseDirectiveFPOSetFrame(
SMLoc L);
1153 bool parseDirectiveFPOPushReg(
SMLoc L);
1154 bool parseDirectiveFPOStackAlloc(
SMLoc L);
1155 bool parseDirectiveFPOStackAlign(
SMLoc L);
1156 bool parseDirectiveFPOEndPrologue(
SMLoc L);
1157 bool parseDirectiveFPOEndProc(
SMLoc L);
1160 bool parseSEHRegisterNumber(
unsigned RegClassID,
MCRegister &RegNo);
1161 bool parseDirectiveSEHPushReg(
SMLoc);
1162 bool parseDirectiveSEHSetFrame(
SMLoc);
1163 bool parseDirectiveSEHSaveReg(
SMLoc);
1164 bool parseDirectiveSEHSaveXMM(
SMLoc);
1165 bool parseDirectiveSEHPushFrame(
SMLoc);
1173 void emitWarningForSpecialLVIInstruction(
SMLoc Loc);
1184 bool MatchingInlineAsm)
override;
1190 bool MatchingInlineAsm);
1192 bool MatchAndEmitATTInstruction(
SMLoc IDLoc,
unsigned &Opcode,
1195 bool MatchingInlineAsm);
1197 bool MatchAndEmitIntelInstruction(
SMLoc IDLoc,
unsigned &Opcode,
1200 bool MatchingInlineAsm);
1209 bool ParseZ(std::unique_ptr<X86Operand> &Z,
const SMLoc &StartLoc);
1211 bool is64BitMode()
const {
1215 bool is32BitMode()
const {
1219 bool is16BitMode()
const {
1223 void SwitchMode(
unsigned mode) {
1225 FeatureBitset AllModes({X86::Is64Bit, X86::Is32Bit, X86::Is16Bit});
1234 unsigned getPointerWidth() {
1235 if (is16BitMode())
return 16;
1236 if (is32BitMode())
return 32;
1237 if (is64BitMode())
return 64;
1241 bool isParsingIntelSyntax() {
1248#define GET_ASSEMBLER_HEADER
1249#include "X86GenAsmMatcher.inc"
1254 enum X86MatchResultTy {
1256#define GET_OPERAND_DIAGNOSTIC_TYPES
1257#include "X86GenAsmMatcher.inc"
1272 SMLoc &EndLoc)
override;
1274 SMLoc &EndLoc)
override;
1293 unsigned Scale,
bool Is64BitMode,
1300 !(BaseReg == X86::RIP || BaseReg == X86::EIP ||
1301 X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg) ||
1302 X86MCRegisterClasses[X86::GR32RegClassID].
contains(BaseReg) ||
1303 X86MCRegisterClasses[X86::GR64RegClassID].
contains(BaseReg))) {
1304 ErrMsg =
"invalid base+index expression";
1308 if (IndexReg != 0 &&
1309 !(IndexReg == X86::EIZ || IndexReg == X86::RIZ ||
1310 X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg) ||
1311 X86MCRegisterClasses[X86::GR32RegClassID].
contains(IndexReg) ||
1312 X86MCRegisterClasses[X86::GR64RegClassID].
contains(IndexReg) ||
1313 X86MCRegisterClasses[X86::VR128XRegClassID].
contains(IndexReg) ||
1314 X86MCRegisterClasses[X86::VR256XRegClassID].
contains(IndexReg) ||
1315 X86MCRegisterClasses[X86::VR512RegClassID].
contains(IndexReg))) {
1316 ErrMsg =
"invalid base+index expression";
1320 if (((BaseReg == X86::RIP || BaseReg == X86::EIP) && IndexReg != 0) ||
1321 IndexReg == X86::EIP || IndexReg == X86::RIP ||
1322 IndexReg == X86::ESP || IndexReg == X86::RSP) {
1323 ErrMsg =
"invalid base+index expression";
1329 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg) &&
1330 (Is64BitMode || (BaseReg != X86::BX && BaseReg != X86::BP &&
1331 BaseReg != X86::SI && BaseReg != X86::DI))) {
1332 ErrMsg =
"invalid 16-bit base register";
1337 X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg)) {
1338 ErrMsg =
"16-bit memory operand may not include only index register";
1342 if (BaseReg != 0 && IndexReg != 0) {
1343 if (X86MCRegisterClasses[X86::GR64RegClassID].
contains(BaseReg) &&
1344 (X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg) ||
1345 X86MCRegisterClasses[X86::GR32RegClassID].
contains(IndexReg) ||
1346 IndexReg == X86::EIZ)) {
1347 ErrMsg =
"base register is 64-bit, but index register is not";
1350 if (X86MCRegisterClasses[X86::GR32RegClassID].
contains(BaseReg) &&
1351 (X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg) ||
1352 X86MCRegisterClasses[X86::GR64RegClassID].
contains(IndexReg) ||
1353 IndexReg == X86::RIZ)) {
1354 ErrMsg =
"base register is 32-bit, but index register is not";
1357 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg)) {
1358 if (X86MCRegisterClasses[X86::GR32RegClassID].
contains(IndexReg) ||
1359 X86MCRegisterClasses[X86::GR64RegClassID].
contains(IndexReg)) {
1360 ErrMsg =
"base register is 16-bit, but index register is not";
1363 if ((BaseReg != X86::BX && BaseReg != X86::BP) ||
1364 (IndexReg != X86::SI && IndexReg != X86::DI)) {
1365 ErrMsg =
"invalid 16-bit base/index register combination";
1372 if (!Is64BitMode && BaseReg != 0 &&
1373 (BaseReg == X86::RIP || BaseReg == X86::EIP)) {
1374 ErrMsg =
"IP-relative addressing requires 64-bit mode";
1395 if (isParsingMSInlineAsm() && isParsingIntelSyntax() &&
1396 (RegNo == X86::EFLAGS || RegNo == X86::MXCSR))
1399 if (!is64BitMode()) {
1403 if (RegNo == X86::RIZ || RegNo == X86::RIP ||
1404 X86MCRegisterClasses[X86::GR64RegClassID].
contains(RegNo) ||
1407 return Error(StartLoc,
1408 "register %" +
RegName +
" is only available in 64-bit mode",
1415 if (RegNo == 0 &&
RegName.startswith(
"db")) {
1474 if (isParsingIntelSyntax())
1476 return Error(StartLoc,
"invalid register name",
SMRange(StartLoc, EndLoc));
1482 SMLoc &EndLoc,
bool RestoreOnFailure) {
1488 auto OnFailure = [RestoreOnFailure, &Lexer, &Tokens]() {
1489 if (RestoreOnFailure) {
1490 while (!Tokens.
empty()) {
1497 StartLoc = PercentTok.
getLoc();
1511 if (isParsingIntelSyntax())
return true;
1512 return Error(StartLoc,
"invalid register name",
1516 if (MatchRegisterByName(RegNo, Tok.
getString(), StartLoc, EndLoc)) {
1522 if (RegNo == X86::ST0) {
1536 return Error(IntTok.
getLoc(),
"expected stack index");
1539 case 0: RegNo = X86::ST0;
break;
1540 case 1: RegNo = X86::ST1;
break;
1541 case 2: RegNo = X86::ST2;
break;
1542 case 3: RegNo = X86::ST3;
break;
1543 case 4: RegNo = X86::ST4;
break;
1544 case 5: RegNo = X86::ST5;
break;
1545 case 6: RegNo = X86::ST6;
break;
1546 case 7: RegNo = X86::ST7;
break;
1549 return Error(IntTok.
getLoc(),
"invalid stack index");
1569 if (isParsingIntelSyntax())
return true;
1570 return Error(StartLoc,
"invalid register name",
1580 return ParseRegister(RegNo, StartLoc, EndLoc,
false);
1587 ParseRegister(RegNo, StartLoc, EndLoc,
true);
1588 bool PendingErrors = getParser().hasPendingError();
1589 getParser().clearPendingErrors();
1597std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(
SMLoc Loc) {
1598 bool Parse32 = is32BitMode() || Code16GCC;
1599 unsigned Basereg = is64BitMode() ? X86::RSI : (Parse32 ? X86::ESI : X86::SI);
1606std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand(
SMLoc Loc) {
1607 bool Parse32 = is32BitMode() || Code16GCC;
1608 unsigned Basereg = is64BitMode() ? X86::RDI : (Parse32 ? X86::EDI : X86::DI);
1615bool X86AsmParser::IsSIReg(
unsigned Reg) {
1629unsigned X86AsmParser::GetSIDIForRegClass(
unsigned RegClassID,
unsigned Reg,
1631 switch (RegClassID) {
1633 case X86::GR64RegClassID:
1634 return IsSIReg ? X86::RSI : X86::RDI;
1635 case X86::GR32RegClassID:
1636 return IsSIReg ? X86::ESI : X86::EDI;
1637 case X86::GR16RegClassID:
1638 return IsSIReg ? X86::SI : X86::DI;
1642void X86AsmParser::AddDefaultSrcDestOperands(
1644 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst) {
1645 if (isParsingIntelSyntax()) {
1646 Operands.push_back(std::move(Dst));
1647 Operands.push_back(std::move(Src));
1650 Operands.push_back(std::move(Src));
1651 Operands.push_back(std::move(Dst));
1655bool X86AsmParser::VerifyAndAdjustOperands(
OperandVector &OrigOperands,
1658 if (OrigOperands.
size() > 1) {
1661 "Operand size mismatch");
1665 int RegClassID = -1;
1666 for (
unsigned int i = 0; i < FinalOperands.
size(); ++i) {
1670 if (FinalOp.
isReg() &&
1675 if (FinalOp.
isMem()) {
1677 if (!OrigOp.
isMem())
1686 if (RegClassID != -1 &&
1687 !X86MCRegisterClasses[RegClassID].
contains(OrigReg)) {
1689 "mismatching source and destination index registers");
1692 if (X86MCRegisterClasses[X86::GR64RegClassID].
contains(OrigReg))
1693 RegClassID = X86::GR64RegClassID;
1694 else if (X86MCRegisterClasses[X86::GR32RegClassID].
contains(OrigReg))
1695 RegClassID = X86::GR32RegClassID;
1696 else if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(OrigReg))
1697 RegClassID = X86::GR16RegClassID;
1703 bool IsSI = IsSIReg(FinalReg);
1704 FinalReg = GetSIDIForRegClass(RegClassID, FinalReg, IsSI);
1706 if (FinalReg != OrigReg) {
1707 std::string
RegName = IsSI ?
"ES:(R|E)SI" :
"ES:(R|E)DI";
1710 "memory operand is only for determining the size, " +
RegName +
1711 " will be used for the location"));
1722 for (
auto &WarningMsg : Warnings) {
1723 Warning(WarningMsg.first, WarningMsg.second);
1727 for (
unsigned int i = 0; i < FinalOperands.
size(); ++i)
1731 for (
unsigned int i = 0; i < FinalOperands.
size(); ++i)
1732 OrigOperands.
push_back(std::move(FinalOperands[i]));
1738 if (isParsingIntelSyntax())
1744bool X86AsmParser::CreateMemForMSInlineAsm(
1745 unsigned SegReg,
const MCExpr *Disp,
unsigned BaseReg,
unsigned IndexReg,
1753 Size = getPointerWidth();
1760 End,
Size, Identifier,
1767 unsigned FrontendSize = 0;
1768 void *Decl =
nullptr;
1769 bool IsGlobalLV =
false;
1772 FrontendSize =
Info.Var.Type * 8;
1773 Decl =
Info.Var.Decl;
1774 IsGlobalLV =
Info.Var.IsGlobalLV;
1778 if (IsGlobalLV && (BaseReg || IndexReg)) {
1780 End,
Size, Identifier, Decl, 0,
1781 BaseReg && IndexReg));
1787 BaseReg = BaseReg ? BaseReg : 1;
1789 getPointerWidth(), SegReg, Disp, BaseReg, IndexReg, Scale, Start, End,
1791 X86::RIP, Identifier, Decl, FrontendSize));
1799 IntelExprStateMachine &SM,
1800 bool &ParseError,
SMLoc &End) {
1804 !getParser().isParsingMasm())
1806 if (
Name.equals_insensitive(
"not")) {
1808 }
else if (
Name.equals_insensitive(
"or")) {
1810 }
else if (
Name.equals_insensitive(
"shl")) {
1812 }
else if (
Name.equals_insensitive(
"shr")) {
1814 }
else if (
Name.equals_insensitive(
"xor")) {
1816 }
else if (
Name.equals_insensitive(
"and")) {
1818 }
else if (
Name.equals_insensitive(
"mod")) {
1820 }
else if (
Name.equals_insensitive(
"offset")) {
1821 SMLoc OffsetLoc = getTok().getLoc();
1822 const MCExpr *Val =
nullptr;
1825 ParseError = ParseIntelOffsetOperator(Val,
ID, Info, End);
1830 SM.onOffset(Val, OffsetLoc,
ID, Info, isParsingMSInlineAsm(), ErrMsg);
1836 if (!
Name.equals_insensitive(
"offset"))
1837 End = consumeToken();
1841 IntelExprStateMachine &SM,
1842 bool &ParseError,
SMLoc &End) {
1843 if (
Name.equals_insensitive(
"eq")) {
1845 }
else if (
Name.equals_insensitive(
"ne")) {
1847 }
else if (
Name.equals_insensitive(
"lt")) {
1849 }
else if (
Name.equals_insensitive(
"le")) {
1851 }
else if (
Name.equals_insensitive(
"gt")) {
1853 }
else if (
Name.equals_insensitive(
"ge")) {
1858 End = consumeToken();
1865 IntelExprStateMachine &SM) {
1869 SM.setAppendAfterOperand();
1872bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM,
SMLoc &End) {
1878 if (getContext().getObjectFileInfo()->isPositionIndependent())
1887 bool UpdateLocLex =
true;
1892 if ((
Done = SM.isValidEndState()))
1894 return Error(Tok.
getLoc(),
"unknown token in expression");
1896 return Error(getLexer().getErrLoc(), getLexer().getErr());
1903 UpdateLocLex =
false;
1904 if (ParseIntelDotOperator(SM, End))
1909 if ((
Done = SM.isValidEndState()))
1911 return Error(Tok.
getLoc(),
"unknown token in expression");
1915 UpdateLocLex =
false;
1916 if (ParseIntelDotOperator(SM, End))
1921 if ((
Done = SM.isValidEndState()))
1923 return Error(Tok.
getLoc(),
"unknown token in expression");
1934 UpdateLocLex =
false;
1935 if (!Val->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
1936 return Error(ValueLoc,
"expected absolute value");
1937 if (SM.onInteger(Res, ErrMsg))
1938 return Error(ValueLoc, ErrMsg);
1947 UpdateLocLex =
false;
1949 size_t DotOffset =
Identifier.find_first_of(
'.');
1967 const AsmToken &NextTok = getLexer().peekTok();
1976 End = consumeToken();
1983 if (!ParseRegister(Reg, IdentLoc, End,
true)) {
1984 if (SM.onRegister(Reg, ErrMsg))
1985 return Error(IdentLoc, ErrMsg);
1989 const std::pair<StringRef, StringRef> IDField =
1993 if (!
Field.empty() &&
1994 !MatchRegisterByName(Reg,
ID, IdentLoc, IDEndLoc)) {
1995 if (SM.onRegister(Reg, ErrMsg))
1996 return Error(IdentLoc, ErrMsg);
2001 return Error(FieldStartLoc,
"unknown offset");
2002 else if (SM.onPlus(ErrMsg))
2003 return Error(getTok().getLoc(), ErrMsg);
2004 else if (SM.onInteger(
Info.Offset, ErrMsg))
2005 return Error(IdentLoc, ErrMsg);
2006 SM.setTypeInfo(
Info.Type);
2008 End = consumeToken();
2014 bool ParseError =
false;
2015 if (ParseIntelNamedOperator(Identifier, SM, ParseError, End)) {
2021 ParseMasmNamedOperator(Identifier, SM, ParseError, End)) {
2034 if (ParseIntelDotOperator(SM, End))
2039 if (isParsingMSInlineAsm()) {
2041 if (
unsigned OpKind = IdentifyIntelInlineAsmOperator(Identifier)) {
2042 if (int64_t Val = ParseIntelInlineAsmOperator(OpKind)) {
2043 if (SM.onInteger(Val, ErrMsg))
2044 return Error(IdentLoc, ErrMsg);
2053 return Error(IdentLoc,
"expected identifier");
2054 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
false, End))
2056 else if (SM.onIdentifierExpr(Val, Identifier, Info, FieldInfo.
Type,
2058 return Error(IdentLoc, ErrMsg);
2062 if (
unsigned OpKind = IdentifyMasmOperator(Identifier)) {
2064 if (ParseMasmOperator(OpKind, Val))
2066 if (SM.onInteger(Val, ErrMsg))
2067 return Error(IdentLoc, ErrMsg);
2070 if (!getParser().lookUpType(Identifier, FieldInfo.
Type)) {
2076 getParser().parseIdentifier(Identifier);
2080 if (getParser().lookUpField(FieldInfo.
Type.
Name, Identifier,
2084 return Error(IdentLoc,
"Unable to lookup field reference!",
2090 if (SM.onInteger(FieldInfo.
Offset, ErrMsg))
2091 return Error(IdentLoc, ErrMsg);
2095 if (getParser().parsePrimaryExpr(Val, End, &FieldInfo.
Type)) {
2096 return Error(Tok.
getLoc(),
"Unexpected identifier!");
2097 }
else if (SM.onIdentifierExpr(Val, Identifier, Info, FieldInfo.
Type,
2099 return Error(IdentLoc, ErrMsg);
2105 SMLoc Loc = getTok().getLoc();
2106 int64_t
IntVal = getTok().getIntVal();
2107 End = consumeToken();
2108 UpdateLocLex =
false;
2111 if (IDVal ==
"f" || IDVal ==
"b") {
2113 getContext().getDirectionalLocalSymbol(IntVal, IDVal ==
"b");
2118 return Error(Loc,
"invalid reference to undefined symbol");
2122 if (SM.onIdentifierExpr(Val, Identifier, Info,
Type,
2123 isParsingMSInlineAsm(), ErrMsg))
2124 return Error(Loc, ErrMsg);
2125 End = consumeToken();
2127 if (SM.onInteger(IntVal, ErrMsg))
2128 return Error(Loc, ErrMsg);
2131 if (SM.onInteger(IntVal, ErrMsg))
2132 return Error(Loc, ErrMsg);
2137 if (SM.onPlus(ErrMsg))
2138 return Error(getTok().getLoc(), ErrMsg);
2141 if (SM.onMinus(ErrMsg))
2142 return Error(getTok().getLoc(), ErrMsg);
2152 SM.onLShift();
break;
2154 SM.onRShift();
break;
2157 return Error(Tok.
getLoc(),
"unexpected bracket encountered");
2158 tryParseOperandIdx(PrevTK, SM);
2161 if (SM.onRBrac(ErrMsg)) {
2169 return Error(Tok.
getLoc(),
"unknown token in expression");
2171 if (!
Done && UpdateLocLex)
2172 End = consumeToken();
2179void X86AsmParser::RewriteIntelExpression(IntelExprStateMachine &SM,
2182 unsigned ExprLen = End.getPointer() - Start.getPointer();
2184 if (SM.getSym() && !SM.isOffsetOperator()) {
2186 if (
unsigned Len = SymName.
data() - Start.getPointer())
2189 ExprLen = End.getPointer() - (SymName.
data() + SymName.
size());
2192 if (!(SM.getBaseReg() || SM.getIndexReg() || SM.getImm())) {
2202 if (SM.getBaseReg())
2204 if (SM.getIndexReg())
2206 if (SM.isOffsetOperator())
2207 OffsetNameStr = SM.getSymName();
2209 IntelExpr Expr(BaseRegStr, IndexRegStr, SM.getScale(), OffsetNameStr,
2210 SM.getImm(), SM.isMemExpr());
2211 InstInfo->
AsmRewrites->emplace_back(Loc, ExprLen, Expr);
2215bool X86AsmParser::ParseIntelInlineAsmIdentifier(
2217 bool IsUnevaluatedOperand,
SMLoc &End,
bool IsParsingOffsetOperator) {
2219 assert(isParsingMSInlineAsm() &&
"Expected to be parsing inline assembly.");
2223 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);
2234 }
while (End.getPointer() < EndPtr);
2239 assert((End.getPointer() == EndPtr ||
2241 "frontend claimed part of a token?");
2247 SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(),
2249 assert(InternalName.
size() &&
"We should have an internal name here.");
2252 if (!IsParsingOffsetOperator)
2260 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
2271 const SMLoc consumedToken = consumeToken();
2273 return Error(Tok.
getLoc(),
"Expected an identifier after {");
2276 .
Case(
"rn", X86::STATIC_ROUNDING::TO_NEAREST_INT)
2277 .
Case(
"rd", X86::STATIC_ROUNDING::TO_NEG_INF)
2278 .
Case(
"ru", X86::STATIC_ROUNDING::TO_POS_INF)
2279 .
Case(
"rz", X86::STATIC_ROUNDING::TO_ZERO)
2282 return Error(Tok.
getLoc(),
"Invalid rounding mode.");
2285 return Error(Tok.
getLoc(),
"Expected - at this point");
2289 return Error(Tok.
getLoc(),
"Expected } at this point");
2292 const MCExpr *RndModeOp =
2300 return Error(Tok.
getLoc(),
"Expected } at this point");
2305 return Error(Tok.
getLoc(),
"unknown token in expression");
2309bool X86AsmParser::ParseIntelDotOperator(IntelExprStateMachine &SM,
2325 }
else if ((isParsingMSInlineAsm() || getParser().isParsingMasm()) &&
2328 TrailingDot = DotDispStr.
substr(DotDispStr.
size() - 1);
2331 const std::pair<StringRef, StringRef> BaseMember = DotDispStr.
split(
'.');
2333 if (getParser().lookUpField(SM.getType(), DotDispStr, Info) &&
2334 getParser().lookUpField(SM.getSymName(), DotDispStr, Info) &&
2335 getParser().lookUpField(DotDispStr, Info) &&
2337 SemaCallback->LookupInlineAsmField(
Base, Member,
Info.Offset)))
2338 return Error(Tok.
getLoc(),
"Unable to lookup field reference!");
2340 return Error(Tok.
getLoc(),
"Unexpected token type!");
2345 const char *DotExprEndLoc = DotDispStr.
data() + DotDispStr.
size();
2348 if (!TrailingDot.
empty())
2350 SM.addImm(
Info.Offset);
2351 SM.setTypeInfo(
Info.Type);
2361 SMLoc Start = Lex().getLoc();
2362 ID = getTok().getString();
2363 if (!isParsingMSInlineAsm()) {
2366 getParser().parsePrimaryExpr(Val, End,
nullptr))
2367 return Error(Start,
"unexpected token!");
2368 }
else if (ParseIntelInlineAsmIdentifier(Val,
ID, Info,
false, End,
true)) {
2369 return Error(Start,
"unable to lookup expression");
2371 return Error(Start,
"offset operator cannot yet handle constants");
2378unsigned X86AsmParser::IdentifyIntelInlineAsmOperator(
StringRef Name) {
2380 .
Cases(
"TYPE",
"type",IOK_TYPE)
2381 .
Cases(
"SIZE",
"size",IOK_SIZE)
2382 .
Cases(
"LENGTH",
"length",IOK_LENGTH)
2392unsigned X86AsmParser::ParseIntelInlineAsmOperator(
unsigned OpKind) {
2397 const MCExpr *Val =
nullptr;
2401 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
2406 Error(Start,
"unable to lookup expression");
2413 case IOK_LENGTH: CVal =
Info.Var.Length;
break;
2414 case IOK_SIZE: CVal =
Info.Var.Size;
break;
2415 case IOK_TYPE: CVal =
Info.Var.Type;
break;
2423unsigned X86AsmParser::IdentifyMasmOperator(
StringRef Name) {
2425 .
Case(
"type", MOK_TYPE)
2426 .
Cases(
"size",
"sizeof", MOK_SIZEOF)
2427 .
Cases(
"length",
"lengthof", MOK_LENGTHOF)
2437bool X86AsmParser::ParseMasmOperator(
unsigned OpKind, int64_t &Val) {
2443 if (OpKind == MOK_SIZEOF || OpKind == MOK_TYPE) {
2446 const AsmToken &IDTok = InParens ? getLexer().peekTok() : Parser.
getTok();
2462 IntelExprStateMachine SM;
2464 if (ParseIntelExpression(SM, End))
2474 Val = SM.getLength();
2477 Val = SM.getElementSize();
2482 return Error(OpLoc,
"expression has unknown type",
SMRange(Start, End));
2488bool X86AsmParser::ParseIntelMemoryOperandSize(
unsigned &
Size) {
2490 .
Cases(
"BYTE",
"byte", 8)
2491 .
Cases(
"WORD",
"word", 16)
2492 .
Cases(
"DWORD",
"dword", 32)
2493 .
Cases(
"FLOAT",
"float", 32)
2494 .
Cases(
"LONG",
"long", 32)
2495 .
Cases(
"FWORD",
"fword", 48)
2496 .
Cases(
"DOUBLE",
"double", 64)
2497 .
Cases(
"QWORD",
"qword", 64)
2498 .
Cases(
"MMWORD",
"mmword", 64)
2499 .
Cases(
"XWORD",
"xword", 80)
2500 .
Cases(
"TBYTE",
"tbyte", 80)
2501 .
Cases(
"XMMWORD",
"xmmword", 128)
2502 .
Cases(
"YMMWORD",
"ymmword", 256)
2503 .
Cases(
"ZMMWORD",
"zmmword", 512)
2508 return Error(Tok.
getLoc(),
"Expected 'PTR' or 'ptr' token!");
2521 if (ParseIntelMemoryOperandSize(
Size))
2529 return ParseRoundingModeOp(Start,
Operands);
2534 if (RegNo == X86::RIP)
2535 return Error(Start,
"rip can only be used as a base register");
2539 return Error(Start,
"expected memory operand after 'ptr', "
2540 "found register operand instead");
2545 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].
contains(RegNo))
2546 return Error(Start,
"invalid segment register");
2548 Start = Lex().getLoc();
2552 IntelExprStateMachine SM;
2553 if (ParseIntelExpression(SM, End))
2556 if (isParsingMSInlineAsm())
2557 RewriteIntelExpression(SM, Start, Tok.
getLoc());
2559 int64_t
Imm = SM.getImm();
2560 const MCExpr *Disp = SM.getSym();
2569 if (!SM.isMemExpr() && !RegNo) {
2570 if (isParsingMSInlineAsm() && SM.isOffsetOperator()) {
2576 SM.getSymName(),
Info.Var.Decl,
2577 Info.Var.IsGlobalLV));
2587 unsigned BaseReg = SM.getBaseReg();
2588 unsigned IndexReg = SM.getIndexReg();
2589 if (IndexReg && BaseReg == X86::RIP)
2591 unsigned Scale = SM.getScale();
2593 Size = SM.getElementSize() << 3;
2595 if (Scale == 0 && BaseReg != X86::ESP && BaseReg != X86::RSP &&
2596 (IndexReg == X86::ESP || IndexReg == X86::RSP))
2602 !(X86MCRegisterClasses[X86::VR128XRegClassID].
contains(IndexReg) ||
2603 X86MCRegisterClasses[X86::VR256XRegClassID].
contains(IndexReg) ||
2604 X86MCRegisterClasses[X86::VR512RegClassID].
contains(IndexReg)) &&
2605 (X86MCRegisterClasses[X86::VR128XRegClassID].
contains(BaseReg) ||
2606 X86MCRegisterClasses[X86::VR256XRegClassID].
contains(BaseReg) ||
2607 X86MCRegisterClasses[X86::VR512RegClassID].
contains(BaseReg)))
2611 X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg))
2612 return Error(Start,
"16-bit addresses cannot have a scale");
2621 if ((BaseReg == X86::SI || BaseReg == X86::DI) &&
2622 (IndexReg == X86::BX || IndexReg == X86::BP))
2625 if ((BaseReg || IndexReg) &&
2628 return Error(Start, ErrMsg);
2629 if (isParsingMSInlineAsm())
2630 return CreateMemForMSInlineAsm(RegNo, Disp, BaseReg, IndexReg, Scale, Start,
2631 End,
Size, SM.getSymName(),
2636 unsigned DefaultBaseReg = X86::NoRegister;
2637 bool MaybeDirectBranchDest =
true;
2640 bool IsUnconditionalBranch =
2641 Name.equals_insensitive(
"jmp") ||
Name.equals_insensitive(
"call");
2642 if (is64BitMode() && SM.getElementSize() > 0) {
2643 DefaultBaseReg = X86::RIP;
2645 if (IsUnconditionalBranch) {
2647 MaybeDirectBranchDest =
false;
2649 DefaultBaseReg = X86::RIP;
2650 }
else if (!BaseReg && !IndexReg && Disp &&
2652 if (is64BitMode()) {
2653 if (SM.getSize() == 8) {
2654 MaybeDirectBranchDest =
false;
2655 DefaultBaseReg = X86::RIP;
2658 if (SM.getSize() == 4 || SM.getSize() == 2)
2659 MaybeDirectBranchDest =
false;
2665 if ((BaseReg || IndexReg || RegNo || DefaultBaseReg != X86::NoRegister))
2667 getPointerWidth(), RegNo, Disp, BaseReg, IndexReg, Scale, Start, End,
2669 0,
false, MaybeDirectBranchDest));
2674 MaybeDirectBranchDest));
2680 switch (getLexer().getKind()) {
2690 "expected immediate expression") ||
2691 getParser().parseExpression(Val, End) ||
2692 check(isa<X86MCExpr>(Val), L,
"expected immediate expression"))
2699 return ParseRoundingModeOp(Start,
Operands);
2708 const MCExpr *Expr =
nullptr;
2714 if (
auto *RE = dyn_cast<X86MCExpr>(Expr)) {
2717 Reg = RE->getRegNo();
2720 if (Reg == X86::EIZ || Reg == X86::RIZ)
2722 Loc,
"%eiz and %riz can only be used as index registers",
2724 if (Reg == X86::RIP)
2725 return Error(Loc,
"%rip can only be used as a base register",
2732 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].
contains(Reg))
2733 return Error(Loc,
"invalid segment register");
2741 return ParseMemOperand(Reg, Expr, Loc, EndLoc,
Operands);
2771bool X86AsmParser::ParseZ(std::unique_ptr<X86Operand> &Z,
2772 const SMLoc &StartLoc) {
2778 (getLexer().getTok().getIdentifier() ==
"z")))
2783 return Error(getLexer().getLoc(),
"Expected } at this point");
2795 const SMLoc consumedToken = consumeToken();
2799 if (getLexer().getTok().getIntVal() != 1)
2800 return TokError(
"Expected 1to<NUM> at this point");
2804 return TokError(
"Expected 1to<NUM> at this point");
2807 StringRef BroadcastString = (
Prefix + getLexer().getTok().getIdentifier())
2810 return TokError(
"Expected 1to<NUM> at this point");
2811 const char *BroadcastPrimitive =
2813 .
Case(
"1to2",
"{1to2}")
2814 .
Case(
"1to4",
"{1to4}")
2815 .
Case(
"1to8",
"{1to8}")
2816 .
Case(
"1to16",
"{1to16}")
2817 .
Case(
"1to32",
"{1to32}")
2819 if (!BroadcastPrimitive)
2820 return TokError(
"Invalid memory broadcast primitive.");
2823 return TokError(
"Expected } at this point");
2834 std::unique_ptr<X86Operand>
Z;
2835 if (ParseZ(Z, consumedToken))
2841 SMLoc StartLoc =
Z ? consumeToken() : consumedToken;
2846 if (!parseRegister(RegNo, RegLoc, StartLoc) &&
2847 X86MCRegisterClasses[X86::VK1RegClassID].
contains(RegNo)) {
2848 if (RegNo == X86::K0)
2849 return Error(RegLoc,
"Register k0 can't be used as write mask");
2851 return Error(getLexer().getLoc(),
"Expected } at this point");
2857 return Error(getLexer().getLoc(),
2858 "Expected an op-mask register at this point");
2863 if (ParseZ(Z, consumeToken()) || !Z)
2864 return Error(getLexer().getLoc(),
2865 "Expected a {z} mark at this point");
2881bool X86AsmParser::ParseMemOperand(
unsigned SegReg,
const MCExpr *Disp,
2902 auto isAtMemOperand = [
this]() {
2907 auto TokCount = this->getLexer().peekTokens(Buf,
true);
2910 switch (Buf[0].getKind()) {
2917 if ((TokCount > 1) &&
2919 (Buf[0].getLoc().getPointer() + 1 == Buf[1].getLoc().getPointer()))
2921 Buf[1].getIdentifier().
size() + 1);
2932 MCSymbol *Sym = this->getContext().getOrCreateSymbol(Id);
2935 return isa<X86MCExpr>(V);
2943 if (!isAtMemOperand()) {
2946 assert(!isa<X86MCExpr>(Disp) &&
"Expected non-register here.");
2962 0, 0, 1, StartLoc, EndLoc));
2968 unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
2969 SMLoc BaseLoc = getLexer().getLoc();
2976 check(!isa<X86MCExpr>(
E), BaseLoc,
"expected register here"))
2980 BaseReg = cast<X86MCExpr>(
E)->getRegNo();
2981 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ)
2982 return Error(BaseLoc,
"eiz and riz can only be used as index registers",
2997 if (!isa<X86MCExpr>(
E)) {
3001 if (!
E->evaluateAsAbsolute(ScaleVal, getStreamer().getAssemblerPtr()))
3002 return Error(Loc,
"expected absolute expression");
3004 Warning(Loc,
"scale factor without index register is ignored");
3007 IndexReg = cast<X86MCExpr>(
E)->getRegNo();
3009 if (BaseReg == X86::RIP)
3011 "%rip as base register can not have an index register");
3012 if (IndexReg == X86::RIP)
3013 return Error(Loc,
"%rip is not allowed as an index register");
3024 return Error(Loc,
"expected scale expression");
3027 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg) &&
3029 return Error(Loc,
"scale factor in 16-bit address must be 1");
3031 return Error(Loc, ErrMsg);
3045 if (BaseReg == X86::DX && IndexReg == 0 && Scale == 1 && SegReg == 0 &&
3046 isa<MCConstantExpr>(Disp) &&
3047 cast<MCConstantExpr>(Disp)->getValue() == 0) {
3054 return Error(BaseLoc, ErrMsg);
3056 if (SegReg || BaseReg || IndexReg)
3058 BaseReg, IndexReg, Scale, StartLoc,
3067bool X86AsmParser::parsePrimaryExpr(
const MCExpr *&Res,
SMLoc &EndLoc) {
3075 if (parseRegister(RegNo, StartLoc, EndLoc))
3089 ForcedVEXEncoding = VEXEncoding_Default;
3090 ForcedDispEncoding = DispEncoding_Default;
3103 if (Prefix ==
"vex")
3104 ForcedVEXEncoding = VEXEncoding_VEX;
3105 else if (Prefix ==
"vex2")
3106 ForcedVEXEncoding = VEXEncoding_VEX2;
3107 else if (Prefix ==
"vex3")
3108 ForcedVEXEncoding = VEXEncoding_VEX3;
3109 else if (Prefix ==
"evex")
3110 ForcedVEXEncoding = VEXEncoding_EVEX;
3111 else if (Prefix ==
"disp8")
3112 ForcedDispEncoding = DispEncoding_Disp8;
3113 else if (Prefix ==
"disp32")
3114 ForcedDispEncoding = DispEncoding_Disp32;
3116 return Error(NameLoc,
"unknown prefix");
3132 if (isParsingMSInlineAsm()) {
3133 if (
Name.equals_insensitive(
"vex"))
3134 ForcedVEXEncoding = VEXEncoding_VEX;
3135 else if (
Name.equals_insensitive(
"vex2"))
3136 ForcedVEXEncoding = VEXEncoding_VEX2;
3137 else if (
Name.equals_insensitive(
"vex3"))
3138 ForcedVEXEncoding = VEXEncoding_VEX3;
3139 else if (
Name.equals_insensitive(
"evex"))
3140 ForcedVEXEncoding = VEXEncoding_EVEX;
3142 if (ForcedVEXEncoding != VEXEncoding_Default) {
3155 if (
Name.consume_back(
".d32")) {
3156 ForcedDispEncoding = DispEncoding_Disp32;
3157 }
else if (
Name.consume_back(
".d8")) {
3158 ForcedDispEncoding = DispEncoding_Disp8;
3164 if (isParsingIntelSyntax() &&
3165 (PatchedName ==
"jmp" || PatchedName ==
"jc" || PatchedName ==
"jnc" ||
3166 PatchedName ==
"jcxz" || PatchedName ==
"jecxz" ||
3171 : NextTok ==
"short") {
3180 NextTok.
size() + 1);
3186 PatchedName !=
"setb" && PatchedName !=
"setnb")
3187 PatchedName = PatchedName.
substr(0,
Name.size()-1);
3189 unsigned ComparisonPredicate = ~0
U;
3196 bool IsVCMP = PatchedName[0] ==
'v';
3197 unsigned CCIdx =
IsVCMP ? 4 : 3;
3199 PatchedName.
slice(CCIdx, PatchedName.
size() - 2))
3201 .
Case(
"eq_oq", 0x00)
3203 .
Case(
"lt_os", 0x01)
3205 .
Case(
"le_os", 0x02)
3206 .
Case(
"unord", 0x03)
3207 .
Case(
"unord_q", 0x03)
3209 .
Case(
"neq_uq", 0x04)
3211 .
Case(
"nlt_us", 0x05)
3213 .
Case(
"nle_us", 0x06)
3215 .
Case(
"ord_q", 0x07)
3217 .
Case(
"eq_uq", 0x08)
3219 .
Case(
"nge_us", 0x09)
3221 .
Case(
"ngt_us", 0x0A)
3222 .
Case(
"false", 0x0B)
3223 .
Case(
"false_oq", 0x0B)
3224 .
Case(
"neq_oq", 0x0C)
3226 .
Case(
"ge_os", 0x0D)
3228 .
Case(
"gt_os", 0x0E)
3230 .
Case(
"true_uq", 0x0F)
3231 .
Case(
"eq_os", 0x10)
3232 .
Case(
"lt_oq", 0x11)
3233 .
Case(
"le_oq", 0x12)
3234 .
Case(
"unord_s", 0x13)
3235 .
Case(
"neq_us", 0x14)
3236 .
Case(
"nlt_uq", 0x15)
3237 .
Case(
"nle_uq", 0x16)
3238 .
Case(
"ord_s", 0x17)
3239 .
Case(
"eq_us", 0x18)
3240 .
Case(
"nge_uq", 0x19)
3241 .
Case(
"ngt_uq", 0x1A)
3242 .
Case(
"false_os", 0x1B)
3243 .
Case(
"neq_os", 0x1C)
3244 .
Case(
"ge_oq", 0x1D)
3245 .
Case(
"gt_oq", 0x1E)
3246 .
Case(
"true_us", 0x1F)
3251 PatchedName =
IsVCMP ?
"vcmpss" :
"cmpss";
3252 else if (PatchedName.
endswith(
"sd"))
3253 PatchedName =
IsVCMP ?
"vcmpsd" :
"cmpsd";
3254 else if (PatchedName.
endswith(
"ps"))
3255 PatchedName =
IsVCMP ?
"vcmpps" :
"cmpps";
3256 else if (PatchedName.
endswith(
"pd"))
3257 PatchedName =
IsVCMP ?
"vcmppd" :
"cmppd";
3258 else if (PatchedName.
endswith(
"sh"))
3259 PatchedName =
"vcmpsh";
3260 else if (PatchedName.
endswith(
"ph"))
3261 PatchedName =
"vcmpph";
3265 ComparisonPredicate =
CC;
3271 (PatchedName.
back() ==
'b' || PatchedName.
back() ==
'w' ||
3272 PatchedName.
back() ==
'd' || PatchedName.
back() ==
'q')) {
3273 unsigned SuffixSize = PatchedName.
drop_back().
back() ==
'u' ? 2 : 1;
3275 PatchedName.
slice(5, PatchedName.
size() - SuffixSize))
3285 if (
CC != ~0U && (
CC != 0 || SuffixSize == 2)) {
3286 switch (PatchedName.
back()) {
3288 case 'b': PatchedName = SuffixSize == 2 ?
"vpcmpub" :
"vpcmpb";
break;
3289 case 'w': PatchedName = SuffixSize == 2 ?
"vpcmpuw" :
"vpcmpw";
break;
3290 case 'd': PatchedName = SuffixSize == 2 ?
"vpcmpud" :
"vpcmpd";
break;
3291 case 'q': PatchedName = SuffixSize == 2 ?
"vpcmpuq" :
"vpcmpq";
break;
3294 ComparisonPredicate =
CC;
3300 (PatchedName.
back() ==
'b' || PatchedName.
back() ==
'w' ||
3301 PatchedName.
back() ==
'd' || PatchedName.
back() ==
'q')) {
3302 unsigned SuffixSize = PatchedName.
drop_back().
back() ==
'u' ? 2 : 1;
3304 PatchedName.
slice(5, PatchedName.
size() - SuffixSize))
3315 switch (PatchedName.
back()) {
3317 case 'b': PatchedName = SuffixSize == 2 ?
"vpcomub" :
"vpcomb";
break;
3318 case 'w': PatchedName = SuffixSize == 2 ?
"vpcomuw" :
"vpcomw";
break;
3319 case 'd': PatchedName = SuffixSize == 2 ?
"vpcomud" :
"vpcomd";
break;
3320 case 'q': PatchedName = SuffixSize == 2 ?
"vpcomuq" :
"vpcomq";
break;
3323 ComparisonPredicate =
CC;
3337 .
Cases(
"cs",
"ds",
"es",
"fs",
"gs",
"ss",
true)
3338 .
Cases(
"rex64",
"data32",
"data16",
"addr32",
"addr16",
true)
3339 .
Cases(
"xacquire",
"xrelease",
true)
3340 .
Cases(
"acquire",
"release", isParsingIntelSyntax())
3343 auto isLockRepeatNtPrefix = [](
StringRef N) {
3345 .
Cases(
"lock",
"rep",
"repe",
"repz",
"repne",
"repnz",
"notrack",
true)
3349 bool CurlyAsEndOfStatement =
false;
3352 while (isLockRepeatNtPrefix(
Name.lower())) {
3373 while (
Name.startswith(
";") ||
Name.startswith(
"\n") ||
3374 Name.startswith(
"#") ||
Name.startswith(
"\t") ||
3375 Name.startswith(
"/")) {
3386 if (PatchedName ==
"data16" && is16BitMode()) {
3387 return Error(NameLoc,
"redundant data16 prefix");
3389 if (PatchedName ==
"data32") {
3391 return Error(NameLoc,
"redundant data32 prefix");
3393 return Error(NameLoc,
"'data32' is not supported in 64-bit mode");
3395 PatchedName =
"data16";
3402 if (Next ==
"callw")
3404 if (Next ==
"ljmpw")
3409 ForcedDataPrefix = X86::Is32Bit;
3417 if (ComparisonPredicate != ~0U && !isParsingIntelSyntax()) {
3419 getParser().getContext());
3448 CurlyAsEndOfStatement =
3449 isParsingIntelSyntax() && isParsingMSInlineAsm() &&
3452 return TokError(
"unexpected token in argument list");
3456 if (ComparisonPredicate != ~0U && isParsingIntelSyntax()) {
3458 getParser().getContext());
3466 else if (CurlyAsEndOfStatement)
3469 getLexer().getTok().getLoc(), 0);
3476 if (IsFp &&
Operands.size() == 1) {
3478 .
Case(
"fsub",
"fsubp")
3479 .
Case(
"fdiv",
"fdivp")
3480 .
Case(
"fsubr",
"fsubrp")
3481 .
Case(
"fdivr",
"fdivrp");
3485 if ((
Name ==
"mov" ||
Name ==
"movw" ||
Name ==
"movl") &&
3493 X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(
3495 (X86MCRegisterClasses[X86::GR16RegClassID].
contains(Op1.
getReg()) ||
3496 X86MCRegisterClasses[X86::GR32RegClassID].
contains(Op1.
getReg()))) {
3498 if (
Name !=
"mov" &&
Name[3] == (is16BitMode() ?
'l' :
'w')) {
3499 Name = is16BitMode() ?
"movw" :
"movl";
3512 if ((
Name ==
"outb" ||
Name ==
"outsb" ||
Name ==
"outw" ||
Name ==
"outsw" ||
3531 bool HadVerifyError =
false;
3534 if (
Name.startswith(
"ins") &&
3539 AddDefaultSrcDestOperands(TmpOperands,
3541 DefaultMemDIOperand(NameLoc));
3542 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3546 if (
Name.startswith(
"outs") &&
3548 (
Name ==
"outsb" ||
Name ==
"outsw" ||
Name ==
"outsl" ||
3549 Name ==
"outsd" ||
Name ==
"outs")) {
3550 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
3552 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3558 if (
Name.startswith(
"lods") &&
3560 (
Name ==
"lods" ||
Name ==
"lodsb" ||
Name ==
"lodsw" ||
3561 Name ==
"lodsl" ||
Name ==
"lodsd" ||
Name ==
"lodsq")) {
3562 TmpOperands.
push_back(DefaultMemSIOperand(NameLoc));
3563 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3569 if (
Name.startswith(
"stos") &&
3571 (
Name ==
"stos" ||
Name ==
"stosb" ||
Name ==
"stosw" ||
3572 Name ==
"stosl" ||
Name ==
"stosd" ||
Name ==
"stosq")) {
3573 TmpOperands.
push_back(DefaultMemDIOperand(NameLoc));
3574 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3580 if (
Name.startswith(
"scas") &&
3582 (
Name ==
"scas" ||
Name ==
"scasb" ||
Name ==
"scasw" ||
3583 Name ==
"scasl" ||
Name ==
"scasd" ||
Name ==
"scasq")) {
3584 TmpOperands.
push_back(DefaultMemDIOperand(NameLoc));
3585 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3589 if (
Name.startswith(
"cmps") &&
3591 (
Name ==
"cmps" ||
Name ==
"cmpsb" ||
Name ==
"cmpsw" ||
3592 Name ==
"cmpsl" ||
Name ==
"cmpsd" ||
Name ==
"cmpsq")) {
3593 AddDefaultSrcDestOperands(TmpOperands, DefaultMemDIOperand(NameLoc),
3594 DefaultMemSIOperand(NameLoc));
3595 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3599 if (((
Name.startswith(
"movs") &&
3600 (
Name ==
"movs" ||
Name ==
"movsb" ||
Name ==
"movsw" ||
3601 Name ==
"movsl" ||
Name ==
"movsd" ||
Name ==
"movsq")) ||
3602 (
Name.startswith(
"smov") &&
3603 (
Name ==
"smov" ||
Name ==
"smovb" ||
Name ==
"smovw" ||
3604 Name ==
"smovl" ||
Name ==
"smovd" ||
Name ==
"smovq"))) &&
3606 if (
Name ==
"movsd" &&
Operands.size() == 1 && !isParsingIntelSyntax())
3608 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
3609 DefaultMemDIOperand(NameLoc));
3610 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3614 if (HadVerifyError) {
3615 return HadVerifyError;
3623 "size, (R|E)BX will be used for the location");
3638 default:
return false;
3643 if (ForcedDispEncoding == DispEncoding_Disp32) {
3644 Inst.
setOpcode(is16BitMode() ? X86::JMP_2 : X86::JMP_4);
3653 if (ForcedDispEncoding == DispEncoding_Disp32) {
3654 Inst.
setOpcode(is16BitMode() ? X86::JCC_2 : X86::JCC_4);
3659 case X86::VMOVZPQILo2PQIrr:
3660 case X86::VMOVAPDrr:
3661 case X86::VMOVAPDYrr:
3662 case X86::VMOVAPSrr:
3663 case X86::VMOVAPSYrr:
3664 case X86::VMOVDQArr:
3665 case X86::VMOVDQAYrr:
3666 case X86::VMOVDQUrr:
3667 case X86::VMOVDQUYrr:
3668 case X86::VMOVUPDrr:
3669 case X86::VMOVUPDYrr:
3670 case X86::VMOVUPSrr:
3671 case X86::VMOVUPSYrr: {
3674 if (ForcedVEXEncoding == VEXEncoding_VEX3 ||
3682 case X86::VMOVZPQILo2PQIrr: NewOpc = X86::VMOVPQI2QIrr;
break;
3683 case X86::VMOVAPDrr: NewOpc = X86::VMOVAPDrr_REV;
break;
3684 case X86::VMOVAPDYrr: NewOpc = X86::VMOVAPDYrr_REV;
break;
3685 case X86::VMOVAPSrr: NewOpc = X86::VMOVAPSrr_REV;
break;
3686 case X86::VMOVAPSYrr: NewOpc = X86::VMOVAPSYrr_REV;
break;
3687 case X86::VMOVDQArr: NewOpc = X86::VMOVDQArr_REV;
break;
3688 case X86::VMOVDQAYrr: NewOpc = X86::VMOVDQAYrr_REV;
break;
3689 case X86::VMOVDQUrr: NewOpc = X86::VMOVDQUrr_REV;
break;
3690 case X86::VMOVDQUYrr: NewOpc = X86::VMOVDQUYrr_REV;
break;
3691 case X86::VMOVUPDrr: NewOpc = X86::VMOVUPDrr_REV;
break;
3692 case X86::VMOVUPDYrr: NewOpc = X86::VMOVUPDYrr_REV;
break;
3693 case X86::VMOVUPSrr: NewOpc = X86::VMOVUPSrr_REV;
break;
3694 case X86::VMOVUPSYrr: NewOpc = X86::VMOVUPSYrr_REV;
break;
3700 case X86::VMOVSSrr: {
3703 if (ForcedVEXEncoding == VEXEncoding_VEX3 ||
3711 case X86::VMOVSDrr: NewOpc = X86::VMOVSDrr_REV;
break;
3712 case X86::VMOVSSrr: NewOpc = X86::VMOVSSrr_REV;
break;
3717 case X86::RCR8ri:
case X86::RCR16ri:
case X86::RCR32ri:
case X86::RCR64ri:
3718 case X86::RCL8ri:
case X86::RCL16ri:
case X86::RCL32ri:
case X86::RCL64ri:
3719 case X86::ROR8ri:
case X86::ROR16ri:
case X86::ROR32ri:
case X86::ROR64ri:
3720 case X86::ROL8ri:
case X86::ROL16ri:
case X86::ROL32ri:
case X86::ROL64ri:
3721 case X86::SAR8ri:
case X86::SAR16ri:
case X86::SAR32ri:
case X86::SAR64ri:
3722 case X86::SHR8ri:
case X86::SHR16ri:
case X86::SHR32ri:
case X86::SHR64ri:
3723 case X86::SHL8ri:
case X86::SHL16ri:
case X86::SHL32ri:
case X86::SHL64ri: {
3732 case X86::RCR8ri: NewOpc = X86::RCR8r1;
break;
3733 case X86::RCR16ri: NewOpc = X86::RCR16r1;
break;
3734 case X86::RCR32ri: NewOpc = X86::RCR32r1;
break;
3735 case X86::RCR64ri: NewOpc = X86::RCR64r1;
break;
3736 case X86::RCL8ri: NewOpc = X86::RCL8r1;
break;
3737 case X86::RCL16ri: NewOpc = X86::RCL16r1;
break;
3738 case X86::RCL32ri: NewOpc = X86::RCL32r1;
break;
3739 case X86::RCL64ri: NewOpc = X86::RCL64r1;
break;
3740 case X86::ROR8ri: NewOpc = X86::ROR8r1;
break;
3741 case X86::ROR16ri: NewOpc = X86::ROR16r1;
break;
3742 case X86::ROR32ri: NewOpc = X86::ROR32r1;
break;
3743 case X86::ROR64ri: NewOpc = X86::ROR64r1;
break;
3744 case X86::ROL8ri: NewOpc = X86::ROL8r1;
break;
3745 case X86::ROL16ri: NewOpc = X86::ROL16r1;
break;
3746 case X86::ROL32ri: NewOpc = X86::ROL32r1;
break;
3747 case X86::ROL64ri: NewOpc = X86::ROL64r1;
break;
3748 case X86::SAR8ri: NewOpc = X86::SAR8r1;
break;
3749 case X86::SAR16ri: NewOpc = X86::SAR16r1;
break;
3750 case X86::SAR32ri: NewOpc = X86::SAR32r1;
break;
3751 case X86::SAR64ri: NewOpc = X86::SAR64r1;
break;
3752 case X86::SHR8ri: NewOpc = X86::SHR8r1;
break;
3753 case X86::SHR16ri: NewOpc = X86::SHR16r1;
break;
3754 case X86::SHR32ri: NewOpc = X86::SHR32r1;
break;
3755 case X86::SHR64ri: NewOpc = X86::SHR64r1;
break;
3756 case X86::SHL8ri: NewOpc = X86::SHL8r1;
break;
3757 case X86::SHL16ri: NewOpc = X86::SHL16r1;
break;
3758 case X86::SHL32ri: NewOpc = X86::SHL32r1;
break;
3759 case X86::SHL64ri: NewOpc = X86::SHL64r1;
break;
3769 case X86::RCR8mi:
case X86::RCR16mi:
case X86::RCR32mi:
case X86::RCR64mi:
3770 case X86::RCL8mi:
case X86::RCL16mi:
case X86::RCL32mi:
case X86::RCL64mi:
3771 case X86::ROR8mi:
case X86::ROR16mi:
case X86::ROR32mi:
case X86::ROR64mi:
3772 case X86::ROL8mi:
case X86::ROL16mi:
case X86::ROL32mi:
case X86::ROL64mi:
3773 case X86::SAR8mi:
case X86::SAR16mi:
case X86::SAR32mi:
case X86::SAR64mi:
3774 case X86::SHR8mi:
case X86::SHR16mi:
case X86::SHR32mi:
case X86::SHR64mi:
3775 case X86::SHL8mi:
case X86::SHL16mi:
case X86::SHL32mi:
case X86::SHL64mi: {
3785 case X86::RCR8mi: NewOpc = X86::RCR8m1;
break;
3786 case X86::RCR16mi: NewOpc = X86::RCR16m1;
break;
3787 case X86::RCR32mi: NewOpc = X86::RCR32m1;
break;
3788 case X86::RCR64mi: NewOpc = X86::RCR64m1;
break;
3789 case X86::RCL8mi: NewOpc = X86::RCL8m1;
break;
3790 case X86::RCL16mi: NewOpc = X86::RCL16m1;
break;
3791 case X86::RCL32mi: NewOpc = X86::RCL32m1;
break;
3792 case X86::RCL64mi: NewOpc = X86::RCL64m1;
break;
3793 case X86::ROR8mi: NewOpc = X86::ROR8m1;
break;
3794 case X86::ROR16mi: NewOpc = X86::ROR16m1;
break;
3795 case X86::ROR32mi: NewOpc = X86::ROR32m1;
break;
3796 case X86::ROR64mi: NewOpc = X86::ROR64m1;
break;
3797 case X86::ROL8mi: NewOpc = X86::ROL8m1;
break;
3798 case X86::ROL16mi: NewOpc = X86::ROL16m1;
break;
3799 case X86::ROL32mi: NewOpc = X86::ROL32m1;
break;
3800 case X86::ROL64mi: NewOpc = X86::ROL64m1;
break;
3801 case X86::SAR8mi: NewOpc = X86::SAR8m1;
break;
3802 case X86::SAR16mi: NewOpc = X86::SAR16m1;
break;
3803 case X86::SAR32mi: NewOpc = X86::SAR32m1;
break;
3804 case X86::SAR64mi: NewOpc = X86::SAR64m1;
break;
3805 case X86::SHR8mi: NewOpc = X86::SHR8m1;
break;
3806 case X86::SHR16mi: NewOpc = X86::SHR16m1;
break;
3807 case X86::SHR32mi: NewOpc = X86::SHR32m1;
break;
3808 case X86::SHR64mi: NewOpc = X86::SHR64m1;
break;
3809 case X86::SHL8mi: NewOpc = X86::SHL8m1;
break;
3810 case X86::SHL16mi: NewOpc = X86::SHL16m1;
break;
3811 case X86::SHL32mi: NewOpc = X86::SHL32m1;
break;
3812 case X86::SHL64mi: NewOpc = X86::SHL64m1;
break;
3837 using namespace X86;
3841 if (isVFCMADDCPH(Opcode) || isVFCMADDCSH(Opcode) || isVFMADDCPH(Opcode) ||
3842 isVFMADDCSH(Opcode)) {
3846 return Warning(Ops[0]->getStartLoc(),
"Destination register should be "
3847 "distinct from source registers");
3848 }
else if (isVFCMULCPH(Opcode) || isVFCMULCSH(Opcode) || isVFMULCPH(Opcode) ||
3849 isVFMULCSH(Opcode)) {
3859 return Warning(Ops[0]->getStartLoc(),
"Destination register should be "
3860 "distinct from source registers");
3861 }
else if (isV4FMADDPS(Opcode) || isV4FMADDSS(Opcode) ||
3862 isV4FNMADDPS(Opcode) || isV4FNMADDSS(Opcode) ||
3863 isVP4DPWSSDS(Opcode) || isVP4DPWSSD(Opcode)) {
3866 unsigned Src2Enc =
MRI->getEncodingValue(Src2);
3867 if (Src2Enc % 4 != 0) {
3869 unsigned GroupStart = (Src2Enc / 4) * 4;
3870 unsigned GroupEnd = GroupStart + 3;
3871 return Warning(Ops[0]->getStartLoc(),
3872 "source register '" +
RegName +
"' implicitly denotes '" +
3877 }
else if (isVGATHERDPD(Opcode) || isVGATHERDPS(Opcode) ||
3878 isVGATHERQPD(Opcode) || isVGATHERQPS(Opcode) ||
3879 isVPGATHERDD(Opcode) || isVPGATHERDQ(Opcode) ||
3880 isVPGATHERQD(Opcode) || isVPGATHERQQ(Opcode)) {
3884 unsigned Index =
MRI->getEncodingValue(
3887 return Warning(Ops[0]->getStartLoc(),
"index and destination registers "
3888 "should be distinct");
3892 unsigned Index =
MRI->getEncodingValue(
3894 if (Dest == Mask || Dest ==
Index || Mask ==
Index)
3895 return Warning(Ops[0]->getStartLoc(),
"mask, index, and destination "
3896 "registers should be distinct");
3906 for (
unsigned i = 0; i != NumOps; ++i) {
3911 if (Reg == X86::AH || Reg == X86::BH || Reg == X86::CH || Reg == X86::DH)
3918 if (UsesRex && HReg != X86::NoRegister) {
3920 return Error(Ops[0]->getStartLoc(),
3921 "can't encode '" +
RegName +
"' in an instruction requiring "
3926 if ((Opcode == X86::PREFETCHIT0 || Opcode == X86::PREFETCHIT1)) {
3930 Ops[0]->getStartLoc(),
3932 :
"'prefetchit1'")) +
3933 " only supports RIP-relative address");
3940void X86AsmParser::emitWarningForSpecialLVIInstruction(
SMLoc Loc) {
3941 Warning(Loc,
"Instruction may be vulnerable to LVI and "
3942 "requires manual mitigation");
3943 Note(
SMLoc(),
"See https://software.intel.com/"
3944 "security-software-guidance/insights/"
3945 "deep-dive-load-value-injection#specialinstructions"
3946 " for more information");
3970 bool Parse32 = is32BitMode() || Code16GCC;
3972 is64BitMode() ? X86::RSP : (Parse32 ? X86::ESP : X86::SP);
3978 ShlMemOp->addMemOperands(ShlInst, 5);
3991 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4003void X86AsmParser::applyLVILoadHardeningMitigation(
MCInst &Inst,
4020 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4023 }
else if (Opcode == X86::REP_PREFIX || Opcode == X86::REPNE_PREFIX) {
4026 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
4048 getSTI().hasFeature(X86::FeatureLVIControlFlowIntegrity))
4049 applyLVICFIMitigation(Inst, Out);
4054 getSTI().hasFeature(X86::FeatureLVILoadHardening))
4055 applyLVILoadHardeningMitigation(Inst, Out);
4058bool X86AsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
4061 bool MatchingInlineAsm) {
4062 if (isParsingIntelSyntax())
4071 bool MatchingInlineAsm) {
4076 .
Case(
"finit",
"fninit")
4077 .
Case(
"fsave",
"fnsave")
4078 .
Case(
"fstcw",
"fnstcw")
4079 .
Case(
"fstcww",
"fnstcw")
4080 .
Case(
"fstenv",
"fnstenv")
4081 .
Case(
"fstsw",
"fnstsw")
4082 .
Case(
"fstsww",
"fnstsw")
4083 .
Case(
"fclex",
"fnclex")
4089 if (!MatchingInlineAsm)
4090 emitInstruction(Inst,
Operands, Out);
4095bool X86AsmParser::ErrorMissingFeature(
SMLoc IDLoc,
4097 bool MatchingInlineAsm) {
4098 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
4101 OS <<
"instruction requires:";
4102 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
4103 if (MissingFeatures[i])
4110 unsigned Result = 0;
4112 if (Prefix.isPrefix()) {
4113 Result = Prefix.getPrefix();
4119unsigned X86AsmParser::checkTargetMatchPredicate(
MCInst &Inst) {
4123 if (ForcedVEXEncoding == VEXEncoding_EVEX &&
4125 return Match_Unsupported;
4127 if ((ForcedVEXEncoding == VEXEncoding_VEX ||
4128 ForcedVEXEncoding == VEXEncoding_VEX2 ||
4129 ForcedVEXEncoding == VEXEncoding_VEX3) &&
4131 return Match_Unsupported;
4135 (ForcedVEXEncoding != VEXEncoding_VEX &&
4136 ForcedVEXEncoding != VEXEncoding_VEX2 &&
4137 ForcedVEXEncoding != VEXEncoding_VEX3))
4138 return Match_Unsupported;
4140 return Match_Success;
4143bool X86AsmParser::MatchAndEmitATTInstruction(
SMLoc IDLoc,
unsigned &Opcode,
4147 bool MatchingInlineAsm) {
4149 assert((*
Operands[0]).isToken() &&
"Leading operand should always be a mnemonic!");
4150 SMRange EmptyRange = std::nullopt;
4154 Out, MatchingInlineAsm);
4162 if (ForcedVEXEncoding == VEXEncoding_VEX)
4164 else if (ForcedVEXEncoding == VEXEncoding_VEX2)
4166 else if (ForcedVEXEncoding == VEXEncoding_VEX3)
4168 else if (ForcedVEXEncoding == VEXEncoding_EVEX)
4172 if (ForcedDispEncoding == DispEncoding_Disp8)
4174 else if (ForcedDispEncoding == DispEncoding_Disp32)
4182 if (ForcedDataPrefix == X86::Is32Bit)
4183 SwitchMode(X86::Is32Bit);
4187 MissingFeatures, MatchingInlineAsm,
4188 isParsingIntelSyntax());
4189 if (ForcedDataPrefix == X86::Is32Bit) {
4190 SwitchMode(X86::Is16Bit);
4191 ForcedDataPrefix = 0;
4193 switch (OriginalError) {
4196 if (!MatchingInlineAsm && validateInstruction(Inst,
Operands))
4201 if (!MatchingInlineAsm)
4202 while (processInstruction(Inst,
Operands))
4206 if (!MatchingInlineAsm)
4207 emitInstruction(Inst,
Operands, Out);
4210 case Match_InvalidImmUnsignedi4: {
4212 if (ErrorLoc ==
SMLoc())
4214 return Error(ErrorLoc,
"immediate must be an integer in range [0, 15]",
4215 EmptyRange, MatchingInlineAsm);
4217 case Match_MissingFeature:
4218 return ErrorMissingFeature(IDLoc, MissingFeatures, MatchingInlineAsm);
4219 case Match_InvalidOperand:
4220 case Match_MnemonicFail:
4221 case Match_Unsupported:
4224 if (
Op.getToken().empty()) {
4225 Error(IDLoc,
"instruction must have size higher than 0", EmptyRange,
4240 Op.setTokenValue(Tmp);
4248 const char *Suffixes =
Base[0] !=
'f' ?
"bwlq" :
"slt\0";
4250 const char *MemSize =
Base[0] !=
'f' ?
"\x08\x10\x20\x40" :
"\x20\x40\x50\0";
4262 bool HasVectorReg =
false;
4267 HasVectorReg =
true;
4268 else if (X86Op->
isMem()) {
4270 assert(
MemOp->Mem.Size == 0 &&
"Memory size always 0 under ATT syntax");
4277 for (
unsigned I = 0,
E = std::size(
Match);
I !=
E; ++
I) {
4278 Tmp.
back() = Suffixes[
I];
4279 if (
MemOp && HasVectorReg)
4280 MemOp->Mem.Size = MemSize[
I];
4281 Match[
I] = Match_MnemonicFail;
4282 if (
MemOp || !HasVectorReg) {
4284 MatchInstruction(
Operands, Inst, ErrorInfoIgnore, MissingFeatures,
4285 MatchingInlineAsm, isParsingIntelSyntax());
4287 if (
Match[
I] == Match_MissingFeature)
4288 ErrorInfoMissingFeatures = MissingFeatures;
4299 if (NumSuccessfulMatches == 1) {
4300 if (!MatchingInlineAsm && validateInstruction(Inst,
Operands))
4305 if (!MatchingInlineAsm)
4306 while (processInstruction(Inst,
Operands))
4310 if (!MatchingInlineAsm)
4311 emitInstruction(Inst,
Operands, Out);
4320 if (NumSuccessfulMatches > 1) {
4322 unsigned NumMatches = 0;
4323 for (
unsigned I = 0,
E = std::size(
Match);
I !=
E; ++
I)
4324 if (
Match[
I] == Match_Success)
4325 MatchChars[NumMatches++] = Suffixes[
I];
4329 OS <<
"ambiguous instructions require an explicit suffix (could be ";
4330 for (
unsigned i = 0; i != NumMatches; ++i) {
4333 if (i + 1 == NumMatches)
4335 OS <<
"'" <<
Base << MatchChars[i] <<
"'";
4338 Error(IDLoc,
OS.str(), EmptyRange, MatchingInlineAsm);
4347 if (OriginalError == Match_MnemonicFail)
4348 return Error(IDLoc,
"invalid instruction mnemonic '" +
Base +
"'",
4349 Op.getLocRange(), MatchingInlineAsm);
4351 if (OriginalError == Match_Unsupported)
4352 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4355 assert(OriginalError == Match_InvalidOperand &&
"Unexpected error");
4359 return Error(IDLoc,
"too few operands for instruction", EmptyRange,
4366 OperandRange, MatchingInlineAsm);
4370 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4376 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4384 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
4391 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4396 Error(IDLoc,
"unknown use of instruction mnemonic without a size suffix",
4397 EmptyRange, MatchingInlineAsm);
4401bool X86AsmParser::MatchAndEmitIntelInstruction(
SMLoc IDLoc,
unsigned &Opcode,
4405 bool MatchingInlineAsm) {
4407 assert((*
Operands[0]).isToken() &&
"Leading operand should always be a mnemonic!");
4409 SMRange EmptyRange = std::nullopt;
4421 if (ForcedVEXEncoding == VEXEncoding_VEX)
4423 else if (ForcedVEXEncoding == VEXEncoding_VEX2)
4425 else if (ForcedVEXEncoding == VEXEncoding_VEX3)
4427 else if (ForcedVEXEncoding == VEXEncoding_EVEX)
4431 if (ForcedDispEncoding == DispEncoding_Disp8)
4433 else if (ForcedDispEncoding == DispEncoding_Disp32)
4444 UnsizedMemOp = X86Op;
4454 static const char *
const PtrSizedInstrs[] = {
"call",
"jmp",
"push"};
4455 for (
const char *Instr : PtrSizedInstrs) {
4456 if (Mnemonic == Instr) {
4457 UnsizedMemOp->
Mem.
Size = getPointerWidth();
4469 if (Mnemonic ==
"push" &&
Operands.size() == 2) {
4471 if (X86Op->
isImm()) {
4473 const auto *
CE = dyn_cast<MCConstantExpr>(X86Op->
getImm());
4474 unsigned Size = getPointerWidth();
4479 Tmp += (is64BitMode())
4481 : (is32BitMode()) ?
"l" : (is16BitMode()) ?
"w" :
" ";
4482 Op.setTokenValue(Tmp);
4485 MissingFeatures, MatchingInlineAsm,
4496 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
4497 for (
unsigned Size : MopSizes) {
4501 unsigned M = MatchInstruction(
Operands, Inst, ErrorInfoIgnore,
4502 MissingFeatures, MatchingInlineAsm,
4503 isParsingIntelSyntax());
4508 if (
Match.back() == Match_MissingFeature)
4509 ErrorInfoMissingFeatures = MissingFeatures;
4519 if (
Match.empty()) {
4520 Match.push_back(MatchInstruction(
4522 isParsingIntelSyntax()));
4524 if (
Match.back() == Match_MissingFeature)
4525 ErrorInfoMissingFeatures = MissingFeatures;
4533 if (
Match.back() == Match_MnemonicFail) {
4534 return Error(IDLoc,
"invalid instruction mnemonic '" + Mnemonic +
"'",
4535 Op.getLocRange(), MatchingInlineAsm);
4542 if (UnsizedMemOp && NumSuccessfulMatches > 1 &&
4545 unsigned M = MatchInstruction(
4547 isParsingIntelSyntax());
4548 if (M == Match_Success)
4549 NumSuccessfulMatches = 1;
4561 if (NumSuccessfulMatches == 1) {
4562 if (!MatchingInlineAsm && validateInstruction(Inst,
Operands))
4567 if (!MatchingInlineAsm)
4568 while (processInstruction(Inst,
Operands))
4571 if (!MatchingInlineAsm)
4572 emitInstruction(Inst,
Operands, Out);
4575 }
else if (NumSuccessfulMatches > 1) {
4577 "multiple matches only possible with unsized memory operands");
4579 "ambiguous operand size for instruction '" + Mnemonic +
"\'",
4585 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4593 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
4600 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4606 if (ErrorLoc ==
SMLoc())
4608 return Error(ErrorLoc,
"immediate must be an integer in range [0, 15]",
4609 EmptyRange, MatchingInlineAsm);
4613 return Error(IDLoc,
"unknown instruction mnemonic", EmptyRange,
4617bool X86AsmParser::OmitRegisterFromClobberLists(
unsigned RegNo) {
4618 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo);
4621bool X86AsmParser::ParseDirective(
AsmToken DirectiveID) {
4625 return parseDirectiveArch();
4627 return ParseDirectiveCode(IDVal, DirectiveID.
getLoc());
4633 return Error(DirectiveID.
getLoc(),
"'.att_syntax noprefix' is not "
4634 "supported: registers must have a "
4635 "'%' prefix in .att_syntax");
4637 getParser().setAssemblerDialect(0);
4639 }
else if (IDVal.
startswith(
".intel_syntax")) {
4640 getParser().setAssemblerDialect(1);
4645 return Error(DirectiveID.
getLoc(),
"'.intel_syntax prefix' is not "
4646 "supported: registers must not have "
4647 "a '%' prefix in .intel_syntax");
4650 }
else if (IDVal ==
".nops")
4651 return parseDirectiveNops(DirectiveID.
getLoc());
4652 else if (IDVal ==
".even")
4653 return parseDirectiveEven(DirectiveID.
getLoc());
4654 else if (IDVal ==
".cv_fpo_proc")
4655 return parseDirectiveFPOProc(DirectiveID.
getLoc());
4656 else if (IDVal ==
".cv_fpo_setframe")
4657 return parseDirectiveFPOSetFrame(DirectiveID.
getLoc());
4658 else if (IDVal ==
".cv_fpo_pushreg")
4659 return parseDirectiveFPOPushReg(DirectiveID.
getLoc());
4660 else if (IDVal ==
".cv_fpo_stackalloc")
4661 return parseDirectiveFPOStackAlloc(DirectiveID.
getLoc());
4662 else if (IDVal ==
".cv_fpo_stackalign")
4663 return parseDirectiveFPOStackAlign(DirectiveID.
getLoc());
4664 else if (IDVal ==
".cv_fpo_endprologue")
4665 return parseDirectiveFPOEndPrologue(DirectiveID.
getLoc());
4666 else if (IDVal ==
".cv_fpo_endproc")
4667 return parseDirectiveFPOEndProc(DirectiveID.
getLoc());
4668 else if (IDVal ==
".seh_pushreg" ||
4670 return parseDirectiveSEHPushReg(DirectiveID.
getLoc());
4671 else if (IDVal ==
".seh_setframe" ||
4673 return parseDirectiveSEHSetFrame(DirectiveID.
getLoc());
4674 else if (IDVal ==
".seh_savereg" ||
4676 return parseDirectiveSEHSaveReg(DirectiveID.
getLoc());
4677 else if (IDVal ==
".seh_savexmm" ||
4679 return parseDirectiveSEHSaveXMM(DirectiveID.
getLoc());
4680 else if (IDVal ==
".seh_pushframe" ||
4682 return parseDirectiveSEHPushFrame(DirectiveID.
getLoc());
4687bool X86AsmParser::parseDirectiveArch() {
4689 getParser().parseStringToEndOfStatement();
4695bool X86AsmParser::parseDirectiveNops(
SMLoc L) {
4696 int64_t NumBytes = 0, Control = 0;
4697 SMLoc NumBytesLoc, ControlLoc;
4699 NumBytesLoc = getTok().getLoc();
4700 if (getParser().checkForValidSection() ||
4701 getParser().parseAbsoluteExpression(NumBytes))
4705 ControlLoc = getTok().getLoc();
4706 if (getParser().parseAbsoluteExpression(Control))
4709 if (getParser().parseEOL())
4712 if (NumBytes <= 0) {
4713 Error(NumBytesLoc,
"'.nops' directive with non-positive size");
4718 Error(ControlLoc,
"'.nops' directive with negative NOP size");
4723 getParser().getStreamer().emitNops(NumBytes, Control, L, STI);
4730bool X86AsmParser::parseDirectiveEven(
SMLoc L) {
4736 getStreamer().initSections(
false, getSTI());
4737 Section = getStreamer().getCurrentSectionOnly();
4740 getStreamer().emitCodeAlignment(
Align(2), &getSTI(), 0);
4742 getStreamer().emitValueToAlignment(
Align(2), 0, 1, 0);
4751 if (IDVal ==
".code16") {
4753 if (!is16BitMode()) {
4754 SwitchMode(X86::Is16Bit);
4755 getParser().getStreamer().emitAssemblerFlag(
MCAF_Code16);
4757 }
else if (IDVal ==
".code16gcc") {
4761 if (!is16BitMode()) {
4762 SwitchMode(X86::Is16Bit);
4763 getParser().getStreamer().emitAssemblerFlag(
MCAF_Code16);
4765 }
else if (IDVal ==
".code32") {
4767 if (!is32BitMode()) {
4768 SwitchMode(X86::Is32Bit);
4769 getParser().getStreamer().emitAssemblerFlag(
MCAF_Code32);
4771 }
else if (IDVal ==
".code64") {
4773 if (!is64BitMode()) {
4774 SwitchMode(X86::Is64Bit);
4775 getParser().getStreamer().emitAssemblerFlag(
MCAF_Code64);
4778 Error(L,
"unknown directive " + IDVal);
4786bool X86AsmParser::parseDirectiveFPOProc(
SMLoc L) {
4791 return Parser.
TokError(
"expected symbol name");
4792 if (Parser.
parseIntToken(ParamsSize,
"expected parameter byte count"))
4795 return Parser.
TokError(
"parameters size out of range");
4798 MCSymbol *ProcSym = getContext().getOrCreateSymbol(ProcName);
4799 return getTargetStreamer().emitFPOProc(ProcSym, ParamsSize, L);
4803bool X86AsmParser::parseDirectiveFPOSetFrame(
SMLoc L) {
4806 if (parseRegister(Reg, DummyLoc, DummyLoc) || parseEOL())
4808 return getTargetStreamer().emitFPOSetFrame(Reg, L);
4812bool X86AsmParser::parseDirectiveFPOPushReg(
SMLoc L) {
4815 if (parseRegister(Reg, DummyLoc, DummyLoc) || parseEOL())
4817 return getTargetStreamer().emitFPOPushReg(Reg, L);
4821bool X86AsmParser::parseDirectiveFPOStackAlloc(
SMLoc L) {
4826 return getTargetStreamer().emitFPOStackAlloc(
Offset, L);
4830bool X86AsmParser::parseDirectiveFPOStackAlign(
SMLoc L) {
4835 return getTargetStreamer().emitFPOStackAlign(
Offset, L);
4839bool X86AsmParser::parseDirectiveFPOEndPrologue(
SMLoc L) {
4843 return getTargetStreamer().emitFPOEndPrologue(L);
4847bool X86AsmParser::parseDirectiveFPOEndProc(
SMLoc L) {
4851 return getTargetStreamer().emitFPOEndProc(L);
4854bool X86AsmParser::parseSEHRegisterNumber(
unsigned RegClassID,
4856 SMLoc startLoc = getLexer().getLoc();
4862 if (parseRegister(RegNo, startLoc, endLoc))
4865 if (!X86MCRegisterClasses[RegClassID].
contains(RegNo)) {
4866 return Error(startLoc,
4867 "register is not supported for use with this directive");
4873 if (getParser().parseAbsoluteExpression(EncodedReg))
4879 for (
MCPhysReg Reg : X86MCRegisterClasses[RegClassID]) {
4880 if (
MRI->getEncodingValue(Reg) == EncodedReg) {
4886 return Error(startLoc,
4887 "incorrect register number for use with this directive");
4894bool X86AsmParser::parseDirectiveSEHPushReg(
SMLoc Loc) {
4896 if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg))
4900 return TokError(
"expected end of directive");
4903 getStreamer().emitWinCFIPushReg(Reg, Loc);
4907bool X86AsmParser::parseDirectiveSEHSetFrame(
SMLoc Loc) {
4910 if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg))
4913 return TokError(
"you must specify a stack pointer offset");
4916 if (getParser().parseAbsoluteExpression(Off))
4920 return TokError(
"expected end of directive");
4923 getStreamer().emitWinCFISetFrame(Reg, Off, Loc);
4927bool X86AsmParser::parseDirectiveSEHSaveReg(
SMLoc Loc) {
4930 if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg))
4933 return TokError(
"you must specify an offset on the stack");
4936 if (getParser().parseAbsoluteExpression(Off))
4940 return TokError(
"expected end of directive");
4943 getStreamer().emitWinCFISaveReg(Reg, Off, Loc);
4947bool X86AsmParser::parseDirectiveSEHSaveXMM(
SMLoc Loc) {
4950 if (parseSEHRegisterNumber(X86::VR128XRegClassID, Reg))
4953 return TokError(
"you must specify an offset on the stack");
4956 if (getParser().parseAbsoluteExpression(Off))
4960 return TokError(
"expected end of directive");
4963 getStreamer().emitWinCFISaveXMM(Reg, Off, Loc);
4967bool X86AsmParser::parseDirectiveSEHPushFrame(
SMLoc Loc) {
4971 SMLoc startLoc = getLexer().getLoc();
4973 if (!getParser().parseIdentifier(CodeID)) {
4974 if (CodeID !=
"code")
4975 return Error(startLoc,
"expected @code");
4981 return TokError(
"expected end of directive");
4984 getStreamer().emitWinCFIPushFrame(Code, Loc);
4994#define GET_REGISTER_MATCHER
4995#define GET_MATCHER_IMPLEMENTATION
4996#define GET_SUBTARGET_FEATURE_NAME
4997#include "X86GenAsmMatcher.inc"
unsigned const MachineRegisterInfo * MRI
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
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 bool startswith(StringRef Magic, const char(&S)[N])
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 const char * getSubtargetFeatureName(uint64_t Val)
static unsigned MatchRegisterName(StringRef Name)
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