42 static const char OpPrecedence[] = {
61 std::unique_ptr<X86AsmInstrumentation> Instrumentation;
65 SMLoc consumeToken() {
73 uint64_t &
ErrorInfo,
bool matchingInlineAsm,
74 unsigned VariantID = 0) {
77 SwitchMode(X86::Mode32Bit);
78 unsigned rv = MatchInstructionImpl(Operands, Inst, ErrorInfo,
79 matchingInlineAsm, VariantID);
81 SwitchMode(X86::Mode16Bit);
85 enum InfixCalculatorTok {
101 class InfixCalculator {
102 typedef std::pair< InfixCalculatorTok, int64_t > ICToken;
107 int64_t popOperand() {
108 assert (!PostfixStack.empty() &&
"Poped an empty stack!");
109 ICToken
Op = PostfixStack.pop_back_val();
110 assert ((Op.first == IC_IMM || Op.first == IC_REGISTER)
111 &&
"Expected and immediate or register!");
114 void pushOperand(InfixCalculatorTok Op, int64_t Val = 0) {
115 assert ((Op == IC_IMM || Op == IC_REGISTER) &&
116 "Unexpected operand!");
117 PostfixStack.push_back(std::make_pair(Op, Val));
120 void popOperator() { InfixOperatorStack.pop_back(); }
121 void pushOperator(InfixCalculatorTok Op) {
123 if (InfixOperatorStack.empty()) {
124 InfixOperatorStack.push_back(Op);
131 unsigned Idx = InfixOperatorStack.size() - 1;
132 InfixCalculatorTok StackOp = InfixOperatorStack[Idx];
133 if (OpPrecedence[Op] > OpPrecedence[StackOp] || StackOp == IC_LPAREN) {
134 InfixOperatorStack.push_back(Op);
140 unsigned ParenCount = 0;
143 if (InfixOperatorStack.empty())
146 Idx = InfixOperatorStack.size() - 1;
147 StackOp = InfixOperatorStack[Idx];
148 if (!(OpPrecedence[StackOp] >= OpPrecedence[Op] || ParenCount))
153 if (!ParenCount && StackOp == IC_LPAREN)
156 if (StackOp == IC_RPAREN) {
158 InfixOperatorStack.pop_back();
159 }
else if (StackOp == IC_LPAREN) {
161 InfixOperatorStack.pop_back();
163 InfixOperatorStack.pop_back();
164 PostfixStack.push_back(std::make_pair(StackOp, 0));
168 InfixOperatorStack.push_back(Op);
173 while (!InfixOperatorStack.empty()) {
174 InfixCalculatorTok StackOp = InfixOperatorStack.pop_back_val();
175 if (StackOp != IC_LPAREN && StackOp != IC_RPAREN)
176 PostfixStack.push_back(std::make_pair(StackOp, 0));
179 if (PostfixStack.empty())
183 for (
unsigned i = 0, e = PostfixStack.size();
i != e; ++
i) {
184 ICToken Op = PostfixStack[
i];
185 if (Op.first == IC_IMM || Op.first == IC_REGISTER) {
188 assert (OperandStack.
size() > 1 &&
"Too few operands.");
197 Val = Op1.second + Op2.second;
198 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
201 Val = Op1.second - Op2.second;
202 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
205 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
206 "Multiply operation with an immediate and a register!");
207 Val = Op1.second * Op2.second;
208 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
211 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
212 "Divide operation with an immediate and a register!");
213 assert (Op2.second != 0 &&
"Division by zero!");
214 Val = Op1.second / Op2.second;
215 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
218 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
219 "Or operation with an immediate and a register!");
220 Val = Op1.second | Op2.second;
221 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
224 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
225 "Xor operation with an immediate and a register!");
226 Val = Op1.second ^ Op2.second;
227 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
230 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
231 "And operation with an immediate and a register!");
232 Val = Op1.second & Op2.second;
233 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
236 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
237 "Left shift operation with an immediate and a register!");
238 Val = Op1.second << Op2.second;
239 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
242 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
243 "Right shift operation with an immediate and a register!");
244 Val = Op1.second >> Op2.second;
245 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
250 assert (OperandStack.
size() == 1 &&
"Expected a single result.");
255 enum IntelExprState {
276 class IntelExprStateMachine {
277 IntelExprState State, PrevState;
278 unsigned BaseReg, IndexReg, TmpReg, Scale;
282 bool StopOnLBrac, AddImmPrefix;
287 IntelExprStateMachine(int64_t imm,
bool stoponlbrac,
bool addimmprefix) :
288 State(IES_PLUS), PrevState(IES_ERROR), BaseReg(0), IndexReg(0), TmpReg(0),
289 Scale(1), Imm(imm), Sym(nullptr), StopOnLBrac(stoponlbrac),
290 AddImmPrefix(addimmprefix) { Info.clear(); }
292 unsigned getBaseReg() {
return BaseReg; }
293 unsigned getIndexReg() {
return IndexReg; }
294 unsigned getScale() {
return Scale; }
296 StringRef getSymName() {
return SymName; }
297 int64_t getImm() {
return Imm + IC.execute(); }
298 bool isValidEndState() {
299 return State == IES_RBRAC || State == IES_INTEGER;
301 bool getStopOnLBrac() {
return StopOnLBrac; }
302 bool getAddImmPrefix() {
return AddImmPrefix; }
303 bool hadError() {
return State == IES_ERROR; }
310 IntelExprState CurrState = State;
319 IC.pushOperator(IC_OR);
322 PrevState = CurrState;
325 IntelExprState CurrState = State;
334 IC.pushOperator(IC_XOR);
337 PrevState = CurrState;
340 IntelExprState CurrState = State;
349 IC.pushOperator(IC_AND);
352 PrevState = CurrState;
355 IntelExprState CurrState = State;
364 IC.pushOperator(IC_LSHIFT);
367 PrevState = CurrState;
370 IntelExprState CurrState = State;
379 IC.pushOperator(IC_RSHIFT);
382 PrevState = CurrState;
385 IntelExprState CurrState = State;
394 IC.pushOperator(IC_PLUS);
395 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
401 assert (!IndexReg &&
"BaseReg/IndexReg already set!");
408 PrevState = CurrState;
411 IntelExprState CurrState = State;
428 if (!(CurrState == IES_PLUS || CurrState == IES_MINUS ||
429 CurrState == IES_MULTIPLY || CurrState == IES_DIVIDE ||
430 CurrState == IES_LPAREN || CurrState == IES_LBRAC))
431 IC.pushOperator(IC_MINUS);
432 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
438 assert (!IndexReg &&
"BaseReg/IndexReg already set!");
445 PrevState = CurrState;
448 IntelExprState CurrState = State;
458 PrevState = CurrState;
460 void onRegister(
unsigned Reg) {
461 IntelExprState CurrState = State;
468 State = IES_REGISTER;
470 IC.pushOperand(IC_REGISTER);
474 if (PrevState == IES_INTEGER) {
475 assert (!IndexReg &&
"IndexReg already set!");
476 State = IES_REGISTER;
479 Scale = IC.popOperand();
480 IC.pushOperand(IC_IMM);
487 PrevState = CurrState;
500 SymName = SymRefName;
501 IC.pushOperand(IC_IMM);
505 bool onInteger(int64_t TmpInt,
StringRef &ErrMsg) {
506 IntelExprState CurrState = State;
523 if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
525 assert (!IndexReg &&
"IndexReg already set!");
528 if(Scale != 1 && Scale != 2 && Scale != 4 && Scale != 8) {
529 ErrMsg =
"scale factor in address must be 1, 2, 4 or 8";
534 }
else if ((PrevState == IES_PLUS || PrevState == IES_MINUS ||
535 PrevState == IES_OR || PrevState == IES_AND ||
536 PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||
537 PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
538 PrevState == IES_LPAREN || PrevState == IES_LBRAC ||
539 PrevState == IES_NOT || PrevState == IES_XOR) &&
540 CurrState == IES_MINUS) {
543 IC.pushOperand(IC_IMM, -TmpInt);
544 }
else if ((PrevState == IES_PLUS || PrevState == IES_MINUS ||
545 PrevState == IES_OR || PrevState == IES_AND ||
546 PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||
547 PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
548 PrevState == IES_LPAREN || PrevState == IES_LBRAC ||
549 PrevState == IES_NOT || PrevState == IES_XOR) &&
550 CurrState == IES_NOT) {
553 IC.pushOperand(IC_IMM, ~TmpInt);
555 IC.pushOperand(IC_IMM, TmpInt);
559 PrevState = CurrState;
571 State = IES_MULTIPLY;
572 IC.pushOperator(IC_MULTIPLY);
585 IC.pushOperator(IC_DIVIDE);
597 IC.pushOperator(IC_PLUS);
602 IntelExprState CurrState = State;
611 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
617 assert (!IndexReg &&
"BaseReg/IndexReg already set!");
624 PrevState = CurrState;
627 IntelExprState CurrState = State;
644 if ((PrevState == IES_PLUS || PrevState == IES_MINUS ||
645 PrevState == IES_OR || PrevState == IES_AND ||
646 PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||
647 PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
648 PrevState == IES_LPAREN || PrevState == IES_LBRAC ||
649 PrevState == IES_NOT || PrevState == IES_XOR) &&
650 (CurrState == IES_MINUS || CurrState == IES_NOT)) {
655 IC.pushOperator(IC_LPAREN);
658 PrevState = CurrState;
670 IC.pushOperator(IC_RPAREN);
677 bool MatchingInlineAsm =
false) {
679 if (MatchingInlineAsm) {
680 if (!getLexer().isAtStartOfStatement())
684 return Parser.
Error(L, Msg, Range);
692 std::unique_ptr<X86Operand> DefaultMemSIOperand(
SMLoc Loc);
693 std::unique_ptr<X86Operand> DefaultMemDIOperand(
SMLoc Loc);
694 bool IsSIReg(
unsigned Reg);
695 unsigned GetSIDIForRegClass(
unsigned RegClassID,
unsigned Reg,
bool IsSIReg);
698 std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
699 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst);
702 std::unique_ptr<X86Operand> ParseOperand();
703 std::unique_ptr<X86Operand> ParseATTOperand();
704 std::unique_ptr<X86Operand> ParseIntelOperand();
705 std::unique_ptr<X86Operand> ParseIntelOffsetOfOperator();
706 bool ParseIntelDotOperator(
const MCExpr *Disp,
const MCExpr *&NewDisp);
707 std::unique_ptr<X86Operand> ParseIntelOperator(
unsigned OpKind);
708 std::unique_ptr<X86Operand>
709 ParseIntelSegmentOverride(
unsigned SegReg,
SMLoc Start,
unsigned Size);
710 std::unique_ptr<X86Operand> ParseRoundingModeOp(
SMLoc Start,
SMLoc End);
711 bool ParseIntelExpression(IntelExprStateMachine &SM,
SMLoc &
End);
712 std::unique_ptr<X86Operand>
713 ParseIntelBracExpression(
unsigned SegReg,
SMLoc Start, int64_t ImmDisp,
714 bool isSymbol,
unsigned Size);
717 bool IsUnevaluatedOperand,
SMLoc &
End);
719 std::unique_ptr<X86Operand> ParseMemOperand(
unsigned SegReg,
SMLoc StartLoc);
721 std::unique_ptr<X86Operand>
722 CreateMemForInlineAsm(
unsigned SegReg,
const MCExpr *Disp,
unsigned BaseReg,
723 unsigned IndexReg,
unsigned Scale,
SMLoc Start,
726 bool AllowBetterSizeMatch =
false);
728 bool parseDirectiveEven(
SMLoc L);
729 bool ParseDirectiveWord(
unsigned Size,
SMLoc L);
738 bool MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
741 bool MatchingInlineAsm)
override;
746 bool ErrorMissingFeature(
SMLoc IDLoc, uint64_t ErrorInfo,
747 bool MatchingInlineAsm);
749 bool MatchAndEmitATTInstruction(
SMLoc IDLoc,
unsigned &Opcode,
752 bool MatchingInlineAsm);
754 bool MatchAndEmitIntelInstruction(
SMLoc IDLoc,
unsigned &Opcode,
757 bool MatchingInlineAsm);
759 bool OmitRegisterFromClobberLists(
unsigned RegNo)
override;
767 bool ParseZ(std::unique_ptr<X86Operand> &Z,
const SMLoc &StartLoc);
772 unsigned AdjustAVX512Mem(
unsigned Size,
X86Operand* UnsizedMemOpNext);
774 bool is64BitMode()
const {
776 return getSTI().getFeatureBits()[X86::Mode64Bit];
778 bool is32BitMode()
const {
780 return getSTI().getFeatureBits()[X86::Mode32Bit];
782 bool is16BitMode()
const {
784 return getSTI().getFeatureBits()[X86::Mode16Bit];
786 void SwitchMode(
unsigned mode) {
788 FeatureBitset AllModes({X86::Mode64Bit, X86::Mode32Bit, X86::Mode16Bit});
790 unsigned FB = ComputeAvailableFeatures(
792 setAvailableFeatures(FB);
797 unsigned getPointerWidth() {
798 if (is16BitMode())
return 16;
799 if (is32BitMode())
return 32;
800 if (is64BitMode())
return 64;
804 bool isParsingIntelSyntax() {
805 return getParser().getAssemblerDialect();
811 #define GET_ASSEMBLER_HEADER
812 #include "X86GenAsmMatcher.inc"
823 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
824 Instrumentation.reset(
828 bool ParseRegister(
unsigned &RegNo,
SMLoc &StartLoc,
SMLoc &EndLoc)
override;
830 void SetFrameRegister(
unsigned RegNo)
override;
835 bool ParseDirective(
AsmToken DirectiveID)
override;
852 if ((BaseReg == X86::RIP && IndexReg != 0) || (IndexReg == X86::RIP)) {
853 ErrMsg =
"invalid base+index expression";
856 if (BaseReg != 0 && IndexReg != 0) {
857 if (X86MCRegisterClasses[X86::GR64RegClassID].
contains(BaseReg) &&
858 (X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg) ||
859 X86MCRegisterClasses[X86::GR32RegClassID].
contains(IndexReg)) &&
860 IndexReg != X86::RIZ) {
861 ErrMsg =
"base register is 64-bit, but index register is not";
864 if (X86MCRegisterClasses[X86::GR32RegClassID].
contains(BaseReg) &&
865 (X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg) ||
866 X86MCRegisterClasses[X86::GR64RegClassID].
contains(IndexReg)) &&
867 IndexReg != X86::EIZ){
868 ErrMsg =
"base register is 32-bit, but index register is not";
871 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg)) {
872 if (X86MCRegisterClasses[X86::GR32RegClassID].
contains(IndexReg) ||
873 X86MCRegisterClasses[X86::GR64RegClassID].
contains(IndexReg)) {
874 ErrMsg =
"base register is 16-bit, but index register is not";
877 if (((BaseReg == X86::BX || BaseReg == X86::BP) &&
878 IndexReg != X86::SI && IndexReg != X86::DI) ||
879 ((BaseReg == X86::SI || BaseReg == X86::DI) &&
880 IndexReg != X86::BX && IndexReg != X86::BP)) {
881 ErrMsg =
"invalid 16-bit base/index register combination";
889 bool X86AsmParser::ParseRegister(
unsigned &RegNo,
894 StartLoc = PercentTok.
getLoc();
905 if (isParsingIntelSyntax())
return true;
906 return Error(StartLoc,
"invalid register name",
918 if (isParsingInlineAsm() && isParsingIntelSyntax() && RegNo == X86::EFLAGS)
921 if (!is64BitMode()) {
927 if (RegNo == X86::RIZ ||
928 X86MCRegisterClasses[X86::GR64RegClassID].
contains(RegNo) ||
931 return Error(StartLoc,
"register %"
932 + Tok.
getString() +
" is only available in 64-bit mode",
934 }
else if (!getSTI().getFeatureBits()[X86::FeatureAVX512]) {
936 return Error(StartLoc,
"register %"
937 + Tok.
getString() +
" is only available with AVX512",
954 return Error(IntTok.
getLoc(),
"expected stack index");
956 case 0: RegNo = X86::ST0;
break;
957 case 1: RegNo = X86::ST1;
break;
958 case 2: RegNo = X86::ST2;
break;
959 case 3: RegNo = X86::ST3;
break;
960 case 4: RegNo = X86::ST4;
break;
961 case 5: RegNo = X86::ST5;
break;
962 case 6: RegNo = X86::ST6;
break;
963 case 7: RegNo = X86::ST7;
break;
964 default:
return Error(IntTok.
getLoc(),
"invalid stack index");
982 case '0': RegNo = X86::DR0;
break;
983 case '1': RegNo = X86::DR1;
break;
984 case '2': RegNo = X86::DR2;
break;
985 case '3': RegNo = X86::DR3;
break;
986 case '4': RegNo = X86::DR4;
break;
987 case '5': RegNo = X86::DR5;
break;
988 case '6': RegNo = X86::DR6;
break;
989 case '7': RegNo = X86::DR7;
break;
1000 if (isParsingIntelSyntax())
return true;
1001 return Error(StartLoc,
"invalid register name",
1009 void X86AsmParser::SetFrameRegister(
unsigned RegNo) {
1010 Instrumentation->SetInitialFrameRegister(RegNo);
1013 std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(
SMLoc Loc) {
1014 bool Parse32 = is32BitMode() || Code16GCC;
1015 unsigned Basereg = is64BitMode() ? X86::RSI : (Parse32 ? X86::ESI : X86::SI);
1022 std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand(
SMLoc Loc) {
1023 bool Parse32 = is32BitMode() || Code16GCC;
1024 unsigned Basereg = is64BitMode() ? X86::RDI : (Parse32 ? X86::EDI : X86::DI);
1031 bool X86AsmParser::IsSIReg(
unsigned Reg) {
1045 unsigned X86AsmParser::GetSIDIForRegClass(
unsigned RegClassID,
unsigned Reg,
1047 switch (RegClassID) {
1049 case X86::GR64RegClassID:
1050 return IsSIReg ? X86::RSI : X86::RDI;
1051 case X86::GR32RegClassID:
1052 return IsSIReg ? X86::ESI : X86::EDI;
1053 case X86::GR16RegClassID:
1054 return IsSIReg ? X86::SI : X86::DI;
1058 void X86AsmParser::AddDefaultSrcDestOperands(
1059 OperandVector& Operands, std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
1060 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst) {
1061 if (isParsingIntelSyntax()) {
1071 bool X86AsmParser::VerifyAndAdjustOperands(
OperandVector &OrigOperands,
1074 if (OrigOperands.
size() > 1) {
1077 "Operand size mismatch");
1081 int RegClassID = -1;
1082 for (
unsigned int i = 0;
i < FinalOperands.
size(); ++
i) {
1086 if (FinalOp.
isReg() &&
1091 if (FinalOp.
isMem()) {
1093 if (!OrigOp.
isMem())
1102 if (RegClassID != -1 &&
1103 !X86MCRegisterClasses[RegClassID].
contains(OrigReg)) {
1105 "mismatching source and destination index registers");
1108 if (X86MCRegisterClasses[X86::GR64RegClassID].
contains(OrigReg))
1109 RegClassID = X86::GR64RegClassID;
1110 else if (X86MCRegisterClasses[X86::GR32RegClassID].
contains(OrigReg))
1111 RegClassID = X86::GR32RegClassID;
1112 else if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(OrigReg))
1113 RegClassID = X86::GR16RegClassID;
1119 bool IsSI = IsSIReg(FinalReg);
1120 FinalReg = GetSIDIForRegClass(RegClassID, FinalReg, IsSI);
1122 if (FinalReg != OrigReg) {
1123 std::string RegName = IsSI ?
"ES:(R|E)SI" :
"ES:(R|E)DI";
1124 Warnings.push_back(std::make_pair(
1126 "memory operand is only for determining the size, " + RegName +
1127 " will be used for the location"));
1138 for (
auto &WarningMsg : Warnings) {
1139 Warning(WarningMsg.first, WarningMsg.second);
1143 for (
unsigned int i = 0;
i < FinalOperands.
size(); ++
i)
1147 for (
unsigned int i = 0;
i < FinalOperands.
size(); ++
i)
1148 OrigOperands.
push_back(std::move(FinalOperands[
i]));
1153 std::unique_ptr<X86Operand> X86AsmParser::ParseOperand() {
1154 if (isParsingIntelSyntax())
1155 return ParseIntelOperand();
1156 return ParseATTOperand();
1162 .
Cases(
"BYTE",
"byte", 8)
1163 .Cases(
"WORD",
"word", 16)
1164 .Cases(
"DWORD",
"dword", 32)
1165 .Cases(
"FWORD",
"fword", 48)
1166 .Cases(
"QWORD",
"qword", 64)
1167 .Cases(
"MMWORD",
"mmword", 64)
1168 .Cases(
"XWORD",
"xword", 80)
1169 .Cases(
"TBYTE",
"tbyte", 80)
1170 .Cases(
"XMMWORD",
"xmmword", 128)
1171 .Cases(
"YMMWORD",
"ymmword", 256)
1172 .Cases(
"ZMMWORD",
"zmmword", 512)
1173 .Cases(
"OPAQUE",
"opaque", -1U)
1178 std::unique_ptr<X86Operand> X86AsmParser::CreateMemForInlineAsm(
1179 unsigned SegReg,
const MCExpr *Disp,
unsigned BaseReg,
unsigned IndexReg,
1187 Size = getPointerWidth();
1195 Identifier, Info.
OpDecl);
1203 isa<MCSymbolRefExpr>(BinOp ? BinOp->
getLHS() : Disp);
1206 Size = Info.
Type * 8;
1210 if (AllowBetterSizeMatch)
1223 BaseReg = BaseReg ? BaseReg : 1;
1225 IndexReg, Scale, Start, End, Size, Identifier,
1232 int64_t FinalImmDisp,
SMLoc &BracLoc,
1242 if (ImmDisp != FinalImmDisp) {
1248 if (AR.Loc.getPointer() > BracLoc.
getPointer())
1251 assert (!Found &&
"ImmDisp already rewritten.");
1253 AR.Len = BracLoc.
getPointer() - AR.Loc.getPointer();
1254 AR.Val = FinalImmDisp;
1259 assert (Found &&
"Unable to rewrite ImmDisp.");
1270 if (AR.Loc.getPointer() < StartInBrac.
getPointer())
1275 const char *SymLocPtr = SymName.
data();
1277 if (
unsigned Len = SymLocPtr - StartInBrac.
getPointer()) {
1278 assert(Len > 0 &&
"Expected a non-negative length.");
1279 AsmRewrites.emplace_back(
AOK_Skip, StartInBrac, Len);
1282 if (
unsigned Len = End.
getPointer() - (SymLocPtr + SymName.
size())) {
1284 assert(Len > 0 &&
"Expected a non-negative length.");
1285 AsmRewrites.emplace_back(
AOK_Skip, Loc, Len);
1289 bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM,
SMLoc &End) {
1296 bool UpdateLocLex =
true;
1310 if (SM.isValidEndState()) {
1314 return Error(Tok.
getLoc(),
"unknown token in expression");
1328 SM.onRegister(TmpReg);
1329 UpdateLocLex =
false;
1332 if (!isParsingInlineAsm()) {
1333 if (getParser().parsePrimaryExpr(Val, End))
1334 return Error(Tok.
getLoc(),
"Unexpected identifier!");
1342 if (ParseIntelIdentifier(Val, Identifier, Info,
1347 SM.onIdentifierExpr(Val, Identifier);
1348 UpdateLocLex =
false;
1351 return Error(Tok.
getLoc(),
"Unexpected identifier!");
1355 if (isParsingInlineAsm() && SM.getAddImmPrefix())
1358 SMLoc Loc = getTok().getLoc();
1359 int64_t
IntVal = getTok().getIntVal();
1360 End = consumeToken();
1361 UpdateLocLex =
false;
1364 if (IDVal ==
"f" || IDVal ==
"b") {
1366 getContext().getDirectionalLocalSymbol(IntVal, IDVal ==
"b");
1371 return Error(Loc,
"invalid reference to undefined symbol");
1373 SM.onIdentifierExpr(Val, Identifier);
1374 End = consumeToken();
1376 if (SM.onInteger(IntVal, ErrMsg))
1377 return Error(Loc, ErrMsg);
1380 if (SM.onInteger(IntVal, ErrMsg))
1381 return Error(Loc, ErrMsg);
1394 SM.onLShift();
break;
1396 SM.onRShift();
break;
1403 return Error(Tok.
getLoc(),
"unknown token in expression");
1405 if (!Done && UpdateLocLex)
1406 End = consumeToken();
1413 std::unique_ptr<X86Operand>
1414 X86AsmParser::ParseIntelBracExpression(
unsigned SegReg,
SMLoc Start,
1415 int64_t ImmDisp,
bool isSymbol,
1421 return ErrorOperand(BracLoc,
"Expected '[' token!");
1428 IntelExprStateMachine SM(ImmDisp,
false,
true);
1429 if (ParseIntelExpression(SM, End))
1432 const MCExpr *Disp =
nullptr;
1433 if (
const MCExpr *Sym = SM.getSym()) {
1436 if (isParsingInlineAsm())
1438 ImmDisp, SM.getImm(), BracLoc, StartInBrac,
1442 if (SM.getImm() || !Disp) {
1458 if (ParseIntelDotOperator(Disp, NewDisp))
1468 Error(Start,
"cannot use more than one symbol in memory operand");
1471 if (SM.getBaseReg()) {
1472 Error(Start,
"cannot use base register with variable reference");
1475 if (SM.getIndexReg()) {
1476 Error(Start,
"cannot use index register with variable reference");
1481 int BaseReg = SM.getBaseReg();
1482 int IndexReg = SM.getIndexReg();
1483 int Scale = SM.getScale();
1484 if (!isParsingInlineAsm()) {
1486 if (!BaseReg && !IndexReg) {
1494 Error(StartInBrac, ErrMsg);
1498 IndexReg, Scale, Start, End, Size);
1502 return CreateMemForInlineAsm(SegReg, Disp, BaseReg, IndexReg, Scale, Start,
1503 End, Size, SM.getSymName(), Info,
1504 isParsingInlineAsm());
1508 bool X86AsmParser::ParseIntelIdentifier(
const MCExpr *&Val,
1511 bool IsUnevaluatedOperand,
SMLoc &End) {
1513 assert(isParsingInlineAsm() &&
"Expected to be parsing inline assembly.");
1518 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);
1530 Identifier = LineBuf;
1535 "frontend claimed part of a token?");
1541 SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(),
1543 assert(InternalName.
size() &&
"We should have an internal name here.");
1545 InstInfo->AsmRewrites->emplace_back(
AOK_Label, Loc, Identifier.
size(),
1550 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
1557 std::unique_ptr<X86Operand>
1558 X86AsmParser::ParseIntelSegmentOverride(
unsigned SegReg,
SMLoc Start,
1561 assert(SegReg != 0 &&
"Tried to parse a segment override without a segment!");
1564 return ErrorOperand(Tok.
getLoc(),
"Expected ':' token!");
1567 int64_t ImmDisp = 0;
1572 if (isParsingInlineAsm())
1587 return ParseIntelBracExpression(SegReg, Start, ImmDisp,
false, Size);
1591 if (!isParsingInlineAsm()) {
1592 if (getParser().parsePrimaryExpr(Val, End))
1593 return ErrorOperand(Tok.
getLoc(),
"unknown token in expression");
1600 if (ParseIntelIdentifier(Val, Identifier, Info,
1603 return CreateMemForInlineAsm(0, Val, 0,0,
1604 1, Start, End, Size, Identifier, Info);
1608 std::unique_ptr<X86Operand>
1609 X86AsmParser::ParseRoundingModeOp(
SMLoc Start,
SMLoc End) {
1613 const SMLoc consumedToken = consumeToken();
1622 return ErrorOperand(Tok.
getLoc(),
"Invalid rounding mode.");
1625 return ErrorOperand(Tok.
getLoc(),
"Expected - at this point");
1629 return ErrorOperand(Tok.
getLoc(),
"Expected } at this point");
1631 const MCExpr *RndModeOp =
1638 return ErrorOperand(Tok.
getLoc(),
"Expected } at this point");
1642 return ErrorOperand(Tok.
getLoc(),
"unknown token in expression");
1646 bool X86AsmParser::ParseIntelDotOperator(
const MCExpr *Disp,
1647 const MCExpr *&NewDisp) {
1650 int64_t OrigDispVal, DotDispVal;
1653 if (
const MCConstantExpr *OrigDisp = dyn_cast<MCConstantExpr>(Disp))
1654 OrigDispVal = OrigDisp->getValue();
1656 return Error(Tok.
getLoc(),
"Non-constant offsets are not supported!");
1660 if (DotDispStr.startswith(
"."))
1666 DotDispStr.getAsInteger(10, DotDisp);
1670 std::pair<StringRef, StringRef> BaseMember = DotDispStr.split(
'.');
1671 if (SemaCallback->LookupInlineAsmField(BaseMember.first, BaseMember.second,
1673 return Error(Tok.
getLoc(),
"Unable to lookup field reference!");
1674 DotDispVal = DotDisp;
1676 return Error(Tok.
getLoc(),
"Unexpected token type!");
1680 unsigned Len = DotDispStr.size();
1681 unsigned Val = OrigDispVal + DotDispVal;
1691 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOffsetOfOperator() {
1701 if (ParseIntelIdentifier(Val, Identifier, Info,
1706 InstInfo->AsmRewrites->emplace_back(
AOK_Skip, OffsetOfLoc, 7);
1711 bool Parse32 = is32BitMode() || Code16GCC;
1712 unsigned RegNo = is64BitMode() ? X86::RBX : (Parse32 ? X86::EBX : X86::BX);
1715 OffsetOfLoc, Identifier, Info.
OpDecl);
1730 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperator(
unsigned OpKind) {
1736 const MCExpr *Val =
nullptr;
1740 if (ParseIntelIdentifier(Val, Identifier, Info,
1745 return ErrorOperand(Start,
"unable to lookup expression");
1758 InstInfo->AsmRewrites->emplace_back(
AOK_Imm, TypeLoc, Len, CVal);
1764 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand() {
1770 if (isParsingInlineAsm()) {
1772 if (AsmTokStr ==
"offset" || AsmTokStr ==
"OFFSET")
1773 return ParseIntelOffsetOfOperator();
1774 if (AsmTokStr ==
"length" || AsmTokStr ==
"LENGTH")
1776 if (AsmTokStr ==
"size" || AsmTokStr ==
"SIZE")
1777 return ParseIntelOperator(
IOK_SIZE);
1778 if (AsmTokStr ==
"type" || AsmTokStr ==
"TYPE")
1779 return ParseIntelOperator(
IOK_TYPE);
1782 bool PtrInOperand =
false;
1787 return ErrorOperand(Tok.
getLoc(),
"Expected 'PTR' or 'ptr' token!");
1789 PtrInOperand =
true;
1795 if (getSTI().getFeatureBits()[X86::FeatureAVX512] &&
1797 return ParseRoundingModeOp(Start, End);
1802 !ParseRegister(RegNo, Start, End)) {
1807 if (RegNo == X86::RIP)
1808 return ErrorOperand(Start,
"rip can only be used as a base register");
1811 return ErrorOperand(Start,
"expected memory operand after "
1812 "'ptr', found register operand instead");
1816 return ParseIntelSegmentOverride(RegNo, Start, Size);
1823 return ParseIntelBracExpression(0, Start, 0,
false,
1827 IntelExprStateMachine SM(0,
true,
1829 if (ParseIntelExpression(SM, End))
1833 int64_t Imm = SM.getImm();
1835 SM.getSym()->evaluateAsAbsolute(Imm);
1845 InstInfo->AsmRewrites->emplace_back(
AOK_Imm, Start, Len, Imm);
1854 if (isParsingInlineAsm())
1855 return CreateMemForInlineAsm(0, SM.getSym(), 0,
1857 1, Start,
End, Size,
1858 SM.getSymName(), SM.getIdentifierInfo());
1869 return ErrorOperand(Start,
"expected a positive immediate displacement "
1870 "before bracketed expr.");
1872 return ParseIntelBracExpression(0, Start, Imm, isSymbol, Size);
1875 std::unique_ptr<X86Operand> X86AsmParser::ParseATTOperand() {
1877 switch (getLexer().getKind()) {
1885 if (ParseRegister(RegNo, Start, End))
return nullptr;
1886 if (RegNo == X86::EIZ || RegNo == X86::RIZ) {
1887 Error(Start,
"%eiz and %riz can only be used as index registers",
1891 if (RegNo == X86::RIP) {
1892 Error(Start,
"%rip can only be used as a base register",
1902 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].
contains(RegNo))
1903 return ErrorOperand(Start,
"invalid segment register");
1906 return ParseMemOperand(RegNo, Start);
1913 if (getParser().parseExpression(Val, End))
1919 if (getSTI().getFeatureBits()[X86::FeatureAVX512])
1920 return ParseRoundingModeOp(Start, End);
1921 return ErrorOperand(Start,
"Unexpected '{' in expression");
1928 bool X86AsmParser::ParseZ(std::unique_ptr<X86Operand> &Z,
1929 const SMLoc &StartLoc) {
1935 (getLexer().getTok().getIdentifier() ==
"z")))
1940 return Error(getLexer().getLoc(),
"Expected } at this point");
1948 bool X86AsmParser::HandleAVX512Operand(
OperandVector &Operands,
1951 if(getSTI().getFeatureBits()[X86::FeatureAVX512]) {
1954 const SMLoc consumedToken = consumeToken();
1958 if (getLexer().getTok().getIntVal() != 1)
1959 return TokError(
"Expected 1to<NUM> at this point");
1962 !getLexer().getTok().getIdentifier().
startswith(
"to"))
1963 return TokError(
"Expected 1to<NUM> at this point");
1965 const char *BroadcastPrimitive =
1967 .Case(
"to2",
"{1to2}")
1968 .
Case(
"to4",
"{1to4}")
1969 .
Case(
"to8",
"{1to8}")
1970 .
Case(
"to16",
"{1to16}")
1972 if (!BroadcastPrimitive)
1973 return TokError(
"Invalid memory broadcast primitive.");
1976 return TokError(
"Expected } at this point");
1987 std::unique_ptr<X86Operand> Z;
1988 if (ParseZ(Z, consumedToken))
1994 const SMLoc StartLoc = Z ? consumeToken() : consumedToken;
1997 if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
1999 return Error(getLexer().getLoc(),
"Expected } at this point");
2004 return Error(getLexer().getLoc(),
2005 "Expected an op-mask register at this point");
2010 if (ParseZ(Z, consumeToken()) || !Z)
2028 std::unique_ptr<X86Operand> X86AsmParser::ParseMemOperand(
unsigned SegReg,
2039 if (getParser().parseExpression(Disp, ExprEnd))
return nullptr;
2066 if (getParser().parseParenExpression(Disp, ExprEnd))
2087 unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
2088 SMLoc IndexLoc, BaseLoc;
2091 SMLoc StartLoc, EndLoc;
2093 if (ParseRegister(BaseReg, StartLoc, EndLoc))
return nullptr;
2094 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) {
2095 Error(StartLoc,
"eiz and riz can only be used as index registers",
2113 if (ParseRegister(IndexReg, L, L))
2115 if (BaseReg == X86::RIP) {
2116 Error(IndexLoc,
"%rip as base register can not have an index register");
2119 if (IndexReg == X86::RIP) {
2120 Error(IndexLoc,
"%rip is not allowed as an index register");
2129 "expected comma in scale expression");
2138 if (getParser().parseAbsoluteExpression(ScaleVal)){
2139 Error(Loc,
"expected scale expression");
2144 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg) &&
2146 Error(Loc,
"scale factor in 16-bit address must be 1");
2149 if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 &&
2151 Error(Loc,
"scale factor in address must be 1, 2, 4 or 8");
2163 if (getParser().parseAbsoluteExpression(Value))
2167 Warning(Loc,
"scale factor without index register is ignored");
2183 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg) &&
2184 (is64BitMode() || (BaseReg != X86::BX && BaseReg != X86::BP &&
2185 BaseReg != X86::SI && BaseReg != X86::DI)) &&
2186 BaseReg != X86::DX) {
2187 Error(BaseLoc,
"invalid 16-bit base register");
2191 X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg)) {
2192 Error(IndexLoc,
"16-bit memory operand may not include only index register");
2198 Error(BaseLoc, ErrMsg);
2202 if (SegReg || BaseReg || IndexReg)
2204 IndexReg, Scale, MemStart, MemEnd);
2214 if (Name ==
"jmp" && isParsingIntelSyntax() && isParsingInlineAsm()) {
2216 if (NextTok ==
"short") {
2223 InstInfo->AsmRewrites->emplace_back(
AOK_Skip, NameEndLoc,
2224 NextTok.
size() + 1);
2230 PatchedName !=
"setb" && PatchedName !=
"setnb")
2231 PatchedName = PatchedName.
substr(0, Name.
size()-1);
2237 bool IsVCMP = PatchedName[0] ==
'v';
2238 unsigned CCIdx = IsVCMP ? 4 : 3;
2240 PatchedName.
slice(CCIdx, PatchedName.
size() - 2))
2242 .
Case(
"eq_oq", 0x00)
2244 .
Case(
"lt_os", 0x01)
2246 .
Case(
"le_os", 0x02)
2247 .
Case(
"unord", 0x03)
2248 .
Case(
"unord_q", 0x03)
2250 .
Case(
"neq_uq", 0x04)
2252 .
Case(
"nlt_us", 0x05)
2254 .
Case(
"nle_us", 0x06)
2256 .
Case(
"ord_q", 0x07)
2258 .
Case(
"eq_uq", 0x08)
2260 .
Case(
"nge_us", 0x09)
2262 .
Case(
"ngt_us", 0x0A)
2263 .
Case(
"false", 0x0B)
2264 .
Case(
"false_oq", 0x0B)
2265 .
Case(
"neq_oq", 0x0C)
2267 .
Case(
"ge_os", 0x0D)
2269 .
Case(
"gt_os", 0x0E)
2271 .
Case(
"true_uq", 0x0F)
2272 .
Case(
"eq_os", 0x10)
2273 .
Case(
"lt_oq", 0x11)
2274 .
Case(
"le_oq", 0x12)
2275 .
Case(
"unord_s", 0x13)
2276 .
Case(
"neq_us", 0x14)
2277 .
Case(
"nlt_uq", 0x15)
2278 .
Case(
"nle_uq", 0x16)
2279 .
Case(
"ord_s", 0x17)
2280 .
Case(
"eq_us", 0x18)
2281 .
Case(
"nge_uq", 0x19)
2282 .
Case(
"ngt_uq", 0x1A)
2283 .
Case(
"false_os", 0x1B)
2284 .
Case(
"neq_os", 0x1C)
2285 .
Case(
"ge_oq", 0x1D)
2286 .
Case(
"gt_oq", 0x1E)
2287 .
Case(
"true_us", 0x1F)
2289 if (ComparisonCode != ~0U && (IsVCMP || ComparisonCode < 8)) {
2295 getParser().getContext());
2298 PatchedName = PatchedName.
substr(PatchedName.
size() - 2);
2306 unsigned CCIdx = PatchedName.
drop_back().
back() ==
'u' ? 2 : 1;
2308 PatchedName.
slice(5, PatchedName.
size() - CCIdx))
2318 if (ComparisonCode != ~0U && (ComparisonCode != 0 || CCIdx == 2)) {
2322 getParser().getContext());
2325 PatchedName = PatchedName.
substr(PatchedName.
size() - CCIdx);
2333 unsigned CCIdx = PatchedName.
drop_back().
back() ==
'u' ? 2 : 1;
2335 PatchedName.
slice(5, PatchedName.
size() - CCIdx))
2345 if (ComparisonCode != ~0U) {
2349 getParser().getContext());
2352 PatchedName = PatchedName.
substr(PatchedName.
size() - CCIdx);
2360 Name ==
"lock" || Name ==
"rep" ||
2361 Name ==
"repe" || Name ==
"repz" ||
2362 Name ==
"repne" || Name ==
"repnz" ||
2363 Name ==
"rex64" || Name ==
"data16";
2365 bool CurlyAsEndOfStatement =
false;
2378 if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
2380 if (HandleAVX512Operand(Operands, *Operands.
back()))
2394 CurlyAsEndOfStatement =
2395 isParsingIntelSyntax() && isParsingInlineAsm() &&
2398 return TokError(
"unexpected token in argument list");
2405 else if (CurlyAsEndOfStatement)
2408 getLexer().getTok().getLoc(), 0);
2414 Name ==
"fsub" || Name ==
"fdiv" || Name ==
"fsubr" || Name ==
"fdivr";
2415 if (IsFp && Operands.
size() == 1) {
2417 .Case(
"fsub",
"fsubp")
2418 .
Case(
"fdiv",
"fdivp")
2419 .
Case(
"fsubr",
"fsubrp")
2420 .
Case(
"fdivr",
"fdivrp");
2421 static_cast<X86Operand &
>(*Operands[0]).setTokenValue(Repl);
2426 if ((Name ==
"mov" || Name ==
"movw" || Name ==
"movl") &&
2427 (Operands.
size() == 3)) {
2432 X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(
2434 (X86MCRegisterClasses[X86::GR16RegClassID].
contains(Op1.
getReg()) ||
2435 X86MCRegisterClasses[X86::GR32RegClassID].
contains(Op1.
getReg()))) {
2437 if (Name !=
"mov" && Name[3] == (is16BitMode() ?
'l' :
'w')) {
2438 Name = is16BitMode() ?
"movw" :
"movl";
2451 if ((Name ==
"outb" || Name ==
"outsb" || Name ==
"outw" || Name ==
"outsw" ||
2452 Name ==
"outl" || Name ==
"outsl" || Name ==
"out" || Name ==
"outs") &&
2453 Operands.
size() == 3) {
2456 isa<MCConstantExpr>(Op.
Mem.
Disp) &&
2457 cast<MCConstantExpr>(Op.
Mem.
Disp)->getValue() == 0 &&
2464 if ((Name ==
"inb" || Name ==
"insb" || Name ==
"inw" || Name ==
"insw" ||
2465 Name ==
"inl" || Name ==
"insl" || Name ==
"in" || Name ==
"ins") &&
2466 Operands.
size() == 3) {
2469 isa<MCConstantExpr>(Op.
Mem.
Disp) &&
2470 cast<MCConstantExpr>(Op.
Mem.
Disp)->getValue() == 0 &&
2478 bool HadVerifyError =
false;
2482 (Operands.
size() == 1 || Operands.
size() == 3) &&
2483 (Name ==
"insb" || Name ==
"insw" || Name ==
"insl" || Name ==
"insd" ||
2486 AddDefaultSrcDestOperands(TmpOperands,
2488 DefaultMemDIOperand(NameLoc));
2489 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2494 (Operands.
size() == 1 || Operands.
size() == 3) &&
2495 (Name ==
"outsb" || Name ==
"outsw" || Name ==
"outsl" ||
2496 Name ==
"outsd" || Name ==
"outs")) {
2497 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
2499 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2506 (Operands.
size() == 1 || Operands.
size() == 2) &&
2507 (Name ==
"lods" || Name ==
"lodsb" || Name ==
"lodsw" ||
2508 Name ==
"lodsl" || Name ==
"lodsd" || Name ==
"lodsq")) {
2509 TmpOperands.
push_back(DefaultMemSIOperand(NameLoc));
2510 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2517 (Operands.
size() == 1 || Operands.
size() == 2) &&
2518 (Name ==
"stos" || Name ==
"stosb" || Name ==
"stosw" ||
2519 Name ==
"stosl" || Name ==
"stosd" || Name ==
"stosq")) {
2520 TmpOperands.
push_back(DefaultMemDIOperand(NameLoc));
2521 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2528 (Operands.
size() == 1 || Operands.
size() == 2) &&
2529 (Name ==
"scas" || Name ==
"scasb" || Name ==
"scasw" ||
2530 Name ==
"scasl" || Name ==
"scasd" || Name ==
"scasq")) {
2531 TmpOperands.
push_back(DefaultMemDIOperand(NameLoc));
2532 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2537 (Operands.
size() == 1 || Operands.
size() == 3) &&
2538 (Name ==
"cmps" || Name ==
"cmpsb" || Name ==
"cmpsw" ||
2539 Name ==
"cmpsl" || Name ==
"cmpsd" || Name ==
"cmpsq")) {
2540 AddDefaultSrcDestOperands(TmpOperands, DefaultMemDIOperand(NameLoc),
2541 DefaultMemSIOperand(NameLoc));
2542 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2547 (Name ==
"movs" || Name ==
"movsb" || Name ==
"movsw" ||
2548 Name ==
"movsl" || Name ==
"movsd" || Name ==
"movsq")) ||
2550 (Name ==
"smov" || Name ==
"smovb" || Name ==
"smovw" ||
2551 Name ==
"smovl" || Name ==
"smovd" || Name ==
"smovq"))) &&
2552 (Operands.
size() == 1 || Operands.
size() == 3)) {
2553 if (Name ==
"movsd" && Operands.
size() == 1 && !isParsingIntelSyntax())
2555 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
2556 DefaultMemDIOperand(NameLoc));
2557 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2561 if (HadVerifyError) {
2562 return HadVerifyError;
2571 Operands.
size() == 3) {
2572 if (isParsingIntelSyntax()) {
2575 if (Op1.
isImm() && isa<MCConstantExpr>(Op1.
getImm()) &&
2576 cast<MCConstantExpr>(Op1.
getImm())->getValue() == 1)
2580 if (Op1.
isImm() && isa<MCConstantExpr>(Op1.
getImm()) &&
2581 cast<MCConstantExpr>(Op1.
getImm())->getValue() == 1)
2588 if (Name ==
"int" && Operands.
size() == 2) {
2591 if (
auto *CE = dyn_cast<MCConstantExpr>(Op1.
getImm()))
2592 if (
CE->getValue() == 3) {
2594 static_cast<X86Operand &
>(*Operands[0]).setTokenValue(
"int3");
2599 if ((Name ==
"xlat" || Name ==
"xlatb") && Operands.
size() == 2) {
2602 Warning(Op1.
getStartLoc(),
"memory operand is only for determining the "
2603 "size, (R|E)BX will be used for the location");
2605 static_cast<X86Operand &
>(*Operands[0]).setTokenValue(
"xlatb");
2620 Instrumentation->InstrumentAndEmitInstruction(Inst, Operands, getContext(),
2624 bool X86AsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
2627 bool MatchingInlineAsm) {
2628 if (isParsingIntelSyntax())
2629 return MatchAndEmitIntelInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2631 return MatchAndEmitATTInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2637 bool MatchingInlineAsm) {
2642 .Case(
"finit",
"fninit")
2643 .
Case(
"fsave",
"fnsave")
2644 .
Case(
"fstcw",
"fnstcw")
2645 .
Case(
"fstcww",
"fnstcw")
2646 .
Case(
"fstenv",
"fnstenv")
2647 .
Case(
"fstsw",
"fnstsw")
2648 .
Case(
"fstsww",
"fnstsw")
2649 .
Case(
"fclex",
"fnclex")
2655 if (!MatchingInlineAsm)
2656 EmitInstruction(Inst, Operands, Out);
2661 bool X86AsmParser::ErrorMissingFeature(
SMLoc IDLoc, uint64_t ErrorInfo,
2662 bool MatchingInlineAsm) {
2663 assert(ErrorInfo &&
"Unknown missing feature!");
2666 OS <<
"instruction requires:";
2668 for (
unsigned i = 0;
i < (
sizeof(ErrorInfo)*8-1); ++
i) {
2669 if (ErrorInfo & Mask)
2673 return Error(IDLoc, OS.str(),
SMRange(), MatchingInlineAsm);
2676 bool X86AsmParser::MatchAndEmitATTInstruction(
SMLoc IDLoc,
unsigned &Opcode,
2679 uint64_t &ErrorInfo,
2680 bool MatchingInlineAsm) {
2681 assert(!Operands.
empty() &&
"Unexpect empty operand list!");
2683 assert(Op.isToken() &&
"Leading operand should always be a mnemonic!");
2687 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2689 bool WasOriginallyInvalidOperand =
false;
2693 switch (MatchInstruction(Operands, Inst, ErrorInfo, MatchingInlineAsm,
2694 isParsingIntelSyntax())) {
2700 if (!MatchingInlineAsm)
2701 while (processInstruction(Inst, Operands))
2705 if (!MatchingInlineAsm)
2706 EmitInstruction(Inst, Operands, Out);
2709 case Match_MissingFeature:
2710 return ErrorMissingFeature(IDLoc, ErrorInfo, MatchingInlineAsm);
2711 case Match_InvalidOperand:
2712 WasOriginallyInvalidOperand =
true;
2714 case Match_MnemonicFail:
2728 Op.setTokenValue(Tmp);
2736 const char *Suffixes = Base[0] !=
'f' ?
"bwlq" :
"slt\0";
2739 uint64_t ErrorInfoIgnore;
2740 uint64_t ErrorInfoMissingFeature = 0;
2744 Tmp.
back() = Suffixes[
I];
2745 Match[
I] = MatchInstruction(Operands, Inst, ErrorInfoIgnore,
2746 MatchingInlineAsm, isParsingIntelSyntax());
2748 if (Match[
I] == Match_MissingFeature)
2749 ErrorInfoMissingFeature = ErrorInfoIgnore;
2753 Op.setTokenValue(Base);
2758 unsigned NumSuccessfulMatches =
2760 if (NumSuccessfulMatches == 1) {
2762 if (!MatchingInlineAsm)
2763 EmitInstruction(Inst, Operands, Out);
2772 if (NumSuccessfulMatches > 1) {
2774 unsigned NumMatches = 0;
2776 if (Match[
I] == Match_Success)
2777 MatchChars[NumMatches++] = Suffixes[
I];
2781 OS <<
"ambiguous instructions require an explicit suffix (could be ";
2782 for (
unsigned i = 0;
i != NumMatches; ++
i) {
2785 if (
i + 1 == NumMatches)
2787 OS <<
"'" << Base << MatchChars[
i] <<
"'";
2790 Error(IDLoc, OS.str(), EmptyRange, MatchingInlineAsm);
2799 if (!WasOriginallyInvalidOperand) {
2800 return Error(IDLoc,
"invalid instruction mnemonic '" + Base +
"'",
2801 Op.getLocRange(), MatchingInlineAsm);
2805 if (ErrorInfo != ~0ULL) {
2806 if (ErrorInfo >= Operands.
size())
2807 return Error(IDLoc,
"too few operands for instruction", EmptyRange,
2814 OperandRange, MatchingInlineAsm);
2818 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
2825 Match_MissingFeature) == 1) {
2826 ErrorInfo = ErrorInfoMissingFeature;
2827 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
2834 Match_InvalidOperand) == 1) {
2835 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
2840 Error(IDLoc,
"unknown use of instruction mnemonic without a size suffix",
2841 EmptyRange, MatchingInlineAsm);
2845 unsigned X86AsmParser::AdjustAVX512Mem(
unsigned Size,
2848 if (!getSTI().getFeatureBits()[X86::FeatureAVX512])
2851 if (Size == 512 || Size == 256 || Size == 128)
2855 if (Size == 64 || Size == 32)
2856 return UnsizedMemOpNext && UnsizedMemOpNext->
isToken() &&
2862 bool X86AsmParser::MatchAndEmitIntelInstruction(
SMLoc IDLoc,
unsigned &Opcode,
2865 uint64_t &ErrorInfo,
2866 bool MatchingInlineAsm) {
2867 assert(!Operands.
empty() &&
"Unexpect empty operand list!");
2869 assert(Op.isToken() &&
"Leading operand should always be a mnemonic!");
2875 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2884 for (
const auto &Op : Operands) {
2887 UnsizedMemOpNext = X86Op;
2893 UnsizedMemOp = X86Op;
2899 static const char *
const PtrSizedInstrs[] = {
"call",
"jmp",
"push"};
2900 for (
const char *Instr : PtrSizedInstrs) {
2901 if (Mnemonic == Instr) {
2902 UnsizedMemOp->
Mem.
Size = getPointerWidth();
2909 uint64_t ErrorInfoMissingFeature = 0;
2913 if (Mnemonic ==
"push" && Operands.size() == 2) {
2914 auto *X86Op =
static_cast<X86Operand *
>(Operands[1].get());
2915 if (X86Op->
isImm()) {
2918 unsigned Size = getPointerWidth();
2923 Tmp += (is64BitMode())
2925 : (is32BitMode()) ?
"l" : (is16BitMode()) ?
"w" :
" ";
2926 Op.setTokenValue(Tmp);
2928 Match.
push_back(MatchInstruction(Operands, Inst, ErrorInfo,
2931 Op.setTokenValue(Base);
2939 unsigned MatchedSize = 0;
2941 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
2942 for (
unsigned Size : MopSizes) {
2943 UnsizedMemOp->
Mem.
Size = Size;
2944 uint64_t ErrorInfoIgnore;
2946 unsigned M = MatchInstruction(Operands, Inst, ErrorInfoIgnore,
2947 MatchingInlineAsm, isParsingIntelSyntax());
2952 if (Match.
back() == Match_MissingFeature)
2953 ErrorInfoMissingFeature = ErrorInfoIgnore;
2954 if (M == Match_Success)
2959 MatchedSize = AdjustAVX512Mem(Size, UnsizedMemOpNext);
2970 if (Match.
empty()) {
2972 Operands, Inst, ErrorInfo, MatchingInlineAsm, isParsingIntelSyntax()));
2974 if (Match.
back() == Match_MissingFeature)
2975 ErrorInfoMissingFeature = ErrorInfo;
2983 if (Match.
back() == Match_MnemonicFail) {
2984 return Error(IDLoc,
"invalid instruction mnemonic '" + Mnemonic +
"'",
2985 Op.getLocRange(), MatchingInlineAsm);
2991 unsigned NumSuccessfulMatches =
2993 if (NumSuccessfulMatches == 1) {
2994 if (MatchedSize && isParsingInlineAsm() && isParsingIntelSyntax())
2998 for (
AsmRewrite &AR : *InstInfo->AsmRewrites)
3001 AR.
Val = MatchedSize;
3005 if (!MatchingInlineAsm)
3006 while (processInstruction(Inst, Operands))
3009 if (!MatchingInlineAsm)
3010 EmitInstruction(Inst, Operands, Out);
3013 }
else if (NumSuccessfulMatches > 1) {
3015 "multiple matches only possible with unsized memory operands");
3017 "ambiguous operand size for instruction '" + Mnemonic +
"\'",
3024 Match_MissingFeature) == 1) {
3025 ErrorInfo = ErrorInfoMissingFeature;
3026 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
3033 Match_InvalidOperand) == 1) {
3034 return Error(IDLoc,
"invalid operand for instruction", EmptyRange,
3039 return Error(IDLoc,
"unknown instruction mnemonic", EmptyRange,
3043 bool X86AsmParser::OmitRegisterFromClobberLists(
unsigned RegNo) {
3044 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo);
3047 bool X86AsmParser::ParseDirective(
AsmToken DirectiveID) {
3050 if (IDVal ==
".word")
3051 return ParseDirectiveWord(2, DirectiveID.
getLoc());
3053 return ParseDirectiveCode(IDVal, DirectiveID.
getLoc());
3059 return Error(DirectiveID.
getLoc(),
"'.att_syntax noprefix' is not "
3060 "supported: registers must have a "
3061 "'%' prefix in .att_syntax");
3063 getParser().setAssemblerDialect(0);
3065 }
else if (IDVal.
startswith(
".intel_syntax")) {
3066 getParser().setAssemblerDialect(1);
3071 return Error(DirectiveID.
getLoc(),
"'.intel_syntax prefix' is not "
3072 "supported: registers must not have "
3073 "a '%' prefix in .intel_syntax");
3076 }
else if (IDVal ==
".even")
3077 return parseDirectiveEven(DirectiveID.
getLoc());
3083 bool X86AsmParser::parseDirectiveEven(
SMLoc L) {
3085 TokError(
"unexpected token in directive");
3090 getStreamer().InitSections(
false);
3091 Section = getStreamer().getCurrentSectionOnly();
3094 getStreamer().EmitCodeAlignment(2, 0);
3096 getStreamer().EmitValueToAlignment(2, 0, 1, 0);
3101 bool X86AsmParser::ParseDirectiveWord(
unsigned Size,
SMLoc L) {
3106 SMLoc ExprLoc = getLexer().getLoc();
3107 if (getParser().parseExpression(Value))
3110 if (
const auto *MCE = dyn_cast<MCConstantExpr>(Value)) {
3111 assert(Size <= 8 &&
"Invalid size");
3112 uint64_t IntValue = MCE->getValue();
3113 if (!
isUIntN(8 * Size, IntValue) && !
isIntN(8 * Size, IntValue))
3114 return Error(ExprLoc,
"literal value out of range for directive");
3115 getStreamer().EmitIntValue(IntValue, Size);
3117 getStreamer().EmitValue(Value, Size, ExprLoc);
3125 Error(L,
"unexpected token in directive");
3138 bool X86AsmParser::ParseDirectiveCode(
StringRef IDVal,
SMLoc L) {
3141 if (IDVal ==
".code16") {
3143 if (!is16BitMode()) {
3144 SwitchMode(X86::Mode16Bit);
3145 getParser().getStreamer().EmitAssemblerFlag(
MCAF_Code16);
3147 }
else if (IDVal ==
".code16gcc") {
3151 if (!is16BitMode()) {
3152 SwitchMode(X86::Mode16Bit);
3153 getParser().getStreamer().EmitAssemblerFlag(
MCAF_Code16);
3155 }
else if (IDVal ==
".code32") {
3157 if (!is32BitMode()) {
3158 SwitchMode(X86::Mode32Bit);
3159 getParser().getStreamer().EmitAssemblerFlag(
MCAF_Code32);
3161 }
else if (IDVal ==
".code64") {
3163 if (!is64BitMode()) {
3164 SwitchMode(X86::Mode64Bit);
3165 getParser().getStreamer().EmitAssemblerFlag(
MCAF_Code64);
3168 Error(L,
"unknown directive " + IDVal);
3181 #define GET_REGISTER_MATCHER
3182 #define GET_MATCHER_IMPLEMENTATION
3183 #define GET_SUBTARGET_FEATURE_NAME
3184 #include "X86GenAsmMatcher.inc"
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
StringRef getToken() const
static const char * getSubtargetFeatureName(uint64_t Val)
Represents a range in source code.
Instances of this class represent a uniqued identifier for a section in the current translation unit...
void push_back(const T &Elt)
const_iterator end(StringRef path)
Get end iterator over path.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool endswith(StringRef Suffix) const
Check if this string ends with the given Suffix.
uint64_t getZExtValue() const
Get zero extended value.
bool isX86_64NonExtLowByteReg(unsigned reg)
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
const char * getPointer() const
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
TokenKind getKind() const
SmallVectorImpl< AsmRewrite > * AsmRewrites
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Generic assembler parser interface, for use by target specific assembly parsers.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
static std::unique_ptr< X86Operand > CreateMem(unsigned ModeSize, const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc, unsigned Size=0, StringRef SymName=StringRef(), void *OpDecl=nullptr)
Create an absolute memory operand.
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
opt Optimize addressing mode
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
bool isNot(TokenKind K) const
A raw_ostream that writes to an SmallVector or SmallString.
const_iterator begin(StringRef path)
Get begin iterator over path.
LLVM_NODISCARD char back() const
back - Get the last character in the string.
return AArch64::GPR64RegClass contains(Reg)
static ModuleSymbolTable::Symbol getSym(DataRefImpl &Symb)
static bool CheckBaseRegAndIndexReg(unsigned BaseReg, unsigned IndexReg, StringRef &ErrMsg)
}
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
void LLVMInitializeX86AsmParser()
SMLoc getEndLoc() const override
getEndLoc - Get the location of the last token of this operand.
bool isImm() const override
isImm - Is this an immediate operand?
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Base class for the full range of assembler expressions which are needed for parsing.
LLVM_ATTRIBUTE_ALWAYS_INLINE R Default(const T &Value) const
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool equals(StringRef RHS) const
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
Reg
All possible values of the reg field in the ModR/M byte.
Target independent representation for an assembler token.
static unsigned getIntelMemOperandSize(StringRef OpStr)
getIntelMemOperandSize - Return intel memory operand size.
Windows NT (Windows on ARM)
const MCExpr * getImm() const
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand...
static std::unique_ptr< X86Operand > CreateImm(const MCExpr *Val, SMLoc StartLoc, SMLoc EndLoc)
LLVM_NODISCARD bool empty() const
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Case(const char(&S)[N], const T &Value)
unsigned getReg() const override
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
.code16 (X86) / .code 16 (ARM)
Function Alias Analysis false
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
auto count(R &&Range, const E &Element) -> typename std::iterator_traits< decltype(std::begin(Range))>::difference_type
Wrapper function around std::count to count the number of times an element Element occurs in the give...
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
int64_t getIntVal() const
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
Instances of this class represent a single low-level machine instruction.
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
bool isPrefix(MCInstrInfo const &MCII, MCInst const &MCI)
bool isX86_64ExtendedReg(unsigned RegNo)
isX86_64ExtendedReg - Is the MachineOperand a x86-64 extended (r8 or higher) register? e.g.
FeatureBitset ToggleFeature(uint64_t FB)
ToggleFeature - Toggle a feature and returns the re-computed feature bits.
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
virtual MCContext & getContext()=0
A switch()-like statement whose cases are string literals.
Streaming machine code generation interface.
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
X86Operand - Instances of this class represent a parsed X86 machine instruction.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t find(char C, size_t From=0) const
Search for the first character C in the string.
SMRange getLocRange() const
getLocRange - Get the range between the first and last token of this operand.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Interface to description of machine instruction set.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang","erlang-compatible garbage collector")
static const unsigned End
bool Error(SMLoc L, const Twine &Msg, SMRange Range=None)
Return an error at the location L, with the message Msg.
virtual bool UseCodeAlign() const =0
Return true if a .align directive should use "optimized nops" to fill instead of 0s.
bool isIntN(unsigned N, int64_t x)
isIntN - Checks if an signed integer fits into the given (dynamic) bit width.
iterator erase(const_iterator CI)
Binary assembler expressions.
bool isToken() const override
isToken - Is this a token operand?
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
SMLoc getStartLoc() const override
getStartLoc - Get the location of the first token of this operand.
unsigned getX86SubSuperRegisterOrZero(unsigned, unsigned, bool High=false)
Returns the sub or super register of a specific X86 register.
X86AsmInstrumentation * CreateX86AsmInstrumentation(const MCTargetOptions &MCOptions, const MCContext &Ctx, const MCSubtargetInfo *&STI)
static bool is32ExtendedReg(unsigned RegNo)
is32ExtendedReg - Is the MemoryOperand a 32 extended (zmm16 or higher) registers? e...
void setOpcode(unsigned Op)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
constexpr size_t array_lengthof(T(&)[N])
Find the length of an array.
static void RewriteIntelBracExpression(SmallVectorImpl< AsmRewrite > &AsmRewrites, StringRef SymName, int64_t ImmDisp, int64_t FinalImmDisp, SMLoc &BracLoc, SMLoc &StartInBrac, SMLoc &End)
LLVM_NODISCARD T pop_back_val()
const FeatureBitset & getFeatureBits() const
getFeatureBits - Return the feature bits.
bool is(TokenKind K) const
bool isMemUnsized() const
unsigned getOpcode() const
Class for arbitrary precision integers.
Base class for user error types.
static std::unique_ptr< X86Operand > CreateToken(StringRef Str, SMLoc Loc)
.code32 (X86) / .code 32 (ARM)
static SMLoc getFromPointer(const char *Ptr)
static std::unique_ptr< X86Operand > CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc, bool AddressOf=false, SMLoc OffsetOfLoc=SMLoc(), StringRef SymName=StringRef(), void *OpDecl=nullptr)
static bool startswith(StringRef Magic, const char(&S)[N])
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string...
RegisterMCAsmParser - Helper template for registering a target specific assembly parser, for use in the target machine initialization function.
void emplace_back(ArgTypes &&...Args)
StringRef getName() const
getName - Get the symbol name.
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
MCSubtargetInfo - Generic base class for all target subtargets.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Target & getTheX86_32Target()
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
static unsigned MatchRegisterName(StringRef Name)
Maps from the set of all register names to a register number.
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
bool isReg() const override
isReg - Is this a register operand?
StringRef - Represent a constant reference to a string, i.e.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef drop_back(size_t N=1) const
Return a StringRef equal to 'this' but with the last N elements dropped.
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml","ocaml 3.10-compatible collector")
Represents a location in source code.
bool isUIntN(unsigned N, uint64_t x)
isUIntN - Checks if an unsigned integer fits into the given (dynamic) bit width.
Target & getTheX86_64Target()
LLVM_NODISCARD std::string lower() const
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx)
bool isMem() const override
isMem - Is this a memory operand?
bool isUndefined(bool SetUsed=true) const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).