Coverage Report

Created: 2019-07-24 05:18

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