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 SMLoc consumeToken() {
119 "do not have a target streamer");
126 bool matchingInlineAsm,
unsigned VariantID = 0) {
129 SwitchMode(X86::Is32Bit);
131 MissingFeatures, matchingInlineAsm,
134 SwitchMode(X86::Is16Bit);
138 enum InfixCalculatorTok {
163 enum IntelOperatorKind {
170 enum MasmOperatorKind {
177 class InfixCalculator {
178 typedef std::pair< InfixCalculatorTok, int64_t > ICToken;
182 bool isUnaryOperator(InfixCalculatorTok Op)
const {
183 return Op == IC_NEG ||
Op == IC_NOT;
187 int64_t popOperand() {
188 assert (!PostfixStack.
empty() &&
"Poped an empty stack!");
190 if (!(
Op.first == IC_IMM ||
Op.first == IC_REGISTER))
194 void pushOperand(InfixCalculatorTok Op, int64_t Val = 0) {
195 assert ((Op == IC_IMM || Op == IC_REGISTER) &&
196 "Unexpected operand!");
197 PostfixStack.
push_back(std::make_pair(Op, Val));
200 void popOperator() { InfixOperatorStack.
pop_back(); }
201 void pushOperator(InfixCalculatorTok Op) {
203 if (InfixOperatorStack.
empty()) {
211 unsigned Idx = InfixOperatorStack.
size() - 1;
212 InfixCalculatorTok StackOp = InfixOperatorStack[
Idx];
213 if (OpPrecedence[Op] > OpPrecedence[StackOp] || StackOp == IC_LPAREN) {
220 unsigned ParenCount = 0;
223 if (InfixOperatorStack.
empty())
226 Idx = InfixOperatorStack.
size() - 1;
227 StackOp = InfixOperatorStack[
Idx];
228 if (!(OpPrecedence[StackOp] >= OpPrecedence[Op] || ParenCount))
233 if (!ParenCount && StackOp == IC_LPAREN)
236 if (StackOp == IC_RPAREN) {
239 }
else if (StackOp == IC_LPAREN) {
244 PostfixStack.
push_back(std::make_pair(StackOp, 0));
253 while (!InfixOperatorStack.
empty()) {
254 InfixCalculatorTok StackOp = InfixOperatorStack.
pop_back_val();
255 if (StackOp != IC_LPAREN && StackOp != IC_RPAREN)
256 PostfixStack.
push_back(std::make_pair(StackOp, 0));
259 if (PostfixStack.
empty())
263 for (
unsigned i = 0, e = PostfixStack.
size(); i != e; ++i) {
264 ICToken
Op = PostfixStack[i];
265 if (
Op.first == IC_IMM ||
Op.first == IC_REGISTER) {
267 }
else if (isUnaryOperator(
Op.first)) {
268 assert (OperandStack.
size() > 0 &&
"Too few operands.");
270 assert (Operand.first == IC_IMM &&
271 "Unary operation with a register!");
277 OperandStack.
push_back(std::make_pair(IC_IMM, -Operand.second));
280 OperandStack.
push_back(std::make_pair(IC_IMM, ~Operand.second));
284 assert (OperandStack.
size() > 1 &&
"Too few operands.");
293 Val = Op1.second + Op2.second;
294 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
297 Val = Op1.second - Op2.second;
298 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
301 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
302 "Multiply operation with an immediate and a register!");
303 Val = Op1.second * Op2.second;
304 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
307 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
308 "Divide operation with an immediate and a register!");
309 assert (Op2.second != 0 &&
"Division by zero!");
310 Val = Op1.second / Op2.second;
311 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
314 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
315 "Modulo operation with an immediate and a register!");
316 Val = Op1.second % Op2.second;
317 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
320 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
321 "Or operation with an immediate and a register!");
322 Val = Op1.second | Op2.second;
323 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
326 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
327 "Xor operation with an immediate and a register!");
328 Val = Op1.second ^ Op2.second;
329 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
332 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
333 "And operation with an immediate and a register!");
334 Val = Op1.second & Op2.second;
335 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
338 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
339 "Left shift operation with an immediate and a register!");
340 Val = Op1.second << Op2.second;
341 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
344 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
345 "Right shift operation with an immediate and a register!");
346 Val = Op1.second >> Op2.second;
347 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
350 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
351 "Equals operation with an immediate and a register!");
352 Val = (Op1.second == Op2.second) ? -1 : 0;
353 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
356 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
357 "Not-equals operation with an immediate and a register!");
358 Val = (Op1.second != Op2.second) ? -1 : 0;
359 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
362 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
363 "Less-than operation with an immediate and a register!");
364 Val = (Op1.second < Op2.second) ? -1 : 0;
365 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
368 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
369 "Less-than-or-equal operation with an immediate and a "
371 Val = (Op1.second <= Op2.second) ? -1 : 0;
372 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
375 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
376 "Greater-than operation with an immediate and a register!");
377 Val = (Op1.second > Op2.second) ? -1 : 0;
378 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
381 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
382 "Greater-than-or-equal operation with an immediate and a "
384 Val = (Op1.second >= Op2.second) ? -1 : 0;
385 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
390 assert (OperandStack.
size() == 1 &&
"Expected a single result.");
395 enum IntelExprState {
426 class IntelExprStateMachine {
427 IntelExprState State = IES_INIT, PrevState = IES_ERROR;
428 unsigned BaseReg = 0, IndexReg = 0, TmpReg = 0, Scale = 0;
435 bool MemExpr =
false;
436 bool BracketUsed =
false;
437 bool OffsetOperator =
false;
438 bool AttachToOperandIdx =
false;
440 SMLoc OffsetOperatorLoc;
445 ErrMsg =
"cannot use more than one symbol in memory operand";
454 IntelExprStateMachine() =
default;
456 void addImm(int64_t imm) {
Imm += imm; }
457 short getBracCount()
const {
return BracCount; }
458 bool isMemExpr()
const {
return MemExpr; }
459 bool isBracketUsed()
const {
return BracketUsed; }
460 bool isOffsetOperator()
const {
return OffsetOperator; }
461 SMLoc getOffsetLoc()
const {
return OffsetOperatorLoc; }
462 unsigned getBaseReg()
const {
return BaseReg; }
463 unsigned getIndexReg()
const {
return IndexReg; }
464 unsigned getScale()
const {
return Scale; }
466 StringRef getSymName()
const {
return SymName; }
469 unsigned getElementSize()
const {
return CurType.
ElementSize; }
470 unsigned getLength()
const {
return CurType.
Length; }
471 int64_t getImm() {
return Imm + IC.execute(); }
472 bool isValidEndState()
const {
473 return State == IES_RBRAC || State == IES_INTEGER;
480 void setAppendAfterOperand() { AttachToOperandIdx =
true; }
482 bool isPIC()
const {
return IsPIC; }
483 void setPIC() { IsPIC =
true; }
485 bool hadError()
const {
return State == IES_ERROR; }
491 if (IsPIC && AttachToOperandIdx)
492 ErrMsg =
"Don't use 2 or more regs for mem offset in PIC model!";
494 ErrMsg =
"BaseReg/IndexReg already set!";
499 IntelExprState CurrState = State;
508 IC.pushOperator(IC_OR);
511 PrevState = CurrState;
514 IntelExprState CurrState = State;
523 IC.pushOperator(IC_XOR);
526 PrevState = CurrState;
529 IntelExprState CurrState = State;
538 IC.pushOperator(IC_AND);
541 PrevState = CurrState;
544 IntelExprState CurrState = State;
553 IC.pushOperator(IC_EQ);
556 PrevState = CurrState;
559 IntelExprState CurrState = State;
568 IC.pushOperator(IC_NE);
571 PrevState = CurrState;
574 IntelExprState CurrState = State;
583 IC.pushOperator(IC_LT);
586 PrevState = CurrState;
589 IntelExprState CurrState = State;
598 IC.pushOperator(IC_LE);
601 PrevState = CurrState;
604 IntelExprState CurrState = State;
613 IC.pushOperator(IC_GT);
616 PrevState = CurrState;
619 IntelExprState CurrState = State;
628 IC.pushOperator(IC_GE);
631 PrevState = CurrState;
634 IntelExprState CurrState = State;
643 IC.pushOperator(IC_LSHIFT);
646 PrevState = CurrState;
649 IntelExprState CurrState = State;
658 IC.pushOperator(IC_RSHIFT);
661 PrevState = CurrState;
664 IntelExprState CurrState = State;
674 IC.pushOperator(IC_PLUS);
675 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
682 return regsUseUpError(ErrMsg);
689 PrevState = CurrState;
693 IntelExprState CurrState = State;
724 if (CurrState == IES_REGISTER || CurrState == IES_RPAREN ||
725 CurrState == IES_INTEGER || CurrState == IES_RBRAC ||
726 CurrState == IES_OFFSET)
727 IC.pushOperator(IC_MINUS);
728 else if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
730 ErrMsg =
"Scale can't be negative";
733 IC.pushOperator(IC_NEG);
734 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
741 return regsUseUpError(ErrMsg);
748 PrevState = CurrState;
752 IntelExprState CurrState = State;
778 IC.pushOperator(IC_NOT);
781 PrevState = CurrState;
783 bool onRegister(
unsigned Reg,
StringRef &ErrMsg) {
784 IntelExprState CurrState = State;
792 State = IES_REGISTER;
794 IC.pushOperand(IC_REGISTER);
798 if (PrevState == IES_INTEGER) {
800 return regsUseUpError(ErrMsg);
801 State = IES_REGISTER;
804 Scale = IC.popOperand();
807 IC.pushOperand(IC_IMM);
814 PrevState = CurrState;
822 if (ParsingMSInlineAsm)
826 if (
auto *CE = dyn_cast<MCConstantExpr>(SymRef))
827 return onInteger(
CE->getValue(), ErrMsg);
840 if (setSymRef(SymRef, SymRefName, ErrMsg))
844 IC.pushOperand(IC_IMM);
845 if (ParsingMSInlineAsm)
852 bool onInteger(int64_t TmpInt,
StringRef &ErrMsg) {
853 IntelExprState CurrState = State;
879 if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
882 return regsUseUpError(ErrMsg);
890 IC.pushOperand(IC_IMM, TmpInt);
894 PrevState = CurrState;
906 State = IES_MULTIPLY;
907 IC.pushOperator(IC_MULTIPLY);
920 IC.pushOperator(IC_DIVIDE);
933 IC.pushOperator(IC_MOD);
949 IC.pushOperator(IC_PLUS);
955 assert(!BracCount &&
"BracCount should be zero on parsing's start");
965 IntelExprState CurrState = State;
974 if (BracCount-- != 1) {
975 ErrMsg =
"unexpected bracket encountered";
979 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
986 return regsUseUpError(ErrMsg);
993 PrevState = CurrState;
997 IntelExprState CurrState = State;
1023 IC.pushOperator(IC_LPAREN);
1026 PrevState = CurrState;
1040 IC.pushOperator(IC_RPAREN);
1046 bool ParsingMSInlineAsm,
StringRef &ErrMsg) {
1050 ErrMsg =
"unexpected offset operator expression";
1055 if (setSymRef(Val,
ID, ErrMsg))
1057 OffsetOperator =
true;
1058 OffsetOperatorLoc = OffsetLoc;
1062 IC.pushOperand(IC_IMM);
1063 if (ParsingMSInlineAsm) {
1086 bool MatchingInlineAsm =
false) {
1088 if (MatchingInlineAsm) {
1089 if (!
getLexer().isAtStartOfStatement())
1093 return Parser.
Error(L, Msg, Range);
1099 bool RestoreOnFailure);
1101 std::unique_ptr<X86Operand> DefaultMemSIOperand(
SMLoc Loc);
1102 std::unique_ptr<X86Operand> DefaultMemDIOperand(
SMLoc Loc);
1103 bool IsSIReg(
unsigned Reg);
1104 unsigned GetSIDIForRegClass(
unsigned RegClassID,
unsigned Reg,
bool IsSIReg);
1107 std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
1108 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst);
1116 bool ParseIntelDotOperator(IntelExprStateMachine &SM,
SMLoc &
End);
1118 unsigned ParseIntelInlineAsmOperator(
unsigned OpKind);
1120 bool ParseMasmOperator(
unsigned OpKind, int64_t &Val);
1122 bool ParseIntelNamedOperator(
StringRef Name, IntelExprStateMachine &SM,
1124 bool ParseMasmNamedOperator(
StringRef Name, IntelExprStateMachine &SM,
1126 void RewriteIntelExpression(IntelExprStateMachine &SM,
SMLoc Start,
1128 bool ParseIntelExpression(IntelExprStateMachine &SM,
SMLoc &
End);
1129 bool ParseIntelInlineAsmIdentifier(
const MCExpr *&Val,
StringRef &Identifier,
1131 bool IsUnevaluatedOperand,
SMLoc &
End,
1132 bool IsParsingOffsetOperator =
false);
1134 IntelExprStateMachine &SM);
1136 bool ParseMemOperand(
unsigned SegReg,
const MCExpr *Disp,
SMLoc StartLoc,
1141 bool ParseIntelMemoryOperandSize(
unsigned &
Size);
1142 bool CreateMemForMSInlineAsm(
unsigned SegReg,
const MCExpr *Disp,
1143 unsigned BaseReg,
unsigned IndexReg,
1149 bool parseDirectiveArch();
1150 bool parseDirectiveNops(
SMLoc L);
1151 bool parseDirectiveEven(
SMLoc L);
1155 bool parseDirectiveFPOProc(
SMLoc L);
1156 bool parseDirectiveFPOSetFrame(
SMLoc L);
1157 bool parseDirectiveFPOPushReg(
SMLoc L);
1158 bool parseDirectiveFPOStackAlloc(
SMLoc L);
1159 bool parseDirectiveFPOStackAlign(
SMLoc L);
1160 bool parseDirectiveFPOEndPrologue(
SMLoc L);
1161 bool parseDirectiveFPOEndProc(
SMLoc L);
1164 bool parseSEHRegisterNumber(
unsigned RegClassID,
MCRegister &RegNo);
1165 bool parseDirectiveSEHPushReg(
SMLoc);
1166 bool parseDirectiveSEHSetFrame(
SMLoc);
1167 bool parseDirectiveSEHSaveReg(
SMLoc);
1168 bool parseDirectiveSEHSaveXMM(
SMLoc);
1169 bool parseDirectiveSEHPushFrame(
SMLoc);
1177 void emitWarningForSpecialLVIInstruction(
SMLoc Loc);
1188 bool MatchingInlineAsm)
override;
1194 bool MatchingInlineAsm);
1196 bool MatchAndEmitATTInstruction(
SMLoc IDLoc,
unsigned &Opcode,
1199 bool MatchingInlineAsm);
1201 bool MatchAndEmitIntelInstruction(
SMLoc IDLoc,
unsigned &Opcode,
1204 bool MatchingInlineAsm);
1213 bool ParseZ(std::unique_ptr<X86Operand> &Z,
const SMLoc &StartLoc);
1215 bool is64BitMode()
const {
1219 bool is32BitMode()
const {
1223 bool is16BitMode()
const {
1227 void SwitchMode(
unsigned mode) {
1229 FeatureBitset AllModes({X86::Is64Bit, X86::Is32Bit, X86::Is16Bit});
1238 unsigned getPointerWidth() {
1239 if (is16BitMode())
return 16;
1240 if (is32BitMode())
return 32;
1241 if (is64BitMode())
return 64;
1245 bool isParsingIntelSyntax() {
1252#define GET_ASSEMBLER_HEADER
1253#include "X86GenAsmMatcher.inc"
1258 enum X86MatchResultTy {
1260#define GET_OPERAND_DIAGNOSTIC_TYPES
1261#include "X86GenAsmMatcher.inc"
1276 SMLoc &EndLoc)
override;
1278 SMLoc &EndLoc)
override;
1289#define GET_REGISTER_MATCHER
1290#define GET_SUBTARGET_FEATURE_NAME
1291#include "X86GenAsmMatcher.inc"
1294 unsigned Scale,
bool Is64BitMode,
1301 !(BaseReg == X86::RIP || BaseReg == X86::EIP ||
1302 X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg) ||
1303 X86MCRegisterClasses[X86::GR32RegClassID].
contains(BaseReg) ||
1304 X86MCRegisterClasses[X86::GR64RegClassID].
contains(BaseReg))) {
1305 ErrMsg =
"invalid base+index expression";
1309 if (IndexReg != 0 &&
1310 !(IndexReg == X86::EIZ || IndexReg == X86::RIZ ||
1311 X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg) ||
1312 X86MCRegisterClasses[X86::GR32RegClassID].
contains(IndexReg) ||
1313 X86MCRegisterClasses[X86::GR64RegClassID].
contains(IndexReg) ||
1314 X86MCRegisterClasses[X86::VR128XRegClassID].
contains(IndexReg) ||
1315 X86MCRegisterClasses[X86::VR256XRegClassID].
contains(IndexReg) ||
1316 X86MCRegisterClasses[X86::VR512RegClassID].
contains(IndexReg))) {
1317 ErrMsg =
"invalid base+index expression";
1321 if (((BaseReg == X86::RIP || BaseReg == X86::EIP) && IndexReg != 0) ||
1322 IndexReg == X86::EIP || IndexReg == X86::RIP ||
1323 IndexReg == X86::ESP || IndexReg == X86::RSP) {
1324 ErrMsg =
"invalid base+index expression";
1330 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg) &&
1331 (Is64BitMode || (BaseReg != X86::BX && BaseReg != X86::BP &&
1332 BaseReg != X86::SI && BaseReg != X86::DI))) {
1333 ErrMsg =
"invalid 16-bit base register";
1338 X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg)) {
1339 ErrMsg =
"16-bit memory operand may not include only index register";
1343 if (BaseReg != 0 && IndexReg != 0) {
1344 if (X86MCRegisterClasses[X86::GR64RegClassID].
contains(BaseReg) &&
1345 (X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg) ||
1346 X86MCRegisterClasses[X86::GR32RegClassID].
contains(IndexReg) ||
1347 IndexReg == X86::EIZ)) {
1348 ErrMsg =
"base register is 64-bit, but index register is not";
1351 if (X86MCRegisterClasses[X86::GR32RegClassID].
contains(BaseReg) &&
1352 (X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg) ||
1353 X86MCRegisterClasses[X86::GR64RegClassID].
contains(IndexReg) ||
1354 IndexReg == X86::RIZ)) {
1355 ErrMsg =
"base register is 32-bit, but index register is not";
1358 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg)) {
1359 if (X86MCRegisterClasses[X86::GR32RegClassID].
contains(IndexReg) ||
1360 X86MCRegisterClasses[X86::GR64RegClassID].
contains(IndexReg)) {
1361 ErrMsg =
"base register is 16-bit, but index register is not";
1364 if ((BaseReg != X86::BX && BaseReg != X86::BP) ||
1365 (IndexReg != X86::SI && IndexReg != X86::DI)) {
1366 ErrMsg =
"invalid 16-bit base/index register combination";
1373 if (!Is64BitMode && BaseReg != 0 &&
1374 (BaseReg == X86::RIP || BaseReg == X86::EIP)) {
1375 ErrMsg =
"IP-relative addressing requires 64-bit mode";
1396 if (isParsingMSInlineAsm() && isParsingIntelSyntax() &&
1397 (RegNo == X86::EFLAGS || RegNo == X86::MXCSR))
1400 if (!is64BitMode()) {
1404 if (RegNo == X86::RIZ || RegNo == X86::RIP ||
1405 X86MCRegisterClasses[X86::GR64RegClassID].
contains(RegNo) ||
1408 return Error(StartLoc,
1409 "register %" +
RegName +
" is only available in 64-bit mode",
1416 if (RegNo == 0 &&
RegName.startswith(
"db")) {
1475 if (isParsingIntelSyntax())
1477 return Error(StartLoc,
"invalid register name",
SMRange(StartLoc, EndLoc));
1483 SMLoc &EndLoc,
bool RestoreOnFailure) {
1489 auto OnFailure = [RestoreOnFailure, &Lexer, &Tokens]() {
1490 if (RestoreOnFailure) {
1491 while (!Tokens.
empty()) {
1498 StartLoc = PercentTok.
getLoc();
1512 if (isParsingIntelSyntax())
return true;
1513 return Error(StartLoc,
"invalid register name",
1517 if (MatchRegisterByName(RegNo, Tok.
getString(), StartLoc, EndLoc)) {
1523 if (RegNo == X86::ST0) {
1537 return Error(IntTok.
getLoc(),
"expected stack index");
1540 case 0: RegNo = X86::ST0;
break;
1541 case 1: RegNo = X86::ST1;
break;
1542 case 2: RegNo = X86::ST2;
break;
1543 case 3: RegNo = X86::ST3;
break;
1544 case 4: RegNo = X86::ST4;
break;
1545 case 5: RegNo = X86::ST5;
break;
1546 case 6: RegNo = X86::ST6;
break;
1547 case 7: RegNo = X86::ST7;
break;
1550 return Error(IntTok.
getLoc(),
"invalid stack index");
1570 if (isParsingIntelSyntax())
return true;
1571 return Error(StartLoc,
"invalid register name",
1581 return ParseRegister(RegNo, StartLoc, EndLoc,
false);
1588 ParseRegister(RegNo, StartLoc, EndLoc,
true);
1589 bool PendingErrors = getParser().hasPendingError();
1590 getParser().clearPendingErrors();
1598std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(
SMLoc Loc) {
1599 bool Parse32 = is32BitMode() || Code16GCC;
1600 unsigned Basereg = is64BitMode() ? X86::RSI : (Parse32 ? X86::ESI : X86::SI);
1607std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand(
SMLoc Loc) {
1608 bool Parse32 = is32BitMode() || Code16GCC;
1609 unsigned Basereg = is64BitMode() ? X86::RDI : (Parse32 ? X86::EDI : X86::DI);
1616bool X86AsmParser::IsSIReg(
unsigned Reg) {
1630unsigned X86AsmParser::GetSIDIForRegClass(
unsigned RegClassID,
unsigned Reg,
1632 switch (RegClassID) {
1634 case X86::GR64RegClassID:
1635 return IsSIReg ? X86::RSI : X86::RDI;
1636 case X86::GR32RegClassID:
1637 return IsSIReg ? X86::ESI : X86::EDI;
1638 case X86::GR16RegClassID:
1639 return IsSIReg ? X86::SI : X86::DI;
1643void X86AsmParser::AddDefaultSrcDestOperands(
1645 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst) {
1646 if (isParsingIntelSyntax()) {
1647 Operands.push_back(std::move(Dst));
1648 Operands.push_back(std::move(Src));
1651 Operands.push_back(std::move(Src));
1652 Operands.push_back(std::move(Dst));
1656bool X86AsmParser::VerifyAndAdjustOperands(
OperandVector &OrigOperands,
1659 if (OrigOperands.
size() > 1) {
1662 "Operand size mismatch");
1666 int RegClassID = -1;
1667 for (
unsigned int i = 0; i < FinalOperands.
size(); ++i) {
1671 if (FinalOp.
isReg() &&
1676 if (FinalOp.
isMem()) {
1678 if (!OrigOp.
isMem())
1687 if (RegClassID != -1 &&
1688 !X86MCRegisterClasses[RegClassID].
contains(OrigReg)) {
1690 "mismatching source and destination index registers");
1693 if (X86MCRegisterClasses[X86::GR64RegClassID].
contains(OrigReg))
1694 RegClassID = X86::GR64RegClassID;
1695 else if (X86MCRegisterClasses[X86::GR32RegClassID].
contains(OrigReg))
1696 RegClassID = X86::GR32RegClassID;
1697 else if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(OrigReg))
1698 RegClassID = X86::GR16RegClassID;
1704 bool IsSI = IsSIReg(FinalReg);
1705 FinalReg = GetSIDIForRegClass(RegClassID, FinalReg, IsSI);
1707 if (FinalReg != OrigReg) {
1708 std::string
RegName = IsSI ?
"ES:(R|E)SI" :
"ES:(R|E)DI";
1711 "memory operand is only for determining the size, " +
RegName +
1712 " will be used for the location"));
1723 for (
auto &WarningMsg : Warnings) {
1724 Warning(WarningMsg.first, WarningMsg.second);
1728 for (
unsigned int i = 0; i < FinalOperands.
size(); ++i)
1732 for (
unsigned int i = 0; i < FinalOperands.
size(); ++i)
1733 OrigOperands.
push_back(std::move(FinalOperands[i]));
1739 if (isParsingIntelSyntax())
1745bool X86AsmParser::CreateMemForMSInlineAsm(
1746 unsigned SegReg,
const MCExpr *Disp,
unsigned BaseReg,
unsigned IndexReg,
1762 unsigned FrontendSize = 0;
1763 void *Decl =
nullptr;
1764 bool IsGlobalLV =
false;
1767 FrontendSize =
Info.Var.Type * 8;
1768 Decl =
Info.Var.Decl;
1769 IsGlobalLV =
Info.Var.IsGlobalLV;
1773 if (IsGlobalLV && (BaseReg || IndexReg)) {
1775 End,
Size, Identifier, Decl, 0,
1776 BaseReg && IndexReg));
1782 BaseReg = BaseReg ? BaseReg : 1;
1784 getPointerWidth(), SegReg, Disp, BaseReg, IndexReg, Scale, Start,
End,
1786 X86::RIP, Identifier, Decl, FrontendSize));
1794 IntelExprStateMachine &SM,
1799 !getParser().isParsingMasm())
1801 if (
Name.equals_insensitive(
"not")) {
1803 }
else if (
Name.equals_insensitive(
"or")) {
1805 }
else if (
Name.equals_insensitive(
"shl")) {
1807 }
else if (
Name.equals_insensitive(
"shr")) {
1809 }
else if (
Name.equals_insensitive(
"xor")) {
1811 }
else if (
Name.equals_insensitive(
"and")) {
1813 }
else if (
Name.equals_insensitive(
"mod")) {
1815 }
else if (
Name.equals_insensitive(
"offset")) {
1816 SMLoc OffsetLoc = getTok().getLoc();
1817 const MCExpr *Val =
nullptr;
1820 ParseError = ParseIntelOffsetOperator(Val,
ID, Info,
End);
1825 SM.onOffset(Val, OffsetLoc,
ID, Info, isParsingMSInlineAsm(), ErrMsg);
1831 if (!
Name.equals_insensitive(
"offset"))
1832 End = consumeToken();
1836 IntelExprStateMachine &SM,
1838 if (
Name.equals_insensitive(
"eq")) {
1840 }
else if (
Name.equals_insensitive(
"ne")) {
1842 }
else if (
Name.equals_insensitive(
"lt")) {
1844 }
else if (
Name.equals_insensitive(
"le")) {
1846 }
else if (
Name.equals_insensitive(
"gt")) {
1848 }
else if (
Name.equals_insensitive(
"ge")) {
1853 End = consumeToken();
1860 IntelExprStateMachine &SM) {
1864 SM.setAppendAfterOperand();
1867bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM,
SMLoc &
End) {
1873 if (getContext().getObjectFileInfo()->isPositionIndependent())
1882 bool UpdateLocLex =
true;
1887 if ((
Done = SM.isValidEndState()))
1889 return Error(Tok.
getLoc(),
"unknown token in expression");
1891 return Error(getLexer().getErrLoc(), getLexer().getErr());
1898 UpdateLocLex =
false;
1899 if (ParseIntelDotOperator(SM,
End))
1904 if ((
Done = SM.isValidEndState()))
1906 return Error(Tok.
getLoc(),
"unknown token in expression");
1910 UpdateLocLex =
false;
1911 if (ParseIntelDotOperator(SM,
End))
1916 if ((
Done = SM.isValidEndState()))
1918 return Error(Tok.
getLoc(),
"unknown token in expression");
1929 UpdateLocLex =
false;
1930 if (!Val->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
1931 return Error(ValueLoc,
"expected absolute value");
1932 if (SM.onInteger(Res, ErrMsg))
1933 return Error(ValueLoc, ErrMsg);
1942 UpdateLocLex =
false;
1944 size_t DotOffset =
Identifier.find_first_of(
'.');
1962 const AsmToken &NextTok = getLexer().peekTok();
1971 End = consumeToken();
1978 if (!ParseRegister(Reg, IdentLoc,
End,
true)) {
1979 if (SM.onRegister(Reg, ErrMsg))
1980 return Error(IdentLoc, ErrMsg);
1984 const std::pair<StringRef, StringRef> IDField =
1988 if (!
Field.empty() &&
1989 !MatchRegisterByName(Reg,
ID, IdentLoc, IDEndLoc)) {
1990 if (SM.onRegister(Reg, ErrMsg))
1991 return Error(IdentLoc, ErrMsg);
1996 return Error(FieldStartLoc,
"unknown offset");
1997 else if (SM.onPlus(ErrMsg))
1998 return Error(getTok().getLoc(), ErrMsg);
1999 else if (SM.onInteger(
Info.Offset, ErrMsg))
2000 return Error(IdentLoc, ErrMsg);
2001 SM.setTypeInfo(
Info.Type);
2003 End = consumeToken();
2009 bool ParseError =
false;
2010 if (ParseIntelNamedOperator(Identifier, SM, ParseError,
End)) {
2016 ParseMasmNamedOperator(Identifier, SM, ParseError,
End)) {
2029 if (ParseIntelDotOperator(SM,
End))
2034 if (isParsingMSInlineAsm()) {
2036 if (
unsigned OpKind = IdentifyIntelInlineAsmOperator(Identifier)) {
2037 if (int64_t Val = ParseIntelInlineAsmOperator(OpKind)) {
2038 if (SM.onInteger(Val, ErrMsg))
2039 return Error(IdentLoc, ErrMsg);
2048 return Error(IdentLoc,
"expected identifier");
2049 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
false,
End))
2051 else if (SM.onIdentifierExpr(Val, Identifier, Info, FieldInfo.
Type,
2053 return Error(IdentLoc, ErrMsg);
2057 if (
unsigned OpKind = IdentifyMasmOperator(Identifier)) {
2059 if (ParseMasmOperator(OpKind, Val))
2061 if (SM.onInteger(Val, ErrMsg))
2062 return Error(IdentLoc, ErrMsg);
2065 if (!getParser().lookUpType(Identifier, FieldInfo.
Type)) {
2071 getParser().parseIdentifier(Identifier);
2075 if (getParser().lookUpField(FieldInfo.
Type.
Name, Identifier,
2079 return Error(IdentLoc,
"Unable to lookup field reference!",
2085 if (SM.onInteger(FieldInfo.
Offset, ErrMsg))
2086 return Error(IdentLoc, ErrMsg);
2090 if (getParser().parsePrimaryExpr(Val,
End, &FieldInfo.
Type)) {
2091 return Error(Tok.
getLoc(),
"Unexpected identifier!");
2092 }
else if (SM.onIdentifierExpr(Val, Identifier, Info, FieldInfo.
Type,
2094 return Error(IdentLoc, ErrMsg);
2100 SMLoc Loc = getTok().getLoc();
2101 int64_t
IntVal = getTok().getIntVal();
2102 End = consumeToken();
2103 UpdateLocLex =
false;
2106 if (IDVal ==
"f" || IDVal ==
"b") {
2108 getContext().getDirectionalLocalSymbol(IntVal, IDVal ==
"b");
2112 if (IDVal ==
"b" &&
Sym->isUndefined())
2113 return Error(Loc,
"invalid reference to undefined symbol");
2117 if (SM.onIdentifierExpr(Val, Identifier, Info,
Type,
2118 isParsingMSInlineAsm(), ErrMsg))
2119 return Error(Loc, ErrMsg);
2120 End = consumeToken();
2122 if (SM.onInteger(IntVal, ErrMsg))
2123 return Error(Loc, ErrMsg);
2126 if (SM.onInteger(IntVal, ErrMsg))
2127 return Error(Loc, ErrMsg);
2132 if (SM.onPlus(ErrMsg))
2133 return Error(getTok().getLoc(), ErrMsg);
2136 if (SM.onMinus(ErrMsg))
2137 return Error(getTok().getLoc(), ErrMsg);
2147 SM.onLShift();
break;
2149 SM.onRShift();
break;
2152 return Error(Tok.
getLoc(),
"unexpected bracket encountered");
2153 tryParseOperandIdx(PrevTK, SM);
2156 if (SM.onRBrac(ErrMsg)) {
2164 return Error(Tok.
getLoc(),
"unknown token in expression");
2166 if (!
Done && UpdateLocLex)
2167 End = consumeToken();
2174void X86AsmParser::RewriteIntelExpression(IntelExprStateMachine &SM,
2177 unsigned ExprLen =
End.getPointer() - Start.getPointer();
2179 if (SM.getSym() && !SM.isOffsetOperator()) {
2181 if (
unsigned Len = SymName.
data() - Start.getPointer())
2184 ExprLen =
End.getPointer() - (SymName.
data() + SymName.
size());
2187 if (!(SM.getBaseReg() || SM.getIndexReg() || SM.getImm())) {
2197 if (SM.getBaseReg())
2199 if (SM.getIndexReg())
2201 if (SM.isOffsetOperator())
2202 OffsetNameStr = SM.getSymName();
2204 IntelExpr Expr(BaseRegStr, IndexRegStr, SM.getScale(), OffsetNameStr,
2205 SM.getImm(), SM.isMemExpr());
2206 InstInfo->
AsmRewrites->emplace_back(Loc, ExprLen, Expr);
2210bool X86AsmParser::ParseIntelInlineAsmIdentifier(
2212 bool IsUnevaluatedOperand,
SMLoc &
End,
bool IsParsingOffsetOperator) {
2214 assert(isParsingMSInlineAsm() &&
"Expected to be parsing inline assembly.");
2218 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);
2229 }
while (
End.getPointer() < EndPtr);
2236 "frontend claimed part of a token?");
2242 SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(),
2244 assert(InternalName.
size() &&
"We should have an internal name here.");
2247 if (!IsParsingOffsetOperator)
2255 MCSymbol *
Sym = getContext().getOrCreateSymbol(Identifier);
2266 const SMLoc consumedToken = consumeToken();
2268 return Error(Tok.
getLoc(),
"Expected an identifier after {");
2271 .
Case(
"rn", X86::STATIC_ROUNDING::TO_NEAREST_INT)
2272 .
Case(
"rd", X86::STATIC_ROUNDING::TO_NEG_INF)
2273 .
Case(
"ru", X86::STATIC_ROUNDING::TO_POS_INF)
2274 .
Case(
"rz", X86::STATIC_ROUNDING::TO_ZERO)
2277 return Error(Tok.
getLoc(),
"Invalid rounding mode.");
2280 return Error(Tok.
getLoc(),
"Expected - at this point");
2284 return Error(Tok.
getLoc(),
"Expected } at this point");
2287 const MCExpr *RndModeOp =
2295 return Error(Tok.
getLoc(),
"Expected } at this point");
2300 return Error(Tok.
getLoc(),
"unknown token in expression");
2304bool X86AsmParser::ParseIntelDotOperator(IntelExprStateMachine &SM,
2321 }
else if ((isParsingMSInlineAsm() || getParser().isParsingMasm()) &&
2324 TrailingDot = DotDispStr.
substr(DotDispStr.
size() - 1);
2327 const std::pair<StringRef, StringRef> BaseMember = DotDispStr.
split(
'.');
2329 if (getParser().lookUpField(SM.getType(), DotDispStr, Info) &&
2330 getParser().lookUpField(SM.getSymName(), DotDispStr, Info) &&
2331 getParser().lookUpField(DotDispStr, Info) &&
2333 SemaCallback->LookupInlineAsmField(
Base, Member,
Info.Offset)))
2334 return Error(Tok.
getLoc(),
"Unable to lookup field reference!");
2336 return Error(Tok.
getLoc(),
"Unexpected token type!");
2341 const char *DotExprEndLoc = DotDispStr.
data() + DotDispStr.
size();
2344 if (!TrailingDot.
empty())
2346 SM.addImm(
Info.Offset);
2347 SM.setTypeInfo(
Info.Type);
2357 SMLoc Start = Lex().getLoc();
2358 ID = getTok().getString();
2359 if (!isParsingMSInlineAsm()) {
2362 getParser().parsePrimaryExpr(Val,
End,
nullptr))
2363 return Error(Start,
"unexpected token!");
2364 }
else if (ParseIntelInlineAsmIdentifier(Val,
ID, Info,
false,
End,
true)) {
2365 return Error(Start,
"unable to lookup expression");
2367 return Error(Start,
"offset operator cannot yet handle constants");
2374unsigned X86AsmParser::IdentifyIntelInlineAsmOperator(
StringRef Name) {
2376 .
Cases(
"TYPE",
"type",IOK_TYPE)
2377 .
Cases(
"SIZE",
"size",IOK_SIZE)
2378 .
Cases(
"LENGTH",
"length",IOK_LENGTH)
2388unsigned X86AsmParser::ParseIntelInlineAsmOperator(
unsigned OpKind) {
2393 const MCExpr *Val =
nullptr;
2397 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
2402 Error(Start,
"unable to lookup expression");
2409 case IOK_LENGTH: CVal =
Info.Var.Length;
break;
2410 case IOK_SIZE: CVal =
Info.Var.Size;
break;
2411 case IOK_TYPE: CVal =
Info.Var.Type;
break;
2419unsigned X86AsmParser::IdentifyMasmOperator(
StringRef Name) {
2421 .
Case(
"type", MOK_TYPE)
2422 .
Cases(
"size",
"sizeof", MOK_SIZEOF)
2423 .
Cases(
"length",
"lengthof", MOK_LENGTHOF)
2433bool X86AsmParser::ParseMasmOperator(
unsigned OpKind, int64_t &Val) {
2439 if (OpKind == MOK_SIZEOF || OpKind == MOK_TYPE) {
2442 const AsmToken &IDTok = InParens ? getLexer().peekTok() : Parser.
getTok();
2458 IntelExprStateMachine SM;
2460 if (ParseIntelExpression(SM,
End))
2470 Val = SM.getLength();
2473 Val = SM.getElementSize();
2478 return Error(OpLoc,
"expression has unknown type",
SMRange(Start,
End));
2484bool X86AsmParser::ParseIntelMemoryOperandSize(
unsigned &
Size) {
2486 .
Cases(
"BYTE",
"byte", 8)
2487 .
Cases(
"WORD",
"word", 16)
2488 .
Cases(
"DWORD",
"dword", 32)
2489 .
Cases(
"FLOAT",
"float", 32)
2490 .
Cases(
"LONG",
"long", 32)
2491 .
Cases(
"FWORD",
"fword", 48)
2492 .
Cases(
"DOUBLE",
"double", 64)
2493 .
Cases(
"QWORD",
"qword", 64)
2494 .
Cases(
"MMWORD",
"mmword", 64)
2495 .
Cases(
"XWORD",
"xword", 80)
2496 .
Cases(
"TBYTE",
"tbyte", 80)
2497 .
Cases(
"XMMWORD",
"xmmword", 128)
2498 .
Cases(
"YMMWORD",
"ymmword", 256)
2499 .
Cases(
"ZMMWORD",
"zmmword", 512)
2504 return Error(Tok.
getLoc(),
"Expected 'PTR' or 'ptr' token!");
2517 if (ParseIntelMemoryOperandSize(
Size))
2525 return ParseRoundingModeOp(Start,
Operands);
2530 if (RegNo == X86::RIP)
2531 return Error(Start,
"rip can only be used as a base register");
2535 return Error(Start,
"expected memory operand after 'ptr', "
2536 "found register operand instead");
2541 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].
contains(RegNo))
2542 return Error(Start,
"invalid segment register");
2544 Start = Lex().getLoc();
2548 IntelExprStateMachine SM;
2549 if (ParseIntelExpression(SM,
End))
2552 if (isParsingMSInlineAsm())
2553 RewriteIntelExpression(SM, Start, Tok.
getLoc());
2555 int64_t
Imm = SM.getImm();
2556 const MCExpr *Disp = SM.getSym();
2565 if (!SM.isMemExpr() && !RegNo) {
2566 if (isParsingMSInlineAsm() && SM.isOffsetOperator()) {
2572 SM.getSymName(),
Info.Var.Decl,
2573 Info.Var.IsGlobalLV));
2583 unsigned BaseReg = SM.getBaseReg();
2584 unsigned IndexReg = SM.getIndexReg();
2585 if (IndexReg && BaseReg == X86::RIP)
2587 unsigned Scale = SM.getScale();
2589 Size = SM.getElementSize() << 3;
2591 if (Scale == 0 && BaseReg != X86::ESP && BaseReg != X86::RSP &&
2592 (IndexReg == X86::ESP || IndexReg == X86::RSP))
2598 !(X86MCRegisterClasses[X86::VR128XRegClassID].
contains(IndexReg) ||
2599 X86MCRegisterClasses[X86::VR256XRegClassID].
contains(IndexReg) ||
2600 X86MCRegisterClasses[X86::VR512RegClassID].
contains(IndexReg)) &&
2601 (X86MCRegisterClasses[X86::VR128XRegClassID].
contains(BaseReg) ||
2602 X86MCRegisterClasses[X86::VR256XRegClassID].
contains(BaseReg) ||
2603 X86MCRegisterClasses[X86::VR512RegClassID].
contains(BaseReg)))
2607 X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg))
2608 return Error(Start,
"16-bit addresses cannot have a scale");
2617 if ((BaseReg == X86::SI || BaseReg == X86::DI) &&
2618 (IndexReg == X86::BX || IndexReg == X86::BP))
2621 if ((BaseReg || IndexReg) &&
2624 return Error(Start, ErrMsg);
2625 if (isParsingMSInlineAsm())
2626 return CreateMemForMSInlineAsm(RegNo, Disp, BaseReg, IndexReg, Scale, Start,
2632 unsigned DefaultBaseReg = X86::NoRegister;
2633 bool MaybeDirectBranchDest =
true;
2635 bool IsUnconditionalBranch =
2636 Name.equals_insensitive(
"jmp") ||
Name.equals_insensitive(
"call");
2638 if (is64BitMode() && SM.getElementSize() > 0) {
2639 DefaultBaseReg = X86::RIP;
2641 if (IsUnconditionalBranch) {
2643 MaybeDirectBranchDest =
false;
2645 DefaultBaseReg = X86::RIP;
2646 }
else if (!BaseReg && !IndexReg && Disp &&
2648 if (is64BitMode()) {
2649 if (SM.getSize() == 8) {
2650 MaybeDirectBranchDest =
false;
2651 DefaultBaseReg = X86::RIP;
2654 if (SM.getSize() == 4 || SM.getSize() == 2)
2655 MaybeDirectBranchDest =
false;
2659 }
else if (IsUnconditionalBranch) {
2661 if (!PtrInOperand && SM.isOffsetOperator())
2663 Start,
"`OFFSET` operator cannot be used in an unconditional branch");
2664 if (PtrInOperand || SM.isBracketUsed())
2665 MaybeDirectBranchDest =
false;
2668 if ((BaseReg || IndexReg || RegNo || DefaultBaseReg != X86::NoRegister))
2670 getPointerWidth(), RegNo, Disp, BaseReg, IndexReg, Scale, Start,
End,
2672 0,
false, MaybeDirectBranchDest));
2677 MaybeDirectBranchDest));
2683 switch (getLexer().getKind()) {
2693 "expected immediate expression") ||
2694 getParser().parseExpression(Val,
End) ||
2695 check(isa<X86MCExpr>(Val), L,
"expected immediate expression"))
2702 return ParseRoundingModeOp(Start,
Operands);
2711 const MCExpr *Expr =
nullptr;
2717 if (
auto *RE = dyn_cast<X86MCExpr>(Expr)) {
2720 Reg = RE->getRegNo();
2723 if (Reg == X86::EIZ || Reg == X86::RIZ)
2725 Loc,
"%eiz and %riz can only be used as index registers",
2727 if (Reg == X86::RIP)
2728 return Error(Loc,
"%rip can only be used as a base register",
2735 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].
contains(Reg))
2736 return Error(Loc,
"invalid segment register");
2744 return ParseMemOperand(Reg, Expr, Loc, EndLoc,
Operands);
2774bool X86AsmParser::ParseZ(std::unique_ptr<X86Operand> &Z,
2775 const SMLoc &StartLoc) {
2781 (getLexer().getTok().getIdentifier() ==
"z")))
2786 return Error(getLexer().getLoc(),
"Expected } at this point");
2798 const SMLoc consumedToken = consumeToken();
2802 if (getLexer().getTok().getIntVal() != 1)
2803 return TokError(
"Expected 1to<NUM> at this point");
2807 return TokError(
"Expected 1to<NUM> at this point");
2810 StringRef BroadcastString = (
Prefix + getLexer().getTok().getIdentifier())
2813 return TokError(
"Expected 1to<NUM> at this point");
2814 const char *BroadcastPrimitive =
2816 .
Case(
"1to2",
"{1to2}")
2817 .
Case(
"1to4",
"{1to4}")
2818 .
Case(
"1to8",
"{1to8}")
2819 .
Case(
"1to16",
"{1to16}")
2820 .
Case(
"1to32",
"{1to32}")
2822 if (!BroadcastPrimitive)
2823 return TokError(
"Invalid memory broadcast primitive.");
2826 return TokError(
"Expected } at this point");
2837 std::unique_ptr<X86Operand>
Z;
2838 if (ParseZ(Z, consumedToken))
2844 SMLoc StartLoc =
Z ? consumeToken() : consumedToken;
2849 if (!parseRegister(RegNo, RegLoc, StartLoc) &&
2850 X86MCRegisterClasses[X86::VK1RegClassID].
contains(RegNo)) {
2851 if (RegNo == X86::K0)
2852 return Error(RegLoc,
"Register k0 can't be used as write mask");
2854 return Error(getLexer().getLoc(),
"Expected } at this point");
2860 return Error(getLexer().getLoc(),
2861 "Expected an op-mask register at this point");
2866 if (ParseZ(Z, consumeToken()) || !Z)
2867 return Error(getLexer().getLoc(),
2868 "Expected a {z} mark at this point");
2884bool X86AsmParser::ParseMemOperand(
unsigned SegReg,
const MCExpr *Disp,
2905 auto isAtMemOperand = [
this]() {
2910 auto TokCount = this->getLexer().peekTokens(Buf,
true);
2913 switch (Buf[0].getKind()) {
2920 if ((TokCount > 1) &&
2922 (Buf[0].getLoc().getPointer() + 1 == Buf[1].getLoc().getPointer()))
2924 Buf[1].getIdentifier().
size() + 1);
2935 MCSymbol *
Sym = this->getContext().getOrCreateSymbol(Id);
2936 if (
Sym->isVariable()) {
2937 auto V =
Sym->getVariableValue(
false);
2938 return isa<X86MCExpr>(V);
2946 if (!isAtMemOperand()) {
2949 assert(!isa<X86MCExpr>(Disp) &&
"Expected non-register here.");
2965 0, 0, 1, StartLoc, EndLoc));
2971 unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
2972 SMLoc BaseLoc = getLexer().getLoc();
2979 check(!isa<X86MCExpr>(
E), BaseLoc,
"expected register here"))
2983 BaseReg = cast<X86MCExpr>(
E)->getRegNo();
2984 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ)
2985 return Error(BaseLoc,
"eiz and riz can only be used as index registers",
3000 if (!isa<X86MCExpr>(
E)) {
3004 if (!
E->evaluateAsAbsolute(ScaleVal, getStreamer().getAssemblerPtr()))
3005 return Error(Loc,
"expected absolute expression");
3007 Warning(Loc,
"scale factor without index register is ignored");
3010 IndexReg = cast<X86MCExpr>(
E)->getRegNo();
3012 if (BaseReg == X86::RIP)
3014 "%rip as base register can not have an index register");
3015 if (IndexReg == X86::RIP)
3016 return Error(Loc,
"%rip is not allowed as an index register");
3027 return Error(Loc,
"expected scale expression");
3030 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg) &&
3032 return Error(Loc,
"scale factor in 16-bit address must be 1");
3034 return Error(Loc, ErrMsg);
3048 if (BaseReg == X86::DX && IndexReg == 0 && Scale == 1 && SegReg == 0 &&
3049 isa<MCConstantExpr>(Disp) &&
3050 cast<MCConstantExpr>(Disp)->getValue() == 0) {
3057 return Error(BaseLoc, ErrMsg);
3059 if (SegReg || BaseReg || IndexReg)
3061 BaseReg, IndexReg, Scale, StartLoc,
3070bool X86AsmParser::parsePrimaryExpr(
const MCExpr *&Res,
SMLoc &EndLoc) {
3078 if (parseRegister(RegNo, StartLoc, EndLoc))
3092 ForcedVEXEncoding = VEXEncoding_Default;
3093 ForcedDispEncoding = DispEncoding_Default;
3106 if (Prefix ==
"vex")
3107 ForcedVEXEncoding = VEXEncoding_VEX;
3108 else if (Prefix ==
"vex2")
3109 ForcedVEXEncoding = VEXEncoding_VEX2;
3110 else if (Prefix ==
"vex3")
3111 ForcedVEXEncoding = VEXEncoding_VEX3;
3112 else if (Prefix ==
"evex")
3113 ForcedVEXEncoding = VEXEncoding_EVEX;
3114 else if (Prefix ==
"disp8")
3115 ForcedDispEncoding = DispEncoding_Disp8;
3116 else if (Prefix ==
"disp32")
3117 ForcedDispEncoding = DispEncoding_Disp32;
3119 return Error(NameLoc,
"unknown prefix");
3135 if (isParsingMSInlineAsm()) {
3136 if (
Name.equals_insensitive(
"vex"))
3137 ForcedVEXEncoding = VEXEncoding_VEX;
3138 else if (
Name.equals_insensitive(
"vex2"))
3139 ForcedVEXEncoding = VEXEncoding_VEX2;
3140 else if (
Name.equals_insensitive(
"vex3"))
3141 ForcedVEXEncoding = VEXEncoding_VEX3;
3142 else if (
Name.equals_insensitive(
"evex"))
3143 ForcedVEXEncoding = VEXEncoding_EVEX;
3145 if (ForcedVEXEncoding != VEXEncoding_Default) {
3158 if (
Name.consume_back(
".d32")) {
3159 ForcedDispEncoding = DispEncoding_Disp32;
3160 }
else if (
Name.consume_back(
".d8")) {
3161 ForcedDispEncoding = DispEncoding_Disp8;
3167 if (isParsingIntelSyntax() &&
3168 (PatchedName ==
"jmp" || PatchedName ==
"jc" || PatchedName ==
"jnc" ||
3169 PatchedName ==
"jcxz" || PatchedName ==
"jecxz" ||
3174 : NextTok ==
"short") {
3183 NextTok.
size() + 1);
3189 PatchedName !=
"setb" && PatchedName !=
"setnb")
3190 PatchedName = PatchedName.
substr(0,
Name.size()-1);
3192 unsigned ComparisonPredicate = ~0
U;
3199 bool IsVCMP = PatchedName[0] ==
'v';
3200 unsigned CCIdx =
IsVCMP ? 4 : 3;
3202 PatchedName.
slice(CCIdx, PatchedName.
size() - 2))
3204 .
Case(
"eq_oq", 0x00)
3206 .
Case(
"lt_os", 0x01)
3208 .
Case(
"le_os", 0x02)
3209 .
Case(
"unord", 0x03)
3210 .
Case(
"unord_q", 0x03)
3212 .
Case(
"neq_uq", 0x04)
3214 .
Case(
"nlt_us", 0x05)
3216 .
Case(
"nle_us", 0x06)
3218 .
Case(
"ord_q", 0x07)
3220 .
Case(
"eq_uq", 0x08)
3222 .
Case(
"nge_us", 0x09)
3224 .
Case(
"ngt_us", 0x0A)
3225 .
Case(
"false", 0x0B)
3226 .
Case(
"false_oq", 0x0B)
3227 .
Case(
"neq_oq", 0x0C)
3229 .
Case(
"ge_os", 0x0D)
3231 .
Case(
"gt_os", 0x0E)
3233 .
Case(
"true_uq", 0x0F)
3234 .
Case(
"eq_os", 0x10)
3235 .
Case(
"lt_oq", 0x11)
3236 .
Case(
"le_oq", 0x12)
3237 .
Case(
"unord_s", 0x13)
3238 .
Case(
"neq_us", 0x14)
3239 .
Case(
"nlt_uq", 0x15)
3240 .
Case(
"nle_uq", 0x16)
3241 .
Case(
"ord_s", 0x17)
3242 .
Case(
"eq_us", 0x18)
3243 .
Case(
"nge_uq", 0x19)
3244 .
Case(
"ngt_uq", 0x1A)
3245 .
Case(
"false_os", 0x1B)
3246 .
Case(
"neq_os", 0x1C)
3247 .
Case(
"ge_oq", 0x1D)
3248 .
Case(
"gt_oq", 0x1E)
3249 .
Case(
"true_us", 0x1F)
3254 PatchedName =
IsVCMP ?
"vcmpss" :
"cmpss";
3255 else if (PatchedName.
endswith(
"sd"))
3256 PatchedName =
IsVCMP ?
"vcmpsd" :
"cmpsd";
3257 else if (PatchedName.
endswith(
"ps"))
3258 PatchedName =
IsVCMP ?
"vcmpps" :
"cmpps";
3259 else if (PatchedName.
endswith(
"pd"))
3260 PatchedName =
IsVCMP ?
"vcmppd" :
"cmppd";
3261 else if (PatchedName.
endswith(
"sh"))
3262 PatchedName =
"vcmpsh";
3263 else if (PatchedName.
endswith(
"ph"))
3264 PatchedName =
"vcmpph";
3268 ComparisonPredicate =
CC;
3274 (PatchedName.
back() ==
'b' || PatchedName.
back() ==
'w' ||
3275 PatchedName.
back() ==
'd' || PatchedName.
back() ==
'q')) {
3276 unsigned SuffixSize = PatchedName.
drop_back().
back() ==
'u' ? 2 : 1;
3278 PatchedName.
slice(5, PatchedName.
size() - SuffixSize))
3288 if (
CC != ~0U && (
CC != 0 || SuffixSize == 2)) {
3289 switch (PatchedName.
back()) {
3291 case 'b': PatchedName = SuffixSize == 2 ?
"vpcmpub" :
"vpcmpb";
break;
3292 case 'w': PatchedName = SuffixSize == 2 ?
"vpcmpuw" :
"vpcmpw";
break;
3293 case 'd': PatchedName = SuffixSize == 2 ?
"vpcmpud" :
"vpcmpd";
break;
3294 case 'q': PatchedName = SuffixSize == 2 ?
"vpcmpuq" :
"vpcmpq";
break;
3297 ComparisonPredicate =
CC;
3303 (PatchedName.
back() ==
'b' || PatchedName.
back() ==
'w' ||
3304 PatchedName.
back() ==
'd' || PatchedName.
back() ==
'q')) {
3305 unsigned SuffixSize = PatchedName.
drop_back().
back() ==
'u' ? 2 : 1;
3307 PatchedName.
slice(5, PatchedName.
size() - SuffixSize))
3318 switch (PatchedName.
back()) {
3320 case 'b': PatchedName = SuffixSize == 2 ?
"vpcomub" :
"vpcomb";
break;
3321 case 'w': PatchedName = SuffixSize == 2 ?
"vpcomuw" :
"vpcomw";
break;
3322 case 'd': PatchedName = SuffixSize == 2 ?
"vpcomud" :
"vpcomd";
break;
3323 case 'q': PatchedName = SuffixSize == 2 ?
"vpcomuq" :
"vpcomq";
break;
3326 ComparisonPredicate =
CC;
3340 .
Cases(
"cs",
"ds",
"es",
"fs",
"gs",
"ss",
true)
3341 .
Cases(
"rex64",
"data32",
"data16",
"addr32",
"addr16",
true)
3342 .
Cases(
"xacquire",
"xrelease",
true)
3343 .
Cases(
"acquire",
"release", isParsingIntelSyntax())
3346 auto isLockRepeatNtPrefix = [](
StringRef N) {
3348 .
Cases(
"lock",
"rep",
"repe",
"repz",
"repne",
"repnz",
"notrack",
true)
3352 bool CurlyAsEndOfStatement =
false;
3355 while (isLockRepeatNtPrefix(
Name.lower())) {
3376 while (
Name.startswith(
";") ||
Name.startswith(
"\n") ||
3377 Name.startswith(
"#") ||
Name.startswith(
"\t") ||
3378 Name.startswith(
"/")) {
3389 if (PatchedName ==
"data16" && is16BitMode()) {
3390 return Error(NameLoc,
"redundant data16 prefix");
3392 if (PatchedName ==
"data32") {
3394 return Error(NameLoc,
"redundant data32 prefix");
3396 return Error(NameLoc,
"'data32' is not supported in 64-bit mode");
3398 PatchedName =
"data16";
3405 if (Next ==
"callw")
3407 if (Next ==
"ljmpw")
3412 ForcedDataPrefix = X86::Is32Bit;
3420 if (ComparisonPredicate != ~0U && !isParsingIntelSyntax()) {
3422 getParser().getContext());
3451 CurlyAsEndOfStatement =
3452 isParsingIntelSyntax() && isParsingMSInlineAsm() &&
3455 return TokError(
"unexpected token in argument list");
3459 if (ComparisonPredicate != ~0U && isParsingIntelSyntax()) {
3461 getParser().getContext());
3469 else if (CurlyAsEndOfStatement)
3472 getLexer().getTok().getLoc(), 0);
3479 if (IsFp &&
Operands.size() == 1) {
3481 .
Case(
"fsub",
"fsubp")
3482 .
Case(
"fdiv",
"fdivp")
3483 .
Case(
"fsubr",
"fsubrp")
3484 .
Case(
"fdivr",
"fdivrp");
3488 if ((
Name ==
"mov" ||
Name ==
"movw" ||
Name ==
"movl") &&
3496 X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(
3498 (X86MCRegisterClasses[X86::GR16RegClassID].
contains(Op1.
getReg()) ||
3499 X86MCRegisterClasses[X86::GR32RegClassID].
contains(Op1.
getReg()))) {
3501 if (
Name !=
"mov" &&
Name[3] == (is16BitMode() ?
'l' :
'w')) {
3502 Name = is16BitMode() ?
"movw" :
"movl";
3515 if ((
Name ==
"outb" ||
Name ==
"outsb" ||
Name ==
"outw" ||
Name ==
"outsw" ||
3534 bool HadVerifyError =
false;
3537 if (
Name.startswith(
"ins") &&
3542 AddDefaultSrcDestOperands(TmpOperands,
3544 DefaultMemDIOperand(NameLoc));
3545 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3549 if (
Name.startswith(
"outs") &&
3551 (
Name ==
"outsb" ||
Name ==
"outsw" ||
Name ==
"outsl" ||
3552 Name ==
"outsd" ||
Name ==
"outs")) {
3553 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
3555 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3561 if (
Name.startswith(
"lods") &&
3563 (
Name ==
"lods" ||
Name ==
"lodsb" ||
Name ==
"lodsw" ||
3564 Name ==
"lodsl" ||
Name ==
"lodsd" ||
Name ==
"lodsq")) {
3565 TmpOperands.
push_back(DefaultMemSIOperand(NameLoc));
3566 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3572 if (
Name.startswith(
"stos") &&
3574 (
Name ==
"stos" ||
Name ==
"stosb" ||
Name ==
"stosw" ||
3575 Name ==
"stosl" ||
Name ==
"stosd" ||
Name ==
"stosq")) {
3576 TmpOperands.
push_back(DefaultMemDIOperand(NameLoc));
3577 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3583 if (
Name.startswith(
"scas") &&
3585 (
Name ==
"scas" ||
Name ==
"scasb" ||
Name ==
"scasw" ||
3586 Name ==
"scasl" ||
Name ==
"scasd" ||
Name ==
"scasq")) {
3587 TmpOperands.
push_back(DefaultMemDIOperand(NameLoc));
3588 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3592 if (
Name.startswith(
"cmps") &&
3594 (
Name ==
"cmps" ||
Name ==
"cmpsb" ||
Name ==
"cmpsw" ||
3595 Name ==
"cmpsl" ||
Name ==
"cmpsd" ||
Name ==
"cmpsq")) {
3596 AddDefaultSrcDestOperands(TmpOperands, DefaultMemDIOperand(NameLoc),
3597 DefaultMemSIOperand(NameLoc));
3598 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3602 if (((
Name.startswith(
"movs") &&
3603 (
Name ==
"movs" ||
Name ==
"movsb" ||
Name ==
"movsw" ||
3604 Name ==
"movsl" ||
Name ==
"movsd" ||
Name ==
"movsq")) ||
3605 (
Name.startswith(
"smov") &&
3606 (
Name ==
"smov" ||
Name ==
"smovb" ||
Name ==
"smovw" ||
3607 Name ==
"smovl" ||
Name ==
"smovd" ||
Name ==
"smovq"))) &&
3609 if (
Name ==
"movsd" &&
Operands.size() == 1 && !isParsingIntelSyntax())
3611 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
3612 DefaultMemDIOperand(NameLoc));
3613 HadVerifyError = VerifyAndAdjustOperands(
Operands, TmpOperands);
3617 if (HadVerifyError) {
3618 return HadVerifyError;
3626 "size, (R|E)BX will be used for the location");
3638 if (ForcedVEXEncoding != VEXEncoding_VEX3 &&
3646 default:
return false;
3651 if (ForcedDispEncoding == DispEncoding_Disp32) {
3652 Inst.
setOpcode(is16BitMode() ? X86::JMP_2 : X86::JMP_4);
3661 if (ForcedDispEncoding == DispEncoding_Disp32) {
3662 Inst.
setOpcode(is16BitMode() ? X86::JCC_2 : X86::JCC_4);
3680 using namespace X86;
3684 if (isVFCMADDCPH(Opcode) || isVFCMADDCSH(Opcode) || isVFMADDCPH(Opcode) ||
3685 isVFMADDCSH(Opcode)) {
3689 return Warning(Ops[0]->getStartLoc(),
"Destination register should be "
3690 "distinct from source registers");
3691 }
else if (isVFCMULCPH(Opcode) || isVFCMULCSH(Opcode) || isVFMULCPH(Opcode) ||
3692 isVFMULCSH(Opcode)) {
3702 return Warning(Ops[0]->getStartLoc(),
"Destination register should be "
3703 "distinct from source registers");
3704 }
else if (isV4FMADDPS(Opcode) || isV4FMADDSS(Opcode) ||
3705 isV4FNMADDPS(Opcode) || isV4FNMADDSS(Opcode) ||
3706 isVP4DPWSSDS(Opcode) || isVP4DPWSSD(Opcode)) {
3709 unsigned Src2Enc =
MRI->getEncodingValue(Src2);
3710 if (Src2Enc % 4 != 0) {
3712 unsigned GroupStart = (Src2Enc / 4) * 4;
3713 unsigned GroupEnd = GroupStart + 3;
3714 return Warning(Ops[0]->getStartLoc(),
3715 "source register '" +
RegName +
"' implicitly denotes '" +
3720 }
else if (isVGATHERDPD(Opcode) || isVGATHERDPS(Opcode) ||
3721 isVGATHERQPD(Opcode) || isVGATHERQPS(Opcode) ||
3722 isVPGATHERDD(Opcode) || isVPGATHERDQ(Opcode) ||
3723 isVPGATHERQD(Opcode) || isVPGATHERQQ(Opcode)) {
3727 unsigned Index =
MRI->getEncodingValue(
3730 return Warning(Ops[0]->getStartLoc(),
"index and destination registers "
3731 "should be distinct");
3735 unsigned Index =
MRI->getEncodingValue(
3737 if (Dest == Mask || Dest ==
Index || Mask ==
Index)
3738 return Warning(Ops[0]->getStartLoc(),
"mask, index, and destination "
3739 "registers should be distinct");
3749 for (
unsigned i = 0; i != NumOps; ++i) {
3754 if (Reg == X86::AH || Reg == X86::BH || Reg == X86::CH || Reg == X86::DH)
3761 if (UsesRex && HReg != X86::NoRegister) {
3763 return Error(Ops[0]->getStartLoc(),
3764 "can't encode '" +
RegName +
"' in an instruction requiring "
3769 if ((Opcode == X86::PREFETCHIT0 || Opcode == X86::PREFETCHIT1)) {
3773 Ops[0]->getStartLoc(),
3775 :
"'prefetchit1'")) +
3776 " only supports RIP-relative address");
3781void X86AsmParser::emitWarningForSpecialLVIInstruction(
SMLoc Loc) {
3782 Warning(Loc,
"Instruction may be vulnerable to LVI and "
3783 "requires manual mitigation");
3784 Note(
SMLoc(),
"See https://software.intel.com/"
3785 "security-software-guidance/insights/"
3786 "deep-dive-load-value-injection#specialinstructions"
3787 " for more information");
3811 bool Parse32 = is32BitMode() || Code16GCC;
3813 is64BitMode() ? X86::RSP : (Parse32 ? X86::ESP : X86::SP);
3819 ShlMemOp->addMemOperands(ShlInst, 5);
3832 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
3844void X86AsmParser::applyLVILoadHardeningMitigation(
MCInst &Inst,
3861 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
3864 }
else if (Opcode == X86::REP_PREFIX || Opcode == X86::REPNE_PREFIX) {
3867 emitWarningForSpecialLVIInstruction(Inst.
getLoc());
3889 getSTI().hasFeature(X86::FeatureLVIControlFlowIntegrity))
3890 applyLVICFIMitigation(Inst, Out);
3895 getSTI().hasFeature(X86::FeatureLVILoadHardening))
3896 applyLVILoadHardeningMitigation(Inst, Out);
3899bool X86AsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
3902 bool MatchingInlineAsm) {
3903 if (isParsingIntelSyntax())
3912 bool MatchingInlineAsm) {
3917 .
Case(
"finit",
"fninit")
3918 .
Case(
"fsave",
"fnsave")
3919 .
Case(
"fstcw",
"fnstcw")
3920 .
Case(
"fstcww",
"fnstcw")
3921 .
Case(
"fstenv",
"fnstenv")
3922 .
Case(
"fstsw",
"fnstsw")
3923 .
Case(
"fstsww",
"fnstsw")
3924 .
Case(
"fclex",
"fnclex")
3930 if (!MatchingInlineAsm)
3931 emitInstruction(Inst,
Operands, Out);
3936bool X86AsmParser::ErrorMissingFeature(
SMLoc IDLoc,
3938 bool MatchingInlineAsm) {
3939 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
3942 OS <<
"instruction requires:";
3943 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
3944 if (MissingFeatures[i])
3951 unsigned Result = 0;
3953 if (Prefix.isPrefix()) {
3954 Result = Prefix.getPrefix();
3960unsigned X86AsmParser::checkTargetMatchPredicate(
MCInst &Inst) {
3964 if (ForcedVEXEncoding == VEXEncoding_EVEX &&
3966 return Match_Unsupported;
3968 if ((ForcedVEXEncoding == VEXEncoding_VEX ||
3969 ForcedVEXEncoding == VEXEncoding_VEX2 ||
3970 ForcedVEXEncoding == VEXEncoding_VEX3) &&
3972 return Match_Unsupported;
3976 (ForcedVEXEncoding != VEXEncoding_VEX &&
3977 ForcedVEXEncoding != VEXEncoding_VEX2 &&
3978 ForcedVEXEncoding != VEXEncoding_VEX3))
3979 return Match_Unsupported;
3981 return Match_Success;
3984bool X86AsmParser::MatchAndEmitATTInstruction(
SMLoc IDLoc,
unsigned &Opcode,
3988 bool MatchingInlineAsm) {
3990 assert((*
Operands[0]).isToken() &&
"Leading operand should always be a mnemonic!");
3991 SMRange EmptyRange = std::nullopt;
3995 Out, MatchingInlineAsm);
4003 if (ForcedVEXEncoding == VEXEncoding_VEX)
4005 else if (ForcedVEXEncoding == VEXEncoding_VEX2)
4007 else if (ForcedVEXEncoding == VEXEncoding_VEX3)
4009 else if (ForcedVEXEncoding == VEXEncoding_EVEX)
4013 if (ForcedDispEncoding == DispEncoding_Disp8)
4015 else if (ForcedDispEncoding == DispEncoding_Disp32)
4023 if (ForcedDataPrefix == X86::Is32Bit)
4024 SwitchMode(X86::Is32Bit);
4028 MissingFeatures, MatchingInlineAsm,
4029 isParsingIntelSyntax());
4030 if (ForcedDataPrefix == X86::Is32Bit) {
4031 SwitchMode(X86::Is16Bit);
4032 ForcedDataPrefix = 0;
4034 switch (OriginalError) {
4037 if (!MatchingInlineAsm && validateInstruction(Inst,
Operands))
4042 if (!MatchingInlineAsm)
4043 while (processInstruction(Inst,
Operands))
4047 if (!MatchingInlineAsm)
4048 emitInstruction(Inst,
Operands, Out);
4051 case Match_InvalidImmUnsignedi4: {
4053 if (ErrorLoc ==
SMLoc())
4055 return Error(ErrorLoc,
"immediate must be an integer in range [0, 15]",
4056 EmptyRange, MatchingInlineAsm);
4058 case Match_MissingFeature:
4059 return ErrorMissingFeature(IDLoc, MissingFeatures, MatchingInlineAsm);
4060 case Match_InvalidOperand:
4061 case Match_MnemonicFail:
4062 case Match_Unsupported:
4065 if (
Op.getToken().empty()) {
4066 Error(IDLoc,
"instruction must have size higher than 0", EmptyRange,
4081 Op.setTokenValue(Tmp);
4089 const char *Suffixes =
Base[0] !=
'f' ?
"bwlq" :
"slt\0";
4091 const char *MemSize =
Base[0] !=
'f' ?
"\x08\x10\x20\x40" :
"\x20\x40\x50\0";
4103 bool HasVectorReg =
false;
4108 HasVectorReg =
true;
4109 else if (X86Op->
isMem()) {
4111 assert(
MemOp->Mem.Size == 0 &&
"Memory size always 0 under ATT syntax");
4118 for (
unsigned I = 0,
E = std::size(
Match);
I !=
E; ++
I) {
4119 Tmp.
back() = Suffixes[
I];
4120 if (
MemOp && HasVectorReg)
4121 MemOp->Mem.Size = MemSize[
I];
4122 Match[
I] = Match_MnemonicFail;
4123 if (
MemOp || !HasVectorReg) {
4125 MatchInstruction(
Operands, Inst, ErrorInfoIgnore, MissingFeatures,
4126 MatchingInlineAsm, isParsingIntelSyntax());
4128 if (
Match[
I] == Match_MissingFeature)
4129 ErrorInfoMissingFeatures = MissingFeatures;
4140 if (NumSuccessfulMatches == 1) {
4141 if (!MatchingInlineAsm && validateInstruction(Inst,
Operands))
4146 if (!MatchingInlineAsm)
4147 while (processInstruction(Inst,
Operands))
4151 if (!MatchingInlineAsm)
4152 emitInstruction(Inst,
Operands, Out);
4161 if (NumSuccessfulMatches > 1) {
4163 unsigned NumMatches = 0;
4164 for (
unsigned I = 0,
E = std::size(
Match);
I !=
E; ++
I)
4165 if (
Match[
I] == Match_Success)
4166 MatchChars[NumMatches++] = Suffixes[
I];
4170 OS <<
"ambiguous instructions require an explicit suffix (could be ";
4171 for (
unsigned i = 0; i != NumMatches; ++i) {
4174 if (i + 1 == NumMatches)
4176 OS <<
"'" <<
Base << MatchChars[i] <<
"'";
4179 Error(IDLoc,
OS.str(), EmptyRange, MatchingInlineAsm);
4188 if (OriginalError == Match_MnemonicFail)
4189 return Error(IDLoc,
"invalid instruction mnemonic '" +
Base +
"'",
4190 Op.getLocRange(), MatchingInlineAsm);
4192 if (OriginalError == Match_Unsupported)
4193 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4196 assert(OriginalError == Match_InvalidOperand &&
"Unexpected error");
4200 return Error(IDLoc,
"too few operands for instruction", EmptyRange,
4207 OperandRange, MatchingInlineAsm);
4211 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4217 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4225 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
4232 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4237 Error(IDLoc,
"unknown use of instruction mnemonic without a size suffix",
4238 EmptyRange, MatchingInlineAsm);
4242bool X86AsmParser::MatchAndEmitIntelInstruction(
SMLoc IDLoc,
unsigned &Opcode,
4246 bool MatchingInlineAsm) {
4248 assert((*
Operands[0]).isToken() &&
"Leading operand should always be a mnemonic!");
4250 SMRange EmptyRange = std::nullopt;
4262 if (ForcedVEXEncoding == VEXEncoding_VEX)
4264 else if (ForcedVEXEncoding == VEXEncoding_VEX2)
4266 else if (ForcedVEXEncoding == VEXEncoding_VEX3)
4268 else if (ForcedVEXEncoding == VEXEncoding_EVEX)
4272 if (ForcedDispEncoding == DispEncoding_Disp8)
4274 else if (ForcedDispEncoding == DispEncoding_Disp32)
4285 UnsizedMemOp = X86Op;
4295 static const char *
const PtrSizedInstrs[] = {
"call",
"jmp",
"push"};
4296 for (
const char *Instr : PtrSizedInstrs) {
4297 if (Mnemonic == Instr) {
4298 UnsizedMemOp->
Mem.
Size = getPointerWidth();
4310 if (Mnemonic ==
"push" &&
Operands.size() == 2) {
4312 if (X86Op->
isImm()) {
4314 const auto *
CE = dyn_cast<MCConstantExpr>(X86Op->
getImm());
4315 unsigned Size = getPointerWidth();
4320 Tmp += (is64BitMode())
4322 : (is32BitMode()) ?
"l" : (is16BitMode()) ?
"w" :
" ";
4323 Op.setTokenValue(Tmp);
4326 MissingFeatures, MatchingInlineAsm,
4337 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
4338 for (
unsigned Size : MopSizes) {
4342 unsigned M = MatchInstruction(
Operands, Inst, ErrorInfoIgnore,
4343 MissingFeatures, MatchingInlineAsm,
4344 isParsingIntelSyntax());
4349 if (
Match.back() == Match_MissingFeature)
4350 ErrorInfoMissingFeatures = MissingFeatures;
4360 if (
Match.empty()) {
4361 Match.push_back(MatchInstruction(
4363 isParsingIntelSyntax()));
4365 if (
Match.back() == Match_MissingFeature)
4366 ErrorInfoMissingFeatures = MissingFeatures;
4374 if (
Match.back() == Match_MnemonicFail) {
4375 return Error(IDLoc,
"invalid instruction mnemonic '" + Mnemonic +
"'",
4376 Op.getLocRange(), MatchingInlineAsm);
4383 if (UnsizedMemOp && NumSuccessfulMatches > 1 &&
4386 unsigned M = MatchInstruction(
4388 isParsingIntelSyntax());
4389 if (M == Match_Success)
4390 NumSuccessfulMatches = 1;
4402 if (NumSuccessfulMatches == 1) {
4403 if (!MatchingInlineAsm && validateInstruction(Inst,
Operands))
4408 if (!MatchingInlineAsm)
4409 while (processInstruction(Inst,
Operands))
4412 if (!MatchingInlineAsm)
4413 emitInstruction(Inst,
Operands, Out);
4416 }
else if (NumSuccessfulMatches > 1) {
4418 "multiple matches only possible with unsized memory operands");
4420 "ambiguous operand size for instruction '" + Mnemonic +
"\'",
4426 return Error(IDLoc,
"unsupported instruction", EmptyRange,
4434 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
4441 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
4447 if (ErrorLoc ==
SMLoc())
4449 return Error(ErrorLoc,
"immediate must be an integer in range [0, 15]",
4450 EmptyRange, MatchingInlineAsm);
4454 return Error(IDLoc,
"unknown instruction mnemonic", EmptyRange,
4458bool X86AsmParser::OmitRegisterFromClobberLists(
unsigned RegNo) {
4459 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo);
4462bool X86AsmParser::ParseDirective(
AsmToken DirectiveID) {
4466 return parseDirectiveArch();
4468 return ParseDirectiveCode(IDVal, DirectiveID.
getLoc());
4474 return Error(DirectiveID.
getLoc(),
"'.att_syntax noprefix' is not "
4475 "supported: registers must have a "
4476 "'%' prefix in .att_syntax");
4478 getParser().setAssemblerDialect(0);
4480 }
else if (IDVal.
startswith(
".intel_syntax")) {
4481 getParser().setAssemblerDialect(1);
4486 return Error(DirectiveID.
getLoc(),
"'.intel_syntax prefix' is not "
4487 "supported: registers must not have "
4488 "a '%' prefix in .intel_syntax");
4491 }
else if (IDVal ==
".nops")
4492 return parseDirectiveNops(DirectiveID.
getLoc());
4493 else if (IDVal ==
".even")
4494 return parseDirectiveEven(DirectiveID.
getLoc());
4495 else if (IDVal ==
".cv_fpo_proc")
4496 return parseDirectiveFPOProc(DirectiveID.
getLoc());
4497 else if (IDVal ==
".cv_fpo_setframe")
4498 return parseDirectiveFPOSetFrame(DirectiveID.
getLoc());
4499 else if (IDVal ==
".cv_fpo_pushreg")
4500 return parseDirectiveFPOPushReg(DirectiveID.
getLoc());
4501 else if (IDVal ==
".cv_fpo_stackalloc")
4502 return parseDirectiveFPOStackAlloc(DirectiveID.
getLoc());
4503 else if (IDVal ==
".cv_fpo_stackalign")
4504 return parseDirectiveFPOStackAlign(DirectiveID.
getLoc());
4505 else if (IDVal ==
".cv_fpo_endprologue")
4506 return parseDirectiveFPOEndPrologue(DirectiveID.
getLoc());
4507 else if (IDVal ==
".cv_fpo_endproc")
4508 return parseDirectiveFPOEndProc(DirectiveID.
getLoc());
4509 else if (IDVal ==
".seh_pushreg" ||
4511 return parseDirectiveSEHPushReg(DirectiveID.
getLoc());
4512 else if (IDVal ==
".seh_setframe" ||
4514 return parseDirectiveSEHSetFrame(DirectiveID.
getLoc());
4515 else if (IDVal ==
".seh_savereg" ||
4517 return parseDirectiveSEHSaveReg(DirectiveID.
getLoc());
4518 else if (IDVal ==
".seh_savexmm" ||
4520 return parseDirectiveSEHSaveXMM(DirectiveID.
getLoc());
4521 else if (IDVal ==
".seh_pushframe" ||
4523 return parseDirectiveSEHPushFrame(DirectiveID.
getLoc());
4528bool X86AsmParser::parseDirectiveArch() {
4530 getParser().parseStringToEndOfStatement();
4536bool X86AsmParser::parseDirectiveNops(
SMLoc L) {
4537 int64_t NumBytes = 0, Control = 0;
4538 SMLoc NumBytesLoc, ControlLoc;
4540 NumBytesLoc = getTok().getLoc();
4541 if (getParser().checkForValidSection() ||
4542 getParser().parseAbsoluteExpression(NumBytes))
4546 ControlLoc = getTok().getLoc();
4547 if (getParser().parseAbsoluteExpression(Control))
4550 if (getParser().parseEOL())
4553 if (NumBytes <= 0) {
4554 Error(NumBytesLoc,
"'.nops' directive with non-positive size");
4559 Error(ControlLoc,
"'.nops' directive with negative NOP size");
4564 getParser().getStreamer().emitNops(NumBytes, Control, L, STI);
4571bool X86AsmParser::parseDirectiveEven(
SMLoc L) {
4577 getStreamer().initSections(
false, getSTI());
4578 Section = getStreamer().getCurrentSectionOnly();
4581 getStreamer().emitCodeAlignment(
Align(2), &getSTI(), 0);
4583 getStreamer().emitValueToAlignment(
Align(2), 0, 1, 0);
4592 if (IDVal ==
".code16") {
4594 if (!is16BitMode()) {
4595 SwitchMode(X86::Is16Bit);
4596 getParser().getStreamer().emitAssemblerFlag(
MCAF_Code16);
4598 }
else if (IDVal ==
".code16gcc") {
4602 if (!is16BitMode()) {
4603 SwitchMode(X86::Is16Bit);
4604 getParser().getStreamer().emitAssemblerFlag(
MCAF_Code16);
4606 }
else if (IDVal ==
".code32") {
4608 if (!is32BitMode()) {
4609 SwitchMode(X86::Is32Bit);
4610 getParser().getStreamer().emitAssemblerFlag(
MCAF_Code32);
4612 }
else if (IDVal ==
".code64") {
4614 if (!is64BitMode()) {
4615 SwitchMode(X86::Is64Bit);
4616 getParser().getStreamer().emitAssemblerFlag(
MCAF_Code64);
4619 Error(L,
"unknown directive " + IDVal);
4627bool X86AsmParser::parseDirectiveFPOProc(
SMLoc L) {
4632 return Parser.
TokError(
"expected symbol name");
4633 if (Parser.
parseIntToken(ParamsSize,
"expected parameter byte count"))
4636 return Parser.
TokError(
"parameters size out of range");
4639 MCSymbol *ProcSym = getContext().getOrCreateSymbol(ProcName);
4640 return getTargetStreamer().emitFPOProc(ProcSym, ParamsSize, L);
4644bool X86AsmParser::parseDirectiveFPOSetFrame(
SMLoc L) {
4647 if (parseRegister(Reg, DummyLoc, DummyLoc) || parseEOL())
4649 return getTargetStreamer().emitFPOSetFrame(Reg, L);
4653bool X86AsmParser::parseDirectiveFPOPushReg(
SMLoc L) {
4656 if (parseRegister(Reg, DummyLoc, DummyLoc) || parseEOL())
4658 return getTargetStreamer().emitFPOPushReg(Reg, L);
4662bool X86AsmParser::parseDirectiveFPOStackAlloc(
SMLoc L) {
4667 return getTargetStreamer().emitFPOStackAlloc(
Offset, L);
4671bool X86AsmParser::parseDirectiveFPOStackAlign(
SMLoc L) {
4676 return getTargetStreamer().emitFPOStackAlign(
Offset, L);
4680bool X86AsmParser::parseDirectiveFPOEndPrologue(
SMLoc L) {
4684 return getTargetStreamer().emitFPOEndPrologue(L);
4688bool X86AsmParser::parseDirectiveFPOEndProc(
SMLoc L) {
4692 return getTargetStreamer().emitFPOEndProc(L);
4695bool X86AsmParser::parseSEHRegisterNumber(
unsigned RegClassID,
4697 SMLoc startLoc = getLexer().getLoc();
4703 if (parseRegister(RegNo, startLoc, endLoc))
4706 if (!X86MCRegisterClasses[RegClassID].
contains(RegNo)) {
4707 return Error(startLoc,
4708 "register is not supported for use with this directive");
4714 if (getParser().parseAbsoluteExpression(EncodedReg))
4720 for (
MCPhysReg Reg : X86MCRegisterClasses[RegClassID]) {
4721 if (
MRI->getEncodingValue(Reg) == EncodedReg) {
4727 return Error(startLoc,
4728 "incorrect register number for use with this directive");
4735bool X86AsmParser::parseDirectiveSEHPushReg(
SMLoc Loc) {
4737 if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg))
4741 return TokError(
"expected end of directive");
4744 getStreamer().emitWinCFIPushReg(Reg, Loc);
4748bool X86AsmParser::parseDirectiveSEHSetFrame(
SMLoc Loc) {
4751 if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg))
4754 return TokError(
"you must specify a stack pointer offset");
4757 if (getParser().parseAbsoluteExpression(Off))
4761 return TokError(
"expected end of directive");
4764 getStreamer().emitWinCFISetFrame(Reg, Off, Loc);
4768bool X86AsmParser::parseDirectiveSEHSaveReg(
SMLoc Loc) {
4771 if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg))
4774 return TokError(
"you must specify an offset on the stack");
4777 if (getParser().parseAbsoluteExpression(Off))
4781 return TokError(
"expected end of directive");
4784 getStreamer().emitWinCFISaveReg(Reg, Off, Loc);
4788bool X86AsmParser::parseDirectiveSEHSaveXMM(
SMLoc Loc) {
4791 if (parseSEHRegisterNumber(X86::VR128XRegClassID, Reg))
4794 return TokError(
"you must specify an offset on the stack");
4797 if (getParser().parseAbsoluteExpression(Off))
4801 return TokError(
"expected end of directive");
4804 getStreamer().emitWinCFISaveXMM(Reg, Off, Loc);
4808bool X86AsmParser::parseDirectiveSEHPushFrame(
SMLoc Loc) {
4812 SMLoc startLoc = getLexer().getLoc();
4814 if (!getParser().parseIdentifier(CodeID)) {
4815 if (CodeID !=
"code")
4816 return Error(startLoc,
"expected @code");
4822 return TokError(
"expected end of directive");
4825 getStreamer().emitWinCFIPushFrame(Code, Loc);
4835#define GET_MATCHER_IMPLEMENTATION
4836#include "X86GenAsmMatcher.inc"
unsigned const MachineRegisterInfo * MRI
static const char * getSubtargetFeatureName(uint64_t Val)
static unsigned MatchRegisterName(StringRef Name)
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 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.
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.