43 static const char OpPrecedence[] = {
63 std::unique_ptr<X86AsmInstrumentation> Instrumentation;
65 SMLoc consumeToken() {
72 enum InfixCalculatorTok {
88 class InfixCalculator {
89 typedef std::pair< InfixCalculatorTok, int64_t > ICToken;
94 int64_t popOperand() {
95 assert (!PostfixStack.empty() &&
"Poped an empty stack!");
97 assert ((Op.first == IC_IMM || Op.first == IC_REGISTER)
98 &&
"Expected and immediate or register!");
101 void pushOperand(InfixCalculatorTok Op, int64_t Val = 0) {
102 assert ((Op == IC_IMM || Op == IC_REGISTER) &&
103 "Unexpected operand!");
104 PostfixStack.push_back(std::make_pair(Op, Val));
107 void popOperator() { InfixOperatorStack.pop_back(); }
108 void pushOperator(InfixCalculatorTok Op) {
110 if (InfixOperatorStack.empty()) {
111 InfixOperatorStack.push_back(Op);
118 unsigned Idx = InfixOperatorStack.size() - 1;
119 InfixCalculatorTok StackOp = InfixOperatorStack[Idx];
120 if (OpPrecedence[Op] > OpPrecedence[StackOp] || StackOp == IC_LPAREN) {
121 InfixOperatorStack.push_back(Op);
127 unsigned ParenCount = 0;
130 if (InfixOperatorStack.empty())
133 Idx = InfixOperatorStack.size() - 1;
134 StackOp = InfixOperatorStack[Idx];
135 if (!(OpPrecedence[StackOp] >= OpPrecedence[Op] || ParenCount))
140 if (!ParenCount && StackOp == IC_LPAREN)
143 if (StackOp == IC_RPAREN) {
145 InfixOperatorStack.pop_back();
146 }
else if (StackOp == IC_LPAREN) {
148 InfixOperatorStack.pop_back();
150 InfixOperatorStack.pop_back();
151 PostfixStack.push_back(std::make_pair(StackOp, 0));
155 InfixOperatorStack.push_back(Op);
159 while (!InfixOperatorStack.empty()) {
160 InfixCalculatorTok StackOp = InfixOperatorStack.pop_back_val();
161 if (StackOp != IC_LPAREN && StackOp != IC_RPAREN)
162 PostfixStack.push_back(std::make_pair(StackOp, 0));
165 if (PostfixStack.empty())
169 for (
unsigned i = 0, e = PostfixStack.size(); i != e; ++i) {
170 ICToken Op = PostfixStack[i];
171 if (Op.first == IC_IMM || Op.first == IC_REGISTER) {
174 assert (OperandStack.
size() > 1 &&
"Too few operands.");
183 Val = Op1.second + Op2.second;
184 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
187 Val = Op1.second - Op2.second;
188 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
191 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
192 "Multiply operation with an immediate and a register!");
193 Val = Op1.second * Op2.second;
194 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
197 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
198 "Divide operation with an immediate and a register!");
199 assert (Op2.second != 0 &&
"Division by zero!");
200 Val = Op1.second / Op2.second;
201 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
204 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
205 "Or operation with an immediate and a register!");
206 Val = Op1.second | Op2.second;
207 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
210 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
211 "Xor operation with an immediate and a register!");
212 Val = Op1.second ^ Op2.second;
213 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
216 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
217 "And operation with an immediate and a register!");
218 Val = Op1.second & Op2.second;
219 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
222 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
223 "Left shift operation with an immediate and a register!");
224 Val = Op1.second << Op2.second;
225 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
228 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
229 "Right shift operation with an immediate and a register!");
230 Val = Op1.second >> Op2.second;
231 OperandStack.
push_back(std::make_pair(IC_IMM, Val));
236 assert (OperandStack.
size() == 1 &&
"Expected a single result.");
241 enum IntelExprState {
262 class IntelExprStateMachine {
263 IntelExprState State, PrevState;
264 unsigned BaseReg, IndexReg, TmpReg, Scale;
268 bool StopOnLBrac, AddImmPrefix;
272 IntelExprStateMachine(int64_t imm,
bool stoponlbrac,
bool addimmprefix) :
273 State(IES_PLUS), PrevState(IES_ERROR), BaseReg(0), IndexReg(0), TmpReg(0),
274 Scale(1), Imm(imm), Sym(nullptr), StopOnLBrac(stoponlbrac),
275 AddImmPrefix(addimmprefix) { Info.clear(); }
277 unsigned getBaseReg() {
return BaseReg; }
278 unsigned getIndexReg() {
return IndexReg; }
279 unsigned getScale() {
return Scale; }
280 const MCExpr *getSym() {
return Sym; }
281 StringRef getSymName() {
return SymName; }
282 int64_t getImm() {
return Imm + IC.execute(); }
283 bool isValidEndState() {
284 return State == IES_RBRAC || State == IES_INTEGER;
286 bool getStopOnLBrac() {
return StopOnLBrac; }
287 bool getAddImmPrefix() {
return AddImmPrefix; }
288 bool hadError() {
return State == IES_ERROR; }
295 IntelExprState CurrState = State;
304 IC.pushOperator(IC_OR);
307 PrevState = CurrState;
310 IntelExprState CurrState = State;
319 IC.pushOperator(IC_XOR);
322 PrevState = CurrState;
325 IntelExprState CurrState = State;
334 IC.pushOperator(IC_AND);
337 PrevState = CurrState;
340 IntelExprState CurrState = State;
349 IC.pushOperator(IC_LSHIFT);
352 PrevState = CurrState;
355 IntelExprState CurrState = State;
364 IC.pushOperator(IC_RSHIFT);
367 PrevState = CurrState;
370 IntelExprState CurrState = State;
379 IC.pushOperator(IC_PLUS);
380 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
386 assert (!IndexReg &&
"BaseReg/IndexReg already set!");
393 PrevState = CurrState;
396 IntelExprState CurrState = State;
413 if (!(CurrState == IES_PLUS || CurrState == IES_MINUS ||
414 CurrState == IES_MULTIPLY || CurrState == IES_DIVIDE ||
415 CurrState == IES_LPAREN || CurrState == IES_LBRAC))
416 IC.pushOperator(IC_MINUS);
417 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
423 assert (!IndexReg &&
"BaseReg/IndexReg already set!");
430 PrevState = CurrState;
433 IntelExprState CurrState = State;
443 PrevState = CurrState;
445 void onRegister(
unsigned Reg) {
446 IntelExprState CurrState = State;
453 State = IES_REGISTER;
455 IC.pushOperand(IC_REGISTER);
459 if (PrevState == IES_INTEGER) {
460 assert (!IndexReg &&
"IndexReg already set!");
461 State = IES_REGISTER;
464 Scale = IC.popOperand();
465 IC.pushOperand(IC_IMM);
472 PrevState = CurrState;
485 SymName = SymRefName;
486 IC.pushOperand(IC_IMM);
490 bool onInteger(int64_t TmpInt,
StringRef &ErrMsg) {
491 IntelExprState CurrState = State;
508 if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
510 assert (!IndexReg &&
"IndexReg already set!");
513 if(Scale != 1 && Scale != 2 && Scale != 4 && Scale != 8) {
514 ErrMsg =
"scale factor in address must be 1, 2, 4 or 8";
519 }
else if ((PrevState == IES_PLUS || PrevState == IES_MINUS ||
520 PrevState == IES_OR || PrevState == IES_AND ||
521 PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||
522 PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
523 PrevState == IES_LPAREN || PrevState == IES_LBRAC ||
524 PrevState == IES_NOT || PrevState == IES_XOR) &&
525 CurrState == IES_MINUS) {
528 IC.pushOperand(IC_IMM, -TmpInt);
529 }
else if ((PrevState == IES_PLUS || PrevState == IES_MINUS ||
530 PrevState == IES_OR || PrevState == IES_AND ||
531 PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||
532 PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
533 PrevState == IES_LPAREN || PrevState == IES_LBRAC ||
534 PrevState == IES_NOT || PrevState == IES_XOR) &&
535 CurrState == IES_NOT) {
538 IC.pushOperand(IC_IMM, ~TmpInt);
540 IC.pushOperand(IC_IMM, TmpInt);
544 PrevState = CurrState;
556 State = IES_MULTIPLY;
557 IC.pushOperator(IC_MULTIPLY);
570 IC.pushOperator(IC_DIVIDE);
582 IC.pushOperator(IC_PLUS);
587 IntelExprState CurrState = State;
596 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
602 assert (!IndexReg &&
"BaseReg/IndexReg already set!");
609 PrevState = CurrState;
612 IntelExprState CurrState = State;
629 if ((PrevState == IES_PLUS || PrevState == IES_MINUS ||
630 PrevState == IES_OR || PrevState == IES_AND ||
631 PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||
632 PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
633 PrevState == IES_LPAREN || PrevState == IES_LBRAC ||
634 PrevState == IES_NOT || PrevState == IES_XOR) &&
635 (CurrState == IES_MINUS || CurrState == IES_NOT)) {
640 IC.pushOperator(IC_LPAREN);
643 PrevState = CurrState;
655 IC.pushOperator(IC_RPAREN);
663 bool MatchingInlineAsm =
false) {
665 if (MatchingInlineAsm)
return true;
669 bool ErrorAndEatStatement(
SMLoc L,
const Twine &Msg,
671 bool MatchingInlineAsm =
false) {
682 std::unique_ptr<X86Operand> DefaultMemSIOperand(
SMLoc Loc);
683 std::unique_ptr<X86Operand> DefaultMemDIOperand(
SMLoc Loc);
684 void AddDefaultSrcDestOperands(
686 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst);
687 std::unique_ptr<X86Operand> ParseOperand();
688 std::unique_ptr<X86Operand> ParseATTOperand();
689 std::unique_ptr<X86Operand> ParseIntelOperand();
690 std::unique_ptr<X86Operand> ParseIntelOffsetOfOperator();
691 bool ParseIntelDotOperator(
const MCExpr *Disp,
const MCExpr *&NewDisp);
692 std::unique_ptr<X86Operand> ParseIntelOperator(
unsigned OpKind);
693 std::unique_ptr<X86Operand>
694 ParseIntelSegmentOverride(
unsigned SegReg,
SMLoc Start,
unsigned Size);
695 std::unique_ptr<X86Operand>
696 ParseIntelMemOperand(int64_t ImmDisp,
SMLoc StartLoc,
unsigned Size);
697 std::unique_ptr<X86Operand> ParseRoundingModeOp(
SMLoc Start,
SMLoc End);
698 bool ParseIntelExpression(IntelExprStateMachine &SM,
SMLoc &End);
699 std::unique_ptr<X86Operand> ParseIntelBracExpression(
unsigned SegReg,
705 bool IsUnevaluatedOperand,
SMLoc &End);
707 std::unique_ptr<X86Operand> ParseMemOperand(
unsigned SegReg,
SMLoc StartLoc);
709 std::unique_ptr<X86Operand>
710 CreateMemForInlineAsm(
unsigned SegReg,
const MCExpr *Disp,
unsigned BaseReg,
711 unsigned IndexReg,
unsigned Scale,
SMLoc Start,
715 bool ParseDirectiveWord(
unsigned Size,
SMLoc L);
725 bool MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
728 bool MatchingInlineAsm)
override;
733 bool ErrorMissingFeature(
SMLoc IDLoc, uint64_t ErrorInfo,
734 bool MatchingInlineAsm);
736 bool MatchAndEmitATTInstruction(
SMLoc IDLoc,
unsigned &Opcode,
739 bool MatchingInlineAsm);
741 bool MatchAndEmitIntelInstruction(
SMLoc IDLoc,
unsigned &Opcode,
744 bool MatchingInlineAsm);
746 bool OmitRegisterFromClobberLists(
unsigned RegNo)
override;
759 bool is64BitMode()
const {
761 return STI.getFeatureBits()[X86::Mode64Bit];
763 bool is32BitMode()
const {
765 return STI.getFeatureBits()[X86::Mode32Bit];
767 bool is16BitMode()
const {
769 return STI.getFeatureBits()[X86::Mode16Bit];
771 void SwitchMode(
unsigned mode) {
772 FeatureBitset AllModes({X86::Mode64Bit, X86::Mode32Bit, X86::Mode16Bit});
774 unsigned FB = ComputeAvailableFeatures(
775 STI.ToggleFeature(OldMode.flip(mode)));
776 setAvailableFeatures(FB);
778 assert(
FeatureBitset({mode}) == (STI.getFeatureBits() & AllModes));
781 unsigned getPointerWidth() {
782 if (is16BitMode())
return 16;
783 if (is32BitMode())
return 32;
784 if (is64BitMode())
return 64;
788 bool isParsingIntelSyntax() {
789 return getParser().getAssemblerDialect();
795 #define GET_ASSEMBLER_HEADER
796 #include "X86GenAsmMatcher.inc"
806 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
807 Instrumentation.reset(
811 bool ParseRegister(
unsigned &RegNo,
SMLoc &StartLoc,
SMLoc &EndLoc)
override;
813 void SetFrameRegister(
unsigned RegNo)
override;
818 bool ParseDirective(
AsmToken DirectiveID)
override;
834 if (BaseReg != 0 && IndexReg != 0) {
835 if (X86MCRegisterClasses[X86::GR64RegClassID].
contains(BaseReg) &&
836 (X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg) ||
837 X86MCRegisterClasses[X86::GR32RegClassID].
contains(IndexReg)) &&
838 IndexReg != X86::RIZ) {
839 ErrMsg =
"base register is 64-bit, but index register is not";
842 if (X86MCRegisterClasses[X86::GR32RegClassID].
contains(BaseReg) &&
843 (X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg) ||
844 X86MCRegisterClasses[X86::GR64RegClassID].
contains(IndexReg)) &&
845 IndexReg != X86::EIZ){
846 ErrMsg =
"base register is 32-bit, but index register is not";
849 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg)) {
850 if (X86MCRegisterClasses[X86::GR32RegClassID].
contains(IndexReg) ||
851 X86MCRegisterClasses[X86::GR64RegClassID].
contains(IndexReg)) {
852 ErrMsg =
"base register is 16-bit, but index register is not";
855 if (((BaseReg == X86::BX || BaseReg == X86::BP) &&
856 IndexReg != X86::SI && IndexReg != X86::DI) ||
857 ((BaseReg == X86::SI || BaseReg == X86::DI) &&
858 IndexReg != X86::BX && IndexReg != X86::BP)) {
859 ErrMsg =
"invalid 16-bit base/index register combination";
878 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(siReg))
879 return X86MCRegisterClasses[X86::GR16RegClassID].
contains(diReg);
880 if (X86MCRegisterClasses[X86::GR32RegClassID].
contains(siReg))
881 return X86MCRegisterClasses[X86::GR32RegClassID].
contains(diReg);
882 if (X86MCRegisterClasses[X86::GR64RegClassID].
contains(siReg))
883 return X86MCRegisterClasses[X86::GR64RegClassID].
contains(diReg);
888 bool X86AsmParser::ParseRegister(
unsigned &RegNo,
893 StartLoc = PercentTok.
getLoc();
904 if (isParsingIntelSyntax())
return true;
905 return Error(StartLoc,
"invalid register name",
915 if (!is64BitMode()) {
921 if (RegNo == X86::RIZ ||
922 X86MCRegisterClasses[X86::GR64RegClassID].
contains(RegNo) ||
925 return Error(StartLoc,
"register %"
926 + Tok.
getString() +
" is only available in 64-bit mode",
943 return Error(IntTok.
getLoc(),
"expected stack index");
945 case 0: RegNo = X86::ST0;
break;
946 case 1: RegNo = X86::ST1;
break;
947 case 2: RegNo = X86::ST2;
break;
948 case 3: RegNo = X86::ST3;
break;
949 case 4: RegNo = X86::ST4;
break;
950 case 5: RegNo = X86::ST5;
break;
951 case 6: RegNo = X86::ST6;
break;
952 case 7: RegNo = X86::ST7;
break;
953 default:
return Error(IntTok.
getLoc(),
"invalid stack index");
971 case '0': RegNo = X86::DR0;
break;
972 case '1': RegNo = X86::DR1;
break;
973 case '2': RegNo = X86::DR2;
break;
974 case '3': RegNo = X86::DR3;
break;
975 case '4': RegNo = X86::DR4;
break;
976 case '5': RegNo = X86::DR5;
break;
977 case '6': RegNo = X86::DR6;
break;
978 case '7': RegNo = X86::DR7;
break;
989 if (isParsingIntelSyntax())
return true;
990 return Error(StartLoc,
"invalid register name",
998 void X86AsmParser::SetFrameRegister(
unsigned RegNo) {
999 Instrumentation->SetInitialFrameRegister(RegNo);
1002 std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(
SMLoc Loc) {
1004 is64BitMode() ? X86::RSI : (is32BitMode() ? X86::ESI : X86::SI);
1011 std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand(
SMLoc Loc) {
1013 is64BitMode() ? X86::RDI : (is32BitMode() ? X86::EDI : X86::DI);
1020 void X86AsmParser::AddDefaultSrcDestOperands(
1022 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst) {
1023 if (isParsingIntelSyntax()) {
1033 std::unique_ptr<X86Operand> X86AsmParser::ParseOperand() {
1034 if (isParsingIntelSyntax())
1035 return ParseIntelOperand();
1036 return ParseATTOperand();
1042 .Cases(
"BYTE",
"byte", 8)
1043 .
Cases(
"WORD",
"word", 16)
1044 .
Cases(
"DWORD",
"dword", 32)
1045 .
Cases(
"QWORD",
"qword", 64)
1046 .
Cases(
"XWORD",
"xword", 80)
1047 .
Cases(
"XMMWORD",
"xmmword", 128)
1048 .
Cases(
"YMMWORD",
"ymmword", 256)
1049 .
Cases(
"ZMMWORD",
"zmmword", 512)
1050 .
Cases(
"OPAQUE",
"opaque", -1U)
1055 std::unique_ptr<X86Operand> X86AsmParser::CreateMemForInlineAsm(
1056 unsigned SegReg,
const MCExpr *Disp,
unsigned BaseReg,
unsigned IndexReg,
1064 Size = getPointerWidth();
1072 Identifier, Info.
OpDecl);
1080 isa<MCSymbolRefExpr>(BinOp ? BinOp->
getLHS() : Disp);
1083 Size = Info.
Type * 8;
1093 BaseReg = BaseReg ? BaseReg : 1;
1095 IndexReg, Scale, Start, End, Size, Identifier,
1102 int64_t FinalImmDisp,
SMLoc &BracLoc,
1112 if (ImmDisp != FinalImmDisp) {
1118 E = AsmRewrites->
end();
I != E; ++
I) {
1119 if ((*I).Loc.getPointer() > BracLoc.
getPointer())
1122 assert (!Found &&
"ImmDisp already rewritten.");
1124 (*I).Len = BracLoc.
getPointer() - (*I).Loc.getPointer();
1125 (*I).Val = FinalImmDisp;
1130 assert (Found &&
"Unable to rewrite ImmDisp.");
1141 E = AsmRewrites->
end();
I != E; ++
I) {
1142 if ((*I).Loc.getPointer() < StartInBrac.
getPointer())
1147 const char *SymLocPtr = SymName.
data();
1149 if (
unsigned Len = SymLocPtr - StartInBrac.
getPointer()) {
1150 assert(Len > 0 &&
"Expected a non-negative length.");
1154 if (
unsigned Len = End.
getPointer() - (SymLocPtr + SymName.
size())) {
1156 assert(Len > 0 &&
"Expected a non-negative length.");
1161 bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM,
SMLoc &End) {
1167 bool UpdateLocLex =
true;
1181 if (SM.isValidEndState()) {
1185 return Error(Tok.
getLoc(),
"unknown token in expression");
1199 SM.onRegister(TmpReg);
1200 UpdateLocLex =
false;
1203 if (!isParsingInlineAsm()) {
1204 if (getParser().parsePrimaryExpr(Val, End))
1205 return Error(Tok.
getLoc(),
"Unexpected identifier!");
1212 if (ParseIntelIdentifier(Val, Identifier, Info,
1217 SM.onIdentifierExpr(Val, Identifier);
1218 UpdateLocLex =
false;
1221 return Error(Tok.
getLoc(),
"Unexpected identifier!");
1225 if (isParsingInlineAsm() && SM.getAddImmPrefix())
1229 SMLoc Loc = getTok().getLoc();
1230 int64_t
IntVal = getTok().getIntVal();
1231 End = consumeToken();
1232 UpdateLocLex =
false;
1235 if (IDVal ==
"f" || IDVal ==
"b") {
1237 getContext().getDirectionalLocalSymbol(IntVal, IDVal ==
"b");
1242 return Error(Loc,
"invalid reference to undefined symbol");
1244 SM.onIdentifierExpr(Val, Identifier);
1245 End = consumeToken();
1247 if (SM.onInteger(IntVal, ErrMsg))
1248 return Error(Loc, ErrMsg);
1251 if (SM.onInteger(IntVal, ErrMsg))
1252 return Error(Loc, ErrMsg);
1265 SM.onLShift();
break;
1267 SM.onRShift();
break;
1274 return Error(Tok.
getLoc(),
"unknown token in expression");
1276 if (!Done && UpdateLocLex)
1277 End = consumeToken();
1282 std::unique_ptr<X86Operand>
1283 X86AsmParser::ParseIntelBracExpression(
unsigned SegReg,
SMLoc Start,
1284 int64_t ImmDisp,
unsigned Size) {
1289 return ErrorOperand(BracLoc,
"Expected '[' token!");
1296 IntelExprStateMachine SM(ImmDisp,
false,
true);
1297 if (ParseIntelExpression(SM, End))
1300 const MCExpr *Disp =
nullptr;
1301 if (
const MCExpr *Sym = SM.getSym()) {
1304 if (isParsingInlineAsm())
1306 ImmDisp, SM.getImm(), BracLoc, StartInBrac,
1310 if (SM.getImm() || !Disp) {
1323 if (ParseIntelDotOperator(Disp, NewDisp))
1331 int BaseReg = SM.getBaseReg();
1332 int IndexReg = SM.getIndexReg();
1333 int Scale = SM.getScale();
1334 if (!isParsingInlineAsm()) {
1336 if (!BaseReg && !IndexReg) {
1344 Error(StartInBrac, ErrMsg);
1348 IndexReg, Scale, Start, End, Size);
1352 return CreateMemForInlineAsm(SegReg, Disp, BaseReg, IndexReg, Scale, Start,
1353 End, Size, SM.getSymName(), Info);
1357 bool X86AsmParser::ParseIntelIdentifier(
const MCExpr *&Val,
1360 bool IsUnevaluatedOperand,
SMLoc &End) {
1362 assert (isParsingInlineAsm() &&
"Expected to be parsing inline assembly.");
1367 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);
1379 assert(End.
getPointer() <= EndPtr &&
"frontend claimed part of a token?");
1382 Identifier = LineBuf;
1388 SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(),
1390 assert(InternalName.
size() &&
"We should have an internal name here.");
1398 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
1405 std::unique_ptr<X86Operand>
1406 X86AsmParser::ParseIntelSegmentOverride(
unsigned SegReg,
SMLoc Start,
1409 assert(SegReg != 0 &&
"Tried to parse a segment override without a segment!");
1412 return ErrorOperand(Tok.
getLoc(),
"Expected ':' token!");
1415 int64_t ImmDisp = 0;
1420 if (isParsingInlineAsm())
1421 InstInfo->AsmRewrites->push_back(
1436 return ParseIntelBracExpression(SegReg, Start, ImmDisp, Size);
1440 if (!isParsingInlineAsm()) {
1441 if (getParser().parsePrimaryExpr(Val, End))
1442 return ErrorOperand(Tok.
getLoc(),
"unknown token in expression");
1449 if (ParseIntelIdentifier(Val, Identifier, Info,
1452 return CreateMemForInlineAsm(0, Val, 0,0,
1453 1, Start, End, Size, Identifier, Info);
1457 std::unique_ptr<X86Operand>
1458 X86AsmParser::ParseRoundingModeOp(
SMLoc Start,
SMLoc End) {
1462 const SMLoc consumedToken = consumeToken();
1471 return ErrorOperand(Tok.
getLoc(),
"Invalid rounding mode.");
1474 return ErrorOperand(Tok.
getLoc(),
"Expected - at this point");
1478 return ErrorOperand(Tok.
getLoc(),
"Expected } at this point");
1480 const MCExpr *RndModeOp =
1487 return ErrorOperand(Tok.
getLoc(),
"Expected } at this point");
1491 return ErrorOperand(Tok.
getLoc(),
"unknown token in expression");
1494 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelMemOperand(int64_t ImmDisp,
1503 return ParseIntelBracExpression(0, Start, ImmDisp, Size);
1504 assert(ImmDisp == 0);
1507 if (!isParsingInlineAsm()) {
1508 if (getParser().parsePrimaryExpr(Val, End))
1509 return ErrorOperand(Tok.
getLoc(),
"unknown token in expression");
1516 if (ParseIntelIdentifier(Val, Identifier, Info,
1521 return CreateMemForInlineAsm(0, Val, 0, 0,
1522 1, Start, End, Size, Identifier, Info);
1527 IntelExprStateMachine SM(0,
true,
1529 if (ParseIntelExpression(SM, End))
1533 Error(Start,
"cannot use more than one symbol in memory operand");
1536 if (SM.getBaseReg()) {
1537 Error(Start,
"cannot use base register with variable reference");
1540 if (SM.getIndexReg()) {
1541 Error(Start,
"cannot use index register with variable reference");
1551 Start, End, Size, Identifier, Info.
OpDecl);
1555 bool X86AsmParser::ParseIntelDotOperator(
const MCExpr *Disp,
1556 const MCExpr *&NewDisp) {
1559 int64_t OrigDispVal, DotDispVal;
1562 if (
const MCConstantExpr *OrigDisp = dyn_cast<MCConstantExpr>(Disp))
1563 OrigDispVal = OrigDisp->getValue();
1565 return Error(Tok.
getLoc(),
"Non-constant offsets are not supported!");
1569 if (DotDispStr.startswith(
"."))
1575 DotDispStr.getAsInteger(10, DotDisp);
1579 std::pair<StringRef, StringRef> BaseMember = DotDispStr.split(
'.');
1580 if (SemaCallback->LookupInlineAsmField(BaseMember.first, BaseMember.second,
1582 return Error(Tok.
getLoc(),
"Unable to lookup field reference!");
1583 DotDispVal = DotDisp;
1585 return Error(Tok.
getLoc(),
"Unexpected token type!");
1589 unsigned Len = DotDispStr.size();
1590 unsigned Val = OrigDispVal + DotDispVal;
1601 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOffsetOfOperator() {
1611 if (ParseIntelIdentifier(Val, Identifier, Info,
1622 is64BitMode() ? X86::RBX : (is32BitMode() ? X86::EBX : X86::BX);
1624 OffsetOfLoc, Identifier, Info.
OpDecl);
1639 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperator(
unsigned OpKind) {
1645 const MCExpr *Val =
nullptr;
1649 if (ParseIntelIdentifier(Val, Identifier, Info,
1654 return ErrorOperand(Start,
"unable to lookup expression");
1673 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand() {
1679 if (isParsingInlineAsm()) {
1681 if (AsmTokStr ==
"offset" || AsmTokStr ==
"OFFSET")
1682 return ParseIntelOffsetOfOperator();
1683 if (AsmTokStr ==
"length" || AsmTokStr ==
"LENGTH")
1685 if (AsmTokStr ==
"size" || AsmTokStr ==
"SIZE")
1686 return ParseIntelOperator(
IOK_SIZE);
1687 if (AsmTokStr ==
"type" || AsmTokStr ==
"TYPE")
1688 return ParseIntelOperator(
IOK_TYPE);
1695 return ErrorOperand(Tok.
getLoc(),
"Expected 'PTR' or 'ptr' token!");
1704 IntelExprStateMachine SM(0,
true,
1706 if (ParseIntelExpression(SM, End))
1709 int64_t Imm = SM.getImm();
1710 if (isParsingInlineAsm()) {
1735 return ErrorOperand(Start,
"expected a positive immediate displacement "
1736 "before bracketed expr.");
1739 return ParseIntelMemOperand(Imm, Start, Size);
1743 if (STI.getFeatureBits()[X86::FeatureAVX512] &&
1745 return ParseRoundingModeOp(Start, End);
1749 if (!ParseRegister(RegNo, Start, End)) {
1755 return ParseIntelSegmentOverride(RegNo, Start, Size);
1759 return ParseIntelMemOperand(0, Start, Size);
1762 std::unique_ptr<X86Operand> X86AsmParser::ParseATTOperand() {
1764 switch (getLexer().getKind()) {
1772 if (ParseRegister(RegNo, Start, End))
return nullptr;
1773 if (RegNo == X86::EIZ || RegNo == X86::RIZ) {
1774 Error(Start,
"%eiz and %riz can only be used as index registers",
1784 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].
contains(RegNo))
1785 return ErrorOperand(Start,
"invalid segment register");
1788 return ParseMemOperand(RegNo, Start);
1795 if (getParser().parseExpression(Val, End))
1801 if (STI.getFeatureBits()[X86::FeatureAVX512])
1802 return ParseRoundingModeOp(Start, End);
1803 return ErrorOperand(Start,
"unknown token in expression");
1808 bool X86AsmParser::HandleAVX512Operand(
OperandVector &Operands,
1811 if(STI.getFeatureBits()[X86::FeatureAVX512]) {
1814 const SMLoc consumedToken = consumeToken();
1818 if (getLexer().getTok().getIntVal() != 1)
1819 return !ErrorAndEatStatement(getLexer().getLoc(),
1820 "Expected 1to<NUM> at this point");
1823 !getLexer().getTok().getIdentifier().startswith(
"to"))
1824 return !ErrorAndEatStatement(getLexer().getLoc(),
1825 "Expected 1to<NUM> at this point");
1827 const char *BroadcastPrimitive =
1829 .Case(
"to2",
"{1to2}")
1830 .
Case(
"to4",
"{1to4}")
1831 .
Case(
"to8",
"{1to8}")
1832 .
Case(
"to16",
"{1to16}")
1834 if (!BroadcastPrimitive)
1835 return !ErrorAndEatStatement(getLexer().getLoc(),
1836 "Invalid memory broadcast primitive.");
1839 return !ErrorAndEatStatement(getLexer().getLoc(),
1840 "Expected } at this point");
1850 if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
1853 return !ErrorAndEatStatement(getLexer().getLoc(),
1854 "Expected } at this point");
1861 getLexer().getTok().getIdentifier() !=
"z")
1862 return !ErrorAndEatStatement(getLexer().getLoc(),
1863 "Expected z at this point");
1866 return !ErrorAndEatStatement(getLexer().getLoc(),
1867 "Expected } at this point");
1879 std::unique_ptr<X86Operand> X86AsmParser::ParseMemOperand(
unsigned SegReg,
1890 if (getParser().parseExpression(Disp, ExprEnd))
return nullptr;
1917 if (getParser().parseParenExpression(Disp, ExprEnd))
1938 unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
1939 SMLoc IndexLoc, BaseLoc;
1942 SMLoc StartLoc, EndLoc;
1944 if (ParseRegister(BaseReg, StartLoc, EndLoc))
return nullptr;
1945 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) {
1946 Error(StartLoc,
"eiz and riz can only be used as index registers",
1964 if (ParseRegister(IndexReg, L, L))
return nullptr;
1971 "expected comma in scale expression");
1980 if (getParser().parseAbsoluteExpression(ScaleVal)){
1981 Error(Loc,
"expected scale expression");
1986 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg) &&
1988 Error(Loc,
"scale factor in 16-bit address must be 1");
1991 if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8){
1992 Error(Loc,
"scale factor in address must be 1, 2, 4 or 8");
2004 if (getParser().parseAbsoluteExpression(Value))
2008 Warning(Loc,
"scale factor without index register is ignored");
2024 if (X86MCRegisterClasses[X86::GR16RegClassID].
contains(BaseReg) &&
2025 (is64BitMode() || (BaseReg != X86::BX && BaseReg != X86::BP &&
2026 BaseReg != X86::SI && BaseReg != X86::DI)) &&
2027 BaseReg != X86::DX) {
2028 Error(BaseLoc,
"invalid 16-bit base register");
2032 X86MCRegisterClasses[X86::GR16RegClassID].
contains(IndexReg)) {
2033 Error(IndexLoc,
"16-bit memory operand may not include only index register");
2039 Error(BaseLoc, ErrMsg);
2043 if (SegReg || BaseReg || IndexReg)
2045 IndexReg, Scale, MemStart, MemEnd);
2057 PatchedName !=
"setb" && PatchedName !=
"setnb")
2058 PatchedName = PatchedName.
substr(0, Name.
size()-1);
2064 bool IsVCMP = PatchedName[0] ==
'v';
2065 unsigned CCIdx = IsVCMP ? 4 : 3;
2067 PatchedName.
slice(CCIdx, PatchedName.
size() - 2))
2071 .
Case(
"unord", 0x03)
2077 .
Case(
"eq_uq", 0x08)
2080 .
Case(
"false", 0x0B)
2081 .
Case(
"neq_oq", 0x0C)
2085 .
Case(
"eq_os", 0x10)
2086 .
Case(
"lt_oq", 0x11)
2087 .
Case(
"le_oq", 0x12)
2088 .
Case(
"unord_s", 0x13)
2089 .
Case(
"neq_us", 0x14)
2090 .
Case(
"nlt_uq", 0x15)
2091 .
Case(
"nle_uq", 0x16)
2092 .
Case(
"ord_s", 0x17)
2093 .
Case(
"eq_us", 0x18)
2094 .
Case(
"nge_uq", 0x19)
2095 .
Case(
"ngt_uq", 0x1A)
2096 .
Case(
"false_os", 0x1B)
2097 .
Case(
"neq_os", 0x1C)
2098 .
Case(
"ge_oq", 0x1D)
2099 .
Case(
"gt_oq", 0x1E)
2100 .
Case(
"true_us", 0x1F)
2102 if (ComparisonCode != ~0U && (IsVCMP || ComparisonCode < 8)) {
2108 getParser().getContext());
2111 PatchedName = PatchedName.
substr(PatchedName.
size() - 2);
2119 unsigned CCIdx = PatchedName.
drop_back().
back() ==
'u' ? 2 : 1;
2121 PatchedName.
slice(5, PatchedName.
size() - CCIdx))
2131 if (ComparisonCode != ~0U && (ComparisonCode != 0 || CCIdx == 2)) {
2135 getParser().getContext());
2138 PatchedName = PatchedName.
substr(PatchedName.
size() - CCIdx);
2146 unsigned CCIdx = PatchedName.
drop_back().
back() ==
'u' ? 2 : 1;
2148 PatchedName.
slice(5, PatchedName.
size() - CCIdx))
2158 if (ComparisonCode != ~0U) {
2162 getParser().getContext());
2165 PatchedName = PatchedName.
substr(PatchedName.
size() - CCIdx);
2173 Name ==
"lock" || Name ==
"rep" ||
2174 Name ==
"repe" || Name ==
"repz" ||
2175 Name ==
"repne" || Name ==
"repnz" ||
2176 Name ==
"rex64" || Name ==
"data16";
2191 if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
2193 if (!HandleAVX512Operand(Operands, *Operands.
back()))
2207 return ErrorAndEatStatement(getLexer().getLoc(),
2208 "unexpected token in argument list");
2219 if ((Name ==
"outb" || Name ==
"outw" || Name ==
"outl" || Name ==
"out") &&
2220 Operands.
size() == 3) {
2223 isa<MCConstantExpr>(Op.
Mem.
Disp) &&
2224 cast<MCConstantExpr>(Op.
Mem.
Disp)->getValue() == 0 &&
2231 if ((Name ==
"inb" || Name ==
"inw" || Name ==
"inl" || Name ==
"in") &&
2232 Operands.
size() == 3) {
2235 isa<MCConstantExpr>(Op.
Mem.
Disp) &&
2236 cast<MCConstantExpr>(Op.
Mem.
Disp)->getValue() == 0 &&
2245 (Name ==
"insb" || Name ==
"insw" || Name ==
"insl" ||
2247 AddDefaultSrcDestOperands(Operands,
2249 DefaultMemDIOperand(NameLoc));
2254 (Name ==
"outsb" || Name ==
"outsw" || Name ==
"outsl" ||
2255 Name ==
"outsd" )) {
2256 AddDefaultSrcDestOperands(Operands,
2257 DefaultMemSIOperand(NameLoc),
2265 (Name ==
"lods" || Name ==
"lodsb" || Name ==
"lodsw" ||
2266 Name ==
"lodsl" || Name ==
"lodsd" || Name ==
"lodsq"))
2267 Operands.
push_back(DefaultMemSIOperand(NameLoc));
2273 (Name ==
"stos" || Name ==
"stosb" || Name ==
"stosw" ||
2274 Name ==
"stosl" || Name ==
"stosd" || Name ==
"stosq"))
2275 Operands.
push_back(DefaultMemDIOperand(NameLoc));
2281 (Name ==
"scas" || Name ==
"scasb" || Name ==
"scasw" ||
2282 Name ==
"scasl" || Name ==
"scasd" || Name ==
"scasq"))
2283 Operands.
push_back(DefaultMemDIOperand(NameLoc));
2287 (Name ==
"cmps" || Name ==
"cmpsb" || Name ==
"cmpsw" ||
2288 Name ==
"cmpsl" || Name ==
"cmpsd" || Name ==
"cmpsq")) {
2289 if (Operands.
size() == 1) {
2290 AddDefaultSrcDestOperands(Operands,
2291 DefaultMemDIOperand(NameLoc),
2292 DefaultMemSIOperand(NameLoc));
2293 }
else if (Operands.
size() == 3) {
2296 if (!doSrcDstMatch(Op, Op2))
2298 "mismatching source and destination index registers");
2304 (Name ==
"movs" || Name ==
"movsb" || Name ==
"movsw" ||
2305 Name ==
"movsl" || Name ==
"movsd" || Name ==
"movsq")) ||
2307 (Name ==
"smov" || Name ==
"smovb" || Name ==
"smovw" ||
2308 Name ==
"smovl" || Name ==
"smovd" || Name ==
"smovq"))) {
2309 if (Operands.
size() == 1) {
2310 if (Name ==
"movsd")
2312 AddDefaultSrcDestOperands(Operands,
2313 DefaultMemSIOperand(NameLoc),
2314 DefaultMemDIOperand(NameLoc));
2315 }
else if (Operands.
size() == 3) {
2318 if (!doSrcDstMatch(Op, Op2))
2320 "mismatching source and destination index registers");
2330 Operands.
size() == 3) {
2331 if (isParsingIntelSyntax()) {
2334 if (Op1.
isImm() && isa<MCConstantExpr>(Op1.
getImm()) &&
2335 cast<MCConstantExpr>(Op1.
getImm())->getValue() == 1)
2339 if (Op1.
isImm() && isa<MCConstantExpr>(Op1.
getImm()) &&
2340 cast<MCConstantExpr>(Op1.
getImm())->getValue() == 1)
2347 if (Name ==
"int" && Operands.
size() == 2) {
2349 if (Op1.
isImm() && isa<MCConstantExpr>(Op1.
getImm()) &&
2350 cast<MCConstantExpr>(Op1.
getImm())->getValue() == 3) {
2352 static_cast<X86Operand &
>(*Operands[0]).setTokenValue(
"int3");
2372 bool isCmp =
false) {
2381 bool isCmp =
false) {
2390 bool isCmp =
false) {
2400 default:
return true;
2403 assert(Op.
isImm() &&
"expected immediate");
2405 if (!Op.
getImm()->evaluateAsAbsolute(Res) || Res > 255) {
2416 default:
return false;
2441 case X86::VMOVAPDrr:
2442 case X86::VMOVAPDYrr:
2443 case X86::VMOVAPSrr:
2444 case X86::VMOVAPSYrr:
2445 case X86::VMOVDQArr:
2446 case X86::VMOVDQAYrr:
2447 case X86::VMOVDQUrr:
2448 case X86::VMOVDQUYrr:
2449 case X86::VMOVUPDrr:
2450 case X86::VMOVUPDYrr:
2451 case X86::VMOVUPSrr:
2452 case X86::VMOVUPSYrr: {
2460 case X86::VMOVAPDrr: NewOpc = X86::VMOVAPDrr_REV;
break;
2461 case X86::VMOVAPDYrr: NewOpc = X86::VMOVAPDYrr_REV;
break;
2462 case X86::VMOVAPSrr: NewOpc = X86::VMOVAPSrr_REV;
break;
2463 case X86::VMOVAPSYrr: NewOpc = X86::VMOVAPSYrr_REV;
break;
2464 case X86::VMOVDQArr: NewOpc = X86::VMOVDQArr_REV;
break;
2465 case X86::VMOVDQAYrr: NewOpc = X86::VMOVDQAYrr_REV;
break;
2466 case X86::VMOVDQUrr: NewOpc = X86::VMOVDQUrr_REV;
break;
2467 case X86::VMOVDQUYrr: NewOpc = X86::VMOVDQUYrr_REV;
break;
2468 case X86::VMOVUPDrr: NewOpc = X86::VMOVUPDrr_REV;
break;
2469 case X86::VMOVUPDYrr: NewOpc = X86::VMOVUPDYrr_REV;
break;
2470 case X86::VMOVUPSrr: NewOpc = X86::VMOVUPSrr_REV;
break;
2471 case X86::VMOVUPSYrr: NewOpc = X86::VMOVUPSYrr_REV;
break;
2477 case X86::VMOVSSrr: {
2484 case X86::VMOVSDrr: NewOpc = X86::VMOVSDrr_REV;
break;
2485 case X86::VMOVSSrr: NewOpc = X86::VMOVSSrr_REV;
break;
2497 Instrumentation->InstrumentAndEmitInstruction(Inst, Operands, getContext(),
2501 bool X86AsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
2504 bool MatchingInlineAsm) {
2505 if (isParsingIntelSyntax())
2506 return MatchAndEmitIntelInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2508 return MatchAndEmitATTInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2514 bool MatchingInlineAsm) {
2519 .Case(
"finit",
"fninit")
2520 .
Case(
"fsave",
"fnsave")
2521 .
Case(
"fstcw",
"fnstcw")
2522 .
Case(
"fstcww",
"fnstcw")
2523 .
Case(
"fstenv",
"fnstenv")
2524 .
Case(
"fstsw",
"fnstsw")
2525 .
Case(
"fstsww",
"fnstsw")
2526 .
Case(
"fclex",
"fnclex")
2532 if (!MatchingInlineAsm)
2533 EmitInstruction(Inst, Operands, Out);
2538 bool X86AsmParser::ErrorMissingFeature(
SMLoc IDLoc, uint64_t ErrorInfo,
2539 bool MatchingInlineAsm) {
2540 assert(ErrorInfo &&
"Unknown missing feature!");
2544 OS <<
"instruction requires:";
2546 for (
unsigned i = 0; i < (
sizeof(ErrorInfo)*8-1); ++i) {
2547 if (ErrorInfo & Mask)
2551 return Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
2554 bool X86AsmParser::MatchAndEmitATTInstruction(
SMLoc IDLoc,
unsigned &Opcode,
2557 uint64_t &ErrorInfo,
2558 bool MatchingInlineAsm) {
2559 assert(!Operands.
empty() &&
"Unexpect empty operand list!");
2561 assert(Op.isToken() &&
"Leading operand should always be a mnemonic!");
2565 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2567 bool WasOriginallyInvalidOperand =
false;
2571 switch (MatchInstructionImpl(Operands, Inst,
2572 ErrorInfo, MatchingInlineAsm,
2573 isParsingIntelSyntax())) {
2576 if (!validateInstruction(Inst, Operands))
2582 if (!MatchingInlineAsm)
2587 if (!MatchingInlineAsm)
2588 EmitInstruction(Inst, Operands, Out);
2591 case Match_MissingFeature:
2592 return ErrorMissingFeature(IDLoc, ErrorInfo, MatchingInlineAsm);
2593 case Match_InvalidOperand:
2594 WasOriginallyInvalidOperand =
true;
2596 case Match_MnemonicFail:
2610 Op.setTokenValue(Tmp);
2618 const char *Suffixes = Base[0] !=
'f' ?
"bwlq" :
"slt\0";
2621 uint64_t ErrorInfoIgnore;
2622 uint64_t ErrorInfoMissingFeature = 0;
2626 Tmp.
back() = Suffixes[
I];
2627 Match[
I] = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
2628 MatchingInlineAsm, isParsingIntelSyntax());
2630 if (Match[
I] == Match_MissingFeature)
2631 ErrorInfoMissingFeature = ErrorInfoIgnore;
2635 Op.setTokenValue(Base);
2640 unsigned NumSuccessfulMatches =
2642 if (NumSuccessfulMatches == 1) {
2644 if (!MatchingInlineAsm)
2645 EmitInstruction(Inst, Operands, Out);
2654 if (NumSuccessfulMatches > 1) {
2656 unsigned NumMatches = 0;
2658 if (Match[
I] == Match_Success)
2659 MatchChars[NumMatches++] = Suffixes[
I];
2663 OS <<
"ambiguous instructions require an explicit suffix (could be ";
2664 for (
unsigned i = 0; i != NumMatches; ++i) {
2667 if (i + 1 == NumMatches)
2669 OS <<
"'" << Base << MatchChars[i] <<
"'";
2672 Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
2681 if (!WasOriginallyInvalidOperand) {
2683 MatchingInlineAsm ? EmptyRanges : Op.getLocRange();
2684 return Error(IDLoc,
"invalid instruction mnemonic '" + Base +
"'",
2685 Ranges, MatchingInlineAsm);
2689 if (ErrorInfo != ~0ULL) {
2690 if (ErrorInfo >= Operands.
size())
2691 return Error(IDLoc,
"too few operands for instruction",
2692 EmptyRanges, MatchingInlineAsm);
2698 OperandRange, MatchingInlineAsm);
2702 return Error(IDLoc,
"invalid operand for instruction", EmptyRanges,
2709 Match_MissingFeature) == 1) {
2710 ErrorInfo = ErrorInfoMissingFeature;
2711 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
2718 Match_InvalidOperand) == 1) {
2719 return Error(IDLoc,
"invalid operand for instruction", EmptyRanges,
2724 Error(IDLoc,
"unknown use of instruction mnemonic without a size suffix",
2725 EmptyRanges, MatchingInlineAsm);
2729 bool X86AsmParser::MatchAndEmitIntelInstruction(
SMLoc IDLoc,
unsigned &Opcode,
2732 uint64_t &ErrorInfo,
2733 bool MatchingInlineAsm) {
2734 assert(!Operands.
empty() &&
"Unexpect empty operand list!");
2736 assert(Op.isToken() &&
"Leading operand should always be a mnemonic!");
2741 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2747 for (
const auto &Op : Operands) {
2750 UnsizedMemOp = X86Op;
2756 static const char *
const PtrSizedInstrs[] = {
"call",
"jmp",
"push"};
2757 for (
const char *Instr : PtrSizedInstrs) {
2758 if (Mnemonic == Instr) {
2759 UnsizedMemOp->
Mem.
Size = getPointerWidth();
2769 uint64_t ErrorInfoMissingFeature = 0;
2771 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
2772 for (
unsigned Size : MopSizes) {
2773 UnsizedMemOp->
Mem.
Size = Size;
2774 uint64_t ErrorInfoIgnore;
2777 MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
2778 MatchingInlineAsm, isParsingIntelSyntax());
2783 if (Match.
back() == Match_MissingFeature)
2784 ErrorInfoMissingFeature = ErrorInfoIgnore;
2795 if (Match.
empty()) {
2796 Match.
push_back(MatchInstructionImpl(Operands, Inst, ErrorInfo,
2798 isParsingIntelSyntax()));
2800 if (Match.
back() == Match_MissingFeature)
2801 ErrorInfoMissingFeature = ErrorInfo;
2809 if (Match.
back() == Match_MnemonicFail) {
2811 MatchingInlineAsm ? EmptyRanges : Op.getLocRange();
2812 return Error(IDLoc,
"invalid instruction mnemonic '" + Mnemonic +
"'",
2813 Ranges, MatchingInlineAsm);
2819 unsigned NumSuccessfulMatches =
2821 if (NumSuccessfulMatches == 1) {
2822 if (!validateInstruction(Inst, Operands))
2828 if (!MatchingInlineAsm)
2832 if (!MatchingInlineAsm)
2833 EmitInstruction(Inst, Operands, Out);
2836 }
else if (NumSuccessfulMatches > 1) {
2837 assert(UnsizedMemOp &&
2838 "multiple matches only possible with unsized memory operands");
2840 MatchingInlineAsm ? EmptyRanges : UnsizedMemOp->
getLocRange();
2842 "ambiguous operand size for instruction '" + Mnemonic +
"\'",
2843 Ranges, MatchingInlineAsm);
2849 Match_MissingFeature) == 1) {
2850 ErrorInfo = ErrorInfoMissingFeature;
2851 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
2858 Match_InvalidOperand) == 1) {
2859 return Error(IDLoc,
"invalid operand for instruction", EmptyRanges,
2864 return Error(IDLoc,
"unknown instruction mnemonic", EmptyRanges,
2868 bool X86AsmParser::OmitRegisterFromClobberLists(
unsigned RegNo) {
2869 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo);
2872 bool X86AsmParser::ParseDirective(
AsmToken DirectiveID) {
2875 if (IDVal ==
".word")
2876 return ParseDirectiveWord(2, DirectiveID.
getLoc());
2878 return ParseDirectiveCode(IDVal, DirectiveID.
getLoc());
2884 return Error(DirectiveID.
getLoc(),
"'.att_syntax noprefix' is not "
2885 "supported: registers must have a "
2886 "'%' prefix in .att_syntax");
2888 getParser().setAssemblerDialect(0);
2890 }
else if (IDVal.
startswith(
".intel_syntax")) {
2891 getParser().setAssemblerDialect(1);
2896 return Error(DirectiveID.
getLoc(),
"'.intel_syntax prefix' is not "
2897 "supported: registers must not have "
2898 "a '%' prefix in .intel_syntax");
2907 bool X86AsmParser::ParseDirectiveWord(
unsigned Size,
SMLoc L) {
2912 if (getParser().parseExpression(Value))
2915 getParser().getStreamer().EmitValue(Value, Size);
2922 Error(L,
"unexpected token in directive");
2935 bool X86AsmParser::ParseDirectiveCode(
StringRef IDVal,
SMLoc L) {
2937 if (IDVal ==
".code16") {
2939 if (!is16BitMode()) {
2940 SwitchMode(X86::Mode16Bit);
2941 getParser().getStreamer().EmitAssemblerFlag(
MCAF_Code16);
2943 }
else if (IDVal ==
".code32") {
2945 if (!is32BitMode()) {
2946 SwitchMode(X86::Mode32Bit);
2947 getParser().getStreamer().EmitAssemblerFlag(
MCAF_Code32);
2949 }
else if (IDVal ==
".code64") {
2951 if (!is64BitMode()) {
2952 SwitchMode(X86::Mode64Bit);
2953 getParser().getStreamer().EmitAssemblerFlag(
MCAF_Code64);
2956 Error(L,
"unknown directive " + IDVal);
2969 #define GET_REGISTER_MATCHER
2970 #define GET_MATCHER_IMPLEMENTATION
2971 #define GET_SUBTARGET_FEATURE_NAME
2972 #include "X86GenAsmMatcher.inc"
StringRef getToken() const
static const char * getSubtargetFeatureName(uint64_t Val)
Represents a range in source code.
void push_back(const T &Elt)
const_iterator end(StringRef path)
Get end iterator over path.
X86AsmInstrumentation * CreateX86AsmInstrumentation(const MCTargetOptions &MCOptions, const MCContext &Ctx, const MCSubtargetInfo &STI)
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
size_t size() const
size - Get the string size.
TokenKind getKind() const
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.
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
bool endswith(StringRef Suffix) const
Check if this string ends with the given Suffix.
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...
StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
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.
static void RewriteIntelBracExpression(SmallVectorImpl< AsmRewrite > *AsmRewrites, StringRef SymName, int64_t ImmDisp, int64_t FinalImmDisp, SMLoc &BracLoc, SMLoc &StartInBrac, SMLoc &End)
StringRef drop_back(size_t N=1) const
Return a StringRef equal to 'this' but with the last N elements dropped.
StringSwitch & Case(const char(&S)[N], const T &Value)
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
Reports a serious error, calling any installed error handler.
static bool CheckBaseRegAndIndexReg(unsigned BaseReg, unsigned IndexReg, StringRef &ErrMsg)
}
static MCOperand createReg(unsigned Reg)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
void LLVMInitializeX86AsmParser()
bool isImmSExti64i8Value(uint64_t Value)
SMLoc getEndLoc() const override
getEndLoc - Get the location of the last token of this operand.
T LLVM_ATTRIBUTE_UNUSED_RESULT pop_back_val()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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.
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.
static bool convert16i16to16ri8(MCInst &Inst, unsigned Opcode, bool isCmp=false)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
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)
.code16 (X86) / .code 16 (ARM)
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
unsigned getReg() const
Returns the register number.
const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
bool isImmSExti16i8Value(uint64_t Value)
static bool processInstruction(Loop &L, Instruction &Inst, DominatorTree &DT, const SmallVectorImpl< BasicBlock * > &ExitBlocks, PredIteratorCache &PredCache, LoopInfo *LI)
Given an instruction in the loop, check to see if it has any uses that are outside the current loop...
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
int64_t getIntVal() const
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.
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.
LLVM_CONSTEXPR size_t array_lengthof(T(&)[N])
Find the length of an array.
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.
X86Operand - Instances of this class represent a parsed X86 machine instruction.
SMRange getLocRange() const
getLocRange - Get the range between the first and last token of this operand.
char back() const
back - Get the last character in the string.
Interface to description of machine instruction set.
This file declares a class to represent arbitrary precision floating point values and provide a varie...
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang","erlang-compatible garbage collector")
iterator erase(iterator I)
Binary assembler expressions.
virtual bool Error(SMLoc L, const Twine &Msg, ArrayRef< SMRange > Ranges=None)=0
Emit an error at the location L, with the message Msg.
SMLoc getStartLoc() const override
getStartLoc - Get the location of the first token of this operand.
static bool convert64i32to64ri8(MCInst &Inst, unsigned Opcode, bool isCmp=false)
void setOpcode(unsigned Op)
bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
static unsigned MatchRegisterName(StringRef Name)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
bool is(TokenKind K) const
R Default(const T &Value) const
bool isMemUnsized() const
unsigned getOpcode() const
Class for arbitrary precision integers.
static bool convertToSExti8(MCInst &Inst, unsigned Opcode, unsigned Reg, bool isCmp)
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
bool equals(StringRef RHS) const
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
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)
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.
StringRef getName() const
getName - Get the symbol name.
static bool convert32i32to32ri8(MCInst &Inst, unsigned Opcode, bool isCmp=false)
MCSubtargetInfo - Generic base class for all target subtargets.
LLVM Value Representation.
StringSwitch & Cases(const char(&S0)[N0], const char(&S1)[N1], const T &Value)
bool isImmSExti32i8Value(uint64_t Value)
void addOperand(const MCOperand &Op)
StringRef - Represent a constant reference to a string, i.e.
bool isUndefined() const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml","ocaml 3.10-compatible collector")
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
Represents a location in source code.
std::string lower() const
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx)
const MCOperand & getOperand(unsigned i) const
bool isMem() const override
isMem - Is this a memory operand?