blob: ce17f7744ee0eea03c5b9754dbb3f359954a39ce [file] [log] [blame]
Daniel Dunbar71475772009-07-17 20:42:00 +00001//===-- X86AsmParser.cpp - Parse X86 assembly to MCInst instructions ------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Evan Cheng11424442011-07-26 00:24:13 +000010#include "MCTargetDesc/X86BaseInfo.h"
Evgeniy Stepanov49e26252014-03-14 08:58:04 +000011#include "X86AsmInstrumentation.h"
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000012#include "X86AsmParserCommon.h"
13#include "X86Operand.h"
Coby Tayreed8912892017-08-24 08:46:25 +000014#include "InstPrinter/X86IntelInstPrinter.h"
Craig Topper690d8ea2013-07-24 07:33:14 +000015#include "llvm/ADT/STLExtras.h"
Chris Lattner1261b812010-09-22 04:11:10 +000016#include "llvm/ADT/SmallString.h"
17#include "llvm/ADT/SmallVector.h"
Chris Lattner1261b812010-09-22 04:11:10 +000018#include "llvm/ADT/StringSwitch.h"
19#include "llvm/ADT/Twine.h"
Chad Rosier8a244662013-04-02 20:02:33 +000020#include "llvm/MC/MCContext.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000021#include "llvm/MC/MCExpr.h"
22#include "llvm/MC/MCInst.h"
Evgeniy Stepanovf4a36992014-04-24 13:29:34 +000023#include "llvm/MC/MCInstrInfo.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000024#include "llvm/MC/MCParser/MCAsmLexer.h"
25#include "llvm/MC/MCParser/MCAsmParser.h"
26#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
Benjamin Kramerb3e8a6d2016-01-27 10:01:28 +000027#include "llvm/MC/MCParser/MCTargetAsmParser.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000028#include "llvm/MC/MCRegisterInfo.h"
Michael Zuckerman02ecd432015-12-13 17:07:23 +000029#include "llvm/MC/MCSection.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000030#include "llvm/MC/MCStreamer.h"
31#include "llvm/MC/MCSubtargetInfo.h"
32#include "llvm/MC/MCSymbol.h"
Daniel Dunbare1fdb0e2009-07-28 22:40:46 +000033#include "llvm/Support/SourceMgr.h"
Evan Cheng2bb40352011-08-24 18:08:43 +000034#include "llvm/Support/TargetRegistry.h"
Daniel Dunbar7d7b4d12010-08-12 00:55:42 +000035#include "llvm/Support/raw_ostream.h"
Reid Kleckner7b1e1a02014-07-30 22:23:11 +000036#include <algorithm>
Evgeniy Stepanov49e26252014-03-14 08:58:04 +000037#include <memory>
Evan Cheng4d1ca962011-07-08 01:53:10 +000038
Daniel Dunbar71475772009-07-17 20:42:00 +000039using namespace llvm;
40
Andrew V. Tischenko32e9b1a2017-07-25 13:05:12 +000041static bool checkScale(unsigned Scale, StringRef &ErrMsg) {
42 if (Scale != 1 && Scale != 2 && Scale != 4 && Scale != 8) {
43 ErrMsg = "scale factor in address must be 1, 2, 4 or 8";
44 return true;
45 }
46 return false;
47}
48
Daniel Dunbar71475772009-07-17 20:42:00 +000049namespace {
Daniel Dunbare1fdb0e2009-07-28 22:40:46 +000050
Chad Rosier5362af92013-04-16 18:15:40 +000051static const char OpPrecedence[] = {
Kevin Enderby2e13b1c2014-01-15 19:05:24 +000052 0, // IC_OR
Michael Kupersteine3de07a2015-06-14 12:59:45 +000053 1, // IC_XOR
54 2, // IC_AND
55 3, // IC_LSHIFT
56 3, // IC_RSHIFT
57 4, // IC_PLUS
58 4, // IC_MINUS
59 5, // IC_MULTIPLY
60 5, // IC_DIVIDE
Coby Tayree41a5b552017-06-27 16:58:27 +000061 5, // IC_MOD
62 6, // IC_NOT
63 7, // IC_NEG
64 8, // IC_RPAREN
65 9, // IC_LPAREN
Chad Rosier5362af92013-04-16 18:15:40 +000066 0, // IC_IMM
67 0 // IC_REGISTER
68};
69
Devang Patel4a6e7782012-01-12 18:03:40 +000070class X86AsmParser : public MCTargetAsmParser {
Evgeniy Stepanovf4a36992014-04-24 13:29:34 +000071 const MCInstrInfo &MII;
Chad Rosierf0e87202012-10-25 20:41:34 +000072 ParseInstructionInfo *InstInfo;
Evgeniy Stepanov49e26252014-03-14 08:58:04 +000073 std::unique_ptr<X86AsmInstrumentation> Instrumentation;
Nirav Dave6477ce22016-09-26 19:33:36 +000074 bool Code16GCC;
NAKAMURA Takumia9cb5382015-09-22 11:14:39 +000075
Daniel Dunbare1fdb0e2009-07-28 22:40:46 +000076private:
Alp Tokera5b88a52013-12-02 16:06:06 +000077 SMLoc consumeToken() {
Rafael Espindola961d4692014-11-11 05:18:41 +000078 MCAsmParser &Parser = getParser();
Alp Tokera5b88a52013-12-02 16:06:06 +000079 SMLoc Result = Parser.getTok().getLoc();
80 Parser.Lex();
81 return Result;
82 }
83
Nirav Dave6477ce22016-09-26 19:33:36 +000084 unsigned MatchInstruction(const OperandVector &Operands, MCInst &Inst,
85 uint64_t &ErrorInfo, bool matchingInlineAsm,
86 unsigned VariantID = 0) {
87 // In Code16GCC mode, match as 32-bit.
88 if (Code16GCC)
89 SwitchMode(X86::Mode32Bit);
90 unsigned rv = MatchInstructionImpl(Operands, Inst, ErrorInfo,
91 matchingInlineAsm, VariantID);
92 if (Code16GCC)
93 SwitchMode(X86::Mode16Bit);
94 return rv;
95 }
96
Chad Rosier5362af92013-04-16 18:15:40 +000097 enum InfixCalculatorTok {
Kevin Enderby2e13b1c2014-01-15 19:05:24 +000098 IC_OR = 0,
Michael Kupersteine3de07a2015-06-14 12:59:45 +000099 IC_XOR,
Kevin Enderby2e13b1c2014-01-15 19:05:24 +0000100 IC_AND,
Kevin Enderbyd6b10712014-02-06 01:21:15 +0000101 IC_LSHIFT,
102 IC_RSHIFT,
Kevin Enderby2e13b1c2014-01-15 19:05:24 +0000103 IC_PLUS,
Chad Rosier5362af92013-04-16 18:15:40 +0000104 IC_MINUS,
105 IC_MULTIPLY,
106 IC_DIVIDE,
Coby Tayree41a5b552017-06-27 16:58:27 +0000107 IC_MOD,
108 IC_NOT,
109 IC_NEG,
Chad Rosier5362af92013-04-16 18:15:40 +0000110 IC_RPAREN,
111 IC_LPAREN,
112 IC_IMM,
113 IC_REGISTER
114 };
115
Coby Tayree07a89742017-03-21 19:31:55 +0000116 enum IntelOperatorKind {
117 IOK_INVALID = 0,
118 IOK_LENGTH,
119 IOK_SIZE,
120 IOK_TYPE,
121 IOK_OFFSET
122 };
123
Chad Rosier5362af92013-04-16 18:15:40 +0000124 class InfixCalculator {
125 typedef std::pair< InfixCalculatorTok, int64_t > ICToken;
126 SmallVector<InfixCalculatorTok, 4> InfixOperatorStack;
127 SmallVector<ICToken, 4> PostfixStack;
Michael Liao5bf95782014-12-04 05:20:33 +0000128
Coby Tayree41a5b552017-06-27 16:58:27 +0000129 bool isUnaryOperator(const InfixCalculatorTok Op) {
130 return Op == IC_NEG || Op == IC_NOT;
131 }
132
Chad Rosier5362af92013-04-16 18:15:40 +0000133 public:
134 int64_t popOperand() {
135 assert (!PostfixStack.empty() && "Poped an empty stack!");
136 ICToken Op = PostfixStack.pop_back_val();
Andrew V. Tischenko32e9b1a2017-07-25 13:05:12 +0000137 if (!(Op.first == IC_IMM || Op.first == IC_REGISTER))
138 return -1; // The invalid Scale value will be caught later by checkScale
Chad Rosier5362af92013-04-16 18:15:40 +0000139 return Op.second;
140 }
141 void pushOperand(InfixCalculatorTok Op, int64_t Val = 0) {
142 assert ((Op == IC_IMM || Op == IC_REGISTER) &&
143 "Unexpected operand!");
144 PostfixStack.push_back(std::make_pair(Op, Val));
145 }
Michael Liao5bf95782014-12-04 05:20:33 +0000146
Jakub Staszak9c349222013-08-08 15:48:46 +0000147 void popOperator() { InfixOperatorStack.pop_back(); }
Chad Rosier5362af92013-04-16 18:15:40 +0000148 void pushOperator(InfixCalculatorTok Op) {
149 // Push the new operator if the stack is empty.
150 if (InfixOperatorStack.empty()) {
151 InfixOperatorStack.push_back(Op);
152 return;
153 }
Michael Liao5bf95782014-12-04 05:20:33 +0000154
Chad Rosier5362af92013-04-16 18:15:40 +0000155 // Push the new operator if it has a higher precedence than the operator
156 // on the top of the stack or the operator on the top of the stack is a
157 // left parentheses.
158 unsigned Idx = InfixOperatorStack.size() - 1;
159 InfixCalculatorTok StackOp = InfixOperatorStack[Idx];
160 if (OpPrecedence[Op] > OpPrecedence[StackOp] || StackOp == IC_LPAREN) {
161 InfixOperatorStack.push_back(Op);
162 return;
163 }
Michael Liao5bf95782014-12-04 05:20:33 +0000164
Chad Rosier5362af92013-04-16 18:15:40 +0000165 // The operator on the top of the stack has higher precedence than the
166 // new operator.
167 unsigned ParenCount = 0;
Kirill Bobyrev6afbaf02017-01-18 16:34:25 +0000168 while (1) {
Chad Rosier5362af92013-04-16 18:15:40 +0000169 // Nothing to process.
170 if (InfixOperatorStack.empty())
171 break;
Michael Liao5bf95782014-12-04 05:20:33 +0000172
Chad Rosier5362af92013-04-16 18:15:40 +0000173 Idx = InfixOperatorStack.size() - 1;
174 StackOp = InfixOperatorStack[Idx];
175 if (!(OpPrecedence[StackOp] >= OpPrecedence[Op] || ParenCount))
176 break;
Michael Liao5bf95782014-12-04 05:20:33 +0000177
Chad Rosier5362af92013-04-16 18:15:40 +0000178 // If we have an even parentheses count and we see a left parentheses,
179 // then stop processing.
180 if (!ParenCount && StackOp == IC_LPAREN)
181 break;
Michael Liao5bf95782014-12-04 05:20:33 +0000182
Chad Rosier5362af92013-04-16 18:15:40 +0000183 if (StackOp == IC_RPAREN) {
184 ++ParenCount;
Jakub Staszak9c349222013-08-08 15:48:46 +0000185 InfixOperatorStack.pop_back();
Chad Rosier5362af92013-04-16 18:15:40 +0000186 } else if (StackOp == IC_LPAREN) {
187 --ParenCount;
Jakub Staszak9c349222013-08-08 15:48:46 +0000188 InfixOperatorStack.pop_back();
Chad Rosier5362af92013-04-16 18:15:40 +0000189 } else {
Jakub Staszak9c349222013-08-08 15:48:46 +0000190 InfixOperatorStack.pop_back();
Chad Rosier5362af92013-04-16 18:15:40 +0000191 PostfixStack.push_back(std::make_pair(StackOp, 0));
192 }
193 }
194 // Push the new operator.
195 InfixOperatorStack.push_back(Op);
196 }
Marina Yatsinaa0e02412015-08-10 11:33:10 +0000197
Chad Rosier5362af92013-04-16 18:15:40 +0000198 int64_t execute() {
199 // Push any remaining operators onto the postfix stack.
200 while (!InfixOperatorStack.empty()) {
201 InfixCalculatorTok StackOp = InfixOperatorStack.pop_back_val();
202 if (StackOp != IC_LPAREN && StackOp != IC_RPAREN)
203 PostfixStack.push_back(std::make_pair(StackOp, 0));
204 }
Michael Liao5bf95782014-12-04 05:20:33 +0000205
Chad Rosier5362af92013-04-16 18:15:40 +0000206 if (PostfixStack.empty())
207 return 0;
Michael Liao5bf95782014-12-04 05:20:33 +0000208
Chad Rosier5362af92013-04-16 18:15:40 +0000209 SmallVector<ICToken, 16> OperandStack;
210 for (unsigned i = 0, e = PostfixStack.size(); i != e; ++i) {
211 ICToken Op = PostfixStack[i];
212 if (Op.first == IC_IMM || Op.first == IC_REGISTER) {
213 OperandStack.push_back(Op);
Coby Tayree41a5b552017-06-27 16:58:27 +0000214 } else if (isUnaryOperator(Op.first)) {
215 assert (OperandStack.size() > 0 && "Too few operands.");
216 ICToken Operand = OperandStack.pop_back_val();
217 assert (Operand.first == IC_IMM &&
218 "Unary operation with a register!");
219 switch (Op.first) {
220 default:
221 report_fatal_error("Unexpected operator!");
222 break;
223 case IC_NEG:
224 OperandStack.push_back(std::make_pair(IC_IMM, -Operand.second));
225 break;
226 case IC_NOT:
227 OperandStack.push_back(std::make_pair(IC_IMM, ~Operand.second));
228 break;
229 }
Chad Rosier5362af92013-04-16 18:15:40 +0000230 } else {
231 assert (OperandStack.size() > 1 && "Too few operands.");
232 int64_t Val;
233 ICToken Op2 = OperandStack.pop_back_val();
234 ICToken Op1 = OperandStack.pop_back_val();
235 switch (Op.first) {
236 default:
237 report_fatal_error("Unexpected operator!");
238 break;
239 case IC_PLUS:
240 Val = Op1.second + Op2.second;
241 OperandStack.push_back(std::make_pair(IC_IMM, Val));
242 break;
243 case IC_MINUS:
244 Val = Op1.second - Op2.second;
245 OperandStack.push_back(std::make_pair(IC_IMM, Val));
246 break;
247 case IC_MULTIPLY:
248 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
249 "Multiply operation with an immediate and a register!");
250 Val = Op1.second * Op2.second;
251 OperandStack.push_back(std::make_pair(IC_IMM, Val));
252 break;
253 case IC_DIVIDE:
254 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
255 "Divide operation with an immediate and a register!");
256 assert (Op2.second != 0 && "Division by zero!");
257 Val = Op1.second / Op2.second;
258 OperandStack.push_back(std::make_pair(IC_IMM, Val));
259 break;
Coby Tayree41a5b552017-06-27 16:58:27 +0000260 case IC_MOD:
261 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
262 "Modulo operation with an immediate and a register!");
263 Val = Op1.second % Op2.second;
264 OperandStack.push_back(std::make_pair(IC_IMM, Val));
265 break;
Kevin Enderby2e13b1c2014-01-15 19:05:24 +0000266 case IC_OR:
267 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
268 "Or operation with an immediate and a register!");
269 Val = Op1.second | Op2.second;
270 OperandStack.push_back(std::make_pair(IC_IMM, Val));
271 break;
Michael Kupersteine3de07a2015-06-14 12:59:45 +0000272 case IC_XOR:
273 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
274 "Xor operation with an immediate and a register!");
275 Val = Op1.second ^ Op2.second;
276 OperandStack.push_back(std::make_pair(IC_IMM, Val));
277 break;
Kevin Enderby2e13b1c2014-01-15 19:05:24 +0000278 case IC_AND:
279 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
280 "And operation with an immediate and a register!");
281 Val = Op1.second & Op2.second;
282 OperandStack.push_back(std::make_pair(IC_IMM, Val));
283 break;
Kevin Enderbyd6b10712014-02-06 01:21:15 +0000284 case IC_LSHIFT:
285 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
286 "Left shift operation with an immediate and a register!");
287 Val = Op1.second << Op2.second;
288 OperandStack.push_back(std::make_pair(IC_IMM, Val));
289 break;
290 case IC_RSHIFT:
291 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
292 "Right shift operation with an immediate and a register!");
293 Val = Op1.second >> Op2.second;
294 OperandStack.push_back(std::make_pair(IC_IMM, Val));
295 break;
Chad Rosier5362af92013-04-16 18:15:40 +0000296 }
297 }
298 }
299 assert (OperandStack.size() == 1 && "Expected a single result.");
300 return OperandStack.pop_back_val().second;
301 }
302 };
303
304 enum IntelExprState {
Coby Tayreed8912892017-08-24 08:46:25 +0000305 IES_INIT,
Kevin Enderby2e13b1c2014-01-15 19:05:24 +0000306 IES_OR,
Michael Kupersteine3de07a2015-06-14 12:59:45 +0000307 IES_XOR,
Kevin Enderby2e13b1c2014-01-15 19:05:24 +0000308 IES_AND,
Kevin Enderbyd6b10712014-02-06 01:21:15 +0000309 IES_LSHIFT,
310 IES_RSHIFT,
Chad Rosier5362af92013-04-16 18:15:40 +0000311 IES_PLUS,
312 IES_MINUS,
Ehsan Akhgari4103da62014-07-04 19:13:05 +0000313 IES_NOT,
Chad Rosier5362af92013-04-16 18:15:40 +0000314 IES_MULTIPLY,
315 IES_DIVIDE,
Coby Tayree41a5b552017-06-27 16:58:27 +0000316 IES_MOD,
Chad Rosier5362af92013-04-16 18:15:40 +0000317 IES_LBRAC,
318 IES_RBRAC,
319 IES_LPAREN,
320 IES_RPAREN,
321 IES_REGISTER,
Chad Rosier5362af92013-04-16 18:15:40 +0000322 IES_INTEGER,
Chad Rosier5362af92013-04-16 18:15:40 +0000323 IES_IDENTIFIER,
324 IES_ERROR
325 };
326
327 class IntelExprStateMachine {
Chad Rosier31246272013-04-17 21:01:45 +0000328 IntelExprState State, PrevState;
Chad Rosier5362af92013-04-16 18:15:40 +0000329 unsigned BaseReg, IndexReg, TmpReg, Scale;
Chad Rosierbfb70992013-04-17 00:11:46 +0000330 int64_t Imm;
Chad Rosier5362af92013-04-16 18:15:40 +0000331 const MCExpr *Sym;
332 StringRef SymName;
333 InfixCalculator IC;
Chad Rosiercb78f0d2013-04-22 19:42:15 +0000334 InlineAsmIdentifierInfo Info;
Coby Tayreed8912892017-08-24 08:46:25 +0000335 short BracCount;
336 bool MemExpr;
NAKAMURA Takumia9cb5382015-09-22 11:14:39 +0000337
Chad Rosier5362af92013-04-16 18:15:40 +0000338 public:
Coby Tayreed8912892017-08-24 08:46:25 +0000339 IntelExprStateMachine()
340 : State(IES_INIT), PrevState(IES_ERROR), BaseReg(0), IndexReg(0),
341 TmpReg(0), Scale(1), Imm(0), Sym(nullptr), BracCount(0),
342 MemExpr(false) {
343 Info.clear();
344 }
Michael Liao5bf95782014-12-04 05:20:33 +0000345
Coby Tayreed8912892017-08-24 08:46:25 +0000346 void addImm(int64_t imm) { Imm += imm; }
347 short getBracCount() { return BracCount; }
348 bool isMemExpr() { return MemExpr; }
Chad Rosier5362af92013-04-16 18:15:40 +0000349 unsigned getBaseReg() { return BaseReg; }
350 unsigned getIndexReg() { return IndexReg; }
351 unsigned getScale() { return Scale; }
352 const MCExpr *getSym() { return Sym; }
353 StringRef getSymName() { return SymName; }
Chad Rosierbfb70992013-04-17 00:11:46 +0000354 int64_t getImm() { return Imm + IC.execute(); }
Chad Rosieredb1dc82013-05-09 23:48:53 +0000355 bool isValidEndState() {
356 return State == IES_RBRAC || State == IES_INTEGER;
357 }
Chad Rosier31246272013-04-17 21:01:45 +0000358 bool hadError() { return State == IES_ERROR; }
Coby Tayreed8912892017-08-24 08:46:25 +0000359 InlineAsmIdentifierInfo &getIdentifierInfo() { return Info; }
Chad Rosiercb78f0d2013-04-22 19:42:15 +0000360
Kevin Enderby2e13b1c2014-01-15 19:05:24 +0000361 void onOr() {
362 IntelExprState CurrState = State;
363 switch (State) {
364 default:
365 State = IES_ERROR;
366 break;
367 case IES_INTEGER:
368 case IES_RPAREN:
369 case IES_REGISTER:
370 State = IES_OR;
371 IC.pushOperator(IC_OR);
372 break;
373 }
374 PrevState = CurrState;
375 }
Michael Kupersteine3de07a2015-06-14 12:59:45 +0000376 void onXor() {
377 IntelExprState CurrState = State;
378 switch (State) {
379 default:
380 State = IES_ERROR;
381 break;
382 case IES_INTEGER:
383 case IES_RPAREN:
384 case IES_REGISTER:
385 State = IES_XOR;
386 IC.pushOperator(IC_XOR);
387 break;
388 }
389 PrevState = CurrState;
390 }
Kevin Enderby2e13b1c2014-01-15 19:05:24 +0000391 void onAnd() {
392 IntelExprState CurrState = State;
393 switch (State) {
394 default:
395 State = IES_ERROR;
396 break;
397 case IES_INTEGER:
398 case IES_RPAREN:
399 case IES_REGISTER:
400 State = IES_AND;
401 IC.pushOperator(IC_AND);
402 break;
403 }
404 PrevState = CurrState;
405 }
Kevin Enderbyd6b10712014-02-06 01:21:15 +0000406 void onLShift() {
407 IntelExprState CurrState = State;
408 switch (State) {
409 default:
410 State = IES_ERROR;
411 break;
412 case IES_INTEGER:
413 case IES_RPAREN:
414 case IES_REGISTER:
415 State = IES_LSHIFT;
416 IC.pushOperator(IC_LSHIFT);
417 break;
418 }
419 PrevState = CurrState;
420 }
421 void onRShift() {
422 IntelExprState CurrState = State;
423 switch (State) {
424 default:
425 State = IES_ERROR;
426 break;
427 case IES_INTEGER:
428 case IES_RPAREN:
429 case IES_REGISTER:
430 State = IES_RSHIFT;
431 IC.pushOperator(IC_RSHIFT);
432 break;
433 }
434 PrevState = CurrState;
435 }
Andrew V. Tischenko32e9b1a2017-07-25 13:05:12 +0000436 bool onPlus(StringRef &ErrMsg) {
Chad Rosier31246272013-04-17 21:01:45 +0000437 IntelExprState CurrState = State;
Chad Rosier5362af92013-04-16 18:15:40 +0000438 switch (State) {
439 default:
440 State = IES_ERROR;
441 break;
442 case IES_INTEGER:
443 case IES_RPAREN:
Chad Rosier5362af92013-04-16 18:15:40 +0000444 case IES_REGISTER:
445 State = IES_PLUS;
Chad Rosier5362af92013-04-16 18:15:40 +0000446 IC.pushOperator(IC_PLUS);
Chad Rosier31246272013-04-17 21:01:45 +0000447 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
448 // If we already have a BaseReg, then assume this is the IndexReg with
449 // a scale of 1.
450 if (!BaseReg) {
451 BaseReg = TmpReg;
452 } else {
Andrew V. Tischenko32e9b1a2017-07-25 13:05:12 +0000453 if (IndexReg) {
454 ErrMsg = "BaseReg/IndexReg already set!";
455 return true;
456 }
Chad Rosier31246272013-04-17 21:01:45 +0000457 IndexReg = TmpReg;
458 Scale = 1;
459 }
460 }
Chad Rosier5362af92013-04-16 18:15:40 +0000461 break;
462 }
Chad Rosier31246272013-04-17 21:01:45 +0000463 PrevState = CurrState;
Andrew V. Tischenko32e9b1a2017-07-25 13:05:12 +0000464 return false;
Chad Rosier5362af92013-04-16 18:15:40 +0000465 }
Andrew V. Tischenko32e9b1a2017-07-25 13:05:12 +0000466 bool onMinus(StringRef &ErrMsg) {
Chad Rosier31246272013-04-17 21:01:45 +0000467 IntelExprState CurrState = State;
Chad Rosier5362af92013-04-16 18:15:40 +0000468 switch (State) {
469 default:
470 State = IES_ERROR;
471 break;
Coby Tayree41a5b552017-06-27 16:58:27 +0000472 case IES_OR:
473 case IES_XOR:
474 case IES_AND:
475 case IES_LSHIFT:
476 case IES_RSHIFT:
Chad Rosier5362af92013-04-16 18:15:40 +0000477 case IES_PLUS:
Ehsan Akhgari4103da62014-07-04 19:13:05 +0000478 case IES_NOT:
Chad Rosier31246272013-04-17 21:01:45 +0000479 case IES_MULTIPLY:
480 case IES_DIVIDE:
Coby Tayree41a5b552017-06-27 16:58:27 +0000481 case IES_MOD:
Chad Rosier5362af92013-04-16 18:15:40 +0000482 case IES_LPAREN:
Chad Rosier5362af92013-04-16 18:15:40 +0000483 case IES_RPAREN:
Chad Rosier31246272013-04-17 21:01:45 +0000484 case IES_LBRAC:
485 case IES_RBRAC:
486 case IES_INTEGER:
Chad Rosier5362af92013-04-16 18:15:40 +0000487 case IES_REGISTER:
Coby Tayreed8912892017-08-24 08:46:25 +0000488 case IES_INIT:
Chad Rosier5362af92013-04-16 18:15:40 +0000489 State = IES_MINUS;
Coby Tayree41a5b552017-06-27 16:58:27 +0000490 // push minus operator if it is not a negate operator
491 if (CurrState == IES_REGISTER || CurrState == IES_RPAREN ||
492 CurrState == IES_INTEGER || CurrState == IES_RBRAC)
Chad Rosier31246272013-04-17 21:01:45 +0000493 IC.pushOperator(IC_MINUS);
Andrew V. Tischenko32e9b1a2017-07-25 13:05:12 +0000494 else if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
495 // We have negate operator for Scale: it's illegal
496 ErrMsg = "Scale can't be negative";
497 return true;
498 } else
Coby Tayree41a5b552017-06-27 16:58:27 +0000499 IC.pushOperator(IC_NEG);
Chad Rosier31246272013-04-17 21:01:45 +0000500 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
501 // If we already have a BaseReg, then assume this is the IndexReg with
502 // a scale of 1.
503 if (!BaseReg) {
504 BaseReg = TmpReg;
505 } else {
Andrew V. Tischenko32e9b1a2017-07-25 13:05:12 +0000506 if (IndexReg) {
507 ErrMsg = "BaseReg/IndexReg already set!";
508 return true;
509 }
Chad Rosier31246272013-04-17 21:01:45 +0000510 IndexReg = TmpReg;
511 Scale = 1;
512 }
Chad Rosier5362af92013-04-16 18:15:40 +0000513 }
Chad Rosier5362af92013-04-16 18:15:40 +0000514 break;
515 }
Chad Rosier31246272013-04-17 21:01:45 +0000516 PrevState = CurrState;
Andrew V. Tischenko32e9b1a2017-07-25 13:05:12 +0000517 return false;
Chad Rosier5362af92013-04-16 18:15:40 +0000518 }
Ehsan Akhgari4103da62014-07-04 19:13:05 +0000519 void onNot() {
520 IntelExprState CurrState = State;
521 switch (State) {
522 default:
523 State = IES_ERROR;
524 break;
Coby Tayree41a5b552017-06-27 16:58:27 +0000525 case IES_OR:
526 case IES_XOR:
527 case IES_AND:
528 case IES_LSHIFT:
529 case IES_RSHIFT:
Ehsan Akhgari4103da62014-07-04 19:13:05 +0000530 case IES_PLUS:
Coby Tayree41a5b552017-06-27 16:58:27 +0000531 case IES_MINUS:
Ehsan Akhgari4103da62014-07-04 19:13:05 +0000532 case IES_NOT:
Coby Tayree41a5b552017-06-27 16:58:27 +0000533 case IES_MULTIPLY:
534 case IES_DIVIDE:
535 case IES_MOD:
536 case IES_LPAREN:
537 case IES_LBRAC:
Coby Tayreed8912892017-08-24 08:46:25 +0000538 case IES_INIT:
Ehsan Akhgari4103da62014-07-04 19:13:05 +0000539 State = IES_NOT;
Coby Tayree41a5b552017-06-27 16:58:27 +0000540 IC.pushOperator(IC_NOT);
Ehsan Akhgari4103da62014-07-04 19:13:05 +0000541 break;
542 }
543 PrevState = CurrState;
544 }
Andrew V. Tischenko32e9b1a2017-07-25 13:05:12 +0000545
546 bool onRegister(unsigned Reg, StringRef &ErrMsg) {
Chad Rosier31246272013-04-17 21:01:45 +0000547 IntelExprState CurrState = State;
Chad Rosier5362af92013-04-16 18:15:40 +0000548 switch (State) {
549 default:
550 State = IES_ERROR;
551 break;
552 case IES_PLUS:
553 case IES_LPAREN:
Coby Tayreed8912892017-08-24 08:46:25 +0000554 case IES_LBRAC:
Chad Rosier5362af92013-04-16 18:15:40 +0000555 State = IES_REGISTER;
556 TmpReg = Reg;
557 IC.pushOperand(IC_REGISTER);
558 break;
Chad Rosier31246272013-04-17 21:01:45 +0000559 case IES_MULTIPLY:
560 // Index Register - Scale * Register
561 if (PrevState == IES_INTEGER) {
Andrew V. Tischenko32e9b1a2017-07-25 13:05:12 +0000562 if (IndexReg) {
563 ErrMsg = "BaseReg/IndexReg already set!";
564 return true;
565 }
Chad Rosier31246272013-04-17 21:01:45 +0000566 State = IES_REGISTER;
567 IndexReg = Reg;
568 // Get the scale and replace the 'Scale * Register' with '0'.
569 Scale = IC.popOperand();
Andrew V. Tischenko32e9b1a2017-07-25 13:05:12 +0000570 if (checkScale(Scale, ErrMsg))
571 return true;
Chad Rosier31246272013-04-17 21:01:45 +0000572 IC.pushOperand(IC_IMM);
573 IC.popOperator();
574 } else {
575 State = IES_ERROR;
576 }
Chad Rosier5362af92013-04-16 18:15:40 +0000577 break;
578 }
Chad Rosier31246272013-04-17 21:01:45 +0000579 PrevState = CurrState;
Andrew V. Tischenko32e9b1a2017-07-25 13:05:12 +0000580 return false;
Chad Rosier5362af92013-04-16 18:15:40 +0000581 }
Coby Tayreed8912892017-08-24 08:46:25 +0000582 bool onIdentifierExpr(const MCExpr *SymRef, StringRef SymRefName,
583 StringRef &ErrMsg) {
Chad Rosierdb003992013-04-18 16:28:19 +0000584 PrevState = State;
Coby Tayreed8912892017-08-24 08:46:25 +0000585 bool HasSymbol = Sym != nullptr;
Chad Rosier5362af92013-04-16 18:15:40 +0000586 switch (State) {
587 default:
588 State = IES_ERROR;
589 break;
590 case IES_PLUS:
591 case IES_MINUS:
Ehsan Akhgari4103da62014-07-04 19:13:05 +0000592 case IES_NOT:
Coby Tayreed8912892017-08-24 08:46:25 +0000593 case IES_INIT:
594 case IES_LBRAC:
595 MemExpr = !(SymRef->getKind() == MCExpr::Constant);
Chad Rosier5362af92013-04-16 18:15:40 +0000596 State = IES_INTEGER;
597 Sym = SymRef;
598 SymName = SymRefName;
599 IC.pushOperand(IC_IMM);
600 break;
601 }
Coby Tayreed8912892017-08-24 08:46:25 +0000602 if (HasSymbol)
603 ErrMsg = "cannot use more than one symbol in memory operand";
604 return HasSymbol;
Chad Rosier5362af92013-04-16 18:15:40 +0000605 }
Kevin Enderby9d117022014-01-23 21:52:41 +0000606 bool onInteger(int64_t TmpInt, StringRef &ErrMsg) {
Chad Rosier31246272013-04-17 21:01:45 +0000607 IntelExprState CurrState = State;
Chad Rosier5362af92013-04-16 18:15:40 +0000608 switch (State) {
609 default:
610 State = IES_ERROR;
611 break;
612 case IES_PLUS:
613 case IES_MINUS:
Ehsan Akhgari4103da62014-07-04 19:13:05 +0000614 case IES_NOT:
Kevin Enderby2e13b1c2014-01-15 19:05:24 +0000615 case IES_OR:
Michael Kupersteine3de07a2015-06-14 12:59:45 +0000616 case IES_XOR:
Kevin Enderby2e13b1c2014-01-15 19:05:24 +0000617 case IES_AND:
Kevin Enderbyd6b10712014-02-06 01:21:15 +0000618 case IES_LSHIFT:
619 case IES_RSHIFT:
Chad Rosier5362af92013-04-16 18:15:40 +0000620 case IES_DIVIDE:
Coby Tayree41a5b552017-06-27 16:58:27 +0000621 case IES_MOD:
Chad Rosier31246272013-04-17 21:01:45 +0000622 case IES_MULTIPLY:
Chad Rosier5362af92013-04-16 18:15:40 +0000623 case IES_LPAREN:
Coby Tayreed8912892017-08-24 08:46:25 +0000624 case IES_INIT:
625 case IES_LBRAC:
Chad Rosier5362af92013-04-16 18:15:40 +0000626 State = IES_INTEGER;
Chad Rosier31246272013-04-17 21:01:45 +0000627 if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
628 // Index Register - Register * Scale
Andrew V. Tischenko32e9b1a2017-07-25 13:05:12 +0000629 if (IndexReg) {
630 ErrMsg = "BaseReg/IndexReg already set!";
Kevin Enderby9d117022014-01-23 21:52:41 +0000631 return true;
632 }
Andrew V. Tischenko32e9b1a2017-07-25 13:05:12 +0000633 IndexReg = TmpReg;
634 Scale = TmpInt;
635 if (checkScale(Scale, ErrMsg))
636 return true;
Chad Rosier31246272013-04-17 21:01:45 +0000637 // Get the scale and replace the 'Register * Scale' with '0'.
638 IC.popOperator();
Chad Rosier31246272013-04-17 21:01:45 +0000639 } else {
640 IC.pushOperand(IC_IMM, TmpInt);
641 }
Chad Rosier5362af92013-04-16 18:15:40 +0000642 break;
643 }
Chad Rosier31246272013-04-17 21:01:45 +0000644 PrevState = CurrState;
Kevin Enderby9d117022014-01-23 21:52:41 +0000645 return false;
Chad Rosier5362af92013-04-16 18:15:40 +0000646 }
647 void onStar() {
Chad Rosierdb003992013-04-18 16:28:19 +0000648 PrevState = State;
Chad Rosier5362af92013-04-16 18:15:40 +0000649 switch (State) {
650 default:
651 State = IES_ERROR;
652 break;
653 case IES_INTEGER:
Chad Rosier5362af92013-04-16 18:15:40 +0000654 case IES_REGISTER:
Chad Rosier5362af92013-04-16 18:15:40 +0000655 case IES_RPAREN:
656 State = IES_MULTIPLY;
657 IC.pushOperator(IC_MULTIPLY);
658 break;
659 }
660 }
661 void onDivide() {
Chad Rosierdb003992013-04-18 16:28:19 +0000662 PrevState = State;
Chad Rosier5362af92013-04-16 18:15:40 +0000663 switch (State) {
664 default:
665 State = IES_ERROR;
666 break;
667 case IES_INTEGER:
Chad Rosier31246272013-04-17 21:01:45 +0000668 case IES_RPAREN:
Chad Rosier5362af92013-04-16 18:15:40 +0000669 State = IES_DIVIDE;
670 IC.pushOperator(IC_DIVIDE);
671 break;
672 }
673 }
Coby Tayree41a5b552017-06-27 16:58:27 +0000674 void onMod() {
675 PrevState = State;
676 switch (State) {
677 default:
678 State = IES_ERROR;
679 break;
680 case IES_INTEGER:
681 case IES_RPAREN:
682 State = IES_MOD;
683 IC.pushOperator(IC_MOD);
684 break;
685 }
686 }
Coby Tayreed8912892017-08-24 08:46:25 +0000687 bool onLBrac() {
688 if (BracCount)
689 return true;
Chad Rosierdb003992013-04-18 16:28:19 +0000690 PrevState = State;
Chad Rosier5362af92013-04-16 18:15:40 +0000691 switch (State) {
692 default:
693 State = IES_ERROR;
694 break;
695 case IES_RBRAC:
Coby Tayreed8912892017-08-24 08:46:25 +0000696 case IES_INTEGER:
697 case IES_RPAREN:
Chad Rosier5362af92013-04-16 18:15:40 +0000698 State = IES_PLUS;
699 IC.pushOperator(IC_PLUS);
700 break;
Coby Tayreed8912892017-08-24 08:46:25 +0000701 case IES_INIT:
702 assert(!BracCount && "BracCount should be zero on parsing's start");
703 State = IES_LBRAC;
704 break;
Chad Rosier5362af92013-04-16 18:15:40 +0000705 }
Coby Tayreed8912892017-08-24 08:46:25 +0000706 MemExpr = true;
707 BracCount++;
708 return false;
Chad Rosier5362af92013-04-16 18:15:40 +0000709 }
Coby Tayreed8912892017-08-24 08:46:25 +0000710 bool onRBrac() {
Chad Rosier31246272013-04-17 21:01:45 +0000711 IntelExprState CurrState = State;
Chad Rosier5362af92013-04-16 18:15:40 +0000712 switch (State) {
713 default:
714 State = IES_ERROR;
715 break;
Chad Rosier5362af92013-04-16 18:15:40 +0000716 case IES_INTEGER:
Chad Rosier5362af92013-04-16 18:15:40 +0000717 case IES_REGISTER:
Chad Rosier31246272013-04-17 21:01:45 +0000718 case IES_RPAREN:
Coby Tayreed8912892017-08-24 08:46:25 +0000719 if (BracCount-- != 1)
720 return true;
Chad Rosier5362af92013-04-16 18:15:40 +0000721 State = IES_RBRAC;
Chad Rosier31246272013-04-17 21:01:45 +0000722 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
723 // If we already have a BaseReg, then assume this is the IndexReg with
724 // a scale of 1.
725 if (!BaseReg) {
726 BaseReg = TmpReg;
727 } else {
728 assert (!IndexReg && "BaseReg/IndexReg already set!");
729 IndexReg = TmpReg;
730 Scale = 1;
731 }
Chad Rosier5362af92013-04-16 18:15:40 +0000732 }
733 break;
734 }
Chad Rosier31246272013-04-17 21:01:45 +0000735 PrevState = CurrState;
Coby Tayreed8912892017-08-24 08:46:25 +0000736 return false;
Chad Rosier5362af92013-04-16 18:15:40 +0000737 }
738 void onLParen() {
Chad Rosier31246272013-04-17 21:01:45 +0000739 IntelExprState CurrState = State;
Chad Rosier5362af92013-04-16 18:15:40 +0000740 switch (State) {
741 default:
742 State = IES_ERROR;
743 break;
744 case IES_PLUS:
745 case IES_MINUS:
Ehsan Akhgari4103da62014-07-04 19:13:05 +0000746 case IES_NOT:
Kevin Enderby2e13b1c2014-01-15 19:05:24 +0000747 case IES_OR:
Michael Kupersteine3de07a2015-06-14 12:59:45 +0000748 case IES_XOR:
Kevin Enderby2e13b1c2014-01-15 19:05:24 +0000749 case IES_AND:
Kevin Enderbyd6b10712014-02-06 01:21:15 +0000750 case IES_LSHIFT:
751 case IES_RSHIFT:
Chad Rosier5362af92013-04-16 18:15:40 +0000752 case IES_MULTIPLY:
753 case IES_DIVIDE:
Coby Tayree41a5b552017-06-27 16:58:27 +0000754 case IES_MOD:
Chad Rosier5362af92013-04-16 18:15:40 +0000755 case IES_LPAREN:
Coby Tayreed8912892017-08-24 08:46:25 +0000756 case IES_INIT:
757 case IES_LBRAC:
Chad Rosier5362af92013-04-16 18:15:40 +0000758 State = IES_LPAREN;
759 IC.pushOperator(IC_LPAREN);
760 break;
761 }
Chad Rosier31246272013-04-17 21:01:45 +0000762 PrevState = CurrState;
Chad Rosier5362af92013-04-16 18:15:40 +0000763 }
764 void onRParen() {
Chad Rosierdb003992013-04-18 16:28:19 +0000765 PrevState = State;
Chad Rosier5362af92013-04-16 18:15:40 +0000766 switch (State) {
767 default:
768 State = IES_ERROR;
769 break;
Chad Rosier5362af92013-04-16 18:15:40 +0000770 case IES_INTEGER:
Chad Rosier31246272013-04-17 21:01:45 +0000771 case IES_REGISTER:
Chad Rosier5362af92013-04-16 18:15:40 +0000772 case IES_RPAREN:
773 State = IES_RPAREN;
774 IC.pushOperator(IC_RPAREN);
775 break;
776 }
777 }
778 };
779
Nirav Dave2364748a2016-09-16 18:30:20 +0000780 bool Error(SMLoc L, const Twine &Msg, SMRange Range = None,
Chad Rosier4453e842012-10-12 23:09:25 +0000781 bool MatchingInlineAsm = false) {
Rafael Espindola961d4692014-11-11 05:18:41 +0000782 MCAsmParser &Parser = getParser();
Nirav Dave2364748a2016-09-16 18:30:20 +0000783 if (MatchingInlineAsm) {
784 if (!getLexer().isAtStartOfStatement())
785 Parser.eatToEndOfStatement();
786 return false;
787 }
788 return Parser.Error(L, Msg, Range);
Elena Demikhovskyc9657012014-02-20 06:34:39 +0000789 }
790
David Blaikie960ea3f2014-06-08 16:18:35 +0000791 std::nullptr_t ErrorOperand(SMLoc Loc, StringRef Msg) {
Devang Patel41b9dde2012-01-17 18:00:18 +0000792 Error(Loc, Msg);
Craig Topper062a2ba2014-04-25 05:30:21 +0000793 return nullptr;
Devang Patel41b9dde2012-01-17 18:00:18 +0000794 }
795
David Blaikie960ea3f2014-06-08 16:18:35 +0000796 std::unique_ptr<X86Operand> DefaultMemSIOperand(SMLoc Loc);
797 std::unique_ptr<X86Operand> DefaultMemDIOperand(SMLoc Loc);
Marina Yatsinab9f4f622016-01-19 15:37:56 +0000798 bool IsSIReg(unsigned Reg);
799 unsigned GetSIDIForRegClass(unsigned RegClassID, unsigned Reg, bool IsSIReg);
800 void
801 AddDefaultSrcDestOperands(OperandVector &Operands,
802 std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
803 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst);
804 bool VerifyAndAdjustOperands(OperandVector &OrigOperands,
805 OperandVector &FinalOperands);
David Blaikie960ea3f2014-06-08 16:18:35 +0000806 std::unique_ptr<X86Operand> ParseOperand();
807 std::unique_ptr<X86Operand> ParseATTOperand();
808 std::unique_ptr<X86Operand> ParseIntelOperand();
809 std::unique_ptr<X86Operand> ParseIntelOffsetOfOperator();
Coby Tayreed8912892017-08-24 08:46:25 +0000810 bool ParseIntelDotOperator(IntelExprStateMachine &SM, SMLoc &End);
811 unsigned IdentifyIntelInlineAsmOperator(StringRef Name);
812 unsigned ParseIntelInlineAsmOperator(unsigned OpKind);
Elena Demikhovsky18fd4962015-03-02 15:00:34 +0000813 std::unique_ptr<X86Operand> ParseRoundingModeOp(SMLoc Start, SMLoc End);
Coby Tayree2cb497a2017-04-04 14:43:23 +0000814 bool ParseIntelNamedOperator(StringRef Name, IntelExprStateMachine &SM);
Coby Tayreed8912892017-08-24 08:46:25 +0000815 void RewriteIntelExpression(IntelExprStateMachine &SM, SMLoc Start,
816 SMLoc End);
Benjamin Kramer951b15e2013-12-01 11:47:42 +0000817 bool ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End);
Coby Tayreed8912892017-08-24 08:46:25 +0000818 bool ParseIntelInlineAsmIdentifier(const MCExpr *&Val, StringRef &Identifier,
819 InlineAsmIdentifierInfo &Info,
820 bool IsUnevaluatedOperand, SMLoc &End);
Chad Rosiercb78f0d2013-04-22 19:42:15 +0000821
David Blaikie960ea3f2014-06-08 16:18:35 +0000822 std::unique_ptr<X86Operand> ParseMemOperand(unsigned SegReg, SMLoc StartLoc);
Kevin Enderbyce4bec82009-09-10 20:51:44 +0000823
Coby Tayreed8912892017-08-24 08:46:25 +0000824 bool ParseIntelMemoryOperandSize(unsigned &Size);
David Blaikie960ea3f2014-06-08 16:18:35 +0000825 std::unique_ptr<X86Operand>
826 CreateMemForInlineAsm(unsigned SegReg, const MCExpr *Disp, unsigned BaseReg,
827 unsigned IndexReg, unsigned Scale, SMLoc Start,
828 SMLoc End, unsigned Size, StringRef Identifier,
Coby Tayreed8912892017-08-24 08:46:25 +0000829 InlineAsmIdentifierInfo &Info);
Chad Rosier7ca135b2013-03-19 21:11:56 +0000830
Michael Zuckerman02ecd432015-12-13 17:07:23 +0000831 bool parseDirectiveEven(SMLoc L);
Kevin Enderbyce4bec82009-09-10 20:51:44 +0000832 bool ParseDirectiveWord(unsigned Size, SMLoc L);
Evan Cheng481ebb02011-07-27 00:38:12 +0000833 bool ParseDirectiveCode(StringRef IDVal, SMLoc L);
Kevin Enderbyce4bec82009-09-10 20:51:44 +0000834
David Blaikie960ea3f2014-06-08 16:18:35 +0000835 bool processInstruction(MCInst &Inst, const OperandVector &Ops);
Devang Patelde47cce2012-01-18 22:42:29 +0000836
Evgeniy Stepanov49e26252014-03-14 08:58:04 +0000837 /// Wrapper around MCStreamer::EmitInstruction(). Possibly adds
838 /// instrumentation around Inst.
David Blaikie960ea3f2014-06-08 16:18:35 +0000839 void EmitInstruction(MCInst &Inst, OperandVector &Operands, MCStreamer &Out);
Evgeniy Stepanov49e26252014-03-14 08:58:04 +0000840
Chad Rosier49963552012-10-13 00:26:04 +0000841 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
David Blaikie960ea3f2014-06-08 16:18:35 +0000842 OperandVector &Operands, MCStreamer &Out,
Tim Northover26bb14e2014-08-18 11:49:42 +0000843 uint64_t &ErrorInfo,
Craig Topper39012cc2014-03-09 18:03:14 +0000844 bool MatchingInlineAsm) override;
Chad Rosier9cb988f2012-08-09 22:04:55 +0000845
Reid Klecknerf6fb7802014-08-26 20:32:34 +0000846 void MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op, OperandVector &Operands,
847 MCStreamer &Out, bool MatchingInlineAsm);
848
Ranjeet Singh86ecbb72015-06-30 12:32:53 +0000849 bool ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
Reid Klecknerf6fb7802014-08-26 20:32:34 +0000850 bool MatchingInlineAsm);
851
852 bool MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
853 OperandVector &Operands, MCStreamer &Out,
854 uint64_t &ErrorInfo,
855 bool MatchingInlineAsm);
856
857 bool MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
858 OperandVector &Operands, MCStreamer &Out,
859 uint64_t &ErrorInfo,
860 bool MatchingInlineAsm);
861
Craig Topperfd38cbe2014-08-30 16:48:34 +0000862 bool OmitRegisterFromClobberLists(unsigned RegNo) override;
Nico Weber42f79db2014-07-17 20:24:55 +0000863
Elena Demikhovskyc9657012014-02-20 06:34:39 +0000864 /// Parses AVX512 specific operand primitives: masked registers ({%k<NUM>}, {z})
865 /// and memory broadcasting ({1to<NUM>}) primitives, updating Operands vector if required.
Michael Zuckerman1bee6342016-10-18 13:52:39 +0000866 /// return false if no parsing errors occurred, true otherwise.
David Blaikie960ea3f2014-06-08 16:18:35 +0000867 bool HandleAVX512Operand(OperandVector &Operands,
868 const MCParsedAsmOperand &Op);
Elena Demikhovskyc9657012014-02-20 06:34:39 +0000869
Michael Zuckerman1bee6342016-10-18 13:52:39 +0000870 bool ParseZ(std::unique_ptr<X86Operand> &Z, const SMLoc &StartLoc);
871
Evan Chengc5e6d2f2011-07-11 03:57:24 +0000872 bool is64BitMode() const {
Evan Cheng4d1ca962011-07-08 01:53:10 +0000873 // FIXME: Can tablegen auto-generate this?
Akira Hatanakabd9fc282015-11-14 05:20:05 +0000874 return getSTI().getFeatureBits()[X86::Mode64Bit];
Evan Cheng4d1ca962011-07-08 01:53:10 +0000875 }
Craig Topper3c80d622014-01-06 04:55:54 +0000876 bool is32BitMode() const {
877 // FIXME: Can tablegen auto-generate this?
Akira Hatanakabd9fc282015-11-14 05:20:05 +0000878 return getSTI().getFeatureBits()[X86::Mode32Bit];
Craig Topper3c80d622014-01-06 04:55:54 +0000879 }
880 bool is16BitMode() const {
881 // FIXME: Can tablegen auto-generate this?
Akira Hatanakabd9fc282015-11-14 05:20:05 +0000882 return getSTI().getFeatureBits()[X86::Mode16Bit];
Craig Topper3c80d622014-01-06 04:55:54 +0000883 }
Michael Kupersteindb0712f2015-05-26 10:47:10 +0000884 void SwitchMode(unsigned mode) {
Akira Hatanakab11ef082015-11-14 06:35:56 +0000885 MCSubtargetInfo &STI = copySTI();
Michael Kupersteindb0712f2015-05-26 10:47:10 +0000886 FeatureBitset AllModes({X86::Mode64Bit, X86::Mode32Bit, X86::Mode16Bit});
887 FeatureBitset OldMode = STI.getFeatureBits() & AllModes;
Ranjeet Singh86ecbb72015-06-30 12:32:53 +0000888 unsigned FB = ComputeAvailableFeatures(
Michael Kupersteindb0712f2015-05-26 10:47:10 +0000889 STI.ToggleFeature(OldMode.flip(mode)));
Evan Cheng481ebb02011-07-27 00:38:12 +0000890 setAvailableFeatures(FB);
NAKAMURA Takumia9cb5382015-09-22 11:14:39 +0000891
Michael Kupersteindb0712f2015-05-26 10:47:10 +0000892 assert(FeatureBitset({mode}) == (STI.getFeatureBits() & AllModes));
Evan Cheng481ebb02011-07-27 00:38:12 +0000893 }
Evan Cheng4d1ca962011-07-08 01:53:10 +0000894
Reid Kleckner5b37c182014-08-01 20:21:24 +0000895 unsigned getPointerWidth() {
896 if (is16BitMode()) return 16;
897 if (is32BitMode()) return 32;
898 if (is64BitMode()) return 64;
899 llvm_unreachable("invalid mode");
900 }
901
Chad Rosierc2f055d2013-04-18 16:13:18 +0000902 bool isParsingIntelSyntax() {
903 return getParser().getAssemblerDialect();
904 }
905
Daniel Dunbareefe8612010-07-19 05:44:09 +0000906 /// @name Auto-generated Matcher Functions
907 /// {
Michael J. Spencer530ce852010-10-09 11:00:50 +0000908
Chris Lattner3e4582a2010-09-06 19:11:01 +0000909#define GET_ASSEMBLER_HEADER
910#include "X86GenAsmMatcher.inc"
Michael J. Spencer530ce852010-10-09 11:00:50 +0000911
Daniel Dunbar00331992009-07-29 00:02:19 +0000912 /// }
Daniel Dunbare1fdb0e2009-07-28 22:40:46 +0000913
914public:
Coby Tayree07a89742017-03-21 19:31:55 +0000915
Akira Hatanakab11ef082015-11-14 06:35:56 +0000916 X86AsmParser(const MCSubtargetInfo &sti, MCAsmParser &Parser,
Rafael Espindola961d4692014-11-11 05:18:41 +0000917 const MCInstrInfo &mii, const MCTargetOptions &Options)
Nirav Dave6477ce22016-09-26 19:33:36 +0000918 : MCTargetAsmParser(Options, sti), MII(mii), InstInfo(nullptr),
919 Code16GCC(false) {
Michael J. Spencer530ce852010-10-09 11:00:50 +0000920
Daniel Dunbareefe8612010-07-19 05:44:09 +0000921 // Initialize the set of available features.
Akira Hatanakabd9fc282015-11-14 05:20:05 +0000922 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
Evgeniy Stepanov0a951b72014-04-23 11:16:03 +0000923 Instrumentation.reset(
924 CreateX86AsmInstrumentation(Options, Parser.getContext(), STI));
Daniel Dunbareefe8612010-07-19 05:44:09 +0000925 }
Evgeniy Stepanov0a951b72014-04-23 11:16:03 +0000926
Craig Topper39012cc2014-03-09 18:03:14 +0000927 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
Daniel Dunbare1fdb0e2009-07-28 22:40:46 +0000928
Yuri Gorshenin3939dec2014-09-10 09:45:49 +0000929 void SetFrameRegister(unsigned RegNo) override;
930
David Blaikie960ea3f2014-06-08 16:18:35 +0000931 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
932 SMLoc NameLoc, OperandVector &Operands) override;
Kevin Enderbyce4bec82009-09-10 20:51:44 +0000933
Craig Topper39012cc2014-03-09 18:03:14 +0000934 bool ParseDirective(AsmToken DirectiveID) override;
Daniel Dunbare1fdb0e2009-07-28 22:40:46 +0000935};
Chris Lattner4eb9df02009-07-29 06:33:53 +0000936} // end anonymous namespace
937
Sean Callanan86c11812010-01-23 00:40:33 +0000938/// @name Auto-generated Match Functions
Bruno Cardoso Lopesd65cd1d2010-07-23 22:15:26 +0000939/// {
Sean Callanan86c11812010-01-23 00:40:33 +0000940
Chris Lattner60db0a62010-02-09 00:34:28 +0000941static unsigned MatchRegisterName(StringRef Name);
Sean Callanan86c11812010-01-23 00:40:33 +0000942
943/// }
Chris Lattner4eb9df02009-07-29 06:33:53 +0000944
Andrew V. Tischenko32e9b1a2017-07-25 13:05:12 +0000945static bool CheckBaseRegAndIndexRegAndScale(unsigned BaseReg, unsigned IndexReg,
946 unsigned Scale, StringRef &ErrMsg) {
Kevin Enderbybc570f22014-01-23 22:34:42 +0000947 // If we have both a base register and an index register make sure they are
948 // both 64-bit or 32-bit registers.
949 // To support VSIB, IndexReg can be 128-bit or 256-bit registers.
Douglas Katzman0411e862016-10-05 15:23:35 +0000950
951 if ((BaseReg == X86::RIP && IndexReg != 0) || (IndexReg == X86::RIP)) {
952 ErrMsg = "invalid base+index expression";
953 return true;
954 }
Kevin Enderbybc570f22014-01-23 22:34:42 +0000955 if (BaseReg != 0 && IndexReg != 0) {
956 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) &&
957 (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
958 X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg)) &&
959 IndexReg != X86::RIZ) {
960 ErrMsg = "base register is 64-bit, but index register is not";
961 return true;
962 }
963 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg) &&
964 (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
965 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) &&
966 IndexReg != X86::EIZ){
967 ErrMsg = "base register is 32-bit, but index register is not";
968 return true;
969 }
970 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg)) {
971 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg) ||
972 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) {
973 ErrMsg = "base register is 16-bit, but index register is not";
974 return true;
975 }
976 if (((BaseReg == X86::BX || BaseReg == X86::BP) &&
977 IndexReg != X86::SI && IndexReg != X86::DI) ||
978 ((BaseReg == X86::SI || BaseReg == X86::DI) &&
979 IndexReg != X86::BX && IndexReg != X86::BP)) {
980 ErrMsg = "invalid 16-bit base/index register combination";
981 return true;
982 }
983 }
984 }
Andrew V. Tischenko32e9b1a2017-07-25 13:05:12 +0000985 return checkScale(Scale, ErrMsg);
Kevin Enderbybc570f22014-01-23 22:34:42 +0000986}
987
Devang Patel4a6e7782012-01-12 18:03:40 +0000988bool X86AsmParser::ParseRegister(unsigned &RegNo,
989 SMLoc &StartLoc, SMLoc &EndLoc) {
Rafael Espindola961d4692014-11-11 05:18:41 +0000990 MCAsmParser &Parser = getParser();
Chris Lattnercc2ad082010-01-15 18:27:19 +0000991 RegNo = 0;
Benjamin Kramere3d658b2012-09-07 14:51:35 +0000992 const AsmToken &PercentTok = Parser.getTok();
993 StartLoc = PercentTok.getLoc();
994
995 // If we encounter a %, ignore it. This code handles registers with and
996 // without the prefix, unprefixed registers can occur in cfi directives.
997 if (!isParsingIntelSyntax() && PercentTok.is(AsmToken::Percent))
Devang Patel41b9dde2012-01-17 18:00:18 +0000998 Parser.Lex(); // Eat percent token.
Kevin Enderby7d912182009-09-03 17:15:07 +0000999
Sean Callanan936b0d32010-01-19 21:44:56 +00001000 const AsmToken &Tok = Parser.getTok();
Jordan Rosee8f1eae2013-01-07 19:00:49 +00001001 EndLoc = Tok.getEndLoc();
1002
Devang Patelce6a2ca2012-01-20 22:32:05 +00001003 if (Tok.isNot(AsmToken::Identifier)) {
Reid Klecknerc990b5d2017-07-24 20:48:15 +00001004 if (isParsingIntelSyntax()) return true;
Benjamin Kramer1930b002011-10-16 12:10:27 +00001005 return Error(StartLoc, "invalid register name",
Jordan Rosee8f1eae2013-01-07 19:00:49 +00001006 SMRange(StartLoc, EndLoc));
Devang Patelce6a2ca2012-01-20 22:32:05 +00001007 }
Daniel Dunbare1fdb0e2009-07-28 22:40:46 +00001008
Kevin Enderby7d912182009-09-03 17:15:07 +00001009 RegNo = MatchRegisterName(Tok.getString());
Bruno Cardoso Lopesd65cd1d2010-07-23 22:15:26 +00001010
Chris Lattner1261b812010-09-22 04:11:10 +00001011 // If the match failed, try the register name as lowercase.
1012 if (RegNo == 0)
Benjamin Kramer20baffb2011-11-06 20:37:06 +00001013 RegNo = MatchRegisterName(Tok.getString().lower());
Michael J. Spencer530ce852010-10-09 11:00:50 +00001014
Michael Kupersteincdb076b2015-07-30 10:10:25 +00001015 // The "flags" register cannot be referenced directly.
1016 // Treat it as an identifier instead.
1017 if (isParsingInlineAsm() && isParsingIntelSyntax() && RegNo == X86::EFLAGS)
1018 RegNo = 0;
1019
Evan Chengeda1d4f2011-07-27 23:22:03 +00001020 if (!is64BitMode()) {
Eric Christopherc0a5aae2013-12-20 02:04:49 +00001021 // FIXME: This should be done using Requires<Not64BitMode> and
Evan Chengeda1d4f2011-07-27 23:22:03 +00001022 // Requires<In64BitMode> so "eiz" usage in 64-bit instructions can be also
1023 // checked.
1024 // FIXME: Check AH, CH, DH, BH cannot be used in an instruction requiring a
1025 // REX prefix.
1026 if (RegNo == X86::RIZ ||
1027 X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo) ||
1028 X86II::isX86_64NonExtLowByteReg(RegNo) ||
Craig Topper6acca802016-08-27 17:13:37 +00001029 X86II::isX86_64ExtendedReg(RegNo))
Benjamin Kramer1930b002011-10-16 12:10:27 +00001030 return Error(StartLoc, "register %"
1031 + Tok.getString() + " is only available in 64-bit mode",
Jordan Rosee8f1eae2013-01-07 19:00:49 +00001032 SMRange(StartLoc, EndLoc));
Craig Topper29c22732016-02-26 05:29:32 +00001033 } else if (!getSTI().getFeatureBits()[X86::FeatureAVX512]) {
1034 if (X86II::is32ExtendedReg(RegNo))
1035 return Error(StartLoc, "register %"
Craig Topperd50b5f82016-02-26 06:50:24 +00001036 + Tok.getString() + " is only available with AVX512",
Craig Topper29c22732016-02-26 05:29:32 +00001037 SMRange(StartLoc, EndLoc));
Evan Chengeda1d4f2011-07-27 23:22:03 +00001038 }
Bruno Cardoso Lopes306a1f92010-07-24 00:06:39 +00001039
Chris Lattner1261b812010-09-22 04:11:10 +00001040 // Parse "%st" as "%st(0)" and "%st(1)", which is multiple tokens.
1041 if (RegNo == 0 && (Tok.getString() == "st" || Tok.getString() == "ST")) {
Chris Lattnerd00faaa2010-02-09 00:49:22 +00001042 RegNo = X86::ST0;
Chris Lattnerd00faaa2010-02-09 00:49:22 +00001043 Parser.Lex(); // Eat 'st'
Bruno Cardoso Lopesd65cd1d2010-07-23 22:15:26 +00001044
Chris Lattnerd00faaa2010-02-09 00:49:22 +00001045 // Check to see if we have '(4)' after %st.
1046 if (getLexer().isNot(AsmToken::LParen))
1047 return false;
1048 // Lex the paren.
1049 getParser().Lex();
1050
1051 const AsmToken &IntTok = Parser.getTok();
1052 if (IntTok.isNot(AsmToken::Integer))
1053 return Error(IntTok.getLoc(), "expected stack index");
1054 switch (IntTok.getIntVal()) {
1055 case 0: RegNo = X86::ST0; break;
1056 case 1: RegNo = X86::ST1; break;
1057 case 2: RegNo = X86::ST2; break;
1058 case 3: RegNo = X86::ST3; break;
1059 case 4: RegNo = X86::ST4; break;
1060 case 5: RegNo = X86::ST5; break;
1061 case 6: RegNo = X86::ST6; break;
1062 case 7: RegNo = X86::ST7; break;
1063 default: return Error(IntTok.getLoc(), "invalid stack index");
1064 }
Bruno Cardoso Lopesd65cd1d2010-07-23 22:15:26 +00001065
Chris Lattnerd00faaa2010-02-09 00:49:22 +00001066 if (getParser().Lex().isNot(AsmToken::RParen))
1067 return Error(Parser.getTok().getLoc(), "expected ')'");
Bruno Cardoso Lopesd65cd1d2010-07-23 22:15:26 +00001068
Jordan Rosee8f1eae2013-01-07 19:00:49 +00001069 EndLoc = Parser.getTok().getEndLoc();
Chris Lattnerd00faaa2010-02-09 00:49:22 +00001070 Parser.Lex(); // Eat ')'
1071 return false;
1072 }
Bruno Cardoso Lopesd65cd1d2010-07-23 22:15:26 +00001073
Jordan Rosee8f1eae2013-01-07 19:00:49 +00001074 EndLoc = Parser.getTok().getEndLoc();
1075
Chris Lattner80486622010-06-24 07:29:18 +00001076 // If this is "db[0-7]", match it as an alias
1077 // for dr[0-7].
1078 if (RegNo == 0 && Tok.getString().size() == 3 &&
1079 Tok.getString().startswith("db")) {
1080 switch (Tok.getString()[2]) {
1081 case '0': RegNo = X86::DR0; break;
1082 case '1': RegNo = X86::DR1; break;
1083 case '2': RegNo = X86::DR2; break;
1084 case '3': RegNo = X86::DR3; break;
1085 case '4': RegNo = X86::DR4; break;
1086 case '5': RegNo = X86::DR5; break;
1087 case '6': RegNo = X86::DR6; break;
1088 case '7': RegNo = X86::DR7; break;
1089 }
Bruno Cardoso Lopesd65cd1d2010-07-23 22:15:26 +00001090
Chris Lattner80486622010-06-24 07:29:18 +00001091 if (RegNo != 0) {
Jordan Rosee8f1eae2013-01-07 19:00:49 +00001092 EndLoc = Parser.getTok().getEndLoc();
Chris Lattner80486622010-06-24 07:29:18 +00001093 Parser.Lex(); // Eat it.
1094 return false;
1095 }
1096 }
Bruno Cardoso Lopesd65cd1d2010-07-23 22:15:26 +00001097
Devang Patelce6a2ca2012-01-20 22:32:05 +00001098 if (RegNo == 0) {
Devang Patel9a9bb5c2012-01-30 20:02:42 +00001099 if (isParsingIntelSyntax()) return true;
Benjamin Kramer1930b002011-10-16 12:10:27 +00001100 return Error(StartLoc, "invalid register name",
Jordan Rosee8f1eae2013-01-07 19:00:49 +00001101 SMRange(StartLoc, EndLoc));
Devang Patelce6a2ca2012-01-20 22:32:05 +00001102 }
Daniel Dunbar00331992009-07-29 00:02:19 +00001103
Sean Callanana83fd7d2010-01-19 20:27:46 +00001104 Parser.Lex(); // Eat identifier token.
Daniel Dunbare1fdb0e2009-07-28 22:40:46 +00001105 return false;
Daniel Dunbar71475772009-07-17 20:42:00 +00001106}
1107
Yuri Gorshenin3939dec2014-09-10 09:45:49 +00001108void X86AsmParser::SetFrameRegister(unsigned RegNo) {
Yuri Gorshenine8c81fd2014-10-07 11:03:09 +00001109 Instrumentation->SetInitialFrameRegister(RegNo);
Yuri Gorshenin3939dec2014-09-10 09:45:49 +00001110}
1111
David Blaikie960ea3f2014-06-08 16:18:35 +00001112std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(SMLoc Loc) {
Nirav Dave6477ce22016-09-26 19:33:36 +00001113 bool Parse32 = is32BitMode() || Code16GCC;
1114 unsigned Basereg = is64BitMode() ? X86::RSI : (Parse32 ? X86::ESI : X86::SI);
Jim Grosbach13760bd2015-05-30 01:25:56 +00001115 const MCExpr *Disp = MCConstantExpr::create(0, getContext());
Craig Topper055845f2015-01-02 07:02:25 +00001116 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
Nirav Dave6477ce22016-09-26 19:33:36 +00001117 /*BaseReg=*/Basereg, /*IndexReg=*/0, /*Scale=*/1,
Craig Topper055845f2015-01-02 07:02:25 +00001118 Loc, Loc, 0);
David Woodhouse2ef8d9c2014-01-22 15:08:08 +00001119}
1120
David Blaikie960ea3f2014-06-08 16:18:35 +00001121std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand(SMLoc Loc) {
Nirav Dave6477ce22016-09-26 19:33:36 +00001122 bool Parse32 = is32BitMode() || Code16GCC;
1123 unsigned Basereg = is64BitMode() ? X86::RDI : (Parse32 ? X86::EDI : X86::DI);
Jim Grosbach13760bd2015-05-30 01:25:56 +00001124 const MCExpr *Disp = MCConstantExpr::create(0, getContext());
Craig Topper055845f2015-01-02 07:02:25 +00001125 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
Nirav Dave6477ce22016-09-26 19:33:36 +00001126 /*BaseReg=*/Basereg, /*IndexReg=*/0, /*Scale=*/1,
Craig Topper055845f2015-01-02 07:02:25 +00001127 Loc, Loc, 0);
David Woodhouseb33c2ef2014-01-22 15:08:21 +00001128}
1129
Marina Yatsinab9f4f622016-01-19 15:37:56 +00001130bool X86AsmParser::IsSIReg(unsigned Reg) {
1131 switch (Reg) {
Craig Topper4d187632016-02-26 05:29:39 +00001132 default: llvm_unreachable("Only (R|E)SI and (R|E)DI are expected!");
Marina Yatsinab9f4f622016-01-19 15:37:56 +00001133 case X86::RSI:
1134 case X86::ESI:
1135 case X86::SI:
1136 return true;
1137 case X86::RDI:
1138 case X86::EDI:
1139 case X86::DI:
1140 return false;
1141 }
1142}
1143
1144unsigned X86AsmParser::GetSIDIForRegClass(unsigned RegClassID, unsigned Reg,
1145 bool IsSIReg) {
1146 switch (RegClassID) {
Craig Topper4d187632016-02-26 05:29:39 +00001147 default: llvm_unreachable("Unexpected register class");
Marina Yatsinab9f4f622016-01-19 15:37:56 +00001148 case X86::GR64RegClassID:
1149 return IsSIReg ? X86::RSI : X86::RDI;
1150 case X86::GR32RegClassID:
1151 return IsSIReg ? X86::ESI : X86::EDI;
1152 case X86::GR16RegClassID:
1153 return IsSIReg ? X86::SI : X86::DI;
1154 }
1155}
1156
Michael Kupersteinffcc7662015-07-23 10:23:48 +00001157void X86AsmParser::AddDefaultSrcDestOperands(
1158 OperandVector& Operands, std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
1159 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst) {
1160 if (isParsingIntelSyntax()) {
1161 Operands.push_back(std::move(Dst));
1162 Operands.push_back(std::move(Src));
1163 }
1164 else {
1165 Operands.push_back(std::move(Src));
1166 Operands.push_back(std::move(Dst));
1167 }
1168}
1169
Marina Yatsinab9f4f622016-01-19 15:37:56 +00001170bool X86AsmParser::VerifyAndAdjustOperands(OperandVector &OrigOperands,
1171 OperandVector &FinalOperands) {
1172
1173 if (OrigOperands.size() > 1) {
Craig Topperd55f4bc2016-02-16 07:45:07 +00001174 // Check if sizes match, OrigOperands also contains the instruction name
Marina Yatsinab9f4f622016-01-19 15:37:56 +00001175 assert(OrigOperands.size() == FinalOperands.size() + 1 &&
Craig Topperd55f4bc2016-02-16 07:45:07 +00001176 "Operand size mismatch");
Marina Yatsinab9f4f622016-01-19 15:37:56 +00001177
Marina Yatsinaff262fa2016-01-21 11:37:06 +00001178 SmallVector<std::pair<SMLoc, std::string>, 2> Warnings;
Marina Yatsinab9f4f622016-01-19 15:37:56 +00001179 // Verify types match
1180 int RegClassID = -1;
1181 for (unsigned int i = 0; i < FinalOperands.size(); ++i) {
1182 X86Operand &OrigOp = static_cast<X86Operand &>(*OrigOperands[i + 1]);
1183 X86Operand &FinalOp = static_cast<X86Operand &>(*FinalOperands[i]);
1184
1185 if (FinalOp.isReg() &&
1186 (!OrigOp.isReg() || FinalOp.getReg() != OrigOp.getReg()))
1187 // Return false and let a normal complaint about bogus operands happen
1188 return false;
1189
1190 if (FinalOp.isMem()) {
1191
1192 if (!OrigOp.isMem())
1193 // Return false and let a normal complaint about bogus operands happen
1194 return false;
1195
1196 unsigned OrigReg = OrigOp.Mem.BaseReg;
1197 unsigned FinalReg = FinalOp.Mem.BaseReg;
1198
1199 // If we've already encounterd a register class, make sure all register
1200 // bases are of the same register class
1201 if (RegClassID != -1 &&
1202 !X86MCRegisterClasses[RegClassID].contains(OrigReg)) {
1203 return Error(OrigOp.getStartLoc(),
1204 "mismatching source and destination index registers");
1205 }
1206
1207 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(OrigReg))
1208 RegClassID = X86::GR64RegClassID;
1209 else if (X86MCRegisterClasses[X86::GR32RegClassID].contains(OrigReg))
1210 RegClassID = X86::GR32RegClassID;
1211 else if (X86MCRegisterClasses[X86::GR16RegClassID].contains(OrigReg))
1212 RegClassID = X86::GR16RegClassID;
Marina Yatsina701938d2016-01-20 14:03:47 +00001213 else
Craig Topper5a62f7e2016-02-16 07:28:03 +00001214 // Unexpected register class type
Marina Yatsina701938d2016-01-20 14:03:47 +00001215 // Return false and let a normal complaint about bogus operands happen
1216 return false;
Marina Yatsinab9f4f622016-01-19 15:37:56 +00001217
1218 bool IsSI = IsSIReg(FinalReg);
1219 FinalReg = GetSIDIForRegClass(RegClassID, FinalReg, IsSI);
1220
1221 if (FinalReg != OrigReg) {
1222 std::string RegName = IsSI ? "ES:(R|E)SI" : "ES:(R|E)DI";
Marina Yatsinaff262fa2016-01-21 11:37:06 +00001223 Warnings.push_back(std::make_pair(
1224 OrigOp.getStartLoc(),
1225 "memory operand is only for determining the size, " + RegName +
1226 " will be used for the location"));
Marina Yatsinab9f4f622016-01-19 15:37:56 +00001227 }
1228
1229 FinalOp.Mem.Size = OrigOp.Mem.Size;
1230 FinalOp.Mem.SegReg = OrigOp.Mem.SegReg;
1231 FinalOp.Mem.BaseReg = FinalReg;
1232 }
1233 }
1234
Marina Yatsinaff262fa2016-01-21 11:37:06 +00001235 // Produce warnings only if all the operands passed the adjustment - prevent
1236 // legal cases like "movsd (%rax), %xmm0" mistakenly produce warnings
Craig Topper16d7eb22016-02-16 07:45:04 +00001237 for (auto &WarningMsg : Warnings) {
1238 Warning(WarningMsg.first, WarningMsg.second);
Marina Yatsinaff262fa2016-01-21 11:37:06 +00001239 }
1240
1241 // Remove old operands
Marina Yatsinab9f4f622016-01-19 15:37:56 +00001242 for (unsigned int i = 0; i < FinalOperands.size(); ++i)
1243 OrigOperands.pop_back();
1244 }
1245 // OrigOperands.append(FinalOperands.begin(), FinalOperands.end());
1246 for (unsigned int i = 0; i < FinalOperands.size(); ++i)
1247 OrigOperands.push_back(std::move(FinalOperands[i]));
1248
1249 return false;
1250}
1251
David Blaikie960ea3f2014-06-08 16:18:35 +00001252std::unique_ptr<X86Operand> X86AsmParser::ParseOperand() {
Devang Patel9a9bb5c2012-01-30 20:02:42 +00001253 if (isParsingIntelSyntax())
Devang Patel46831de2012-01-12 01:36:43 +00001254 return ParseIntelOperand();
1255 return ParseATTOperand();
1256}
1257
David Blaikie960ea3f2014-06-08 16:18:35 +00001258std::unique_ptr<X86Operand> X86AsmParser::CreateMemForInlineAsm(
1259 unsigned SegReg, const MCExpr *Disp, unsigned BaseReg, unsigned IndexReg,
1260 unsigned Scale, SMLoc Start, SMLoc End, unsigned Size, StringRef Identifier,
Coby Tayreed8912892017-08-24 08:46:25 +00001261 InlineAsmIdentifierInfo &Info) {
Reid Kleckner5b37c182014-08-01 20:21:24 +00001262 // If we found a decl other than a VarDecl, then assume it is a FuncDecl or
1263 // some other label reference.
Eric Christopheradfe5362017-07-25 19:22:09 +00001264 if (isa<MCSymbolRefExpr>(Disp) && Info.OpDecl && !Info.IsVarDecl) {
Reid Kleckner5b37c182014-08-01 20:21:24 +00001265 // Insert an explicit size if the user didn't have one.
1266 if (!Size) {
1267 Size = getPointerWidth();
Craig Topper7d5b2312015-10-10 05:25:02 +00001268 InstInfo->AsmRewrites->emplace_back(AOK_SizeDirective, Start,
1269 /*Len=*/0, Size);
Reid Kleckner5b37c182014-08-01 20:21:24 +00001270 }
1271
1272 // Create an absolute memory reference in order to match against
1273 // instructions taking a PC relative operand.
Craig Topper055845f2015-01-02 07:02:25 +00001274 return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size,
1275 Identifier, Info.OpDecl);
Reid Klecknerd84e70e2014-03-04 00:33:17 +00001276 }
1277
Reid Kleckner6d2ea6e2017-05-04 18:19:52 +00001278
Reid Klecknerd84e70e2014-03-04 00:33:17 +00001279 // We either have a direct symbol reference, or an offset from a symbol. The
1280 // parser always puts the symbol on the LHS, so look there for size
1281 // calculation purposes.
Reid Kleckner6d2ea6e2017-05-04 18:19:52 +00001282 unsigned FrontendSize = 0;
Reid Klecknerd84e70e2014-03-04 00:33:17 +00001283 const MCBinaryExpr *BinOp = dyn_cast<MCBinaryExpr>(Disp);
1284 bool IsSymRef =
1285 isa<MCSymbolRefExpr>(BinOp ? BinOp->getLHS() : Disp);
Reid Kleckner6d2ea6e2017-05-04 18:19:52 +00001286 if (IsSymRef && !Size && Info.Type)
1287 FrontendSize = Info.Type * 8; // Size is in terms of bits in this context.
Chad Rosier7ca135b2013-03-19 21:11:56 +00001288
Chad Rosier7ca135b2013-03-19 21:11:56 +00001289 // When parsing inline assembly we set the base register to a non-zero value
Chad Rosier175d0ae2013-04-12 18:21:18 +00001290 // if we don't know the actual value at this time. This is necessary to
Chad Rosier7ca135b2013-03-19 21:11:56 +00001291 // get the matching correct in some cases.
Chad Rosier175d0ae2013-04-12 18:21:18 +00001292 BaseReg = BaseReg ? BaseReg : 1;
Craig Topper055845f2015-01-02 07:02:25 +00001293 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
1294 IndexReg, Scale, Start, End, Size, Identifier,
Reid Kleckner6d2ea6e2017-05-04 18:19:52 +00001295 Info.OpDecl, FrontendSize);
Chad Rosier7ca135b2013-03-19 21:11:56 +00001296}
1297
Coby Tayree2cb497a2017-04-04 14:43:23 +00001298// Some binary bitwise operators have a named synonymous
1299// Query a candidate string for being such a named operator
1300// and if so - invoke the appropriate handler
1301bool X86AsmParser::ParseIntelNamedOperator(StringRef Name, IntelExprStateMachine &SM) {
1302 // A named operator should be either lower or upper case, but not a mix
1303 if (Name.compare(Name.lower()) && Name.compare(Name.upper()))
1304 return false;
1305 if (Name.equals_lower("not"))
1306 SM.onNot();
1307 else if (Name.equals_lower("or"))
1308 SM.onOr();
1309 else if (Name.equals_lower("shl"))
1310 SM.onLShift();
1311 else if (Name.equals_lower("shr"))
1312 SM.onRShift();
1313 else if (Name.equals_lower("xor"))
1314 SM.onXor();
1315 else if (Name.equals_lower("and"))
1316 SM.onAnd();
Coby Tayree41a5b552017-06-27 16:58:27 +00001317 else if (Name.equals_lower("mod"))
1318 SM.onMod();
Coby Tayree2cb497a2017-04-04 14:43:23 +00001319 else
1320 return false;
1321 return true;
1322}
1323
Benjamin Kramer951b15e2013-12-01 11:47:42 +00001324bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
Rafael Espindola961d4692014-11-11 05:18:41 +00001325 MCAsmParser &Parser = getParser();
Chad Rosier6844ea02012-10-24 22:13:37 +00001326 const AsmToken &Tok = Parser.getTok();
Andrew V. Tischenko32e9b1a2017-07-25 13:05:12 +00001327 StringRef ErrMsg;
Chad Rosier51afe632012-06-27 22:34:28 +00001328
Marina Yatsina8dfd5cb2015-12-24 12:09:51 +00001329 AsmToken::TokenKind PrevTK = AsmToken::Error;
Chad Rosier5c118fd2013-01-14 22:31:35 +00001330 bool Done = false;
Chad Rosier5c118fd2013-01-14 22:31:35 +00001331 while (!Done) {
1332 bool UpdateLocLex = true;
Andrew V. Tischenkofdb264e2017-05-26 13:23:34 +00001333 AsmToken::TokenKind TK = getLexer().getKind();
Chad Rosier5c118fd2013-01-14 22:31:35 +00001334
David Majnemer6a5b8122014-06-19 01:25:43 +00001335 switch (TK) {
Coby Tayreed8912892017-08-24 08:46:25 +00001336 default:
1337 if ((Done = SM.isValidEndState()))
Chad Rosier5c118fd2013-01-14 22:31:35 +00001338 break;
Benjamin Kramer951b15e2013-12-01 11:47:42 +00001339 return Error(Tok.getLoc(), "unknown token in expression");
Coby Tayreed8912892017-08-24 08:46:25 +00001340 case AsmToken::EndOfStatement:
Chad Rosierbfb70992013-04-17 00:11:46 +00001341 Done = true;
1342 break;
Coby Tayreed8912892017-08-24 08:46:25 +00001343 case AsmToken::Real:
1344 // DotOperator: [ebx].0
1345 UpdateLocLex = false;
1346 if (ParseIntelDotOperator(SM, End))
1347 return true;
1348 break;
David Majnemer6a5b8122014-06-19 01:25:43 +00001349 case AsmToken::String:
Chad Rosier5c118fd2013-01-14 22:31:35 +00001350 case AsmToken::Identifier: {
Chad Rosier175d0ae2013-04-12 18:21:18 +00001351 // This could be a register or a symbolic displacement.
1352 unsigned TmpReg;
Chad Rosier95ce8892013-04-19 18:39:50 +00001353 const MCExpr *Val;
Chad Rosier152749c2013-04-12 18:54:20 +00001354 SMLoc IdentLoc = Tok.getLoc();
1355 StringRef Identifier = Tok.getString();
Coby Tayree07a89742017-03-21 19:31:55 +00001356 UpdateLocLex = false;
David Majnemer6a5b8122014-06-19 01:25:43 +00001357 if (TK != AsmToken::String && !ParseRegister(TmpReg, IdentLoc, End)) {
Andrew V. Tischenko32e9b1a2017-07-25 13:05:12 +00001358 if (SM.onRegister(TmpReg, ErrMsg))
1359 return Error(Tok.getLoc(), ErrMsg);
Coby Tayree2cb497a2017-04-04 14:43:23 +00001360 } else if (ParseIntelNamedOperator(Identifier, SM)) {
1361 UpdateLocLex = true;
Coby Tayree07a89742017-03-21 19:31:55 +00001362 } else if (!isParsingInlineAsm()) {
1363 if (getParser().parsePrimaryExpr(Val, End))
1364 return Error(Tok.getLoc(), "Unexpected identifier!");
Coby Tayreed8912892017-08-24 08:46:25 +00001365 if (auto *CE = dyn_cast<MCConstantExpr>(Val)) {
1366 if (SM.onInteger(CE->getValue(), ErrMsg))
1367 return Error(IdentLoc, ErrMsg);
1368 } else if (SM.onIdentifierExpr(Val, Identifier, ErrMsg))
1369 return Error(IdentLoc, ErrMsg);
1370 } else if (unsigned OpKind = IdentifyIntelInlineAsmOperator(Identifier)) {
1371 if (OpKind == IOK_OFFSET)
Coby Tayree07a89742017-03-21 19:31:55 +00001372 return Error(IdentLoc, "Dealing OFFSET operator as part of"
1373 "a compound immediate expression is yet to be supported");
Coby Tayreed8912892017-08-24 08:46:25 +00001374 int64_t Val = ParseIntelInlineAsmOperator(OpKind);
Coby Tayree07a89742017-03-21 19:31:55 +00001375 if (!Val)
1376 return true;
Coby Tayree07a89742017-03-21 19:31:55 +00001377 if (SM.onInteger(Val, ErrMsg))
1378 return Error(IdentLoc, ErrMsg);
Coby Tayreed8912892017-08-24 08:46:25 +00001379 } else if (Identifier.count('.') && PrevTK == AsmToken::RBrac) {
1380 if (ParseIntelDotOperator(SM, End))
1381 return true;
1382 } else if (ParseIntelInlineAsmIdentifier(Val, Identifier,
1383 SM.getIdentifierInfo(),
1384 /*Unevaluated=*/false, End)) {
1385 return true;
1386 } else if (SM.onIdentifierExpr(Val, Identifier, ErrMsg)) {
1387 return Error(IdentLoc, ErrMsg);
Chad Rosier5c118fd2013-01-14 22:31:35 +00001388 }
Coby Tayree07a89742017-03-21 19:31:55 +00001389 break;
Chad Rosier5c118fd2013-01-14 22:31:35 +00001390 }
Kevin Enderby36eba252013-12-19 23:16:14 +00001391 case AsmToken::Integer: {
Kevin Enderby36eba252013-12-19 23:16:14 +00001392 // Look for 'b' or 'f' following an Integer as a directional label
1393 SMLoc Loc = getTok().getLoc();
1394 int64_t IntVal = getTok().getIntVal();
1395 End = consumeToken();
1396 UpdateLocLex = false;
1397 if (getLexer().getKind() == AsmToken::Identifier) {
1398 StringRef IDVal = getTok().getString();
1399 if (IDVal == "f" || IDVal == "b") {
1400 MCSymbol *Sym =
Jim Grosbach6f482002015-05-18 18:43:14 +00001401 getContext().getDirectionalLocalSymbol(IntVal, IDVal == "b");
Kevin Enderby36eba252013-12-19 23:16:14 +00001402 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
Michael Liao5bf95782014-12-04 05:20:33 +00001403 const MCExpr *Val =
NAKAMURA Takumi0a7d0ad2015-09-22 11:15:07 +00001404 MCSymbolRefExpr::create(Sym, Variant, getContext());
Kevin Enderby36eba252013-12-19 23:16:14 +00001405 if (IDVal == "b" && Sym->isUndefined())
1406 return Error(Loc, "invalid reference to undefined symbol");
1407 StringRef Identifier = Sym->getName();
Coby Tayreed8912892017-08-24 08:46:25 +00001408 if (SM.onIdentifierExpr(Val, Identifier, ErrMsg))
1409 return Error(Loc, ErrMsg);
Kevin Enderby36eba252013-12-19 23:16:14 +00001410 End = consumeToken();
1411 } else {
Kevin Enderby9d117022014-01-23 21:52:41 +00001412 if (SM.onInteger(IntVal, ErrMsg))
1413 return Error(Loc, ErrMsg);
Kevin Enderby36eba252013-12-19 23:16:14 +00001414 }
1415 } else {
Kevin Enderby9d117022014-01-23 21:52:41 +00001416 if (SM.onInteger(IntVal, ErrMsg))
1417 return Error(Loc, ErrMsg);
Kevin Enderby36eba252013-12-19 23:16:14 +00001418 }
Chad Rosier5c118fd2013-01-14 22:31:35 +00001419 break;
Kevin Enderby36eba252013-12-19 23:16:14 +00001420 }
Andrew V. Tischenko32e9b1a2017-07-25 13:05:12 +00001421 case AsmToken::Plus:
1422 if (SM.onPlus(ErrMsg))
1423 return Error(getTok().getLoc(), ErrMsg);
1424 break;
1425 case AsmToken::Minus:
1426 if (SM.onMinus(ErrMsg))
1427 return Error(getTok().getLoc(), ErrMsg);
1428 break;
Ehsan Akhgari4103da62014-07-04 19:13:05 +00001429 case AsmToken::Tilde: SM.onNot(); break;
Chad Rosier5c118fd2013-01-14 22:31:35 +00001430 case AsmToken::Star: SM.onStar(); break;
Chad Rosier4a7005e2013-04-05 16:28:55 +00001431 case AsmToken::Slash: SM.onDivide(); break;
Kevin Enderby2e13b1c2014-01-15 19:05:24 +00001432 case AsmToken::Pipe: SM.onOr(); break;
Michael Kupersteine3de07a2015-06-14 12:59:45 +00001433 case AsmToken::Caret: SM.onXor(); break;
Kevin Enderby2e13b1c2014-01-15 19:05:24 +00001434 case AsmToken::Amp: SM.onAnd(); break;
Kevin Enderbyd6b10712014-02-06 01:21:15 +00001435 case AsmToken::LessLess:
1436 SM.onLShift(); break;
1437 case AsmToken::GreaterGreater:
1438 SM.onRShift(); break;
Coby Tayreed8912892017-08-24 08:46:25 +00001439 case AsmToken::LBrac:
1440 if (SM.onLBrac())
1441 return Error(Tok.getLoc(), "unexpected bracket encountered");
1442 break;
1443 case AsmToken::RBrac:
1444 if (SM.onRBrac())
1445 return Error(Tok.getLoc(), "unexpected bracket encountered");
1446 break;
Chad Rosier4a7005e2013-04-05 16:28:55 +00001447 case AsmToken::LParen: SM.onLParen(); break;
1448 case AsmToken::RParen: SM.onRParen(); break;
Chad Rosier5c118fd2013-01-14 22:31:35 +00001449 }
Chad Rosier31246272013-04-17 21:01:45 +00001450 if (SM.hadError())
Benjamin Kramer951b15e2013-12-01 11:47:42 +00001451 return Error(Tok.getLoc(), "unknown token in expression");
Chad Rosier31246272013-04-17 21:01:45 +00001452
Alp Tokera5b88a52013-12-02 16:06:06 +00001453 if (!Done && UpdateLocLex)
1454 End = consumeToken();
Marina Yatsina8dfd5cb2015-12-24 12:09:51 +00001455
1456 PrevTK = TK;
Devang Patel41b9dde2012-01-17 18:00:18 +00001457 }
Benjamin Kramer951b15e2013-12-01 11:47:42 +00001458 return false;
Chad Rosier5362af92013-04-16 18:15:40 +00001459}
1460
Coby Tayreed8912892017-08-24 08:46:25 +00001461void X86AsmParser::RewriteIntelExpression(IntelExprStateMachine &SM,
1462 SMLoc Start, SMLoc End) {
1463 SMLoc Loc = Start;
1464 unsigned ExprLen = End.getPointer() - Start.getPointer();
1465 // Skip everything before a symbol displacement (if we have one)
1466 if (SM.getSym()) {
1467 StringRef SymName = SM.getSymName();
1468 if (unsigned Len = SymName.data() - Start.getPointer())
1469 InstInfo->AsmRewrites->emplace_back(AOK_Skip, Start, Len);
1470 Loc = SMLoc::getFromPointer(SymName.data() + SymName.size());
1471 ExprLen = End.getPointer() - (SymName.data() + SymName.size());
1472 // If we have only a symbol than there's no need for complex rewrite,
1473 // simply skip everything after it
1474 if (!(SM.getBaseReg() || SM.getIndexReg() || SM.getImm())) {
1475 if (ExprLen)
1476 InstInfo->AsmRewrites->emplace_back(AOK_Skip, Loc, ExprLen);
1477 return;
Nirav Dave8601ac12016-08-02 17:56:03 +00001478 }
1479 }
Coby Tayreed8912892017-08-24 08:46:25 +00001480 // Build an Intel Expression rewrite
1481 StringRef BaseRegStr;
1482 StringRef IndexRegStr;
1483 if (SM.getBaseReg())
1484 BaseRegStr = X86IntelInstPrinter::getRegisterName(SM.getBaseReg());
1485 if (SM.getIndexReg())
1486 IndexRegStr = X86IntelInstPrinter::getRegisterName(SM.getIndexReg());
1487 // Emit it
1488 IntelExpr Expr(BaseRegStr, IndexRegStr, SM.getScale(), SM.getImm(), SM.isMemExpr());
1489 InstInfo->AsmRewrites->emplace_back(Loc, ExprLen, Expr);
Devang Patel41b9dde2012-01-17 18:00:18 +00001490}
1491
Chad Rosier8a244662013-04-02 20:02:33 +00001492// Inline assembly may use variable names with namespace alias qualifiers.
Coby Tayreed8912892017-08-24 08:46:25 +00001493bool X86AsmParser::ParseIntelInlineAsmIdentifier(const MCExpr *&Val,
1494 StringRef &Identifier,
1495 InlineAsmIdentifierInfo &Info,
1496 bool IsUnevaluatedOperand,
1497 SMLoc &End) {
Rafael Espindola961d4692014-11-11 05:18:41 +00001498 MCAsmParser &Parser = getParser();
Reid Klecknerc2b92542015-08-26 21:57:25 +00001499 assert(isParsingInlineAsm() && "Expected to be parsing inline assembly.");
Craig Topper062a2ba2014-04-25 05:30:21 +00001500 Val = nullptr;
Chad Rosier8a244662013-04-02 20:02:33 +00001501
Chad Rosiercb78f0d2013-04-22 19:42:15 +00001502 StringRef LineBuf(Identifier.data());
Ehsan Akhgaridb0e7062014-09-22 02:21:35 +00001503 void *Result =
1504 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);
Chad Rosiercb78f0d2013-04-22 19:42:15 +00001505
Chad Rosier8a244662013-04-02 20:02:33 +00001506 const AsmToken &Tok = Parser.getTok();
Ehsan Akhgaridb0e7062014-09-22 02:21:35 +00001507 SMLoc Loc = Tok.getLoc();
John McCallf73981b2013-05-03 00:15:41 +00001508
1509 // Advance the token stream until the end of the current token is
1510 // after the end of what the frontend claimed.
1511 const char *EndPtr = Tok.getLoc().getPointer() + LineBuf.size();
Reid Klecknerc2b92542015-08-26 21:57:25 +00001512 do {
John McCallf73981b2013-05-03 00:15:41 +00001513 End = Tok.getEndLoc();
1514 getLexer().Lex();
Reid Klecknerc2b92542015-08-26 21:57:25 +00001515 } while (End.getPointer() < EndPtr);
Ehsan Akhgaridb0e7062014-09-22 02:21:35 +00001516 Identifier = LineBuf;
1517
Reid Klecknerc2b92542015-08-26 21:57:25 +00001518 // The frontend should end parsing on an assembler token boundary, unless it
1519 // failed parsing.
1520 assert((End.getPointer() == EndPtr || !Result) &&
1521 "frontend claimed part of a token?");
1522
Ehsan Akhgaridb0e7062014-09-22 02:21:35 +00001523 // If the identifier lookup was unsuccessful, assume that we are dealing with
1524 // a label.
1525 if (!Result) {
Ehsan Akhgaribb6bb072014-09-22 20:40:36 +00001526 StringRef InternalName =
1527 SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(),
1528 Loc, false);
1529 assert(InternalName.size() && "We should have an internal name here.");
1530 // Push a rewrite for replacing the identifier name with the internal name.
Craig Topper7d5b2312015-10-10 05:25:02 +00001531 InstInfo->AsmRewrites->emplace_back(AOK_Label, Loc, Identifier.size(),
1532 InternalName);
Ehsan Akhgaridb0e7062014-09-22 02:21:35 +00001533 }
Chad Rosiercb78f0d2013-04-22 19:42:15 +00001534
1535 // Create the symbol reference.
Jim Grosbach6f482002015-05-18 18:43:14 +00001536 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
Chad Rosier8a244662013-04-02 20:02:33 +00001537 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
Jim Grosbach13760bd2015-05-30 01:25:56 +00001538 Val = MCSymbolRefExpr::create(Sym, Variant, getParser().getContext());
Benjamin Kramer951b15e2013-12-01 11:47:42 +00001539 return false;
Chad Rosier8a244662013-04-02 20:02:33 +00001540}
1541
Elena Demikhovsky18fd4962015-03-02 15:00:34 +00001542//ParseRoundingModeOp - Parse AVX-512 rounding mode operand
1543std::unique_ptr<X86Operand>
1544X86AsmParser::ParseRoundingModeOp(SMLoc Start, SMLoc End) {
1545 MCAsmParser &Parser = getParser();
1546 const AsmToken &Tok = Parser.getTok();
Elena Demikhovsky29792e92015-05-07 11:24:42 +00001547 // Eat "{" and mark the current place.
1548 const SMLoc consumedToken = consumeToken();
Elena Demikhovsky18fd4962015-03-02 15:00:34 +00001549 if (Tok.getIdentifier().startswith("r")){
1550 int rndMode = StringSwitch<int>(Tok.getIdentifier())
1551 .Case("rn", X86::STATIC_ROUNDING::TO_NEAREST_INT)
1552 .Case("rd", X86::STATIC_ROUNDING::TO_NEG_INF)
1553 .Case("ru", X86::STATIC_ROUNDING::TO_POS_INF)
1554 .Case("rz", X86::STATIC_ROUNDING::TO_ZERO)
1555 .Default(-1);
1556 if (-1 == rndMode)
1557 return ErrorOperand(Tok.getLoc(), "Invalid rounding mode.");
1558 Parser.Lex(); // Eat "r*" of r*-sae
1559 if (!getLexer().is(AsmToken::Minus))
1560 return ErrorOperand(Tok.getLoc(), "Expected - at this point");
1561 Parser.Lex(); // Eat "-"
1562 Parser.Lex(); // Eat the sae
1563 if (!getLexer().is(AsmToken::RCurly))
1564 return ErrorOperand(Tok.getLoc(), "Expected } at this point");
1565 Parser.Lex(); // Eat "}"
1566 const MCExpr *RndModeOp =
Jim Grosbach13760bd2015-05-30 01:25:56 +00001567 MCConstantExpr::create(rndMode, Parser.getContext());
Elena Demikhovsky18fd4962015-03-02 15:00:34 +00001568 return X86Operand::CreateImm(RndModeOp, Start, End);
1569 }
Elena Demikhovsky29792e92015-05-07 11:24:42 +00001570 if(Tok.getIdentifier().equals("sae")){
1571 Parser.Lex(); // Eat the sae
1572 if (!getLexer().is(AsmToken::RCurly))
1573 return ErrorOperand(Tok.getLoc(), "Expected } at this point");
1574 Parser.Lex(); // Eat "}"
1575 return X86Operand::CreateToken("{sae}", consumedToken);
1576 }
Elena Demikhovsky18fd4962015-03-02 15:00:34 +00001577 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1578}
Chad Rosier91c82662012-10-24 17:22:29 +00001579
Chad Rosier5dcb4662012-10-24 22:21:50 +00001580/// Parse the '.' operator.
Coby Tayreed8912892017-08-24 08:46:25 +00001581bool X86AsmParser::ParseIntelDotOperator(IntelExprStateMachine &SM, SMLoc &End) {
1582 const AsmToken &Tok = getTok();
1583 unsigned Offset;
Chad Rosier5dcb4662012-10-24 22:21:50 +00001584
Reid Kleckner94a1c4d2014-03-06 19:19:12 +00001585 // Drop the optional '.'.
1586 StringRef DotDispStr = Tok.getString();
1587 if (DotDispStr.startswith("."))
1588 DotDispStr = DotDispStr.drop_front(1);
Chad Rosier5dcb4662012-10-24 22:21:50 +00001589
Chad Rosier5dcb4662012-10-24 22:21:50 +00001590 // .Imm gets lexed as a real.
1591 if (Tok.is(AsmToken::Real)) {
1592 APInt DotDisp;
1593 DotDispStr.getAsInteger(10, DotDisp);
Coby Tayreed8912892017-08-24 08:46:25 +00001594 Offset = DotDisp.getZExtValue();
Chad Rosiercc541e82013-04-19 15:57:00 +00001595 } else if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) {
Chad Rosier240b7b92012-10-25 21:51:10 +00001596 std::pair<StringRef, StringRef> BaseMember = DotDispStr.split('.');
1597 if (SemaCallback->LookupInlineAsmField(BaseMember.first, BaseMember.second,
Coby Tayreed8912892017-08-24 08:46:25 +00001598 Offset))
Benjamin Kramer951b15e2013-12-01 11:47:42 +00001599 return Error(Tok.getLoc(), "Unable to lookup field reference!");
Chad Rosiercc541e82013-04-19 15:57:00 +00001600 } else
Benjamin Kramer951b15e2013-12-01 11:47:42 +00001601 return Error(Tok.getLoc(), "Unexpected token type!");
Chad Rosier911c1f32012-10-25 17:37:43 +00001602
Coby Tayreed8912892017-08-24 08:46:25 +00001603 // Eat the DotExpression and update End
1604 End = SMLoc::getFromPointer(DotDispStr.data());
1605 const char *DotExprEndLoc = DotDispStr.data() + DotDispStr.size();
1606 while (Tok.getLoc().getPointer() < DotExprEndLoc)
1607 Lex();
1608 SM.addImm(Offset);
Benjamin Kramer951b15e2013-12-01 11:47:42 +00001609 return false;
Chad Rosier5dcb4662012-10-24 22:21:50 +00001610}
1611
Chad Rosier91c82662012-10-24 17:22:29 +00001612/// Parse the 'offset' operator. This operator is used to specify the
1613/// location rather then the content of a variable.
David Blaikie960ea3f2014-06-08 16:18:35 +00001614std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOffsetOfOperator() {
Rafael Espindola961d4692014-11-11 05:18:41 +00001615 MCAsmParser &Parser = getParser();
Chad Rosier18785852013-04-09 20:58:48 +00001616 const AsmToken &Tok = Parser.getTok();
Chad Rosier10d1d1c2013-04-09 20:44:09 +00001617 SMLoc OffsetOfLoc = Tok.getLoc();
Chad Rosier91c82662012-10-24 17:22:29 +00001618 Parser.Lex(); // Eat offset.
Chad Rosier91c82662012-10-24 17:22:29 +00001619
Chad Rosier91c82662012-10-24 17:22:29 +00001620 const MCExpr *Val;
Chad Rosiercb78f0d2013-04-22 19:42:15 +00001621 InlineAsmIdentifierInfo Info;
Chad Rosier18785852013-04-09 20:58:48 +00001622 SMLoc Start = Tok.getLoc(), End;
Chad Rosierae7ecd62013-04-11 23:37:34 +00001623 StringRef Identifier = Tok.getString();
Coby Tayreed8912892017-08-24 08:46:25 +00001624 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
1625 /*Unevaluated=*/false, End))
Craig Topper062a2ba2014-04-25 05:30:21 +00001626 return nullptr;
Chad Rosierae7ecd62013-04-11 23:37:34 +00001627
Chad Rosiere2f03772012-10-26 16:09:20 +00001628 // Don't emit the offset operator.
Craig Topper7d5b2312015-10-10 05:25:02 +00001629 InstInfo->AsmRewrites->emplace_back(AOK_Skip, OffsetOfLoc, 7);
Chad Rosiere2f03772012-10-26 16:09:20 +00001630
Chad Rosier91c82662012-10-24 17:22:29 +00001631 // The offset operator will have an 'r' constraint, thus we need to create
1632 // register operand to ensure proper matching. Just pick a GPR based on
1633 // the size of a pointer.
Nirav Dave6477ce22016-09-26 19:33:36 +00001634 bool Parse32 = is32BitMode() || Code16GCC;
1635 unsigned RegNo = is64BitMode() ? X86::RBX : (Parse32 ? X86::EBX : X86::BX);
1636
Chad Rosiera4bc9432013-01-10 22:10:27 +00001637 return X86Operand::CreateReg(RegNo, Start, End, /*GetAddress=*/true,
Peter Collingbourne0da86302016-10-10 22:49:37 +00001638 OffsetOfLoc, Identifier, Info.OpDecl);
Devang Patel41b9dde2012-01-17 18:00:18 +00001639}
1640
Coby Tayree07a89742017-03-21 19:31:55 +00001641// Query a candidate string for being an Intel assembly operator
1642// Report back its kind, or IOK_INVALID if does not evaluated as a known one
Coby Tayreed8912892017-08-24 08:46:25 +00001643unsigned X86AsmParser::IdentifyIntelInlineAsmOperator(StringRef Name) {
Coby Tayree07a89742017-03-21 19:31:55 +00001644 return StringSwitch<unsigned>(Name)
1645 .Cases("TYPE","type",IOK_TYPE)
1646 .Cases("SIZE","size",IOK_SIZE)
1647 .Cases("LENGTH","length",IOK_LENGTH)
1648 .Cases("OFFSET","offset",IOK_OFFSET)
1649 .Default(IOK_INVALID);
1650}
Chad Rosierd0ed73a2013-01-17 19:21:48 +00001651
1652/// Parse the 'LENGTH', 'TYPE' and 'SIZE' operators. The LENGTH operator
1653/// returns the number of elements in an array. It returns the value 1 for
1654/// non-array variables. The SIZE operator returns the size of a C or C++
1655/// variable. A variable's size is the product of its LENGTH and TYPE. The
1656/// TYPE operator returns the size of a C or C++ type or variable. If the
1657/// variable is an array, TYPE returns the size of a single element.
Coby Tayreed8912892017-08-24 08:46:25 +00001658unsigned X86AsmParser::ParseIntelInlineAsmOperator(unsigned OpKind) {
Rafael Espindola961d4692014-11-11 05:18:41 +00001659 MCAsmParser &Parser = getParser();
Chad Rosier18785852013-04-09 20:58:48 +00001660 const AsmToken &Tok = Parser.getTok();
Chad Rosier10d1d1c2013-04-09 20:44:09 +00001661 Parser.Lex(); // Eat operator.
Chad Rosier11c42f22012-10-26 18:04:20 +00001662
Craig Topper062a2ba2014-04-25 05:30:21 +00001663 const MCExpr *Val = nullptr;
Chad Rosiercb78f0d2013-04-22 19:42:15 +00001664 InlineAsmIdentifierInfo Info;
Chad Rosier18785852013-04-09 20:58:48 +00001665 SMLoc Start = Tok.getLoc(), End;
Chad Rosierb67f8052013-04-11 23:57:04 +00001666 StringRef Identifier = Tok.getString();
Coby Tayreed8912892017-08-24 08:46:25 +00001667 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
1668 /*Unevaluated=*/true, End))
Coby Tayree07a89742017-03-21 19:31:55 +00001669 return 0;
Benjamin Kramer951b15e2013-12-01 11:47:42 +00001670
Coby Tayree07a89742017-03-21 19:31:55 +00001671 if (!Info.OpDecl) {
1672 Error(Start, "unable to lookup expression");
1673 return 0;
1674 }
Coby Tayreed8912892017-08-24 08:46:25 +00001675
Chad Rosierf6675c32013-04-22 17:01:46 +00001676 unsigned CVal = 0;
Chad Rosiercb78f0d2013-04-22 19:42:15 +00001677 switch(OpKind) {
1678 default: llvm_unreachable("Unexpected operand kind!");
1679 case IOK_LENGTH: CVal = Info.Length; break;
1680 case IOK_SIZE: CVal = Info.Size; break;
1681 case IOK_TYPE: CVal = Info.Type; break;
1682 }
Eric Christopheradfe5362017-07-25 19:22:09 +00001683
Coby Tayree07a89742017-03-21 19:31:55 +00001684 return CVal;
Chad Rosier11c42f22012-10-26 18:04:20 +00001685}
1686
Coby Tayreed8912892017-08-24 08:46:25 +00001687bool X86AsmParser::ParseIntelMemoryOperandSize(unsigned &Size) {
1688 Size = StringSwitch<unsigned>(getTok().getString())
1689 .Cases("BYTE", "byte", 8)
1690 .Cases("WORD", "word", 16)
1691 .Cases("DWORD", "dword", 32)
1692 .Cases("FWORD", "fword", 48)
1693 .Cases("QWORD", "qword", 64)
1694 .Cases("MMWORD","mmword", 64)
1695 .Cases("XWORD", "xword", 80)
1696 .Cases("TBYTE", "tbyte", 80)
1697 .Cases("XMMWORD", "xmmword", 128)
1698 .Cases("YMMWORD", "ymmword", 256)
1699 .Cases("ZMMWORD", "zmmword", 512)
1700 .Cases("OPAQUE", "opaque", -1U) // needs to be non-zero, but doesn't matter
1701 .Default(0);
1702 if (Size) {
1703 const AsmToken &Tok = Lex(); // Eat operand size (e.g., byte, word).
1704 if (!(Tok.getString().equals("PTR") || Tok.getString().equals("ptr")))
1705 return Error(Tok.getLoc(), "Expected 'PTR' or 'ptr' token!");
1706 Lex(); // Eat ptr.
1707 }
1708 return false;
1709}
1710
David Blaikie960ea3f2014-06-08 16:18:35 +00001711std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand() {
Rafael Espindola961d4692014-11-11 05:18:41 +00001712 MCAsmParser &Parser = getParser();
Chad Rosier70f47592013-04-10 20:07:47 +00001713 const AsmToken &Tok = Parser.getTok();
David Majnemeraa34d792013-08-27 21:56:17 +00001714 SMLoc Start, End;
Chad Rosier91c82662012-10-24 17:22:29 +00001715
Coby Tayree07a89742017-03-21 19:31:55 +00001716 // FIXME: Offset operator
1717 // Should be handled as part of immediate expression, as other operators
1718 // Currently, only supported as a stand-alone operand
1719 if (isParsingInlineAsm())
Coby Tayreed8912892017-08-24 08:46:25 +00001720 if (IdentifyIntelInlineAsmOperator(Tok.getString()) == IOK_OFFSET)
Chad Rosier10d1d1c2013-04-09 20:44:09 +00001721 return ParseIntelOffsetOfOperator();
Chad Rosier11c42f22012-10-26 18:04:20 +00001722
Coby Tayreed8912892017-08-24 08:46:25 +00001723 // Parse optional Size directive.
1724 unsigned Size;
1725 if (ParseIntelMemoryOperandSize(Size))
1726 return nullptr;
1727 bool PtrInOperand = bool(Size);
Nirav Dave8601ac12016-08-02 17:56:03 +00001728
David Majnemeraa34d792013-08-27 21:56:17 +00001729 Start = Tok.getLoc();
1730
Coby Tayreed8912892017-08-24 08:46:25 +00001731 // Rounding mode operand.
Akira Hatanakabd9fc282015-11-14 05:20:05 +00001732 if (getSTI().getFeatureBits()[X86::FeatureAVX512] &&
Elena Demikhovsky18fd4962015-03-02 15:00:34 +00001733 getLexer().is(AsmToken::LCurly))
1734 return ParseRoundingModeOp(Start, End);
1735
Coby Tayreed8912892017-08-24 08:46:25 +00001736 // Register operand.
Devang Patelce6a2ca2012-01-20 22:32:05 +00001737 unsigned RegNo = 0;
Coby Tayreed8912892017-08-24 08:46:25 +00001738 if (Tok.is(AsmToken::Identifier) && !ParseRegister(RegNo, Start, End)) {
Douglas Katzman0411e862016-10-05 15:23:35 +00001739 if (RegNo == X86::RIP)
1740 return ErrorOperand(Start, "rip can only be used as a base register");
Coby Tayreed8912892017-08-24 08:46:25 +00001741 // A Register followed by ':' is considered a segment override
1742 if (Tok.isNot(AsmToken::Colon))
1743 return !PtrInOperand ? X86Operand::CreateReg(RegNo, Start, End) :
1744 ErrorOperand(Start, "expected memory operand after 'ptr', "
1745 "found register operand instead");
1746 // An alleged segment override. check if we have a valid segment register
1747 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo))
1748 return ErrorOperand(Start, "invalid segment register");
1749 // Eat ':' and update Start location
1750 Start = Lex().getLoc();
Devang Patel46831de2012-01-12 01:36:43 +00001751 }
1752
Nirav Dave8601ac12016-08-02 17:56:03 +00001753 // Immediates and Memory
Coby Tayreed8912892017-08-24 08:46:25 +00001754 IntelExprStateMachine SM;
Nirav Dave8601ac12016-08-02 17:56:03 +00001755 if (ParseIntelExpression(SM, End))
1756 return nullptr;
1757
Coby Tayreed8912892017-08-24 08:46:25 +00001758 if (isParsingInlineAsm())
1759 RewriteIntelExpression(SM, Start, Tok.getLoc());
1760
Nirav Dave8601ac12016-08-02 17:56:03 +00001761 int64_t Imm = SM.getImm();
Coby Tayreed8912892017-08-24 08:46:25 +00001762 const MCExpr *Disp = SM.getSym();
1763 const MCExpr *ImmDisp = MCConstantExpr::create(Imm, getContext());
1764 if (Disp && Imm)
1765 Disp = MCBinaryExpr::createAdd(Disp, ImmDisp, getContext());
1766 if (!Disp)
1767 Disp = ImmDisp;
Nirav Dave8601ac12016-08-02 17:56:03 +00001768
Coby Tayreed8912892017-08-24 08:46:25 +00001769 // RegNo != 0 specifies a valid segment register,
1770 // and we are parsing a segment override
1771 if (!SM.isMemExpr() && !RegNo)
1772 return X86Operand::CreateImm(Disp, Start, End);
Nirav Dave8601ac12016-08-02 17:56:03 +00001773
Coby Tayreed8912892017-08-24 08:46:25 +00001774 StringRef ErrMsg;
1775 unsigned BaseReg = SM.getBaseReg();
1776 unsigned IndexReg = SM.getIndexReg();
1777 unsigned Scale = SM.getScale();
Nirav Dave8601ac12016-08-02 17:56:03 +00001778
Coby Tayreed8912892017-08-24 08:46:25 +00001779 if ((BaseReg || IndexReg) &&
1780 CheckBaseRegAndIndexRegAndScale(BaseReg, IndexReg, Scale, ErrMsg))
1781 return ErrorOperand(Start, ErrMsg);
1782 if (isParsingInlineAsm())
1783 return CreateMemForInlineAsm(RegNo, Disp, BaseReg, IndexReg,
1784 Scale, Start, End, Size, SM.getSymName(),
1785 SM.getIdentifierInfo());
1786 if (!(BaseReg || IndexReg || RegNo))
1787 return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size);
1788 return X86Operand::CreateMem(getPointerWidth(), RegNo, Disp,
1789 BaseReg, IndexReg, Scale, Start, End, Size);
Devang Patel46831de2012-01-12 01:36:43 +00001790}
1791
David Blaikie960ea3f2014-06-08 16:18:35 +00001792std::unique_ptr<X86Operand> X86AsmParser::ParseATTOperand() {
Rafael Espindola961d4692014-11-11 05:18:41 +00001793 MCAsmParser &Parser = getParser();
Daniel Dunbare1fdb0e2009-07-28 22:40:46 +00001794 switch (getLexer().getKind()) {
1795 default:
Chris Lattnerb9270732010-04-17 18:56:34 +00001796 // Parse a memory operand with no segment register.
1797 return ParseMemOperand(0, Parser.getTok().getLoc());
Chris Lattnercc2ad082010-01-15 18:27:19 +00001798 case AsmToken::Percent: {
Chris Lattnerb9270732010-04-17 18:56:34 +00001799 // Read the register.
Chris Lattnercc2ad082010-01-15 18:27:19 +00001800 unsigned RegNo;
Chris Lattner0c2538f2010-01-15 18:51:29 +00001801 SMLoc Start, End;
Craig Topper062a2ba2014-04-25 05:30:21 +00001802 if (ParseRegister(RegNo, Start, End)) return nullptr;
Bruno Cardoso Lopes306a1f92010-07-24 00:06:39 +00001803 if (RegNo == X86::EIZ || RegNo == X86::RIZ) {
Benjamin Kramer1930b002011-10-16 12:10:27 +00001804 Error(Start, "%eiz and %riz can only be used as index registers",
1805 SMRange(Start, End));
Craig Topper062a2ba2014-04-25 05:30:21 +00001806 return nullptr;
Bruno Cardoso Lopes306a1f92010-07-24 00:06:39 +00001807 }
Douglas Katzman0411e862016-10-05 15:23:35 +00001808 if (RegNo == X86::RIP) {
1809 Error(Start, "%rip can only be used as a base register",
1810 SMRange(Start, End));
1811 return nullptr;
1812 }
Bruno Cardoso Lopesd65cd1d2010-07-23 22:15:26 +00001813
Chris Lattnerb9270732010-04-17 18:56:34 +00001814 // If this is a segment register followed by a ':', then this is the start
1815 // of a memory reference, otherwise this is a normal register reference.
1816 if (getLexer().isNot(AsmToken::Colon))
1817 return X86Operand::CreateReg(RegNo, Start, End);
Bruno Cardoso Lopesd65cd1d2010-07-23 22:15:26 +00001818
Reid Kleckner0c5da972014-07-31 23:03:22 +00001819 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo))
1820 return ErrorOperand(Start, "invalid segment register");
1821
Chris Lattnerb9270732010-04-17 18:56:34 +00001822 getParser().Lex(); // Eat the colon.
1823 return ParseMemOperand(RegNo, Start);
Chris Lattnercc2ad082010-01-15 18:27:19 +00001824 }
Daniel Dunbare1fdb0e2009-07-28 22:40:46 +00001825 case AsmToken::Dollar: {
1826 // $42 -> immediate.
Sean Callanan936b0d32010-01-19 21:44:56 +00001827 SMLoc Start = Parser.getTok().getLoc(), End;
Sean Callanana83fd7d2010-01-19 20:27:46 +00001828 Parser.Lex();
Daniel Dunbar73da11e2009-08-31 08:08:38 +00001829 const MCExpr *Val;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001830 if (getParser().parseExpression(Val, End))
Craig Topper062a2ba2014-04-25 05:30:21 +00001831 return nullptr;
Chris Lattner528d00b2010-01-15 19:28:38 +00001832 return X86Operand::CreateImm(Val, Start, End);
Daniel Dunbare1fdb0e2009-07-28 22:40:46 +00001833 }
Elena Demikhovsky18fd4962015-03-02 15:00:34 +00001834 case AsmToken::LCurly:{
1835 SMLoc Start = Parser.getTok().getLoc(), End;
Akira Hatanakabd9fc282015-11-14 05:20:05 +00001836 if (getSTI().getFeatureBits()[X86::FeatureAVX512])
Elena Demikhovsky18fd4962015-03-02 15:00:34 +00001837 return ParseRoundingModeOp(Start, End);
Nirav Dave8601ac12016-08-02 17:56:03 +00001838 return ErrorOperand(Start, "Unexpected '{' in expression");
Elena Demikhovsky18fd4962015-03-02 15:00:34 +00001839 }
Daniel Dunbare1fdb0e2009-07-28 22:40:46 +00001840 }
Daniel Dunbar2b11c7d2009-07-20 20:01:54 +00001841}
1842
Michael Zuckerman1bee6342016-10-18 13:52:39 +00001843// true on failure, false otherwise
1844// If no {z} mark was found - Parser doesn't advance
1845bool X86AsmParser::ParseZ(std::unique_ptr<X86Operand> &Z,
1846 const SMLoc &StartLoc) {
1847 MCAsmParser &Parser = getParser();
1848 // Assuming we are just pass the '{' mark, quering the next token
Coby Tayree179ff0e2016-11-20 09:31:11 +00001849 // Searched for {z}, but none was found. Return false, as no parsing error was
Michael Zuckerman1bee6342016-10-18 13:52:39 +00001850 // encountered
1851 if (!(getLexer().is(AsmToken::Identifier) &&
1852 (getLexer().getTok().getIdentifier() == "z")))
1853 return false;
1854 Parser.Lex(); // Eat z
1855 // Query and eat the '}' mark
1856 if (!getLexer().is(AsmToken::RCurly))
1857 return Error(getLexer().getLoc(), "Expected } at this point");
1858 Parser.Lex(); // Eat '}'
1859 // Assign Z with the {z} mark opernad
Benjamin Kramerfc54e352016-11-24 15:17:39 +00001860 Z = X86Operand::CreateToken("{z}", StartLoc);
Michael Zuckerman1bee6342016-10-18 13:52:39 +00001861 return false;
1862}
1863
1864// true on failure, false otherwise
David Blaikie960ea3f2014-06-08 16:18:35 +00001865bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands,
1866 const MCParsedAsmOperand &Op) {
Rafael Espindola961d4692014-11-11 05:18:41 +00001867 MCAsmParser &Parser = getParser();
Akira Hatanakabd9fc282015-11-14 05:20:05 +00001868 if(getSTI().getFeatureBits()[X86::FeatureAVX512]) {
Elena Demikhovskyc9657012014-02-20 06:34:39 +00001869 if (getLexer().is(AsmToken::LCurly)) {
1870 // Eat "{" and mark the current place.
1871 const SMLoc consumedToken = consumeToken();
1872 // Distinguish {1to<NUM>} from {%k<NUM>}.
1873 if(getLexer().is(AsmToken::Integer)) {
1874 // Parse memory broadcasting ({1to<NUM>}).
1875 if (getLexer().getTok().getIntVal() != 1)
Michael Zuckerman1bee6342016-10-18 13:52:39 +00001876 return TokError("Expected 1to<NUM> at this point");
Elena Demikhovskyc9657012014-02-20 06:34:39 +00001877 Parser.Lex(); // Eat "1" of 1to8
1878 if (!getLexer().is(AsmToken::Identifier) ||
1879 !getLexer().getTok().getIdentifier().startswith("to"))
Michael Zuckerman1bee6342016-10-18 13:52:39 +00001880 return TokError("Expected 1to<NUM> at this point");
Elena Demikhovskyc9657012014-02-20 06:34:39 +00001881 // Recognize only reasonable suffixes.
1882 const char *BroadcastPrimitive =
1883 StringSwitch<const char*>(getLexer().getTok().getIdentifier())
Robert Khasanovbfa01312014-07-21 14:54:21 +00001884 .Case("to2", "{1to2}")
1885 .Case("to4", "{1to4}")
Elena Demikhovskyc9657012014-02-20 06:34:39 +00001886 .Case("to8", "{1to8}")
1887 .Case("to16", "{1to16}")
Craig Topper062a2ba2014-04-25 05:30:21 +00001888 .Default(nullptr);
Elena Demikhovskyc9657012014-02-20 06:34:39 +00001889 if (!BroadcastPrimitive)
Michael Zuckerman1bee6342016-10-18 13:52:39 +00001890 return TokError("Invalid memory broadcast primitive.");
Elena Demikhovskyc9657012014-02-20 06:34:39 +00001891 Parser.Lex(); // Eat "toN" of 1toN
1892 if (!getLexer().is(AsmToken::RCurly))
Michael Zuckerman1bee6342016-10-18 13:52:39 +00001893 return TokError("Expected } at this point");
Elena Demikhovskyc9657012014-02-20 06:34:39 +00001894 Parser.Lex(); // Eat "}"
1895 Operands.push_back(X86Operand::CreateToken(BroadcastPrimitive,
1896 consumedToken));
1897 // No AVX512 specific primitives can pass
1898 // after memory broadcasting, so return.
Michael Zuckerman1bee6342016-10-18 13:52:39 +00001899 return false;
Elena Demikhovskyc9657012014-02-20 06:34:39 +00001900 } else {
Michael Zuckerman1bee6342016-10-18 13:52:39 +00001901 // Parse either {k}{z}, {z}{k}, {k} or {z}
1902 // last one have no meaning, but GCC accepts it
1903 // Currently, we're just pass a '{' mark
1904 std::unique_ptr<X86Operand> Z;
1905 if (ParseZ(Z, consumedToken))
1906 return true;
1907 // Reaching here means that parsing of the allegadly '{z}' mark yielded
1908 // no errors.
1909 // Query for the need of further parsing for a {%k<NUM>} mark
1910 if (!Z || getLexer().is(AsmToken::LCurly)) {
Coby Tayree3bfb3652017-08-09 12:32:05 +00001911 SMLoc StartLoc = Z ? consumeToken() : consumedToken;
Michael Zuckerman1bee6342016-10-18 13:52:39 +00001912 // Parse an op-mask register mark ({%k<NUM>}), which is now to be
1913 // expected
Coby Tayree3bfb3652017-08-09 12:32:05 +00001914 unsigned RegNo;
Coby Tayree799fa2c2017-08-13 12:03:00 +00001915 SMLoc RegLoc;
1916 if (!ParseRegister(RegNo, RegLoc, StartLoc) &&
Coby Tayree3bfb3652017-08-09 12:32:05 +00001917 X86MCRegisterClasses[X86::VK1RegClassID].contains(RegNo)) {
Coby Tayree799fa2c2017-08-13 12:03:00 +00001918 if (RegNo == X86::K0)
1919 return Error(RegLoc, "Register k0 can't be used as write mask");
Elena Demikhovskyc9657012014-02-20 06:34:39 +00001920 if (!getLexer().is(AsmToken::RCurly))
Michael Zuckerman1bee6342016-10-18 13:52:39 +00001921 return Error(getLexer().getLoc(), "Expected } at this point");
1922 Operands.push_back(X86Operand::CreateToken("{", StartLoc));
Haojian Wuc1cae0b2017-08-09 12:49:20 +00001923 Operands.push_back(
1924 X86Operand::CreateReg(RegNo, StartLoc, StartLoc));
Michael Zuckerman1bee6342016-10-18 13:52:39 +00001925 Operands.push_back(X86Operand::CreateToken("}", consumeToken()));
1926 } else
1927 return Error(getLexer().getLoc(),
1928 "Expected an op-mask register at this point");
1929 // {%k<NUM>} mark is found, inquire for {z}
1930 if (getLexer().is(AsmToken::LCurly) && !Z) {
1931 // Have we've found a parsing error, or found no (expected) {z} mark
1932 // - report an error
1933 if (ParseZ(Z, consumeToken()) || !Z)
Coby Tayree3bfb3652017-08-09 12:32:05 +00001934 return Error(getLexer().getLoc(),
1935 "Expected a {z} mark at this point");
Michael Zuckerman1bee6342016-10-18 13:52:39 +00001936
Elena Demikhovskyc9657012014-02-20 06:34:39 +00001937 }
Michael Zuckerman1bee6342016-10-18 13:52:39 +00001938 // '{z}' on its own is meaningless, hence should be ignored.
1939 // on the contrary - have it been accompanied by a K register,
1940 // allow it.
1941 if (Z)
1942 Operands.push_back(std::move(Z));
Elena Demikhovskyc9657012014-02-20 06:34:39 +00001943 }
1944 }
1945 }
1946 }
Michael Zuckerman1bee6342016-10-18 13:52:39 +00001947 return false;
Elena Demikhovskyc9657012014-02-20 06:34:39 +00001948}
1949
Chris Lattnerb9270732010-04-17 18:56:34 +00001950/// ParseMemOperand: segment: disp(basereg, indexreg, scale). The '%ds:' prefix
1951/// has already been parsed if present.
David Blaikie960ea3f2014-06-08 16:18:35 +00001952std::unique_ptr<X86Operand> X86AsmParser::ParseMemOperand(unsigned SegReg,
1953 SMLoc MemStart) {
Bruno Cardoso Lopesd65cd1d2010-07-23 22:15:26 +00001954
Rafael Espindola961d4692014-11-11 05:18:41 +00001955 MCAsmParser &Parser = getParser();
Daniel Dunbare1fdb0e2009-07-28 22:40:46 +00001956 // We have to disambiguate a parenthesized expression "(4+5)" from the start
1957 // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)". The
Chris Lattner807a3bc2010-01-24 01:07:33 +00001958 // only way to do this without lookahead is to eat the '(' and see what is
1959 // after it.
Jim Grosbach13760bd2015-05-30 01:25:56 +00001960 const MCExpr *Disp = MCConstantExpr::create(0, getParser().getContext());
Daniel Dunbare1fdb0e2009-07-28 22:40:46 +00001961 if (getLexer().isNot(AsmToken::LParen)) {
Chris Lattnere17df0b2010-01-15 19:39:23 +00001962 SMLoc ExprEnd;
Craig Topper062a2ba2014-04-25 05:30:21 +00001963 if (getParser().parseExpression(Disp, ExprEnd)) return nullptr;
Bruno Cardoso Lopesd65cd1d2010-07-23 22:15:26 +00001964
Daniel Dunbare1fdb0e2009-07-28 22:40:46 +00001965 // After parsing the base expression we could either have a parenthesized
1966 // memory address or not. If not, return now. If so, eat the (.
1967 if (getLexer().isNot(AsmToken::LParen)) {
Daniel Dunbara4fc8d92009-07-31 22:22:54 +00001968 // Unless we have a segment register, treat this as an immediate.
Chris Lattnera2bbb7c2010-01-15 18:44:13 +00001969 if (SegReg == 0)
Craig Topper055845f2015-01-02 07:02:25 +00001970 return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, ExprEnd);
1971 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
1972 MemStart, ExprEnd);
Daniel Dunbare1fdb0e2009-07-28 22:40:46 +00001973 }
Bruno Cardoso Lopesd65cd1d2010-07-23 22:15:26 +00001974
Daniel Dunbare1fdb0e2009-07-28 22:40:46 +00001975 // Eat the '('.
Sean Callanana83fd7d2010-01-19 20:27:46 +00001976 Parser.Lex();
Daniel Dunbare1fdb0e2009-07-28 22:40:46 +00001977 } else {
1978 // Okay, we have a '('. We don't know if this is an expression or not, but
1979 // so we have to eat the ( to see beyond it.
Sean Callanan936b0d32010-01-19 21:44:56 +00001980 SMLoc LParenLoc = Parser.getTok().getLoc();
Sean Callanana83fd7d2010-01-19 20:27:46 +00001981 Parser.Lex(); // Eat the '('.
Bruno Cardoso Lopesd65cd1d2010-07-23 22:15:26 +00001982
Kevin Enderby7d912182009-09-03 17:15:07 +00001983 if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) {
Daniel Dunbare1fdb0e2009-07-28 22:40:46 +00001984 // Nothing to do here, fall into the code below with the '(' part of the
1985 // memory operand consumed.
1986 } else {
Chris Lattner528d00b2010-01-15 19:28:38 +00001987 SMLoc ExprEnd;
Bruno Cardoso Lopesd65cd1d2010-07-23 22:15:26 +00001988
Daniel Dunbare1fdb0e2009-07-28 22:40:46 +00001989 // It must be an parenthesized expression, parse it now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001990 if (getParser().parseParenExpression(Disp, ExprEnd))
Craig Topper062a2ba2014-04-25 05:30:21 +00001991 return nullptr;
Bruno Cardoso Lopesd65cd1d2010-07-23 22:15:26 +00001992
Daniel Dunbare1fdb0e2009-07-28 22:40:46 +00001993 // After parsing the base expression we could either have a parenthesized
1994 // memory address or not. If not, return now. If so, eat the (.
1995 if (getLexer().isNot(AsmToken::LParen)) {
Daniel Dunbara4fc8d92009-07-31 22:22:54 +00001996 // Unless we have a segment register, treat this as an immediate.
Chris Lattnera2bbb7c2010-01-15 18:44:13 +00001997 if (SegReg == 0)
Craig Topper055845f2015-01-02 07:02:25 +00001998 return X86Operand::CreateMem(getPointerWidth(), Disp, LParenLoc,
1999 ExprEnd);
2000 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
2001 MemStart, ExprEnd);
Daniel Dunbare1fdb0e2009-07-28 22:40:46 +00002002 }
Bruno Cardoso Lopesd65cd1d2010-07-23 22:15:26 +00002003
Daniel Dunbare1fdb0e2009-07-28 22:40:46 +00002004 // Eat the '('.
Sean Callanana83fd7d2010-01-19 20:27:46 +00002005 Parser.Lex();
Daniel Dunbare1fdb0e2009-07-28 22:40:46 +00002006 }
2007 }
Bruno Cardoso Lopesd65cd1d2010-07-23 22:15:26 +00002008
Daniel Dunbare1fdb0e2009-07-28 22:40:46 +00002009 // If we reached here, then we just ate the ( of the memory operand. Process
2010 // the rest of the memory operand.
Daniel Dunbar3ebf8482009-07-31 20:53:16 +00002011 unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
David Woodhouse6dbda442014-01-08 12:58:28 +00002012 SMLoc IndexLoc, BaseLoc;
Bruno Cardoso Lopesd65cd1d2010-07-23 22:15:26 +00002013
Chris Lattner0c2538f2010-01-15 18:51:29 +00002014 if (getLexer().is(AsmToken::Percent)) {
Benjamin Kramer1930b002011-10-16 12:10:27 +00002015 SMLoc StartLoc, EndLoc;
David Woodhouse6dbda442014-01-08 12:58:28 +00002016 BaseLoc = Parser.getTok().getLoc();
Craig Topper062a2ba2014-04-25 05:30:21 +00002017 if (ParseRegister(BaseReg, StartLoc, EndLoc)) return nullptr;
Bruno Cardoso Lopes306a1f92010-07-24 00:06:39 +00002018 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) {
Benjamin Kramer1930b002011-10-16 12:10:27 +00002019 Error(StartLoc, "eiz and riz can only be used as index registers",
2020 SMRange(StartLoc, EndLoc));
Craig Topper062a2ba2014-04-25 05:30:21 +00002021 return nullptr;
Bruno Cardoso Lopes306a1f92010-07-24 00:06:39 +00002022 }
Chris Lattner0c2538f2010-01-15 18:51:29 +00002023 }
Bruno Cardoso Lopesd65cd1d2010-07-23 22:15:26 +00002024
Daniel Dunbare1fdb0e2009-07-28 22:40:46 +00002025 if (getLexer().is(AsmToken::Comma)) {
Sean Callanana83fd7d2010-01-19 20:27:46 +00002026 Parser.Lex(); // Eat the comma.
Kevin Enderbyfb3110b2012-03-12 21:32:09 +00002027 IndexLoc = Parser.getTok().getLoc();
Daniel Dunbare1fdb0e2009-07-28 22:40:46 +00002028
2029 // Following the comma we should have either an index register, or a scale
2030 // value. We don't support the later form, but we want to parse it
2031 // correctly.
2032 //
2033 // Not that even though it would be completely consistent to support syntax
Bruno Cardoso Lopes306a1f92010-07-24 00:06:39 +00002034 // like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this.
Kevin Enderby7d912182009-09-03 17:15:07 +00002035 if (getLexer().is(AsmToken::Percent)) {
Chris Lattner0c2538f2010-01-15 18:51:29 +00002036 SMLoc L;
Douglas Katzman0411e862016-10-05 15:23:35 +00002037 if (ParseRegister(IndexReg, L, L))
2038 return nullptr;
2039 if (BaseReg == X86::RIP) {
2040 Error(IndexLoc, "%rip as base register can not have an index register");
2041 return nullptr;
2042 }
2043 if (IndexReg == X86::RIP) {
2044 Error(IndexLoc, "%rip is not allowed as an index register");
2045 return nullptr;
2046 }
Bruno Cardoso Lopesd65cd1d2010-07-23 22:15:26 +00002047
Daniel Dunbare1fdb0e2009-07-28 22:40:46 +00002048 if (getLexer().isNot(AsmToken::RParen)) {
2049 // Parse the scale amount:
2050 // ::= ',' [scale-expression]
Chris Lattnera2bbb7c2010-01-15 18:44:13 +00002051 if (getLexer().isNot(AsmToken::Comma)) {
Sean Callanan936b0d32010-01-19 21:44:56 +00002052 Error(Parser.getTok().getLoc(),
Chris Lattnera2bbb7c2010-01-15 18:44:13 +00002053 "expected comma in scale expression");
Craig Topper062a2ba2014-04-25 05:30:21 +00002054 return nullptr;
Chris Lattnera2bbb7c2010-01-15 18:44:13 +00002055 }
Sean Callanana83fd7d2010-01-19 20:27:46 +00002056 Parser.Lex(); // Eat the comma.
Daniel Dunbare1fdb0e2009-07-28 22:40:46 +00002057
2058 if (getLexer().isNot(AsmToken::RParen)) {
Sean Callanan936b0d32010-01-19 21:44:56 +00002059 SMLoc Loc = Parser.getTok().getLoc();
Daniel Dunbare1fdb0e2009-07-28 22:40:46 +00002060
2061 int64_t ScaleVal;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002062 if (getParser().parseAbsoluteExpression(ScaleVal)){
Kevin Enderbydeed5aa2012-03-09 22:24:10 +00002063 Error(Loc, "expected scale expression");
Craig Topper062a2ba2014-04-25 05:30:21 +00002064 return nullptr;
Craig Topper6bf3ed42012-07-18 04:59:16 +00002065 }
Bruno Cardoso Lopesd65cd1d2010-07-23 22:15:26 +00002066
Daniel Dunbare1fdb0e2009-07-28 22:40:46 +00002067 // Validate the scale amount.
NAKAMURA Takumi0a7d0ad2015-09-22 11:15:07 +00002068 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
David Woodhouse6dbda442014-01-08 12:58:28 +00002069 ScaleVal != 1) {
2070 Error(Loc, "scale factor in 16-bit address must be 1");
Craig Topper062a2ba2014-04-25 05:30:21 +00002071 return nullptr;
NAKAMURA Takumi0a7d0ad2015-09-22 11:15:07 +00002072 }
2073 if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 &&
2074 ScaleVal != 8) {
Chris Lattnera2bbb7c2010-01-15 18:44:13 +00002075 Error(Loc, "scale factor in address must be 1, 2, 4 or 8");
Craig Topper062a2ba2014-04-25 05:30:21 +00002076 return nullptr;
Chris Lattnera2bbb7c2010-01-15 18:44:13 +00002077 }
Daniel Dunbare1fdb0e2009-07-28 22:40:46 +00002078 Scale = (unsigned)ScaleVal;
2079 }
2080 }
2081 } else if (getLexer().isNot(AsmToken::RParen)) {
Daniel Dunbar94b84a12010-08-24 19:13:38 +00002082 // A scale amount without an index is ignored.
Daniel Dunbare1fdb0e2009-07-28 22:40:46 +00002083 // index.
Sean Callanan936b0d32010-01-19 21:44:56 +00002084 SMLoc Loc = Parser.getTok().getLoc();
Daniel Dunbare1fdb0e2009-07-28 22:40:46 +00002085
2086 int64_t Value;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002087 if (getParser().parseAbsoluteExpression(Value))
Craig Topper062a2ba2014-04-25 05:30:21 +00002088 return nullptr;
Bruno Cardoso Lopesd65cd1d2010-07-23 22:15:26 +00002089
Daniel Dunbar94b84a12010-08-24 19:13:38 +00002090 if (Value != 1)
2091 Warning(Loc, "scale factor without index register is ignored");
2092 Scale = 1;
Daniel Dunbare1fdb0e2009-07-28 22:40:46 +00002093 }
2094 }
Bruno Cardoso Lopesd65cd1d2010-07-23 22:15:26 +00002095
Daniel Dunbare1fdb0e2009-07-28 22:40:46 +00002096 // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
Chris Lattnera2bbb7c2010-01-15 18:44:13 +00002097 if (getLexer().isNot(AsmToken::RParen)) {
Sean Callanan936b0d32010-01-19 21:44:56 +00002098 Error(Parser.getTok().getLoc(), "unexpected token in memory operand");
Craig Topper062a2ba2014-04-25 05:30:21 +00002099 return nullptr;
Chris Lattnera2bbb7c2010-01-15 18:44:13 +00002100 }
Jordan Rosee8f1eae2013-01-07 19:00:49 +00002101 SMLoc MemEnd = Parser.getTok().getEndLoc();
Sean Callanana83fd7d2010-01-19 20:27:46 +00002102 Parser.Lex(); // Eat the ')'.
Bruno Cardoso Lopesd65cd1d2010-07-23 22:15:26 +00002103
David Woodhouse6dbda442014-01-08 12:58:28 +00002104 // Check for use of invalid 16-bit registers. Only BX/BP/SI/DI are allowed,
2105 // and then only in non-64-bit modes. Except for DX, which is a special case
2106 // because an unofficial form of in/out instructions uses it.
2107 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
2108 (is64BitMode() || (BaseReg != X86::BX && BaseReg != X86::BP &&
2109 BaseReg != X86::SI && BaseReg != X86::DI)) &&
2110 BaseReg != X86::DX) {
2111 Error(BaseLoc, "invalid 16-bit base register");
Craig Topper062a2ba2014-04-25 05:30:21 +00002112 return nullptr;
David Woodhouse6dbda442014-01-08 12:58:28 +00002113 }
2114 if (BaseReg == 0 &&
2115 X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg)) {
2116 Error(IndexLoc, "16-bit memory operand may not include only index register");
Craig Topper062a2ba2014-04-25 05:30:21 +00002117 return nullptr;
David Woodhouse6dbda442014-01-08 12:58:28 +00002118 }
Kevin Enderbybc570f22014-01-23 22:34:42 +00002119
2120 StringRef ErrMsg;
Andrew V. Tischenko32e9b1a2017-07-25 13:05:12 +00002121 if (CheckBaseRegAndIndexRegAndScale(BaseReg, IndexReg, Scale, ErrMsg)) {
Kevin Enderbybc570f22014-01-23 22:34:42 +00002122 Error(BaseLoc, ErrMsg);
Craig Topper062a2ba2014-04-25 05:30:21 +00002123 return nullptr;
Kevin Enderbyfb3110b2012-03-12 21:32:09 +00002124 }
2125
Reid Klecknerb7e2f602014-07-31 23:26:35 +00002126 if (SegReg || BaseReg || IndexReg)
Craig Topper055845f2015-01-02 07:02:25 +00002127 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
2128 IndexReg, Scale, MemStart, MemEnd);
2129 return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, MemEnd);
Daniel Dunbare1fdb0e2009-07-28 22:40:46 +00002130}
2131
David Blaikie960ea3f2014-06-08 16:18:35 +00002132bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2133 SMLoc NameLoc, OperandVector &Operands) {
Rafael Espindola961d4692014-11-11 05:18:41 +00002134 MCAsmParser &Parser = getParser();
Chad Rosierf0e87202012-10-25 20:41:34 +00002135 InstInfo = &Info;
Chris Lattner2cb092d2010-10-30 19:23:13 +00002136 StringRef PatchedName = Name;
Daniel Dunbar0e767d72010-05-25 19:49:32 +00002137
Coby Tayree48d67cd2017-07-30 11:12:47 +00002138 if ((Name.equals("jmp") || Name.equals("jc") || Name.equals("jz")) &&
2139 isParsingIntelSyntax() && isParsingInlineAsm()) {
Michael Zuckerman174d2e72016-10-14 08:09:40 +00002140 StringRef NextTok = Parser.getTok().getString();
2141 if (NextTok == "short") {
2142 SMLoc NameEndLoc =
2143 NameLoc.getFromPointer(NameLoc.getPointer() + Name.size());
2144 // Eat the short keyword
2145 Parser.Lex();
2146 // MS ignores the short keyword, it determines the jmp type based
2147 // on the distance of the label
2148 InstInfo->AsmRewrites->emplace_back(AOK_Skip, NameEndLoc,
2149 NextTok.size() + 1);
2150 }
2151 }
2152
Chris Lattner7e8a99b2010-11-28 20:23:50 +00002153 // FIXME: Hack to recognize setneb as setne.
2154 if (PatchedName.startswith("set") && PatchedName.endswith("b") &&
2155 PatchedName != "setb" && PatchedName != "setnb")
2156 PatchedName = PatchedName.substr(0, Name.size()-1);
Chad Rosier51afe632012-06-27 22:34:28 +00002157
Daniel Dunbar0e767d72010-05-25 19:49:32 +00002158 // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}.
Bruno Cardoso Lopes3183dd52010-06-23 21:10:57 +00002159 if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) &&
Daniel Dunbar0e767d72010-05-25 19:49:32 +00002160 (PatchedName.endswith("ss") || PatchedName.endswith("sd") ||
2161 PatchedName.endswith("ps") || PatchedName.endswith("pd"))) {
Craig Toppera0a603e2012-03-29 07:11:23 +00002162 bool IsVCMP = PatchedName[0] == 'v';
Craig Topper78c424d2015-02-15 07:13:48 +00002163 unsigned CCIdx = IsVCMP ? 4 : 3;
2164 unsigned ComparisonCode = StringSwitch<unsigned>(
2165 PatchedName.slice(CCIdx, PatchedName.size() - 2))
Craig Toppera0a603e2012-03-29 07:11:23 +00002166 .Case("eq", 0x00)
Michael Zuckerman72b72232016-01-25 08:43:26 +00002167 .Case("eq_oq", 0x00)
Craig Toppera0a603e2012-03-29 07:11:23 +00002168 .Case("lt", 0x01)
Michael Zuckerman72b72232016-01-25 08:43:26 +00002169 .Case("lt_os", 0x01)
Craig Toppera0a603e2012-03-29 07:11:23 +00002170 .Case("le", 0x02)
Michael Zuckerman72b72232016-01-25 08:43:26 +00002171 .Case("le_os", 0x02)
Craig Toppera0a603e2012-03-29 07:11:23 +00002172 .Case("unord", 0x03)
Michael Zuckerman72b72232016-01-25 08:43:26 +00002173 .Case("unord_q", 0x03)
Craig Toppera0a603e2012-03-29 07:11:23 +00002174 .Case("neq", 0x04)
Michael Zuckerman72b72232016-01-25 08:43:26 +00002175 .Case("neq_uq", 0x04)
Craig Toppera0a603e2012-03-29 07:11:23 +00002176 .Case("nlt", 0x05)
Michael Zuckerman72b72232016-01-25 08:43:26 +00002177 .Case("nlt_us", 0x05)
Craig Toppera0a603e2012-03-29 07:11:23 +00002178 .Case("nle", 0x06)
Michael Zuckerman72b72232016-01-25 08:43:26 +00002179 .Case("nle_us", 0x06)
Craig Toppera0a603e2012-03-29 07:11:23 +00002180 .Case("ord", 0x07)
Michael Zuckerman72b72232016-01-25 08:43:26 +00002181 .Case("ord_q", 0x07)
Craig Toppera0a603e2012-03-29 07:11:23 +00002182 /* AVX only from here */
2183 .Case("eq_uq", 0x08)
2184 .Case("nge", 0x09)
Michael Zuckerman72b72232016-01-25 08:43:26 +00002185 .Case("nge_us", 0x09)
Bruno Cardoso Lopes6c614512010-07-07 22:24:03 +00002186 .Case("ngt", 0x0A)
Michael Zuckerman72b72232016-01-25 08:43:26 +00002187 .Case("ngt_us", 0x0A)
Bruno Cardoso Lopes6c614512010-07-07 22:24:03 +00002188 .Case("false", 0x0B)
Michael Zuckerman72b72232016-01-25 08:43:26 +00002189 .Case("false_oq", 0x0B)
Bruno Cardoso Lopes6c614512010-07-07 22:24:03 +00002190 .Case("neq_oq", 0x0C)
2191 .Case("ge", 0x0D)
Michael Zuckerman72b72232016-01-25 08:43:26 +00002192 .Case("ge_os", 0x0D)
Bruno Cardoso Lopes6c614512010-07-07 22:24:03 +00002193 .Case("gt", 0x0E)
Michael Zuckerman72b72232016-01-25 08:43:26 +00002194 .Case("gt_os", 0x0E)
Bruno Cardoso Lopes6c614512010-07-07 22:24:03 +00002195 .Case("true", 0x0F)
Michael Zuckerman72b72232016-01-25 08:43:26 +00002196 .Case("true_uq", 0x0F)
Bruno Cardoso Lopes6c614512010-07-07 22:24:03 +00002197 .Case("eq_os", 0x10)
2198 .Case("lt_oq", 0x11)
2199 .Case("le_oq", 0x12)
2200 .Case("unord_s", 0x13)
2201 .Case("neq_us", 0x14)
2202 .Case("nlt_uq", 0x15)
2203 .Case("nle_uq", 0x16)
2204 .Case("ord_s", 0x17)
2205 .Case("eq_us", 0x18)
2206 .Case("nge_uq", 0x19)
2207 .Case("ngt_uq", 0x1A)
2208 .Case("false_os", 0x1B)
2209 .Case("neq_os", 0x1C)
2210 .Case("ge_oq", 0x1D)
2211 .Case("gt_oq", 0x1E)
2212 .Case("true_us", 0x1F)
Daniel Dunbar0e767d72010-05-25 19:49:32 +00002213 .Default(~0U);
Craig Topper78c424d2015-02-15 07:13:48 +00002214 if (ComparisonCode != ~0U && (IsVCMP || ComparisonCode < 8)) {
Craig Topper43860832015-02-14 21:54:03 +00002215
Craig Topper78c424d2015-02-15 07:13:48 +00002216 Operands.push_back(X86Operand::CreateToken(PatchedName.slice(0, CCIdx),
Craig Topper43860832015-02-14 21:54:03 +00002217 NameLoc));
2218
Jim Grosbach13760bd2015-05-30 01:25:56 +00002219 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
Craig Topper43860832015-02-14 21:54:03 +00002220 getParser().getContext());
2221 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2222
2223 PatchedName = PatchedName.substr(PatchedName.size() - 2);
Daniel Dunbar0e767d72010-05-25 19:49:32 +00002224 }
2225 }
Bruno Cardoso Lopesea0e05a2010-07-23 18:41:12 +00002226
Craig Topper78c424d2015-02-15 07:13:48 +00002227 // FIXME: Hack to recognize vpcmp<comparison code>{ub,uw,ud,uq,b,w,d,q}.
2228 if (PatchedName.startswith("vpcmp") &&
2229 (PatchedName.endswith("b") || PatchedName.endswith("w") ||
2230 PatchedName.endswith("d") || PatchedName.endswith("q"))) {
2231 unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1;
2232 unsigned ComparisonCode = StringSwitch<unsigned>(
2233 PatchedName.slice(5, PatchedName.size() - CCIdx))
2234 .Case("eq", 0x0) // Only allowed on unsigned. Checked below.
2235 .Case("lt", 0x1)
2236 .Case("le", 0x2)
2237 //.Case("false", 0x3) // Not a documented alias.
2238 .Case("neq", 0x4)
2239 .Case("nlt", 0x5)
2240 .Case("nle", 0x6)
2241 //.Case("true", 0x7) // Not a documented alias.
2242 .Default(~0U);
2243 if (ComparisonCode != ~0U && (ComparisonCode != 0 || CCIdx == 2)) {
2244 Operands.push_back(X86Operand::CreateToken("vpcmp", NameLoc));
2245
Jim Grosbach13760bd2015-05-30 01:25:56 +00002246 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
Craig Topper78c424d2015-02-15 07:13:48 +00002247 getParser().getContext());
2248 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2249
2250 PatchedName = PatchedName.substr(PatchedName.size() - CCIdx);
2251 }
2252 }
2253
Craig Topper916708f2015-02-13 07:42:25 +00002254 // FIXME: Hack to recognize vpcom<comparison code>{ub,uw,ud,uq,b,w,d,q}.
2255 if (PatchedName.startswith("vpcom") &&
2256 (PatchedName.endswith("b") || PatchedName.endswith("w") ||
2257 PatchedName.endswith("d") || PatchedName.endswith("q"))) {
Craig Topper78c424d2015-02-15 07:13:48 +00002258 unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1;
2259 unsigned ComparisonCode = StringSwitch<unsigned>(
2260 PatchedName.slice(5, PatchedName.size() - CCIdx))
Craig Topper916708f2015-02-13 07:42:25 +00002261 .Case("lt", 0x0)
2262 .Case("le", 0x1)
2263 .Case("gt", 0x2)
2264 .Case("ge", 0x3)
2265 .Case("eq", 0x4)
2266 .Case("neq", 0x5)
2267 .Case("false", 0x6)
2268 .Case("true", 0x7)
2269 .Default(~0U);
Craig Topper78c424d2015-02-15 07:13:48 +00002270 if (ComparisonCode != ~0U) {
Craig Topper916708f2015-02-13 07:42:25 +00002271 Operands.push_back(X86Operand::CreateToken("vpcom", NameLoc));
2272
Jim Grosbach13760bd2015-05-30 01:25:56 +00002273 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
Craig Topper916708f2015-02-13 07:42:25 +00002274 getParser().getContext());
2275 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2276
Craig Topper78c424d2015-02-15 07:13:48 +00002277 PatchedName = PatchedName.substr(PatchedName.size() - CCIdx);
Craig Topper916708f2015-02-13 07:42:25 +00002278 }
2279 }
2280
Daniel Dunbar3e0c9792010-02-10 21:19:28 +00002281 Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
Daniel Dunbare1fdb0e2009-07-28 22:40:46 +00002282
Chris Lattner086a83a2010-09-08 05:17:37 +00002283 // Determine whether this is an instruction prefix.
Coby Tayreec54c5cb2017-08-21 07:50:15 +00002284 // FIXME:
2285 // Enhace prefixes integrity robustness. for example, following forms
2286 // are currently tolerated:
2287 // repz repnz <insn> ; GAS errors for the use of two similar prefixes
2288 // lock addq %rax, %rbx ; Destination operand must be of memory type
2289 // xacquire <insn> ; xacquire must be accompanied by 'lock'
2290 bool isPrefix = StringSwitch<bool>(Name)
2291 .Cases("lock",
2292 "rep", "repe",
2293 "repz", "repne",
2294 "repnz", "rex64",
2295 "data32", "data16", true)
2296 .Cases("xacquire", "xrelease", true)
2297 .Cases("acquire", "release", isParsingIntelSyntax())
2298 .Default(false);
Michael J. Spencer530ce852010-10-09 11:00:50 +00002299
Marina Yatsina5f5de9f2016-03-07 18:11:16 +00002300 bool CurlyAsEndOfStatement = false;
Chris Lattner086a83a2010-09-08 05:17:37 +00002301 // This does the actual operand parsing. Don't parse any more if we have a
2302 // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we
2303 // just want to parse the "lock" as the first instruction and the "incl" as
2304 // the next one.
2305 if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) {
Daniel Dunbar71527c12009-08-11 05:00:25 +00002306
2307 // Parse '*' modifier.
Alp Tokera5b88a52013-12-02 16:06:06 +00002308 if (getLexer().is(AsmToken::Star))
2309 Operands.push_back(X86Operand::CreateToken("*", consumeToken()));
Daniel Dunbar71527c12009-08-11 05:00:25 +00002310
Elena Demikhovskyc9657012014-02-20 06:34:39 +00002311 // Read the operands.
Kirill Bobyrev6afbaf02017-01-18 16:34:25 +00002312 while(1) {
David Blaikie960ea3f2014-06-08 16:18:35 +00002313 if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
2314 Operands.push_back(std::move(Op));
Michael Zuckerman1bee6342016-10-18 13:52:39 +00002315 if (HandleAVX512Operand(Operands, *Operands.back()))
Elena Demikhovsky89529742013-09-12 08:55:00 +00002316 return true;
Elena Demikhovskyc9657012014-02-20 06:34:39 +00002317 } else {
Elena Demikhovskyc9657012014-02-20 06:34:39 +00002318 return true;
Elena Demikhovsky89529742013-09-12 08:55:00 +00002319 }
Elena Demikhovskyc9657012014-02-20 06:34:39 +00002320 // check for comma and eat it
2321 if (getLexer().is(AsmToken::Comma))
2322 Parser.Lex();
2323 else
2324 break;
2325 }
Elena Demikhovsky89529742013-09-12 08:55:00 +00002326
Hiroshi Inouee9dea6e2017-07-13 06:48:39 +00002327 // In MS inline asm curly braces mark the beginning/end of a block,
2328 // therefore they should be interepreted as end of statement
Marina Yatsina5f5de9f2016-03-07 18:11:16 +00002329 CurlyAsEndOfStatement =
2330 isParsingIntelSyntax() && isParsingInlineAsm() &&
2331 (getLexer().is(AsmToken::LCurly) || getLexer().is(AsmToken::RCurly));
2332 if (getLexer().isNot(AsmToken::EndOfStatement) && !CurlyAsEndOfStatement)
Nirav Dave2364748a2016-09-16 18:30:20 +00002333 return TokError("unexpected token in argument list");
Elena Demikhovskyc9657012014-02-20 06:34:39 +00002334 }
Michael J. Spencer530ce852010-10-09 11:00:50 +00002335
Elena Demikhovskyc9657012014-02-20 06:34:39 +00002336 // Consume the EndOfStatement or the prefix separator Slash
Elena Demikhovsky9f09b3e2014-02-20 07:00:10 +00002337 if (getLexer().is(AsmToken::EndOfStatement) ||
2338 (isPrefix && getLexer().is(AsmToken::Slash)))
Elena Demikhovskyc9657012014-02-20 06:34:39 +00002339 Parser.Lex();
Marina Yatsina5f5de9f2016-03-07 18:11:16 +00002340 else if (CurlyAsEndOfStatement)
2341 // Add an actual EndOfStatement before the curly brace
2342 Info.AsmRewrites->emplace_back(AOK_EndOfStatement,
2343 getLexer().getTok().getLoc(), 0);
Daniel Dunbare1fdb0e2009-07-28 22:40:46 +00002344
Michael Zuckermanfd3fe9e2015-11-12 16:58:51 +00002345 // This is for gas compatibility and cannot be done in td.
2346 // Adding "p" for some floating point with no argument.
2347 // For example: fsub --> fsubp
2348 bool IsFp =
2349 Name == "fsub" || Name == "fdiv" || Name == "fsubr" || Name == "fdivr";
2350 if (IsFp && Operands.size() == 1) {
2351 const char *Repl = StringSwitch<const char *>(Name)
2352 .Case("fsub", "fsubp")
2353 .Case("fdiv", "fdivp")
2354 .Case("fsubr", "fsubrp")
2355 .Case("fdivr", "fdivrp");
2356 static_cast<X86Operand &>(*Operands[0]).setTokenValue(Repl);
2357 }
2358
Nirav Davef45fd2b2016-08-08 18:01:04 +00002359 // Moving a 32 or 16 bit value into a segment register has the same
2360 // behavior. Modify such instructions to always take shorter form.
2361 if ((Name == "mov" || Name == "movw" || Name == "movl") &&
2362 (Operands.size() == 3)) {
2363 X86Operand &Op1 = (X86Operand &)*Operands[1];
2364 X86Operand &Op2 = (X86Operand &)*Operands[2];
2365 SMLoc Loc = Op1.getEndLoc();
2366 if (Op1.isReg() && Op2.isReg() &&
2367 X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(
2368 Op2.getReg()) &&
2369 (X86MCRegisterClasses[X86::GR16RegClassID].contains(Op1.getReg()) ||
2370 X86MCRegisterClasses[X86::GR32RegClassID].contains(Op1.getReg()))) {
2371 // Change instruction name to match new instruction.
2372 if (Name != "mov" && Name[3] == (is16BitMode() ? 'l' : 'w')) {
2373 Name = is16BitMode() ? "movw" : "movl";
2374 Operands[0] = X86Operand::CreateToken(Name, NameLoc);
2375 }
2376 // Select the correct equivalent 16-/32-bit source register.
2377 unsigned Reg =
2378 getX86SubSuperRegisterOrZero(Op1.getReg(), is16BitMode() ? 16 : 32);
2379 Operands[1] = X86Operand::CreateReg(Reg, Loc, Loc);
2380 }
2381 }
2382
Nirav Dave8e103802016-06-29 19:54:27 +00002383 // This is a terrible hack to handle "out[s]?[bwl]? %al, (%dx)" ->
Chris Lattnerb6f8e822010-11-06 19:25:43 +00002384 // "outb %al, %dx". Out doesn't take a memory form, but this is a widely
2385 // documented form in various unofficial manuals, so a lot of code uses it.
Nirav Dave8e103802016-06-29 19:54:27 +00002386 if ((Name == "outb" || Name == "outsb" || Name == "outw" || Name == "outsw" ||
2387 Name == "outl" || Name == "outsl" || Name == "out" || Name == "outs") &&
Chris Lattnerb6f8e822010-11-06 19:25:43 +00002388 Operands.size() == 3) {
David Blaikie960ea3f2014-06-08 16:18:35 +00002389 X86Operand &Op = (X86Operand &)*Operands.back();
Chris Lattnerb6f8e822010-11-06 19:25:43 +00002390 if (Op.isMem() && Op.Mem.SegReg == 0 &&
2391 isa<MCConstantExpr>(Op.Mem.Disp) &&
2392 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
2393 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
2394 SMLoc Loc = Op.getEndLoc();
2395 Operands.back() = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
Chris Lattnerb6f8e822010-11-06 19:25:43 +00002396 }
2397 }
Nirav Dave8e103802016-06-29 19:54:27 +00002398 // Same hack for "in[s]?[bwl]? (%dx), %al" -> "inb %dx, %al".
2399 if ((Name == "inb" || Name == "insb" || Name == "inw" || Name == "insw" ||
2400 Name == "inl" || Name == "insl" || Name == "in" || Name == "ins") &&
Joerg Sonnenbergerb7e635d2011-02-22 20:40:09 +00002401 Operands.size() == 3) {
David Blaikie960ea3f2014-06-08 16:18:35 +00002402 X86Operand &Op = (X86Operand &)*Operands[1];
Joerg Sonnenbergerb7e635d2011-02-22 20:40:09 +00002403 if (Op.isMem() && Op.Mem.SegReg == 0 &&
2404 isa<MCConstantExpr>(Op.Mem.Disp) &&
2405 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
2406 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
2407 SMLoc Loc = Op.getEndLoc();
David Blaikie960ea3f2014-06-08 16:18:35 +00002408 Operands[1] = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
Joerg Sonnenbergerb7e635d2011-02-22 20:40:09 +00002409 }
2410 }
David Woodhouse4ce66062014-01-22 15:08:55 +00002411
Marina Yatsinab9f4f622016-01-19 15:37:56 +00002412 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 2> TmpOperands;
2413 bool HadVerifyError = false;
2414
David Woodhouse4ce66062014-01-22 15:08:55 +00002415 // Append default arguments to "ins[bwld]"
Marina Yatsinab9f4f622016-01-19 15:37:56 +00002416 if (Name.startswith("ins") &&
2417 (Operands.size() == 1 || Operands.size() == 3) &&
2418 (Name == "insb" || Name == "insw" || Name == "insl" || Name == "insd" ||
2419 Name == "ins")) {
2420
2421 AddDefaultSrcDestOperands(TmpOperands,
Michael Kupersteinffcc7662015-07-23 10:23:48 +00002422 X86Operand::CreateReg(X86::DX, NameLoc, NameLoc),
2423 DefaultMemDIOperand(NameLoc));
Marina Yatsinab9f4f622016-01-19 15:37:56 +00002424 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
Joerg Sonnenberger3fbfcc02011-03-18 11:59:40 +00002425 }
2426
David Woodhousec472b812014-01-22 15:08:49 +00002427 // Append default arguments to "outs[bwld]"
Marina Yatsinab9f4f622016-01-19 15:37:56 +00002428 if (Name.startswith("outs") &&
2429 (Operands.size() == 1 || Operands.size() == 3) &&
David Woodhousec472b812014-01-22 15:08:49 +00002430 (Name == "outsb" || Name == "outsw" || Name == "outsl" ||
Marina Yatsinab9f4f622016-01-19 15:37:56 +00002431 Name == "outsd" || Name == "outs")) {
2432 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
Michael Kupersteinffcc7662015-07-23 10:23:48 +00002433 X86Operand::CreateReg(X86::DX, NameLoc, NameLoc));
Marina Yatsinab9f4f622016-01-19 15:37:56 +00002434 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
Joerg Sonnenberger3fbfcc02011-03-18 11:59:40 +00002435 }
2436
David Woodhouse2ef8d9c2014-01-22 15:08:08 +00002437 // Transform "lods[bwlq]" into "lods[bwlq] ($SIREG)" for appropriate
2438 // values of $SIREG according to the mode. It would be nice if this
2439 // could be achieved with InstAlias in the tables.
Marina Yatsinab9f4f622016-01-19 15:37:56 +00002440 if (Name.startswith("lods") &&
2441 (Operands.size() == 1 || Operands.size() == 2) &&
Joerg Sonnenberger3fbfcc02011-03-18 11:59:40 +00002442 (Name == "lods" || Name == "lodsb" || Name == "lodsw" ||
Marina Yatsinab9f4f622016-01-19 15:37:56 +00002443 Name == "lodsl" || Name == "lodsd" || Name == "lodsq")) {
2444 TmpOperands.push_back(DefaultMemSIOperand(NameLoc));
2445 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2446 }
David Woodhouse2ef8d9c2014-01-22 15:08:08 +00002447
David Woodhouseb33c2ef2014-01-22 15:08:21 +00002448 // Transform "stos[bwlq]" into "stos[bwlq] ($DIREG)" for appropriate
2449 // values of $DIREG according to the mode. It would be nice if this
2450 // could be achieved with InstAlias in the tables.
Marina Yatsinab9f4f622016-01-19 15:37:56 +00002451 if (Name.startswith("stos") &&
2452 (Operands.size() == 1 || Operands.size() == 2) &&
Joerg Sonnenberger3fbfcc02011-03-18 11:59:40 +00002453 (Name == "stos" || Name == "stosb" || Name == "stosw" ||
Marina Yatsinab9f4f622016-01-19 15:37:56 +00002454 Name == "stosl" || Name == "stosd" || Name == "stosq")) {
2455 TmpOperands.push_back(DefaultMemDIOperand(NameLoc));
2456 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2457 }
Joerg Sonnenberger3fbfcc02011-03-18 11:59:40 +00002458
David Woodhouse20fe4802014-01-22 15:08:27 +00002459 // Transform "scas[bwlq]" into "scas[bwlq] ($DIREG)" for appropriate
2460 // values of $DIREG according to the mode. It would be nice if this
2461 // could be achieved with InstAlias in the tables.
Marina Yatsinab9f4f622016-01-19 15:37:56 +00002462 if (Name.startswith("scas") &&
2463 (Operands.size() == 1 || Operands.size() == 2) &&
David Woodhouse20fe4802014-01-22 15:08:27 +00002464 (Name == "scas" || Name == "scasb" || Name == "scasw" ||
Marina Yatsinab9f4f622016-01-19 15:37:56 +00002465 Name == "scasl" || Name == "scasd" || Name == "scasq")) {
2466 TmpOperands.push_back(DefaultMemDIOperand(NameLoc));
2467 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2468 }
David Woodhouse20fe4802014-01-22 15:08:27 +00002469
David Woodhouse9bbf7ca2014-01-22 15:08:36 +00002470 // Add default SI and DI operands to "cmps[bwlq]".
2471 if (Name.startswith("cmps") &&
Marina Yatsinab9f4f622016-01-19 15:37:56 +00002472 (Operands.size() == 1 || Operands.size() == 3) &&
David Woodhouse9bbf7ca2014-01-22 15:08:36 +00002473 (Name == "cmps" || Name == "cmpsb" || Name == "cmpsw" ||
2474 Name == "cmpsl" || Name == "cmpsd" || Name == "cmpsq")) {
Marina Yatsinab9f4f622016-01-19 15:37:56 +00002475 AddDefaultSrcDestOperands(TmpOperands, DefaultMemDIOperand(NameLoc),
2476 DefaultMemSIOperand(NameLoc));
2477 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
David Woodhouse9bbf7ca2014-01-22 15:08:36 +00002478 }
2479
David Woodhouse6f417de2014-01-22 15:08:42 +00002480 // Add default SI and DI operands to "movs[bwlq]".
Marina Yatsinab9f4f622016-01-19 15:37:56 +00002481 if (((Name.startswith("movs") &&
2482 (Name == "movs" || Name == "movsb" || Name == "movsw" ||
2483 Name == "movsl" || Name == "movsd" || Name == "movsq")) ||
2484 (Name.startswith("smov") &&
2485 (Name == "smov" || Name == "smovb" || Name == "smovw" ||
2486 Name == "smovl" || Name == "smovd" || Name == "smovq"))) &&
2487 (Operands.size() == 1 || Operands.size() == 3)) {
Coby Tayree94ddbb42016-11-21 15:50:56 +00002488 if (Name == "movsd" && Operands.size() == 1 && !isParsingIntelSyntax())
Marina Yatsinab9f4f622016-01-19 15:37:56 +00002489 Operands.back() = X86Operand::CreateToken("movsl", NameLoc);
2490 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
2491 DefaultMemDIOperand(NameLoc));
2492 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2493 }
2494
2495 // Check if we encountered an error for one the string insturctions
2496 if (HadVerifyError) {
2497 return HadVerifyError;
David Woodhouse6f417de2014-01-22 15:08:42 +00002498 }
2499
Chris Lattner4bd21712010-09-15 04:33:27 +00002500 // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>. Canonicalize to
Chris Lattner30561ab2010-09-11 16:32:12 +00002501 // "shift <op>".
Daniel Dunbar18fc3442010-03-13 00:47:29 +00002502 if ((Name.startswith("shr") || Name.startswith("sar") ||
Chris Lattner64f91b92010-11-06 21:23:40 +00002503 Name.startswith("shl") || Name.startswith("sal") ||
2504 Name.startswith("rcl") || Name.startswith("rcr") ||
2505 Name.startswith("rol") || Name.startswith("ror")) &&
Chris Lattner4cfbcdc2010-09-06 18:32:06 +00002506 Operands.size() == 3) {
Devang Patel9a9bb5c2012-01-30 20:02:42 +00002507 if (isParsingIntelSyntax()) {
Devang Patela410ed32012-01-24 21:43:36 +00002508 // Intel syntax
David Blaikie960ea3f2014-06-08 16:18:35 +00002509 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[2]);
2510 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2511 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
Craig Topper6bf3ed42012-07-18 04:59:16 +00002512 Operands.pop_back();
Devang Patela410ed32012-01-24 21:43:36 +00002513 } else {
David Blaikie960ea3f2014-06-08 16:18:35 +00002514 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2515 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2516 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
Craig Topper6bf3ed42012-07-18 04:59:16 +00002517 Operands.erase(Operands.begin() + 1);
Chris Lattner4cfbcdc2010-09-06 18:32:06 +00002518 }
Daniel Dunbarfbd12cc2010-03-20 22:36:38 +00002519 }
Chad Rosier51afe632012-06-27 22:34:28 +00002520
Chris Lattnerfc4fe002011-04-09 19:41:05 +00002521 // Transforms "int $3" into "int3" as a size optimization. We can't write an
2522 // instalias with an immediate operand yet.
2523 if (Name == "int" && Operands.size() == 2) {
David Blaikie960ea3f2014-06-08 16:18:35 +00002524 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
Duncan P. N. Exon Smithd5313222015-07-23 19:27:07 +00002525 if (Op1.isImm())
2526 if (auto *CE = dyn_cast<MCConstantExpr>(Op1.getImm()))
2527 if (CE->getValue() == 3) {
2528 Operands.erase(Operands.begin() + 1);
2529 static_cast<X86Operand &>(*Operands[0]).setTokenValue("int3");
2530 }
Chris Lattnerfc4fe002011-04-09 19:41:05 +00002531 }
Michael J. Spencer530ce852010-10-09 11:00:50 +00002532
Marina Yatsinad9658d12016-01-19 16:35:38 +00002533 // Transforms "xlat mem8" into "xlatb"
2534 if ((Name == "xlat" || Name == "xlatb") && Operands.size() == 2) {
2535 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2536 if (Op1.isMem8()) {
2537 Warning(Op1.getStartLoc(), "memory operand is only for determining the "
2538 "size, (R|E)BX will be used for the location");
2539 Operands.pop_back();
2540 static_cast<X86Operand &>(*Operands[0]).setTokenValue("xlatb");
2541 }
2542 }
2543
Chris Lattnerf29c0b62010-01-14 22:21:20 +00002544 return false;
Daniel Dunbar3c2a8932009-07-20 18:55:04 +00002545}
2546
David Blaikie960ea3f2014-06-08 16:18:35 +00002547bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) {
Aaron Ballmana81264b2016-05-23 15:52:59 +00002548 return false;
Devang Patelde47cce2012-01-18 22:42:29 +00002549}
2550
Ranjeet Singh86ecbb72015-06-30 12:32:53 +00002551static const char *getSubtargetFeatureName(uint64_t Val);
Evgeniy Stepanov49e26252014-03-14 08:58:04 +00002552
David Blaikie960ea3f2014-06-08 16:18:35 +00002553void X86AsmParser::EmitInstruction(MCInst &Inst, OperandVector &Operands,
2554 MCStreamer &Out) {
Evgeniy Stepanov77ad8662014-07-31 09:11:04 +00002555 Instrumentation->InstrumentAndEmitInstruction(Inst, Operands, getContext(),
2556 MII, Out);
Evgeniy Stepanov49e26252014-03-14 08:58:04 +00002557}
2558
David Blaikie960ea3f2014-06-08 16:18:35 +00002559bool X86AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2560 OperandVector &Operands,
Tim Northover26bb14e2014-08-18 11:49:42 +00002561 MCStreamer &Out, uint64_t &ErrorInfo,
David Blaikie960ea3f2014-06-08 16:18:35 +00002562 bool MatchingInlineAsm) {
Reid Klecknerf6fb7802014-08-26 20:32:34 +00002563 if (isParsingIntelSyntax())
2564 return MatchAndEmitIntelInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
Ranjeet Singh86ecbb72015-06-30 12:32:53 +00002565 MatchingInlineAsm);
Reid Klecknerf6fb7802014-08-26 20:32:34 +00002566 return MatchAndEmitATTInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
Ranjeet Singh86ecbb72015-06-30 12:32:53 +00002567 MatchingInlineAsm);
Reid Klecknerf6fb7802014-08-26 20:32:34 +00002568}
Daniel Dunbar2ecc3bb2010-08-12 00:55:38 +00002569
Reid Klecknerf6fb7802014-08-26 20:32:34 +00002570void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op,
2571 OperandVector &Operands, MCStreamer &Out,
2572 bool MatchingInlineAsm) {
Chris Lattnera63292a2010-09-29 01:50:45 +00002573 // FIXME: This should be replaced with a real .td file alias mechanism.
Chad Rosier3b1336c2012-08-28 23:57:47 +00002574 // Also, MatchInstructionImpl should actually *do* the EmitInstruction
Chris Lattner4869d342010-11-06 19:57:21 +00002575 // call.
Reid Klecknerb1f2d2f2014-07-31 00:07:33 +00002576 const char *Repl = StringSwitch<const char *>(Op.getToken())
2577 .Case("finit", "fninit")
2578 .Case("fsave", "fnsave")
2579 .Case("fstcw", "fnstcw")
2580 .Case("fstcww", "fnstcw")
2581 .Case("fstenv", "fnstenv")
2582 .Case("fstsw", "fnstsw")
2583 .Case("fstsww", "fnstsw")
2584 .Case("fclex", "fnclex")
2585 .Default(nullptr);
2586 if (Repl) {
Chris Lattnera63292a2010-09-29 01:50:45 +00002587 MCInst Inst;
2588 Inst.setOpcode(X86::WAIT);
Jim Grosbach8f28dbd2012-01-27 00:51:27 +00002589 Inst.setLoc(IDLoc);
Chad Rosier4453e842012-10-12 23:09:25 +00002590 if (!MatchingInlineAsm)
Evgeniy Stepanov49e26252014-03-14 08:58:04 +00002591 EmitInstruction(Inst, Operands, Out);
Chris Lattneradc0dbe2010-09-30 16:39:29 +00002592 Operands[0] = X86Operand::CreateToken(Repl, IDLoc);
Chris Lattnera63292a2010-09-29 01:50:45 +00002593 }
Reid Klecknerf6fb7802014-08-26 20:32:34 +00002594}
2595
Ranjeet Singh86ecbb72015-06-30 12:32:53 +00002596bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
Reid Klecknerf6fb7802014-08-26 20:32:34 +00002597 bool MatchingInlineAsm) {
Ranjeet Singh86ecbb72015-06-30 12:32:53 +00002598 assert(ErrorInfo && "Unknown missing feature!");
Reid Klecknerf6fb7802014-08-26 20:32:34 +00002599 SmallString<126> Msg;
2600 raw_svector_ostream OS(Msg);
2601 OS << "instruction requires:";
Ranjeet Singh86ecbb72015-06-30 12:32:53 +00002602 uint64_t Mask = 1;
2603 for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
2604 if (ErrorInfo & Mask)
2605 OS << ' ' << getSubtargetFeatureName(ErrorInfo & Mask);
2606 Mask <<= 1;
Reid Klecknerf6fb7802014-08-26 20:32:34 +00002607 }
Nirav Dave2364748a2016-09-16 18:30:20 +00002608 return Error(IDLoc, OS.str(), SMRange(), MatchingInlineAsm);
Reid Klecknerf6fb7802014-08-26 20:32:34 +00002609}
2610
2611bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
2612 OperandVector &Operands,
2613 MCStreamer &Out,
2614 uint64_t &ErrorInfo,
2615 bool MatchingInlineAsm) {
2616 assert(!Operands.empty() && "Unexpect empty operand list!");
2617 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2618 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
Nirav Dave2364748a2016-09-16 18:30:20 +00002619 SMRange EmptyRange = None;
Reid Klecknerf6fb7802014-08-26 20:32:34 +00002620
2621 // First, handle aliases that expand to multiple instructions.
2622 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
Michael J. Spencer530ce852010-10-09 11:00:50 +00002623
Chris Lattner628fbec2010-09-06 21:54:15 +00002624 bool WasOriginallyInvalidOperand = false;
Chris Lattnerb44fd242010-09-29 01:42:58 +00002625 MCInst Inst;
Michael J. Spencer530ce852010-10-09 11:00:50 +00002626
Daniel Dunbar9b816a12010-05-04 16:12:42 +00002627 // First, try a direct match.
Nirav Dave6477ce22016-09-26 19:33:36 +00002628 switch (MatchInstruction(Operands, Inst, ErrorInfo, MatchingInlineAsm,
2629 isParsingIntelSyntax())) {
Craig Topper589ceee2015-01-03 08:16:34 +00002630 default: llvm_unreachable("Unexpected match result!");
Chris Lattnerb4be28f2010-09-06 20:08:02 +00002631 case Match_Success:
Devang Patelde47cce2012-01-18 22:42:29 +00002632 // Some instructions need post-processing to, for example, tweak which
2633 // encoding is selected. Loop on it while changes happen so the
Chad Rosier51afe632012-06-27 22:34:28 +00002634 // individual transformations can chain off each other.
Chad Rosier4453e842012-10-12 23:09:25 +00002635 if (!MatchingInlineAsm)
Chad Rosierf4e35dc2012-10-01 23:45:51 +00002636 while (processInstruction(Inst, Operands))
2637 ;
Devang Patelde47cce2012-01-18 22:42:29 +00002638
Jim Grosbach8f28dbd2012-01-27 00:51:27 +00002639 Inst.setLoc(IDLoc);
Chad Rosier4453e842012-10-12 23:09:25 +00002640 if (!MatchingInlineAsm)
Evgeniy Stepanov49e26252014-03-14 08:58:04 +00002641 EmitInstruction(Inst, Operands, Out);
Chad Rosierf4e35dc2012-10-01 23:45:51 +00002642 Opcode = Inst.getOpcode();
Daniel Dunbar9b816a12010-05-04 16:12:42 +00002643 return false;
Reid Klecknerf6fb7802014-08-26 20:32:34 +00002644 case Match_MissingFeature:
Ranjeet Singh86ecbb72015-06-30 12:32:53 +00002645 return ErrorMissingFeature(IDLoc, ErrorInfo, MatchingInlineAsm);
Chris Lattner628fbec2010-09-06 21:54:15 +00002646 case Match_InvalidOperand:
2647 WasOriginallyInvalidOperand = true;
2648 break;
2649 case Match_MnemonicFail:
Chris Lattnerb4be28f2010-09-06 20:08:02 +00002650 break;
2651 }
Daniel Dunbar9b816a12010-05-04 16:12:42 +00002652
Daniel Dunbar9b816a12010-05-04 16:12:42 +00002653 // FIXME: Ideally, we would only attempt suffix matches for things which are
2654 // valid prefixes, and we could just infer the right unambiguous
2655 // type. However, that requires substantially more matcher support than the
2656 // following hack.
Michael J. Spencer530ce852010-10-09 11:00:50 +00002657
Daniel Dunbar9b816a12010-05-04 16:12:42 +00002658 // Change the operand to point to a temporary token.
David Blaikie960ea3f2014-06-08 16:18:35 +00002659 StringRef Base = Op.getToken();
Daniel Dunbar2ecc3bb2010-08-12 00:55:38 +00002660 SmallString<16> Tmp;
2661 Tmp += Base;
2662 Tmp += ' ';
Yaron Keren075759a2015-03-30 15:42:36 +00002663 Op.setTokenValue(Tmp);
Daniel Dunbar9b816a12010-05-04 16:12:42 +00002664
Chris Lattnerfab94132010-11-06 18:28:02 +00002665 // If this instruction starts with an 'f', then it is a floating point stack
2666 // instruction. These come in up to three forms for 32-bit, 64-bit, and
2667 // 80-bit floating point, which use the suffixes s,l,t respectively.
2668 //
2669 // Otherwise, we assume that this may be an integer instruction, which comes
2670 // in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively.
2671 const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0";
Chad Rosier51afe632012-06-27 22:34:28 +00002672
Daniel Dunbar9b816a12010-05-04 16:12:42 +00002673 // Check for the various suffix matches.
Tim Northover26bb14e2014-08-18 11:49:42 +00002674 uint64_t ErrorInfoIgnore;
Ranjeet Singh86ecbb72015-06-30 12:32:53 +00002675 uint64_t ErrorInfoMissingFeature = 0; // Init suppresses compiler warnings.
Reid Kleckner7b1e1a02014-07-30 22:23:11 +00002676 unsigned Match[4];
Chad Rosier51afe632012-06-27 22:34:28 +00002677
Reid Kleckner7b1e1a02014-07-30 22:23:11 +00002678 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I) {
2679 Tmp.back() = Suffixes[I];
Nirav Dave6477ce22016-09-26 19:33:36 +00002680 Match[I] = MatchInstruction(Operands, Inst, ErrorInfoIgnore,
2681 MatchingInlineAsm, isParsingIntelSyntax());
Reid Kleckner7b1e1a02014-07-30 22:23:11 +00002682 // If this returned as a missing feature failure, remember that.
2683 if (Match[I] == Match_MissingFeature)
Ranjeet Singh86ecbb72015-06-30 12:32:53 +00002684 ErrorInfoMissingFeature = ErrorInfoIgnore;
Reid Kleckner7b1e1a02014-07-30 22:23:11 +00002685 }
Daniel Dunbar9b816a12010-05-04 16:12:42 +00002686
2687 // Restore the old token.
David Blaikie960ea3f2014-06-08 16:18:35 +00002688 Op.setTokenValue(Base);
Daniel Dunbar9b816a12010-05-04 16:12:42 +00002689
2690 // If exactly one matched, then we treat that as a successful match (and the
2691 // instruction will already have been filled in correctly, since the failing
2692 // matches won't have modified it).
Chris Lattnerb4be28f2010-09-06 20:08:02 +00002693 unsigned NumSuccessfulMatches =
Reid Kleckner7b1e1a02014-07-30 22:23:11 +00002694 std::count(std::begin(Match), std::end(Match), Match_Success);
Chris Lattnerb44fd242010-09-29 01:42:58 +00002695 if (NumSuccessfulMatches == 1) {
Jim Grosbach8f28dbd2012-01-27 00:51:27 +00002696 Inst.setLoc(IDLoc);
Chad Rosier4453e842012-10-12 23:09:25 +00002697 if (!MatchingInlineAsm)
Evgeniy Stepanov49e26252014-03-14 08:58:04 +00002698 EmitInstruction(Inst, Operands, Out);
Chad Rosierf4e35dc2012-10-01 23:45:51 +00002699 Opcode = Inst.getOpcode();
Daniel Dunbar9b816a12010-05-04 16:12:42 +00002700 return false;
Chris Lattnerb44fd242010-09-29 01:42:58 +00002701 }
Daniel Dunbar9b816a12010-05-04 16:12:42 +00002702
Chris Lattnerb4be28f2010-09-06 20:08:02 +00002703 // Otherwise, the match failed, try to produce a decent error message.
Daniel Dunbar2ecc3bb2010-08-12 00:55:38 +00002704
Daniel Dunbar7d7b4d12010-08-12 00:55:42 +00002705 // If we had multiple suffix matches, then identify this as an ambiguous
2706 // match.
Chris Lattnerb4be28f2010-09-06 20:08:02 +00002707 if (NumSuccessfulMatches > 1) {
Daniel Dunbar7d7b4d12010-08-12 00:55:42 +00002708 char MatchChars[4];
2709 unsigned NumMatches = 0;
Reid Kleckner7b1e1a02014-07-30 22:23:11 +00002710 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I)
2711 if (Match[I] == Match_Success)
2712 MatchChars[NumMatches++] = Suffixes[I];
Daniel Dunbar7d7b4d12010-08-12 00:55:42 +00002713
Alp Tokere69170a2014-06-26 22:52:05 +00002714 SmallString<126> Msg;
2715 raw_svector_ostream OS(Msg);
Daniel Dunbar7d7b4d12010-08-12 00:55:42 +00002716 OS << "ambiguous instructions require an explicit suffix (could be ";
2717 for (unsigned i = 0; i != NumMatches; ++i) {
2718 if (i != 0)
2719 OS << ", ";
2720 if (i + 1 == NumMatches)
2721 OS << "or ";
2722 OS << "'" << Base << MatchChars[i] << "'";
2723 }
2724 OS << ")";
Nirav Dave2364748a2016-09-16 18:30:20 +00002725 Error(IDLoc, OS.str(), EmptyRange, MatchingInlineAsm);
Chris Lattnerb4be28f2010-09-06 20:08:02 +00002726 return true;
Daniel Dunbar7d7b4d12010-08-12 00:55:42 +00002727 }
Michael J. Spencer530ce852010-10-09 11:00:50 +00002728
Chris Lattner628fbec2010-09-06 21:54:15 +00002729 // Okay, we know that none of the variants matched successfully.
Michael J. Spencer530ce852010-10-09 11:00:50 +00002730
Chris Lattner628fbec2010-09-06 21:54:15 +00002731 // If all of the instructions reported an invalid mnemonic, then the original
2732 // mnemonic was invalid.
Reid Kleckner7b1e1a02014-07-30 22:23:11 +00002733 if (std::count(std::begin(Match), std::end(Match), Match_MnemonicFail) == 4) {
Chris Lattner339cc7b2010-09-06 22:11:18 +00002734 if (!WasOriginallyInvalidOperand) {
Benjamin Kramerd416bae2011-10-16 11:28:29 +00002735 return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'",
Nirav Dave2364748a2016-09-16 18:30:20 +00002736 Op.getLocRange(), MatchingInlineAsm);
Chris Lattner339cc7b2010-09-06 22:11:18 +00002737 }
2738
2739 // Recover location info for the operand if we know which was the problem.
Tim Northover26bb14e2014-08-18 11:49:42 +00002740 if (ErrorInfo != ~0ULL) {
Chad Rosier49963552012-10-13 00:26:04 +00002741 if (ErrorInfo >= Operands.size())
Nirav Dave2364748a2016-09-16 18:30:20 +00002742 return Error(IDLoc, "too few operands for instruction", EmptyRange,
2743 MatchingInlineAsm);
Michael J. Spencer530ce852010-10-09 11:00:50 +00002744
David Blaikie960ea3f2014-06-08 16:18:35 +00002745 X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo];
2746 if (Operand.getStartLoc().isValid()) {
2747 SMRange OperandRange = Operand.getLocRange();
2748 return Error(Operand.getStartLoc(), "invalid operand for instruction",
Chad Rosier4453e842012-10-12 23:09:25 +00002749 OperandRange, MatchingInlineAsm);
Chris Lattnera3a06812011-10-16 04:47:35 +00002750 }
Chris Lattner339cc7b2010-09-06 22:11:18 +00002751 }
2752
Nirav Dave2364748a2016-09-16 18:30:20 +00002753 return Error(IDLoc, "invalid operand for instruction", EmptyRange,
Chad Rosier4453e842012-10-12 23:09:25 +00002754 MatchingInlineAsm);
Chris Lattner628fbec2010-09-06 21:54:15 +00002755 }
Michael J. Spencer530ce852010-10-09 11:00:50 +00002756
Chris Lattnerb4be28f2010-09-06 20:08:02 +00002757 // If one instruction matched with a missing feature, report this as a
2758 // missing feature.
Reid Kleckner7b1e1a02014-07-30 22:23:11 +00002759 if (std::count(std::begin(Match), std::end(Match),
2760 Match_MissingFeature) == 1) {
Ranjeet Singh86ecbb72015-06-30 12:32:53 +00002761 ErrorInfo = ErrorInfoMissingFeature;
2762 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
Reid Klecknerf6fb7802014-08-26 20:32:34 +00002763 MatchingInlineAsm);
Chris Lattnerb4be28f2010-09-06 20:08:02 +00002764 }
Michael J. Spencer530ce852010-10-09 11:00:50 +00002765
Chris Lattner628fbec2010-09-06 21:54:15 +00002766 // If one instruction matched with an invalid operand, report this as an
2767 // operand failure.
Reid Kleckner7b1e1a02014-07-30 22:23:11 +00002768 if (std::count(std::begin(Match), std::end(Match),
2769 Match_InvalidOperand) == 1) {
Nirav Dave2364748a2016-09-16 18:30:20 +00002770 return Error(IDLoc, "invalid operand for instruction", EmptyRange,
Reid Klecknerf6fb7802014-08-26 20:32:34 +00002771 MatchingInlineAsm);
Chris Lattner628fbec2010-09-06 21:54:15 +00002772 }
Michael J. Spencer530ce852010-10-09 11:00:50 +00002773
Chris Lattnerb4be28f2010-09-06 20:08:02 +00002774 // If all of these were an outright failure, report it in a useless way.
Chad Rosier3d4bc622012-08-21 19:36:59 +00002775 Error(IDLoc, "unknown use of instruction mnemonic without a size suffix",
Nirav Dave2364748a2016-09-16 18:30:20 +00002776 EmptyRange, MatchingInlineAsm);
Daniel Dunbar9b816a12010-05-04 16:12:42 +00002777 return true;
2778}
2779
Reid Klecknerf6fb7802014-08-26 20:32:34 +00002780bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
2781 OperandVector &Operands,
2782 MCStreamer &Out,
2783 uint64_t &ErrorInfo,
2784 bool MatchingInlineAsm) {
2785 assert(!Operands.empty() && "Unexpect empty operand list!");
2786 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2787 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
2788 StringRef Mnemonic = Op.getToken();
Nirav Dave2364748a2016-09-16 18:30:20 +00002789 SMRange EmptyRange = None;
Nirav Daveee554e62016-10-06 15:28:08 +00002790 StringRef Base = Op.getToken();
Reid Klecknerf6fb7802014-08-26 20:32:34 +00002791
2792 // First, handle aliases that expand to multiple instructions.
2793 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2794
2795 MCInst Inst;
2796
2797 // Find one unsized memory operand, if present.
2798 X86Operand *UnsizedMemOp = nullptr;
2799 for (const auto &Op : Operands) {
2800 X86Operand *X86Op = static_cast<X86Operand *>(Op.get());
Reid Kleckner6d2ea6e2017-05-04 18:19:52 +00002801 if (X86Op->isMemUnsized()) {
2802 UnsizedMemOp = X86Op;
Coby Tayree49b37332016-11-22 09:30:29 +00002803 // Have we found an unqualified memory operand,
2804 // break. IA allows only one memory operand.
2805 break;
2806 }
Reid Klecknerf6fb7802014-08-26 20:32:34 +00002807 }
2808
2809 // Allow some instructions to have implicitly pointer-sized operands. This is
2810 // compatible with gas.
2811 if (UnsizedMemOp) {
2812 static const char *const PtrSizedInstrs[] = {"call", "jmp", "push"};
2813 for (const char *Instr : PtrSizedInstrs) {
2814 if (Mnemonic == Instr) {
Craig Topper055845f2015-01-02 07:02:25 +00002815 UnsizedMemOp->Mem.Size = getPointerWidth();
Reid Klecknerf6fb7802014-08-26 20:32:34 +00002816 break;
2817 }
2818 }
2819 }
2820
Nirav Daveee554e62016-10-06 15:28:08 +00002821 SmallVector<unsigned, 8> Match;
2822 uint64_t ErrorInfoMissingFeature = 0;
2823
2824 // If unsized push has immediate operand we should default the default pointer
2825 // size for the size.
2826 if (Mnemonic == "push" && Operands.size() == 2) {
2827 auto *X86Op = static_cast<X86Operand *>(Operands[1].get());
2828 if (X86Op->isImm()) {
2829 // If it's not a constant fall through and let remainder take care of it.
2830 const auto *CE = dyn_cast<MCConstantExpr>(X86Op->getImm());
2831 unsigned Size = getPointerWidth();
2832 if (CE &&
2833 (isIntN(Size, CE->getValue()) || isUIntN(Size, CE->getValue()))) {
2834 SmallString<16> Tmp;
2835 Tmp += Base;
2836 Tmp += (is64BitMode())
2837 ? "q"
2838 : (is32BitMode()) ? "l" : (is16BitMode()) ? "w" : " ";
2839 Op.setTokenValue(Tmp);
2840 // Do match in ATT mode to allow explicit suffix usage.
2841 Match.push_back(MatchInstruction(Operands, Inst, ErrorInfo,
2842 MatchingInlineAsm,
2843 false /*isParsingIntelSyntax()*/));
2844 Op.setTokenValue(Base);
2845 }
2846 }
2847 }
2848
Reid Klecknerf6fb7802014-08-26 20:32:34 +00002849 // If an unsized memory operand is present, try to match with each memory
2850 // operand size. In Intel assembly, the size is not part of the instruction
2851 // mnemonic.
Reid Klecknerf6fb7802014-08-26 20:32:34 +00002852 if (UnsizedMemOp && UnsizedMemOp->isMemUnsized()) {
Ahmed Bougachad65f7872014-12-03 02:03:26 +00002853 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
Reid Klecknerf6fb7802014-08-26 20:32:34 +00002854 for (unsigned Size : MopSizes) {
2855 UnsizedMemOp->Mem.Size = Size;
2856 uint64_t ErrorInfoIgnore;
Reid Kleckner7b7a5992014-08-27 20:10:38 +00002857 unsigned LastOpcode = Inst.getOpcode();
Nirav Dave6477ce22016-09-26 19:33:36 +00002858 unsigned M = MatchInstruction(Operands, Inst, ErrorInfoIgnore,
2859 MatchingInlineAsm, isParsingIntelSyntax());
Reid Kleckner7b7a5992014-08-27 20:10:38 +00002860 if (Match.empty() || LastOpcode != Inst.getOpcode())
2861 Match.push_back(M);
2862
Reid Klecknerf6fb7802014-08-26 20:32:34 +00002863 // If this returned as a missing feature failure, remember that.
2864 if (Match.back() == Match_MissingFeature)
Ranjeet Singh86ecbb72015-06-30 12:32:53 +00002865 ErrorInfoMissingFeature = ErrorInfoIgnore;
Reid Klecknerf6fb7802014-08-26 20:32:34 +00002866 }
Reid Kleckner7b7a5992014-08-27 20:10:38 +00002867
2868 // Restore the size of the unsized memory operand if we modified it.
Reid Kleckner6d2ea6e2017-05-04 18:19:52 +00002869 UnsizedMemOp->Mem.Size = 0;
Reid Kleckner7b7a5992014-08-27 20:10:38 +00002870 }
2871
2872 // If we haven't matched anything yet, this is not a basic integer or FPU
Saleem Abdulrasoolc3f8ad32015-01-16 20:16:06 +00002873 // operation. There shouldn't be any ambiguity in our mnemonic table, so try
Reid Kleckner7b7a5992014-08-27 20:10:38 +00002874 // matching with the unsized operand.
2875 if (Match.empty()) {
Nirav Dave6477ce22016-09-26 19:33:36 +00002876 Match.push_back(MatchInstruction(
2877 Operands, Inst, ErrorInfo, MatchingInlineAsm, isParsingIntelSyntax()));
Reid Klecknerf6fb7802014-08-26 20:32:34 +00002878 // If this returned as a missing feature failure, remember that.
2879 if (Match.back() == Match_MissingFeature)
Ranjeet Singh86ecbb72015-06-30 12:32:53 +00002880 ErrorInfoMissingFeature = ErrorInfo;
Reid Klecknerf6fb7802014-08-26 20:32:34 +00002881 }
2882
2883 // Restore the size of the unsized memory operand if we modified it.
2884 if (UnsizedMemOp)
2885 UnsizedMemOp->Mem.Size = 0;
2886
2887 // If it's a bad mnemonic, all results will be the same.
2888 if (Match.back() == Match_MnemonicFail) {
Reid Klecknerf6fb7802014-08-26 20:32:34 +00002889 return Error(IDLoc, "invalid instruction mnemonic '" + Mnemonic + "'",
Nirav Dave2364748a2016-09-16 18:30:20 +00002890 Op.getLocRange(), MatchingInlineAsm);
Reid Klecknerf6fb7802014-08-26 20:32:34 +00002891 }
2892
Reid Kleckner6d2ea6e2017-05-04 18:19:52 +00002893 unsigned NumSuccessfulMatches =
2894 std::count(std::begin(Match), std::end(Match), Match_Success);
2895
2896 // If matching was ambiguous and we had size information from the frontend,
2897 // try again with that. This handles cases like "movxz eax, m8/m16".
2898 if (UnsizedMemOp && NumSuccessfulMatches > 1 &&
2899 UnsizedMemOp->getMemFrontendSize()) {
2900 UnsizedMemOp->Mem.Size = UnsizedMemOp->getMemFrontendSize();
2901 unsigned M = MatchInstruction(
2902 Operands, Inst, ErrorInfo, MatchingInlineAsm, isParsingIntelSyntax());
2903 if (M == Match_Success)
2904 NumSuccessfulMatches = 1;
2905
2906 // Add a rewrite that encodes the size information we used from the
2907 // frontend.
2908 InstInfo->AsmRewrites->emplace_back(
2909 AOK_SizeDirective, UnsizedMemOp->getStartLoc(),
2910 /*Len=*/0, UnsizedMemOp->getMemFrontendSize());
2911 }
2912
Reid Klecknerf6fb7802014-08-26 20:32:34 +00002913 // If exactly one matched, then we treat that as a successful match (and the
2914 // instruction will already have been filled in correctly, since the failing
2915 // matches won't have modified it).
Reid Klecknerf6fb7802014-08-26 20:32:34 +00002916 if (NumSuccessfulMatches == 1) {
2917 // Some instructions need post-processing to, for example, tweak which
2918 // encoding is selected. Loop on it while changes happen so the individual
2919 // transformations can chain off each other.
2920 if (!MatchingInlineAsm)
2921 while (processInstruction(Inst, Operands))
2922 ;
2923 Inst.setLoc(IDLoc);
2924 if (!MatchingInlineAsm)
2925 EmitInstruction(Inst, Operands, Out);
2926 Opcode = Inst.getOpcode();
2927 return false;
2928 } else if (NumSuccessfulMatches > 1) {
2929 assert(UnsizedMemOp &&
2930 "multiple matches only possible with unsized memory operands");
Reid Klecknerf6fb7802014-08-26 20:32:34 +00002931 return Error(UnsizedMemOp->getStartLoc(),
2932 "ambiguous operand size for instruction '" + Mnemonic + "\'",
Reid Kleckner6d2ea6e2017-05-04 18:19:52 +00002933 UnsizedMemOp->getLocRange());
Reid Klecknerf6fb7802014-08-26 20:32:34 +00002934 }
2935
2936 // If one instruction matched with a missing feature, report this as a
2937 // missing feature.
2938 if (std::count(std::begin(Match), std::end(Match),
2939 Match_MissingFeature) == 1) {
Ranjeet Singh86ecbb72015-06-30 12:32:53 +00002940 ErrorInfo = ErrorInfoMissingFeature;
Reid Klecknerf6fb7802014-08-26 20:32:34 +00002941 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
2942 MatchingInlineAsm);
2943 }
2944
2945 // If one instruction matched with an invalid operand, report this as an
2946 // operand failure.
2947 if (std::count(std::begin(Match), std::end(Match),
2948 Match_InvalidOperand) == 1) {
Nirav Dave2364748a2016-09-16 18:30:20 +00002949 return Error(IDLoc, "invalid operand for instruction", EmptyRange,
Reid Klecknerf6fb7802014-08-26 20:32:34 +00002950 MatchingInlineAsm);
2951 }
2952
2953 // If all of these were an outright failure, report it in a useless way.
Nirav Dave2364748a2016-09-16 18:30:20 +00002954 return Error(IDLoc, "unknown instruction mnemonic", EmptyRange,
Reid Klecknerf6fb7802014-08-26 20:32:34 +00002955 MatchingInlineAsm);
2956}
2957
Nico Weber42f79db2014-07-17 20:24:55 +00002958bool X86AsmParser::OmitRegisterFromClobberLists(unsigned RegNo) {
2959 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo);
2960}
Daniel Dunbar9b816a12010-05-04 16:12:42 +00002961
Devang Patel4a6e7782012-01-12 18:03:40 +00002962bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
Rafael Espindola961d4692014-11-11 05:18:41 +00002963 MCAsmParser &Parser = getParser();
Chris Lattner72c0b592010-10-30 17:38:55 +00002964 StringRef IDVal = DirectiveID.getIdentifier();
2965 if (IDVal == ".word")
2966 return ParseDirectiveWord(2, DirectiveID.getLoc());
Evan Cheng481ebb02011-07-27 00:38:12 +00002967 else if (IDVal.startswith(".code"))
2968 return ParseDirectiveCode(IDVal, DirectiveID.getLoc());
Chad Rosier6f8d8b22012-09-10 20:54:39 +00002969 else if (IDVal.startswith(".att_syntax")) {
Andrew V. Tischenkoc3c67232017-04-26 09:56:59 +00002970 getParser().setParsingInlineAsm(false);
Reid Klecknerce63b792014-08-06 23:21:13 +00002971 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2972 if (Parser.getTok().getString() == "prefix")
2973 Parser.Lex();
2974 else if (Parser.getTok().getString() == "noprefix")
2975 return Error(DirectiveID.getLoc(), "'.att_syntax noprefix' is not "
2976 "supported: registers must have a "
2977 "'%' prefix in .att_syntax");
2978 }
Chad Rosier6f8d8b22012-09-10 20:54:39 +00002979 getParser().setAssemblerDialect(0);
2980 return false;
2981 } else if (IDVal.startswith(".intel_syntax")) {
Devang Patela173ee52012-01-31 18:14:05 +00002982 getParser().setAssemblerDialect(1);
Andrew V. Tischenkoc3c67232017-04-26 09:56:59 +00002983 getParser().setParsingInlineAsm(true);
Devang Patel9a9bb5c2012-01-30 20:02:42 +00002984 if (getLexer().isNot(AsmToken::EndOfStatement)) {
Saleem Abdulrasoola6505ca2014-01-13 01:15:39 +00002985 if (Parser.getTok().getString() == "noprefix")
Craig Topper6bf3ed42012-07-18 04:59:16 +00002986 Parser.Lex();
Reid Klecknerce63b792014-08-06 23:21:13 +00002987 else if (Parser.getTok().getString() == "prefix")
2988 return Error(DirectiveID.getLoc(), "'.intel_syntax prefix' is not "
2989 "supported: registers must not have "
2990 "a '%' prefix in .intel_syntax");
Devang Patel9a9bb5c2012-01-30 20:02:42 +00002991 }
2992 return false;
Michael Zuckerman02ecd432015-12-13 17:07:23 +00002993 } else if (IDVal == ".even")
2994 return parseDirectiveEven(DirectiveID.getLoc());
Chris Lattner72c0b592010-10-30 17:38:55 +00002995 return true;
2996}
2997
Michael Zuckerman02ecd432015-12-13 17:07:23 +00002998/// parseDirectiveEven
2999/// ::= .even
3000bool X86AsmParser::parseDirectiveEven(SMLoc L) {
Michael Zuckerman02ecd432015-12-13 17:07:23 +00003001 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3002 TokError("unexpected token in directive");
3003 return false;
3004 }
Eric Christopher445c9522016-10-14 05:47:37 +00003005 const MCSection *Section = getStreamer().getCurrentSectionOnly();
Michael Zuckerman02ecd432015-12-13 17:07:23 +00003006 if (!Section) {
3007 getStreamer().InitSections(false);
Eric Christopher445c9522016-10-14 05:47:37 +00003008 Section = getStreamer().getCurrentSectionOnly();
Michael Zuckerman02ecd432015-12-13 17:07:23 +00003009 }
3010 if (Section->UseCodeAlign())
3011 getStreamer().EmitCodeAlignment(2, 0);
3012 else
3013 getStreamer().EmitValueToAlignment(2, 0, 1, 0);
3014 return false;
3015}
Chris Lattner72c0b592010-10-30 17:38:55 +00003016/// ParseDirectiveWord
3017/// ::= .word [ expression (, expression)* ]
Devang Patel4a6e7782012-01-12 18:03:40 +00003018bool X86AsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
Rafael Espindola961d4692014-11-11 05:18:41 +00003019 MCAsmParser &Parser = getParser();
Chris Lattner72c0b592010-10-30 17:38:55 +00003020 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3021 for (;;) {
3022 const MCExpr *Value;
David Majnemera375b262015-10-26 02:45:50 +00003023 SMLoc ExprLoc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00003024 if (getParser().parseExpression(Value))
Saleem Abdulrasoola6505ca2014-01-13 01:15:39 +00003025 return false;
Chad Rosier51afe632012-06-27 22:34:28 +00003026
David Majnemera375b262015-10-26 02:45:50 +00003027 if (const auto *MCE = dyn_cast<MCConstantExpr>(Value)) {
3028 assert(Size <= 8 && "Invalid size");
3029 uint64_t IntValue = MCE->getValue();
3030 if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))
3031 return Error(ExprLoc, "literal value out of range for directive");
3032 getStreamer().EmitIntValue(IntValue, Size);
3033 } else {
3034 getStreamer().EmitValue(Value, Size, ExprLoc);
3035 }
Chad Rosier51afe632012-06-27 22:34:28 +00003036
Chris Lattner72c0b592010-10-30 17:38:55 +00003037 if (getLexer().is(AsmToken::EndOfStatement))
3038 break;
Chad Rosier51afe632012-06-27 22:34:28 +00003039
Chris Lattner72c0b592010-10-30 17:38:55 +00003040 // FIXME: Improve diagnostic.
Saleem Abdulrasoola6505ca2014-01-13 01:15:39 +00003041 if (getLexer().isNot(AsmToken::Comma)) {
3042 Error(L, "unexpected token in directive");
3043 return false;
3044 }
Chris Lattner72c0b592010-10-30 17:38:55 +00003045 Parser.Lex();
3046 }
3047 }
Chad Rosier51afe632012-06-27 22:34:28 +00003048
Chris Lattner72c0b592010-10-30 17:38:55 +00003049 Parser.Lex();
3050 return false;
3051}
3052
Evan Cheng481ebb02011-07-27 00:38:12 +00003053/// ParseDirectiveCode
Craig Topper3c80d622014-01-06 04:55:54 +00003054/// ::= .code16 | .code32 | .code64
Devang Patel4a6e7782012-01-12 18:03:40 +00003055bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
Rafael Espindola961d4692014-11-11 05:18:41 +00003056 MCAsmParser &Parser = getParser();
Nirav Dave6477ce22016-09-26 19:33:36 +00003057 Code16GCC = false;
Craig Topper3c80d622014-01-06 04:55:54 +00003058 if (IDVal == ".code16") {
Evan Cheng481ebb02011-07-27 00:38:12 +00003059 Parser.Lex();
Craig Topper3c80d622014-01-06 04:55:54 +00003060 if (!is16BitMode()) {
3061 SwitchMode(X86::Mode16Bit);
3062 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
3063 }
Nirav Dave6477ce22016-09-26 19:33:36 +00003064 } else if (IDVal == ".code16gcc") {
3065 // .code16gcc parses as if in 32-bit mode, but emits code in 16-bit mode.
3066 Parser.Lex();
3067 Code16GCC = true;
3068 if (!is16BitMode()) {
3069 SwitchMode(X86::Mode16Bit);
3070 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
3071 }
Saleem Abdulrasoola6505ca2014-01-13 01:15:39 +00003072 } else if (IDVal == ".code32") {
Craig Topper3c80d622014-01-06 04:55:54 +00003073 Parser.Lex();
3074 if (!is32BitMode()) {
3075 SwitchMode(X86::Mode32Bit);
Evan Cheng481ebb02011-07-27 00:38:12 +00003076 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
3077 }
3078 } else if (IDVal == ".code64") {
3079 Parser.Lex();
3080 if (!is64BitMode()) {
Craig Topper3c80d622014-01-06 04:55:54 +00003081 SwitchMode(X86::Mode64Bit);
Evan Cheng481ebb02011-07-27 00:38:12 +00003082 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code64);
3083 }
3084 } else {
Saleem Abdulrasoola6505ca2014-01-13 01:15:39 +00003085 Error(L, "unknown directive " + IDVal);
3086 return false;
Evan Cheng481ebb02011-07-27 00:38:12 +00003087 }
Chris Lattner72c0b592010-10-30 17:38:55 +00003088
Evan Cheng481ebb02011-07-27 00:38:12 +00003089 return false;
3090}
Chris Lattner72c0b592010-10-30 17:38:55 +00003091
Daniel Dunbar71475772009-07-17 20:42:00 +00003092// Force static initialization.
3093extern "C" void LLVMInitializeX86AsmParser() {
Mehdi Aminif42454b2016-10-09 23:00:34 +00003094 RegisterMCAsmParser<X86AsmParser> X(getTheX86_32Target());
3095 RegisterMCAsmParser<X86AsmParser> Y(getTheX86_64Target());
Daniel Dunbar71475772009-07-17 20:42:00 +00003096}
Daniel Dunbar00331992009-07-29 00:02:19 +00003097
Chris Lattner3e4582a2010-09-06 19:11:01 +00003098#define GET_REGISTER_MATCHER
3099#define GET_MATCHER_IMPLEMENTATION
Jim Grosbach6f1f41b2012-11-14 18:04:47 +00003100#define GET_SUBTARGET_FEATURE_NAME
Daniel Dunbar00331992009-07-29 00:02:19 +00003101#include "X86GenAsmMatcher.inc"