Coverage Report

Created: 2026-09-14 06:12

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