LLVM  7.0.0svn
X86AsmParser.cpp
Go to the documentation of this file.
1 //===-- 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 
12 #include "MCTargetDesc/X86MCExpr.h"
14 #include "X86AsmInstrumentation.h"
15 #include "X86AsmParserCommon.h"
16 #include "X86Operand.h"
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/ADT/SmallString.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/ADT/StringSwitch.h"
21 #include "llvm/ADT/Twine.h"
22 #include "llvm/MC/MCContext.h"
23 #include "llvm/MC/MCExpr.h"
24 #include "llvm/MC/MCInst.h"
25 #include "llvm/MC/MCInstrInfo.h"
30 #include "llvm/MC/MCRegisterInfo.h"
31 #include "llvm/MC/MCSection.h"
32 #include "llvm/MC/MCStreamer.h"
34 #include "llvm/MC/MCSymbol.h"
35 #include "llvm/Support/SourceMgr.h"
38 #include <algorithm>
39 #include <memory>
40 
41 using namespace llvm;
42 
43 static bool checkScale(unsigned Scale, StringRef &ErrMsg) {
44  if (Scale != 1 && Scale != 2 && Scale != 4 && Scale != 8) {
45  ErrMsg = "scale factor in address must be 1, 2, 4 or 8";
46  return true;
47  }
48  return false;
49 }
50 
51 namespace {
52 
53 static const char OpPrecedence[] = {
54  0, // IC_OR
55  1, // IC_XOR
56  2, // IC_AND
57  3, // IC_LSHIFT
58  3, // IC_RSHIFT
59  4, // IC_PLUS
60  4, // IC_MINUS
61  5, // IC_MULTIPLY
62  5, // IC_DIVIDE
63  5, // IC_MOD
64  6, // IC_NOT
65  7, // IC_NEG
66  8, // IC_RPAREN
67  9, // IC_LPAREN
68  0, // IC_IMM
69  0 // IC_REGISTER
70 };
71 
72 class X86AsmParser : public MCTargetAsmParser {
73  ParseInstructionInfo *InstInfo;
74  std::unique_ptr<X86AsmInstrumentation> Instrumentation;
75  bool Code16GCC;
76 
77 private:
78  SMLoc consumeToken() {
79  MCAsmParser &Parser = getParser();
80  SMLoc Result = Parser.getTok().getLoc();
81  Parser.Lex();
82  return Result;
83  }
84 
85  X86TargetStreamer &getTargetStreamer() {
86  assert(getParser().getStreamer().getTargetStreamer() &&
87  "do not have a target streamer");
88  MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
89  return static_cast<X86TargetStreamer &>(TS);
90  }
91 
92  unsigned MatchInstruction(const OperandVector &Operands, MCInst &Inst,
93  uint64_t &ErrorInfo, bool matchingInlineAsm,
94  unsigned VariantID = 0) {
95  // In Code16GCC mode, match as 32-bit.
96  if (Code16GCC)
97  SwitchMode(X86::Mode32Bit);
98  unsigned rv = MatchInstructionImpl(Operands, Inst, ErrorInfo,
99  matchingInlineAsm, VariantID);
100  if (Code16GCC)
101  SwitchMode(X86::Mode16Bit);
102  return rv;
103  }
104 
105  enum InfixCalculatorTok {
106  IC_OR = 0,
107  IC_XOR,
108  IC_AND,
109  IC_LSHIFT,
110  IC_RSHIFT,
111  IC_PLUS,
112  IC_MINUS,
113  IC_MULTIPLY,
114  IC_DIVIDE,
115  IC_MOD,
116  IC_NOT,
117  IC_NEG,
118  IC_RPAREN,
119  IC_LPAREN,
120  IC_IMM,
121  IC_REGISTER
122  };
123 
124  enum IntelOperatorKind {
125  IOK_INVALID = 0,
126  IOK_LENGTH,
127  IOK_SIZE,
128  IOK_TYPE,
129  IOK_OFFSET
130  };
131 
132  class InfixCalculator {
133  typedef std::pair< InfixCalculatorTok, int64_t > ICToken;
134  SmallVector<InfixCalculatorTok, 4> InfixOperatorStack;
135  SmallVector<ICToken, 4> PostfixStack;
136 
137  bool isUnaryOperator(const InfixCalculatorTok Op) {
138  return Op == IC_NEG || Op == IC_NOT;
139  }
140 
141  public:
142  int64_t popOperand() {
143  assert (!PostfixStack.empty() && "Poped an empty stack!");
144  ICToken Op = PostfixStack.pop_back_val();
145  if (!(Op.first == IC_IMM || Op.first == IC_REGISTER))
146  return -1; // The invalid Scale value will be caught later by checkScale
147  return Op.second;
148  }
149  void pushOperand(InfixCalculatorTok Op, int64_t Val = 0) {
150  assert ((Op == IC_IMM || Op == IC_REGISTER) &&
151  "Unexpected operand!");
152  PostfixStack.push_back(std::make_pair(Op, Val));
153  }
154 
155  void popOperator() { InfixOperatorStack.pop_back(); }
156  void pushOperator(InfixCalculatorTok Op) {
157  // Push the new operator if the stack is empty.
158  if (InfixOperatorStack.empty()) {
159  InfixOperatorStack.push_back(Op);
160  return;
161  }
162 
163  // Push the new operator if it has a higher precedence than the operator
164  // on the top of the stack or the operator on the top of the stack is a
165  // left parentheses.
166  unsigned Idx = InfixOperatorStack.size() - 1;
167  InfixCalculatorTok StackOp = InfixOperatorStack[Idx];
168  if (OpPrecedence[Op] > OpPrecedence[StackOp] || StackOp == IC_LPAREN) {
169  InfixOperatorStack.push_back(Op);
170  return;
171  }
172 
173  // The operator on the top of the stack has higher precedence than the
174  // new operator.
175  unsigned ParenCount = 0;
176  while (1) {
177  // Nothing to process.
178  if (InfixOperatorStack.empty())
179  break;
180 
181  Idx = InfixOperatorStack.size() - 1;
182  StackOp = InfixOperatorStack[Idx];
183  if (!(OpPrecedence[StackOp] >= OpPrecedence[Op] || ParenCount))
184  break;
185 
186  // If we have an even parentheses count and we see a left parentheses,
187  // then stop processing.
188  if (!ParenCount && StackOp == IC_LPAREN)
189  break;
190 
191  if (StackOp == IC_RPAREN) {
192  ++ParenCount;
193  InfixOperatorStack.pop_back();
194  } else if (StackOp == IC_LPAREN) {
195  --ParenCount;
196  InfixOperatorStack.pop_back();
197  } else {
198  InfixOperatorStack.pop_back();
199  PostfixStack.push_back(std::make_pair(StackOp, 0));
200  }
201  }
202  // Push the new operator.
203  InfixOperatorStack.push_back(Op);
204  }
205 
206  int64_t execute() {
207  // Push any remaining operators onto the postfix stack.
208  while (!InfixOperatorStack.empty()) {
209  InfixCalculatorTok StackOp = InfixOperatorStack.pop_back_val();
210  if (StackOp != IC_LPAREN && StackOp != IC_RPAREN)
211  PostfixStack.push_back(std::make_pair(StackOp, 0));
212  }
213 
214  if (PostfixStack.empty())
215  return 0;
216 
217  SmallVector<ICToken, 16> OperandStack;
218  for (unsigned i = 0, e = PostfixStack.size(); i != e; ++i) {
219  ICToken Op = PostfixStack[i];
220  if (Op.first == IC_IMM || Op.first == IC_REGISTER) {
221  OperandStack.push_back(Op);
222  } else if (isUnaryOperator(Op.first)) {
223  assert (OperandStack.size() > 0 && "Too few operands.");
224  ICToken Operand = OperandStack.pop_back_val();
225  assert (Operand.first == IC_IMM &&
226  "Unary operation with a register!");
227  switch (Op.first) {
228  default:
229  report_fatal_error("Unexpected operator!");
230  break;
231  case IC_NEG:
232  OperandStack.push_back(std::make_pair(IC_IMM, -Operand.second));
233  break;
234  case IC_NOT:
235  OperandStack.push_back(std::make_pair(IC_IMM, ~Operand.second));
236  break;
237  }
238  } else {
239  assert (OperandStack.size() > 1 && "Too few operands.");
240  int64_t Val;
241  ICToken Op2 = OperandStack.pop_back_val();
242  ICToken Op1 = OperandStack.pop_back_val();
243  switch (Op.first) {
244  default:
245  report_fatal_error("Unexpected operator!");
246  break;
247  case IC_PLUS:
248  Val = Op1.second + Op2.second;
249  OperandStack.push_back(std::make_pair(IC_IMM, Val));
250  break;
251  case IC_MINUS:
252  Val = Op1.second - Op2.second;
253  OperandStack.push_back(std::make_pair(IC_IMM, Val));
254  break;
255  case IC_MULTIPLY:
256  assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
257  "Multiply operation with an immediate and a register!");
258  Val = Op1.second * Op2.second;
259  OperandStack.push_back(std::make_pair(IC_IMM, Val));
260  break;
261  case IC_DIVIDE:
262  assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
263  "Divide operation with an immediate and a register!");
264  assert (Op2.second != 0 && "Division by zero!");
265  Val = Op1.second / Op2.second;
266  OperandStack.push_back(std::make_pair(IC_IMM, Val));
267  break;
268  case IC_MOD:
269  assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
270  "Modulo operation with an immediate and a register!");
271  Val = Op1.second % Op2.second;
272  OperandStack.push_back(std::make_pair(IC_IMM, Val));
273  break;
274  case IC_OR:
275  assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
276  "Or operation with an immediate and a register!");
277  Val = Op1.second | Op2.second;
278  OperandStack.push_back(std::make_pair(IC_IMM, Val));
279  break;
280  case IC_XOR:
281  assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
282  "Xor operation with an immediate and a register!");
283  Val = Op1.second ^ Op2.second;
284  OperandStack.push_back(std::make_pair(IC_IMM, Val));
285  break;
286  case IC_AND:
287  assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
288  "And operation with an immediate and a register!");
289  Val = Op1.second & Op2.second;
290  OperandStack.push_back(std::make_pair(IC_IMM, Val));
291  break;
292  case IC_LSHIFT:
293  assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
294  "Left shift operation with an immediate and a register!");
295  Val = Op1.second << Op2.second;
296  OperandStack.push_back(std::make_pair(IC_IMM, Val));
297  break;
298  case IC_RSHIFT:
299  assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
300  "Right shift operation with an immediate and a register!");
301  Val = Op1.second >> Op2.second;
302  OperandStack.push_back(std::make_pair(IC_IMM, Val));
303  break;
304  }
305  }
306  }
307  assert (OperandStack.size() == 1 && "Expected a single result.");
308  return OperandStack.pop_back_val().second;
309  }
310  };
311 
312  enum IntelExprState {
313  IES_INIT,
314  IES_OR,
315  IES_XOR,
316  IES_AND,
317  IES_LSHIFT,
318  IES_RSHIFT,
319  IES_PLUS,
320  IES_MINUS,
321  IES_NOT,
322  IES_MULTIPLY,
323  IES_DIVIDE,
324  IES_MOD,
325  IES_LBRAC,
326  IES_RBRAC,
327  IES_LPAREN,
328  IES_RPAREN,
329  IES_REGISTER,
330  IES_INTEGER,
331  IES_IDENTIFIER,
332  IES_ERROR
333  };
334 
335  class IntelExprStateMachine {
336  IntelExprState State, PrevState;
337  unsigned BaseReg, IndexReg, TmpReg, Scale;
338  int64_t Imm;
339  const MCExpr *Sym;
340  StringRef SymName;
341  InfixCalculator IC;
343  short BracCount;
344  bool MemExpr;
345 
346  public:
347  IntelExprStateMachine()
348  : State(IES_INIT), PrevState(IES_ERROR), BaseReg(0), IndexReg(0),
349  TmpReg(0), Scale(1), Imm(0), Sym(nullptr), BracCount(0),
350  MemExpr(false) {}
351 
352  void addImm(int64_t imm) { Imm += imm; }
353  short getBracCount() { return BracCount; }
354  bool isMemExpr() { return MemExpr; }
355  unsigned getBaseReg() { return BaseReg; }
356  unsigned getIndexReg() { return IndexReg; }
357  unsigned getScale() { return Scale; }
358  const MCExpr *getSym() { return Sym; }
359  StringRef getSymName() { return SymName; }
360  int64_t getImm() { return Imm + IC.execute(); }
361  bool isValidEndState() {
362  return State == IES_RBRAC || State == IES_INTEGER;
363  }
364  bool hadError() { return State == IES_ERROR; }
365  InlineAsmIdentifierInfo &getIdentifierInfo() { return Info; }
366 
367  void onOr() {
368  IntelExprState CurrState = State;
369  switch (State) {
370  default:
371  State = IES_ERROR;
372  break;
373  case IES_INTEGER:
374  case IES_RPAREN:
375  case IES_REGISTER:
376  State = IES_OR;
377  IC.pushOperator(IC_OR);
378  break;
379  }
380  PrevState = CurrState;
381  }
382  void onXor() {
383  IntelExprState CurrState = State;
384  switch (State) {
385  default:
386  State = IES_ERROR;
387  break;
388  case IES_INTEGER:
389  case IES_RPAREN:
390  case IES_REGISTER:
391  State = IES_XOR;
392  IC.pushOperator(IC_XOR);
393  break;
394  }
395  PrevState = CurrState;
396  }
397  void onAnd() {
398  IntelExprState CurrState = State;
399  switch (State) {
400  default:
401  State = IES_ERROR;
402  break;
403  case IES_INTEGER:
404  case IES_RPAREN:
405  case IES_REGISTER:
406  State = IES_AND;
407  IC.pushOperator(IC_AND);
408  break;
409  }
410  PrevState = CurrState;
411  }
412  void onLShift() {
413  IntelExprState CurrState = State;
414  switch (State) {
415  default:
416  State = IES_ERROR;
417  break;
418  case IES_INTEGER:
419  case IES_RPAREN:
420  case IES_REGISTER:
421  State = IES_LSHIFT;
422  IC.pushOperator(IC_LSHIFT);
423  break;
424  }
425  PrevState = CurrState;
426  }
427  void onRShift() {
428  IntelExprState CurrState = State;
429  switch (State) {
430  default:
431  State = IES_ERROR;
432  break;
433  case IES_INTEGER:
434  case IES_RPAREN:
435  case IES_REGISTER:
436  State = IES_RSHIFT;
437  IC.pushOperator(IC_RSHIFT);
438  break;
439  }
440  PrevState = CurrState;
441  }
442  bool onPlus(StringRef &ErrMsg) {
443  IntelExprState CurrState = State;
444  switch (State) {
445  default:
446  State = IES_ERROR;
447  break;
448  case IES_INTEGER:
449  case IES_RPAREN:
450  case IES_REGISTER:
451  State = IES_PLUS;
452  IC.pushOperator(IC_PLUS);
453  if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
454  // If we already have a BaseReg, then assume this is the IndexReg with
455  // a scale of 1.
456  if (!BaseReg) {
457  BaseReg = TmpReg;
458  } else {
459  if (IndexReg) {
460  ErrMsg = "BaseReg/IndexReg already set!";
461  return true;
462  }
463  IndexReg = TmpReg;
464  Scale = 1;
465  }
466  }
467  break;
468  }
469  PrevState = CurrState;
470  return false;
471  }
472  bool onMinus(StringRef &ErrMsg) {
473  IntelExprState CurrState = State;
474  switch (State) {
475  default:
476  State = IES_ERROR;
477  break;
478  case IES_OR:
479  case IES_XOR:
480  case IES_AND:
481  case IES_LSHIFT:
482  case IES_RSHIFT:
483  case IES_PLUS:
484  case IES_NOT:
485  case IES_MULTIPLY:
486  case IES_DIVIDE:
487  case IES_MOD:
488  case IES_LPAREN:
489  case IES_RPAREN:
490  case IES_LBRAC:
491  case IES_RBRAC:
492  case IES_INTEGER:
493  case IES_REGISTER:
494  case IES_INIT:
495  State = IES_MINUS;
496  // push minus operator if it is not a negate operator
497  if (CurrState == IES_REGISTER || CurrState == IES_RPAREN ||
498  CurrState == IES_INTEGER || CurrState == IES_RBRAC)
499  IC.pushOperator(IC_MINUS);
500  else if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
501  // We have negate operator for Scale: it's illegal
502  ErrMsg = "Scale can't be negative";
503  return true;
504  } else
505  IC.pushOperator(IC_NEG);
506  if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
507  // If we already have a BaseReg, then assume this is the IndexReg with
508  // a scale of 1.
509  if (!BaseReg) {
510  BaseReg = TmpReg;
511  } else {
512  if (IndexReg) {
513  ErrMsg = "BaseReg/IndexReg already set!";
514  return true;
515  }
516  IndexReg = TmpReg;
517  Scale = 1;
518  }
519  }
520  break;
521  }
522  PrevState = CurrState;
523  return false;
524  }
525  void onNot() {
526  IntelExprState CurrState = State;
527  switch (State) {
528  default:
529  State = IES_ERROR;
530  break;
531  case IES_OR:
532  case IES_XOR:
533  case IES_AND:
534  case IES_LSHIFT:
535  case IES_RSHIFT:
536  case IES_PLUS:
537  case IES_MINUS:
538  case IES_NOT:
539  case IES_MULTIPLY:
540  case IES_DIVIDE:
541  case IES_MOD:
542  case IES_LPAREN:
543  case IES_LBRAC:
544  case IES_INIT:
545  State = IES_NOT;
546  IC.pushOperator(IC_NOT);
547  break;
548  }
549  PrevState = CurrState;
550  }
551 
552  bool onRegister(unsigned Reg, StringRef &ErrMsg) {
553  IntelExprState CurrState = State;
554  switch (State) {
555  default:
556  State = IES_ERROR;
557  break;
558  case IES_PLUS:
559  case IES_LPAREN:
560  case IES_LBRAC:
561  State = IES_REGISTER;
562  TmpReg = Reg;
563  IC.pushOperand(IC_REGISTER);
564  break;
565  case IES_MULTIPLY:
566  // Index Register - Scale * Register
567  if (PrevState == IES_INTEGER) {
568  if (IndexReg) {
569  ErrMsg = "BaseReg/IndexReg already set!";
570  return true;
571  }
572  State = IES_REGISTER;
573  IndexReg = Reg;
574  // Get the scale and replace the 'Scale * Register' with '0'.
575  Scale = IC.popOperand();
576  if (checkScale(Scale, ErrMsg))
577  return true;
578  IC.pushOperand(IC_IMM);
579  IC.popOperator();
580  } else {
581  State = IES_ERROR;
582  }
583  break;
584  }
585  PrevState = CurrState;
586  return false;
587  }
588  bool onIdentifierExpr(const MCExpr *SymRef, StringRef SymRefName,
589  const InlineAsmIdentifierInfo &IDInfo,
590  bool ParsingInlineAsm, StringRef &ErrMsg) {
591  // InlineAsm: Treat an enum value as an integer
592  if (ParsingInlineAsm)
594  return onInteger(IDInfo.Enum.EnumVal, ErrMsg);
595  // Treat a symbolic constant like an integer
596  if (auto *CE = dyn_cast<MCConstantExpr>(SymRef))
597  return onInteger(CE->getValue(), ErrMsg);
598  PrevState = State;
599  bool HasSymbol = Sym != nullptr;
600  switch (State) {
601  default:
602  State = IES_ERROR;
603  break;
604  case IES_PLUS:
605  case IES_MINUS:
606  case IES_NOT:
607  case IES_INIT:
608  case IES_LBRAC:
609  MemExpr = true;
610  State = IES_INTEGER;
611  Sym = SymRef;
612  SymName = SymRefName;
613  IC.pushOperand(IC_IMM);
614  if (ParsingInlineAsm)
615  Info = IDInfo;
616  break;
617  }
618  if (HasSymbol)
619  ErrMsg = "cannot use more than one symbol in memory operand";
620  return HasSymbol;
621  }
622  bool onInteger(int64_t TmpInt, StringRef &ErrMsg) {
623  IntelExprState CurrState = State;
624  switch (State) {
625  default:
626  State = IES_ERROR;
627  break;
628  case IES_PLUS:
629  case IES_MINUS:
630  case IES_NOT:
631  case IES_OR:
632  case IES_XOR:
633  case IES_AND:
634  case IES_LSHIFT:
635  case IES_RSHIFT:
636  case IES_DIVIDE:
637  case IES_MOD:
638  case IES_MULTIPLY:
639  case IES_LPAREN:
640  case IES_INIT:
641  case IES_LBRAC:
642  State = IES_INTEGER;
643  if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
644  // Index Register - Register * Scale
645  if (IndexReg) {
646  ErrMsg = "BaseReg/IndexReg already set!";
647  return true;
648  }
649  IndexReg = TmpReg;
650  Scale = TmpInt;
651  if (checkScale(Scale, ErrMsg))
652  return true;
653  // Get the scale and replace the 'Register * Scale' with '0'.
654  IC.popOperator();
655  } else {
656  IC.pushOperand(IC_IMM, TmpInt);
657  }
658  break;
659  }
660  PrevState = CurrState;
661  return false;
662  }
663  void onStar() {
664  PrevState = State;
665  switch (State) {
666  default:
667  State = IES_ERROR;
668  break;
669  case IES_INTEGER:
670  case IES_REGISTER:
671  case IES_RPAREN:
672  State = IES_MULTIPLY;
673  IC.pushOperator(IC_MULTIPLY);
674  break;
675  }
676  }
677  void onDivide() {
678  PrevState = State;
679  switch (State) {
680  default:
681  State = IES_ERROR;
682  break;
683  case IES_INTEGER:
684  case IES_RPAREN:
685  State = IES_DIVIDE;
686  IC.pushOperator(IC_DIVIDE);
687  break;
688  }
689  }
690  void onMod() {
691  PrevState = State;
692  switch (State) {
693  default:
694  State = IES_ERROR;
695  break;
696  case IES_INTEGER:
697  case IES_RPAREN:
698  State = IES_MOD;
699  IC.pushOperator(IC_MOD);
700  break;
701  }
702  }
703  bool onLBrac() {
704  if (BracCount)
705  return true;
706  PrevState = State;
707  switch (State) {
708  default:
709  State = IES_ERROR;
710  break;
711  case IES_RBRAC:
712  case IES_INTEGER:
713  case IES_RPAREN:
714  State = IES_PLUS;
715  IC.pushOperator(IC_PLUS);
716  break;
717  case IES_INIT:
718  assert(!BracCount && "BracCount should be zero on parsing's start");
719  State = IES_LBRAC;
720  break;
721  }
722  MemExpr = true;
723  BracCount++;
724  return false;
725  }
726  bool onRBrac() {
727  IntelExprState CurrState = State;
728  switch (State) {
729  default:
730  State = IES_ERROR;
731  break;
732  case IES_INTEGER:
733  case IES_REGISTER:
734  case IES_RPAREN:
735  if (BracCount-- != 1)
736  return true;
737  State = IES_RBRAC;
738  if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
739  // If we already have a BaseReg, then assume this is the IndexReg with
740  // a scale of 1.
741  if (!BaseReg) {
742  BaseReg = TmpReg;
743  } else {
744  assert (!IndexReg && "BaseReg/IndexReg already set!");
745  IndexReg = TmpReg;
746  Scale = 1;
747  }
748  }
749  break;
750  }
751  PrevState = CurrState;
752  return false;
753  }
754  void onLParen() {
755  IntelExprState CurrState = State;
756  switch (State) {
757  default:
758  State = IES_ERROR;
759  break;
760  case IES_PLUS:
761  case IES_MINUS:
762  case IES_NOT:
763  case IES_OR:
764  case IES_XOR:
765  case IES_AND:
766  case IES_LSHIFT:
767  case IES_RSHIFT:
768  case IES_MULTIPLY:
769  case IES_DIVIDE:
770  case IES_MOD:
771  case IES_LPAREN:
772  case IES_INIT:
773  case IES_LBRAC:
774  State = IES_LPAREN;
775  IC.pushOperator(IC_LPAREN);
776  break;
777  }
778  PrevState = CurrState;
779  }
780  void onRParen() {
781  PrevState = State;
782  switch (State) {
783  default:
784  State = IES_ERROR;
785  break;
786  case IES_INTEGER:
787  case IES_REGISTER:
788  case IES_RPAREN:
789  State = IES_RPAREN;
790  IC.pushOperator(IC_RPAREN);
791  break;
792  }
793  }
794  };
795 
796  bool Error(SMLoc L, const Twine &Msg, SMRange Range = None,
797  bool MatchingInlineAsm = false) {
798  MCAsmParser &Parser = getParser();
799  if (MatchingInlineAsm) {
800  if (!getLexer().isAtStartOfStatement())
801  Parser.eatToEndOfStatement();
802  return false;
803  }
804  return Parser.Error(L, Msg, Range);
805  }
806 
807  std::nullptr_t ErrorOperand(SMLoc Loc, StringRef Msg) {
808  Error(Loc, Msg);
809  return nullptr;
810  }
811 
812  std::unique_ptr<X86Operand> DefaultMemSIOperand(SMLoc Loc);
813  std::unique_ptr<X86Operand> DefaultMemDIOperand(SMLoc Loc);
814  bool IsSIReg(unsigned Reg);
815  unsigned GetSIDIForRegClass(unsigned RegClassID, unsigned Reg, bool IsSIReg);
816  void
817  AddDefaultSrcDestOperands(OperandVector &Operands,
818  std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
819  std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst);
820  bool VerifyAndAdjustOperands(OperandVector &OrigOperands,
821  OperandVector &FinalOperands);
822  std::unique_ptr<X86Operand> ParseOperand();
823  std::unique_ptr<X86Operand> ParseATTOperand();
824  std::unique_ptr<X86Operand> ParseIntelOperand();
825  std::unique_ptr<X86Operand> ParseIntelOffsetOfOperator();
826  bool ParseIntelDotOperator(IntelExprStateMachine &SM, SMLoc &End);
827  unsigned IdentifyIntelInlineAsmOperator(StringRef Name);
828  unsigned ParseIntelInlineAsmOperator(unsigned OpKind);
829  std::unique_ptr<X86Operand> ParseRoundingModeOp(SMLoc Start);
830  bool ParseIntelNamedOperator(StringRef Name, IntelExprStateMachine &SM);
831  void RewriteIntelExpression(IntelExprStateMachine &SM, SMLoc Start,
832  SMLoc End);
833  bool ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End);
834  bool ParseIntelInlineAsmIdentifier(const MCExpr *&Val, StringRef &Identifier,
836  bool IsUnevaluatedOperand, SMLoc &End);
837 
838  std::unique_ptr<X86Operand> ParseMemOperand(unsigned SegReg, SMLoc StartLoc);
839 
840  bool ParseIntelMemoryOperandSize(unsigned &Size);
841  std::unique_ptr<X86Operand>
842  CreateMemForInlineAsm(unsigned SegReg, const MCExpr *Disp, unsigned BaseReg,
843  unsigned IndexReg, unsigned Scale, SMLoc Start,
844  SMLoc End, unsigned Size, StringRef Identifier,
845  const InlineAsmIdentifierInfo &Info);
846 
847  bool parseDirectiveEven(SMLoc L);
848  bool ParseDirectiveWord(unsigned Size, SMLoc L);
849  bool ParseDirectiveCode(StringRef IDVal, SMLoc L);
850 
851  /// CodeView FPO data directives.
852  bool parseDirectiveFPOProc(SMLoc L);
853  bool parseDirectiveFPOSetFrame(SMLoc L);
854  bool parseDirectiveFPOPushReg(SMLoc L);
855  bool parseDirectiveFPOStackAlloc(SMLoc L);
856  bool parseDirectiveFPOEndPrologue(SMLoc L);
857  bool parseDirectiveFPOEndProc(SMLoc L);
858  bool parseDirectiveFPOData(SMLoc L);
859 
860  bool validateInstruction(MCInst &Inst, const OperandVector &Ops);
861  bool processInstruction(MCInst &Inst, const OperandVector &Ops);
862 
863  /// Wrapper around MCStreamer::EmitInstruction(). Possibly adds
864  /// instrumentation around Inst.
865  void EmitInstruction(MCInst &Inst, OperandVector &Operands, MCStreamer &Out);
866 
867  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
868  OperandVector &Operands, MCStreamer &Out,
869  uint64_t &ErrorInfo,
870  bool MatchingInlineAsm) override;
871 
872  void MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op, OperandVector &Operands,
873  MCStreamer &Out, bool MatchingInlineAsm);
874 
875  bool ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
876  bool MatchingInlineAsm);
877 
878  bool MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
879  OperandVector &Operands, MCStreamer &Out,
880  uint64_t &ErrorInfo,
881  bool MatchingInlineAsm);
882 
883  bool MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
884  OperandVector &Operands, MCStreamer &Out,
885  uint64_t &ErrorInfo,
886  bool MatchingInlineAsm);
887 
888  bool OmitRegisterFromClobberLists(unsigned RegNo) override;
889 
890  /// Parses AVX512 specific operand primitives: masked registers ({%k<NUM>}, {z})
891  /// and memory broadcasting ({1to<NUM>}) primitives, updating Operands vector if required.
892  /// return false if no parsing errors occurred, true otherwise.
893  bool HandleAVX512Operand(OperandVector &Operands,
894  const MCParsedAsmOperand &Op);
895 
896  bool ParseZ(std::unique_ptr<X86Operand> &Z, const SMLoc &StartLoc);
897 
898  bool is64BitMode() const {
899  // FIXME: Can tablegen auto-generate this?
900  return getSTI().getFeatureBits()[X86::Mode64Bit];
901  }
902  bool is32BitMode() const {
903  // FIXME: Can tablegen auto-generate this?
904  return getSTI().getFeatureBits()[X86::Mode32Bit];
905  }
906  bool is16BitMode() const {
907  // FIXME: Can tablegen auto-generate this?
908  return getSTI().getFeatureBits()[X86::Mode16Bit];
909  }
910  void SwitchMode(unsigned mode) {
911  MCSubtargetInfo &STI = copySTI();
912  FeatureBitset AllModes({X86::Mode64Bit, X86::Mode32Bit, X86::Mode16Bit});
913  FeatureBitset OldMode = STI.getFeatureBits() & AllModes;
914  uint64_t FB = ComputeAvailableFeatures(
915  STI.ToggleFeature(OldMode.flip(mode)));
916  setAvailableFeatures(FB);
917 
918  assert(FeatureBitset({mode}) == (STI.getFeatureBits() & AllModes));
919  }
920 
921  unsigned getPointerWidth() {
922  if (is16BitMode()) return 16;
923  if (is32BitMode()) return 32;
924  if (is64BitMode()) return 64;
925  llvm_unreachable("invalid mode");
926  }
927 
928  bool isParsingIntelSyntax() {
929  return getParser().getAssemblerDialect();
930  }
931 
932  /// @name Auto-generated Matcher Functions
933  /// {
934 
935 #define GET_ASSEMBLER_HEADER
936 #include "X86GenAsmMatcher.inc"
937 
938  /// }
939 
940 public:
941 
942  X86AsmParser(const MCSubtargetInfo &sti, MCAsmParser &Parser,
943  const MCInstrInfo &mii, const MCTargetOptions &Options)
944  : MCTargetAsmParser(Options, sti, mii), InstInfo(nullptr),
945  Code16GCC(false) {
946 
947  // Initialize the set of available features.
948  setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
949  Instrumentation.reset(
950  CreateX86AsmInstrumentation(Options, Parser.getContext(), STI));
951  }
952 
953  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
954 
955  void SetFrameRegister(unsigned RegNo) override;
956 
957  bool parseAssignmentExpression(const MCExpr *&Res, SMLoc &EndLoc) override;
958 
959  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
960  SMLoc NameLoc, OperandVector &Operands) override;
961 
962  bool ParseDirective(AsmToken DirectiveID) override;
963 };
964 } // end anonymous namespace
965 
966 /// @name Auto-generated Match Functions
967 /// {
968 
969 static unsigned MatchRegisterName(StringRef Name);
970 
971 /// }
972 
973 static bool CheckBaseRegAndIndexRegAndScale(unsigned BaseReg, unsigned IndexReg,
974  unsigned Scale, StringRef &ErrMsg) {
975  // If we have both a base register and an index register make sure they are
976  // both 64-bit or 32-bit registers.
977  // To support VSIB, IndexReg can be 128-bit or 256-bit registers.
978 
979  if ((BaseReg == X86::RIP && IndexReg != 0) || (IndexReg == X86::RIP)) {
980  ErrMsg = "invalid base+index expression";
981  return true;
982  }
983  if (BaseReg != 0 && IndexReg != 0) {
984  if (X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) &&
985  (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
986  X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg)) &&
987  IndexReg != X86::RIZ) {
988  ErrMsg = "base register is 64-bit, but index register is not";
989  return true;
990  }
991  if (X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg) &&
992  (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
993  X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) &&
994  IndexReg != X86::EIZ){
995  ErrMsg = "base register is 32-bit, but index register is not";
996  return true;
997  }
998  if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg)) {
999  if (X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg) ||
1000  X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) {
1001  ErrMsg = "base register is 16-bit, but index register is not";
1002  return true;
1003  }
1004  if (((BaseReg == X86::BX || BaseReg == X86::BP) &&
1005  IndexReg != X86::SI && IndexReg != X86::DI) ||
1006  ((BaseReg == X86::SI || BaseReg == X86::DI) &&
1007  IndexReg != X86::BX && IndexReg != X86::BP)) {
1008  ErrMsg = "invalid 16-bit base/index register combination";
1009  return true;
1010  }
1011  }
1012  }
1013  return checkScale(Scale, ErrMsg);
1014 }
1015 
1016 bool X86AsmParser::ParseRegister(unsigned &RegNo,
1017  SMLoc &StartLoc, SMLoc &EndLoc) {
1018  MCAsmParser &Parser = getParser();
1019  RegNo = 0;
1020  const AsmToken &PercentTok = Parser.getTok();
1021  StartLoc = PercentTok.getLoc();
1022 
1023  // If we encounter a %, ignore it. This code handles registers with and
1024  // without the prefix, unprefixed registers can occur in cfi directives.
1025  if (!isParsingIntelSyntax() && PercentTok.is(AsmToken::Percent))
1026  Parser.Lex(); // Eat percent token.
1027 
1028  const AsmToken &Tok = Parser.getTok();
1029  EndLoc = Tok.getEndLoc();
1030 
1031  if (Tok.isNot(AsmToken::Identifier)) {
1032  if (isParsingIntelSyntax()) return true;
1033  return Error(StartLoc, "invalid register name",
1034  SMRange(StartLoc, EndLoc));
1035  }
1036 
1037  RegNo = MatchRegisterName(Tok.getString());
1038 
1039  // If the match failed, try the register name as lowercase.
1040  if (RegNo == 0)
1041  RegNo = MatchRegisterName(Tok.getString().lower());
1042 
1043  // The "flags" register cannot be referenced directly.
1044  // Treat it as an identifier instead.
1045  if (isParsingInlineAsm() && isParsingIntelSyntax() && RegNo == X86::EFLAGS)
1046  RegNo = 0;
1047 
1048  if (!is64BitMode()) {
1049  // FIXME: This should be done using Requires<Not64BitMode> and
1050  // Requires<In64BitMode> so "eiz" usage in 64-bit instructions can be also
1051  // checked.
1052  // FIXME: Check AH, CH, DH, BH cannot be used in an instruction requiring a
1053  // REX prefix.
1054  if (RegNo == X86::RIZ ||
1055  X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo) ||
1058  return Error(StartLoc, "register %"
1059  + Tok.getString() + " is only available in 64-bit mode",
1060  SMRange(StartLoc, EndLoc));
1061  }
1062 
1063  // Parse "%st" as "%st(0)" and "%st(1)", which is multiple tokens.
1064  if (RegNo == 0 && (Tok.getString() == "st" || Tok.getString() == "ST")) {
1065  RegNo = X86::ST0;
1066  Parser.Lex(); // Eat 'st'
1067 
1068  // Check to see if we have '(4)' after %st.
1069  if (getLexer().isNot(AsmToken::LParen))
1070  return false;
1071  // Lex the paren.
1072  getParser().Lex();
1073 
1074  const AsmToken &IntTok = Parser.getTok();
1075  if (IntTok.isNot(AsmToken::Integer))
1076  return Error(IntTok.getLoc(), "expected stack index");
1077  switch (IntTok.getIntVal()) {
1078  case 0: RegNo = X86::ST0; break;
1079  case 1: RegNo = X86::ST1; break;
1080  case 2: RegNo = X86::ST2; break;
1081  case 3: RegNo = X86::ST3; break;
1082  case 4: RegNo = X86::ST4; break;
1083  case 5: RegNo = X86::ST5; break;
1084  case 6: RegNo = X86::ST6; break;
1085  case 7: RegNo = X86::ST7; break;
1086  default: return Error(IntTok.getLoc(), "invalid stack index");
1087  }
1088 
1089  if (getParser().Lex().isNot(AsmToken::RParen))
1090  return Error(Parser.getTok().getLoc(), "expected ')'");
1091 
1092  EndLoc = Parser.getTok().getEndLoc();
1093  Parser.Lex(); // Eat ')'
1094  return false;
1095  }
1096 
1097  EndLoc = Parser.getTok().getEndLoc();
1098 
1099  // If this is "db[0-15]", match it as an alias
1100  // for dr[0-15].
1101  if (RegNo == 0 && Tok.getString().startswith("db")) {
1102  if (Tok.getString().size() == 3) {
1103  switch (Tok.getString()[2]) {
1104  case '0': RegNo = X86::DR0; break;
1105  case '1': RegNo = X86::DR1; break;
1106  case '2': RegNo = X86::DR2; break;
1107  case '3': RegNo = X86::DR3; break;
1108  case '4': RegNo = X86::DR4; break;
1109  case '5': RegNo = X86::DR5; break;
1110  case '6': RegNo = X86::DR6; break;
1111  case '7': RegNo = X86::DR7; break;
1112  case '8': RegNo = X86::DR8; break;
1113  case '9': RegNo = X86::DR9; break;
1114  }
1115  } else if (Tok.getString().size() == 4 && Tok.getString()[2] == '1') {
1116  switch (Tok.getString()[3]) {
1117  case '0': RegNo = X86::DR10; break;
1118  case '1': RegNo = X86::DR11; break;
1119  case '2': RegNo = X86::DR12; break;
1120  case '3': RegNo = X86::DR13; break;
1121  case '4': RegNo = X86::DR14; break;
1122  case '5': RegNo = X86::DR15; break;
1123  }
1124  }
1125 
1126  if (RegNo != 0) {
1127  EndLoc = Parser.getTok().getEndLoc();
1128  Parser.Lex(); // Eat it.
1129  return false;
1130  }
1131  }
1132 
1133  if (RegNo == 0) {
1134  if (isParsingIntelSyntax()) return true;
1135  return Error(StartLoc, "invalid register name",
1136  SMRange(StartLoc, EndLoc));
1137  }
1138 
1139  Parser.Lex(); // Eat identifier token.
1140  return false;
1141 }
1142 
1143 void X86AsmParser::SetFrameRegister(unsigned RegNo) {
1144  Instrumentation->SetInitialFrameRegister(RegNo);
1145 }
1146 
1147 std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(SMLoc Loc) {
1148  bool Parse32 = is32BitMode() || Code16GCC;
1149  unsigned Basereg = is64BitMode() ? X86::RSI : (Parse32 ? X86::ESI : X86::SI);
1150  const MCExpr *Disp = MCConstantExpr::create(0, getContext());
1151  return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
1152  /*BaseReg=*/Basereg, /*IndexReg=*/0, /*Scale=*/1,
1153  Loc, Loc, 0);
1154 }
1155 
1156 std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand(SMLoc Loc) {
1157  bool Parse32 = is32BitMode() || Code16GCC;
1158  unsigned Basereg = is64BitMode() ? X86::RDI : (Parse32 ? X86::EDI : X86::DI);
1159  const MCExpr *Disp = MCConstantExpr::create(0, getContext());
1160  return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
1161  /*BaseReg=*/Basereg, /*IndexReg=*/0, /*Scale=*/1,
1162  Loc, Loc, 0);
1163 }
1164 
1165 bool X86AsmParser::IsSIReg(unsigned Reg) {
1166  switch (Reg) {
1167  default: llvm_unreachable("Only (R|E)SI and (R|E)DI are expected!");
1168  case X86::RSI:
1169  case X86::ESI:
1170  case X86::SI:
1171  return true;
1172  case X86::RDI:
1173  case X86::EDI:
1174  case X86::DI:
1175  return false;
1176  }
1177 }
1178 
1179 unsigned X86AsmParser::GetSIDIForRegClass(unsigned RegClassID, unsigned Reg,
1180  bool IsSIReg) {
1181  switch (RegClassID) {
1182  default: llvm_unreachable("Unexpected register class");
1183  case X86::GR64RegClassID:
1184  return IsSIReg ? X86::RSI : X86::RDI;
1185  case X86::GR32RegClassID:
1186  return IsSIReg ? X86::ESI : X86::EDI;
1187  case X86::GR16RegClassID:
1188  return IsSIReg ? X86::SI : X86::DI;
1189  }
1190 }
1191 
1192 void X86AsmParser::AddDefaultSrcDestOperands(
1193  OperandVector& Operands, std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
1194  std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst) {
1195  if (isParsingIntelSyntax()) {
1196  Operands.push_back(std::move(Dst));
1197  Operands.push_back(std::move(Src));
1198  }
1199  else {
1200  Operands.push_back(std::move(Src));
1201  Operands.push_back(std::move(Dst));
1202  }
1203 }
1204 
1205 bool X86AsmParser::VerifyAndAdjustOperands(OperandVector &OrigOperands,
1206  OperandVector &FinalOperands) {
1207 
1208  if (OrigOperands.size() > 1) {
1209  // Check if sizes match, OrigOperands also contains the instruction name
1210  assert(OrigOperands.size() == FinalOperands.size() + 1 &&
1211  "Operand size mismatch");
1212 
1214  // Verify types match
1215  int RegClassID = -1;
1216  for (unsigned int i = 0; i < FinalOperands.size(); ++i) {
1217  X86Operand &OrigOp = static_cast<X86Operand &>(*OrigOperands[i + 1]);
1218  X86Operand &FinalOp = static_cast<X86Operand &>(*FinalOperands[i]);
1219 
1220  if (FinalOp.isReg() &&
1221  (!OrigOp.isReg() || FinalOp.getReg() != OrigOp.getReg()))
1222  // Return false and let a normal complaint about bogus operands happen
1223  return false;
1224 
1225  if (FinalOp.isMem()) {
1226 
1227  if (!OrigOp.isMem())
1228  // Return false and let a normal complaint about bogus operands happen
1229  return false;
1230 
1231  unsigned OrigReg = OrigOp.Mem.BaseReg;
1232  unsigned FinalReg = FinalOp.Mem.BaseReg;
1233 
1234  // If we've already encounterd a register class, make sure all register
1235  // bases are of the same register class
1236  if (RegClassID != -1 &&
1237  !X86MCRegisterClasses[RegClassID].contains(OrigReg)) {
1238  return Error(OrigOp.getStartLoc(),
1239  "mismatching source and destination index registers");
1240  }
1241 
1242  if (X86MCRegisterClasses[X86::GR64RegClassID].contains(OrigReg))
1243  RegClassID = X86::GR64RegClassID;
1244  else if (X86MCRegisterClasses[X86::GR32RegClassID].contains(OrigReg))
1245  RegClassID = X86::GR32RegClassID;
1246  else if (X86MCRegisterClasses[X86::GR16RegClassID].contains(OrigReg))
1247  RegClassID = X86::GR16RegClassID;
1248  else
1249  // Unexpected register class type
1250  // Return false and let a normal complaint about bogus operands happen
1251  return false;
1252 
1253  bool IsSI = IsSIReg(FinalReg);
1254  FinalReg = GetSIDIForRegClass(RegClassID, FinalReg, IsSI);
1255 
1256  if (FinalReg != OrigReg) {
1257  std::string RegName = IsSI ? "ES:(R|E)SI" : "ES:(R|E)DI";
1258  Warnings.push_back(std::make_pair(
1259  OrigOp.getStartLoc(),
1260  "memory operand is only for determining the size, " + RegName +
1261  " will be used for the location"));
1262  }
1263 
1264  FinalOp.Mem.Size = OrigOp.Mem.Size;
1265  FinalOp.Mem.SegReg = OrigOp.Mem.SegReg;
1266  FinalOp.Mem.BaseReg = FinalReg;
1267  }
1268  }
1269 
1270  // Produce warnings only if all the operands passed the adjustment - prevent
1271  // legal cases like "movsd (%rax), %xmm0" mistakenly produce warnings
1272  for (auto &WarningMsg : Warnings) {
1273  Warning(WarningMsg.first, WarningMsg.second);
1274  }
1275 
1276  // Remove old operands
1277  for (unsigned int i = 0; i < FinalOperands.size(); ++i)
1278  OrigOperands.pop_back();
1279  }
1280  // OrigOperands.append(FinalOperands.begin(), FinalOperands.end());
1281  for (unsigned int i = 0; i < FinalOperands.size(); ++i)
1282  OrigOperands.push_back(std::move(FinalOperands[i]));
1283 
1284  return false;
1285 }
1286 
1287 std::unique_ptr<X86Operand> X86AsmParser::ParseOperand() {
1288  if (isParsingIntelSyntax())
1289  return ParseIntelOperand();
1290  return ParseATTOperand();
1291 }
1292 
1293 std::unique_ptr<X86Operand> X86AsmParser::CreateMemForInlineAsm(
1294  unsigned SegReg, const MCExpr *Disp, unsigned BaseReg, unsigned IndexReg,
1295  unsigned Scale, SMLoc Start, SMLoc End, unsigned Size, StringRef Identifier,
1296  const InlineAsmIdentifierInfo &Info) {
1297  // If we found a decl other than a VarDecl, then assume it is a FuncDecl or
1298  // some other label reference.
1300  // Insert an explicit size if the user didn't have one.
1301  if (!Size) {
1302  Size = getPointerWidth();
1303  InstInfo->AsmRewrites->emplace_back(AOK_SizeDirective, Start,
1304  /*Len=*/0, Size);
1305  }
1306  // Create an absolute memory reference in order to match against
1307  // instructions taking a PC relative operand.
1308  return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size,
1309  Identifier, Info.Label.Decl);
1310  }
1311  // We either have a direct symbol reference, or an offset from a symbol. The
1312  // parser always puts the symbol on the LHS, so look there for size
1313  // calculation purposes.
1314  unsigned FrontendSize = 0;
1315  void *Decl = nullptr;
1316  bool IsGlobalLV = false;
1318  // Size is in terms of bits in this context.
1319  FrontendSize = Info.Var.Type * 8;
1320  Decl = Info.Var.Decl;
1321  IsGlobalLV = Info.Var.IsGlobalLV;
1322  }
1323  // It is widely common for MS InlineAsm to use a global variable and one/two
1324  // registers in a mmory expression, and though unaccessible via rip/eip.
1325  if (IsGlobalLV && (BaseReg || IndexReg)) {
1326  return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End);
1327  // Otherwise, we set the base register to a non-zero value
1328  // if we don't know the actual value at this time. This is necessary to
1329  // get the matching correct in some cases.
1330  } else {
1331  BaseReg = BaseReg ? BaseReg : 1;
1332  return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
1333  IndexReg, Scale, Start, End, Size, Identifier,
1334  Decl, FrontendSize);
1335  }
1336 }
1337 
1338 // Some binary bitwise operators have a named synonymous
1339 // Query a candidate string for being such a named operator
1340 // and if so - invoke the appropriate handler
1341 bool X86AsmParser::ParseIntelNamedOperator(StringRef Name, IntelExprStateMachine &SM) {
1342  // A named operator should be either lower or upper case, but not a mix
1343  if (Name.compare(Name.lower()) && Name.compare(Name.upper()))
1344  return false;
1345  if (Name.equals_lower("not"))
1346  SM.onNot();
1347  else if (Name.equals_lower("or"))
1348  SM.onOr();
1349  else if (Name.equals_lower("shl"))
1350  SM.onLShift();
1351  else if (Name.equals_lower("shr"))
1352  SM.onRShift();
1353  else if (Name.equals_lower("xor"))
1354  SM.onXor();
1355  else if (Name.equals_lower("and"))
1356  SM.onAnd();
1357  else if (Name.equals_lower("mod"))
1358  SM.onMod();
1359  else
1360  return false;
1361  return true;
1362 }
1363 
1364 bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
1365  MCAsmParser &Parser = getParser();
1366  const AsmToken &Tok = Parser.getTok();
1367  StringRef ErrMsg;
1368 
1370  bool Done = false;
1371  while (!Done) {
1372  bool UpdateLocLex = true;
1373  AsmToken::TokenKind TK = getLexer().getKind();
1374 
1375  switch (TK) {
1376  default:
1377  if ((Done = SM.isValidEndState()))
1378  break;
1379  return Error(Tok.getLoc(), "unknown token in expression");
1381  Done = true;
1382  break;
1383  case AsmToken::Real:
1384  // DotOperator: [ebx].0
1385  UpdateLocLex = false;
1386  if (ParseIntelDotOperator(SM, End))
1387  return true;
1388  break;
1389  case AsmToken::At:
1390  case AsmToken::String:
1391  case AsmToken::Identifier: {
1392  SMLoc IdentLoc = Tok.getLoc();
1393  StringRef Identifier = Tok.getString();
1394  UpdateLocLex = false;
1395  // Register
1396  unsigned Reg;
1397  if (Tok.is(AsmToken::Identifier) && !ParseRegister(Reg, IdentLoc, End)) {
1398  if (SM.onRegister(Reg, ErrMsg))
1399  return Error(Tok.getLoc(), ErrMsg);
1400  break;
1401  }
1402  // Operator synonymous ("not", "or" etc.)
1403  if ((UpdateLocLex = ParseIntelNamedOperator(Identifier, SM)))
1404  break;
1405  // Symbol reference, when parsing assembly content
1407  const MCExpr *Val;
1408  if (!isParsingInlineAsm()) {
1409  if (getParser().parsePrimaryExpr(Val, End)) {
1410  return Error(Tok.getLoc(), "Unexpected identifier!");
1411  } else if (SM.onIdentifierExpr(Val, Identifier, Info, false, ErrMsg)) {
1412  return Error(IdentLoc, ErrMsg);
1413  } else
1414  break;
1415  }
1416  // MS InlineAsm operators (TYPE/LENGTH/SIZE)
1417  if (unsigned OpKind = IdentifyIntelInlineAsmOperator(Identifier)) {
1418  if (OpKind == IOK_OFFSET)
1419  return Error(IdentLoc, "Dealing OFFSET operator as part of"
1420  "a compound immediate expression is yet to be supported");
1421  if (int64_t Val = ParseIntelInlineAsmOperator(OpKind)) {
1422  if (SM.onInteger(Val, ErrMsg))
1423  return Error(IdentLoc, ErrMsg);
1424  } else
1425  return true;
1426  break;
1427  }
1428  // MS Dot Operator expression
1429  if (Identifier.count('.') && PrevTK == AsmToken::RBrac) {
1430  if (ParseIntelDotOperator(SM, End))
1431  return true;
1432  break;
1433  }
1434  // MS InlineAsm identifier
1435  // Call parseIdentifier() to combine @ with the identifier behind it.
1436  if (TK == AsmToken::At && Parser.parseIdentifier(Identifier))
1437  return Error(IdentLoc, "expected identifier");
1438  if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info, false, End))
1439  return true;
1440  else if (SM.onIdentifierExpr(Val, Identifier, Info, true, ErrMsg))
1441  return Error(IdentLoc, ErrMsg);
1442  break;
1443  }
1444  case AsmToken::Integer: {
1445  // Look for 'b' or 'f' following an Integer as a directional label
1446  SMLoc Loc = getTok().getLoc();
1447  int64_t IntVal = getTok().getIntVal();
1448  End = consumeToken();
1449  UpdateLocLex = false;
1450  if (getLexer().getKind() == AsmToken::Identifier) {
1451  StringRef IDVal = getTok().getString();
1452  if (IDVal == "f" || IDVal == "b") {
1453  MCSymbol *Sym =
1454  getContext().getDirectionalLocalSymbol(IntVal, IDVal == "b");
1456  const MCExpr *Val =
1457  MCSymbolRefExpr::create(Sym, Variant, getContext());
1458  if (IDVal == "b" && Sym->isUndefined())
1459  return Error(Loc, "invalid reference to undefined symbol");
1460  StringRef Identifier = Sym->getName();
1462  if (SM.onIdentifierExpr(Val, Identifier, Info,
1463  isParsingInlineAsm(), ErrMsg))
1464  return Error(Loc, ErrMsg);
1465  End = consumeToken();
1466  } else {
1467  if (SM.onInteger(IntVal, ErrMsg))
1468  return Error(Loc, ErrMsg);
1469  }
1470  } else {
1471  if (SM.onInteger(IntVal, ErrMsg))
1472  return Error(Loc, ErrMsg);
1473  }
1474  break;
1475  }
1476  case AsmToken::Plus:
1477  if (SM.onPlus(ErrMsg))
1478  return Error(getTok().getLoc(), ErrMsg);
1479  break;
1480  case AsmToken::Minus:
1481  if (SM.onMinus(ErrMsg))
1482  return Error(getTok().getLoc(), ErrMsg);
1483  break;
1484  case AsmToken::Tilde: SM.onNot(); break;
1485  case AsmToken::Star: SM.onStar(); break;
1486  case AsmToken::Slash: SM.onDivide(); break;
1487  case AsmToken::Percent: SM.onMod(); break;
1488  case AsmToken::Pipe: SM.onOr(); break;
1489  case AsmToken::Caret: SM.onXor(); break;
1490  case AsmToken::Amp: SM.onAnd(); break;
1491  case AsmToken::LessLess:
1492  SM.onLShift(); break;
1494  SM.onRShift(); break;
1495  case AsmToken::LBrac:
1496  if (SM.onLBrac())
1497  return Error(Tok.getLoc(), "unexpected bracket encountered");
1498  break;
1499  case AsmToken::RBrac:
1500  if (SM.onRBrac())
1501  return Error(Tok.getLoc(), "unexpected bracket encountered");
1502  break;
1503  case AsmToken::LParen: SM.onLParen(); break;
1504  case AsmToken::RParen: SM.onRParen(); break;
1505  }
1506  if (SM.hadError())
1507  return Error(Tok.getLoc(), "unknown token in expression");
1508 
1509  if (!Done && UpdateLocLex)
1510  End = consumeToken();
1511 
1512  PrevTK = TK;
1513  }
1514  return false;
1515 }
1516 
1517 void X86AsmParser::RewriteIntelExpression(IntelExprStateMachine &SM,
1518  SMLoc Start, SMLoc End) {
1519  SMLoc Loc = Start;
1520  unsigned ExprLen = End.getPointer() - Start.getPointer();
1521  // Skip everything before a symbol displacement (if we have one)
1522  if (SM.getSym()) {
1523  StringRef SymName = SM.getSymName();
1524  if (unsigned Len = SymName.data() - Start.getPointer())
1525  InstInfo->AsmRewrites->emplace_back(AOK_Skip, Start, Len);
1526  Loc = SMLoc::getFromPointer(SymName.data() + SymName.size());
1527  ExprLen = End.getPointer() - (SymName.data() + SymName.size());
1528  // If we have only a symbol than there's no need for complex rewrite,
1529  // simply skip everything after it
1530  if (!(SM.getBaseReg() || SM.getIndexReg() || SM.getImm())) {
1531  if (ExprLen)
1532  InstInfo->AsmRewrites->emplace_back(AOK_Skip, Loc, ExprLen);
1533  return;
1534  }
1535  }
1536  // Build an Intel Expression rewrite
1537  StringRef BaseRegStr;
1538  StringRef IndexRegStr;
1539  if (SM.getBaseReg())
1540  BaseRegStr = X86IntelInstPrinter::getRegisterName(SM.getBaseReg());
1541  if (SM.getIndexReg())
1542  IndexRegStr = X86IntelInstPrinter::getRegisterName(SM.getIndexReg());
1543  // Emit it
1544  IntelExpr Expr(BaseRegStr, IndexRegStr, SM.getScale(), SM.getImm(), SM.isMemExpr());
1545  InstInfo->AsmRewrites->emplace_back(Loc, ExprLen, Expr);
1546 }
1547 
1548 // Inline assembly may use variable names with namespace alias qualifiers.
1549 bool X86AsmParser::ParseIntelInlineAsmIdentifier(const MCExpr *&Val,
1550  StringRef &Identifier,
1552  bool IsUnevaluatedOperand,
1553  SMLoc &End) {
1554  MCAsmParser &Parser = getParser();
1555  assert(isParsingInlineAsm() && "Expected to be parsing inline assembly.");
1556  Val = nullptr;
1557 
1558  StringRef LineBuf(Identifier.data());
1559  SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);
1560 
1561  const AsmToken &Tok = Parser.getTok();
1562  SMLoc Loc = Tok.getLoc();
1563 
1564  // Advance the token stream until the end of the current token is
1565  // after the end of what the frontend claimed.
1566  const char *EndPtr = Tok.getLoc().getPointer() + LineBuf.size();
1567  do {
1568  End = Tok.getEndLoc();
1569  getLexer().Lex();
1570  } while (End.getPointer() < EndPtr);
1571  Identifier = LineBuf;
1572 
1573  // The frontend should end parsing on an assembler token boundary, unless it
1574  // failed parsing.
1575  assert((End.getPointer() == EndPtr ||
1577  "frontend claimed part of a token?");
1578 
1579  // If the identifier lookup was unsuccessful, assume that we are dealing with
1580  // a label.
1582  StringRef InternalName =
1583  SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(),
1584  Loc, false);
1585  assert(InternalName.size() && "We should have an internal name here.");
1586  // Push a rewrite for replacing the identifier name with the internal name.
1587  InstInfo->AsmRewrites->emplace_back(AOK_Label, Loc, Identifier.size(),
1588  InternalName);
1590  return false;
1591  // Create the symbol reference.
1592  MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
1594  Val = MCSymbolRefExpr::create(Sym, Variant, getParser().getContext());
1595  return false;
1596 }
1597 
1598 //ParseRoundingModeOp - Parse AVX-512 rounding mode operand
1599 std::unique_ptr<X86Operand>
1600 X86AsmParser::ParseRoundingModeOp(SMLoc Start) {
1601  MCAsmParser &Parser = getParser();
1602  const AsmToken &Tok = Parser.getTok();
1603  // Eat "{" and mark the current place.
1604  const SMLoc consumedToken = consumeToken();
1605  if (Tok.getIdentifier().startswith("r")){
1606  int rndMode = StringSwitch<int>(Tok.getIdentifier())
1611  .Default(-1);
1612  if (-1 == rndMode)
1613  return ErrorOperand(Tok.getLoc(), "Invalid rounding mode.");
1614  Parser.Lex(); // Eat "r*" of r*-sae
1615  if (!getLexer().is(AsmToken::Minus))
1616  return ErrorOperand(Tok.getLoc(), "Expected - at this point");
1617  Parser.Lex(); // Eat "-"
1618  Parser.Lex(); // Eat the sae
1619  if (!getLexer().is(AsmToken::RCurly))
1620  return ErrorOperand(Tok.getLoc(), "Expected } at this point");
1621  SMLoc End = Tok.getEndLoc();
1622  Parser.Lex(); // Eat "}"
1623  const MCExpr *RndModeOp =
1624  MCConstantExpr::create(rndMode, Parser.getContext());
1625  return X86Operand::CreateImm(RndModeOp, Start, End);
1626  }
1627  if(Tok.getIdentifier().equals("sae")){
1628  Parser.Lex(); // Eat the sae
1629  if (!getLexer().is(AsmToken::RCurly))
1630  return ErrorOperand(Tok.getLoc(), "Expected } at this point");
1631  Parser.Lex(); // Eat "}"
1632  return X86Operand::CreateToken("{sae}", consumedToken);
1633  }
1634  return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1635 }
1636 
1637 /// Parse the '.' operator.
1638 bool X86AsmParser::ParseIntelDotOperator(IntelExprStateMachine &SM, SMLoc &End) {
1639  const AsmToken &Tok = getTok();
1640  unsigned Offset;
1641 
1642  // Drop the optional '.'.
1643  StringRef DotDispStr = Tok.getString();
1644  if (DotDispStr.startswith("."))
1645  DotDispStr = DotDispStr.drop_front(1);
1646 
1647  // .Imm gets lexed as a real.
1648  if (Tok.is(AsmToken::Real)) {
1649  APInt DotDisp;
1650  DotDispStr.getAsInteger(10, DotDisp);
1651  Offset = DotDisp.getZExtValue();
1652  } else if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) {
1653  std::pair<StringRef, StringRef> BaseMember = DotDispStr.split('.');
1654  if (SemaCallback->LookupInlineAsmField(BaseMember.first, BaseMember.second,
1655  Offset))
1656  return Error(Tok.getLoc(), "Unable to lookup field reference!");
1657  } else
1658  return Error(Tok.getLoc(), "Unexpected token type!");
1659 
1660  // Eat the DotExpression and update End
1661  End = SMLoc::getFromPointer(DotDispStr.data());
1662  const char *DotExprEndLoc = DotDispStr.data() + DotDispStr.size();
1663  while (Tok.getLoc().getPointer() < DotExprEndLoc)
1664  Lex();
1665  SM.addImm(Offset);
1666  return false;
1667 }
1668 
1669 /// Parse the 'offset' operator. This operator is used to specify the
1670 /// location rather then the content of a variable.
1671 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOffsetOfOperator() {
1672  MCAsmParser &Parser = getParser();
1673  const AsmToken &Tok = Parser.getTok();
1674  SMLoc OffsetOfLoc = Tok.getLoc();
1675  Parser.Lex(); // Eat offset.
1676 
1677  const MCExpr *Val;
1679  SMLoc Start = Tok.getLoc(), End;
1680  StringRef Identifier = Tok.getString();
1681  if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
1682  /*Unevaluated=*/false, End))
1683  return nullptr;
1684 
1685  void *Decl = nullptr;
1686  // FIXME: MS evaluates "offset <Constant>" to the underlying integral
1688  return ErrorOperand(Start, "offset operator cannot yet handle constants");
1689  else if (Info.isKind(InlineAsmIdentifierInfo::IK_Var))
1690  Decl = Info.Var.Decl;
1691  // Don't emit the offset operator.
1692  InstInfo->AsmRewrites->emplace_back(AOK_Skip, OffsetOfLoc, 7);
1693 
1694  // The offset operator will have an 'r' constraint, thus we need to create
1695  // register operand to ensure proper matching. Just pick a GPR based on
1696  // the size of a pointer.
1697  bool Parse32 = is32BitMode() || Code16GCC;
1698  unsigned RegNo = is64BitMode() ? X86::RBX : (Parse32 ? X86::EBX : X86::BX);
1699 
1700  return X86Operand::CreateReg(RegNo, Start, End, /*GetAddress=*/true,
1701  OffsetOfLoc, Identifier, Decl);
1702 }
1703 
1704 // Query a candidate string for being an Intel assembly operator
1705 // Report back its kind, or IOK_INVALID if does not evaluated as a known one
1706 unsigned X86AsmParser::IdentifyIntelInlineAsmOperator(StringRef Name) {
1708  .Cases("TYPE","type",IOK_TYPE)
1709  .Cases("SIZE","size",IOK_SIZE)
1710  .Cases("LENGTH","length",IOK_LENGTH)
1711  .Cases("OFFSET","offset",IOK_OFFSET)
1712  .Default(IOK_INVALID);
1713 }
1714 
1715 /// Parse the 'LENGTH', 'TYPE' and 'SIZE' operators. The LENGTH operator
1716 /// returns the number of elements in an array. It returns the value 1 for
1717 /// non-array variables. The SIZE operator returns the size of a C or C++
1718 /// variable. A variable's size is the product of its LENGTH and TYPE. The
1719 /// TYPE operator returns the size of a C or C++ type or variable. If the
1720 /// variable is an array, TYPE returns the size of a single element.
1721 unsigned X86AsmParser::ParseIntelInlineAsmOperator(unsigned OpKind) {
1722  MCAsmParser &Parser = getParser();
1723  const AsmToken &Tok = Parser.getTok();
1724  Parser.Lex(); // Eat operator.
1725 
1726  const MCExpr *Val = nullptr;
1728  SMLoc Start = Tok.getLoc(), End;
1729  StringRef Identifier = Tok.getString();
1730  if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
1731  /*Unevaluated=*/true, End))
1732  return 0;
1733 
1735  Error(Start, "unable to lookup expression");
1736  return 0;
1737  }
1738 
1739  unsigned CVal = 0;
1740  switch(OpKind) {
1741  default: llvm_unreachable("Unexpected operand kind!");
1742  case IOK_LENGTH: CVal = Info.Var.Length; break;
1743  case IOK_SIZE: CVal = Info.Var.Size; break;
1744  case IOK_TYPE: CVal = Info.Var.Type; break;
1745  }
1746 
1747  return CVal;
1748 }
1749 
1750 bool X86AsmParser::ParseIntelMemoryOperandSize(unsigned &Size) {
1751  Size = StringSwitch<unsigned>(getTok().getString())
1752  .Cases("BYTE", "byte", 8)
1753  .Cases("WORD", "word", 16)
1754  .Cases("DWORD", "dword", 32)
1755  .Cases("FLOAT", "float", 32)
1756  .Cases("LONG", "long", 32)
1757  .Cases("FWORD", "fword", 48)
1758  .Cases("DOUBLE", "double", 64)
1759  .Cases("QWORD", "qword", 64)
1760  .Cases("MMWORD","mmword", 64)
1761  .Cases("XWORD", "xword", 80)
1762  .Cases("TBYTE", "tbyte", 80)
1763  .Cases("XMMWORD", "xmmword", 128)
1764  .Cases("YMMWORD", "ymmword", 256)
1765  .Cases("ZMMWORD", "zmmword", 512)
1766  .Default(0);
1767  if (Size) {
1768  const AsmToken &Tok = Lex(); // Eat operand size (e.g., byte, word).
1769  if (!(Tok.getString().equals("PTR") || Tok.getString().equals("ptr")))
1770  return Error(Tok.getLoc(), "Expected 'PTR' or 'ptr' token!");
1771  Lex(); // Eat ptr.
1772  }
1773  return false;
1774 }
1775 
1776 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand() {
1777  MCAsmParser &Parser = getParser();
1778  const AsmToken &Tok = Parser.getTok();
1779  SMLoc Start, End;
1780 
1781  // FIXME: Offset operator
1782  // Should be handled as part of immediate expression, as other operators
1783  // Currently, only supported as a stand-alone operand
1784  if (isParsingInlineAsm())
1785  if (IdentifyIntelInlineAsmOperator(Tok.getString()) == IOK_OFFSET)
1786  return ParseIntelOffsetOfOperator();
1787 
1788  // Parse optional Size directive.
1789  unsigned Size;
1790  if (ParseIntelMemoryOperandSize(Size))
1791  return nullptr;
1792  bool PtrInOperand = bool(Size);
1793 
1794  Start = Tok.getLoc();
1795 
1796  // Rounding mode operand.
1797  if (getLexer().is(AsmToken::LCurly))
1798  return ParseRoundingModeOp(Start);
1799 
1800  // Register operand.
1801  unsigned RegNo = 0;
1802  if (Tok.is(AsmToken::Identifier) && !ParseRegister(RegNo, Start, End)) {
1803  if (RegNo == X86::RIP)
1804  return ErrorOperand(Start, "rip can only be used as a base register");
1805  // A Register followed by ':' is considered a segment override
1806  if (Tok.isNot(AsmToken::Colon))
1807  return !PtrInOperand ? X86Operand::CreateReg(RegNo, Start, End) :
1808  ErrorOperand(Start, "expected memory operand after 'ptr', "
1809  "found register operand instead");
1810  // An alleged segment override. check if we have a valid segment register
1811  if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo))
1812  return ErrorOperand(Start, "invalid segment register");
1813  // Eat ':' and update Start location
1814  Start = Lex().getLoc();
1815  }
1816 
1817  // Immediates and Memory
1818  IntelExprStateMachine SM;
1819  if (ParseIntelExpression(SM, End))
1820  return nullptr;
1821 
1822  if (isParsingInlineAsm())
1823  RewriteIntelExpression(SM, Start, Tok.getLoc());
1824 
1825  int64_t Imm = SM.getImm();
1826  const MCExpr *Disp = SM.getSym();
1827  const MCExpr *ImmDisp = MCConstantExpr::create(Imm, getContext());
1828  if (Disp && Imm)
1829  Disp = MCBinaryExpr::createAdd(Disp, ImmDisp, getContext());
1830  if (!Disp)
1831  Disp = ImmDisp;
1832 
1833  // RegNo != 0 specifies a valid segment register,
1834  // and we are parsing a segment override
1835  if (!SM.isMemExpr() && !RegNo)
1836  return X86Operand::CreateImm(Disp, Start, End);
1837 
1838  StringRef ErrMsg;
1839  unsigned BaseReg = SM.getBaseReg();
1840  unsigned IndexReg = SM.getIndexReg();
1841  unsigned Scale = SM.getScale();
1842 
1843  if ((BaseReg || IndexReg) &&
1844  CheckBaseRegAndIndexRegAndScale(BaseReg, IndexReg, Scale, ErrMsg))
1845  return ErrorOperand(Start, ErrMsg);
1846  if (isParsingInlineAsm())
1847  return CreateMemForInlineAsm(RegNo, Disp, BaseReg, IndexReg,
1848  Scale, Start, End, Size, SM.getSymName(),
1849  SM.getIdentifierInfo());
1850  if (!(BaseReg || IndexReg || RegNo))
1851  return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size);
1852  return X86Operand::CreateMem(getPointerWidth(), RegNo, Disp,
1853  BaseReg, IndexReg, Scale, Start, End, Size);
1854 }
1855 
1856 std::unique_ptr<X86Operand> X86AsmParser::ParseATTOperand() {
1857  MCAsmParser &Parser = getParser();
1858  switch (getLexer().getKind()) {
1859  default:
1860  // Parse a memory operand with no segment register.
1861  return ParseMemOperand(0, Parser.getTok().getLoc());
1862  case AsmToken::Percent: {
1863  // Read the register.
1864  unsigned RegNo;
1865  SMLoc Start, End;
1866  if (ParseRegister(RegNo, Start, End)) return nullptr;
1867  if (RegNo == X86::EIZ || RegNo == X86::RIZ) {
1868  Error(Start, "%eiz and %riz can only be used as index registers",
1869  SMRange(Start, End));
1870  return nullptr;
1871  }
1872  if (RegNo == X86::RIP) {
1873  Error(Start, "%rip can only be used as a base register",
1874  SMRange(Start, End));
1875  return nullptr;
1876  }
1877 
1878  // If this is a segment register followed by a ':', then this is the start
1879  // of a memory reference, otherwise this is a normal register reference.
1880  if (getLexer().isNot(AsmToken::Colon))
1881  return X86Operand::CreateReg(RegNo, Start, End);
1882 
1883  if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo))
1884  return ErrorOperand(Start, "invalid segment register");
1885 
1886  getParser().Lex(); // Eat the colon.
1887  return ParseMemOperand(RegNo, Start);
1888  }
1889  case AsmToken::Dollar: {
1890  // $42 -> immediate.
1891  SMLoc Start = Parser.getTok().getLoc(), End;
1892  Parser.Lex();
1893  const MCExpr *Val;
1894  if (getParser().parseExpression(Val, End))
1895  return nullptr;
1896  return X86Operand::CreateImm(Val, Start, End);
1897  }
1898  case AsmToken::LCurly:{
1899  SMLoc Start = Parser.getTok().getLoc();
1900  return ParseRoundingModeOp(Start);
1901  }
1902  }
1903 }
1904 
1905 // true on failure, false otherwise
1906 // If no {z} mark was found - Parser doesn't advance
1907 bool X86AsmParser::ParseZ(std::unique_ptr<X86Operand> &Z,
1908  const SMLoc &StartLoc) {
1909  MCAsmParser &Parser = getParser();
1910  // Assuming we are just pass the '{' mark, quering the next token
1911  // Searched for {z}, but none was found. Return false, as no parsing error was
1912  // encountered
1913  if (!(getLexer().is(AsmToken::Identifier) &&
1914  (getLexer().getTok().getIdentifier() == "z")))
1915  return false;
1916  Parser.Lex(); // Eat z
1917  // Query and eat the '}' mark
1918  if (!getLexer().is(AsmToken::RCurly))
1919  return Error(getLexer().getLoc(), "Expected } at this point");
1920  Parser.Lex(); // Eat '}'
1921  // Assign Z with the {z} mark opernad
1922  Z = X86Operand::CreateToken("{z}", StartLoc);
1923  return false;
1924 }
1925 
1926 // true on failure, false otherwise
1927 bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands,
1928  const MCParsedAsmOperand &Op) {
1929  MCAsmParser &Parser = getParser();
1930  if (getLexer().is(AsmToken::LCurly)) {
1931  // Eat "{" and mark the current place.
1932  const SMLoc consumedToken = consumeToken();
1933  // Distinguish {1to<NUM>} from {%k<NUM>}.
1934  if(getLexer().is(AsmToken::Integer)) {
1935  // Parse memory broadcasting ({1to<NUM>}).
1936  if (getLexer().getTok().getIntVal() != 1)
1937  return TokError("Expected 1to<NUM> at this point");
1938  Parser.Lex(); // Eat "1" of 1to8
1939  if (!getLexer().is(AsmToken::Identifier) ||
1940  !getLexer().getTok().getIdentifier().startswith("to"))
1941  return TokError("Expected 1to<NUM> at this point");
1942  // Recognize only reasonable suffixes.
1943  const char *BroadcastPrimitive =
1944  StringSwitch<const char*>(getLexer().getTok().getIdentifier())
1945  .Case("to2", "{1to2}")
1946  .Case("to4", "{1to4}")
1947  .Case("to8", "{1to8}")
1948  .Case("to16", "{1to16}")
1949  .Default(nullptr);
1950  if (!BroadcastPrimitive)
1951  return TokError("Invalid memory broadcast primitive.");
1952  Parser.Lex(); // Eat "toN" of 1toN
1953  if (!getLexer().is(AsmToken::RCurly))
1954  return TokError("Expected } at this point");
1955  Parser.Lex(); // Eat "}"
1956  Operands.push_back(X86Operand::CreateToken(BroadcastPrimitive,
1957  consumedToken));
1958  // No AVX512 specific primitives can pass
1959  // after memory broadcasting, so return.
1960  return false;
1961  } else {
1962  // Parse either {k}{z}, {z}{k}, {k} or {z}
1963  // last one have no meaning, but GCC accepts it
1964  // Currently, we're just pass a '{' mark
1965  std::unique_ptr<X86Operand> Z;
1966  if (ParseZ(Z, consumedToken))
1967  return true;
1968  // Reaching here means that parsing of the allegadly '{z}' mark yielded
1969  // no errors.
1970  // Query for the need of further parsing for a {%k<NUM>} mark
1971  if (!Z || getLexer().is(AsmToken::LCurly)) {
1972  SMLoc StartLoc = Z ? consumeToken() : consumedToken;
1973  // Parse an op-mask register mark ({%k<NUM>}), which is now to be
1974  // expected
1975  unsigned RegNo;
1976  SMLoc RegLoc;
1977  if (!ParseRegister(RegNo, RegLoc, StartLoc) &&
1978  X86MCRegisterClasses[X86::VK1RegClassID].contains(RegNo)) {
1979  if (RegNo == X86::K0)
1980  return Error(RegLoc, "Register k0 can't be used as write mask");
1981  if (!getLexer().is(AsmToken::RCurly))
1982  return Error(getLexer().getLoc(), "Expected } at this point");
1983  Operands.push_back(X86Operand::CreateToken("{", StartLoc));
1984  Operands.push_back(
1985  X86Operand::CreateReg(RegNo, StartLoc, StartLoc));
1986  Operands.push_back(X86Operand::CreateToken("}", consumeToken()));
1987  } else
1988  return Error(getLexer().getLoc(),
1989  "Expected an op-mask register at this point");
1990  // {%k<NUM>} mark is found, inquire for {z}
1991  if (getLexer().is(AsmToken::LCurly) && !Z) {
1992  // Have we've found a parsing error, or found no (expected) {z} mark
1993  // - report an error
1994  if (ParseZ(Z, consumeToken()) || !Z)
1995  return Error(getLexer().getLoc(),
1996  "Expected a {z} mark at this point");
1997 
1998  }
1999  // '{z}' on its own is meaningless, hence should be ignored.
2000  // on the contrary - have it been accompanied by a K register,
2001  // allow it.
2002  if (Z)
2003  Operands.push_back(std::move(Z));
2004  }
2005  }
2006  }
2007  return false;
2008 }
2009 
2010 /// ParseMemOperand: segment: disp(basereg, indexreg, scale). The '%ds:' prefix
2011 /// has already been parsed if present.
2012 std::unique_ptr<X86Operand> X86AsmParser::ParseMemOperand(unsigned SegReg,
2013  SMLoc MemStart) {
2014 
2015  MCAsmParser &Parser = getParser();
2016  // We have to disambiguate a parenthesized expression "(4+5)" from the start
2017  // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)". The
2018  // only way to do this without lookahead is to eat the '(' and see what is
2019  // after it.
2020  const MCExpr *Disp = MCConstantExpr::create(0, getParser().getContext());
2021  if (getLexer().isNot(AsmToken::LParen)) {
2022  SMLoc ExprEnd;
2023  if (getParser().parseExpression(Disp, ExprEnd)) return nullptr;
2024  // Disp may be a variable, handle register values.
2025  if (auto *RE = dyn_cast<X86MCExpr>(Disp))
2026  return X86Operand::CreateReg(RE->getRegNo(), MemStart, ExprEnd);
2027 
2028  // After parsing the base expression we could either have a parenthesized
2029  // memory address or not. If not, return now. If so, eat the (.
2030  if (getLexer().isNot(AsmToken::LParen)) {
2031  // Unless we have a segment register, treat this as an immediate.
2032  if (SegReg == 0)
2033  return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, ExprEnd);
2034  return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
2035  MemStart, ExprEnd);
2036  }
2037 
2038  // Eat the '('.
2039  Parser.Lex();
2040  } else {
2041  // Okay, we have a '('. We don't know if this is an expression or not, but
2042  // so we have to eat the ( to see beyond it.
2043  SMLoc LParenLoc = Parser.getTok().getLoc();
2044  Parser.Lex(); // Eat the '('.
2045 
2046  if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) {
2047  // Nothing to do here, fall into the code below with the '(' part of the
2048  // memory operand consumed.
2049  } else {
2050  SMLoc ExprEnd;
2051  getLexer().UnLex(AsmToken(AsmToken::LParen, "("));
2052 
2053  // It must be either an parenthesized expression, or an expression that
2054  // begins from a parenthesized expression, parse it now. Example: (1+2) or
2055  // (1+2)+3
2056  if (getParser().parseExpression(Disp, ExprEnd))
2057  return nullptr;
2058 
2059  // After parsing the base expression we could either have a parenthesized
2060  // memory address or not. If not, return now. If so, eat the (.
2061  if (getLexer().isNot(AsmToken::LParen)) {
2062  // Unless we have a segment register, treat this as an immediate.
2063  if (SegReg == 0)
2064  return X86Operand::CreateMem(getPointerWidth(), Disp, LParenLoc,
2065  ExprEnd);
2066  return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
2067  MemStart, ExprEnd);
2068  }
2069 
2070  // Eat the '('.
2071  Parser.Lex();
2072  }
2073  }
2074 
2075  // If we reached here, then we just ate the ( of the memory operand. Process
2076  // the rest of the memory operand.
2077  unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
2078  SMLoc IndexLoc, BaseLoc;
2079 
2080  if (getLexer().is(AsmToken::Percent)) {
2081  SMLoc StartLoc, EndLoc;
2082  BaseLoc = Parser.getTok().getLoc();
2083  if (ParseRegister(BaseReg, StartLoc, EndLoc)) return nullptr;
2084  if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) {
2085  Error(StartLoc, "eiz and riz can only be used as index registers",
2086  SMRange(StartLoc, EndLoc));
2087  return nullptr;
2088  }
2089  }
2090 
2091  if (getLexer().is(AsmToken::Comma)) {
2092  Parser.Lex(); // Eat the comma.
2093  IndexLoc = Parser.getTok().getLoc();
2094 
2095  // Following the comma we should have either an index register, or a scale
2096  // value. We don't support the later form, but we want to parse it
2097  // correctly.
2098  //
2099  // Not that even though it would be completely consistent to support syntax
2100  // like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this.
2101  if (getLexer().is(AsmToken::Percent)) {
2102  SMLoc L;
2103  if (ParseRegister(IndexReg, L, L))
2104  return nullptr;
2105  if (BaseReg == X86::RIP) {
2106  Error(IndexLoc, "%rip as base register can not have an index register");
2107  return nullptr;
2108  }
2109  if (IndexReg == X86::RIP) {
2110  Error(IndexLoc, "%rip is not allowed as an index register");
2111  return nullptr;
2112  }
2113 
2114  if (getLexer().isNot(AsmToken::RParen)) {
2115  // Parse the scale amount:
2116  // ::= ',' [scale-expression]
2117  if (parseToken(AsmToken::Comma, "expected comma in scale expression"))
2118  return nullptr;
2119 
2120  if (getLexer().isNot(AsmToken::RParen)) {
2121  SMLoc Loc = Parser.getTok().getLoc();
2122 
2123  int64_t ScaleVal;
2124  if (getParser().parseAbsoluteExpression(ScaleVal)){
2125  Error(Loc, "expected scale expression");
2126  return nullptr;
2127  }
2128 
2129  // Validate the scale amount.
2130  if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
2131  ScaleVal != 1) {
2132  Error(Loc, "scale factor in 16-bit address must be 1");
2133  return nullptr;
2134  }
2135  if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 &&
2136  ScaleVal != 8) {
2137  Error(Loc, "scale factor in address must be 1, 2, 4 or 8");
2138  return nullptr;
2139  }
2140  Scale = (unsigned)ScaleVal;
2141  }
2142  }
2143  } else if (getLexer().isNot(AsmToken::RParen)) {
2144  // A scale amount without an index is ignored.
2145  // index.
2146  SMLoc Loc = Parser.getTok().getLoc();
2147 
2148  int64_t Value;
2149  if (getParser().parseAbsoluteExpression(Value))
2150  return nullptr;
2151 
2152  if (Value != 1)
2153  Warning(Loc, "scale factor without index register is ignored");
2154  Scale = 1;
2155  }
2156  }
2157 
2158  // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
2159  SMLoc MemEnd = Parser.getTok().getEndLoc();
2160  if (parseToken(AsmToken::RParen, "unexpected token in memory operand"))
2161  return nullptr;
2162 
2163  // Check for use of invalid 16-bit registers. Only BX/BP/SI/DI are allowed,
2164  // and then only in non-64-bit modes. Except for DX, which is a special case
2165  // because an unofficial form of in/out instructions uses it.
2166  if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
2167  (is64BitMode() || (BaseReg != X86::BX && BaseReg != X86::BP &&
2168  BaseReg != X86::SI && BaseReg != X86::DI)) &&
2169  BaseReg != X86::DX) {
2170  Error(BaseLoc, "invalid 16-bit base register");
2171  return nullptr;
2172  }
2173  if (BaseReg == 0 &&
2174  X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg)) {
2175  Error(IndexLoc, "16-bit memory operand may not include only index register");
2176  return nullptr;
2177  }
2178 
2179  StringRef ErrMsg;
2180  if (CheckBaseRegAndIndexRegAndScale(BaseReg, IndexReg, Scale, ErrMsg)) {
2181  Error(BaseLoc, ErrMsg);
2182  return nullptr;
2183  }
2184 
2185  if (SegReg || BaseReg || IndexReg)
2186  return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
2187  IndexReg, Scale, MemStart, MemEnd);
2188  return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, MemEnd);
2189 }
2190 
2191 // Parse either a standard expression or a register.
2193  SMLoc &EndLoc) {
2194  MCAsmParser &Parser = getParser();
2195  if (Parser.parseExpression(Res, EndLoc)) {
2196  SMLoc StartLoc = Parser.getTok().getLoc();
2197  // Normal Expression parse fails, check if it could be a register.
2198  unsigned RegNo;
2199  if (Parser.getTargetParser().ParseRegister(RegNo, StartLoc, EndLoc))
2200  return true;
2201  // Clear previous parse error and return correct expression.
2202  Parser.clearPendingErrors();
2203  Res = X86MCExpr::create(RegNo, Parser.getContext());
2204  return false;
2205  }
2206 
2207  return false;
2208 }
2209 
2210 bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2211  SMLoc NameLoc, OperandVector &Operands) {
2212  MCAsmParser &Parser = getParser();
2213  InstInfo = &Info;
2214  StringRef PatchedName = Name;
2215 
2216  if ((Name.equals("jmp") || Name.equals("jc") || Name.equals("jz")) &&
2217  isParsingIntelSyntax() && isParsingInlineAsm()) {
2218  StringRef NextTok = Parser.getTok().getString();
2219  if (NextTok == "short") {
2220  SMLoc NameEndLoc =
2221  NameLoc.getFromPointer(NameLoc.getPointer() + Name.size());
2222  // Eat the short keyword
2223  Parser.Lex();
2224  // MS ignores the short keyword, it determines the jmp type based
2225  // on the distance of the label
2226  InstInfo->AsmRewrites->emplace_back(AOK_Skip, NameEndLoc,
2227  NextTok.size() + 1);
2228  }
2229  }
2230 
2231  // FIXME: Hack to recognize setneb as setne.
2232  if (PatchedName.startswith("set") && PatchedName.endswith("b") &&
2233  PatchedName != "setb" && PatchedName != "setnb")
2234  PatchedName = PatchedName.substr(0, Name.size()-1);
2235 
2236  // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}.
2237  if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) &&
2238  (PatchedName.endswith("ss") || PatchedName.endswith("sd") ||
2239  PatchedName.endswith("ps") || PatchedName.endswith("pd"))) {
2240  bool IsVCMP = PatchedName[0] == 'v';
2241  unsigned CCIdx = IsVCMP ? 4 : 3;
2242  unsigned ComparisonCode = StringSwitch<unsigned>(
2243  PatchedName.slice(CCIdx, PatchedName.size() - 2))
2244  .Case("eq", 0x00)
2245  .Case("eq_oq", 0x00)
2246  .Case("lt", 0x01)
2247  .Case("lt_os", 0x01)
2248  .Case("le", 0x02)
2249  .Case("le_os", 0x02)
2250  .Case("unord", 0x03)
2251  .Case("unord_q", 0x03)
2252  .Case("neq", 0x04)
2253  .Case("neq_uq", 0x04)
2254  .Case("nlt", 0x05)
2255  .Case("nlt_us", 0x05)
2256  .Case("nle", 0x06)
2257  .Case("nle_us", 0x06)
2258  .Case("ord", 0x07)
2259  .Case("ord_q", 0x07)
2260  /* AVX only from here */
2261  .Case("eq_uq", 0x08)
2262  .Case("nge", 0x09)
2263  .Case("nge_us", 0x09)
2264  .Case("ngt", 0x0A)
2265  .Case("ngt_us", 0x0A)
2266  .Case("false", 0x0B)
2267  .Case("false_oq", 0x0B)
2268  .Case("neq_oq", 0x0C)
2269  .Case("ge", 0x0D)
2270  .Case("ge_os", 0x0D)
2271  .Case("gt", 0x0E)
2272  .Case("gt_os", 0x0E)
2273  .Case("true", 0x0F)
2274  .Case("true_uq", 0x0F)
2275  .Case("eq_os", 0x10)
2276  .Case("lt_oq", 0x11)
2277  .Case("le_oq", 0x12)
2278  .Case("unord_s", 0x13)
2279  .Case("neq_us", 0x14)
2280  .Case("nlt_uq", 0x15)
2281  .Case("nle_uq", 0x16)
2282  .Case("ord_s", 0x17)
2283  .Case("eq_us", 0x18)
2284  .Case("nge_uq", 0x19)
2285  .Case("ngt_uq", 0x1A)
2286  .Case("false_os", 0x1B)
2287  .Case("neq_os", 0x1C)
2288  .Case("ge_oq", 0x1D)
2289  .Case("gt_oq", 0x1E)
2290  .Case("true_us", 0x1F)
2291  .Default(~0U);
2292  if (ComparisonCode != ~0U && (IsVCMP || ComparisonCode < 8)) {
2293 
2294  Operands.push_back(X86Operand::CreateToken(PatchedName.slice(0, CCIdx),
2295  NameLoc));
2296 
2297  const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2298  getParser().getContext());
2299  Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2300 
2301  PatchedName = PatchedName.substr(PatchedName.size() - 2);
2302  }
2303  }
2304 
2305  // FIXME: Hack to recognize vpcmp<comparison code>{ub,uw,ud,uq,b,w,d,q}.
2306  if (PatchedName.startswith("vpcmp") &&
2307  (PatchedName.endswith("b") || PatchedName.endswith("w") ||
2308  PatchedName.endswith("d") || PatchedName.endswith("q"))) {
2309  unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1;
2310  unsigned ComparisonCode = StringSwitch<unsigned>(
2311  PatchedName.slice(5, PatchedName.size() - CCIdx))
2312  .Case("eq", 0x0) // Only allowed on unsigned. Checked below.
2313  .Case("lt", 0x1)
2314  .Case("le", 0x2)
2315  //.Case("false", 0x3) // Not a documented alias.
2316  .Case("neq", 0x4)
2317  .Case("nlt", 0x5)
2318  .Case("nle", 0x6)
2319  //.Case("true", 0x7) // Not a documented alias.
2320  .Default(~0U);
2321  if (ComparisonCode != ~0U && (ComparisonCode != 0 || CCIdx == 2)) {
2322  Operands.push_back(X86Operand::CreateToken("vpcmp", NameLoc));
2323 
2324  const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2325  getParser().getContext());
2326  Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2327 
2328  PatchedName = PatchedName.substr(PatchedName.size() - CCIdx);
2329  }
2330  }
2331 
2332  // FIXME: Hack to recognize vpcom<comparison code>{ub,uw,ud,uq,b,w,d,q}.
2333  if (PatchedName.startswith("vpcom") &&
2334  (PatchedName.endswith("b") || PatchedName.endswith("w") ||
2335  PatchedName.endswith("d") || PatchedName.endswith("q"))) {
2336  unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1;
2337  unsigned ComparisonCode = StringSwitch<unsigned>(
2338  PatchedName.slice(5, PatchedName.size() - CCIdx))
2339  .Case("lt", 0x0)
2340  .Case("le", 0x1)
2341  .Case("gt", 0x2)
2342  .Case("ge", 0x3)
2343  .Case("eq", 0x4)
2344  .Case("neq", 0x5)
2345  .Case("false", 0x6)
2346  .Case("true", 0x7)
2347  .Default(~0U);
2348  if (ComparisonCode != ~0U) {
2349  Operands.push_back(X86Operand::CreateToken("vpcom", NameLoc));
2350 
2351  const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2352  getParser().getContext());
2353  Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2354 
2355  PatchedName = PatchedName.substr(PatchedName.size() - CCIdx);
2356  }
2357  }
2358 
2359 
2360  // Determine whether this is an instruction prefix.
2361  // FIXME:
2362  // Enhance prefixes integrity robustness. for example, following forms
2363  // are currently tolerated:
2364  // repz repnz <insn> ; GAS errors for the use of two similar prefixes
2365  // lock addq %rax, %rbx ; Destination operand must be of memory type
2366  // xacquire <insn> ; xacquire must be accompanied by 'lock'
2368  .Cases("rex64", "data32", "data16", true)
2369  .Cases("xacquire", "xrelease", true)
2370  .Cases("acquire", "release", isParsingIntelSyntax())
2371  .Default(false);
2372 
2373  auto isLockRepeatNtPrefix = [](StringRef N) {
2374  return StringSwitch<bool>(N)
2375  .Cases("lock", "rep", "repe", "repz", "repne", "repnz", "notrack", true)
2376  .Default(false);
2377  };
2378 
2379  bool CurlyAsEndOfStatement = false;
2380 
2381  unsigned Flags = X86::IP_NO_PREFIX;
2382  while (isLockRepeatNtPrefix(Name.lower())) {
2383  unsigned Prefix =
2385  .Cases("lock", "lock", X86::IP_HAS_LOCK)
2386  .Cases("rep", "repe", "repz", X86::IP_HAS_REPEAT)
2387  .Cases("repne", "repnz", X86::IP_HAS_REPEAT_NE)
2388  .Cases("notrack", "notrack", X86::IP_HAS_NOTRACK)
2389  .Default(X86::IP_NO_PREFIX); // Invalid prefix (impossible)
2390  Flags |= Prefix;
2391  if (getLexer().is(AsmToken::EndOfStatement)) {
2392  // We don't have real instr with the given prefix
2393  // let's use the prefix as the instr.
2394  // TODO: there could be several prefixes one after another
2395  Flags = X86::IP_NO_PREFIX;
2396  break;
2397  }
2398  Name = Parser.getTok().getString();
2399  Parser.Lex(); // eat the prefix
2400  // Hack: we could have something like "rep # some comment" or
2401  // "lock; cmpxchg16b $1" or "lock\0A\09incl" or "lock/incl"
2402  while (Name.startswith(";") || Name.startswith("\n") ||
2403  Name.startswith("#") || Name.startswith("\t") ||
2404  Name.startswith("/")) {
2405  Name = Parser.getTok().getString();
2406  Parser.Lex(); // go to next prefix or instr
2407  }
2408  }
2409 
2410  if (Flags)
2411  PatchedName = Name;
2412 
2413  // Hacks to handle 'data16' and 'data32'
2414  if (PatchedName == "data16" && is16BitMode()) {
2415  return Error(NameLoc, "redundant data16 prefix");
2416  }
2417  if (PatchedName == "data32") {
2418  if (is32BitMode())
2419  return Error(NameLoc, "redundant data32 prefix");
2420  if (is64BitMode())
2421  return Error(NameLoc, "'data32' is not supported in 64-bit mode");
2422  // Hack to 'data16' for the table lookup.
2423  PatchedName = "data16";
2424  }
2425 
2426  Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
2427 
2428  // This does the actual operand parsing. Don't parse any more if we have a
2429  // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we
2430  // just want to parse the "lock" as the first instruction and the "incl" as
2431  // the next one.
2432  if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) {
2433  // Parse '*' modifier.
2434  if (getLexer().is(AsmToken::Star))
2435  Operands.push_back(X86Operand::CreateToken("*", consumeToken()));
2436 
2437  // Read the operands.
2438  while(1) {
2439  if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
2440  Operands.push_back(std::move(Op));
2441  if (HandleAVX512Operand(Operands, *Operands.back()))
2442  return true;
2443  } else {
2444  return true;
2445  }
2446  // check for comma and eat it
2447  if (getLexer().is(AsmToken::Comma))
2448  Parser.Lex();
2449  else
2450  break;
2451  }
2452 
2453  // In MS inline asm curly braces mark the beginning/end of a block,
2454  // therefore they should be interepreted as end of statement
2455  CurlyAsEndOfStatement =
2456  isParsingIntelSyntax() && isParsingInlineAsm() &&
2457  (getLexer().is(AsmToken::LCurly) || getLexer().is(AsmToken::RCurly));
2458  if (getLexer().isNot(AsmToken::EndOfStatement) && !CurlyAsEndOfStatement)
2459  return TokError("unexpected token in argument list");
2460  }
2461 
2462  // Consume the EndOfStatement or the prefix separator Slash
2463  if (getLexer().is(AsmToken::EndOfStatement) ||
2464  (isPrefix && getLexer().is(AsmToken::Slash)))
2465  Parser.Lex();
2466  else if (CurlyAsEndOfStatement)
2467  // Add an actual EndOfStatement before the curly brace
2468  Info.AsmRewrites->emplace_back(AOK_EndOfStatement,
2469  getLexer().getTok().getLoc(), 0);
2470 
2471  // This is for gas compatibility and cannot be done in td.
2472  // Adding "p" for some floating point with no argument.
2473  // For example: fsub --> fsubp
2474  bool IsFp =
2475  Name == "fsub" || Name == "fdiv" || Name == "fsubr" || Name == "fdivr";
2476  if (IsFp && Operands.size() == 1) {
2477  const char *Repl = StringSwitch<const char *>(Name)
2478  .Case("fsub", "fsubp")
2479  .Case("fdiv", "fdivp")
2480  .Case("fsubr", "fsubrp")
2481  .Case("fdivr", "fdivrp");
2482  static_cast<X86Operand &>(*Operands[0]).setTokenValue(Repl);
2483  }
2484 
2485  // Moving a 32 or 16 bit value into a segment register has the same
2486  // behavior. Modify such instructions to always take shorter form.
2487  if ((Name == "mov" || Name == "movw" || Name == "movl") &&
2488  (Operands.size() == 3)) {
2489  X86Operand &Op1 = (X86Operand &)*Operands[1];
2490  X86Operand &Op2 = (X86Operand &)*Operands[2];
2491  SMLoc Loc = Op1.getEndLoc();
2492  if (Op1.isReg() && Op2.isReg() &&
2493  X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(
2494  Op2.getReg()) &&
2495  (X86MCRegisterClasses[X86::GR16RegClassID].contains(Op1.getReg()) ||
2496  X86MCRegisterClasses[X86::GR32RegClassID].contains(Op1.getReg()))) {
2497  // Change instruction name to match new instruction.
2498  if (Name != "mov" && Name[3] == (is16BitMode() ? 'l' : 'w')) {
2499  Name = is16BitMode() ? "movw" : "movl";
2500  Operands[0] = X86Operand::CreateToken(Name, NameLoc);
2501  }
2502  // Select the correct equivalent 16-/32-bit source register.
2503  unsigned Reg =
2504  getX86SubSuperRegisterOrZero(Op1.getReg(), is16BitMode() ? 16 : 32);
2505  Operands[1] = X86Operand::CreateReg(Reg, Loc, Loc);
2506  }
2507  }
2508 
2509  // This is a terrible hack to handle "out[s]?[bwl]? %al, (%dx)" ->
2510  // "outb %al, %dx". Out doesn't take a memory form, but this is a widely
2511  // documented form in various unofficial manuals, so a lot of code uses it.
2512  if ((Name == "outb" || Name == "outsb" || Name == "outw" || Name == "outsw" ||
2513  Name == "outl" || Name == "outsl" || Name == "out" || Name == "outs") &&
2514  Operands.size() == 3) {
2515  X86Operand &Op = (X86Operand &)*Operands.back();
2516  if (Op.isMem() && Op.Mem.SegReg == 0 &&
2517  isa<MCConstantExpr>(Op.Mem.Disp) &&
2518  cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
2519  Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
2520  SMLoc Loc = Op.getEndLoc();
2521  Operands.back() = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
2522  }
2523  }
2524  // Same hack for "in[s]?[bwl]? (%dx), %al" -> "inb %dx, %al".
2525  if ((Name == "inb" || Name == "insb" || Name == "inw" || Name == "insw" ||
2526  Name == "inl" || Name == "insl" || Name == "in" || Name == "ins") &&
2527  Operands.size() == 3) {
2528  X86Operand &Op = (X86Operand &)*Operands[1];
2529  if (Op.isMem() && Op.Mem.SegReg == 0 &&
2530  isa<MCConstantExpr>(Op.Mem.Disp) &&
2531  cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
2532  Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
2533  SMLoc Loc = Op.getEndLoc();
2534  Operands[1] = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
2535  }
2536  }
2537 
2539  bool HadVerifyError = false;
2540 
2541  // Append default arguments to "ins[bwld]"
2542  if (Name.startswith("ins") &&
2543  (Operands.size() == 1 || Operands.size() == 3) &&
2544  (Name == "insb" || Name == "insw" || Name == "insl" || Name == "insd" ||
2545  Name == "ins")) {
2546 
2547  AddDefaultSrcDestOperands(TmpOperands,
2548  X86Operand::CreateReg(X86::DX, NameLoc, NameLoc),
2549  DefaultMemDIOperand(NameLoc));
2550  HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2551  }
2552 
2553  // Append default arguments to "outs[bwld]"
2554  if (Name.startswith("outs") &&
2555  (Operands.size() == 1 || Operands.size() == 3) &&
2556  (Name == "outsb" || Name == "outsw" || Name == "outsl" ||
2557  Name == "outsd" || Name == "outs")) {
2558  AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
2559  X86Operand::CreateReg(X86::DX, NameLoc, NameLoc));
2560  HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2561  }
2562 
2563  // Transform "lods[bwlq]" into "lods[bwlq] ($SIREG)" for appropriate
2564  // values of $SIREG according to the mode. It would be nice if this
2565  // could be achieved with InstAlias in the tables.
2566  if (Name.startswith("lods") &&
2567  (Operands.size() == 1 || Operands.size() == 2) &&
2568  (Name == "lods" || Name == "lodsb" || Name == "lodsw" ||
2569  Name == "lodsl" || Name == "lodsd" || Name == "lodsq")) {
2570  TmpOperands.push_back(DefaultMemSIOperand(NameLoc));
2571  HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2572  }
2573 
2574  // Transform "stos[bwlq]" into "stos[bwlq] ($DIREG)" for appropriate
2575  // values of $DIREG according to the mode. It would be nice if this
2576  // could be achieved with InstAlias in the tables.
2577  if (Name.startswith("stos") &&
2578  (Operands.size() == 1 || Operands.size() == 2) &&
2579  (Name == "stos" || Name == "stosb" || Name == "stosw" ||
2580  Name == "stosl" || Name == "stosd" || Name == "stosq")) {
2581  TmpOperands.push_back(DefaultMemDIOperand(NameLoc));
2582  HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2583  }
2584 
2585  // Transform "scas[bwlq]" into "scas[bwlq] ($DIREG)" for appropriate
2586  // values of $DIREG according to the mode. It would be nice if this
2587  // could be achieved with InstAlias in the tables.
2588  if (Name.startswith("scas") &&
2589  (Operands.size() == 1 || Operands.size() == 2) &&
2590  (Name == "scas" || Name == "scasb" || Name == "scasw" ||
2591  Name == "scasl" || Name == "scasd" || Name == "scasq")) {
2592  TmpOperands.push_back(DefaultMemDIOperand(NameLoc));
2593  HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2594  }
2595 
2596  // Add default SI and DI operands to "cmps[bwlq]".
2597  if (Name.startswith("cmps") &&
2598  (Operands.size() == 1 || Operands.size() == 3) &&
2599  (Name == "cmps" || Name == "cmpsb" || Name == "cmpsw" ||
2600  Name == "cmpsl" || Name == "cmpsd" || Name == "cmpsq")) {
2601  AddDefaultSrcDestOperands(TmpOperands, DefaultMemDIOperand(NameLoc),
2602  DefaultMemSIOperand(NameLoc));
2603  HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2604  }
2605 
2606  // Add default SI and DI operands to "movs[bwlq]".
2607  if (((Name.startswith("movs") &&
2608  (Name == "movs" || Name == "movsb" || Name == "movsw" ||
2609  Name == "movsl" || Name == "movsd" || Name == "movsq")) ||
2610  (Name.startswith("smov") &&
2611  (Name == "smov" || Name == "smovb" || Name == "smovw" ||
2612  Name == "smovl" || Name == "smovd" || Name == "smovq"))) &&
2613  (Operands.size() == 1 || Operands.size() == 3)) {
2614  if (Name == "movsd" && Operands.size() == 1 && !isParsingIntelSyntax())
2615  Operands.back() = X86Operand::CreateToken("movsl", NameLoc);
2616  AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
2617  DefaultMemDIOperand(NameLoc));
2618  HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2619  }
2620 
2621  // Check if we encountered an error for one the string insturctions
2622  if (HadVerifyError) {
2623  return HadVerifyError;
2624  }
2625 
2626  // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>. Canonicalize to
2627  // "shift <op>".
2628  if ((Name.startswith("shr") || Name.startswith("sar") ||
2629  Name.startswith("shl") || Name.startswith("sal") ||
2630  Name.startswith("rcl") || Name.startswith("rcr") ||
2631  Name.startswith("rol") || Name.startswith("ror")) &&
2632  Operands.size() == 3) {
2633  if (isParsingIntelSyntax()) {
2634  // Intel syntax
2635  X86Operand &Op1 = static_cast<X86Operand &>(*Operands[2]);
2636  if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2637  cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2638  Operands.pop_back();
2639  } else {
2640  X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2641  if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2642  cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2643  Operands.erase(Operands.begin() + 1);
2644  }
2645  }
2646 
2647  // Transforms "int $3" into "int3" as a size optimization. We can't write an
2648  // instalias with an immediate operand yet.
2649  if (Name == "int" && Operands.size() == 2) {
2650  X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2651  if (Op1.isImm())
2652  if (auto *CE = dyn_cast<MCConstantExpr>(Op1.getImm()))
2653  if (CE->getValue() == 3) {
2654  Operands.erase(Operands.begin() + 1);
2655  static_cast<X86Operand &>(*Operands[0]).setTokenValue("int3");
2656  }
2657  }
2658 
2659  // Transforms "xlat mem8" into "xlatb"
2660  if ((Name == "xlat" || Name == "xlatb") && Operands.size() == 2) {
2661  X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2662  if (Op1.isMem8()) {
2663  Warning(Op1.getStartLoc(), "memory operand is only for determining the "
2664  "size, (R|E)BX will be used for the location");
2665  Operands.pop_back();
2666  static_cast<X86Operand &>(*Operands[0]).setTokenValue("xlatb");
2667  }
2668  }
2669 
2670  if (Flags)
2671  Operands.push_back(X86Operand::CreatePrefix(Flags, NameLoc, NameLoc));
2672  return false;
2673 }
2674 
2675 bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) {
2676  return false;
2677 }
2678 
2679 bool X86AsmParser::validateInstruction(MCInst &Inst, const OperandVector &Ops) {
2680  const MCRegisterInfo *MRI = getContext().getRegisterInfo();
2681 
2682  switch (Inst.getOpcode()) {
2683  case X86::VGATHERDPDYrm:
2684  case X86::VGATHERDPDrm:
2685  case X86::VGATHERDPSYrm:
2686  case X86::VGATHERDPSrm:
2687  case X86::VGATHERQPDYrm:
2688  case X86::VGATHERQPDrm:
2689  case X86::VGATHERQPSYrm:
2690  case X86::VGATHERQPSrm:
2691  case X86::VPGATHERDDYrm:
2692  case X86::VPGATHERDDrm:
2693  case X86::VPGATHERDQYrm:
2694  case X86::VPGATHERDQrm:
2695  case X86::VPGATHERQDYrm:
2696  case X86::VPGATHERQDrm:
2697  case X86::VPGATHERQQYrm:
2698  case X86::VPGATHERQQrm: {
2699  unsigned Dest = MRI->getEncodingValue(Inst.getOperand(0).getReg());
2700  unsigned Mask = MRI->getEncodingValue(Inst.getOperand(1).getReg());
2701  unsigned Index =
2703  if (Dest == Mask || Dest == Index || Mask == Index)
2704  return Warning(Ops[0]->getStartLoc(), "mask, index, and destination "
2705  "registers should be distinct");
2706  break;
2707  }
2708  case X86::VGATHERDPDZ128rm:
2709  case X86::VGATHERDPDZ256rm:
2710  case X86::VGATHERDPDZrm:
2711  case X86::VGATHERDPSZ128rm:
2712  case X86::VGATHERDPSZ256rm:
2713  case X86::VGATHERDPSZrm:
2714  case X86::VGATHERQPDZ128rm:
2715  case X86::VGATHERQPDZ256rm:
2716  case X86::VGATHERQPDZrm:
2717  case X86::VGATHERQPSZ128rm:
2718  case X86::VGATHERQPSZ256rm:
2719  case X86::VGATHERQPSZrm:
2720  case X86::VPGATHERDDZ128rm:
2721  case X86::VPGATHERDDZ256rm:
2722  case X86::VPGATHERDDZrm:
2723  case X86::VPGATHERDQZ128rm:
2724  case X86::VPGATHERDQZ256rm:
2725  case X86::VPGATHERDQZrm:
2726  case X86::VPGATHERQDZ128rm:
2727  case X86::VPGATHERQDZ256rm:
2728  case X86::VPGATHERQDZrm:
2729  case X86::VPGATHERQQZ128rm:
2730  case X86::VPGATHERQQZ256rm:
2731  case X86::VPGATHERQQZrm: {
2732  unsigned Dest = MRI->getEncodingValue(Inst.getOperand(0).getReg());
2733  unsigned Index =
2735  if (Dest == Index)
2736  return Warning(Ops[0]->getStartLoc(), "index and destination registers "
2737  "should be distinct");
2738  break;
2739  }
2740  case X86::V4FMADDPSrm:
2741  case X86::V4FMADDPSrmk:
2742  case X86::V4FMADDPSrmkz:
2743  case X86::V4FMADDSSrm:
2744  case X86::V4FMADDSSrmk:
2745  case X86::V4FMADDSSrmkz:
2746  case X86::V4FNMADDPSrm:
2747  case X86::V4FNMADDPSrmk:
2748  case X86::V4FNMADDPSrmkz:
2749  case X86::V4FNMADDSSrm:
2750  case X86::V4FNMADDSSrmk:
2751  case X86::V4FNMADDSSrmkz:
2752  case X86::VP4DPWSSDSrm:
2753  case X86::VP4DPWSSDSrmk:
2754  case X86::VP4DPWSSDSrmkz:
2755  case X86::VP4DPWSSDrm:
2756  case X86::VP4DPWSSDrmk:
2757  case X86::VP4DPWSSDrmkz: {
2758  unsigned Src2 = Inst.getOperand(Inst.getNumOperands() -
2760  unsigned Src2Enc = MRI->getEncodingValue(Src2);
2761  if (Src2Enc % 4 != 0) {
2763  unsigned GroupStart = (Src2Enc / 4) * 4;
2764  unsigned GroupEnd = GroupStart + 3;
2765  return Warning(Ops[0]->getStartLoc(),
2766  "source register '" + RegName + "' implicitly denotes '" +
2767  RegName.take_front(3) + Twine(GroupStart) + "' to '" +
2768  RegName.take_front(3) + Twine(GroupEnd) +
2769  "' source group");
2770  }
2771  break;
2772  }
2773  }
2774 
2775  return false;
2776 }
2777 
2778 static const char *getSubtargetFeatureName(uint64_t Val);
2779 
2780 void X86AsmParser::EmitInstruction(MCInst &Inst, OperandVector &Operands,
2781  MCStreamer &Out) {
2782  Instrumentation->InstrumentAndEmitInstruction(
2783  Inst, Operands, getContext(), MII, Out,
2784  getParser().shouldPrintSchedInfo());
2785 }
2786 
2787 bool X86AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2788  OperandVector &Operands,
2789  MCStreamer &Out, uint64_t &ErrorInfo,
2790  bool MatchingInlineAsm) {
2791  if (isParsingIntelSyntax())
2792  return MatchAndEmitIntelInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2793  MatchingInlineAsm);
2794  return MatchAndEmitATTInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2795  MatchingInlineAsm);
2796 }
2797 
2798 void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op,
2799  OperandVector &Operands, MCStreamer &Out,
2800  bool MatchingInlineAsm) {
2801  // FIXME: This should be replaced with a real .td file alias mechanism.
2802  // Also, MatchInstructionImpl should actually *do* the EmitInstruction
2803  // call.
2804  const char *Repl = StringSwitch<const char *>(Op.getToken())
2805  .Case("finit", "fninit")
2806  .Case("fsave", "fnsave")
2807  .Case("fstcw", "fnstcw")
2808  .Case("fstcww", "fnstcw")
2809  .Case("fstenv", "fnstenv")
2810  .Case("fstsw", "fnstsw")
2811  .Case("fstsww", "fnstsw")
2812  .Case("fclex", "fnclex")
2813  .Default(nullptr);
2814  if (Repl) {
2815  MCInst Inst;
2816  Inst.setOpcode(X86::WAIT);
2817  Inst.setLoc(IDLoc);
2818  if (!MatchingInlineAsm)
2819  EmitInstruction(Inst, Operands, Out);
2820  Operands[0] = X86Operand::CreateToken(Repl, IDLoc);
2821  }
2822 }
2823 
2824 bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
2825  bool MatchingInlineAsm) {
2826  assert(ErrorInfo && "Unknown missing feature!");
2827  SmallString<126> Msg;
2828  raw_svector_ostream OS(Msg);
2829  OS << "instruction requires:";
2830  uint64_t Mask = 1;
2831  for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
2832  if (ErrorInfo & Mask)
2833  OS << ' ' << getSubtargetFeatureName(ErrorInfo & Mask);
2834  Mask <<= 1;
2835  }
2836  return Error(IDLoc, OS.str(), SMRange(), MatchingInlineAsm);
2837 }
2838 
2839 static unsigned getPrefixes(OperandVector &Operands) {
2840  unsigned Result = 0;
2841  X86Operand &Prefix = static_cast<X86Operand &>(*Operands.back());
2842  if (Prefix.isPrefix()) {
2843  Result = Prefix.getPrefix();
2844  Operands.pop_back();
2845  }
2846  return Result;
2847 }
2848 
2849 bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
2850  OperandVector &Operands,
2851  MCStreamer &Out,
2852  uint64_t &ErrorInfo,
2853  bool MatchingInlineAsm) {
2854  assert(!Operands.empty() && "Unexpect empty operand list!");
2855  X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2856  assert(Op.isToken() && "Leading operand should always be a mnemonic!");
2857  SMRange EmptyRange = None;
2858 
2859  // First, handle aliases that expand to multiple instructions.
2860  MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2861 
2862  bool WasOriginallyInvalidOperand = false;
2863  unsigned Prefixes = getPrefixes(Operands);
2864 
2865  MCInst Inst;
2866 
2867  if (Prefixes)
2868  Inst.setFlags(Prefixes);
2869 
2870  // First, try a direct match.
2871  switch (MatchInstruction(Operands, Inst, ErrorInfo, MatchingInlineAsm,
2872  isParsingIntelSyntax())) {
2873  default: llvm_unreachable("Unexpected match result!");
2874  case Match_Success:
2875  if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
2876  return true;
2877  // Some instructions need post-processing to, for example, tweak which
2878  // encoding is selected. Loop on it while changes happen so the
2879  // individual transformations can chain off each other.
2880  if (!MatchingInlineAsm)
2881  while (processInstruction(Inst, Operands))
2882  ;
2883 
2884  Inst.setLoc(IDLoc);
2885  if (!MatchingInlineAsm)
2886  EmitInstruction(Inst, Operands, Out);
2887  Opcode = Inst.getOpcode();
2888  return false;
2889  case Match_MissingFeature:
2890  return ErrorMissingFeature(IDLoc, ErrorInfo, MatchingInlineAsm);
2891  case Match_InvalidOperand:
2892  WasOriginallyInvalidOperand = true;
2893  break;
2894  case Match_MnemonicFail:
2895  break;
2896  }
2897 
2898  // FIXME: Ideally, we would only attempt suffix matches for things which are
2899  // valid prefixes, and we could just infer the right unambiguous
2900  // type. However, that requires substantially more matcher support than the
2901  // following hack.
2902 
2903  // Change the operand to point to a temporary token.
2904  StringRef Base = Op.getToken();
2905  SmallString<16> Tmp;
2906  Tmp += Base;
2907  Tmp += ' ';
2908  Op.setTokenValue(Tmp);
2909 
2910  // If this instruction starts with an 'f', then it is a floating point stack
2911  // instruction. These come in up to three forms for 32-bit, 64-bit, and
2912  // 80-bit floating point, which use the suffixes s,l,t respectively.
2913  //
2914  // Otherwise, we assume that this may be an integer instruction, which comes
2915  // in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively.
2916  const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0";
2917 
2918  // Check for the various suffix matches.
2919  uint64_t ErrorInfoIgnore;
2920  uint64_t ErrorInfoMissingFeature = 0; // Init suppresses compiler warnings.
2921  unsigned Match[4];
2922 
2923  for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I) {
2924  Tmp.back() = Suffixes[I];
2925  Match[I] = MatchInstruction(Operands, Inst, ErrorInfoIgnore,
2926  MatchingInlineAsm, isParsingIntelSyntax());
2927  // If this returned as a missing feature failure, remember that.
2928  if (Match[I] == Match_MissingFeature)
2929  ErrorInfoMissingFeature = ErrorInfoIgnore;
2930  }
2931 
2932  // Restore the old token.
2933  Op.setTokenValue(Base);
2934 
2935  // If exactly one matched, then we treat that as a successful match (and the
2936  // instruction will already have been filled in correctly, since the failing
2937  // matches won't have modified it).
2938  unsigned NumSuccessfulMatches =
2939  std::count(std::begin(Match), std::end(Match), Match_Success);
2940  if (NumSuccessfulMatches == 1) {
2941  Inst.setLoc(IDLoc);
2942  if (!MatchingInlineAsm)
2943  EmitInstruction(Inst, Operands, Out);
2944  Opcode = Inst.getOpcode();
2945  return false;
2946  }
2947 
2948  // Otherwise, the match failed, try to produce a decent error message.
2949 
2950  // If we had multiple suffix matches, then identify this as an ambiguous
2951  // match.
2952  if (NumSuccessfulMatches > 1) {
2953  char MatchChars[4];
2954  unsigned NumMatches = 0;
2955  for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I)
2956  if (Match[I] == Match_Success)
2957  MatchChars[NumMatches++] = Suffixes[I];
2958 
2959  SmallString<126> Msg;
2960  raw_svector_ostream OS(Msg);
2961  OS << "ambiguous instructions require an explicit suffix (could be ";
2962  for (unsigned i = 0; i != NumMatches; ++i) {
2963  if (i != 0)
2964  OS << ", ";
2965  if (i + 1 == NumMatches)
2966  OS << "or ";
2967  OS << "'" << Base << MatchChars[i] << "'";
2968  }
2969  OS << ")";
2970  Error(IDLoc, OS.str(), EmptyRange, MatchingInlineAsm);
2971  return true;
2972  }
2973 
2974  // Okay, we know that none of the variants matched successfully.
2975 
2976  // If all of the instructions reported an invalid mnemonic, then the original
2977  // mnemonic was invalid.
2978  if (std::count(std::begin(Match), std::end(Match), Match_MnemonicFail) == 4) {
2979  if (!WasOriginallyInvalidOperand) {
2980  return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'",
2981  Op.getLocRange(), MatchingInlineAsm);
2982  }
2983 
2984  // Recover location info for the operand if we know which was the problem.
2985  if (ErrorInfo != ~0ULL) {
2986  if (ErrorInfo >= Operands.size())
2987  return Error(IDLoc, "too few operands for instruction", EmptyRange,
2988  MatchingInlineAsm);
2989 
2990  X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo];
2991  if (Operand.getStartLoc().isValid()) {
2992  SMRange OperandRange = Operand.getLocRange();
2993  return Error(Operand.getStartLoc(), "invalid operand for instruction",
2994  OperandRange, MatchingInlineAsm);
2995  }
2996  }
2997 
2998  return Error(IDLoc, "invalid operand for instruction", EmptyRange,
2999  MatchingInlineAsm);
3000  }
3001 
3002  // If one instruction matched with a missing feature, report this as a
3003  // missing feature.
3004  if (std::count(std::begin(Match), std::end(Match),
3005  Match_MissingFeature) == 1) {
3006  ErrorInfo = ErrorInfoMissingFeature;
3007  return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
3008  MatchingInlineAsm);
3009  }
3010 
3011  // If one instruction matched with an invalid operand, report this as an
3012  // operand failure.
3013  if (std::count(std::begin(Match), std::end(Match),
3014  Match_InvalidOperand) == 1) {
3015  return Error(IDLoc, "invalid operand for instruction", EmptyRange,
3016  MatchingInlineAsm);
3017  }
3018 
3019  // If all of these were an outright failure, report it in a useless way.
3020  Error(IDLoc, "unknown use of instruction mnemonic without a size suffix",
3021  EmptyRange, MatchingInlineAsm);
3022  return true;
3023 }
3024 
3025 bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
3026  OperandVector &Operands,
3027  MCStreamer &Out,
3028  uint64_t &ErrorInfo,
3029  bool MatchingInlineAsm) {
3030  assert(!Operands.empty() && "Unexpect empty operand list!");
3031  X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
3032  assert(Op.isToken() && "Leading operand should always be a mnemonic!");
3033  StringRef Mnemonic = Op.getToken();
3034  SMRange EmptyRange = None;
3035  StringRef Base = Op.getToken();
3036  unsigned Prefixes = getPrefixes(Operands);
3037 
3038  // First, handle aliases that expand to multiple instructions.
3039  MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
3040 
3041  MCInst Inst;
3042 
3043  if (Prefixes)
3044  Inst.setFlags(Prefixes);
3045 
3046  // Find one unsized memory operand, if present.
3047  X86Operand *UnsizedMemOp = nullptr;
3048  for (const auto &Op : Operands) {
3049  X86Operand *X86Op = static_cast<X86Operand *>(Op.get());
3050  if (X86Op->isMemUnsized()) {
3051  UnsizedMemOp = X86Op;
3052  // Have we found an unqualified memory operand,
3053  // break. IA allows only one memory operand.
3054  break;
3055  }
3056  }
3057 
3058  // Allow some instructions to have implicitly pointer-sized operands. This is
3059  // compatible with gas.
3060  if (UnsizedMemOp) {
3061  static const char *const PtrSizedInstrs[] = {"call", "jmp", "push"};
3062  for (const char *Instr : PtrSizedInstrs) {
3063  if (Mnemonic == Instr) {
3064  UnsizedMemOp->Mem.Size = getPointerWidth();
3065  break;
3066  }
3067  }
3068  }
3069 
3071  uint64_t ErrorInfoMissingFeature = 0;
3072 
3073  // If unsized push has immediate operand we should default the default pointer
3074  // size for the size.
3075  if (Mnemonic == "push" && Operands.size() == 2) {
3076  auto *X86Op = static_cast<X86Operand *>(Operands[1].get());
3077  if (X86Op->isImm()) {
3078  // If it's not a constant fall through and let remainder take care of it.
3079  const auto *CE = dyn_cast<MCConstantExpr>(X86Op->getImm());
3080  unsigned Size = getPointerWidth();
3081  if (CE &&
3082  (isIntN(Size, CE->getValue()) || isUIntN(Size, CE->getValue()))) {
3083  SmallString<16> Tmp;
3084  Tmp += Base;
3085  Tmp += (is64BitMode())
3086  ? "q"
3087  : (is32BitMode()) ? "l" : (is16BitMode()) ? "w" : " ";
3088  Op.setTokenValue(Tmp);
3089  // Do match in ATT mode to allow explicit suffix usage.
3090  Match.push_back(MatchInstruction(Operands, Inst, ErrorInfo,
3091  MatchingInlineAsm,
3092  false /*isParsingIntelSyntax()*/));
3093  Op.setTokenValue(Base);
3094  }
3095  }
3096  }
3097 
3098  // If an unsized memory operand is present, try to match with each memory
3099  // operand size. In Intel assembly, the size is not part of the instruction
3100  // mnemonic.
3101  if (UnsizedMemOp && UnsizedMemOp->isMemUnsized()) {
3102  static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
3103  for (unsigned Size : MopSizes) {
3104  UnsizedMemOp->Mem.Size = Size;
3105  uint64_t ErrorInfoIgnore;
3106  unsigned LastOpcode = Inst.getOpcode();
3107  unsigned M = MatchInstruction(Operands, Inst, ErrorInfoIgnore,
3108  MatchingInlineAsm, isParsingIntelSyntax());
3109  if (Match.empty() || LastOpcode != Inst.getOpcode())
3110  Match.push_back(M);
3111 
3112  // If this returned as a missing feature failure, remember that.
3113  if (Match.back() == Match_MissingFeature)
3114  ErrorInfoMissingFeature = ErrorInfoIgnore;
3115  }
3116 
3117  // Restore the size of the unsized memory operand if we modified it.
3118  UnsizedMemOp->Mem.Size = 0;
3119  }
3120 
3121  // If we haven't matched anything yet, this is not a basic integer or FPU
3122  // operation. There shouldn't be any ambiguity in our mnemonic table, so try
3123  // matching with the unsized operand.
3124  if (Match.empty()) {
3125  Match.push_back(MatchInstruction(
3126  Operands, Inst, ErrorInfo, MatchingInlineAsm, isParsingIntelSyntax()));
3127  // If this returned as a missing feature failure, remember that.
3128  if (Match.back() == Match_MissingFeature)
3129  ErrorInfoMissingFeature = ErrorInfo;
3130  }
3131 
3132  // Restore the size of the unsized memory operand if we modified it.
3133  if (UnsizedMemOp)
3134  UnsizedMemOp->Mem.Size = 0;
3135 
3136  // If it's a bad mnemonic, all results will be the same.
3137  if (Match.back() == Match_MnemonicFail) {
3138  return Error(IDLoc, "invalid instruction mnemonic '" + Mnemonic + "'",
3139  Op.getLocRange(), MatchingInlineAsm);
3140  }
3141 
3142  unsigned NumSuccessfulMatches =
3143  std::count(std::begin(Match), std::end(Match), Match_Success);
3144 
3145  // If matching was ambiguous and we had size information from the frontend,
3146  // try again with that. This handles cases like "movxz eax, m8/m16".
3147  if (UnsizedMemOp && NumSuccessfulMatches > 1 &&
3148  UnsizedMemOp->getMemFrontendSize()) {
3149  UnsizedMemOp->Mem.Size = UnsizedMemOp->getMemFrontendSize();
3150  unsigned M = MatchInstruction(
3151  Operands, Inst, ErrorInfo, MatchingInlineAsm, isParsingIntelSyntax());
3152  if (M == Match_Success)
3153  NumSuccessfulMatches = 1;
3154 
3155  // Add a rewrite that encodes the size information we used from the
3156  // frontend.
3157  InstInfo->AsmRewrites->emplace_back(
3158  AOK_SizeDirective, UnsizedMemOp->getStartLoc(),
3159  /*Len=*/0, UnsizedMemOp->getMemFrontendSize());
3160  }
3161 
3162  // If exactly one matched, then we treat that as a successful match (and the
3163  // instruction will already have been filled in correctly, since the failing
3164  // matches won't have modified it).
3165  if (NumSuccessfulMatches == 1) {
3166  if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
3167  return true;
3168  // Some instructions need post-processing to, for example, tweak which
3169  // encoding is selected. Loop on it while changes happen so the individual
3170  // transformations can chain off each other.
3171  if (!MatchingInlineAsm)
3172  while (processInstruction(Inst, Operands))
3173  ;
3174  Inst.setLoc(IDLoc);
3175  if (!MatchingInlineAsm)
3176  EmitInstruction(Inst, Operands, Out);
3177  Opcode = Inst.getOpcode();
3178  return false;
3179  } else if (NumSuccessfulMatches > 1) {
3180  assert(UnsizedMemOp &&
3181  "multiple matches only possible with unsized memory operands");
3182  return Error(UnsizedMemOp->getStartLoc(),
3183  "ambiguous operand size for instruction '" + Mnemonic + "\'",
3184  UnsizedMemOp->getLocRange());
3185  }
3186 
3187  // If one instruction matched with a missing feature, report this as a
3188  // missing feature.
3189  if (std::count(std::begin(Match), std::end(Match),
3190  Match_MissingFeature) == 1) {
3191  ErrorInfo = ErrorInfoMissingFeature;
3192  return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
3193  MatchingInlineAsm);
3194  }
3195 
3196  // If one instruction matched with an invalid operand, report this as an
3197  // operand failure.
3198  if (std::count(std::begin(Match), std::end(Match),
3199  Match_InvalidOperand) == 1) {
3200  return Error(IDLoc, "invalid operand for instruction", EmptyRange,
3201  MatchingInlineAsm);
3202  }
3203 
3204  // If all of these were an outright failure, report it in a useless way.
3205  return Error(IDLoc, "unknown instruction mnemonic", EmptyRange,
3206  MatchingInlineAsm);
3207 }
3208 
3209 bool X86AsmParser::OmitRegisterFromClobberLists(unsigned RegNo) {
3210  return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo);
3211 }
3212 
3213 bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
3214  MCAsmParser &Parser = getParser();
3215  StringRef IDVal = DirectiveID.getIdentifier();
3216  if (IDVal == ".word")
3217  return ParseDirectiveWord(2, DirectiveID.getLoc());
3218  else if (IDVal.startswith(".code"))
3219  return ParseDirectiveCode(IDVal, DirectiveID.getLoc());
3220  else if (IDVal.startswith(".att_syntax")) {
3221  getParser().setParsingInlineAsm(false);
3222  if (getLexer().isNot(AsmToken::EndOfStatement)) {
3223  if (Parser.getTok().getString() == "prefix")
3224  Parser.Lex();
3225  else if (Parser.getTok().getString() == "noprefix")
3226  return Error(DirectiveID.getLoc(), "'.att_syntax noprefix' is not "
3227  "supported: registers must have a "
3228  "'%' prefix in .att_syntax");
3229  }
3230  getParser().setAssemblerDialect(0);
3231  return false;
3232  } else if (IDVal.startswith(".intel_syntax")) {
3233  getParser().setAssemblerDialect(1);
3234  getParser().setParsingInlineAsm(true);
3235  if (getLexer().isNot(AsmToken::EndOfStatement)) {
3236  if (Parser.getTok().getString() == "noprefix")
3237  Parser.Lex();
3238  else if (Parser.getTok().getString() == "prefix")
3239  return Error(DirectiveID.getLoc(), "'.intel_syntax prefix' is not "
3240  "supported: registers must not have "
3241  "a '%' prefix in .intel_syntax");
3242  }
3243  return false;
3244  } else if (IDVal == ".even")
3245  return parseDirectiveEven(DirectiveID.getLoc());
3246  else if (IDVal == ".cv_fpo_proc")
3247  return parseDirectiveFPOProc(DirectiveID.getLoc());
3248  else if (IDVal == ".cv_fpo_setframe")
3249  return parseDirectiveFPOSetFrame(DirectiveID.getLoc());
3250  else if (IDVal == ".cv_fpo_pushreg")
3251  return parseDirectiveFPOPushReg(DirectiveID.getLoc());
3252  else if (IDVal == ".cv_fpo_stackalloc")
3253  return parseDirectiveFPOStackAlloc(DirectiveID.getLoc());
3254  else if (IDVal == ".cv_fpo_endprologue")
3255  return parseDirectiveFPOEndPrologue(DirectiveID.getLoc());
3256  else if (IDVal == ".cv_fpo_endproc")
3257  return parseDirectiveFPOEndProc(DirectiveID.getLoc());
3258 
3259  return true;
3260 }
3261 
3262 /// parseDirectiveEven
3263 /// ::= .even
3264 bool X86AsmParser::parseDirectiveEven(SMLoc L) {
3265  if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive"))
3266  return false;
3267 
3268  const MCSection *Section = getStreamer().getCurrentSectionOnly();
3269  if (!Section) {
3270  getStreamer().InitSections(false);
3271  Section = getStreamer().getCurrentSectionOnly();
3272  }
3273  if (Section->UseCodeAlign())
3274  getStreamer().EmitCodeAlignment(2, 0);
3275  else
3276  getStreamer().EmitValueToAlignment(2, 0, 1, 0);
3277  return false;
3278 }
3279 /// ParseDirectiveWord
3280 /// ::= .word [ expression (, expression)* ]
3281 bool X86AsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
3282  auto parseOp = [&]() -> bool {
3283  const MCExpr *Value;
3284  SMLoc ExprLoc = getLexer().getLoc();
3285  if (getParser().parseExpression(Value))
3286  return true;
3287  if (const auto *MCE = dyn_cast<MCConstantExpr>(Value)) {
3288  assert(Size <= 8 && "Invalid size");
3289  uint64_t IntValue = MCE->getValue();
3290  if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))
3291  return Error(ExprLoc, "literal value out of range for directive");
3292  getStreamer().EmitIntValue(IntValue, Size);
3293  } else
3294  getStreamer().EmitValue(Value, Size, ExprLoc);
3295  return false;
3296  };
3297  parseMany(parseOp);
3298  return false;
3299 }
3300 
3301 /// ParseDirectiveCode
3302 /// ::= .code16 | .code32 | .code64
3303 bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
3304  MCAsmParser &Parser = getParser();
3305  Code16GCC = false;
3306  if (IDVal == ".code16") {
3307  Parser.Lex();
3308  if (!is16BitMode()) {
3309  SwitchMode(X86::Mode16Bit);
3310  getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
3311  }
3312  } else if (IDVal == ".code16gcc") {
3313  // .code16gcc parses as if in 32-bit mode, but emits code in 16-bit mode.
3314  Parser.Lex();
3315  Code16GCC = true;
3316  if (!is16BitMode()) {
3317  SwitchMode(X86::Mode16Bit);
3318  getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
3319  }
3320  } else if (IDVal == ".code32") {
3321  Parser.Lex();
3322  if (!is32BitMode()) {
3323  SwitchMode(X86::Mode32Bit);
3324  getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
3325  }
3326  } else if (IDVal == ".code64") {
3327  Parser.Lex();
3328  if (!is64BitMode()) {
3329  SwitchMode(X86::Mode64Bit);
3330  getParser().getStreamer().EmitAssemblerFlag(MCAF_Code64);
3331  }
3332  } else {
3333  Error(L, "unknown directive " + IDVal);
3334  return false;
3335  }
3336 
3337  return false;
3338 }
3339 
3340 // .cv_fpo_proc foo
3341 bool X86AsmParser::parseDirectiveFPOProc(SMLoc L) {
3342  MCAsmParser &Parser = getParser();
3343  StringRef ProcName;
3344  int64_t ParamsSize;
3345  if (Parser.parseIdentifier(ProcName))
3346  return Parser.TokError("expected symbol name");
3347  if (Parser.parseIntToken(ParamsSize, "expected parameter byte count"))
3348  return true;
3349  if (!isUIntN(32, ParamsSize))
3350  return Parser.TokError("parameters size out of range");
3351  if (Parser.parseEOL("unexpected tokens"))
3352  return addErrorSuffix(" in '.cv_fpo_proc' directive");
3353  MCSymbol *ProcSym = getContext().getOrCreateSymbol(ProcName);
3354  return getTargetStreamer().emitFPOProc(ProcSym, ParamsSize, L);
3355 }
3356 
3357 // .cv_fpo_setframe ebp
3358 bool X86AsmParser::parseDirectiveFPOSetFrame(SMLoc L) {
3359  MCAsmParser &Parser = getParser();
3360  unsigned Reg;
3361  SMLoc DummyLoc;
3362  if (ParseRegister(Reg, DummyLoc, DummyLoc) ||
3363  Parser.parseEOL("unexpected tokens"))
3364  return addErrorSuffix(" in '.cv_fpo_setframe' directive");
3365  return getTargetStreamer().emitFPOSetFrame(Reg, L);
3366 }
3367 
3368 // .cv_fpo_pushreg ebx
3369 bool X86AsmParser::parseDirectiveFPOPushReg(SMLoc L) {
3370  MCAsmParser &Parser = getParser();
3371  unsigned Reg;
3372  SMLoc DummyLoc;
3373  if (ParseRegister(Reg, DummyLoc, DummyLoc) ||
3374  Parser.parseEOL("unexpected tokens"))
3375  return addErrorSuffix(" in '.cv_fpo_pushreg' directive");
3376  return getTargetStreamer().emitFPOPushReg(Reg, L);
3377 }
3378 
3379 // .cv_fpo_stackalloc 20
3380 bool X86AsmParser::parseDirectiveFPOStackAlloc(SMLoc L) {
3381  MCAsmParser &Parser = getParser();
3382  int64_t Offset;
3383  if (Parser.parseIntToken(Offset, "expected offset") ||
3384  Parser.parseEOL("unexpected tokens"))
3385  return addErrorSuffix(" in '.cv_fpo_stackalloc' directive");
3386  return getTargetStreamer().emitFPOStackAlloc(Offset, L);
3387 }
3388 
3389 // .cv_fpo_endprologue
3390 bool X86AsmParser::parseDirectiveFPOEndPrologue(SMLoc L) {
3391  MCAsmParser &Parser = getParser();
3392  if (Parser.parseEOL("unexpected tokens"))
3393  return addErrorSuffix(" in '.cv_fpo_endprologue' directive");
3394  return getTargetStreamer().emitFPOEndPrologue(L);
3395 }
3396 
3397 // .cv_fpo_endproc
3398 bool X86AsmParser::parseDirectiveFPOEndProc(SMLoc L) {
3399  MCAsmParser &Parser = getParser();
3400  if (Parser.parseEOL("unexpected tokens"))
3401  return addErrorSuffix(" in '.cv_fpo_endproc' directive");
3402  return getTargetStreamer().emitFPOEndProc(L);
3403 }
3404 
3405 // Force static initialization.
3406 extern "C" void LLVMInitializeX86AsmParser() {
3409 }
3410 
3411 #define GET_REGISTER_MATCHER
3412 #define GET_MATCHER_IMPLEMENTATION
3413 #define GET_SUBTARGET_FEATURE_NAME
3414 #include "X86GenAsmMatcher.inc"
static const char * getSubtargetFeatureName(uint64_t Val)
Represents a range in source code.
Definition: SMLoc.h:49
Instances of this class represent a uniqued identifier for a section in the current translation unit...
Definition: MCSection.h:39
static bool checkScale(unsigned Scale, StringRef &ErrMsg)
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:250
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
Definition: MCAsmMacro.h:111
uint64_t getZExtValue() const
Get zero extended value.
Definition: APInt.h:1547
unsigned getMemFrontendSize() const
Definition: X86Operand.h:195
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
Definition: Path.cpp:241
bool isX86_64NonExtLowByteReg(unsigned reg)
Definition: X86BaseInfo.h:801
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:321
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:115
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
SMRange getLocRange() const
getLocRange - Get the range between the first and last token of this operand.
Definition: X86Operand.h:94
SmallVectorImpl< AsmRewrite > * AsmRewrites
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:42
LLVM_NODISCARD bool equals_lower(StringRef RHS) const
equals_lower - Check for string equality, ignoring case.
Definition: StringRef.h:176
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
Definition: SmallVector.h:137
Generic assembler parser interface, for use by target specific assembly parsers.
Definition: MCAsmParser.h:110
bool isKind(IdKind kind) const
Definition: MCAsmParser.h:66
MCTargetAsmParser - Generic interface to target specific assembly parsers.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
Definition: StringRef.h:138
Target specific streamer interface.
Definition: MCStreamer.h:83
unsigned Reg
bool isNot(TokenKind K) const
Definition: MCAsmMacro.h:84
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:504
const AsmToken & getTok() const
Get the current AsmToken from the stream.
Definition: MCAsmParser.cpp:34
static std::unique_ptr< X86Operand > CreateMem(unsigned ModeSize, const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc, unsigned Size=0, StringRef SymName=StringRef(), void *OpDecl=nullptr, unsigned FrontendSize=0)
Create an absolute memory operand.
Definition: X86Operand.h:558
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:128
bool parseIntToken(int64_t &V, const Twine &ErrMsg)
Definition: MCAsmParser.cpp:59
return AArch64::GPR64RegClass contains(Reg)
static ModuleSymbolTable::Symbol getSym(DataRefImpl &Symb)
StringRef getToken() const
Definition: X86Operand.h:146
amode Optimize addressing mode
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool endswith(StringRef Suffix) const
Check if this string ends with the given Suffix.
Definition: StringRef.h:279
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string...
Definition: MCAsmMacro.h:100
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
void LLVMInitializeX86AsmParser()
const FeatureBitset & getFeatureBits() const
unsigned getPrefix() const
Definition: X86Operand.h:161
bool isMemUnsized() const
Definition: X86Operand.h:279
SMLoc getEndLoc() const override
getEndLoc - Get the location of the last token of this operand.
Definition: X86Operand.h:90
LLVM_NODISCARD size_t count(char C) const
Return the number of occurrences of C in the string.
Definition: StringRef.h:476
bool isImm() const override
isImm - Is this an immediate operand?
Definition: X86Operand.h:202
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:42
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:36
virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc)=0
Target independent representation for an assembler token.
Definition: MCAsmMacro.h:22
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE R Default(T Value)
Definition: StringSwitch.h:203
bool isMem8() const
Definition: X86Operand.h:282
zlib-gnu style compression
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand...
static std::unique_ptr< X86Operand > CreateImm(const MCExpr *Val, SMLoc StartLoc, SMLoc EndLoc)
Definition: X86Operand.h:549
static bool startswith(StringRef Magic, const char(&S)[N])
Definition: Magic.cpp:30
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
unsigned getReg() const
Returns the register number.
Definition: MCInst.h:65
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:267
unsigned getReg() const override
Definition: X86Operand.h:156
RegisterMCAsmParser - Helper template for registering a target specific assembly parser, for use in the target machine initialization function.
.code16 (X86) / .code 16 (ARM)
Definition: MCDirectives.h:51
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:26
SMLoc getLoc() const
Definition: MCAsmLexer.cpp:28
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:598
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:459
LLVM_NODISCARD std::string upper() const
Convert the given ASCII string to uppercase.
Definition: StringRef.cpp:116
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:161
void clearPendingErrors()
Definition: MCAsmParser.h:217
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
auto count(R &&Range, const E &Element) -> typename std::iterator_traits< decltype(adl_begin(Range))>::difference_type
Wrapper function around std::count to count the number of times an element Element occurs in the give...
Definition: STLExtras.h:974
static const X86MCExpr * create(int64_t RegNo, MCContext &Ctx)
Definition: X86MCExpr.h:37
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
bool isPrefix() const
Definition: X86Operand.h:442
bool isX86_64ExtendedReg(unsigned RegNo)
isX86_64ExtendedReg - Is the MachineOperand a x86-64 extended (r8 or higher) register? e.g.
Definition: X86BaseInfo.h:767
FeatureBitset ToggleFeature(uint64_t FB)
Toggle a feature and return the re-computed feature bits.
const char * getPointer() const
Definition: SMLoc.h:35
virtual MCContext & getContext()=0
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:43
Streaming machine code generation interface.
Definition: MCStreamer.h:183
unsigned const MachineRegisterInfo * MRI
X86Operand - Instances of this class represent a parsed X86 machine instruction.
Definition: X86Operand.h:32
MCTargetStreamer * getTargetStreamer()
Definition: MCStreamer.h:257
Container class for subtarget features.
SMLoc getEndLoc() const
Definition: MCAsmLexer.cpp:32
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
Definition: SmallVector.h:117
bool parseAssignmentExpression(StringRef Name, bool allow_redef, MCAsmParser &Parser, MCSymbol *&Symbol, const MCExpr *&Value, bool AllowExtendedExpr=false)
Parse a value expression and return whether it can be assigned to a symbol with the given name...
Definition: AsmParser.cpp:5811
static bool CheckBaseRegAndIndexRegAndScale(unsigned BaseReg, unsigned IndexReg, unsigned Scale, StringRef &ErrMsg)
}
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:24
const MCExpr * getImm() const
Definition: X86Operand.h:166
static const unsigned End
int64_t getIntVal() const
Definition: MCAsmMacro.h:116
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE int compare(StringRef RHS) const
compare - Compare two strings; the result is -1, 0, or 1 if this string is lexicographically less tha...
Definition: StringRef.h:184
unsigned getNumOperands() const
Definition: MCInst.h:184
bool Error(SMLoc L, const Twine &Msg, SMRange Range=None)
Return an error at the location L, with the message Msg.
Definition: MCAsmParser.cpp:88
static const char * getRegisterName(unsigned RegNo)
virtual bool UseCodeAlign() const =0
Return true if a .align directive should use "optimized nops" to fill instead of 0s.
bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
Definition: MathExtras.h:390
iterator erase(const_iterator CI)
Definition: SmallVector.h:446
LLVM_NODISCARD char back() const
back - Get the last character in the string.
Definition: StringRef.h:149
void setLoc(SMLoc loc)
Definition: MCInst.h:179
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
SMLoc getStartLoc() const override
getStartLoc - Get the location of the first token of this operand.
Definition: X86Operand.h:87
unsigned getX86SubSuperRegisterOrZero(unsigned, unsigned, bool High=false)
Returns the sub or super register of a specific X86 register.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef drop_back(size_t N=1) const
Return a StringRef equal to &#39;this&#39; but with the last N elements dropped.
Definition: StringRef.h:654
std::enable_if< std::numeric_limits< T >::is_signed, bool >::type getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
Definition: StringRef.h:497
X86AsmInstrumentation * CreateX86AsmInstrumentation(const MCTargetOptions &MCOptions, const MCContext &Ctx, const MCSubtargetInfo *&STI)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef drop_front(size_t N=1) const
Return a StringRef equal to &#39;this&#39; but with the first N elements dropped.
Definition: StringRef.h:645
void setFlags(unsigned F)
Definition: MCInst.h:176
MCStreamer & getStreamer()
Definition: MCStreamer.h:91
void setOpcode(unsigned Op)
Definition: MCInst.h:173
bool isUndefined(bool SetUsed=true) const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
Definition: MCSymbol.h:257
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:861
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:182
LLVM_NODISCARD std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition: StringRef.h:727
constexpr size_t array_lengthof(T(&)[N])
Find the length of an array.
Definition: STLExtras.h:787
struct MemOp Mem
Definition: X86Operand.h:76
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
Definition: StringRef.h:710
LLVM_NODISCARD T pop_back_val()
Definition: SmallVector.h:382
StringRef str()
Return a StringRef for the vector contents.
Definition: raw_ostream.h:529
X86 target streamer implementing x86-only assembly directives.
static bool isPrefix(const IndicesVector &Prefix, const IndicesVector &Longer)
Returns true if Prefix is a prefix of longer.
AddrNumOperands - Total number of operands in a memory reference.
Definition: X86BaseInfo.h:42
bool is(TokenKind K) const
Definition: MCAsmMacro.h:83
Class for arbitrary precision integers.
Definition: APInt.h:69
bool isValid() const
Definition: SMLoc.h:30
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
Base class for user error types.
Definition: Error.h:331
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:70
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool equals(StringRef RHS) const
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
Definition: StringRef.h:169
static std::unique_ptr< X86Operand > CreateToken(StringRef Str, SMLoc Loc)
Definition: X86Operand.h:521
VariableIdentifier Var
Definition: MCAsmParser.h:64
.code32 (X86) / .code 32 (ARM)
Definition: MCDirectives.h:52
static SMLoc getFromPointer(const char *Ptr)
Definition: SMLoc.h:37
static std::unique_ptr< X86Operand > CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc, bool AddressOf=false, SMLoc OffsetOfLoc=SMLoc(), StringRef SymName=StringRef(), void *OpDecl=nullptr)
Definition: X86Operand.h:530
.code64 (X86)
Definition: MCDirectives.h:53
uint16_t getEncodingValue(unsigned RegNo) const
Returns the encoding for RegNo.
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:62
#define I(x, y, z)
Definition: MD5.cpp:58
#define N
static unsigned getPrefixes(OperandVector &Operands)
Generic base class for all target subtargets.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:323
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Cases(StringLiteral S0, StringLiteral S1, T Value)
Definition: StringSwitch.h:94
Target & getTheX86_32Target()
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:203
LLVM_NODISCARD std::string lower() const
Definition: StringRef.cpp:108
static std::unique_ptr< X86Operand > CreatePrefix(unsigned Prefixes, SMLoc StartLoc, SMLoc EndLoc)
Definition: X86Operand.h:543
MCTargetAsmParser & getTargetParser() const
Definition: MCAsmParser.h:159
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool TokError(const Twine &Msg, SMRange Range=None)
Report an error at the current lexer location.
Definition: MCAsmParser.cpp:84
LLVM Value Representation.
Definition: Value.h:73
constexpr char Size[]
Key for Kernel::Arg::Metadata::mSize.
static unsigned MatchRegisterName(StringRef Name)
Maps from the set of all register names to a register number.
bool parseEOL(const Twine &ErrMsg)
Definition: MCAsmParser.cpp:43
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E&#39;s largest value.
Definition: BitmaskEnum.h:81
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef take_front(size_t N=1) const
Return a StringRef equal to &#39;this&#39; but with only the first N elements remaining.
Definition: StringRef.h:608
bool isReg() const override
isReg - Is this a register operand?
Definition: X86Operand.h:443
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
const MCExpr * Disp
Definition: X86Operand.h:60
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents...
Represents a location in source code.
Definition: SMLoc.h:24
unsigned getOpcode() const
Definition: MCInst.h:174
bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
Definition: MathExtras.h:385
Target & getTheX86_64Target()
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx)
Definition: MCExpr.cpp:164
bool isMem() const override
isMem - Is this a memory operand?
Definition: X86Operand.h:278