LLVM  9.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(0), 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  // no explicit scale.
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 = 0;
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  // no explicit scale.
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 = 0;
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  // no explicit scale.
741  if (!BaseReg) {
742  BaseReg = TmpReg;
743  } else {
744  assert (!IndexReg && "BaseReg/IndexReg already set!");
745  IndexReg = TmpReg;
746  Scale = 0;
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, SMRange R = SMRange()) {
808  Error(Loc, Msg, R);
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,
839  const MCExpr *&Disp,
840  const SMLoc &StartLoc,
841  SMLoc &EndLoc);
842 
843  bool ParseIntelMemoryOperandSize(unsigned &Size);
844  std::unique_ptr<X86Operand>
845  CreateMemForInlineAsm(unsigned SegReg, const MCExpr *Disp, unsigned BaseReg,
846  unsigned IndexReg, unsigned Scale, SMLoc Start,
847  SMLoc End, unsigned Size, StringRef Identifier,
848  const InlineAsmIdentifierInfo &Info);
849 
850  bool parseDirectiveEven(SMLoc L);
851  bool ParseDirectiveCode(StringRef IDVal, SMLoc L);
852 
853  /// CodeView FPO data directives.
854  bool parseDirectiveFPOProc(SMLoc L);
855  bool parseDirectiveFPOSetFrame(SMLoc L);
856  bool parseDirectiveFPOPushReg(SMLoc L);
857  bool parseDirectiveFPOStackAlloc(SMLoc L);
858  bool parseDirectiveFPOStackAlign(SMLoc L);
859  bool parseDirectiveFPOEndPrologue(SMLoc L);
860  bool parseDirectiveFPOEndProc(SMLoc L);
861  bool parseDirectiveFPOData(SMLoc L);
862 
863  bool validateInstruction(MCInst &Inst, const OperandVector &Ops);
864  bool processInstruction(MCInst &Inst, const OperandVector &Ops);
865 
866  /// Wrapper around MCStreamer::EmitInstruction(). Possibly adds
867  /// instrumentation around Inst.
868  void EmitInstruction(MCInst &Inst, OperandVector &Operands, MCStreamer &Out);
869 
870  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
871  OperandVector &Operands, MCStreamer &Out,
872  uint64_t &ErrorInfo,
873  bool MatchingInlineAsm) override;
874 
875  void MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op, OperandVector &Operands,
876  MCStreamer &Out, bool MatchingInlineAsm);
877 
878  bool ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
879  bool MatchingInlineAsm);
880 
881  bool MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
882  OperandVector &Operands, MCStreamer &Out,
883  uint64_t &ErrorInfo,
884  bool MatchingInlineAsm);
885 
886  bool MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
887  OperandVector &Operands, MCStreamer &Out,
888  uint64_t &ErrorInfo,
889  bool MatchingInlineAsm);
890 
891  bool OmitRegisterFromClobberLists(unsigned RegNo) override;
892 
893  /// Parses AVX512 specific operand primitives: masked registers ({%k<NUM>}, {z})
894  /// and memory broadcasting ({1to<NUM>}) primitives, updating Operands vector if required.
895  /// return false if no parsing errors occurred, true otherwise.
896  bool HandleAVX512Operand(OperandVector &Operands,
897  const MCParsedAsmOperand &Op);
898 
899  bool ParseZ(std::unique_ptr<X86Operand> &Z, const SMLoc &StartLoc);
900 
901  bool is64BitMode() const {
902  // FIXME: Can tablegen auto-generate this?
903  return getSTI().getFeatureBits()[X86::Mode64Bit];
904  }
905  bool is32BitMode() const {
906  // FIXME: Can tablegen auto-generate this?
907  return getSTI().getFeatureBits()[X86::Mode32Bit];
908  }
909  bool is16BitMode() const {
910  // FIXME: Can tablegen auto-generate this?
911  return getSTI().getFeatureBits()[X86::Mode16Bit];
912  }
913  void SwitchMode(unsigned mode) {
914  MCSubtargetInfo &STI = copySTI();
915  FeatureBitset AllModes({X86::Mode64Bit, X86::Mode32Bit, X86::Mode16Bit});
916  FeatureBitset OldMode = STI.getFeatureBits() & AllModes;
917  uint64_t FB = ComputeAvailableFeatures(
918  STI.ToggleFeature(OldMode.flip(mode)));
919  setAvailableFeatures(FB);
920 
921  assert(FeatureBitset({mode}) == (STI.getFeatureBits() & AllModes));
922  }
923 
924  unsigned getPointerWidth() {
925  if (is16BitMode()) return 16;
926  if (is32BitMode()) return 32;
927  if (is64BitMode()) return 64;
928  llvm_unreachable("invalid mode");
929  }
930 
931  bool isParsingIntelSyntax() {
932  return getParser().getAssemblerDialect();
933  }
934 
935  /// @name Auto-generated Matcher Functions
936  /// {
937 
938 #define GET_ASSEMBLER_HEADER
939 #include "X86GenAsmMatcher.inc"
940 
941  /// }
942 
943 public:
944 
945  X86AsmParser(const MCSubtargetInfo &sti, MCAsmParser &Parser,
946  const MCInstrInfo &mii, const MCTargetOptions &Options)
947  : MCTargetAsmParser(Options, sti, mii), InstInfo(nullptr),
948  Code16GCC(false) {
949 
950  Parser.addAliasForDirective(".word", ".2byte");
951 
952  // Initialize the set of available features.
953  setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
954  Instrumentation.reset(
955  CreateX86AsmInstrumentation(Options, Parser.getContext(), STI));
956  }
957 
958  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
959 
960  void SetFrameRegister(unsigned RegNo) override;
961 
962  bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) override;
963 
964  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
965  SMLoc NameLoc, OperandVector &Operands) override;
966 
967  bool ParseDirective(AsmToken DirectiveID) override;
968 };
969 } // end anonymous namespace
970 
971 /// @name Auto-generated Match Functions
972 /// {
973 
974 static unsigned MatchRegisterName(StringRef Name);
975 
976 /// }
977 
978 static bool CheckBaseRegAndIndexRegAndScale(unsigned BaseReg, unsigned IndexReg,
979  unsigned Scale, bool Is64BitMode,
980  StringRef &ErrMsg) {
981  // If we have both a base register and an index register make sure they are
982  // both 64-bit or 32-bit registers.
983  // To support VSIB, IndexReg can be 128-bit or 256-bit registers.
984 
985  if (BaseReg != 0 &&
986  !(BaseReg == X86::RIP || BaseReg == X86::EIP ||
987  X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) ||
988  X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg) ||
989  X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg))) {
990  ErrMsg = "invalid base+index expression";
991  return true;
992  }
993 
994  if (IndexReg != 0 &&
995  !(IndexReg == X86::EIZ || IndexReg == X86::RIZ ||
996  X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
997  X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg) ||
998  X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg) ||
999  X86MCRegisterClasses[X86::VR128XRegClassID].contains(IndexReg) ||
1000  X86MCRegisterClasses[X86::VR256XRegClassID].contains(IndexReg) ||
1001  X86MCRegisterClasses[X86::VR512RegClassID].contains(IndexReg))) {
1002  ErrMsg = "invalid base+index expression";
1003  return true;
1004  }
1005 
1006  if (((BaseReg == X86::RIP || BaseReg == X86::EIP) && IndexReg != 0) ||
1007  IndexReg == X86::EIP || IndexReg == X86::RIP ||
1008  IndexReg == X86::ESP || IndexReg == X86::RSP) {
1009  ErrMsg = "invalid base+index expression";
1010  return true;
1011  }
1012 
1013  // Check for use of invalid 16-bit registers. Only BX/BP/SI/DI are allowed,
1014  // and then only in non-64-bit modes.
1015  if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
1016  (Is64BitMode || (BaseReg != X86::BX && BaseReg != X86::BP &&
1017  BaseReg != X86::SI && BaseReg != X86::DI))) {
1018  ErrMsg = "invalid 16-bit base register";
1019  return true;
1020  }
1021 
1022  if (BaseReg == 0 &&
1023  X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg)) {
1024  ErrMsg = "16-bit memory operand may not include only index register";
1025  return true;
1026  }
1027 
1028  if (BaseReg != 0 && IndexReg != 0) {
1029  if (X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) &&
1030  (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
1031  X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg) ||
1032  IndexReg == X86::EIZ)) {
1033  ErrMsg = "base register is 64-bit, but index register is not";
1034  return true;
1035  }
1036  if (X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg) &&
1037  (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
1038  X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg) ||
1039  IndexReg == X86::RIZ)) {
1040  ErrMsg = "base register is 32-bit, but index register is not";
1041  return true;
1042  }
1043  if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg)) {
1044  if (X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg) ||
1045  X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) {
1046  ErrMsg = "base register is 16-bit, but index register is not";
1047  return true;
1048  }
1049  if ((BaseReg != X86::BX && BaseReg != X86::BP) ||
1050  (IndexReg != X86::SI && IndexReg != X86::DI)) {
1051  ErrMsg = "invalid 16-bit base/index register combination";
1052  return true;
1053  }
1054  }
1055  }
1056 
1057  // RIP/EIP-relative addressing is only supported in 64-bit mode.
1058  if (!Is64BitMode && BaseReg != 0 &&
1059  (BaseReg == X86::RIP || BaseReg == X86::EIP)) {
1060  ErrMsg = "IP-relative addressing requires 64-bit mode";
1061  return true;
1062  }
1063 
1064  return checkScale(Scale, ErrMsg);
1065 }
1066 
1067 bool X86AsmParser::ParseRegister(unsigned &RegNo,
1068  SMLoc &StartLoc, SMLoc &EndLoc) {
1069  MCAsmParser &Parser = getParser();
1070  RegNo = 0;
1071  const AsmToken &PercentTok = Parser.getTok();
1072  StartLoc = PercentTok.getLoc();
1073 
1074  // If we encounter a %, ignore it. This code handles registers with and
1075  // without the prefix, unprefixed registers can occur in cfi directives.
1076  if (!isParsingIntelSyntax() && PercentTok.is(AsmToken::Percent))
1077  Parser.Lex(); // Eat percent token.
1078 
1079  const AsmToken &Tok = Parser.getTok();
1080  EndLoc = Tok.getEndLoc();
1081 
1082  if (Tok.isNot(AsmToken::Identifier)) {
1083  if (isParsingIntelSyntax()) return true;
1084  return Error(StartLoc, "invalid register name",
1085  SMRange(StartLoc, EndLoc));
1086  }
1087 
1088  RegNo = MatchRegisterName(Tok.getString());
1089 
1090  // If the match failed, try the register name as lowercase.
1091  if (RegNo == 0)
1092  RegNo = MatchRegisterName(Tok.getString().lower());
1093 
1094  // The "flags" register cannot be referenced directly.
1095  // Treat it as an identifier instead.
1096  if (isParsingInlineAsm() && isParsingIntelSyntax() && RegNo == X86::EFLAGS)
1097  RegNo = 0;
1098 
1099  if (!is64BitMode()) {
1100  // FIXME: This should be done using Requires<Not64BitMode> and
1101  // Requires<In64BitMode> so "eiz" usage in 64-bit instructions can be also
1102  // checked.
1103  // FIXME: Check AH, CH, DH, BH cannot be used in an instruction requiring a
1104  // REX prefix.
1105  if (RegNo == X86::RIZ || RegNo == X86::RIP ||
1106  X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo) ||
1108  X86II::isX86_64ExtendedReg(RegNo)) {
1109  StringRef RegName = Tok.getString();
1110  Parser.Lex(); // Eat register name.
1111  return Error(StartLoc,
1112  "register %" + RegName + " is only available in 64-bit mode",
1113  SMRange(StartLoc, EndLoc));
1114  }
1115  }
1116 
1117  // Parse "%st" as "%st(0)" and "%st(1)", which is multiple tokens.
1118  if (RegNo == 0 && (Tok.getString() == "st" || Tok.getString() == "ST")) {
1119  RegNo = X86::ST0;
1120  Parser.Lex(); // Eat 'st'
1121 
1122  // Check to see if we have '(4)' after %st.
1123  if (getLexer().isNot(AsmToken::LParen))
1124  return false;
1125  // Lex the paren.
1126  getParser().Lex();
1127 
1128  const AsmToken &IntTok = Parser.getTok();
1129  if (IntTok.isNot(AsmToken::Integer))
1130  return Error(IntTok.getLoc(), "expected stack index");
1131  switch (IntTok.getIntVal()) {
1132  case 0: RegNo = X86::ST0; break;
1133  case 1: RegNo = X86::ST1; break;
1134  case 2: RegNo = X86::ST2; break;
1135  case 3: RegNo = X86::ST3; break;
1136  case 4: RegNo = X86::ST4; break;
1137  case 5: RegNo = X86::ST5; break;
1138  case 6: RegNo = X86::ST6; break;
1139  case 7: RegNo = X86::ST7; break;
1140  default: return Error(IntTok.getLoc(), "invalid stack index");
1141  }
1142 
1143  if (getParser().Lex().isNot(AsmToken::RParen))
1144  return Error(Parser.getTok().getLoc(), "expected ')'");
1145 
1146  EndLoc = Parser.getTok().getEndLoc();
1147  Parser.Lex(); // Eat ')'
1148  return false;
1149  }
1150 
1151  EndLoc = Parser.getTok().getEndLoc();
1152 
1153  // If this is "db[0-15]", match it as an alias
1154  // for dr[0-15].
1155  if (RegNo == 0 && Tok.getString().startswith("db")) {
1156  if (Tok.getString().size() == 3) {
1157  switch (Tok.getString()[2]) {
1158  case '0': RegNo = X86::DR0; break;
1159  case '1': RegNo = X86::DR1; break;
1160  case '2': RegNo = X86::DR2; break;
1161  case '3': RegNo = X86::DR3; break;
1162  case '4': RegNo = X86::DR4; break;
1163  case '5': RegNo = X86::DR5; break;
1164  case '6': RegNo = X86::DR6; break;
1165  case '7': RegNo = X86::DR7; break;
1166  case '8': RegNo = X86::DR8; break;
1167  case '9': RegNo = X86::DR9; break;
1168  }
1169  } else if (Tok.getString().size() == 4 && Tok.getString()[2] == '1') {
1170  switch (Tok.getString()[3]) {
1171  case '0': RegNo = X86::DR10; break;
1172  case '1': RegNo = X86::DR11; break;
1173  case '2': RegNo = X86::DR12; break;
1174  case '3': RegNo = X86::DR13; break;
1175  case '4': RegNo = X86::DR14; break;
1176  case '5': RegNo = X86::DR15; break;
1177  }
1178  }
1179 
1180  if (RegNo != 0) {
1181  EndLoc = Parser.getTok().getEndLoc();
1182  Parser.Lex(); // Eat it.
1183  return false;
1184  }
1185  }
1186 
1187  if (RegNo == 0) {
1188  if (isParsingIntelSyntax()) return true;
1189  return Error(StartLoc, "invalid register name",
1190  SMRange(StartLoc, EndLoc));
1191  }
1192 
1193  Parser.Lex(); // Eat identifier token.
1194  return false;
1195 }
1196 
1197 void X86AsmParser::SetFrameRegister(unsigned RegNo) {
1198  Instrumentation->SetInitialFrameRegister(RegNo);
1199 }
1200 
1201 std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(SMLoc Loc) {
1202  bool Parse32 = is32BitMode() || Code16GCC;
1203  unsigned Basereg = is64BitMode() ? X86::RSI : (Parse32 ? X86::ESI : X86::SI);
1204  const MCExpr *Disp = MCConstantExpr::create(0, getContext());
1205  return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
1206  /*BaseReg=*/Basereg, /*IndexReg=*/0, /*Scale=*/1,
1207  Loc, Loc, 0);
1208 }
1209 
1210 std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand(SMLoc Loc) {
1211  bool Parse32 = is32BitMode() || Code16GCC;
1212  unsigned Basereg = is64BitMode() ? X86::RDI : (Parse32 ? X86::EDI : X86::DI);
1213  const MCExpr *Disp = MCConstantExpr::create(0, getContext());
1214  return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
1215  /*BaseReg=*/Basereg, /*IndexReg=*/0, /*Scale=*/1,
1216  Loc, Loc, 0);
1217 }
1218 
1219 bool X86AsmParser::IsSIReg(unsigned Reg) {
1220  switch (Reg) {
1221  default: llvm_unreachable("Only (R|E)SI and (R|E)DI are expected!");
1222  case X86::RSI:
1223  case X86::ESI:
1224  case X86::SI:
1225  return true;
1226  case X86::RDI:
1227  case X86::EDI:
1228  case X86::DI:
1229  return false;
1230  }
1231 }
1232 
1233 unsigned X86AsmParser::GetSIDIForRegClass(unsigned RegClassID, unsigned Reg,
1234  bool IsSIReg) {
1235  switch (RegClassID) {
1236  default: llvm_unreachable("Unexpected register class");
1237  case X86::GR64RegClassID:
1238  return IsSIReg ? X86::RSI : X86::RDI;
1239  case X86::GR32RegClassID:
1240  return IsSIReg ? X86::ESI : X86::EDI;
1241  case X86::GR16RegClassID:
1242  return IsSIReg ? X86::SI : X86::DI;
1243  }
1244 }
1245 
1246 void X86AsmParser::AddDefaultSrcDestOperands(
1247  OperandVector& Operands, std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
1248  std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst) {
1249  if (isParsingIntelSyntax()) {
1250  Operands.push_back(std::move(Dst));
1251  Operands.push_back(std::move(Src));
1252  }
1253  else {
1254  Operands.push_back(std::move(Src));
1255  Operands.push_back(std::move(Dst));
1256  }
1257 }
1258 
1259 bool X86AsmParser::VerifyAndAdjustOperands(OperandVector &OrigOperands,
1260  OperandVector &FinalOperands) {
1261 
1262  if (OrigOperands.size() > 1) {
1263  // Check if sizes match, OrigOperands also contains the instruction name
1264  assert(OrigOperands.size() == FinalOperands.size() + 1 &&
1265  "Operand size mismatch");
1266 
1268  // Verify types match
1269  int RegClassID = -1;
1270  for (unsigned int i = 0; i < FinalOperands.size(); ++i) {
1271  X86Operand &OrigOp = static_cast<X86Operand &>(*OrigOperands[i + 1]);
1272  X86Operand &FinalOp = static_cast<X86Operand &>(*FinalOperands[i]);
1273 
1274  if (FinalOp.isReg() &&
1275  (!OrigOp.isReg() || FinalOp.getReg() != OrigOp.getReg()))
1276  // Return false and let a normal complaint about bogus operands happen
1277  return false;
1278 
1279  if (FinalOp.isMem()) {
1280 
1281  if (!OrigOp.isMem())
1282  // Return false and let a normal complaint about bogus operands happen
1283  return false;
1284 
1285  unsigned OrigReg = OrigOp.Mem.BaseReg;
1286  unsigned FinalReg = FinalOp.Mem.BaseReg;
1287 
1288  // If we've already encounterd a register class, make sure all register
1289  // bases are of the same register class
1290  if (RegClassID != -1 &&
1291  !X86MCRegisterClasses[RegClassID].contains(OrigReg)) {
1292  return Error(OrigOp.getStartLoc(),
1293  "mismatching source and destination index registers");
1294  }
1295 
1296  if (X86MCRegisterClasses[X86::GR64RegClassID].contains(OrigReg))
1297  RegClassID = X86::GR64RegClassID;
1298  else if (X86MCRegisterClasses[X86::GR32RegClassID].contains(OrigReg))
1299  RegClassID = X86::GR32RegClassID;
1300  else if (X86MCRegisterClasses[X86::GR16RegClassID].contains(OrigReg))
1301  RegClassID = X86::GR16RegClassID;
1302  else
1303  // Unexpected register class type
1304  // Return false and let a normal complaint about bogus operands happen
1305  return false;
1306 
1307  bool IsSI = IsSIReg(FinalReg);
1308  FinalReg = GetSIDIForRegClass(RegClassID, FinalReg, IsSI);
1309 
1310  if (FinalReg != OrigReg) {
1311  std::string RegName = IsSI ? "ES:(R|E)SI" : "ES:(R|E)DI";
1312  Warnings.push_back(std::make_pair(
1313  OrigOp.getStartLoc(),
1314  "memory operand is only for determining the size, " + RegName +
1315  " will be used for the location"));
1316  }
1317 
1318  FinalOp.Mem.Size = OrigOp.Mem.Size;
1319  FinalOp.Mem.SegReg = OrigOp.Mem.SegReg;
1320  FinalOp.Mem.BaseReg = FinalReg;
1321  }
1322  }
1323 
1324  // Produce warnings only if all the operands passed the adjustment - prevent
1325  // legal cases like "movsd (%rax), %xmm0" mistakenly produce warnings
1326  for (auto &WarningMsg : Warnings) {
1327  Warning(WarningMsg.first, WarningMsg.second);
1328  }
1329 
1330  // Remove old operands
1331  for (unsigned int i = 0; i < FinalOperands.size(); ++i)
1332  OrigOperands.pop_back();
1333  }
1334  // OrigOperands.append(FinalOperands.begin(), FinalOperands.end());
1335  for (unsigned int i = 0; i < FinalOperands.size(); ++i)
1336  OrigOperands.push_back(std::move(FinalOperands[i]));
1337 
1338  return false;
1339 }
1340 
1341 std::unique_ptr<X86Operand> X86AsmParser::ParseOperand() {
1342  if (isParsingIntelSyntax())
1343  return ParseIntelOperand();
1344  return ParseATTOperand();
1345 }
1346 
1347 std::unique_ptr<X86Operand> X86AsmParser::CreateMemForInlineAsm(
1348  unsigned SegReg, const MCExpr *Disp, unsigned BaseReg, unsigned IndexReg,
1349  unsigned Scale, SMLoc Start, SMLoc End, unsigned Size, StringRef Identifier,
1350  const InlineAsmIdentifierInfo &Info) {
1351  // If we found a decl other than a VarDecl, then assume it is a FuncDecl or
1352  // some other label reference.
1354  // Insert an explicit size if the user didn't have one.
1355  if (!Size) {
1356  Size = getPointerWidth();
1357  InstInfo->AsmRewrites->emplace_back(AOK_SizeDirective, Start,
1358  /*Len=*/0, Size);
1359  }
1360  // Create an absolute memory reference in order to match against
1361  // instructions taking a PC relative operand.
1362  return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size,
1363  Identifier, Info.Label.Decl);
1364  }
1365  // We either have a direct symbol reference, or an offset from a symbol. The
1366  // parser always puts the symbol on the LHS, so look there for size
1367  // calculation purposes.
1368  unsigned FrontendSize = 0;
1369  void *Decl = nullptr;
1370  bool IsGlobalLV = false;
1372  // Size is in terms of bits in this context.
1373  FrontendSize = Info.Var.Type * 8;
1374  Decl = Info.Var.Decl;
1375  IsGlobalLV = Info.Var.IsGlobalLV;
1376  }
1377  // It is widely common for MS InlineAsm to use a global variable and one/two
1378  // registers in a mmory expression, and though unaccessible via rip/eip.
1379  if (IsGlobalLV && (BaseReg || IndexReg)) {
1380  return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End);
1381  // Otherwise, we set the base register to a non-zero value
1382  // if we don't know the actual value at this time. This is necessary to
1383  // get the matching correct in some cases.
1384  } else {
1385  BaseReg = BaseReg ? BaseReg : 1;
1386  return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
1387  IndexReg, Scale, Start, End, Size, Identifier,
1388  Decl, FrontendSize);
1389  }
1390 }
1391 
1392 // Some binary bitwise operators have a named synonymous
1393 // Query a candidate string for being such a named operator
1394 // and if so - invoke the appropriate handler
1395 bool X86AsmParser::ParseIntelNamedOperator(StringRef Name, IntelExprStateMachine &SM) {
1396  // A named operator should be either lower or upper case, but not a mix
1397  if (Name.compare(Name.lower()) && Name.compare(Name.upper()))
1398  return false;
1399  if (Name.equals_lower("not"))
1400  SM.onNot();
1401  else if (Name.equals_lower("or"))
1402  SM.onOr();
1403  else if (Name.equals_lower("shl"))
1404  SM.onLShift();
1405  else if (Name.equals_lower("shr"))
1406  SM.onRShift();
1407  else if (Name.equals_lower("xor"))
1408  SM.onXor();
1409  else if (Name.equals_lower("and"))
1410  SM.onAnd();
1411  else if (Name.equals_lower("mod"))
1412  SM.onMod();
1413  else
1414  return false;
1415  return true;
1416 }
1417 
1418 bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
1419  MCAsmParser &Parser = getParser();
1420  const AsmToken &Tok = Parser.getTok();
1421  StringRef ErrMsg;
1422 
1424  bool Done = false;
1425  while (!Done) {
1426  bool UpdateLocLex = true;
1427  AsmToken::TokenKind TK = getLexer().getKind();
1428 
1429  switch (TK) {
1430  default:
1431  if ((Done = SM.isValidEndState()))
1432  break;
1433  return Error(Tok.getLoc(), "unknown token in expression");
1435  Done = true;
1436  break;
1437  case AsmToken::Real:
1438  // DotOperator: [ebx].0
1439  UpdateLocLex = false;
1440  if (ParseIntelDotOperator(SM, End))
1441  return true;
1442  break;
1443  case AsmToken::At:
1444  case AsmToken::String:
1445  case AsmToken::Identifier: {
1446  SMLoc IdentLoc = Tok.getLoc();
1447  StringRef Identifier = Tok.getString();
1448  UpdateLocLex = false;
1449  // Register
1450  unsigned Reg;
1451  if (Tok.is(AsmToken::Identifier) && !ParseRegister(Reg, IdentLoc, End)) {
1452  if (SM.onRegister(Reg, ErrMsg))
1453  return Error(Tok.getLoc(), ErrMsg);
1454  break;
1455  }
1456  // Operator synonymous ("not", "or" etc.)
1457  if ((UpdateLocLex = ParseIntelNamedOperator(Identifier, SM)))
1458  break;
1459  // Symbol reference, when parsing assembly content
1461  const MCExpr *Val;
1462  if (!isParsingInlineAsm()) {
1463  if (getParser().parsePrimaryExpr(Val, End)) {
1464  return Error(Tok.getLoc(), "Unexpected identifier!");
1465  } else if (SM.onIdentifierExpr(Val, Identifier, Info, false, ErrMsg)) {
1466  return Error(IdentLoc, ErrMsg);
1467  } else
1468  break;
1469  }
1470  // MS InlineAsm operators (TYPE/LENGTH/SIZE)
1471  if (unsigned OpKind = IdentifyIntelInlineAsmOperator(Identifier)) {
1472  if (OpKind == IOK_OFFSET)
1473  return Error(IdentLoc, "Dealing OFFSET operator as part of"
1474  "a compound immediate expression is yet to be supported");
1475  if (int64_t Val = ParseIntelInlineAsmOperator(OpKind)) {
1476  if (SM.onInteger(Val, ErrMsg))
1477  return Error(IdentLoc, ErrMsg);
1478  } else
1479  return true;
1480  break;
1481  }
1482  // MS Dot Operator expression
1483  if (Identifier.count('.') && PrevTK == AsmToken::RBrac) {
1484  if (ParseIntelDotOperator(SM, End))
1485  return true;
1486  break;
1487  }
1488  // MS InlineAsm identifier
1489  // Call parseIdentifier() to combine @ with the identifier behind it.
1490  if (TK == AsmToken::At && Parser.parseIdentifier(Identifier))
1491  return Error(IdentLoc, "expected identifier");
1492  if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info, false, End))
1493  return true;
1494  else if (SM.onIdentifierExpr(Val, Identifier, Info, true, ErrMsg))
1495  return Error(IdentLoc, ErrMsg);
1496  break;
1497  }
1498  case AsmToken::Integer: {
1499  // Look for 'b' or 'f' following an Integer as a directional label
1500  SMLoc Loc = getTok().getLoc();
1501  int64_t IntVal = getTok().getIntVal();
1502  End = consumeToken();
1503  UpdateLocLex = false;
1504  if (getLexer().getKind() == AsmToken::Identifier) {
1505  StringRef IDVal = getTok().getString();
1506  if (IDVal == "f" || IDVal == "b") {
1507  MCSymbol *Sym =
1508  getContext().getDirectionalLocalSymbol(IntVal, IDVal == "b");
1510  const MCExpr *Val =
1511  MCSymbolRefExpr::create(Sym, Variant, getContext());
1512  if (IDVal == "b" && Sym->isUndefined())
1513  return Error(Loc, "invalid reference to undefined symbol");
1514  StringRef Identifier = Sym->getName();
1516  if (SM.onIdentifierExpr(Val, Identifier, Info,
1517  isParsingInlineAsm(), ErrMsg))
1518  return Error(Loc, ErrMsg);
1519  End = consumeToken();
1520  } else {
1521  if (SM.onInteger(IntVal, ErrMsg))
1522  return Error(Loc, ErrMsg);
1523  }
1524  } else {
1525  if (SM.onInteger(IntVal, ErrMsg))
1526  return Error(Loc, ErrMsg);
1527  }
1528  break;
1529  }
1530  case AsmToken::Plus:
1531  if (SM.onPlus(ErrMsg))
1532  return Error(getTok().getLoc(), ErrMsg);
1533  break;
1534  case AsmToken::Minus:
1535  if (SM.onMinus(ErrMsg))
1536  return Error(getTok().getLoc(), ErrMsg);
1537  break;
1538  case AsmToken::Tilde: SM.onNot(); break;
1539  case AsmToken::Star: SM.onStar(); break;
1540  case AsmToken::Slash: SM.onDivide(); break;
1541  case AsmToken::Percent: SM.onMod(); break;
1542  case AsmToken::Pipe: SM.onOr(); break;
1543  case AsmToken::Caret: SM.onXor(); break;
1544  case AsmToken::Amp: SM.onAnd(); break;
1545  case AsmToken::LessLess:
1546  SM.onLShift(); break;
1548  SM.onRShift(); break;
1549  case AsmToken::LBrac:
1550  if (SM.onLBrac())
1551  return Error(Tok.getLoc(), "unexpected bracket encountered");
1552  break;
1553  case AsmToken::RBrac:
1554  if (SM.onRBrac())
1555  return Error(Tok.getLoc(), "unexpected bracket encountered");
1556  break;
1557  case AsmToken::LParen: SM.onLParen(); break;
1558  case AsmToken::RParen: SM.onRParen(); break;
1559  }
1560  if (SM.hadError())
1561  return Error(Tok.getLoc(), "unknown token in expression");
1562 
1563  if (!Done && UpdateLocLex)
1564  End = consumeToken();
1565 
1566  PrevTK = TK;
1567  }
1568  return false;
1569 }
1570 
1571 void X86AsmParser::RewriteIntelExpression(IntelExprStateMachine &SM,
1572  SMLoc Start, SMLoc End) {
1573  SMLoc Loc = Start;
1574  unsigned ExprLen = End.getPointer() - Start.getPointer();
1575  // Skip everything before a symbol displacement (if we have one)
1576  if (SM.getSym()) {
1577  StringRef SymName = SM.getSymName();
1578  if (unsigned Len = SymName.data() - Start.getPointer())
1579  InstInfo->AsmRewrites->emplace_back(AOK_Skip, Start, Len);
1580  Loc = SMLoc::getFromPointer(SymName.data() + SymName.size());
1581  ExprLen = End.getPointer() - (SymName.data() + SymName.size());
1582  // If we have only a symbol than there's no need for complex rewrite,
1583  // simply skip everything after it
1584  if (!(SM.getBaseReg() || SM.getIndexReg() || SM.getImm())) {
1585  if (ExprLen)
1586  InstInfo->AsmRewrites->emplace_back(AOK_Skip, Loc, ExprLen);
1587  return;
1588  }
1589  }
1590  // Build an Intel Expression rewrite
1591  StringRef BaseRegStr;
1592  StringRef IndexRegStr;
1593  if (SM.getBaseReg())
1594  BaseRegStr = X86IntelInstPrinter::getRegisterName(SM.getBaseReg());
1595  if (SM.getIndexReg())
1596  IndexRegStr = X86IntelInstPrinter::getRegisterName(SM.getIndexReg());
1597  // Emit it
1598  IntelExpr Expr(BaseRegStr, IndexRegStr, SM.getScale(), SM.getImm(), SM.isMemExpr());
1599  InstInfo->AsmRewrites->emplace_back(Loc, ExprLen, Expr);
1600 }
1601 
1602 // Inline assembly may use variable names with namespace alias qualifiers.
1603 bool X86AsmParser::ParseIntelInlineAsmIdentifier(const MCExpr *&Val,
1604  StringRef &Identifier,
1606  bool IsUnevaluatedOperand,
1607  SMLoc &End) {
1608  MCAsmParser &Parser = getParser();
1609  assert(isParsingInlineAsm() && "Expected to be parsing inline assembly.");
1610  Val = nullptr;
1611 
1612  StringRef LineBuf(Identifier.data());
1613  SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);
1614 
1615  const AsmToken &Tok = Parser.getTok();
1616  SMLoc Loc = Tok.getLoc();
1617 
1618  // Advance the token stream until the end of the current token is
1619  // after the end of what the frontend claimed.
1620  const char *EndPtr = Tok.getLoc().getPointer() + LineBuf.size();
1621  do {
1622  End = Tok.getEndLoc();
1623  getLexer().Lex();
1624  } while (End.getPointer() < EndPtr);
1625  Identifier = LineBuf;
1626 
1627  // The frontend should end parsing on an assembler token boundary, unless it
1628  // failed parsing.
1629  assert((End.getPointer() == EndPtr ||
1631  "frontend claimed part of a token?");
1632 
1633  // If the identifier lookup was unsuccessful, assume that we are dealing with
1634  // a label.
1636  StringRef InternalName =
1637  SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(),
1638  Loc, false);
1639  assert(InternalName.size() && "We should have an internal name here.");
1640  // Push a rewrite for replacing the identifier name with the internal name.
1641  InstInfo->AsmRewrites->emplace_back(AOK_Label, Loc, Identifier.size(),
1642  InternalName);
1644  return false;
1645  // Create the symbol reference.
1646  MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
1648  Val = MCSymbolRefExpr::create(Sym, Variant, getParser().getContext());
1649  return false;
1650 }
1651 
1652 //ParseRoundingModeOp - Parse AVX-512 rounding mode operand
1653 std::unique_ptr<X86Operand>
1654 X86AsmParser::ParseRoundingModeOp(SMLoc Start) {
1655  MCAsmParser &Parser = getParser();
1656  const AsmToken &Tok = Parser.getTok();
1657  // Eat "{" and mark the current place.
1658  const SMLoc consumedToken = consumeToken();
1659  if (Tok.getIdentifier().startswith("r")){
1660  int rndMode = StringSwitch<int>(Tok.getIdentifier())
1665  .Default(-1);
1666  if (-1 == rndMode)
1667  return ErrorOperand(Tok.getLoc(), "Invalid rounding mode.");
1668  Parser.Lex(); // Eat "r*" of r*-sae
1669  if (!getLexer().is(AsmToken::Minus))
1670  return ErrorOperand(Tok.getLoc(), "Expected - at this point");
1671  Parser.Lex(); // Eat "-"
1672  Parser.Lex(); // Eat the sae
1673  if (!getLexer().is(AsmToken::RCurly))
1674  return ErrorOperand(Tok.getLoc(), "Expected } at this point");
1675  SMLoc End = Tok.getEndLoc();
1676  Parser.Lex(); // Eat "}"
1677  const MCExpr *RndModeOp =
1678  MCConstantExpr::create(rndMode, Parser.getContext());
1679  return X86Operand::CreateImm(RndModeOp, Start, End);
1680  }
1681  if(Tok.getIdentifier().equals("sae")){
1682  Parser.Lex(); // Eat the sae
1683  if (!getLexer().is(AsmToken::RCurly))
1684  return ErrorOperand(Tok.getLoc(), "Expected } at this point");
1685  Parser.Lex(); // Eat "}"
1686  return X86Operand::CreateToken("{sae}", consumedToken);
1687  }
1688  return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1689 }
1690 
1691 /// Parse the '.' operator.
1692 bool X86AsmParser::ParseIntelDotOperator(IntelExprStateMachine &SM, SMLoc &End) {
1693  const AsmToken &Tok = getTok();
1694  unsigned Offset;
1695 
1696  // Drop the optional '.'.
1697  StringRef DotDispStr = Tok.getString();
1698  if (DotDispStr.startswith("."))
1699  DotDispStr = DotDispStr.drop_front(1);
1700 
1701  // .Imm gets lexed as a real.
1702  if (Tok.is(AsmToken::Real)) {
1703  APInt DotDisp;
1704  DotDispStr.getAsInteger(10, DotDisp);
1705  Offset = DotDisp.getZExtValue();
1706  } else if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) {
1707  std::pair<StringRef, StringRef> BaseMember = DotDispStr.split('.');
1708  if (SemaCallback->LookupInlineAsmField(BaseMember.first, BaseMember.second,
1709  Offset))
1710  return Error(Tok.getLoc(), "Unable to lookup field reference!");
1711  } else
1712  return Error(Tok.getLoc(), "Unexpected token type!");
1713 
1714  // Eat the DotExpression and update End
1715  End = SMLoc::getFromPointer(DotDispStr.data());
1716  const char *DotExprEndLoc = DotDispStr.data() + DotDispStr.size();
1717  while (Tok.getLoc().getPointer() < DotExprEndLoc)
1718  Lex();
1719  SM.addImm(Offset);
1720  return false;
1721 }
1722 
1723 /// Parse the 'offset' operator. This operator is used to specify the
1724 /// location rather then the content of a variable.
1725 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOffsetOfOperator() {
1726  MCAsmParser &Parser = getParser();
1727  const AsmToken &Tok = Parser.getTok();
1728  SMLoc OffsetOfLoc = Tok.getLoc();
1729  Parser.Lex(); // Eat offset.
1730 
1731  const MCExpr *Val;
1733  SMLoc Start = Tok.getLoc(), End;
1734  StringRef Identifier = Tok.getString();
1735  if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
1736  /*Unevaluated=*/false, End))
1737  return nullptr;
1738 
1739  void *Decl = nullptr;
1740  // FIXME: MS evaluates "offset <Constant>" to the underlying integral
1742  return ErrorOperand(Start, "offset operator cannot yet handle constants");
1743  else if (Info.isKind(InlineAsmIdentifierInfo::IK_Var))
1744  Decl = Info.Var.Decl;
1745  // Don't emit the offset operator.
1746  InstInfo->AsmRewrites->emplace_back(AOK_Skip, OffsetOfLoc, 7);
1747 
1748  // The offset operator will have an 'r' constraint, thus we need to create
1749  // register operand to ensure proper matching. Just pick a GPR based on
1750  // the size of a pointer.
1751  bool Parse32 = is32BitMode() || Code16GCC;
1752  unsigned RegNo = is64BitMode() ? X86::RBX : (Parse32 ? X86::EBX : X86::BX);
1753 
1754  return X86Operand::CreateReg(RegNo, Start, End, /*GetAddress=*/true,
1755  OffsetOfLoc, Identifier, Decl);
1756 }
1757 
1758 // Query a candidate string for being an Intel assembly operator
1759 // Report back its kind, or IOK_INVALID if does not evaluated as a known one
1760 unsigned X86AsmParser::IdentifyIntelInlineAsmOperator(StringRef Name) {
1762  .Cases("TYPE","type",IOK_TYPE)
1763  .Cases("SIZE","size",IOK_SIZE)
1764  .Cases("LENGTH","length",IOK_LENGTH)
1765  .Cases("OFFSET","offset",IOK_OFFSET)
1766  .Default(IOK_INVALID);
1767 }
1768 
1769 /// Parse the 'LENGTH', 'TYPE' and 'SIZE' operators. The LENGTH operator
1770 /// returns the number of elements in an array. It returns the value 1 for
1771 /// non-array variables. The SIZE operator returns the size of a C or C++
1772 /// variable. A variable's size is the product of its LENGTH and TYPE. The
1773 /// TYPE operator returns the size of a C or C++ type or variable. If the
1774 /// variable is an array, TYPE returns the size of a single element.
1775 unsigned X86AsmParser::ParseIntelInlineAsmOperator(unsigned OpKind) {
1776  MCAsmParser &Parser = getParser();
1777  const AsmToken &Tok = Parser.getTok();
1778  Parser.Lex(); // Eat operator.
1779 
1780  const MCExpr *Val = nullptr;
1782  SMLoc Start = Tok.getLoc(), End;
1783  StringRef Identifier = Tok.getString();
1784  if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
1785  /*Unevaluated=*/true, End))
1786  return 0;
1787 
1789  Error(Start, "unable to lookup expression");
1790  return 0;
1791  }
1792 
1793  unsigned CVal = 0;
1794  switch(OpKind) {
1795  default: llvm_unreachable("Unexpected operand kind!");
1796  case IOK_LENGTH: CVal = Info.Var.Length; break;
1797  case IOK_SIZE: CVal = Info.Var.Size; break;
1798  case IOK_TYPE: CVal = Info.Var.Type; break;
1799  }
1800 
1801  return CVal;
1802 }
1803 
1804 bool X86AsmParser::ParseIntelMemoryOperandSize(unsigned &Size) {
1805  Size = StringSwitch<unsigned>(getTok().getString())
1806  .Cases("BYTE", "byte", 8)
1807  .Cases("WORD", "word", 16)
1808  .Cases("DWORD", "dword", 32)
1809  .Cases("FLOAT", "float", 32)
1810  .Cases("LONG", "long", 32)
1811  .Cases("FWORD", "fword", 48)
1812  .Cases("DOUBLE", "double", 64)
1813  .Cases("QWORD", "qword", 64)
1814  .Cases("MMWORD","mmword", 64)
1815  .Cases("XWORD", "xword", 80)
1816  .Cases("TBYTE", "tbyte", 80)
1817  .Cases("XMMWORD", "xmmword", 128)
1818  .Cases("YMMWORD", "ymmword", 256)
1819  .Cases("ZMMWORD", "zmmword", 512)
1820  .Default(0);
1821  if (Size) {
1822  const AsmToken &Tok = Lex(); // Eat operand size (e.g., byte, word).
1823  if (!(Tok.getString().equals("PTR") || Tok.getString().equals("ptr")))
1824  return Error(Tok.getLoc(), "Expected 'PTR' or 'ptr' token!");
1825  Lex(); // Eat ptr.
1826  }
1827  return false;
1828 }
1829 
1830 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand() {
1831  MCAsmParser &Parser = getParser();
1832  const AsmToken &Tok = Parser.getTok();
1833  SMLoc Start, End;
1834 
1835  // FIXME: Offset operator
1836  // Should be handled as part of immediate expression, as other operators
1837  // Currently, only supported as a stand-alone operand
1838  if (isParsingInlineAsm())
1839  if (IdentifyIntelInlineAsmOperator(Tok.getString()) == IOK_OFFSET)
1840  return ParseIntelOffsetOfOperator();
1841 
1842  // Parse optional Size directive.
1843  unsigned Size;
1844  if (ParseIntelMemoryOperandSize(Size))
1845  return nullptr;
1846  bool PtrInOperand = bool(Size);
1847 
1848  Start = Tok.getLoc();
1849 
1850  // Rounding mode operand.
1851  if (getLexer().is(AsmToken::LCurly))
1852  return ParseRoundingModeOp(Start);
1853 
1854  // Register operand.
1855  unsigned RegNo = 0;
1856  if (Tok.is(AsmToken::Identifier) && !ParseRegister(RegNo, Start, End)) {
1857  if (RegNo == X86::RIP)
1858  return ErrorOperand(Start, "rip can only be used as a base register");
1859  // A Register followed by ':' is considered a segment override
1860  if (Tok.isNot(AsmToken::Colon))
1861  return !PtrInOperand ? X86Operand::CreateReg(RegNo, Start, End) :
1862  ErrorOperand(Start, "expected memory operand after 'ptr', "
1863  "found register operand instead");
1864  // An alleged segment override. check if we have a valid segment register
1865  if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo))
1866  return ErrorOperand(Start, "invalid segment register");
1867  // Eat ':' and update Start location
1868  Start = Lex().getLoc();
1869  }
1870 
1871  // Immediates and Memory
1872  IntelExprStateMachine SM;
1873  if (ParseIntelExpression(SM, End))
1874  return nullptr;
1875 
1876  if (isParsingInlineAsm())
1877  RewriteIntelExpression(SM, Start, Tok.getLoc());
1878 
1879  int64_t Imm = SM.getImm();
1880  const MCExpr *Disp = SM.getSym();
1881  const MCExpr *ImmDisp = MCConstantExpr::create(Imm, getContext());
1882  if (Disp && Imm)
1883  Disp = MCBinaryExpr::createAdd(Disp, ImmDisp, getContext());
1884  if (!Disp)
1885  Disp = ImmDisp;
1886 
1887  // RegNo != 0 specifies a valid segment register,
1888  // and we are parsing a segment override
1889  if (!SM.isMemExpr() && !RegNo)
1890  return X86Operand::CreateImm(Disp, Start, End);
1891 
1892  StringRef ErrMsg;
1893  unsigned BaseReg = SM.getBaseReg();
1894  unsigned IndexReg = SM.getIndexReg();
1895  unsigned Scale = SM.getScale();
1896 
1897  if (Scale == 0 && BaseReg != X86::ESP && BaseReg != X86::RSP &&
1898  (IndexReg == X86::ESP || IndexReg == X86::RSP))
1899  std::swap(BaseReg, IndexReg);
1900 
1901  // If BaseReg is a vector register and IndexReg is not, swap them unless
1902  // Scale was specified in which case it would be an error.
1903  if (Scale == 0 &&
1904  !(X86MCRegisterClasses[X86::VR128XRegClassID].contains(IndexReg) ||
1905  X86MCRegisterClasses[X86::VR256XRegClassID].contains(IndexReg) ||
1906  X86MCRegisterClasses[X86::VR512RegClassID].contains(IndexReg)) &&
1907  (X86MCRegisterClasses[X86::VR128XRegClassID].contains(BaseReg) ||
1908  X86MCRegisterClasses[X86::VR256XRegClassID].contains(BaseReg) ||
1909  X86MCRegisterClasses[X86::VR512RegClassID].contains(BaseReg)))
1910  std::swap(BaseReg, IndexReg);
1911 
1912  if (Scale != 0 &&
1913  X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg))
1914  return ErrorOperand(Start, "16-bit addresses cannot have a scale");
1915 
1916  // If there was no explicit scale specified, change it to 1.
1917  if (Scale == 0)
1918  Scale = 1;
1919 
1920  // If this is a 16-bit addressing mode with the base and index in the wrong
1921  // order, swap them so CheckBaseRegAndIndexRegAndScale doesn't fail. It is
1922  // shared with att syntax where order matters.
1923  if ((BaseReg == X86::SI || BaseReg == X86::DI) &&
1924  (IndexReg == X86::BX || IndexReg == X86::BP))
1925  std::swap(BaseReg, IndexReg);
1926 
1927  if ((BaseReg || IndexReg) &&
1928  CheckBaseRegAndIndexRegAndScale(BaseReg, IndexReg, Scale, is64BitMode(),
1929  ErrMsg))
1930  return ErrorOperand(Start, ErrMsg);
1931  if (isParsingInlineAsm())
1932  return CreateMemForInlineAsm(RegNo, Disp, BaseReg, IndexReg,
1933  Scale, Start, End, Size, SM.getSymName(),
1934  SM.getIdentifierInfo());
1935  if (!(BaseReg || IndexReg || RegNo))
1936  return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size);
1937  return X86Operand::CreateMem(getPointerWidth(), RegNo, Disp,
1938  BaseReg, IndexReg, Scale, Start, End, Size);
1939 }
1940 
1941 std::unique_ptr<X86Operand> X86AsmParser::ParseATTOperand() {
1942  MCAsmParser &Parser = getParser();
1943  switch (getLexer().getKind()) {
1944  case AsmToken::Dollar: {
1945  // $42 or $ID -> immediate.
1946  SMLoc Start = Parser.getTok().getLoc(), End;
1947  Parser.Lex();
1948  const MCExpr *Val;
1949  // This is an immediate, so we should not parse a register. Do a precheck
1950  // for '%' to supercede intra-register parse errors.
1951  SMLoc L = Parser.getTok().getLoc();
1952  if (check(getLexer().is(AsmToken::Percent), L,
1953  "expected immediate expression") ||
1954  getParser().parseExpression(Val, End) ||
1955  check(isa<X86MCExpr>(Val), L, "expected immediate expression"))
1956  return nullptr;
1957  return X86Operand::CreateImm(Val, Start, End);
1958  }
1959  case AsmToken::LCurly: {
1960  SMLoc Start = Parser.getTok().getLoc();
1961  return ParseRoundingModeOp(Start);
1962  }
1963  default: {
1964  // This a memory operand or a register. We have some parsing complications
1965  // as a '(' may be part of an immediate expression or the addressing mode
1966  // block. This is complicated by the fact that an assembler-level variable
1967  // may refer either to a register or an immediate expression.
1968 
1969  SMLoc Loc = Parser.getTok().getLoc(), EndLoc;
1970  const MCExpr *Expr = nullptr;
1971  unsigned Reg = 0;
1972  if (getLexer().isNot(AsmToken::LParen)) {
1973  // No '(' so this is either a displacement expression or a register.
1974  if (Parser.parseExpression(Expr, EndLoc))
1975  return nullptr;
1976  if (auto *RE = dyn_cast<X86MCExpr>(Expr)) {
1977  // Segment Register. Reset Expr and copy value to register.
1978  Expr = nullptr;
1979  Reg = RE->getRegNo();
1980 
1981  // Sanity check register.
1982  if (Reg == X86::EIZ || Reg == X86::RIZ)
1983  return ErrorOperand(
1984  Loc, "%eiz and %riz can only be used as index registers",
1985  SMRange(Loc, EndLoc));
1986  if (Reg == X86::RIP)
1987  return ErrorOperand(Loc, "%rip can only be used as a base register",
1988  SMRange(Loc, EndLoc));
1989  // Return register that are not segment prefixes immediately.
1990  if (!Parser.parseOptionalToken(AsmToken::Colon))
1991  return X86Operand::CreateReg(Reg, Loc, EndLoc);
1992  if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(Reg))
1993  return ErrorOperand(Loc, "invalid segment register");
1994  }
1995  }
1996  // This is a Memory operand.
1997  return ParseMemOperand(Reg, Expr, Loc, EndLoc);
1998  }
1999  }
2000 }
2001 
2002 // true on failure, false otherwise
2003 // If no {z} mark was found - Parser doesn't advance
2004 bool X86AsmParser::ParseZ(std::unique_ptr<X86Operand> &Z,
2005  const SMLoc &StartLoc) {
2006  MCAsmParser &Parser = getParser();
2007  // Assuming we are just pass the '{' mark, quering the next token
2008  // Searched for {z}, but none was found. Return false, as no parsing error was
2009  // encountered
2010  if (!(getLexer().is(AsmToken::Identifier) &&
2011  (getLexer().getTok().getIdentifier() == "z")))
2012  return false;
2013  Parser.Lex(); // Eat z
2014  // Query and eat the '}' mark
2015  if (!getLexer().is(AsmToken::RCurly))
2016  return Error(getLexer().getLoc(), "Expected } at this point");
2017  Parser.Lex(); // Eat '}'
2018  // Assign Z with the {z} mark opernad
2019  Z = X86Operand::CreateToken("{z}", StartLoc);
2020  return false;
2021 }
2022 
2023 // true on failure, false otherwise
2024 bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands,
2025  const MCParsedAsmOperand &Op) {
2026  MCAsmParser &Parser = getParser();
2027  if (getLexer().is(AsmToken::LCurly)) {
2028  // Eat "{" and mark the current place.
2029  const SMLoc consumedToken = consumeToken();
2030  // Distinguish {1to<NUM>} from {%k<NUM>}.
2031  if(getLexer().is(AsmToken::Integer)) {
2032  // Parse memory broadcasting ({1to<NUM>}).
2033  if (getLexer().getTok().getIntVal() != 1)
2034  return TokError("Expected 1to<NUM> at this point");
2035  Parser.Lex(); // Eat "1" of 1to8
2036  if (!getLexer().is(AsmToken::Identifier) ||
2037  !getLexer().getTok().getIdentifier().startswith("to"))
2038  return TokError("Expected 1to<NUM> at this point");
2039  // Recognize only reasonable suffixes.
2040  const char *BroadcastPrimitive =
2041  StringSwitch<const char*>(getLexer().getTok().getIdentifier())
2042  .Case("to2", "{1to2}")
2043  .Case("to4", "{1to4}")
2044  .Case("to8", "{1to8}")
2045  .Case("to16", "{1to16}")
2046  .Default(nullptr);
2047  if (!BroadcastPrimitive)
2048  return TokError("Invalid memory broadcast primitive.");
2049  Parser.Lex(); // Eat "toN" of 1toN
2050  if (!getLexer().is(AsmToken::RCurly))
2051  return TokError("Expected } at this point");
2052  Parser.Lex(); // Eat "}"
2053  Operands.push_back(X86Operand::CreateToken(BroadcastPrimitive,
2054  consumedToken));
2055  // No AVX512 specific primitives can pass
2056  // after memory broadcasting, so return.
2057  return false;
2058  } else {
2059  // Parse either {k}{z}, {z}{k}, {k} or {z}
2060  // last one have no meaning, but GCC accepts it
2061  // Currently, we're just pass a '{' mark
2062  std::unique_ptr<X86Operand> Z;
2063  if (ParseZ(Z, consumedToken))
2064  return true;
2065  // Reaching here means that parsing of the allegadly '{z}' mark yielded
2066  // no errors.
2067  // Query for the need of further parsing for a {%k<NUM>} mark
2068  if (!Z || getLexer().is(AsmToken::LCurly)) {
2069  SMLoc StartLoc = Z ? consumeToken() : consumedToken;
2070  // Parse an op-mask register mark ({%k<NUM>}), which is now to be
2071  // expected
2072  unsigned RegNo;
2073  SMLoc RegLoc;
2074  if (!ParseRegister(RegNo, RegLoc, StartLoc) &&
2075  X86MCRegisterClasses[X86::VK1RegClassID].contains(RegNo)) {
2076  if (RegNo == X86::K0)
2077  return Error(RegLoc, "Register k0 can't be used as write mask");
2078  if (!getLexer().is(AsmToken::RCurly))
2079  return Error(getLexer().getLoc(), "Expected } at this point");
2080  Operands.push_back(X86Operand::CreateToken("{", StartLoc));
2081  Operands.push_back(
2082  X86Operand::CreateReg(RegNo, StartLoc, StartLoc));
2083  Operands.push_back(X86Operand::CreateToken("}", consumeToken()));
2084  } else
2085  return Error(getLexer().getLoc(),
2086  "Expected an op-mask register at this point");
2087  // {%k<NUM>} mark is found, inquire for {z}
2088  if (getLexer().is(AsmToken::LCurly) && !Z) {
2089  // Have we've found a parsing error, or found no (expected) {z} mark
2090  // - report an error
2091  if (ParseZ(Z, consumeToken()) || !Z)
2092  return Error(getLexer().getLoc(),
2093  "Expected a {z} mark at this point");
2094 
2095  }
2096  // '{z}' on its own is meaningless, hence should be ignored.
2097  // on the contrary - have it been accompanied by a K register,
2098  // allow it.
2099  if (Z)
2100  Operands.push_back(std::move(Z));
2101  }
2102  }
2103  }
2104  return false;
2105 }
2106 
2107 /// ParseMemOperand: 'seg : disp(basereg, indexreg, scale)'. The '%ds:' prefix
2108 /// has already been parsed if present. disp may be provided as well.
2109 std::unique_ptr<X86Operand> X86AsmParser::ParseMemOperand(unsigned SegReg,
2110  const MCExpr *&Disp,
2111  const SMLoc &StartLoc,
2112  SMLoc &EndLoc) {
2113  MCAsmParser &Parser = getParser();
2114  SMLoc Loc;
2115  // Based on the initial passed values, we may be in any of these cases, we are
2116  // in one of these cases (with current position (*)):
2117 
2118  // 1. seg : * disp (base-index-scale-expr)
2119  // 2. seg : *(disp) (base-index-scale-expr)
2120  // 3. seg : *(base-index-scale-expr)
2121  // 4. disp *(base-index-scale-expr)
2122  // 5. *(disp) (base-index-scale-expr)
2123  // 6. *(base-index-scale-expr)
2124  // 7. disp *
2125  // 8. *(disp)
2126 
2127  // If we do not have an displacement yet, check if we're in cases 4 or 6 by
2128  // checking if the first object after the parenthesis is a register (or an
2129  // identifier referring to a register) and parse the displacement or default
2130  // to 0 as appropriate.
2131  auto isAtMemOperand = [this]() {
2132  if (this->getLexer().isNot(AsmToken::LParen))
2133  return false;
2134  AsmToken Buf[2];
2135  StringRef Id;
2136  auto TokCount = this->getLexer().peekTokens(Buf, true);
2137  if (TokCount == 0)
2138  return false;
2139  switch (Buf[0].getKind()) {
2140  case AsmToken::Percent:
2141  case AsmToken::Comma:
2142  return true;
2143  // These lower cases are doing a peekIdentifier.
2144  case AsmToken::At:
2145  case AsmToken::Dollar:
2146  if ((TokCount > 1) &&
2147  (Buf[1].is(AsmToken::Identifier) || Buf[1].is(AsmToken::String)) &&
2148  (Buf[0].getLoc().getPointer() + 1 == Buf[1].getLoc().getPointer()))
2149  Id = StringRef(Buf[0].getLoc().getPointer(),
2150  Buf[1].getIdentifier().size() + 1);
2151  break;
2152  case AsmToken::Identifier:
2153  case AsmToken::String:
2154  Id = Buf[0].getIdentifier();
2155  break;
2156  default:
2157  return false;
2158  }
2159  // We have an ID. Check if it is bound to a register.
2160  if (!Id.empty()) {
2161  MCSymbol *Sym = this->getContext().getOrCreateSymbol(Id);
2162  if (Sym->isVariable()) {
2163  auto V = Sym->getVariableValue(/*SetUsed*/ false);
2164  return isa<X86MCExpr>(V);
2165  }
2166  }
2167  return false;
2168  };
2169 
2170  if (!Disp) {
2171  // Parse immediate if we're not at a mem operand yet.
2172  if (!isAtMemOperand()) {
2173  if (Parser.parseTokenLoc(Loc) || Parser.parseExpression(Disp, EndLoc))
2174  return nullptr;
2175  assert(!isa<X86MCExpr>(Disp) && "Expected non-register here.");
2176  } else {
2177  // Disp is implicitly zero if we haven't parsed it yet.
2178  Disp = MCConstantExpr::create(0, Parser.getContext());
2179  }
2180  }
2181 
2182  // We are now either at the end of the operand or at the '(' at the start of a
2183  // base-index-scale-expr.
2184 
2185  if (!parseOptionalToken(AsmToken::LParen)) {
2186  if (SegReg == 0)
2187  return X86Operand::CreateMem(getPointerWidth(), Disp, StartLoc, EndLoc);
2188  return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
2189  StartLoc, EndLoc);
2190  }
2191 
2192  // If we reached here, then eat the '(' and Process
2193  // the rest of the memory operand.
2194  unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
2195  SMLoc BaseLoc = getLexer().getLoc();
2196  const MCExpr *E;
2197  StringRef ErrMsg;
2198 
2199  // Parse BaseReg if one is provided.
2200  if (getLexer().isNot(AsmToken::Comma) && getLexer().isNot(AsmToken::RParen)) {
2201  if (Parser.parseExpression(E, EndLoc) ||
2202  check(!isa<X86MCExpr>(E), BaseLoc, "expected register here"))
2203  return nullptr;
2204 
2205  // Sanity check register.
2206  BaseReg = cast<X86MCExpr>(E)->getRegNo();
2207  if (BaseReg == X86::EIZ || BaseReg == X86::RIZ)
2208  return ErrorOperand(BaseLoc,
2209  "eiz and riz can only be used as index registers",
2210  SMRange(BaseLoc, EndLoc));
2211  }
2212 
2213  if (parseOptionalToken(AsmToken::Comma)) {
2214  // Following the comma we should have either an index register, or a scale
2215  // value. We don't support the later form, but we want to parse it
2216  // correctly.
2217  //
2218  // Even though it would be completely consistent to support syntax like
2219  // "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this.
2220  if (getLexer().isNot(AsmToken::RParen)) {
2221  if (Parser.parseTokenLoc(Loc) || Parser.parseExpression(E, EndLoc))
2222  return nullptr;
2223 
2224  if (!isa<X86MCExpr>(E)) {
2225  // We've parsed an unexpected Scale Value instead of an index
2226  // register. Interpret it as an absolute.
2227  int64_t ScaleVal;
2228  if (!E->evaluateAsAbsolute(ScaleVal, getStreamer().getAssemblerPtr()))
2229  return ErrorOperand(Loc, "expected absolute expression");
2230  if (ScaleVal != 1)
2231  Warning(Loc, "scale factor without index register is ignored");
2232  Scale = 1;
2233  } else { // IndexReg Found.
2234  IndexReg = cast<X86MCExpr>(E)->getRegNo();
2235 
2236  if (BaseReg == X86::RIP)
2237  return ErrorOperand(
2238  Loc, "%rip as base register can not have an index register");
2239  if (IndexReg == X86::RIP)
2240  return ErrorOperand(Loc, "%rip is not allowed as an index register");
2241 
2242  if (parseOptionalToken(AsmToken::Comma)) {
2243  // Parse the scale amount:
2244  // ::= ',' [scale-expression]
2245 
2246  // A scale amount without an index is ignored.
2247  if (getLexer().isNot(AsmToken::RParen)) {
2248  int64_t ScaleVal;
2249  if (Parser.parseTokenLoc(Loc) ||
2250  Parser.parseAbsoluteExpression(ScaleVal))
2251  return ErrorOperand(Loc, "expected scale expression");
2252  Scale = (unsigned)ScaleVal;
2253  // Validate the scale amount.
2254  if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
2255  Scale != 1)
2256  return ErrorOperand(Loc,
2257  "scale factor in 16-bit address must be 1");
2258  if (checkScale(Scale, ErrMsg))
2259  return ErrorOperand(Loc, ErrMsg);
2260  }
2261  }
2262  }
2263  }
2264  }
2265 
2266  // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
2267  if (parseToken(AsmToken::RParen, "unexpected token in memory operand"))
2268  return nullptr;
2269 
2270  // This is to support otherwise illegal operand (%dx) found in various
2271  // unofficial manuals examples (e.g. "out[s]?[bwl]? %al, (%dx)") and must now
2272  // be supported. Mark such DX variants separately fix only in special cases.
2273  if (BaseReg == X86::DX && IndexReg == 0 && Scale == 1 && SegReg == 0 &&
2274  isa<MCConstantExpr>(Disp) && cast<MCConstantExpr>(Disp)->getValue() == 0)
2275  return X86Operand::CreateDXReg(BaseLoc, BaseLoc);
2276 
2277  if (CheckBaseRegAndIndexRegAndScale(BaseReg, IndexReg, Scale, is64BitMode(),
2278  ErrMsg))
2279  return ErrorOperand(BaseLoc, ErrMsg);
2280 
2281  if (SegReg || BaseReg || IndexReg)
2282  return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
2283  IndexReg, Scale, StartLoc, EndLoc);
2284  return X86Operand::CreateMem(getPointerWidth(), Disp, StartLoc, EndLoc);
2285 }
2286 
2287 // Parse either a standard primary expression or a register.
2288 bool X86AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
2289  MCAsmParser &Parser = getParser();
2290  // See if this is a register first.
2291  if (getTok().is(AsmToken::Percent) ||
2292  (isParsingIntelSyntax() && getTok().is(AsmToken::Identifier) &&
2293  MatchRegisterName(Parser.getTok().getString()))) {
2294  SMLoc StartLoc = Parser.getTok().getLoc();
2295  unsigned RegNo;
2296  if (ParseRegister(RegNo, StartLoc, EndLoc))
2297  return true;
2298  Res = X86MCExpr::create(RegNo, Parser.getContext());
2299  return false;
2300  }
2301  return Parser.parsePrimaryExpr(Res, EndLoc);
2302 }
2303 
2304 bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2305  SMLoc NameLoc, OperandVector &Operands) {
2306  MCAsmParser &Parser = getParser();
2307  InstInfo = &Info;
2308  StringRef PatchedName = Name;
2309 
2310  if ((Name.equals("jmp") || Name.equals("jc") || Name.equals("jz")) &&
2311  isParsingIntelSyntax() && isParsingInlineAsm()) {
2312  StringRef NextTok = Parser.getTok().getString();
2313  if (NextTok == "short") {
2314  SMLoc NameEndLoc =
2315  NameLoc.getFromPointer(NameLoc.getPointer() + Name.size());
2316  // Eat the short keyword
2317  Parser.Lex();
2318  // MS ignores the short keyword, it determines the jmp type based
2319  // on the distance of the label
2320  InstInfo->AsmRewrites->emplace_back(AOK_Skip, NameEndLoc,
2321  NextTok.size() + 1);
2322  }
2323  }
2324 
2325  // FIXME: Hack to recognize setneb as setne.
2326  if (PatchedName.startswith("set") && PatchedName.endswith("b") &&
2327  PatchedName != "setb" && PatchedName != "setnb")
2328  PatchedName = PatchedName.substr(0, Name.size()-1);
2329 
2330  // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}.
2331  if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) &&
2332  (PatchedName.endswith("ss") || PatchedName.endswith("sd") ||
2333  PatchedName.endswith("ps") || PatchedName.endswith("pd"))) {
2334  bool IsVCMP = PatchedName[0] == 'v';
2335  unsigned CCIdx = IsVCMP ? 4 : 3;
2336  unsigned ComparisonCode = StringSwitch<unsigned>(
2337  PatchedName.slice(CCIdx, PatchedName.size() - 2))
2338  .Case("eq", 0x00)
2339  .Case("eq_oq", 0x00)
2340  .Case("lt", 0x01)
2341  .Case("lt_os", 0x01)
2342  .Case("le", 0x02)
2343  .Case("le_os", 0x02)
2344  .Case("unord", 0x03)
2345  .Case("unord_q", 0x03)
2346  .Case("neq", 0x04)
2347  .Case("neq_uq", 0x04)
2348  .Case("nlt", 0x05)
2349  .Case("nlt_us", 0x05)
2350  .Case("nle", 0x06)
2351  .Case("nle_us", 0x06)
2352  .Case("ord", 0x07)
2353  .Case("ord_q", 0x07)
2354  /* AVX only from here */
2355  .Case("eq_uq", 0x08)
2356  .Case("nge", 0x09)
2357  .Case("nge_us", 0x09)
2358  .Case("ngt", 0x0A)
2359  .Case("ngt_us", 0x0A)
2360  .Case("false", 0x0B)
2361  .Case("false_oq", 0x0B)
2362  .Case("neq_oq", 0x0C)
2363  .Case("ge", 0x0D)
2364  .Case("ge_os", 0x0D)
2365  .Case("gt", 0x0E)
2366  .Case("gt_os", 0x0E)
2367  .Case("true", 0x0F)
2368  .Case("true_uq", 0x0F)
2369  .Case("eq_os", 0x10)
2370  .Case("lt_oq", 0x11)
2371  .Case("le_oq", 0x12)
2372  .Case("unord_s", 0x13)
2373  .Case("neq_us", 0x14)
2374  .Case("nlt_uq", 0x15)
2375  .Case("nle_uq", 0x16)
2376  .Case("ord_s", 0x17)
2377  .Case("eq_us", 0x18)
2378  .Case("nge_uq", 0x19)
2379  .Case("ngt_uq", 0x1A)
2380  .Case("false_os", 0x1B)
2381  .Case("neq_os", 0x1C)
2382  .Case("ge_oq", 0x1D)
2383  .Case("gt_oq", 0x1E)
2384  .Case("true_us", 0x1F)
2385  .Default(~0U);
2386  if (ComparisonCode != ~0U && (IsVCMP || ComparisonCode < 8)) {
2387 
2388  Operands.push_back(X86Operand::CreateToken(PatchedName.slice(0, CCIdx),
2389  NameLoc));
2390 
2391  const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2392  getParser().getContext());
2393  Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2394 
2395  PatchedName = PatchedName.substr(PatchedName.size() - 2);
2396  }
2397  }
2398 
2399  // FIXME: Hack to recognize vpcmp<comparison code>{ub,uw,ud,uq,b,w,d,q}.
2400  if (PatchedName.startswith("vpcmp") &&
2401  (PatchedName.endswith("b") || PatchedName.endswith("w") ||
2402  PatchedName.endswith("d") || PatchedName.endswith("q"))) {
2403  unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1;
2404  unsigned ComparisonCode = StringSwitch<unsigned>(
2405  PatchedName.slice(5, PatchedName.size() - CCIdx))
2406  .Case("eq", 0x0) // Only allowed on unsigned. Checked below.
2407  .Case("lt", 0x1)
2408  .Case("le", 0x2)
2409  //.Case("false", 0x3) // Not a documented alias.
2410  .Case("neq", 0x4)
2411  .Case("nlt", 0x5)
2412  .Case("nle", 0x6)
2413  //.Case("true", 0x7) // Not a documented alias.
2414  .Default(~0U);
2415  if (ComparisonCode != ~0U && (ComparisonCode != 0 || CCIdx == 2)) {
2416  Operands.push_back(X86Operand::CreateToken("vpcmp", NameLoc));
2417 
2418  const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2419  getParser().getContext());
2420  Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2421 
2422  PatchedName = PatchedName.substr(PatchedName.size() - CCIdx);
2423  }
2424  }
2425 
2426  // FIXME: Hack to recognize vpcom<comparison code>{ub,uw,ud,uq,b,w,d,q}.
2427  if (PatchedName.startswith("vpcom") &&
2428  (PatchedName.endswith("b") || PatchedName.endswith("w") ||
2429  PatchedName.endswith("d") || PatchedName.endswith("q"))) {
2430  unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1;
2431  unsigned ComparisonCode = StringSwitch<unsigned>(
2432  PatchedName.slice(5, PatchedName.size() - CCIdx))
2433  .Case("lt", 0x0)
2434  .Case("le", 0x1)
2435  .Case("gt", 0x2)
2436  .Case("ge", 0x3)
2437  .Case("eq", 0x4)
2438  .Case("neq", 0x5)
2439  .Case("false", 0x6)
2440  .Case("true", 0x7)
2441  .Default(~0U);
2442  if (ComparisonCode != ~0U) {
2443  Operands.push_back(X86Operand::CreateToken("vpcom", NameLoc));
2444 
2445  const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2446  getParser().getContext());
2447  Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2448 
2449  PatchedName = PatchedName.substr(PatchedName.size() - CCIdx);
2450  }
2451  }
2452 
2453 
2454  // Determine whether this is an instruction prefix.
2455  // FIXME:
2456  // Enhance prefixes integrity robustness. for example, following forms
2457  // are currently tolerated:
2458  // repz repnz <insn> ; GAS errors for the use of two similar prefixes
2459  // lock addq %rax, %rbx ; Destination operand must be of memory type
2460  // xacquire <insn> ; xacquire must be accompanied by 'lock'
2462  .Cases("rex64", "data32", "data16", true)
2463  .Cases("xacquire", "xrelease", true)
2464  .Cases("acquire", "release", isParsingIntelSyntax())
2465  .Default(false);
2466 
2467  auto isLockRepeatNtPrefix = [](StringRef N) {
2468  return StringSwitch<bool>(N)
2469  .Cases("lock", "rep", "repe", "repz", "repne", "repnz", "notrack", true)
2470  .Default(false);
2471  };
2472 
2473  bool CurlyAsEndOfStatement = false;
2474 
2475  unsigned Flags = X86::IP_NO_PREFIX;
2476  while (isLockRepeatNtPrefix(Name.lower())) {
2477  unsigned Prefix =
2479  .Cases("lock", "lock", X86::IP_HAS_LOCK)
2480  .Cases("rep", "repe", "repz", X86::IP_HAS_REPEAT)
2481  .Cases("repne", "repnz", X86::IP_HAS_REPEAT_NE)
2482  .Cases("notrack", "notrack", X86::IP_HAS_NOTRACK)
2483  .Default(X86::IP_NO_PREFIX); // Invalid prefix (impossible)
2484  Flags |= Prefix;
2485  if (getLexer().is(AsmToken::EndOfStatement)) {
2486  // We don't have real instr with the given prefix
2487  // let's use the prefix as the instr.
2488  // TODO: there could be several prefixes one after another
2489  Flags = X86::IP_NO_PREFIX;
2490  break;
2491  }
2492  Name = Parser.getTok().getString();
2493  Parser.Lex(); // eat the prefix
2494  // Hack: we could have something like "rep # some comment" or
2495  // "lock; cmpxchg16b $1" or "lock\0A\09incl" or "lock/incl"
2496  while (Name.startswith(";") || Name.startswith("\n") ||
2497  Name.startswith("#") || Name.startswith("\t") ||
2498  Name.startswith("/")) {
2499  Name = Parser.getTok().getString();
2500  Parser.Lex(); // go to next prefix or instr
2501  }
2502  }
2503 
2504  if (Flags)
2505  PatchedName = Name;
2506 
2507  // Hacks to handle 'data16' and 'data32'
2508  if (PatchedName == "data16" && is16BitMode()) {
2509  return Error(NameLoc, "redundant data16 prefix");
2510  }
2511  if (PatchedName == "data32") {
2512  if (is32BitMode())
2513  return Error(NameLoc, "redundant data32 prefix");
2514  if (is64BitMode())
2515  return Error(NameLoc, "'data32' is not supported in 64-bit mode");
2516  // Hack to 'data16' for the table lookup.
2517  PatchedName = "data16";
2518  }
2519 
2520  Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
2521 
2522  // This does the actual operand parsing. Don't parse any more if we have a
2523  // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we
2524  // just want to parse the "lock" as the first instruction and the "incl" as
2525  // the next one.
2526  if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) {
2527  // Parse '*' modifier.
2528  if (getLexer().is(AsmToken::Star))
2529  Operands.push_back(X86Operand::CreateToken("*", consumeToken()));
2530 
2531  // Read the operands.
2532  while(1) {
2533  if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
2534  Operands.push_back(std::move(Op));
2535  if (HandleAVX512Operand(Operands, *Operands.back()))
2536  return true;
2537  } else {
2538  return true;
2539  }
2540  // check for comma and eat it
2541  if (getLexer().is(AsmToken::Comma))
2542  Parser.Lex();
2543  else
2544  break;
2545  }
2546 
2547  // In MS inline asm curly braces mark the beginning/end of a block,
2548  // therefore they should be interepreted as end of statement
2549  CurlyAsEndOfStatement =
2550  isParsingIntelSyntax() && isParsingInlineAsm() &&
2551  (getLexer().is(AsmToken::LCurly) || getLexer().is(AsmToken::RCurly));
2552  if (getLexer().isNot(AsmToken::EndOfStatement) && !CurlyAsEndOfStatement)
2553  return TokError("unexpected token in argument list");
2554  }
2555 
2556  // Consume the EndOfStatement or the prefix separator Slash
2557  if (getLexer().is(AsmToken::EndOfStatement) ||
2558  (isPrefix && getLexer().is(AsmToken::Slash)))
2559  Parser.Lex();
2560  else if (CurlyAsEndOfStatement)
2561  // Add an actual EndOfStatement before the curly brace
2562  Info.AsmRewrites->emplace_back(AOK_EndOfStatement,
2563  getLexer().getTok().getLoc(), 0);
2564 
2565  // This is for gas compatibility and cannot be done in td.
2566  // Adding "p" for some floating point with no argument.
2567  // For example: fsub --> fsubp
2568  bool IsFp =
2569  Name == "fsub" || Name == "fdiv" || Name == "fsubr" || Name == "fdivr";
2570  if (IsFp && Operands.size() == 1) {
2571  const char *Repl = StringSwitch<const char *>(Name)
2572  .Case("fsub", "fsubp")
2573  .Case("fdiv", "fdivp")
2574  .Case("fsubr", "fsubrp")
2575  .Case("fdivr", "fdivrp");
2576  static_cast<X86Operand &>(*Operands[0]).setTokenValue(Repl);
2577  }
2578 
2579  // Moving a 32 or 16 bit value into a segment register has the same
2580  // behavior. Modify such instructions to always take shorter form.
2581  if ((Name == "mov" || Name == "movw" || Name == "movl") &&
2582  (Operands.size() == 3)) {
2583  X86Operand &Op1 = (X86Operand &)*Operands[1];
2584  X86Operand &Op2 = (X86Operand &)*Operands[2];
2585  SMLoc Loc = Op1.getEndLoc();
2586  if (Op1.isReg() && Op2.isReg() &&
2587  X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(
2588  Op2.getReg()) &&
2589  (X86MCRegisterClasses[X86::GR16RegClassID].contains(Op1.getReg()) ||
2590  X86MCRegisterClasses[X86::GR32RegClassID].contains(Op1.getReg()))) {
2591  // Change instruction name to match new instruction.
2592  if (Name != "mov" && Name[3] == (is16BitMode() ? 'l' : 'w')) {
2593  Name = is16BitMode() ? "movw" : "movl";
2594  Operands[0] = X86Operand::CreateToken(Name, NameLoc);
2595  }
2596  // Select the correct equivalent 16-/32-bit source register.
2597  unsigned Reg =
2598  getX86SubSuperRegisterOrZero(Op1.getReg(), is16BitMode() ? 16 : 32);
2599  Operands[1] = X86Operand::CreateReg(Reg, Loc, Loc);
2600  }
2601  }
2602 
2603  // This is a terrible hack to handle "out[s]?[bwl]? %al, (%dx)" ->
2604  // "outb %al, %dx". Out doesn't take a memory form, but this is a widely
2605  // documented form in various unofficial manuals, so a lot of code uses it.
2606  if ((Name == "outb" || Name == "outsb" || Name == "outw" || Name == "outsw" ||
2607  Name == "outl" || Name == "outsl" || Name == "out" || Name == "outs") &&
2608  Operands.size() == 3) {
2609  X86Operand &Op = (X86Operand &)*Operands.back();
2610  if (Op.isDXReg())
2611  Operands.back() = X86Operand::CreateReg(X86::DX, Op.getStartLoc(),
2612  Op.getEndLoc());
2613  }
2614  // Same hack for "in[s]?[bwl]? (%dx), %al" -> "inb %dx, %al".
2615  if ((Name == "inb" || Name == "insb" || Name == "inw" || Name == "insw" ||
2616  Name == "inl" || Name == "insl" || Name == "in" || Name == "ins") &&
2617  Operands.size() == 3) {
2618  X86Operand &Op = (X86Operand &)*Operands[1];
2619  if (Op.isDXReg())
2620  Operands[1] = X86Operand::CreateReg(X86::DX, Op.getStartLoc(),
2621  Op.getEndLoc());
2622  }
2623 
2625  bool HadVerifyError = false;
2626 
2627  // Append default arguments to "ins[bwld]"
2628  if (Name.startswith("ins") &&
2629  (Operands.size() == 1 || Operands.size() == 3) &&
2630  (Name == "insb" || Name == "insw" || Name == "insl" || Name == "insd" ||
2631  Name == "ins")) {
2632 
2633  AddDefaultSrcDestOperands(TmpOperands,
2634  X86Operand::CreateReg(X86::DX, NameLoc, NameLoc),
2635  DefaultMemDIOperand(NameLoc));
2636  HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2637  }
2638 
2639  // Append default arguments to "outs[bwld]"
2640  if (Name.startswith("outs") &&
2641  (Operands.size() == 1 || Operands.size() == 3) &&
2642  (Name == "outsb" || Name == "outsw" || Name == "outsl" ||
2643  Name == "outsd" || Name == "outs")) {
2644  AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
2645  X86Operand::CreateReg(X86::DX, NameLoc, NameLoc));
2646  HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2647  }
2648 
2649  // Transform "lods[bwlq]" into "lods[bwlq] ($SIREG)" for appropriate
2650  // values of $SIREG according to the mode. It would be nice if this
2651  // could be achieved with InstAlias in the tables.
2652  if (Name.startswith("lods") &&
2653  (Operands.size() == 1 || Operands.size() == 2) &&
2654  (Name == "lods" || Name == "lodsb" || Name == "lodsw" ||
2655  Name == "lodsl" || Name == "lodsd" || Name == "lodsq")) {
2656  TmpOperands.push_back(DefaultMemSIOperand(NameLoc));
2657  HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2658  }
2659 
2660  // Transform "stos[bwlq]" into "stos[bwlq] ($DIREG)" for appropriate
2661  // values of $DIREG according to the mode. It would be nice if this
2662  // could be achieved with InstAlias in the tables.
2663  if (Name.startswith("stos") &&
2664  (Operands.size() == 1 || Operands.size() == 2) &&
2665  (Name == "stos" || Name == "stosb" || Name == "stosw" ||
2666  Name == "stosl" || Name == "stosd" || Name == "stosq")) {
2667  TmpOperands.push_back(DefaultMemDIOperand(NameLoc));
2668  HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2669  }
2670 
2671  // Transform "scas[bwlq]" into "scas[bwlq] ($DIREG)" for appropriate
2672  // values of $DIREG according to the mode. It would be nice if this
2673  // could be achieved with InstAlias in the tables.
2674  if (Name.startswith("scas") &&
2675  (Operands.size() == 1 || Operands.size() == 2) &&
2676  (Name == "scas" || Name == "scasb" || Name == "scasw" ||
2677  Name == "scasl" || Name == "scasd" || Name == "scasq")) {
2678  TmpOperands.push_back(DefaultMemDIOperand(NameLoc));
2679  HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2680  }
2681 
2682  // Add default SI and DI operands to "cmps[bwlq]".
2683  if (Name.startswith("cmps") &&
2684  (Operands.size() == 1 || Operands.size() == 3) &&
2685  (Name == "cmps" || Name == "cmpsb" || Name == "cmpsw" ||
2686  Name == "cmpsl" || Name == "cmpsd" || Name == "cmpsq")) {
2687  AddDefaultSrcDestOperands(TmpOperands, DefaultMemDIOperand(NameLoc),
2688  DefaultMemSIOperand(NameLoc));
2689  HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2690  }
2691 
2692  // Add default SI and DI operands to "movs[bwlq]".
2693  if (((Name.startswith("movs") &&
2694  (Name == "movs" || Name == "movsb" || Name == "movsw" ||
2695  Name == "movsl" || Name == "movsd" || Name == "movsq")) ||
2696  (Name.startswith("smov") &&
2697  (Name == "smov" || Name == "smovb" || Name == "smovw" ||
2698  Name == "smovl" || Name == "smovd" || Name == "smovq"))) &&
2699  (Operands.size() == 1 || Operands.size() == 3)) {
2700  if (Name == "movsd" && Operands.size() == 1 && !isParsingIntelSyntax())
2701  Operands.back() = X86Operand::CreateToken("movsl", NameLoc);
2702  AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
2703  DefaultMemDIOperand(NameLoc));
2704  HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2705  }
2706 
2707  // Check if we encountered an error for one the string insturctions
2708  if (HadVerifyError) {
2709  return HadVerifyError;
2710  }
2711 
2712  // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>. Canonicalize to
2713  // "shift <op>".
2714  if ((Name.startswith("shr") || Name.startswith("sar") ||
2715  Name.startswith("shl") || Name.startswith("sal") ||
2716  Name.startswith("rcl") || Name.startswith("rcr") ||
2717  Name.startswith("rol") || Name.startswith("ror")) &&
2718  Operands.size() == 3) {
2719  if (isParsingIntelSyntax()) {
2720  // Intel syntax
2721  X86Operand &Op1 = static_cast<X86Operand &>(*Operands[2]);
2722  if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2723  cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2724  Operands.pop_back();
2725  } else {
2726  X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2727  if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2728  cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2729  Operands.erase(Operands.begin() + 1);
2730  }
2731  }
2732 
2733  // Transforms "int $3" into "int3" as a size optimization. We can't write an
2734  // instalias with an immediate operand yet.
2735  if (Name == "int" && Operands.size() == 2) {
2736  X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2737  if (Op1.isImm())
2738  if (auto *CE = dyn_cast<MCConstantExpr>(Op1.getImm()))
2739  if (CE->getValue() == 3) {
2740  Operands.erase(Operands.begin() + 1);
2741  static_cast<X86Operand &>(*Operands[0]).setTokenValue("int3");
2742  }
2743  }
2744 
2745  // Transforms "xlat mem8" into "xlatb"
2746  if ((Name == "xlat" || Name == "xlatb") && Operands.size() == 2) {
2747  X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2748  if (Op1.isMem8()) {
2749  Warning(Op1.getStartLoc(), "memory operand is only for determining the "
2750  "size, (R|E)BX will be used for the location");
2751  Operands.pop_back();
2752  static_cast<X86Operand &>(*Operands[0]).setTokenValue("xlatb");
2753  }
2754  }
2755 
2756  if (Flags)
2757  Operands.push_back(X86Operand::CreatePrefix(Flags, NameLoc, NameLoc));
2758  return false;
2759 }
2760 
2761 bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) {
2762  return false;
2763 }
2764 
2765 bool X86AsmParser::validateInstruction(MCInst &Inst, const OperandVector &Ops) {
2766  const MCRegisterInfo *MRI = getContext().getRegisterInfo();
2767 
2768  switch (Inst.getOpcode()) {
2769  case X86::VGATHERDPDYrm:
2770  case X86::VGATHERDPDrm:
2771  case X86::VGATHERDPSYrm:
2772  case X86::VGATHERDPSrm:
2773  case X86::VGATHERQPDYrm:
2774  case X86::VGATHERQPDrm:
2775  case X86::VGATHERQPSYrm:
2776  case X86::VGATHERQPSrm:
2777  case X86::VPGATHERDDYrm:
2778  case X86::VPGATHERDDrm:
2779  case X86::VPGATHERDQYrm:
2780  case X86::VPGATHERDQrm:
2781  case X86::VPGATHERQDYrm:
2782  case X86::VPGATHERQDrm:
2783  case X86::VPGATHERQQYrm:
2784  case X86::VPGATHERQQrm: {
2785  unsigned Dest = MRI->getEncodingValue(Inst.getOperand(0).getReg());
2786  unsigned Mask = MRI->getEncodingValue(Inst.getOperand(1).getReg());
2787  unsigned Index =
2789  if (Dest == Mask || Dest == Index || Mask == Index)
2790  return Warning(Ops[0]->getStartLoc(), "mask, index, and destination "
2791  "registers should be distinct");
2792  break;
2793  }
2794  case X86::VGATHERDPDZ128rm:
2795  case X86::VGATHERDPDZ256rm:
2796  case X86::VGATHERDPDZrm:
2797  case X86::VGATHERDPSZ128rm:
2798  case X86::VGATHERDPSZ256rm:
2799  case X86::VGATHERDPSZrm:
2800  case X86::VGATHERQPDZ128rm:
2801  case X86::VGATHERQPDZ256rm:
2802  case X86::VGATHERQPDZrm:
2803  case X86::VGATHERQPSZ128rm:
2804  case X86::VGATHERQPSZ256rm:
2805  case X86::VGATHERQPSZrm:
2806  case X86::VPGATHERDDZ128rm:
2807  case X86::VPGATHERDDZ256rm:
2808  case X86::VPGATHERDDZrm:
2809  case X86::VPGATHERDQZ128rm:
2810  case X86::VPGATHERDQZ256rm:
2811  case X86::VPGATHERDQZrm:
2812  case X86::VPGATHERQDZ128rm:
2813  case X86::VPGATHERQDZ256rm:
2814  case X86::VPGATHERQDZrm:
2815  case X86::VPGATHERQQZ128rm:
2816  case X86::VPGATHERQQZ256rm:
2817  case X86::VPGATHERQQZrm: {
2818  unsigned Dest = MRI->getEncodingValue(Inst.getOperand(0).getReg());
2819  unsigned Index =
2821  if (Dest == Index)
2822  return Warning(Ops[0]->getStartLoc(), "index and destination registers "
2823  "should be distinct");
2824  break;
2825  }
2826  case X86::V4FMADDPSrm:
2827  case X86::V4FMADDPSrmk:
2828  case X86::V4FMADDPSrmkz:
2829  case X86::V4FMADDSSrm:
2830  case X86::V4FMADDSSrmk:
2831  case X86::V4FMADDSSrmkz:
2832  case X86::V4FNMADDPSrm:
2833  case X86::V4FNMADDPSrmk:
2834  case X86::V4FNMADDPSrmkz:
2835  case X86::V4FNMADDSSrm:
2836  case X86::V4FNMADDSSrmk:
2837  case X86::V4FNMADDSSrmkz:
2838  case X86::VP4DPWSSDSrm:
2839  case X86::VP4DPWSSDSrmk:
2840  case X86::VP4DPWSSDSrmkz:
2841  case X86::VP4DPWSSDrm:
2842  case X86::VP4DPWSSDrmk:
2843  case X86::VP4DPWSSDrmkz: {
2844  unsigned Src2 = Inst.getOperand(Inst.getNumOperands() -
2846  unsigned Src2Enc = MRI->getEncodingValue(Src2);
2847  if (Src2Enc % 4 != 0) {
2849  unsigned GroupStart = (Src2Enc / 4) * 4;
2850  unsigned GroupEnd = GroupStart + 3;
2851  return Warning(Ops[0]->getStartLoc(),
2852  "source register '" + RegName + "' implicitly denotes '" +
2853  RegName.take_front(3) + Twine(GroupStart) + "' to '" +
2854  RegName.take_front(3) + Twine(GroupEnd) +
2855  "' source group");
2856  }
2857  break;
2858  }
2859  }
2860 
2861  return false;
2862 }
2863 
2864 static const char *getSubtargetFeatureName(uint64_t Val);
2865 
2866 void X86AsmParser::EmitInstruction(MCInst &Inst, OperandVector &Operands,
2867  MCStreamer &Out) {
2868  Instrumentation->InstrumentAndEmitInstruction(
2869  Inst, Operands, getContext(), MII, Out,
2870  getParser().shouldPrintSchedInfo());
2871 }
2872 
2873 bool X86AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2874  OperandVector &Operands,
2875  MCStreamer &Out, uint64_t &ErrorInfo,
2876  bool MatchingInlineAsm) {
2877  if (isParsingIntelSyntax())
2878  return MatchAndEmitIntelInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2879  MatchingInlineAsm);
2880  return MatchAndEmitATTInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2881  MatchingInlineAsm);
2882 }
2883 
2884 void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op,
2885  OperandVector &Operands, MCStreamer &Out,
2886  bool MatchingInlineAsm) {
2887  // FIXME: This should be replaced with a real .td file alias mechanism.
2888  // Also, MatchInstructionImpl should actually *do* the EmitInstruction
2889  // call.
2890  const char *Repl = StringSwitch<const char *>(Op.getToken())
2891  .Case("finit", "fninit")
2892  .Case("fsave", "fnsave")
2893  .Case("fstcw", "fnstcw")
2894  .Case("fstcww", "fnstcw")
2895  .Case("fstenv", "fnstenv")
2896  .Case("fstsw", "fnstsw")
2897  .Case("fstsww", "fnstsw")
2898  .Case("fclex", "fnclex")
2899  .Default(nullptr);
2900  if (Repl) {
2901  MCInst Inst;
2902  Inst.setOpcode(X86::WAIT);
2903  Inst.setLoc(IDLoc);
2904  if (!MatchingInlineAsm)
2905  EmitInstruction(Inst, Operands, Out);
2906  Operands[0] = X86Operand::CreateToken(Repl, IDLoc);
2907  }
2908 }
2909 
2910 bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
2911  bool MatchingInlineAsm) {
2912  assert(ErrorInfo && "Unknown missing feature!");
2913  SmallString<126> Msg;
2914  raw_svector_ostream OS(Msg);
2915  OS << "instruction requires:";
2916  uint64_t Mask = 1;
2917  for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
2918  if (ErrorInfo & Mask)
2919  OS << ' ' << getSubtargetFeatureName(ErrorInfo & Mask);
2920  Mask <<= 1;
2921  }
2922  return Error(IDLoc, OS.str(), SMRange(), MatchingInlineAsm);
2923 }
2924 
2925 static unsigned getPrefixes(OperandVector &Operands) {
2926  unsigned Result = 0;
2927  X86Operand &Prefix = static_cast<X86Operand &>(*Operands.back());
2928  if (Prefix.isPrefix()) {
2929  Result = Prefix.getPrefix();
2930  Operands.pop_back();
2931  }
2932  return Result;
2933 }
2934 
2935 bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
2936  OperandVector &Operands,
2937  MCStreamer &Out,
2938  uint64_t &ErrorInfo,
2939  bool MatchingInlineAsm) {
2940  assert(!Operands.empty() && "Unexpect empty operand list!");
2941  X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2942  assert(Op.isToken() && "Leading operand should always be a mnemonic!");
2943  SMRange EmptyRange = None;
2944 
2945  // First, handle aliases that expand to multiple instructions.
2946  MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2947 
2948  bool WasOriginallyInvalidOperand = false;
2949  unsigned Prefixes = getPrefixes(Operands);
2950 
2951  MCInst Inst;
2952 
2953  if (Prefixes)
2954  Inst.setFlags(Prefixes);
2955 
2956  // First, try a direct match.
2957  switch (MatchInstruction(Operands, Inst, ErrorInfo, MatchingInlineAsm,
2958  isParsingIntelSyntax())) {
2959  default: llvm_unreachable("Unexpected match result!");
2960  case Match_Success:
2961  if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
2962  return true;
2963  // Some instructions need post-processing to, for example, tweak which
2964  // encoding is selected. Loop on it while changes happen so the
2965  // individual transformations can chain off each other.
2966  if (!MatchingInlineAsm)
2967  while (processInstruction(Inst, Operands))
2968  ;
2969 
2970  Inst.setLoc(IDLoc);
2971  if (!MatchingInlineAsm)
2972  EmitInstruction(Inst, Operands, Out);
2973  Opcode = Inst.getOpcode();
2974  return false;
2975  case Match_MissingFeature:
2976  return ErrorMissingFeature(IDLoc, ErrorInfo, MatchingInlineAsm);
2977  case Match_InvalidOperand:
2978  WasOriginallyInvalidOperand = true;
2979  break;
2980  case Match_MnemonicFail:
2981  break;
2982  }
2983 
2984  // FIXME: Ideally, we would only attempt suffix matches for things which are
2985  // valid prefixes, and we could just infer the right unambiguous
2986  // type. However, that requires substantially more matcher support than the
2987  // following hack.
2988 
2989  // Change the operand to point to a temporary token.
2990  StringRef Base = Op.getToken();
2991  SmallString<16> Tmp;
2992  Tmp += Base;
2993  Tmp += ' ';
2994  Op.setTokenValue(Tmp);
2995 
2996  // If this instruction starts with an 'f', then it is a floating point stack
2997  // instruction. These come in up to three forms for 32-bit, 64-bit, and
2998  // 80-bit floating point, which use the suffixes s,l,t respectively.
2999  //
3000  // Otherwise, we assume that this may be an integer instruction, which comes
3001  // in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively.
3002  const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0";
3003 
3004  // Check for the various suffix matches.
3005  uint64_t ErrorInfoIgnore;
3006  uint64_t ErrorInfoMissingFeature = 0; // Init suppresses compiler warnings.
3007  unsigned Match[4];
3008 
3009  for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I) {
3010  Tmp.back() = Suffixes[I];
3011  Match[I] = MatchInstruction(Operands, Inst, ErrorInfoIgnore,
3012  MatchingInlineAsm, isParsingIntelSyntax());
3013  // If this returned as a missing feature failure, remember that.
3014  if (Match[I] == Match_MissingFeature)
3015  ErrorInfoMissingFeature = ErrorInfoIgnore;
3016  }
3017 
3018  // Restore the old token.
3019  Op.setTokenValue(Base);
3020 
3021  // If exactly one matched, then we treat that as a successful match (and the
3022  // instruction will already have been filled in correctly, since the failing
3023  // matches won't have modified it).
3024  unsigned NumSuccessfulMatches =
3025  std::count(std::begin(Match), std::end(Match), Match_Success);
3026  if (NumSuccessfulMatches == 1) {
3027  Inst.setLoc(IDLoc);
3028  if (!MatchingInlineAsm)
3029  EmitInstruction(Inst, Operands, Out);
3030  Opcode = Inst.getOpcode();
3031  return false;
3032  }
3033 
3034  // Otherwise, the match failed, try to produce a decent error message.
3035 
3036  // If we had multiple suffix matches, then identify this as an ambiguous
3037  // match.
3038  if (NumSuccessfulMatches > 1) {
3039  char MatchChars[4];
3040  unsigned NumMatches = 0;
3041  for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I)
3042  if (Match[I] == Match_Success)
3043  MatchChars[NumMatches++] = Suffixes[I];
3044 
3045  SmallString<126> Msg;
3046  raw_svector_ostream OS(Msg);
3047  OS << "ambiguous instructions require an explicit suffix (could be ";
3048  for (unsigned i = 0; i != NumMatches; ++i) {
3049  if (i != 0)
3050  OS << ", ";
3051  if (i + 1 == NumMatches)
3052  OS << "or ";
3053  OS << "'" << Base << MatchChars[i] << "'";
3054  }
3055  OS << ")";
3056  Error(IDLoc, OS.str(), EmptyRange, MatchingInlineAsm);
3057  return true;
3058  }
3059 
3060  // Okay, we know that none of the variants matched successfully.
3061 
3062  // If all of the instructions reported an invalid mnemonic, then the original
3063  // mnemonic was invalid.
3064  if (std::count(std::begin(Match), std::end(Match), Match_MnemonicFail) == 4) {
3065  if (!WasOriginallyInvalidOperand) {
3066  return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'",
3067  Op.getLocRange(), MatchingInlineAsm);
3068  }
3069 
3070  // Recover location info for the operand if we know which was the problem.
3071  if (ErrorInfo != ~0ULL) {
3072  if (ErrorInfo >= Operands.size())
3073  return Error(IDLoc, "too few operands for instruction", EmptyRange,
3074  MatchingInlineAsm);
3075 
3076  X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo];
3077  if (Operand.getStartLoc().isValid()) {
3078  SMRange OperandRange = Operand.getLocRange();
3079  return Error(Operand.getStartLoc(), "invalid operand for instruction",
3080  OperandRange, MatchingInlineAsm);
3081  }
3082  }
3083 
3084  return Error(IDLoc, "invalid operand for instruction", EmptyRange,
3085  MatchingInlineAsm);
3086  }
3087 
3088  // If one instruction matched with a missing feature, report this as a
3089  // missing feature.
3090  if (std::count(std::begin(Match), std::end(Match),
3091  Match_MissingFeature) == 1) {
3092  ErrorInfo = ErrorInfoMissingFeature;
3093  return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
3094  MatchingInlineAsm);
3095  }
3096 
3097  // If one instruction matched with an invalid operand, report this as an
3098  // operand failure.
3099  if (std::count(std::begin(Match), std::end(Match),
3100  Match_InvalidOperand) == 1) {
3101  return Error(IDLoc, "invalid operand for instruction", EmptyRange,
3102  MatchingInlineAsm);
3103  }
3104 
3105  // If all of these were an outright failure, report it in a useless way.
3106  Error(IDLoc, "unknown use of instruction mnemonic without a size suffix",
3107  EmptyRange, MatchingInlineAsm);
3108  return true;
3109 }
3110 
3111 bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
3112  OperandVector &Operands,
3113  MCStreamer &Out,
3114  uint64_t &ErrorInfo,
3115  bool MatchingInlineAsm) {
3116  assert(!Operands.empty() && "Unexpect empty operand list!");
3117  X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
3118  assert(Op.isToken() && "Leading operand should always be a mnemonic!");
3119  StringRef Mnemonic = Op.getToken();
3120  SMRange EmptyRange = None;
3121  StringRef Base = Op.getToken();
3122  unsigned Prefixes = getPrefixes(Operands);
3123 
3124  // First, handle aliases that expand to multiple instructions.
3125  MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
3126 
3127  MCInst Inst;
3128 
3129  if (Prefixes)
3130  Inst.setFlags(Prefixes);
3131 
3132  // Find one unsized memory operand, if present.
3133  X86Operand *UnsizedMemOp = nullptr;
3134  for (const auto &Op : Operands) {
3135  X86Operand *X86Op = static_cast<X86Operand *>(Op.get());
3136  if (X86Op->isMemUnsized()) {
3137  UnsizedMemOp = X86Op;
3138  // Have we found an unqualified memory operand,
3139  // break. IA allows only one memory operand.
3140  break;
3141  }
3142  }
3143 
3144  // Allow some instructions to have implicitly pointer-sized operands. This is
3145  // compatible with gas.
3146  if (UnsizedMemOp) {
3147  static const char *const PtrSizedInstrs[] = {"call", "jmp", "push"};
3148  for (const char *Instr : PtrSizedInstrs) {
3149  if (Mnemonic == Instr) {
3150  UnsizedMemOp->Mem.Size = getPointerWidth();
3151  break;
3152  }
3153  }
3154  }
3155 
3157  uint64_t ErrorInfoMissingFeature = 0;
3158 
3159  // If unsized push has immediate operand we should default the default pointer
3160  // size for the size.
3161  if (Mnemonic == "push" && Operands.size() == 2) {
3162  auto *X86Op = static_cast<X86Operand *>(Operands[1].get());
3163  if (X86Op->isImm()) {
3164  // If it's not a constant fall through and let remainder take care of it.
3165  const auto *CE = dyn_cast<MCConstantExpr>(X86Op->getImm());
3166  unsigned Size = getPointerWidth();
3167  if (CE &&
3168  (isIntN(Size, CE->getValue()) || isUIntN(Size, CE->getValue()))) {
3169  SmallString<16> Tmp;
3170  Tmp += Base;
3171  Tmp += (is64BitMode())
3172  ? "q"
3173  : (is32BitMode()) ? "l" : (is16BitMode()) ? "w" : " ";
3174  Op.setTokenValue(Tmp);
3175  // Do match in ATT mode to allow explicit suffix usage.
3176  Match.push_back(MatchInstruction(Operands, Inst, ErrorInfo,
3177  MatchingInlineAsm,
3178  false /*isParsingIntelSyntax()*/));
3179  Op.setTokenValue(Base);
3180  }
3181  }
3182  }
3183 
3184  // If an unsized memory operand is present, try to match with each memory
3185  // operand size. In Intel assembly, the size is not part of the instruction
3186  // mnemonic.
3187  if (UnsizedMemOp && UnsizedMemOp->isMemUnsized()) {
3188  static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
3189  for (unsigned Size : MopSizes) {
3190  UnsizedMemOp->Mem.Size = Size;
3191  uint64_t ErrorInfoIgnore;
3192  unsigned LastOpcode = Inst.getOpcode();
3193  unsigned M = MatchInstruction(Operands, Inst, ErrorInfoIgnore,
3194  MatchingInlineAsm, isParsingIntelSyntax());
3195  if (Match.empty() || LastOpcode != Inst.getOpcode())
3196  Match.push_back(M);
3197 
3198  // If this returned as a missing feature failure, remember that.
3199  if (Match.back() == Match_MissingFeature)
3200  ErrorInfoMissingFeature = ErrorInfoIgnore;
3201  }
3202 
3203  // Restore the size of the unsized memory operand if we modified it.
3204  UnsizedMemOp->Mem.Size = 0;
3205  }
3206 
3207  // If we haven't matched anything yet, this is not a basic integer or FPU
3208  // operation. There shouldn't be any ambiguity in our mnemonic table, so try
3209  // matching with the unsized operand.
3210  if (Match.empty()) {
3211  Match.push_back(MatchInstruction(
3212  Operands, Inst, ErrorInfo, MatchingInlineAsm, isParsingIntelSyntax()));
3213  // If this returned as a missing feature failure, remember that.
3214  if (Match.back() == Match_MissingFeature)
3215  ErrorInfoMissingFeature = ErrorInfo;
3216  }
3217 
3218  // Restore the size of the unsized memory operand if we modified it.
3219  if (UnsizedMemOp)
3220  UnsizedMemOp->Mem.Size = 0;
3221 
3222  // If it's a bad mnemonic, all results will be the same.
3223  if (Match.back() == Match_MnemonicFail) {
3224  return Error(IDLoc, "invalid instruction mnemonic '" + Mnemonic + "'",
3225  Op.getLocRange(), MatchingInlineAsm);
3226  }
3227 
3228  unsigned NumSuccessfulMatches =
3229  std::count(std::begin(Match), std::end(Match), Match_Success);
3230 
3231  // If matching was ambiguous and we had size information from the frontend,
3232  // try again with that. This handles cases like "movxz eax, m8/m16".
3233  if (UnsizedMemOp && NumSuccessfulMatches > 1 &&
3234  UnsizedMemOp->getMemFrontendSize()) {
3235  UnsizedMemOp->Mem.Size = UnsizedMemOp->getMemFrontendSize();
3236  unsigned M = MatchInstruction(
3237  Operands, Inst, ErrorInfo, MatchingInlineAsm, isParsingIntelSyntax());
3238  if (M == Match_Success)
3239  NumSuccessfulMatches = 1;
3240 
3241  // Add a rewrite that encodes the size information we used from the
3242  // frontend.
3243  InstInfo->AsmRewrites->emplace_back(
3244  AOK_SizeDirective, UnsizedMemOp->getStartLoc(),
3245  /*Len=*/0, UnsizedMemOp->getMemFrontendSize());
3246  }
3247 
3248  // If exactly one matched, then we treat that as a successful match (and the
3249  // instruction will already have been filled in correctly, since the failing
3250  // matches won't have modified it).
3251  if (NumSuccessfulMatches == 1) {
3252  if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
3253  return true;
3254  // Some instructions need post-processing to, for example, tweak which
3255  // encoding is selected. Loop on it while changes happen so the individual
3256  // transformations can chain off each other.
3257  if (!MatchingInlineAsm)
3258  while (processInstruction(Inst, Operands))
3259  ;
3260  Inst.setLoc(IDLoc);
3261  if (!MatchingInlineAsm)
3262  EmitInstruction(Inst, Operands, Out);
3263  Opcode = Inst.getOpcode();
3264  return false;
3265  } else if (NumSuccessfulMatches > 1) {
3266  assert(UnsizedMemOp &&
3267  "multiple matches only possible with unsized memory operands");
3268  return Error(UnsizedMemOp->getStartLoc(),
3269  "ambiguous operand size for instruction '" + Mnemonic + "\'",
3270  UnsizedMemOp->getLocRange());
3271  }
3272 
3273  // If one instruction matched with a missing feature, report this as a
3274  // missing feature.
3275  if (std::count(std::begin(Match), std::end(Match),
3276  Match_MissingFeature) == 1) {
3277  ErrorInfo = ErrorInfoMissingFeature;
3278  return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
3279  MatchingInlineAsm);
3280  }
3281 
3282  // If one instruction matched with an invalid operand, report this as an
3283  // operand failure.
3284  if (std::count(std::begin(Match), std::end(Match),
3285  Match_InvalidOperand) == 1) {
3286  return Error(IDLoc, "invalid operand for instruction", EmptyRange,
3287  MatchingInlineAsm);
3288  }
3289 
3290  // If all of these were an outright failure, report it in a useless way.
3291  return Error(IDLoc, "unknown instruction mnemonic", EmptyRange,
3292  MatchingInlineAsm);
3293 }
3294 
3295 bool X86AsmParser::OmitRegisterFromClobberLists(unsigned RegNo) {
3296  return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo);
3297 }
3298 
3299 bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
3300  MCAsmParser &Parser = getParser();
3301  StringRef IDVal = DirectiveID.getIdentifier();
3302  if (IDVal.startswith(".code"))
3303  return ParseDirectiveCode(IDVal, DirectiveID.getLoc());
3304  else if (IDVal.startswith(".att_syntax")) {
3305  if (getLexer().isNot(AsmToken::EndOfStatement)) {
3306  if (Parser.getTok().getString() == "prefix")
3307  Parser.Lex();
3308  else if (Parser.getTok().getString() == "noprefix")
3309  return Error(DirectiveID.getLoc(), "'.att_syntax noprefix' is not "
3310  "supported: registers must have a "
3311  "'%' prefix in .att_syntax");
3312  }
3313  getParser().setAssemblerDialect(0);
3314  return false;
3315  } else if (IDVal.startswith(".intel_syntax")) {
3316  getParser().setAssemblerDialect(1);
3317  if (getLexer().isNot(AsmToken::EndOfStatement)) {
3318  if (Parser.getTok().getString() == "noprefix")
3319  Parser.Lex();
3320  else if (Parser.getTok().getString() == "prefix")
3321  return Error(DirectiveID.getLoc(), "'.intel_syntax prefix' is not "
3322  "supported: registers must not have "
3323  "a '%' prefix in .intel_syntax");
3324  }
3325  return false;
3326  } else if (IDVal == ".even")
3327  return parseDirectiveEven(DirectiveID.getLoc());
3328  else if (IDVal == ".cv_fpo_proc")
3329  return parseDirectiveFPOProc(DirectiveID.getLoc());
3330  else if (IDVal == ".cv_fpo_setframe")
3331  return parseDirectiveFPOSetFrame(DirectiveID.getLoc());
3332  else if (IDVal == ".cv_fpo_pushreg")
3333  return parseDirectiveFPOPushReg(DirectiveID.getLoc());
3334  else if (IDVal == ".cv_fpo_stackalloc")
3335  return parseDirectiveFPOStackAlloc(DirectiveID.getLoc());
3336  else if (IDVal == ".cv_fpo_stackalign")
3337  return parseDirectiveFPOStackAlign(DirectiveID.getLoc());
3338  else if (IDVal == ".cv_fpo_endprologue")
3339  return parseDirectiveFPOEndPrologue(DirectiveID.getLoc());
3340  else if (IDVal == ".cv_fpo_endproc")
3341  return parseDirectiveFPOEndProc(DirectiveID.getLoc());
3342 
3343  return true;
3344 }
3345 
3346 /// parseDirectiveEven
3347 /// ::= .even
3348 bool X86AsmParser::parseDirectiveEven(SMLoc L) {
3349  if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive"))
3350  return false;
3351 
3352  const MCSection *Section = getStreamer().getCurrentSectionOnly();
3353  if (!Section) {
3354  getStreamer().InitSections(false);
3355  Section = getStreamer().getCurrentSectionOnly();
3356  }
3357  if (Section->UseCodeAlign())
3358  getStreamer().EmitCodeAlignment(2, 0);
3359  else
3360  getStreamer().EmitValueToAlignment(2, 0, 1, 0);
3361  return false;
3362 }
3363 
3364 /// ParseDirectiveCode
3365 /// ::= .code16 | .code32 | .code64
3366 bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
3367  MCAsmParser &Parser = getParser();
3368  Code16GCC = false;
3369  if (IDVal == ".code16") {
3370  Parser.Lex();
3371  if (!is16BitMode()) {
3372  SwitchMode(X86::Mode16Bit);
3373  getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
3374  }
3375  } else if (IDVal == ".code16gcc") {
3376  // .code16gcc parses as if in 32-bit mode, but emits code in 16-bit mode.
3377  Parser.Lex();
3378  Code16GCC = true;
3379  if (!is16BitMode()) {
3380  SwitchMode(X86::Mode16Bit);
3381  getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
3382  }
3383  } else if (IDVal == ".code32") {
3384  Parser.Lex();
3385  if (!is32BitMode()) {
3386  SwitchMode(X86::Mode32Bit);
3387  getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
3388  }
3389  } else if (IDVal == ".code64") {
3390  Parser.Lex();
3391  if (!is64BitMode()) {
3392  SwitchMode(X86::Mode64Bit);
3393  getParser().getStreamer().EmitAssemblerFlag(MCAF_Code64);
3394  }
3395  } else {
3396  Error(L, "unknown directive " + IDVal);
3397  return false;
3398  }
3399 
3400  return false;
3401 }
3402 
3403 // .cv_fpo_proc foo
3404 bool X86AsmParser::parseDirectiveFPOProc(SMLoc L) {
3405  MCAsmParser &Parser = getParser();
3406  StringRef ProcName;
3407  int64_t ParamsSize;
3408  if (Parser.parseIdentifier(ProcName))
3409  return Parser.TokError("expected symbol name");
3410  if (Parser.parseIntToken(ParamsSize, "expected parameter byte count"))
3411  return true;
3412  if (!isUIntN(32, ParamsSize))
3413  return Parser.TokError("parameters size out of range");
3414  if (Parser.parseEOL("unexpected tokens"))
3415  return addErrorSuffix(" in '.cv_fpo_proc' directive");
3416  MCSymbol *ProcSym = getContext().getOrCreateSymbol(ProcName);
3417  return getTargetStreamer().emitFPOProc(ProcSym, ParamsSize, L);
3418 }
3419 
3420 // .cv_fpo_setframe ebp
3421 bool X86AsmParser::parseDirectiveFPOSetFrame(SMLoc L) {
3422  MCAsmParser &Parser = getParser();
3423  unsigned Reg;
3424  SMLoc DummyLoc;
3425  if (ParseRegister(Reg, DummyLoc, DummyLoc) ||
3426  Parser.parseEOL("unexpected tokens"))
3427  return addErrorSuffix(" in '.cv_fpo_setframe' directive");
3428  return getTargetStreamer().emitFPOSetFrame(Reg, L);
3429 }
3430 
3431 // .cv_fpo_pushreg ebx
3432 bool X86AsmParser::parseDirectiveFPOPushReg(SMLoc L) {
3433  MCAsmParser &Parser = getParser();
3434  unsigned Reg;
3435  SMLoc DummyLoc;
3436  if (ParseRegister(Reg, DummyLoc, DummyLoc) ||
3437  Parser.parseEOL("unexpected tokens"))
3438  return addErrorSuffix(" in '.cv_fpo_pushreg' directive");
3439  return getTargetStreamer().emitFPOPushReg(Reg, L);
3440 }
3441 
3442 // .cv_fpo_stackalloc 20
3443 bool X86AsmParser::parseDirectiveFPOStackAlloc(SMLoc L) {
3444  MCAsmParser &Parser = getParser();
3445  int64_t Offset;
3446  if (Parser.parseIntToken(Offset, "expected offset") ||
3447  Parser.parseEOL("unexpected tokens"))
3448  return addErrorSuffix(" in '.cv_fpo_stackalloc' directive");
3449  return getTargetStreamer().emitFPOStackAlloc(Offset, L);
3450 }
3451 
3452 // .cv_fpo_stackalign 8
3453 bool X86AsmParser::parseDirectiveFPOStackAlign(SMLoc L) {
3454  MCAsmParser &Parser = getParser();
3455  int64_t Offset;
3456  if (Parser.parseIntToken(Offset, "expected offset") ||
3457  Parser.parseEOL("unexpected tokens"))
3458  return addErrorSuffix(" in '.cv_fpo_stackalign' directive");
3459  return getTargetStreamer().emitFPOStackAlign(Offset, L);
3460 }
3461 
3462 // .cv_fpo_endprologue
3463 bool X86AsmParser::parseDirectiveFPOEndPrologue(SMLoc L) {
3464  MCAsmParser &Parser = getParser();
3465  if (Parser.parseEOL("unexpected tokens"))
3466  return addErrorSuffix(" in '.cv_fpo_endprologue' directive");
3467  return getTargetStreamer().emitFPOEndPrologue(L);
3468 }
3469 
3470 // .cv_fpo_endproc
3471 bool X86AsmParser::parseDirectiveFPOEndProc(SMLoc L) {
3472  MCAsmParser &Parser = getParser();
3473  if (Parser.parseEOL("unexpected tokens"))
3474  return addErrorSuffix(" in '.cv_fpo_endproc' directive");
3475  return getTargetStreamer().emitFPOEndProc(L);
3476 }
3477 
3478 // Force static initialization.
3479 extern "C" void LLVMInitializeX86AsmParser() {
3482 }
3483 
3484 #define GET_REGISTER_MATCHER
3485 #define GET_MATCHER_IMPLEMENTATION
3486 #define GET_SUBTARGET_FEATURE_NAME
3487 #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:259
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:1563
unsigned getMemFrontendSize() const
Definition: X86Operand.h:198
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
Definition: Path.cpp:250
bool isX86_64NonExtLowByteReg(unsigned reg)
Definition: X86BaseInfo.h:806
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:323
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:140
This class represents lattice values for constants.
Definition: AllocatorList.h:24
SMRange getLocRange() const
getLocRange - Get the range between the first and last token of this operand.
Definition: X86Operand.h:94
bool isVariable() const
isVariable - Check if this is a variable symbol.
Definition: MCSymbol.h:294
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
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:84
unsigned Reg
bool isNot(TokenKind K) const
Definition: MCAsmMacro.h:84
AddrNumOperands - Total number of operands in a memory reference.
Definition: X86BaseInfo.h:42
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:510
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:567
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:149
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
amdgpu Simplify well known AMD library false Value Value const Twine & Name
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:164
bool isMemUnsized() const
Definition: X86Operand.h:282
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:205
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
Target independent representation for an assembler token.
Definition: MCAsmMacro.h:22
static bool CheckBaseRegAndIndexRegAndScale(unsigned BaseReg, unsigned IndexReg, unsigned Scale, bool Is64BitMode, StringRef &ErrMsg)
}
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE R Default(T Value)
Definition: StringSwitch.h:203
bool isMem8() const
Definition: X86Operand.h:285
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:558
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:159
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
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:133
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:461
LLVM_NODISCARD std::string upper() const
Convert the given ASCII string to uppercase.
Definition: StringRef.cpp:116
Analysis containing CSE Info
Definition: CSEInfo.cpp:21
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:161
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:1252
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:445
bool isX86_64ExtendedReg(unsigned RegNo)
isX86_64ExtendedReg - Is the MachineOperand a x86-64 extended (r8 or higher) register? e.g.
Definition: X86BaseInfo.h:772
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
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:189
unsigned const MachineRegisterInfo * MRI
X86Operand - Instances of this class represent a parsed X86 machine instruction.
Definition: X86Operand.h:32
MCTargetStreamer * getTargetStreamer()
Definition: MCStreamer.h:258
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:129
virtual bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse a primary expression.
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:24
const MCExpr * getImm() const
Definition: X86Operand.h:169
bool parseTokenLoc(SMLoc &Loc)
Definition: MCAsmParser.cpp:38
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
static std::unique_ptr< X86Operand > CreateDXReg(SMLoc StartLoc, SMLoc EndLoc)
Definition: X86Operand.h:547
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:398
iterator erase(const_iterator CI)
Definition: SmallVector.h:445
size_t size() const
Definition: SmallVector.h:53
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:92
void setOpcode(unsigned Op)
Definition: MCInst.h:173
auto size(R &&Range, typename std::enable_if< std::is_same< typename std::iterator_traits< decltype(Range.begin())>::iterator_category, std::random_access_iterator_tag >::value, void >::type *=nullptr) -> decltype(std::distance(Range.begin(), Range.end()))
Get the size of a range.
Definition: STLExtras.h:1167
bool isUndefined(bool SetUsed=true) const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
Definition: MCSymbol.h:257
static unsigned MatchRegisterName(StringRef Name)
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:847
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:1044
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:381
StringRef str()
Return a StringRef for the vector contents.
Definition: raw_ostream.h:535
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.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:941
bool is(TokenKind K) const
Definition: MCAsmMacro.h:83
Class for arbitrary precision integers.
Definition: APInt.h:70
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:345
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:525
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:534
.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:56
#define I(x, y, z)
Definition: MD5.cpp:58
#define N
static unsigned getPrefixes(OperandVector &Operands)
Generic base class for all target subtargets.
virtual bool parseAbsoluteExpression(int64_t &Res)=0
Parse an expression which must evaluate to an absolute value.
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()
uint32_t Size
Definition: Profile.cpp:47
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:203
bool isDXReg() const
Definition: X86Operand.h:447
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:552
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
const MCExpr * getVariableValue(bool SetUsed=true) const
getVariableValue - Get the value for variable symbols.
Definition: MCSymbol.h:299
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 parseOptionalToken(AsmToken::TokenKind T)
Attempt to parse and consume token, returning true on success.
Definition: MCAsmParser.cpp:67
bool isReg() const override
isReg - Is this a register operand?
Definition: X86Operand.h:446
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
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:393
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:281