Coverage Report

Created: 2025-11-11 06:44

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
106k
  SMLoc consumeToken() {
73
106k
    MCAsmParser &Parser = getParser();
74
106k
    SMLoc Result = Parser.getTok().getLoc();
75
106k
    Parser.Lex();
76
106k
    return Result;
77
106k
  }
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
29
    int64_t popOperand(bool &valid) {
102
29
      valid = true;
103
      //assert (!PostfixStack.empty() && "Poped an empty stack!");
104
29
      if (PostfixStack.empty())
105
0
          valid = false;
106
29
      ICToken Op = PostfixStack.pop_back_val();
107
      //assert ((Op.first == IC_IMM || Op.first == IC_REGISTER)
108
      //        && "Expected an immediate or register!");
109
29
      if ((Op.first != IC_IMM && Op.first != IC_REGISTER))
110
1
          valid = false;
111
29
      return Op.second;
112
29
    }
113
61.1k
    void pushOperand(InfixCalculatorTok Op, int64_t Val = 0) {
114
61.1k
      assert ((Op == IC_IMM || Op == IC_REGISTER) &&
115
61.1k
              "Unexpected operand!");
116
61.1k
      PostfixStack.push_back(std::make_pair(Op, Val));
117
61.1k
    }
118
119
106
    void popOperator() { InfixOperatorStack.pop_back(); }
120
46.6k
    void pushOperator(InfixCalculatorTok Op) {
121
      // Push the new operator if the stack is empty.
122
46.6k
      if (InfixOperatorStack.empty()) {
123
14.5k
        InfixOperatorStack.push_back(Op);
124
14.5k
        return;
125
14.5k
      }
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
32.1k
      unsigned Idx = InfixOperatorStack.size() - 1;
131
32.1k
      InfixCalculatorTok StackOp = InfixOperatorStack[Idx];
132
32.1k
      if (OpPrecedence[Op] > OpPrecedence[StackOp] || StackOp == IC_LPAREN) {
133
7.38k
        InfixOperatorStack.push_back(Op);
134
7.38k
        return;
135
7.38k
      }
136
137
      // The operator on the top of the stack has higher precedence than the
138
      // new operator.
139
24.7k
      unsigned ParenCount = 0;
140
51.4k
      while (1) {
141
        // Nothing to process.
142
51.4k
        if (InfixOperatorStack.empty())
143
22.5k
          break;
144
145
28.9k
        Idx = InfixOperatorStack.size() - 1;
146
28.9k
        StackOp = InfixOperatorStack[Idx];
147
28.9k
        if (!(OpPrecedence[StackOp] >= OpPrecedence[Op] || ParenCount))
148
772
          break;
149
150
        // If we have an even parentheses count and we see a left parentheses,
151
        // then stop processing.
152
28.1k
        if (!ParenCount && StackOp == IC_LPAREN)
153
1.43k
          break;
154
155
26.7k
        if (StackOp == IC_RPAREN) {
156
1.12k
          ++ParenCount;
157
1.12k
          InfixOperatorStack.pop_back();
158
25.6k
        } else if (StackOp == IC_LPAREN) {
159
532
          --ParenCount;
160
532
          InfixOperatorStack.pop_back();
161
25.1k
        } else {
162
25.1k
          InfixOperatorStack.pop_back();
163
25.1k
          PostfixStack.push_back(std::make_pair(StackOp, 0));
164
25.1k
        }
165
26.7k
      }
166
      // Push the new operator.
167
24.7k
      InfixOperatorStack.push_back(Op);
168
24.7k
    }
169
170
33.0k
    int64_t execute(unsigned int &KsError) {
171
      // Push any remaining operators onto the postfix stack.
172
51.5k
      while (!InfixOperatorStack.empty()) {
173
18.4k
        InfixCalculatorTok StackOp = InfixOperatorStack.pop_back_val();
174
18.4k
        if (StackOp != IC_LPAREN && StackOp != IC_RPAREN)
175
14.9k
          PostfixStack.push_back(std::make_pair(StackOp, 0));
176
18.4k
      }
177
178
33.0k
      if (PostfixStack.empty())
179
10.4k
        return 0;
180
181
22.6k
      SmallVector<ICToken, 16> OperandStack;
182
125k
      for (unsigned i = 0, e = PostfixStack.size(); i != e; ++i) {
183
104k
        ICToken Op = PostfixStack[i];
184
104k
        if (Op.first == IC_IMM || Op.first == IC_REGISTER) {
185
62.7k
          OperandStack.push_back(Op);
186
62.7k
        } else {
187
          //assert (OperandStack.size() > 1 && "Too few operands.");
188
41.3k
          if (OperandStack.size() <= 1) {
189
1.24k
                KsError = KS_ERR_ASM_INVALIDOPERAND;
190
                // return a dummy value
191
1.24k
                return 0;
192
1.24k
          }
193
40.0k
          int64_t Val;
194
40.0k
          ICToken Op2 = OperandStack.pop_back_val();
195
40.0k
          ICToken Op1 = OperandStack.pop_back_val();
196
40.0k
          switch (Op.first) {
197
0
          default:
198
0
            report_fatal_error("Unexpected operator!");
199
0
            break;
200
5.26k
          case IC_PLUS:
201
5.26k
            Val = Op1.second + Op2.second;
202
5.26k
            OperandStack.push_back(std::make_pair(IC_IMM, Val));
203
5.26k
            break;
204
30.5k
          case IC_MINUS:
205
30.5k
            Val = Op1.second - Op2.second;
206
30.5k
            OperandStack.push_back(std::make_pair(IC_IMM, Val));
207
30.5k
            break;
208
1.59k
          case IC_MULTIPLY:
209
            //assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
210
            //        "Multiply operation with an immediate and a register!");
211
1.59k
            if (!(Op1.first == IC_IMM && Op2.first == IC_IMM)) {
212
11
                KsError = KS_ERR_ASM_INVALIDOPERAND;
213
                // return a dummy value
214
11
                return 0;
215
11
            }
216
1.58k
            Val = Op1.second * Op2.second;
217
1.58k
            OperandStack.push_back(std::make_pair(IC_IMM, Val));
218
1.58k
            break;
219
452
          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
452
            if (!(Op1.first == IC_IMM && Op2.first == IC_IMM) || Op2.second == 0) {
224
25
                KsError = KS_ERR_ASM_INVALIDOPERAND;
225
                // return a dummy value
226
25
                return 0;
227
25
            }
228
427
            Val = Op1.second / Op2.second;
229
427
            OperandStack.push_back(std::make_pair(IC_IMM, Val));
230
427
            break;
231
400
          case IC_OR:
232
            //assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
233
            //        "Or operation with an immediate and a register!");
234
400
            if (!(Op1.first == IC_IMM && Op2.first == IC_IMM)) {
235
0
                KsError = KS_ERR_ASM_INVALIDOPERAND;
236
                // return a dummy value
237
0
                return 0;
238
0
            }
239
400
            Val = Op1.second | Op2.second;
240
400
            OperandStack.push_back(std::make_pair(IC_IMM, Val));
241
400
            break;
242
187
          case IC_XOR:
243
            //assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
244
            //  "Xor operation with an immediate and a register!");
245
187
            if (!(Op1.first == IC_IMM && Op2.first == IC_IMM)) {
246
3
                KsError = KS_ERR_ASM_INVALIDOPERAND;
247
                // return a dummy value
248
3
                return 0;
249
3
            }
250
184
            Val = Op1.second ^ Op2.second;
251
184
            OperandStack.push_back(std::make_pair(IC_IMM, Val));
252
184
            break;
253
249
          case IC_AND:
254
            //assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
255
            //        "And operation with an immediate and a register!");
256
249
            if (!(Op1.first == IC_IMM && Op2.first == IC_IMM)) {
257
9
                KsError = KS_ERR_ASM_INVALIDOPERAND;
258
                // return a dummy value
259
9
                return 0;
260
9
            }
261
240
            Val = Op1.second & Op2.second;
262
240
            OperandStack.push_back(std::make_pair(IC_IMM, Val));
263
240
            break;
264
507
          case IC_LSHIFT:
265
            //assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
266
            //        "Left shift operation with an immediate and a register!");
267
507
            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
504
            Val = Op1.second << Op2.second;
273
504
            OperandStack.push_back(std::make_pair(IC_IMM, Val));
274
504
            break;
275
889
          case IC_RSHIFT:
276
            //assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
277
            //        "Right shift operation with an immediate and a register!");
278
889
            if (!(Op1.first == IC_IMM && Op2.first == IC_IMM)) {
279
4
                KsError = KS_ERR_ASM_INVALIDOPERAND;
280
                // return a dummy value
281
4
                return 0;
282
4
            }
283
885
            Val = Op1.second >> Op2.second;
284
885
            OperandStack.push_back(std::make_pair(IC_IMM, Val));
285
885
            break;
286
40.0k
          }
287
40.0k
        }
288
104k
      }
289
      //assert (OperandStack.size() == 1 && "Expected a single result.");
290
21.3k
      if (OperandStack.size() != 1) {
291
0
          KsError = KS_ERR_ASM_INVALIDOPERAND;
292
          // return a dummy value
293
0
          return 0;
294
0
      }
295
21.3k
      return OperandStack.pop_back_val().second;
296
21.3k
    }
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
32.1k
      State(IES_PLUS), PrevState(IES_ERROR), BaseReg(0), IndexReg(0), TmpReg(0),
333
32.1k
      Scale(1), Imm(imm), Sym(nullptr), StopOnLBrac(stoponlbrac),
334
32.1k
      AddImmPrefix(addimmprefix), Rel(isrel), Abs(false) { Info.clear(); }
335
336
2.62k
    unsigned getBaseReg() { return (Rel && !Abs && BaseReg == 0 && IndexReg == 0) ? (unsigned)X86::RIP : BaseReg; }
337
2.62k
    unsigned getIndexReg() { return IndexReg; }
338
2.62k
    unsigned getScale() { return Scale; }
339
41.4k
    const MCExpr *getSym() { return Sym; }
340
0
    StringRef getSymName() { return SymName; }
341
33.0k
    int64_t getImm(unsigned int &KsError) { return Imm + IC.execute(KsError); }
342
4.53k
    bool isValidEndState() {
343
4.53k
      return State == IES_RBRAC || State == IES_INTEGER;
344
4.53k
    }
345
168k
    bool getStopOnLBrac() { return StopOnLBrac; }
346
0
    bool getAddImmPrefix() { return AddImmPrefix; }
347
167k
    bool hadError() { return State == IES_ERROR; }
348
349
0
    InlineAsmIdentifierInfo &getIdentifierInfo() {
350
0
      return Info;
351
0
    }
352
353
424
    void onOr() {
354
424
      IntelExprState CurrState = State;
355
424
      switch (State) {
356
5
      default:
357
5
        State = IES_ERROR;
358
5
        break;
359
415
      case IES_INTEGER:
360
416
      case IES_RPAREN:
361
419
      case IES_REGISTER:
362
419
        State = IES_OR;
363
419
        IC.pushOperator(IC_OR);
364
419
        break;
365
424
      }
366
424
      PrevState = CurrState;
367
424
    }
368
197
    void onXor() {
369
197
      IntelExprState CurrState = State;
370
197
      switch (State) {
371
6
      default:
372
6
        State = IES_ERROR;
373
6
        break;
374
189
      case IES_INTEGER:
375
189
      case IES_RPAREN:
376
191
      case IES_REGISTER:
377
191
        State = IES_XOR;
378
191
        IC.pushOperator(IC_XOR);
379
191
        break;
380
197
      }
381
197
      PrevState = CurrState;
382
197
    }
383
323
    void onAnd() {
384
323
      IntelExprState CurrState = State;
385
323
      switch (State) {
386
1
      default:
387
1
        State = IES_ERROR;
388
1
        break;
389
314
      case IES_INTEGER:
390
314
      case IES_RPAREN:
391
322
      case IES_REGISTER:
392
322
        State = IES_AND;
393
322
        IC.pushOperator(IC_AND);
394
322
        break;
395
323
      }
396
323
      PrevState = CurrState;
397
323
    }
398
329
    void onLShift() {
399
329
      IntelExprState CurrState = State;
400
329
      switch (State) {
401
2
      default:
402
2
        State = IES_ERROR;
403
2
        break;
404
325
      case IES_INTEGER:
405
325
      case IES_RPAREN:
406
327
      case IES_REGISTER:
407
327
        State = IES_LSHIFT;
408
327
        IC.pushOperator(IC_LSHIFT);
409
327
        break;
410
329
      }
411
329
      PrevState = CurrState;
412
329
    }
413
943
    void onRShift() {
414
943
      IntelExprState CurrState = State;
415
943
      switch (State) {
416
4
      default:
417
4
        State = IES_ERROR;
418
4
        break;
419
936
      case IES_INTEGER:
420
936
      case IES_RPAREN:
421
939
      case IES_REGISTER:
422
939
        State = IES_RSHIFT;
423
939
        IC.pushOperator(IC_RSHIFT);
424
939
        break;
425
943
      }
426
943
      PrevState = CurrState;
427
943
    }
428
4.54k
    void onPlus() {
429
4.54k
      IntelExprState CurrState = State;
430
4.54k
      switch (State) {
431
9
      default:
432
9
        State = IES_ERROR;
433
9
        break;
434
3.35k
      case IES_INTEGER:
435
3.36k
      case IES_RPAREN:
436
4.53k
      case IES_REGISTER:
437
4.53k
        State = IES_PLUS;
438
4.53k
        IC.pushOperator(IC_PLUS);
439
4.53k
        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
1.17k
          if (!BaseReg) {
443
759
            BaseReg = TmpReg;
444
759
          } else {
445
            //assert (!IndexReg && "BaseReg/IndexReg already set!");
446
412
            if (IndexReg) {
447
10
                State = IES_ERROR;
448
10
                break;
449
10
            }
450
402
            IndexReg = TmpReg;
451
402
            Scale = 1;
452
402
          }
453
1.17k
        }
454
4.52k
        break;
455
4.54k
      }
456
4.54k
      PrevState = CurrState;
457
4.54k
    }
458
58.3k
    void onMinus() {
459
58.3k
      IntelExprState CurrState = State;
460
58.3k
      switch (State) {
461
17
      default:
462
17
        State = IES_ERROR;
463
17
        break;
464
25.5k
      case IES_PLUS:
465
25.5k
      case IES_NOT:
466
26.0k
      case IES_MULTIPLY:
467
26.2k
      case IES_DIVIDE:
468
26.5k
      case IES_LPAREN:
469
26.8k
      case IES_RPAREN:
470
26.8k
      case IES_LBRAC:
471
26.8k
      case IES_RBRAC:
472
57.7k
      case IES_INTEGER:
473
58.2k
      case IES_REGISTER:
474
58.2k
        State = IES_MINUS;
475
        // Only push the minus operator if it is not a unary operator.
476
58.2k
        if (!(CurrState == IES_PLUS || CurrState == IES_MINUS ||
477
32.7k
              CurrState == IES_MULTIPLY || CurrState == IES_DIVIDE ||
478
32.0k
              CurrState == IES_LPAREN || CurrState == IES_LBRAC))
479
31.7k
          IC.pushOperator(IC_MINUS);
480
58.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
515
          if (!BaseReg) {
484
493
            BaseReg = TmpReg;
485
493
          } else {
486
            //assert (!IndexReg && "BaseReg/IndexReg already set!");
487
22
            if (IndexReg) {
488
4
                State = IES_ERROR;
489
4
                break;
490
4
            }
491
18
            IndexReg = TmpReg;
492
18
            Scale = 1;
493
18
          }
494
515
        }
495
58.2k
        break;
496
58.3k
      }
497
58.3k
      PrevState = CurrState;
498
58.3k
    }
499
2.14k
    void onNot() {
500
2.14k
      IntelExprState CurrState = State;
501
2.14k
      switch (State) {
502
11
      default:
503
11
        State = IES_ERROR;
504
11
        break;
505
1.00k
      case IES_PLUS:
506
2.13k
      case IES_NOT:
507
2.13k
        State = IES_NOT;
508
2.13k
        break;
509
2.14k
      }
510
2.14k
      PrevState = CurrState;
511
2.14k
    }
512
13
    void onRel() {
513
13
      Rel = true;
514
13
    }
515
0
    void onAbs() {
516
0
      Abs = true;
517
0
    }
518
1.92k
    void onRegister(unsigned Reg) {
519
1.92k
      IntelExprState CurrState = State;
520
1.92k
      switch (State) {
521
21
      default:
522
21
        State = IES_ERROR;
523
21
        break;
524
1.85k
      case IES_PLUS:
525
1.87k
      case IES_LPAREN:
526
1.87k
        State = IES_REGISTER;
527
1.87k
        TmpReg = Reg;
528
1.87k
        IC.pushOperand(IC_REGISTER);
529
1.87k
        break;
530
31
      case IES_MULTIPLY:
531
        // Index Register - Scale * Register
532
31
        if (PrevState == IES_INTEGER) {
533
          //assert (!IndexReg && "IndexReg already set!");
534
30
          if (IndexReg) {
535
1
              State = IES_ERROR;
536
1
              break;
537
1
          }
538
29
          State = IES_REGISTER;
539
29
          IndexReg = Reg;
540
          // Get the scale and replace the 'Scale * Register' with '0'.
541
29
          bool valid;
542
29
          Scale = IC.popOperand(valid);
543
29
          if (!valid) {
544
1
              State = IES_ERROR;
545
1
              break;
546
1
          }
547
28
          IC.pushOperand(IC_IMM);
548
28
          IC.popOperator();
549
28
        } else {
550
1
          State = IES_ERROR;
551
1
        }
552
29
        break;
553
1.92k
      }
554
1.92k
      PrevState = CurrState;
555
1.92k
    }
556
38.3k
    void onIdentifierExpr(const MCExpr *SymRef, StringRef SymRefName) {
557
38.3k
      PrevState = State;
558
38.3k
      switch (State) {
559
192
      default:
560
192
        State = IES_ERROR;
561
192
        break;
562
2.82k
      case IES_PLUS:
563
37.5k
      case IES_MINUS:
564
38.1k
      case IES_NOT:
565
38.1k
        State = IES_INTEGER;
566
38.1k
        Sym = SymRef;
567
38.1k
        SymName = SymRefName;
568
38.1k
        IC.pushOperand(IC_IMM);
569
38.1k
        break;
570
38.3k
      }
571
38.3k
    }
572
21.2k
    bool onInteger(int64_t TmpInt, StringRef &ErrMsg) {
573
21.2k
      IntelExprState CurrState = State;
574
21.2k
      switch (State) {
575
30
      default:
576
30
        State = IES_ERROR;
577
30
        break;
578
4.21k
      case IES_PLUS:
579
17.2k
      case IES_MINUS:
580
17.3k
      case IES_NOT:
581
17.4k
      case IES_OR:
582
17.6k
      case IES_XOR:
583
17.8k
      case IES_AND:
584
18.1k
      case IES_LSHIFT:
585
18.2k
      case IES_RSHIFT:
586
18.4k
      case IES_DIVIDE:
587
19.1k
      case IES_MULTIPLY:
588
21.2k
      case IES_LPAREN:
589
21.2k
        State = IES_INTEGER;
590
21.2k
        if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
591
          // Index Register - Register * Scale
592
          //assert (!IndexReg && "IndexReg already set!");
593
91
          if (IndexReg) {
594
1
              State = IES_ERROR;
595
1
              break;
596
1
          }
597
90
          IndexReg = TmpReg;
598
90
          Scale = TmpInt;
599
90
          if(Scale != 1 && Scale != 2 && Scale != 4 && Scale != 8) {
600
12
            ErrMsg = "scale factor in address must be 1, 2, 4 or 8";
601
12
            return true;
602
12
          }
603
          // Get the scale and replace the 'Register * Scale' with '0'.
604
78
          IC.popOperator();
605
21.1k
        } else if ((PrevState == IES_PLUS || PrevState == IES_MINUS ||
606
19.0k
                    PrevState == IES_OR || PrevState == IES_AND ||
607
18.8k
                    PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||
608
18.5k
                    PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
609
17.9k
                    PrevState == IES_LPAREN || PrevState == IES_LBRAC ||
610
17.0k
                    PrevState == IES_NOT || PrevState == IES_XOR) &&
611
4.05k
                   CurrState == IES_MINUS) {
612
          // Unary minus.  No need to pop the minus operand because it was never
613
          // pushed.
614
1.89k
          IC.pushOperand(IC_IMM, -TmpInt); // Push -Imm.
615
19.2k
        } else if ((PrevState == IES_PLUS || PrevState == IES_MINUS ||
616
18.7k
                    PrevState == IES_OR || PrevState == IES_AND ||
617
18.5k
                    PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||
618
18.2k
                    PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
619
17.9k
                    PrevState == IES_LPAREN || PrevState == IES_LBRAC ||
620
17.0k
                    PrevState == IES_NOT || PrevState == IES_XOR) &&
621
2.15k
                   CurrState == IES_NOT) {
622
          // Unary not.  No need to pop the not operand because it was never
623
          // pushed.
624
113
          IC.pushOperand(IC_IMM, ~TmpInt); // Push ~Imm.
625
19.1k
        } else {
626
19.1k
          IC.pushOperand(IC_IMM, TmpInt);
627
19.1k
        }
628
21.2k
        break;
629
21.2k
      }
630
21.2k
      PrevState = CurrState;
631
21.2k
      return false;
632
21.2k
    }
633
634
1.81k
    void onStar() {
635
1.81k
      PrevState = State;
636
1.81k
      switch (State) {
637
8
      default:
638
8
        State = IES_ERROR;
639
8
        break;
640
1.40k
      case IES_INTEGER:
641
1.50k
      case IES_REGISTER:
642
1.80k
      case IES_RPAREN:
643
1.80k
        State = IES_MULTIPLY;
644
1.80k
        IC.pushOperator(IC_MULTIPLY);
645
1.80k
        break;
646
1.81k
      }
647
1.81k
    }
648
521
    void onDivide() {
649
521
      PrevState = State;
650
521
      switch (State) {
651
1
      default:
652
1
        State = IES_ERROR;
653
1
        break;
654
513
      case IES_INTEGER:
655
520
      case IES_RPAREN:
656
520
        State = IES_DIVIDE;
657
520
        IC.pushOperator(IC_DIVIDE);
658
520
        break;
659
521
      }
660
521
    }
661
159
    void onLBrac() {
662
159
      PrevState = State;
663
159
      switch (State) {
664
22
      default:
665
22
        State = IES_ERROR;
666
22
        break;
667
137
      case IES_RBRAC:
668
137
        State = IES_PLUS;
669
137
        IC.pushOperator(IC_PLUS);
670
137
        break;
671
159
      }
672
159
    }
673
243
    void onRBrac() {
674
243
      IntelExprState CurrState = State;
675
243
      switch (State) {
676
7
      default:
677
7
        State = IES_ERROR;
678
7
        break;
679
201
      case IES_INTEGER:
680
236
      case IES_REGISTER:
681
236
      case IES_RPAREN:
682
236
        State = IES_RBRAC;
683
236
        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
34
          if (!BaseReg) {
687
28
            BaseReg = TmpReg;
688
28
          } else {
689
            //assert (!IndexReg && "BaseReg/IndexReg already set!");
690
6
            if (IndexReg) {
691
1
                State = IES_ERROR;
692
1
                break;
693
1
            }
694
5
            IndexReg = TmpReg;
695
5
            Scale = 1;
696
5
          }
697
34
        }
698
235
        break;
699
243
      }
700
243
      PrevState = CurrState;
701
243
    }
702
4.55k
    void onLParen() {
703
4.55k
      IntelExprState CurrState = State;
704
4.55k
      switch (State) {
705
12
      default:
706
12
        State = IES_ERROR;
707
12
        break;
708
637
      case IES_PLUS:
709
677
      case IES_MINUS:
710
679
      case IES_NOT:
711
995
      case IES_OR:
712
1.01k
      case IES_XOR:
713
1.04k
      case IES_AND:
714
1.08k
      case IES_LSHIFT:
715
1.97k
      case IES_RSHIFT:
716
2.50k
      case IES_MULTIPLY:
717
2.53k
      case IES_DIVIDE:
718
4.54k
      case IES_LPAREN:
719
        // FIXME: We don't handle this type of unary minus or not, yet.
720
4.54k
        if ((PrevState == IES_PLUS || PrevState == IES_MINUS ||
721
4.45k
            PrevState == IES_OR || PrevState == IES_AND ||
722
4.42k
            PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||
723
3.80k
            PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
724
3.59k
            PrevState == IES_LPAREN || PrevState == IES_LBRAC ||
725
2.53k
            PrevState == IES_NOT || PrevState == IES_XOR) &&
726
2.01k
            (CurrState == IES_MINUS || CurrState == IES_NOT)) {
727
3
          State = IES_ERROR;
728
3
          break;
729
3
        }
730
4.53k
        State = IES_LPAREN;
731
4.53k
        IC.pushOperator(IC_LPAREN);
732
4.53k
        break;
733
4.55k
      }
734
4.55k
      PrevState = CurrState;
735
4.55k
    }
736
1.17k
    void onRParen() {
737
1.17k
      PrevState = State;
738
1.17k
      switch (State) {
739
6
      default:
740
6
        State = IES_ERROR;
741
6
        break;
742
630
      case IES_INTEGER:
743
630
      case IES_REGISTER:
744
1.17k
      case IES_RPAREN:
745
1.17k
        State = IES_RPAREN;
746
1.17k
        IC.pushOperator(IC_RPAREN);
747
1.17k
        break;
748
1.17k
      }
749
1.17k
    }
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
3.50k
  std::nullptr_t ErrorOperand(SMLoc Loc, StringRef Msg) {
772
    //Error(Loc, Msg);
773
3.50k
    return nullptr;
774
3.50k
  }
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
76.3k
  bool is64BitMode() const {
855
    // FIXME: Can tablegen auto-generate this?
856
76.3k
    return getSTI().getFeatureBits()[X86::Mode64Bit];
857
76.3k
  }
858
46.5k
  bool is32BitMode() const {
859
    // FIXME: Can tablegen auto-generate this?
860
46.5k
    return getSTI().getFeatureBits()[X86::Mode32Bit];
861
46.5k
  }
862
43.9k
  bool is16BitMode() const {
863
    // FIXME: Can tablegen auto-generate this?
864
43.9k
    return getSTI().getFeatureBits()[X86::Mode16Bit];
865
43.9k
  }
866
532
  void SwitchMode(unsigned mode) {
867
532
    MCSubtargetInfo &STI = copySTI();
868
532
    FeatureBitset AllModes({X86::Mode64Bit, X86::Mode32Bit, X86::Mode16Bit});
869
532
    FeatureBitset OldMode = STI.getFeatureBits() & AllModes;
870
532
    unsigned FB = ComputeAvailableFeatures(
871
532
      STI.ToggleFeature(OldMode.flip(mode)));
872
532
    setAvailableFeatures(FB);
873
874
532
    assert(FeatureBitset({mode}) == (STI.getFeatureBits() & AllModes));
875
532
  }
876
877
43.9k
  unsigned getPointerWidth() {
878
43.9k
    if (is16BitMode()) return 16;
879
35.3k
    if (is32BitMode()) return 32;
880
5.47k
    if (is64BitMode()) return 64;
881
5.47k
    llvm_unreachable("invalid mode");
882
5.47k
  }
883
884
602k
  bool isParsingIntelSyntax() {
885
602k
    return getParser().getAssemblerDialect();
886
602k
  }
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
16.9k
    : MCTargetAsmParser(Options, sti), MII(mii), InstInfo(nullptr) {
900
901
    // Initialize the set of available features.
902
16.9k
    setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
903
16.9k
    Instrumentation.reset(
904
16.9k
        CreateX86AsmInstrumentation(Options, Parser.getContext(), STI));
905
16.9k
  }
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
1.31k
                                    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
1.31k
  if ((BaseReg == X86::RIP && IndexReg != 0) || (IndexReg == X86::RIP)) {
932
0
    ErrMsg = "invalid base+index expression";
933
0
    return true;
934
0
  }
935
1.31k
  if (BaseReg != 0 && IndexReg != 0) {
936
388
    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
388
    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
387
    if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg)) {
951
8
      if (X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg) ||
952
7
          X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) {
953
1
        ErrMsg = "base register is 16-bit, but index register is not";
954
1
        return true;
955
1
      }
956
7
      if (((BaseReg == X86::BX || BaseReg == X86::BP) &&
957
5
           IndexReg != X86::SI && IndexReg != X86::DI) ||
958
2
          ((BaseReg == X86::SI || BaseReg == X86::DI) &&
959
6
           IndexReg != X86::BX && IndexReg != X86::BP)) {
960
6
        ErrMsg = "invalid 16-bit base/index register combination";
961
6
        return true;
962
6
      }
963
7
    }
964
387
  }
965
1.30k
  return false;
966
1.31k
}
967
968
bool X86AsmParser::ParseRegister(unsigned &RegNo,
969
                                 SMLoc &StartLoc, SMLoc &EndLoc, unsigned int &ErrorCode)
970
112k
{
971
112k
  MCAsmParser &Parser = getParser();
972
112k
  RegNo = 0;
973
112k
  const AsmToken &PercentTok = Parser.getTok();
974
112k
  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
112k
  if (!isParsingIntelSyntax() && PercentTok.is(AsmToken::Percent))
979
43
    Parser.Lex(); // Eat percent token.
980
981
112k
  const AsmToken &Tok = Parser.getTok();
982
112k
  EndLoc = Tok.getEndLoc();
983
984
112k
  if (Tok.isNot(AsmToken::Identifier)) {
985
53.7k
    if (isParsingIntelSyntax()) return true;
986
    //return Error(StartLoc, "invalid register name",
987
    //             SMRange(StartLoc, EndLoc));
988
7
    return true;
989
53.7k
  }
990
991
58.2k
  RegNo = MatchRegisterName(Tok.getString());
992
993
  // If the match failed, try the register name as lowercase.
994
58.2k
  if (RegNo == 0)
995
56.8k
    RegNo = MatchRegisterName(Tok.getString().lower());
996
997
  // The "flags" register cannot be referenced directly.
998
  // Treat it as an identifier instead.
999
58.2k
  if (isParsingInlineAsm() && isParsingIntelSyntax() && RegNo == X86::EFLAGS)
1000
0
    RegNo = 0;
1001
1002
58.2k
  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
51.6k
    if (RegNo == X86::RIZ ||
1009
51.6k
        X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo) ||
1010
51.4k
        X86II::isX86_64NonExtLowByteReg(RegNo) ||
1011
51.3k
        X86II::isX86_64ExtendedReg(RegNo))
1012
      //return Error(StartLoc, "register %"
1013
      //             + Tok.getString() + " is only available in 64-bit mode",
1014
      //             SMRange(StartLoc, EndLoc));
1015
1.89k
      return true;
1016
51.6k
  }
1017
1018
  // Parse "%st" as "%st(0)" and "%st(1)", which is multiple tokens.
1019
56.3k
  if (RegNo == 0 && (Tok.getString() == "st" || Tok.getString() == "ST")) {
1020
108
    RegNo = X86::ST0;
1021
108
    Parser.Lex(); // Eat 'st'
1022
1023
    // Check to see if we have '(4)' after %st.
1024
108
    if (getLexer().isNot(AsmToken::LParen))
1025
45
      return false;
1026
    // Lex the paren.
1027
63
    getParser().Lex();
1028
1029
63
    const AsmToken &IntTok = Parser.getTok();
1030
63
    if (IntTok.isNot(AsmToken::Integer))
1031
      //return Error(IntTok.getLoc(), "expected stack index");
1032
14
      return true;
1033
49
    bool valid;
1034
49
    unsigned r = IntTok.getIntVal(valid);
1035
49
    if (!valid)
1036
0
        return true;
1037
49
    switch (r) {
1038
1
    case 0: RegNo = X86::ST0; break;
1039
11
    case 1: RegNo = X86::ST1; break;
1040
7
    case 2: RegNo = X86::ST2; break;
1041
0
    case 3: RegNo = X86::ST3; break;
1042
1
    case 4: RegNo = X86::ST4; break;
1043
0
    case 5: RegNo = X86::ST5; break;
1044
0
    case 6: RegNo = X86::ST6; break;
1045
1
    case 7: RegNo = X86::ST7; break;
1046
28
    default: return true; //return Error(IntTok.getLoc(), "invalid stack index");
1047
49
    }
1048
1049
21
    if (getParser().Lex().isNot(AsmToken::RParen))
1050
      //return Error(Parser.getTok().getLoc(), "expected ')'");
1051
20
      return true;
1052
1053
1
    EndLoc = Parser.getTok().getEndLoc();
1054
1
    Parser.Lex(); // Eat ')'
1055
1
    return false;
1056
21
  }
1057
1058
56.2k
  EndLoc = Parser.getTok().getEndLoc();
1059
1060
  // If this is "db[0-7]", match it as an alias
1061
  // for dr[0-7].
1062
56.2k
  if (RegNo == 0 && Tok.getString().size() == 3 &&
1063
5.81k
      Tok.getString().startswith("db")) {
1064
10
    switch (Tok.getString()[2]) {
1065
1
    case '0': RegNo = X86::DR0; break;
1066
1
    case '1': RegNo = X86::DR1; break;
1067
0
    case '2': RegNo = X86::DR2; break;
1068
0
    case '3': RegNo = X86::DR3; break;
1069
1
    case '4': RegNo = X86::DR4; break;
1070
3
    case '5': RegNo = X86::DR5; break;
1071
0
    case '6': RegNo = X86::DR6; break;
1072
1
    case '7': RegNo = X86::DR7; break;
1073
10
    }
1074
1075
10
    if (RegNo != 0) {
1076
7
      EndLoc = Parser.getTok().getEndLoc();
1077
7
      Parser.Lex(); // Eat it.
1078
7
      return false;
1079
7
    }
1080
10
  }
1081
1082
56.2k
  if (RegNo == 0) {
1083
52.5k
    if (isParsingIntelSyntax()) return true;
1084
    //return Error(StartLoc, "invalid register name",
1085
    //             SMRange(StartLoc, EndLoc));
1086
1
    return true;
1087
52.5k
  }
1088
1089
3.71k
  Parser.Lex(); // Eat identifier token.
1090
3.71k
  return false;
1091
56.2k
}
1092
1093
0
void X86AsmParser::SetFrameRegister(unsigned RegNo) {
1094
0
  Instrumentation->SetInitialFrameRegister(RegNo);
1095
0
}
1096
1097
8.06k
std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(SMLoc Loc) {
1098
8.06k
  unsigned basereg =
1099
8.06k
    is64BitMode() ? X86::RSI : (is32BitMode() ? X86::ESI : X86::SI);
1100
8.06k
  const MCExpr *Disp = MCConstantExpr::create(0, getContext());
1101
8.06k
  return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
1102
8.06k
                               /*BaseReg=*/basereg, /*IndexReg=*/0, /*Scale=*/1,
1103
8.06k
                               Loc, Loc, 0);
1104
8.06k
}
1105
1106
3.77k
std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand(SMLoc Loc) {
1107
3.77k
  unsigned basereg =
1108
3.77k
    is64BitMode() ? X86::RDI : (is32BitMode() ? X86::EDI : X86::DI);
1109
3.77k
  const MCExpr *Disp = MCConstantExpr::create(0, getContext());
1110
3.77k
  return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
1111
3.77k
                               /*BaseReg=*/basereg, /*IndexReg=*/0, /*Scale=*/1,
1112
3.77k
                               Loc, Loc, 0);
1113
3.77k
}
1114
1115
1
bool X86AsmParser::IsSIReg(unsigned Reg) {
1116
1
  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
1
  case X86::DI:
1127
1
    return false;
1128
1
  }
1129
1
}
1130
1131
unsigned X86AsmParser::GetSIDIForRegClass(unsigned RegClassID, unsigned Reg,
1132
1
                                          bool IsSIReg) {
1133
1
  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
0
  case X86::GR32RegClassID:
1140
0
    return IsSIReg ? X86::ESI : X86::EDI;
1141
1
  case X86::GR16RegClassID:
1142
1
    return IsSIReg ? X86::SI : X86::DI;
1143
1
  }
1144
1
}
1145
1146
void X86AsmParser::AddDefaultSrcDestOperands(
1147
    OperandVector& Operands, std::unique_ptr<llvm_ks::MCParsedAsmOperand> &&Src,
1148
7.88k
    std::unique_ptr<llvm_ks::MCParsedAsmOperand> &&Dst) {
1149
7.88k
  if (isParsingIntelSyntax()) {
1150
7.35k
    Operands.push_back(std::move(Dst));
1151
7.35k
    Operands.push_back(std::move(Src));
1152
7.35k
  }
1153
531
  else {
1154
531
    Operands.push_back(std::move(Src));
1155
531
    Operands.push_back(std::move(Dst));
1156
531
  }
1157
7.88k
}
1158
1159
bool X86AsmParser::VerifyAndAdjustOperands(OperandVector &OrigOperands,
1160
8.44k
                                           OperandVector &FinalOperands) {
1161
1162
8.44k
  if (OrigOperands.size() > 1) {
1163
    // Check if sizes match, OrigOpernads also contains the instruction name
1164
20
    assert(OrigOperands.size() == FinalOperands.size() + 1 &&
1165
20
           "Opernand size mismatch");
1166
1167
20
    SmallVector<std::pair<SMLoc, std::string>, 2> Warnings;
1168
    // Verify types match
1169
20
    int RegClassID = -1;
1170
21
    for (unsigned int i = 0; i < FinalOperands.size(); ++i) {
1171
21
      X86Operand &OrigOp = static_cast<X86Operand &>(*OrigOperands[i + 1]);
1172
21
      X86Operand &FinalOp = static_cast<X86Operand &>(*FinalOperands[i]);
1173
1174
21
      if (FinalOp.isReg() &&
1175
3
          (!OrigOp.isReg() || FinalOp.getReg() != OrigOp.getReg()))
1176
        // Return false and let a normal complaint about bogus operands happen
1177
3
        return false;
1178
1179
18
      if (FinalOp.isMem()) {
1180
1181
18
        if (!OrigOp.isMem())
1182
          // Return false and let a normal complaint about bogus operands happen
1183
5
          return false;
1184
1185
13
        unsigned OrigReg = OrigOp.Mem.BaseReg;
1186
13
        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
13
        if (RegClassID != -1 &&
1191
0
            !X86MCRegisterClasses[RegClassID].contains(OrigReg)) {
1192
          //return Error(OrigOp.getStartLoc(),
1193
          //             "mismatching source and destination index registers");
1194
0
          return true;
1195
0
        }
1196
1197
13
        if (X86MCRegisterClasses[X86::GR64RegClassID].contains(OrigReg))
1198
0
          RegClassID = X86::GR64RegClassID;
1199
13
        else if (X86MCRegisterClasses[X86::GR32RegClassID].contains(OrigReg))
1200
0
          RegClassID = X86::GR32RegClassID;
1201
13
        else if (X86MCRegisterClasses[X86::GR16RegClassID].contains(OrigReg))
1202
1
          RegClassID = X86::GR16RegClassID;
1203
12
        else
1204
          // Unexpexted register class type
1205
          // Return false and let a normal complaint about bogus operands happen
1206
12
          return false;
1207
1208
1
        bool IsSI = IsSIReg(FinalReg);
1209
1
        FinalReg = GetSIDIForRegClass(RegClassID, FinalReg, IsSI);
1210
1211
1
        if (FinalReg != OrigReg) {
1212
0
          std::string RegName = IsSI ? "ES:(R|E)SI" : "ES:(R|E)DI";
1213
0
          Warnings.push_back(std::make_pair(
1214
0
              OrigOp.getStartLoc(),
1215
0
              "memory operand is only for determining the size, " + RegName +
1216
0
                  " will be used for the location"));
1217
0
        }
1218
1219
1
        FinalOp.Mem.Size = OrigOp.Mem.Size;
1220
1
        FinalOp.Mem.SegReg = OrigOp.Mem.SegReg;
1221
1
        FinalOp.Mem.BaseReg = FinalReg;
1222
1
      }
1223
18
    }
1224
1225
    // Produce warnings only if all the operands passed the adjustment - prevent
1226
    // legal cases like "movsd (%rax), %xmm0" mistakenly produce warnings
1227
0
    for (auto WarningMsg = Warnings.begin(); WarningMsg < Warnings.end();
1228
0
         ++WarningMsg) {
1229
0
      Warning((*WarningMsg).first, (*WarningMsg).second);
1230
0
    }
1231
1232
    // Remove old operands
1233
0
    for (unsigned int i = 0; i < FinalOperands.size(); ++i)
1234
0
      OrigOperands.pop_back();
1235
0
  }
1236
  // OrigOperands.append(FinalOperands.begin(), FinalOperands.end());
1237
24.7k
  for (unsigned int i = 0; i < FinalOperands.size(); ++i)
1238
16.3k
    OrigOperands.push_back(std::move(FinalOperands[i]));
1239
1240
8.42k
  return false;
1241
8.44k
}
1242
1243
std::unique_ptr<X86Operand> X86AsmParser::ParseOperand(std::string Mnem, unsigned int &KsError)
1244
110k
{
1245
110k
  if (isParsingIntelSyntax())
1246
100k
    return ParseIntelOperand(Mnem, KsError);
1247
9.93k
  return ParseATTOperand(KsError);
1248
110k
}
1249
1250
/// getIntelMemOperandSize - Return intel memory operand size.
1251
100k
static unsigned getIntelMemOperandSize(StringRef OpStr) {
1252
100k
  unsigned Size = StringSwitch<unsigned>(OpStr)
1253
100k
    .Cases("BYTE", "byte", 8)
1254
100k
    .Cases("WORD", "word", 16)
1255
100k
    .Cases("DWORD", "dword", 32)
1256
100k
    .Cases("FWORD", "fword", 48)
1257
100k
    .Cases("QWORD", "qword", 64)
1258
100k
    .Cases("MMWORD","mmword", 64)
1259
100k
    .Cases("XWORD", "xword", 80)
1260
100k
    .Cases("TBYTE", "tbyte", 80)
1261
100k
    .Cases("XMMWORD", "xmmword", 128)
1262
100k
    .Cases("YMMWORD", "ymmword", 256)
1263
100k
    .Cases("ZMMWORD", "zmmword", 512)
1264
100k
    .Cases("OPAQUE", "opaque", -1U) // needs to be non-zero, but doesn't matter
1265
100k
    .Default(0);
1266
100k
  return Size;
1267
100k
}
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
32.1k
{
1376
32.1k
  unsigned int ErrorCode;
1377
32.1k
  MCAsmParser &Parser = getParser();
1378
32.1k
  const AsmToken &Tok = Parser.getTok();
1379
1380
  // nasm tokens rel / abs are only valid at the beginning of the expression.
1381
32.1k
  if (KsSyntax == KS_OPT_SYNTAX_NASM) {
1382
517
    while (getLexer().getKind() == AsmToken::Identifier) {
1383
120
      std::string Identifier = Tok.getString().lower();
1384
120
      if (Identifier == "rel") {
1385
13
        SM.onRel();
1386
13
        consumeToken();
1387
13
        continue;
1388
107
      } else if (Identifier == "abs") {
1389
0
        SM.onAbs();
1390
0
        consumeToken();
1391
0
        continue;
1392
0
      }
1393
107
      break;
1394
120
    }
1395
504
  }
1396
1397
32.1k
  AsmToken::TokenKind PrevTK = AsmToken::Error;
1398
32.1k
  bool Done = false;
1399
197k
  while (!Done) {
1400
168k
    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
168k
    if (Tok.getString().startswith("."))
1405
254
      break;
1406
1407
    // If we're parsing an immediate expression, we don't expect a '['.
1408
168k
    if (SM.getStopOnLBrac() && getLexer().getKind() == AsmToken::LBrac)
1409
1.92k
      break;
1410
1411
166k
    AsmToken::TokenKind TK = getLexer().getKind();
1412
166k
    switch (TK) {
1413
4.53k
    default: {
1414
4.53k
      if (SM.isValidEndState()) {
1415
4.41k
        Done = true;
1416
4.41k
        break;
1417
4.41k
      }
1418
      //return Error(Tok.getLoc(), "unknown token in expression");
1419
120
      return true;
1420
4.53k
    }
1421
24.1k
    case AsmToken::EndOfStatement: {
1422
24.1k
      Done = true;
1423
24.1k
      break;
1424
4.53k
    }
1425
9
    case AsmToken::String:
1426
41.0k
    case AsmToken::Identifier: {
1427
      // This could be a register or a symbolic displacement.
1428
41.0k
      unsigned TmpReg;
1429
41.0k
      const MCExpr *Val;
1430
41.0k
      SMLoc IdentLoc = Tok.getLoc();
1431
41.0k
      StringRef Identifier = Tok.getString();
1432
41.0k
      if (TK != AsmToken::String && !ParseRegister(TmpReg, IdentLoc, End, ErrorCode)) {
1433
1.92k
        SM.onRegister(TmpReg);
1434
1.92k
        if (SM.hadError())
1435
24
            return true;
1436
1.90k
        UpdateLocLex = false;
1437
1.90k
        break;
1438
39.1k
      } else {
1439
39.1k
        if (!isParsingInlineAsm()) {
1440
39.1k
          if (getParser().parsePrimaryExpr(Val, End))
1441
            //return Error(Tok.getLoc(), "Unexpected identifier!");
1442
831
            return true;
1443
39.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
38.3k
        SM.onIdentifierExpr(Val, Identifier);
1456
38.3k
        UpdateLocLex = false;
1457
38.3k
        break;
1458
39.1k
      }
1459
      //return Error(Tok.getLoc(), "Unexpected identifier!");
1460
0
      return true;
1461
41.0k
    }
1462
21.2k
    case AsmToken::Integer: {
1463
21.2k
      StringRef ErrMsg;
1464
21.2k
      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
21.2k
      bool valid;
1469
21.2k
      int64_t IntVal = getTok().getIntVal(valid);
1470
21.2k
      if (!valid)
1471
0
          return true;
1472
21.2k
      End = consumeToken();
1473
21.2k
      UpdateLocLex = false;
1474
21.2k
      if (getLexer().getKind() == AsmToken::Identifier) {
1475
182
        StringRef IDVal = getTok().getString();
1476
182
        if (IDVal == "f" || IDVal == "b") {
1477
12
          bool valid;
1478
12
          MCSymbol *Sym =
1479
12
              getContext().getDirectionalLocalSymbol(IntVal, IDVal == "b", valid);
1480
12
          if (!valid)
1481
12
              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
170
        } else {
1492
170
          if (SM.onInteger(IntVal, ErrMsg))
1493
            //return Error(Loc, ErrMsg);
1494
2
            return true;
1495
170
        }
1496
21.0k
      } else {
1497
21.0k
        if (SM.onInteger(IntVal, ErrMsg))
1498
          //return Error(Loc, ErrMsg);
1499
10
          return true;
1500
21.0k
      }
1501
21.2k
      break;
1502
21.2k
    }
1503
21.2k
    case AsmToken::Plus:    SM.onPlus(); break;
1504
58.3k
    case AsmToken::Minus:   SM.onMinus(); break;
1505
2.14k
    case AsmToken::Tilde:   SM.onNot(); break;
1506
1.81k
    case AsmToken::Star:    SM.onStar(); break;
1507
521
    case AsmToken::Slash:   SM.onDivide(); break;
1508
424
    case AsmToken::Pipe:    SM.onOr(); break;
1509
197
    case AsmToken::Caret:   SM.onXor(); break;
1510
323
    case AsmToken::Amp:     SM.onAnd(); break;
1511
329
    case AsmToken::LessLess:
1512
329
                            SM.onLShift(); break;
1513
943
    case AsmToken::GreaterGreater:
1514
943
                            SM.onRShift(); break;
1515
159
    case AsmToken::LBrac:   SM.onLBrac(); break;
1516
243
    case AsmToken::RBrac:   SM.onRBrac(); break;
1517
4.55k
    case AsmToken::LParen:  SM.onLParen(); break;
1518
1.17k
    case AsmToken::RParen:  SM.onRParen(); break;
1519
166k
    }
1520
165k
    if (SM.hadError())
1521
      //return Error(Tok.getLoc(), "unknown token in expression");
1522
352
      return true;
1523
1524
165k
    if (!Done && UpdateLocLex)
1525
75.5k
      End = consumeToken();
1526
1527
165k
    PrevTK = TK;
1528
165k
  }
1529
30.7k
  return false;
1530
32.1k
}
1531
1532
std::unique_ptr<X86Operand>
1533
X86AsmParser::ParseIntelBracExpression(unsigned SegReg, SMLoc Start,
1534
                                       int64_t ImmDisp, unsigned Size, unsigned int &KsError)
1535
2.91k
{
1536
2.91k
  MCAsmParser &Parser = getParser();
1537
2.91k
  const AsmToken &Tok = Parser.getTok();
1538
2.91k
  SMLoc BracLoc = Tok.getLoc(), End = Tok.getEndLoc();
1539
2.91k
  if (getLexer().isNot(AsmToken::LBrac))
1540
0
    return ErrorOperand(BracLoc, "Expected '[' token!");
1541
2.91k
  Parser.Lex(); // Eat '['
1542
1543
2.91k
  SMLoc StartInBrac = Tok.getLoc();
1544
2.91k
  bool IsRel;
1545
2.91k
  switch(SegReg) {
1546
16
    default:
1547
16
      IsRel = false;
1548
16
      break;
1549
2.90k
    case 0:
1550
2.90k
    case X86::CS:
1551
2.90k
    case X86::DS:
1552
2.90k
      IsRel = getParser().isNasmDefaultRel();
1553
2.91k
  }
1554
  // Parse [ Symbol + ImmDisp ] and [ BaseReg + Scale*IndexReg + ImmDisp ].  We
1555
  // may have already parsed an immediate displacement before the bracketed
1556
  // expression.
1557
2.91k
  IntelExprStateMachine SM(ImmDisp, /*StopOnLBrac=*/false, /*AddImmPrefix=*/true,
1558
2.91k
                           /*IsRel*/IsRel);
1559
2.91k
  if (ParseIntelExpression(SM, End)) {
1560
211
    KsError = KS_ERR_ASM_INVALIDOPERAND;
1561
211
    return nullptr;
1562
211
  }
1563
1564
2.70k
  const MCExpr *Disp = nullptr;
1565
2.70k
  if (const MCExpr *Sym = SM.getSym()) {
1566
    // A symbolic displacement.
1567
925
    Disp = Sym;
1568
925
    if (isParsingInlineAsm())
1569
0
      RewriteIntelBracExpression(*InstInfo->AsmRewrites, SM.getSymName(),
1570
0
                                 ImmDisp, SM.getImm(KsError), BracLoc, StartInBrac,
1571
0
                                 End);
1572
925
  }
1573
1574
2.70k
  if (SM.getImm(KsError) || !Disp) {
1575
2.31k
    const MCExpr *Imm = MCConstantExpr::create(SM.getImm(KsError), getContext());
1576
2.31k
    if (Disp)
1577
530
      Disp = MCBinaryExpr::createAdd(Disp, Imm, getContext());
1578
1.78k
    else
1579
1.78k
      Disp = Imm;  // An immediate displacement only.
1580
2.31k
  }
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
2.70k
  if (Tok.getString().find('.') != StringRef::npos) {
1586
227
    const MCExpr *NewDisp;
1587
227
    if (ParseIntelDotOperator(Disp, NewDisp)) {
1588
85
      KsError = KS_ERR_ASM_INVALIDOPERAND;
1589
85
      return nullptr;
1590
85
    }
1591
1592
142
    End = Tok.getEndLoc();
1593
142
    Parser.Lex();  // Eat the field.
1594
142
    Disp = NewDisp;
1595
142
  }
1596
1597
2.62k
  int BaseReg = SM.getBaseReg();
1598
2.62k
  int IndexReg = SM.getIndexReg();
1599
  //printf("--- BaseReg = %u, IndexReg = %u, SegReg = %u\n", BaseReg, IndexReg, SegReg);
1600
2.62k
  int Scale = SM.getScale();
1601
2.62k
  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
2.62k
  if (Scale != 1 && Scale != 2 && Scale != 4 && Scale != 8) {
1608
      // invalid Scale
1609
18
      KsError = KS_ERR_ASM_INVALIDOPERAND;
1610
18
      return nullptr;
1611
18
  }
1612
1613
2.60k
  if (!isParsingInlineAsm()) {
1614
    // handle [-42]
1615
2.60k
    if (!BaseReg && !IndexReg) {
1616
1.31k
      if (!SegReg)
1617
1.29k
        return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size);
1618
15
      return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
1619
15
                                   Start, End, Size);
1620
1.31k
    }
1621
1.29k
    StringRef ErrMsg;
1622
1.29k
    if (CheckBaseRegAndIndexReg(BaseReg, IndexReg, ErrMsg)) {
1623
      //Error(StartInBrac, ErrMsg);
1624
8
      KsError = KS_ERR_ASM_INVALIDOPERAND;
1625
8
      return nullptr;
1626
8
    }
1627
1.28k
    return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
1628
1.28k
                                 IndexReg, Scale, Start, End, Size);
1629
1.29k
  }
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
2.60k
}
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
214
{
1690
214
  MCAsmParser &Parser = getParser();
1691
214
  assert(SegReg != 0 && "Tried to parse a segment override without a segment!");
1692
214
  const AsmToken &Tok = Parser.getTok(); // Eat colon.
1693
214
  if (Tok.isNot(AsmToken::Colon))
1694
0
    return ErrorOperand(Tok.getLoc(), "Expected ':' token!");
1695
214
  Parser.Lex(); // Eat ':'
1696
1697
214
  int64_t ImmDisp = 0;
1698
214
  if (getLexer().is(AsmToken::Integer)) {
1699
74
    bool valid;
1700
74
    ImmDisp = Tok.getIntVal(valid);
1701
74
    if (!valid) {
1702
0
        KsError = KS_ERR_ASM_INVALIDOPERAND;
1703
0
        return nullptr;
1704
0
    }
1705
74
    AsmToken ImmDispToken = Parser.Lex(); // Eat the integer.
1706
1707
74
    if (isParsingInlineAsm())
1708
0
      InstInfo->AsmRewrites->emplace_back(AOK_ImmPrefix, ImmDispToken.getLoc());
1709
1710
74
    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
65
      const MCExpr *Disp = MCConstantExpr::create(ImmDisp, getContext());
1715
65
      return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp,
1716
65
                                   /*BaseReg=*/0, /*IndexReg=*/0, /*Scale=*/1,
1717
65
                                   Start, ImmDispToken.getEndLoc(), Size);
1718
65
    }
1719
74
  }
1720
1721
149
  if (getLexer().is(AsmToken::LBrac))
1722
16
    return ParseIntelBracExpression(SegReg, Start, ImmDisp, Size, KsError);
1723
1724
133
  const MCExpr *Val;
1725
133
  SMLoc End;
1726
133
  if (!isParsingInlineAsm()) {
1727
133
    if (getParser().parsePrimaryExpr(Val, End))
1728
60
      return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1729
1730
73
    return X86Operand::CreateMem(getPointerWidth(), Val, Start, End, Size);
1731
133
  }
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
111
{
1748
111
  MCAsmParser &Parser = getParser();
1749
111
  const AsmToken &Tok = Parser.getTok();
1750
  // Eat "{" and mark the current place.
1751
111
  const SMLoc consumedToken = consumeToken();
1752
111
  if (Tok.getIdentifier().startswith("r")) {
1753
15
    int rndMode = StringSwitch<int>(Tok.getIdentifier())
1754
15
      .Case("rn", X86::STATIC_ROUNDING::TO_NEAREST_INT)
1755
15
      .Case("rd", X86::STATIC_ROUNDING::TO_NEG_INF)
1756
15
      .Case("ru", X86::STATIC_ROUNDING::TO_POS_INF)
1757
15
      .Case("rz", X86::STATIC_ROUNDING::TO_ZERO)
1758
15
      .Default(-1);
1759
15
    if (-1 == rndMode)
1760
9
      return ErrorOperand(Tok.getLoc(), "Invalid rounding mode.");
1761
6
     Parser.Lex();  // Eat "r*" of r*-sae
1762
6
    if (!getLexer().is(AsmToken::Minus))
1763
3
      return ErrorOperand(Tok.getLoc(), "Expected - at this point");
1764
3
    Parser.Lex();  // Eat "-"
1765
3
    Parser.Lex();  // Eat the sae
1766
3
    if (!getLexer().is(AsmToken::RCurly))
1767
1
      return ErrorOperand(Tok.getLoc(), "Expected } at this point");
1768
2
    Parser.Lex();  // Eat "}"
1769
2
    const MCExpr *RndModeOp =
1770
2
      MCConstantExpr::create(rndMode, Parser.getContext());
1771
2
    return X86Operand::CreateImm(RndModeOp, Start, End);
1772
3
  }
1773
96
  if(Tok.getIdentifier().equals("sae")){
1774
1
    Parser.Lex();  // Eat the sae
1775
1
    if (!getLexer().is(AsmToken::RCurly))
1776
0
      return ErrorOperand(Tok.getLoc(), "Expected } at this point");
1777
1
    Parser.Lex();  // Eat "}"
1778
1
    return X86Operand::CreateToken("{sae}", consumedToken);
1779
1
  }
1780
1781
95
  KsError = KS_ERR_ASM_INVALIDOPERAND;
1782
95
  return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1783
96
}
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
70.9k
{
1791
70.9k
  MCAsmParser &Parser = getParser();
1792
70.9k
  const AsmToken &Tok = Parser.getTok();
1793
70.9k
  SMLoc End;
1794
1795
  // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
1796
70.9k
  if (getLexer().is(AsmToken::LBrac))
1797
2.90k
    return ParseIntelBracExpression(/*SegReg=*/0, Start, ImmDisp, Size, KsError);
1798
70.9k
  assert(ImmDisp == 0);
1799
1800
68.0k
  const MCExpr *Val;
1801
68.0k
  if (Mnem == "loop" || Mnem == "loope" || Mnem == "loopne" ||
1802
67.8k
      Mnem == "call" || Mnem.c_str()[0] == 'j') {
1803
      // CALL/JMP/Jxx <immediate> (Keystone)
1804
5.52k
      if (getParser().parsePrimaryExpr(Val, End))
1805
3.28k
          return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1806
1807
2.24k
      return X86Operand::CreateMem(0, Val, Start, End, Size);
1808
62.5k
  } else {
1809
62.5k
    if (getParser().parseExpression(Val, End)) {
1810
44.1k
      KsError = KS_ERR_ASM_INVALIDOPERAND;
1811
44.1k
      return nullptr;
1812
44.1k
    }
1813
18.4k
    return X86Operand::CreateImm(Val, Start, End);
1814
62.5k
  }
1815
68.0k
}
1816
1817
/// Parse the '.' operator.
1818
bool X86AsmParser::ParseIntelDotOperator(const MCExpr *Disp,
1819
                                                const MCExpr *&NewDisp)
1820
227
{
1821
227
  MCAsmParser &Parser = getParser();
1822
227
  const AsmToken &Tok = Parser.getTok();
1823
227
  int64_t OrigDispVal, DotDispVal;
1824
1825
  // FIXME: Handle non-constant expressions.
1826
227
  if (const MCConstantExpr *OrigDisp = dyn_cast<MCConstantExpr>(Disp))
1827
220
    OrigDispVal = OrigDisp->getValue();
1828
7
  else
1829
    //return Error(Tok.getLoc(), "Non-constant offsets are not supported!");
1830
7
    return true;
1831
1832
  // Drop the optional '.'.
1833
220
  StringRef DotDispStr = Tok.getString();
1834
220
  if (DotDispStr.startswith("."))
1835
220
    DotDispStr = DotDispStr.drop_front(1);
1836
1837
  // .Imm gets lexed as a real.
1838
220
  if (Tok.is(AsmToken::Real)) {
1839
211
    APInt DotDisp;
1840
211
    DotDispStr.getAsInteger(10, DotDisp);
1841
    // sanity check
1842
211
    if (DotDisp.getActiveBits() > 64) {
1843
69
        return true;
1844
69
    }
1845
142
    DotDispVal = DotDisp.getZExtValue();
1846
142
  } 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
9
    return true;
1857
1858
142
  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
142
  NewDisp = MCConstantExpr::create(OrigDispVal + DotDispVal, getContext());
1866
142
  return false;
1867
220
}
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
100k
{
1951
100k
  MCAsmParser &Parser = getParser();
1952
100k
  const AsmToken &Tok = Parser.getTok();
1953
100k
  SMLoc Start, End;
1954
1955
  //printf(">> ParseIntelOperand::Tok = %s\n", Tok.getString().str().c_str());
1956
1957
  // Offset, length, type and size operators.
1958
100k
  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
100k
  bool PtrInOperand = false;
1971
100k
  unsigned Size = getIntelMemOperandSize(Tok.getString());
1972
100k
  if (Size) {
1973
105
    Parser.Lex(); // Eat operand size (e.g., byte, word).
1974
105
    if (KsSyntax == KS_OPT_SYNTAX_NASM) {
1975
        // Nasm do not accept 'PTR' in memory operands
1976
64
        if (Tok.getString().lower() == "ptr")
1977
0
            return ErrorOperand(Tok.getLoc(), "Do not expected 'PTR' or 'ptr' token!");
1978
64
    } else {
1979
        // LLVM requires 'PTR' in memory operand
1980
        // except in the case of "push"
1981
41
        if (Tok.getString().lower() == "ptr") {
1982
0
            Parser.Lex(); // Eat ptr.
1983
41
        } else if (Mnem != "push")
1984
28
            return ErrorOperand(Tok.getLoc(), "Expected 'PTR' or 'ptr' token!");
1985
41
    }
1986
77
    PtrInOperand = true;
1987
77
  }
1988
1989
100k
  Start = Tok.getLoc();
1990
1991
  // Immediate.
1992
100k
  if (getLexer().is(AsmToken::Integer) || getLexer().is(AsmToken::Minus) ||
1993
72.1k
      getLexer().is(AsmToken::Tilde) || getLexer().is(AsmToken::LParen)) {
1994
29.2k
    AsmToken StartTok = Tok;
1995
29.2k
    IntelExprStateMachine SM(/*Imm=*/0, /*StopOnLBrac=*/true,
1996
29.2k
                             /*AddImmPrefix=*/false);
1997
29.2k
    if (ParseIntelExpression(SM, End)) {
1998
1.14k
      KsError = KS_ERR_ASM_INVALIDOPERAND;
1999
1.14k
      return nullptr;
2000
1.14k
    }
2001
2002
28.0k
    int64_t Imm = SM.getImm(KsError);
2003
28.0k
    if (KsError) {
2004
159
      return nullptr;
2005
159
    }
2006
2007
27.9k
    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
27.9k
    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
25.9k
      if (SM.getSym())
2023
12.7k
        return X86Operand::CreateMem(getPointerWidth(), SM.getSym(), Start, End,
2024
12.7k
                                     Size);
2025
2026
13.2k
      if (Mnem == "call" || Mnem == "loop" || Mnem == "loope" ||
2027
12.8k
              Mnem == "loopne" || Mnem.c_str()[0] == 'j') {
2028
          // CALL/JMP/Jxx <immediate> (Keystone)
2029
10.6k
          const MCExpr *Disp = MCConstantExpr::create(Imm, Parser.getContext());
2030
10.6k
          return X86Operand::CreateMem(0, 0, Disp, 0, 0, 1,
2031
10.6k
                  Start, End, 0);
2032
10.6k
      }
2033
2034
      // dirty hacky way to deal with PUSH 0xd/PUSH word 0xd
2035
2.59k
      if (Mnem == "push") {
2036
131
          if (Size == 0)
2037
129
              push32 = true;
2038
131
      }
2039
2040
2.59k
      const MCExpr *ImmExpr = MCConstantExpr::create(Imm, getContext());
2041
2.59k
      return X86Operand::CreateImm(ImmExpr, Start, End);
2042
13.2k
    }
2043
2044
    // Only positive immediates are valid.
2045
1.92k
    if (Imm < 0)
2046
27
      return ErrorOperand(Start, "expected a positive immediate displacement "
2047
27
                          "before bracketed expr.");
2048
2049
    // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
2050
1.89k
    return ParseIntelMemOperand(Mnem, Imm, Start, Size, KsError);
2051
1.92k
  }
2052
2053
  // rounding mode token
2054
70.9k
  if (getSTI().getFeatureBits()[X86::FeatureAVX512] &&
2055
70.9k
      getLexer().is(AsmToken::LCurly)) {
2056
82
    return ParseRoundingModeOp(Start, End, KsError);
2057
82
  }
2058
2059
  // Register.
2060
70.8k
  unsigned RegNo = 0;
2061
70.8k
  unsigned int ErrorCode;
2062
70.8k
  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
1.80k
    if (RegNo == X86::RIP)
2068
0
      return ErrorOperand(Start, "rip can only be used as a base register");
2069
1.80k
    if (getLexer().isNot(AsmToken::Colon)) {
2070
1.58k
      if (PtrInOperand) {
2071
0
        return ErrorOperand(Start, "expected memory operand after "
2072
0
                                   "'ptr', found register operand instead");
2073
0
      }
2074
1.58k
      return X86Operand::CreateReg(RegNo, Start, End);
2075
1.58k
    }
2076
    
2077
214
    return ParseIntelSegmentOverride(/*SegReg=*/RegNo, Start, Size, KsError);
2078
1.80k
  }
2079
2080
  // Memory operand.
2081
69.0k
  return ParseIntelMemOperand(Mnem, /*Disp=*/0, Start, Size, KsError);
2082
70.8k
}
2083
2084
std::unique_ptr<X86Operand> X86AsmParser::ParseATTOperand(unsigned int &KsError)
2085
9.93k
{
2086
9.93k
  MCAsmParser &Parser = getParser();
2087
9.93k
  switch (getLexer().getKind()) {
2088
9.76k
  default:
2089
    // Parse a memory operand with no segment register.
2090
9.76k
    return ParseMemOperand(0, Parser.getTok().getLoc(), KsError);
2091
15
  case AsmToken::Percent: {
2092
    // Read the register.
2093
15
    unsigned RegNo;
2094
15
    SMLoc Start, End;
2095
15
    unsigned int ErrorCode;
2096
15
    if (ParseRegister(RegNo, Start, End, ErrorCode)) return nullptr;
2097
11
    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
11
    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
11
    if (getLexer().isNot(AsmToken::Colon))
2113
8
      return X86Operand::CreateReg(RegNo, Start, End);
2114
2115
3
    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
1
    getParser().Lex(); // Eat the colon.
2121
1
    return ParseMemOperand(RegNo, Start, KsError);
2122
3
  }
2123
124
  case AsmToken::Dollar: {
2124
    // $42 -> immediate.
2125
124
    SMLoc Start = Parser.getTok().getLoc(), End;
2126
124
    Parser.Lex();
2127
124
    const MCExpr *Val;
2128
124
    if (getParser().parseExpression(Val, End)) {
2129
12
      KsError = KS_ERR_ASM_INVALIDOPERAND;
2130
12
      return nullptr;
2131
12
    }
2132
112
    return X86Operand::CreateImm(Val, Start, End);
2133
124
  }
2134
29
  case AsmToken::LCurly:{
2135
29
    SMLoc Start = Parser.getTok().getLoc(), End;
2136
29
    if (getSTI().getFeatureBits()[X86::FeatureAVX512])
2137
29
      return ParseRoundingModeOp(Start, End, KsError);
2138
0
    KsError = KS_ERR_ASM_INVALIDOPERAND;
2139
0
    return ErrorOperand(Start, "unknown token in expression");
2140
29
  }
2141
9.93k
  }
2142
9.93k
}
2143
2144
bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands,
2145
                                       const MCParsedAsmOperand &Op)
2146
56.0k
{
2147
56.0k
  MCAsmParser &Parser = getParser();
2148
56.0k
  if(getSTI().getFeatureBits()[X86::FeatureAVX512]) {
2149
56.0k
    if (getLexer().is(AsmToken::LCurly)) {
2150
      // Eat "{" and mark the current place.
2151
1.72k
      const SMLoc consumedToken = consumeToken();
2152
      // Distinguish {1to<NUM>} from {%k<NUM>}.
2153
1.72k
      if(getLexer().is(AsmToken::Integer)) {
2154
        // Parse memory broadcasting ({1to<NUM>}).
2155
46
        bool valid;
2156
46
        if (getLexer().getTok().getIntVal(valid) != 1)
2157
          //return !ErrorAndEatStatement(getLexer().getLoc(),
2158
          //                             "Expected 1to<NUM> at this point");
2159
34
          return false;
2160
12
        Parser.Lex();  // Eat "1" of 1to8
2161
12
        if (!getLexer().is(AsmToken::Identifier) ||
2162
11
            !getLexer().getTok().getIdentifier().startswith("to"))
2163
          //return !ErrorAndEatStatement(getLexer().getLoc(),
2164
          //                             "Expected 1to<NUM> at this point");
2165
7
          return false;
2166
        // Recognize only reasonable suffixes.
2167
5
        const char *BroadcastPrimitive =
2168
5
          StringSwitch<const char*>(getLexer().getTok().getIdentifier())
2169
5
            .Case("to2",  "{1to2}")
2170
5
            .Case("to4",  "{1to4}")
2171
5
            .Case("to8",  "{1to8}")
2172
5
            .Case("to16", "{1to16}")
2173
5
            .Default(nullptr);
2174
5
        if (!BroadcastPrimitive)
2175
          //return !ErrorAndEatStatement(getLexer().getLoc(),
2176
          //                             "Invalid memory broadcast primitive.");
2177
2
          return false;
2178
3
        Parser.Lex();  // Eat "toN" of 1toN
2179
3
        if (!getLexer().is(AsmToken::RCurly))
2180
          //return !ErrorAndEatStatement(getLexer().getLoc(),
2181
          //                             "Expected } at this point");
2182
3
          return false;
2183
0
        Parser.Lex();  // Eat "}"
2184
0
        Operands.push_back(X86Operand::CreateToken(BroadcastPrimitive,
2185
0
                                                   consumedToken));
2186
        // No AVX512 specific primitives can pass
2187
        // after memory broadcasting, so return.
2188
0
        return true;
2189
1.68k
      } else {
2190
        // Parse mask register {%k1}
2191
1.68k
        unsigned int KsError;
2192
1.68k
        Operands.push_back(X86Operand::CreateToken("{", consumedToken));
2193
1.68k
        if (std::unique_ptr<X86Operand> Op = ParseOperand("", KsError)) {
2194
94
          Operands.push_back(std::move(Op));
2195
94
          if (!getLexer().is(AsmToken::RCurly))
2196
            //return !ErrorAndEatStatement(getLexer().getLoc(),
2197
            //                             "Expected } at this point");
2198
74
            return false;
2199
20
          Operands.push_back(X86Operand::CreateToken("}", consumeToken()));
2200
2201
          // Parse "zeroing non-masked" semantic {z}
2202
20
          if (getLexer().is(AsmToken::LCurly)) {
2203
9
            Operands.push_back(X86Operand::CreateToken("{z}", consumeToken()));
2204
9
            if (!getLexer().is(AsmToken::Identifier) ||
2205
6
                getLexer().getTok().getIdentifier() != "z")
2206
              //return !ErrorAndEatStatement(getLexer().getLoc(),
2207
              //                             "Expected z at this point");
2208
8
              return false;
2209
1
            Parser.Lex();  // Eat the z
2210
1
            if (!getLexer().is(AsmToken::RCurly))
2211
              //return !ErrorAndEatStatement(getLexer().getLoc(),
2212
              //                             "Expected } at this point");
2213
1
              return false;
2214
0
            Parser.Lex();  // Eat the }
2215
0
          }
2216
1.58k
        } else {
2217
1.58k
            return true;
2218
1.58k
        }
2219
1.68k
      }
2220
1.72k
    }
2221
56.0k
  }
2222
54.3k
  return true;
2223
56.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
9.76k
{
2230
2231
9.76k
  unsigned int ErrorCode;
2232
9.76k
  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
9.76k
  const MCExpr *Disp = MCConstantExpr::create(0, getParser().getContext());
2238
9.76k
  if (getLexer().isNot(AsmToken::LParen)) {
2239
9.37k
    SMLoc ExprEnd;
2240
9.37k
    if (getParser().parseExpression(Disp, ExprEnd)) {
2241
4.30k
        KsError = KS_ERR_ASM_INVALIDOPERAND;
2242
4.30k
        return nullptr;
2243
4.30k
    }
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
5.07k
    if (getLexer().isNot(AsmToken::LParen)) {
2248
      // Unless we have a segment register, treat this as an immediate.
2249
5.02k
      if (SegReg == 0)
2250
5.02k
        return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, ExprEnd);
2251
1
      return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
2252
1
                                   MemStart, ExprEnd);
2253
5.02k
    }
2254
2255
    // Eat the '('.
2256
51
    Parser.Lex();
2257
388
  } 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
388
    SMLoc LParenLoc = Parser.getTok().getLoc();
2261
388
    Parser.Lex(); // Eat the '('.
2262
2263
388
    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
212
    } else {
2267
212
      SMLoc ExprEnd;
2268
2269
      // It must be an parenthesized expression, parse it now.
2270
212
      if (getParser().parseParenExpression(Disp, ExprEnd)) {
2271
195
        KsError = KS_ERR_ASM_INVALIDOPERAND;
2272
195
        return nullptr;
2273
195
      }
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
17
      if (getLexer().isNot(AsmToken::LParen)) {
2278
        // Unless we have a segment register, treat this as an immediate.
2279
16
        if (SegReg == 0)
2280
16
          return X86Operand::CreateMem(getPointerWidth(), Disp, LParenLoc,
2281
16
                                       ExprEnd);
2282
0
        return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
2283
0
                                     MemStart, ExprEnd);
2284
16
      }
2285
2286
      // Eat the '('.
2287
1
      Parser.Lex();
2288
1
    }
2289
388
  }
2290
2291
  // If we reached here, then we just ate the ( of the memory operand.  Process
2292
  // the rest of the memory operand.
2293
228
  unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
2294
228
  SMLoc IndexLoc, BaseLoc;
2295
2296
228
  if (getLexer().is(AsmToken::Percent)) {
2297
2
    SMLoc StartLoc, EndLoc;
2298
2
    BaseLoc = Parser.getTok().getLoc();
2299
2
    if (ParseRegister(BaseReg, StartLoc, EndLoc, ErrorCode)) {
2300
1
        KsError = KS_ERR_ASM_INVALIDOPERAND;
2301
1
        return nullptr;
2302
1
    }
2303
1
    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
1
  }
2310
2311
227
  if (getLexer().is(AsmToken::Comma)) {
2312
203
    Parser.Lex(); // Eat the comma.
2313
203
    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
203
    if (getLexer().is(AsmToken::Percent)) {
2322
14
      SMLoc L;
2323
14
      if (ParseRegister(IndexReg, L, L, ErrorCode)) {
2324
1
          KsError = KS_ERR_ASM_INVALIDOPERAND;
2325
1
          return nullptr;
2326
1
      }
2327
2328
13
      if (ParseRegister(IndexReg, L, L, ErrorCode)) {
2329
2
        KsError = KS_ERR_ASM_X86_INVALIDOPERAND;
2330
2
        return nullptr;
2331
2
      }
2332
11
      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
11
      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
11
      if (getLexer().isNot(AsmToken::RParen)) {
2344
        // Parse the scale amount:
2345
        //  ::= ',' [scale-expression]
2346
10
        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
9
        Parser.Lex(); // Eat the comma.
2353
2354
9
        if (getLexer().isNot(AsmToken::RParen)) {
2355
          //SMLoc Loc = Parser.getTok().getLoc();
2356
2357
8
          int64_t ScaleVal;
2358
8
          if (getParser().parseAbsoluteExpression(ScaleVal)){
2359
            //Error(Loc, "expected scale expression");
2360
1
            KsError = KS_ERR_ASM_INVALIDOPERAND;
2361
1
            return nullptr;
2362
1
          }
2363
2364
          // Validate the scale amount.
2365
7
          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
7
          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
2
            KsError = KS_ERR_ASM_INVALIDOPERAND;
2375
2
            return nullptr;
2376
2
          }
2377
5
          Scale = (unsigned)ScaleVal;
2378
5
        }
2379
9
      }
2380
189
    } 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
188
      int64_t Value;
2386
188
      if (getParser().parseAbsoluteExpression(Value)) {
2387
184
        KsError = KS_ERR_ASM_INVALIDOPERAND;
2388
184
        return nullptr;
2389
184
      }
2390
2391
      //if (Value != 1)
2392
      //  Warning(Loc, "scale factor without index register is ignored");
2393
4
      Scale = 1;
2394
4
    }
2395
203
  }
2396
2397
  // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
2398
36
  if (getLexer().isNot(AsmToken::RParen)) {
2399
    //Error(Parser.getTok().getLoc(), "unexpected token in memory operand");
2400
15
    KsError = KS_ERR_ASM_INVALIDOPERAND;
2401
15
    return nullptr;
2402
15
  }
2403
21
  SMLoc MemEnd = Parser.getTok().getEndLoc();
2404
21
  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
21
  if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
2410
0
      (is64BitMode() || (BaseReg != X86::BX && BaseReg != X86::BP &&
2411
0
                         BaseReg != X86::SI && BaseReg != X86::DI)) &&
2412
0
      BaseReg != X86::DX) {
2413
    //Error(BaseLoc, "invalid 16-bit base register");
2414
0
    KsError = KS_ERR_ASM_INVALIDOPERAND;
2415
0
    return nullptr;
2416
0
  }
2417
21
  if (BaseReg == 0 &&
2418
20
      X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg)) {
2419
    //Error(IndexLoc, "16-bit memory operand may not include only index register");
2420
1
    KsError = KS_ERR_ASM_INVALIDOPERAND;
2421
1
    return nullptr;
2422
1
  }
2423
2424
20
  StringRef ErrMsg;
2425
20
  if (CheckBaseRegAndIndexReg(BaseReg, IndexReg, ErrMsg)) {
2426
    //Error(BaseLoc, ErrMsg);
2427
0
    KsError = KS_ERR_ASM_INVALIDOPERAND;
2428
0
    return nullptr;
2429
0
  }
2430
2431
20
  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
20
  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
20
  if (SegReg || BaseReg || IndexReg)
2444
7
    return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
2445
7
                                 IndexReg, Scale, MemStart, MemEnd);
2446
13
  return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, MemEnd);
2447
20
}
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
105k
{
2454
105k
  MCAsmParser &Parser = getParser();
2455
105k
  InstInfo = &Info;
2456
2457
  // Nasm accepts JMP/CALL, but not LJMP/LCALL
2458
105k
  if (KsSyntax == KS_OPT_SYNTAX_NASM) {
2459
659
      if (Name == "jmp" || Name == "call") {
2460
205
          AsmToken Tokens[3];
2461
205
          MutableArrayRef<AsmToken> Buf(Tokens);
2462
205
          size_t count = getLexer().peekTokens(Buf);
2463
205
          if (count == 3 && Tokens[0].getString() == ":") {
2464
11
              if (Name == "jmp")
2465
2
                  Name = "ljmp";
2466
9
              else if (Name == "call")
2467
9
                  Name = "lcall";
2468
11
          }
2469
205
      }
2470
659
  }
2471
2472
105k
  StringRef PatchedName = Name;
2473
2474
  // FIXME: Hack to recognize setneb as setne.
2475
105k
  if (PatchedName.startswith("set") && PatchedName.endswith("b") &&
2476
84
      PatchedName != "setb" && PatchedName != "setnb")
2477
49
    PatchedName = PatchedName.substr(0, Name.size()-1);
2478
2479
  // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}.
2480
105k
  if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) &&
2481
1.42k
      (PatchedName.endswith("ss") || PatchedName.endswith("sd") ||
2482
998
       PatchedName.endswith("ps") || PatchedName.endswith("pd"))) {
2483
863
    bool IsVCMP = PatchedName[0] == 'v';
2484
863
    unsigned CCIdx = IsVCMP ? 4 : 3;
2485
863
    unsigned ComparisonCode = StringSwitch<unsigned>(
2486
863
      PatchedName.slice(CCIdx, PatchedName.size() - 2))
2487
863
      .Case("eq",       0x00)
2488
863
      .Case("eq_oq",    0x00)
2489
863
      .Case("lt",       0x01)
2490
863
      .Case("lt_os",    0x01)
2491
863
      .Case("le",       0x02)
2492
863
      .Case("le_os",    0x02)
2493
863
      .Case("unord",    0x03)
2494
863
      .Case("unord_q",  0x03)
2495
863
      .Case("neq",      0x04)
2496
863
      .Case("neq_uq",   0x04)
2497
863
      .Case("nlt",      0x05)
2498
863
      .Case("nlt_us",   0x05)
2499
863
      .Case("nle",      0x06)
2500
863
      .Case("nle_us",   0x06)
2501
863
      .Case("ord",      0x07)
2502
863
      .Case("ord_q",    0x07)
2503
      /* AVX only from here */
2504
863
      .Case("eq_uq",    0x08)
2505
863
      .Case("nge",      0x09)
2506
863
      .Case("nge_us",   0x09)
2507
863
      .Case("ngt",      0x0A)
2508
863
      .Case("ngt_us",   0x0A)
2509
863
      .Case("false",    0x0B)
2510
863
      .Case("false_oq", 0x0B)
2511
863
      .Case("neq_oq",   0x0C)
2512
863
      .Case("ge",       0x0D)
2513
863
      .Case("ge_os",    0x0D)
2514
863
      .Case("gt",       0x0E)
2515
863
      .Case("gt_os",    0x0E)
2516
863
      .Case("true",     0x0F)
2517
863
      .Case("true_uq",  0x0F)
2518
863
      .Case("eq_os",    0x10)
2519
863
      .Case("lt_oq",    0x11)
2520
863
      .Case("le_oq",    0x12)
2521
863
      .Case("unord_s",  0x13)
2522
863
      .Case("neq_us",   0x14)
2523
863
      .Case("nlt_uq",   0x15)
2524
863
      .Case("nle_uq",   0x16)
2525
863
      .Case("ord_s",    0x17)
2526
863
      .Case("eq_us",    0x18)
2527
863
      .Case("nge_uq",   0x19)
2528
863
      .Case("ngt_uq",   0x1A)
2529
863
      .Case("false_os", 0x1B)
2530
863
      .Case("neq_os",   0x1C)
2531
863
      .Case("ge_oq",    0x1D)
2532
863
      .Case("gt_oq",    0x1E)
2533
863
      .Case("true_us",  0x1F)
2534
863
      .Default(~0U);
2535
863
    if (ComparisonCode != ~0U && (IsVCMP || ComparisonCode < 8)) {
2536
2537
67
      Operands.push_back(X86Operand::CreateToken(PatchedName.slice(0, CCIdx),
2538
67
                                                 NameLoc));
2539
2540
67
      const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2541
67
                                                   getParser().getContext());
2542
67
      Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2543
2544
67
      PatchedName = PatchedName.substr(PatchedName.size() - 2);
2545
67
    }
2546
863
  }
2547
2548
  // FIXME: Hack to recognize vpcmp<comparison code>{ub,uw,ud,uq,b,w,d,q}.
2549
105k
  if (PatchedName.startswith("vpcmp") &&
2550
273
      (PatchedName.endswith("b") || PatchedName.endswith("w") ||
2551
225
       PatchedName.endswith("d") || PatchedName.endswith("q"))) {
2552
196
    unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1;
2553
196
    unsigned ComparisonCode = StringSwitch<unsigned>(
2554
196
      PatchedName.slice(5, PatchedName.size() - CCIdx))
2555
196
      .Case("eq",    0x0) // Only allowed on unsigned. Checked below.
2556
196
      .Case("lt",    0x1)
2557
196
      .Case("le",    0x2)
2558
      //.Case("false", 0x3) // Not a documented alias.
2559
196
      .Case("neq",   0x4)
2560
196
      .Case("nlt",   0x5)
2561
196
      .Case("nle",   0x6)
2562
      //.Case("true",  0x7) // Not a documented alias.
2563
196
      .Default(~0U);
2564
196
    if (ComparisonCode != ~0U && (ComparisonCode != 0 || CCIdx == 2)) {
2565
26
      Operands.push_back(X86Operand::CreateToken("vpcmp", NameLoc));
2566
2567
26
      const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2568
26
                                                   getParser().getContext());
2569
26
      Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2570
2571
26
      PatchedName = PatchedName.substr(PatchedName.size() - CCIdx);
2572
26
    }
2573
196
  }
2574
2575
  // FIXME: Hack to recognize vpcom<comparison code>{ub,uw,ud,uq,b,w,d,q}.
2576
105k
  if (PatchedName.startswith("vpcom") &&
2577
74
      (PatchedName.endswith("b") || PatchedName.endswith("w") ||
2578
48
       PatchedName.endswith("d") || PatchedName.endswith("q"))) {
2579
48
    unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1;
2580
48
    unsigned ComparisonCode = StringSwitch<unsigned>(
2581
48
      PatchedName.slice(5, PatchedName.size() - CCIdx))
2582
48
      .Case("lt",    0x0)
2583
48
      .Case("le",    0x1)
2584
48
      .Case("gt",    0x2)
2585
48
      .Case("ge",    0x3)
2586
48
      .Case("eq",    0x4)
2587
48
      .Case("neq",   0x5)
2588
48
      .Case("false", 0x6)
2589
48
      .Case("true",  0x7)
2590
48
      .Default(~0U);
2591
48
    if (ComparisonCode != ~0U) {
2592
11
      Operands.push_back(X86Operand::CreateToken("vpcom", NameLoc));
2593
2594
11
      const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2595
11
                                                   getParser().getContext());
2596
11
      Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2597
2598
11
      PatchedName = PatchedName.substr(PatchedName.size() - CCIdx);
2599
11
    }
2600
48
  }
2601
2602
105k
  Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
2603
2604
  // Determine whether this is an instruction prefix.
2605
105k
  bool isPrefix =
2606
105k
    Name == "lock" || Name == "rep" ||
2607
104k
    Name == "repe" || Name == "repz" ||
2608
104k
    Name == "repne" || Name == "repnz" ||
2609
104k
    Name == "rex64" || Name == "data16";
2610
2611
105k
  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
105k
  if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) {
2618
    // Parse '*' modifier.
2619
84.8k
    if (getLexer().is(AsmToken::Star))
2620
7.02k
      Operands.push_back(X86Operand::CreateToken("*", consumeToken()));
2621
2622
    // Read the operands.
2623
108k
    while(1) {
2624
108k
      if (std::unique_ptr<X86Operand> Op = ParseOperand(Name.str(), ErrorCode)) {
2625
56.0k
        Operands.push_back(std::move(Op));
2626
56.0k
        if (!HandleAVX512Operand(Operands, *Operands.back()))
2627
129
          return true;
2628
56.0k
      } else {
2629
52.3k
         Parser.eatToEndOfStatement();
2630
52.3k
         return true;
2631
52.3k
      }
2632
2633
55.9k
      if (getLexer().is(AsmToken::Colon)) {
2634
          // for LJMP/LCALL, check for ':'. otherwise, check for comma and eat it
2635
454
          if (Name.startswith("ljmp") || Name.startswith("lcall"))
2636
430
              Operands.push_back(X86Operand::CreateToken(":", consumeToken()));
2637
24
          else
2638
24
              break;
2639
55.4k
      } else if (getLexer().is(AsmToken::Comma))
2640
23.1k
          Parser.Lex();
2641
32.2k
      else
2642
32.2k
          break;
2643
55.9k
    }
2644
2645
32.2k
    if (getLexer().isNot(AsmToken::EndOfStatement) && getLexer().isNot(AsmToken::Eof)) {
2646
      //return ErrorAndEatStatement(getLexer().getLoc(),
2647
      //                            "unexpected token in argument list");
2648
1.07k
      ErrorCode = KS_ERR_ASM_INVALIDOPERAND;
2649
1.07k
      return true;
2650
1.07k
    }
2651
32.2k
   }
2652
2653
  // Consume the EndOfStatement or the prefix separator Slash
2654
52.0k
  if (getLexer().is(AsmToken::EndOfStatement) ||
2655
965
      (isPrefix && getLexer().is(AsmToken::Slash)))
2656
51.2k
    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
52.0k
  bool IsFp =
2662
52.0k
    Name == "fsub" || Name == "fdiv" || Name == "fsubr" || Name == "fdivr";
2663
52.0k
  if (IsFp && Operands.size() == 1) {
2664
129
    const char *Repl = StringSwitch<const char *>(Name)
2665
129
      .Case("fsub", "fsubp")
2666
129
      .Case("fdiv", "fdivp")
2667
129
      .Case("fsubr", "fsubrp")
2668
129
      .Case("fdivr", "fdivrp");
2669
129
    static_cast<X86Operand &>(*Operands[0]).setTokenValue(Repl);
2670
129
  }
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
52.0k
  if ((Name == "outb" || Name == "outw" || Name == "outl" || Name == "out") &&
2676
87
      Operands.size() == 3) {
2677
27
    X86Operand &Op = (X86Operand &)*Operands.back();
2678
27
    if (Op.isMem() && Op.Mem.SegReg == 0 &&
2679
25
        isa<MCConstantExpr>(Op.Mem.Disp) &&
2680
24
        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
27
  }
2686
  // Same hack for "in[bwl]? (%dx), %al" -> "inb %dx, %al".
2687
52.0k
  if ((Name == "inb" || Name == "inw" || Name == "inl" || Name == "in") &&
2688
52
      Operands.size() == 3) {
2689
17
    X86Operand &Op = (X86Operand &)*Operands[1];
2690
17
    if (Op.isMem() && Op.Mem.SegReg == 0 &&
2691
12
        isa<MCConstantExpr>(Op.Mem.Disp) &&
2692
4
        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
17
  }
2698
2699
52.0k
  SmallVector<std::unique_ptr<MCParsedAsmOperand>, 2> TmpOperands;
2700
52.0k
  bool HadVerifyError = false;
2701
2702
  // Append default arguments to "ins[bwld]"
2703
52.0k
  if (Name.startswith("ins") && 
2704
36
      (Operands.size() == 1 || Operands.size() == 3) &&
2705
23
      (Name == "insb" || Name == "insw" || Name == "insl" || Name == "insd" ||
2706
19
       Name == "ins")) {
2707
    
2708
12
    AddDefaultSrcDestOperands(TmpOperands,
2709
12
                              X86Operand::CreateReg(X86::DX, NameLoc, NameLoc),
2710
12
                              DefaultMemDIOperand(NameLoc));
2711
12
    HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2712
12
  }
2713
2714
  // Append default arguments to "outs[bwld]"
2715
52.0k
  if (Name.startswith("outs") && 
2716
4.49k
      (Operands.size() == 1 || Operands.size() == 3) &&
2717
4.49k
      (Name == "outsb" || Name == "outsw" || Name == "outsl" ||
2718
4.48k
       Name == "outsd" || Name == "outs")) {
2719
4.48k
    AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
2720
4.48k
                              X86Operand::CreateReg(X86::DX, NameLoc, NameLoc));
2721
4.48k
    HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2722
4.48k
  }
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
52.0k
  if (Name.startswith("lods") &&
2728
193
      (Operands.size() == 1 || Operands.size() == 2) &&
2729
192
      (Name == "lods" || Name == "lodsb" || Name == "lodsw" ||
2730
186
       Name == "lodsl" || Name == "lodsd" || Name == "lodsq")) {
2731
186
    TmpOperands.push_back(DefaultMemSIOperand(NameLoc));
2732
186
    HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2733
186
  }
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
52.0k
  if (Name.startswith("stos") &&
2739
278
      (Operands.size() == 1 || Operands.size() == 2) &&
2740
276
      (Name == "stos" || Name == "stosb" || Name == "stosw" ||
2741
263
       Name == "stosl" || Name == "stosd" || Name == "stosq")) {
2742
263
    TmpOperands.push_back(DefaultMemDIOperand(NameLoc));
2743
263
    HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2744
263
  }
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
52.0k
  if (Name.startswith("scas") &&
2750
116
      (Operands.size() == 1 || Operands.size() == 2) &&
2751
115
      (Name == "scas" || Name == "scasb" || Name == "scasw" ||
2752
110
       Name == "scasl" || Name == "scasd" || Name == "scasq")) {
2753
110
    TmpOperands.push_back(DefaultMemDIOperand(NameLoc));
2754
110
    HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2755
110
  }
2756
2757
  // Add default SI and DI operands to "cmps[bwlq]".
2758
52.0k
  if (Name.startswith("cmps") &&
2759
319
      (Operands.size() == 1 || Operands.size() == 3) &&
2760
314
      (Name == "cmps" || Name == "cmpsb" || Name == "cmpsw" ||
2761
281
       Name == "cmpsl" || Name == "cmpsd" || Name == "cmpsq")) {
2762
281
    AddDefaultSrcDestOperands(TmpOperands, DefaultMemDIOperand(NameLoc),
2763
281
                              DefaultMemSIOperand(NameLoc));
2764
281
    HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2765
281
  }
2766
2767
  // Add default SI and DI operands to "movs[bwlq]".
2768
52.0k
  if (((Name.startswith("movs") &&
2769
3.11k
        (Name == "movs" || Name == "movsb" || Name == "movsw" ||
2770
3.05k
         Name == "movsl" || Name == "movsd" || Name == "movsq")) ||
2771
48.9k
       (Name.startswith("smov") &&
2772
13
        (Name == "smov" || Name == "smovb" || Name == "smovw" ||
2773
8
         Name == "smovl" || Name == "smovd" || Name == "smovq"))) &&
2774
3.11k
      (Operands.size() == 1 || Operands.size() == 3)) {
2775
3.11k
    if (Name == "movsd" && Operands.size() == 1)
2776
1
      Operands.back() = X86Operand::CreateToken("movsl", NameLoc);
2777
3.11k
    AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
2778
3.11k
                              DefaultMemDIOperand(NameLoc));
2779
3.11k
    HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2780
3.11k
  }
2781
2782
  // Check if we encountered an error for one the string insturctions
2783
52.0k
  if (HadVerifyError) {
2784
0
    ErrorCode = KS_ERR_ASM_X86_INVALIDOPERAND;
2785
0
    return HadVerifyError;
2786
0
  }
2787
2788
  // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>.  Canonicalize to
2789
  // "shift <op>".
2790
52.0k
  if ((Name.startswith("shr") || Name.startswith("sar") ||
2791
52.0k
       Name.startswith("shl") || Name.startswith("sal") ||
2792
51.8k
       Name.startswith("rcl") || Name.startswith("rcr") ||
2793
51.8k
       Name.startswith("rol") || Name.startswith("ror")) &&
2794
316
      Operands.size() == 3) {
2795
103
    if (isParsingIntelSyntax()) {
2796
      // Intel syntax
2797
81
      X86Operand &Op1 = static_cast<X86Operand &>(*Operands[2]);
2798
81
      if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2799
59
          cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2800
1
        Operands.pop_back();
2801
81
    } else {
2802
22
      X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2803
22
      if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2804
0
          cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2805
0
        Operands.erase(Operands.begin() + 1);
2806
22
    }
2807
103
  }
2808
2809
  // Transforms "xlat mem8" into "xlatb"
2810
52.0k
  if ((Name == "xlat" || Name == "xlatb") && Operands.size() == 2) {
2811
89
    X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2812
89
    if (Op1.isMem8()) {
2813
87
      Warning(Op1.getStartLoc(), "memory operand is only for determining the "
2814
87
                                 "size, (R|E)BX will be used for the location");
2815
87
      Operands.pop_back();
2816
87
      static_cast<X86Operand &>(*Operands[0]).setTokenValue("xlatb");
2817
87
    }
2818
89
  }
2819
2820
52.0k
  return false;
2821
52.0k
}
2822
2823
bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops)
2824
45.4k
{
2825
45.4k
  switch (Inst.getOpcode()) {
2826
45.4k
  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
45.4k
  }
2879
45.4k
}
2880
2881
static const char *getSubtargetFeatureName(uint64_t Val);
2882
2883
void X86AsmParser::EmitInstruction(MCInst &Inst, OperandVector &Operands,
2884
47.9k
                                   MCStreamer &Out, unsigned int &KsError) {
2885
47.9k
  Instrumentation->InstrumentAndEmitInstruction(Inst, Operands, getContext(),
2886
47.9k
                                                MII, Out, KsError);
2887
47.9k
}
2888
2889
bool X86AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2890
                                           OperandVector &Operands,
2891
                                           MCStreamer &Out, uint64_t &ErrorInfo,
2892
52.0k
                                           bool MatchingInlineAsm, unsigned int &ErrorCode, uint64_t &Address) {
2893
52.0k
  if (isParsingIntelSyntax())
2894
46.2k
    return MatchAndEmitIntelInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2895
46.2k
                                        MatchingInlineAsm, ErrorCode, Address);
2896
5.80k
  return MatchAndEmitATTInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2897
5.80k
                                    MatchingInlineAsm, ErrorCode, Address);
2898
52.0k
}
2899
2900
void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op,
2901
                                     OperandVector &Operands, MCStreamer &Out,
2902
52.0k
                                     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
52.0k
  const char *Repl = StringSwitch<const char *>(Op.getToken())
2907
52.0k
                         .Case("finit", "fninit")
2908
52.0k
                         .Case("fsave", "fnsave")
2909
52.0k
                         .Case("fstcw", "fnstcw")
2910
52.0k
                         .Case("fstcww", "fnstcw")
2911
52.0k
                         .Case("fstenv", "fnstenv")
2912
52.0k
                         .Case("fstsw", "fnstsw")
2913
52.0k
                         .Case("fstsww", "fnstsw")
2914
52.0k
                         .Case("fclex", "fnclex")
2915
52.0k
                         .Default(nullptr);
2916
52.0k
  if (Repl) {
2917
1.63k
    MCInst Inst;
2918
1.63k
    Inst.setOpcode(X86::WAIT);
2919
1.63k
    Inst.setLoc(IDLoc);
2920
1.63k
    unsigned int KsError = 0;
2921
1.63k
    if (!MatchingInlineAsm)
2922
1.63k
      EmitInstruction(Inst, Operands, Out, KsError);
2923
1.63k
    Operands[0] = X86Operand::CreateToken(Repl, IDLoc);
2924
1.63k
  }
2925
52.0k
}
2926
2927
bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
2928
2
                                       bool MatchingInlineAsm) {
2929
2
  assert(ErrorInfo && "Unknown missing feature!");
2930
  //ArrayRef<SMRange> EmptyRanges = None;
2931
2
  SmallString<126> Msg;
2932
2
  raw_svector_ostream OS(Msg);
2933
2
  OS << "instruction requires:";
2934
2
  uint64_t Mask = 1;
2935
128
  for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
2936
126
    if (ErrorInfo & Mask)
2937
2
      OS << ' ' << getSubtargetFeatureName(ErrorInfo & Mask);
2938
126
    Mask <<= 1;
2939
126
  }
2940
  //return Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
2941
2
  return true;
2942
2
}
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
5.80k
{
2950
5.80k
  assert(!Operands.empty() && "Unexpect empty operand list!");
2951
5.80k
  X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2952
5.80k
  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
5.80k
  MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2957
2958
5.80k
  bool WasOriginallyInvalidOperand = false;
2959
5.80k
  MCInst Inst;
2960
2961
  // First, try a direct match.
2962
5.80k
  switch (MatchInstructionImpl(Operands, Inst,
2963
5.80k
                               ErrorInfo, MatchingInlineAsm,
2964
5.80k
                               isParsingIntelSyntax())) {
2965
0
  default: llvm_unreachable("Unexpected match result!");
2966
3.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
3.10k
    if (!MatchingInlineAsm)
2971
3.10k
      while (processInstruction(Inst, Operands))
2972
0
        ;
2973
2974
3.10k
    Inst.setLoc(IDLoc);
2975
3.10k
    if (!MatchingInlineAsm) {
2976
3.10k
      EmitInstruction(Inst, Operands, Out, ErrorCode);
2977
3.10k
      if (ErrorCode)
2978
0
          return true;
2979
3.10k
    }
2980
3.10k
    Opcode = Inst.getOpcode();
2981
3.10k
    return false;
2982
2
  case Match_MissingFeature:
2983
2
    return ErrorMissingFeature(IDLoc, ErrorInfo, MatchingInlineAsm);
2984
119
  case Match_InvalidOperand:
2985
119
    WasOriginallyInvalidOperand = true;
2986
119
    break;
2987
2.57k
  case Match_MnemonicFail:
2988
2.57k
    break;
2989
5.80k
  }
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
2.69k
  StringRef Base = Op.getToken();
2998
2.69k
  SmallString<16> Tmp;
2999
2.69k
  Tmp += Base;
3000
2.69k
  Tmp += ' ';
3001
2.69k
  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
2.69k
  const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0";
3010
3011
  // Check for the various suffix matches.
3012
2.69k
  uint64_t ErrorInfoIgnore;
3013
2.69k
  uint64_t ErrorInfoMissingFeature = 0; // Init suppresses compiler warnings.
3014
2.69k
  unsigned Match[4];
3015
3016
13.4k
  for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I) {
3017
10.7k
    Tmp.back() = Suffixes[I];
3018
10.7k
    Match[I] = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
3019
10.7k
                                  MatchingInlineAsm, isParsingIntelSyntax());
3020
    // If this returned as a missing feature failure, remember that.
3021
10.7k
    if (Match[I] == Match_MissingFeature)
3022
4
      ErrorInfoMissingFeature = ErrorInfoIgnore;
3023
10.7k
  }
3024
3025
  // Restore the old token.
3026
2.69k
  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
2.69k
  unsigned NumSuccessfulMatches =
3032
2.69k
      std::count(std::begin(Match), std::end(Match), Match_Success);
3033
2.69k
  if (NumSuccessfulMatches == 1) {
3034
865
    Inst.setLoc(IDLoc);
3035
865
    if (!MatchingInlineAsm) {
3036
865
      EmitInstruction(Inst, Operands, Out, ErrorCode);
3037
865
      if (ErrorCode)
3038
0
          return true;
3039
865
    }
3040
865
    Opcode = Inst.getOpcode();
3041
865
    return false;
3042
865
  }
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
1.83k
  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
45
    ErrorCode = KS_ERR_ASM_X86_INVALIDOPERAND;
3070
    //Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
3071
45
    return true;
3072
45
  }
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
1.78k
  if (std::count(std::begin(Match), std::end(Match), Match_MnemonicFail) == 4) {
3079
1.62k
    if (!WasOriginallyInvalidOperand) {
3080
      //ArrayRef<SMRange> Ranges =
3081
      //    MatchingInlineAsm ? EmptyRanges : Op.getLocRange();
3082
      //return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'",
3083
      //             Ranges, MatchingInlineAsm);
3084
1.56k
      ErrorCode = KS_ERR_ASM_X86_MNEMONICFAIL;
3085
1.56k
      return true;
3086
1.56k
    }
3087
3088
    // Recover location info for the operand if we know which was the problem.
3089
65
    if (ErrorInfo != ~0ULL) {
3090
65
      if (ErrorInfo >= Operands.size()) {
3091
          //printf("*** >>> InvalidOperand 22\n");
3092
31
          ErrorCode = KS_ERR_ASM_X86_INVALIDOPERAND;
3093
          //return Error(IDLoc, "too few operands for instruction",
3094
          //             EmptyRanges, MatchingInlineAsm);
3095
31
          return true;
3096
31
      }
3097
3098
34
      X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo];
3099
34
      if (Operand.getStartLoc().isValid()) {
3100
        //SMRange OperandRange = Operand.getLocRange();
3101
        //return Error(Operand.getStartLoc(), "invalid operand for instruction",
3102
        //             OperandRange, MatchingInlineAsm);
3103
34
        return true;
3104
34
      }
3105
34
    }
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
65
  }
3113
3114
  // If one instruction matched with a missing feature, report this as a
3115
  // missing feature.
3116
162
  if (std::count(std::begin(Match), std::end(Match),
3117
162
                 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
162
  if (std::count(std::begin(Match), std::end(Match),
3128
162
                 Match_InvalidOperand) == 1) {
3129
    //printf("*** >>> InvalidOperand 44\n");
3130
9
    ErrorCode = KS_ERR_ASM_X86_INVALIDOPERAND;
3131
    //return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
3132
    //             MatchingInlineAsm);
3133
9
    return true;
3134
9
  }
3135
3136
  // If all of these were an outright failure, report it in a useless way.
3137
153
  ErrorCode = KS_ERR_ASM_X86_MNEMONICFAIL;
3138
  //Error(IDLoc, "unknown use of instruction mnemonic without a size suffix",
3139
  //      EmptyRanges, MatchingInlineAsm);
3140
153
  return true;
3141
162
}
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
46.2k
{
3149
46.2k
  assert(!Operands.empty() && "Unexpect empty operand list!");
3150
46.2k
  X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
3151
46.2k
  assert(Op.isToken() && "Leading operand should always be a mnemonic!");
3152
46.2k
  StringRef Mnemonic = Op.getToken();
3153
  //ArrayRef<SMRange> EmptyRanges = None;
3154
3155
  // First, handle aliases that expand to multiple instructions.
3156
46.2k
  MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
3157
3158
46.2k
  MCInst Inst(Address);
3159
3160
  // Find one unsized memory operand, if present.
3161
46.2k
  X86Operand *UnsizedMemOp = nullptr;
3162
96.2k
  for (const auto &Op : Operands) {
3163
96.2k
    X86Operand *X86Op = static_cast<X86Operand *>(Op.get());
3164
96.2k
    if (X86Op->isMemUnsized())
3165
36.7k
      UnsizedMemOp = X86Op;
3166
96.2k
  }
3167
3168
  // Allow some instructions to have implicitly pointer-sized operands.  This is
3169
  // compatible with gas.
3170
46.2k
  if (UnsizedMemOp) {
3171
33.2k
    static const char *const PtrSizedInstrs[] = {"call", "jmp", "push"};
3172
77.7k
    for (const char *Instr : PtrSizedInstrs) {
3173
77.7k
      if (Mnemonic == Instr) {
3174
11.5k
        UnsizedMemOp->Mem.Size = getPointerWidth();
3175
11.5k
        break;
3176
11.5k
      }
3177
77.7k
    }
3178
33.2k
  }
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
46.2k
  SmallVector<unsigned, 8> Match;
3184
46.2k
  uint64_t ErrorInfoMissingFeature = 0;
3185
46.2k
  if (UnsizedMemOp && UnsizedMemOp->isMemUnsized()) {
3186
21.6k
    static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
3187
173k
    for (unsigned Size : MopSizes) {
3188
173k
      UnsizedMemOp->Mem.Size = Size;
3189
173k
      uint64_t ErrorInfoIgnore;
3190
173k
      unsigned LastOpcode = Inst.getOpcode();
3191
173k
      unsigned M =
3192
173k
          MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
3193
173k
                               MatchingInlineAsm, isParsingIntelSyntax());
3194
173k
      if (Match.empty() || LastOpcode != Inst.getOpcode())
3195
27.6k
        Match.push_back(M);
3196
3197
      // If this returned as a missing feature failure, remember that.
3198
173k
      if (Match.back() == Match_MissingFeature)
3199
0
        ErrorInfoMissingFeature = ErrorInfoIgnore;
3200
173k
    }
3201
3202
    // Restore the size of the unsized memory operand if we modified it.
3203
21.6k
    if (UnsizedMemOp)
3204
21.6k
      UnsizedMemOp->Mem.Size = 0;
3205
21.6k
  }
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
46.2k
  if (Match.empty()) {
3211
24.5k
    Match.push_back(MatchInstructionImpl(Operands, Inst, ErrorInfo,
3212
24.5k
                                         MatchingInlineAsm,
3213
24.5k
                                         isParsingIntelSyntax()));
3214
    // If this returned as a missing feature failure, remember that.
3215
24.5k
    if (Match.back() == Match_MissingFeature)
3216
1
      ErrorInfoMissingFeature = ErrorInfo;
3217
24.5k
  }
3218
3219
46.2k
  if (push32 && Inst.getOpcode() == X86::PUSH16i8)
3220
25
      Inst.setOpcode(X86::PUSH32i8);
3221
3222
  // Restore the size of the unsized memory operand if we modified it.
3223
46.2k
  if (UnsizedMemOp)
3224
33.2k
    UnsizedMemOp->Mem.Size = 0;
3225
3226
  // If it's a bad mnemonic, all results will be the same.
3227
46.2k
  if (Match.back() == Match_MnemonicFail) {
3228
    //ArrayRef<SMRange> Ranges =
3229
    //    MatchingInlineAsm ? EmptyRanges : Op.getLocRange();
3230
3.20k
    ErrorCode = KS_ERR_ASM_X86_MNEMONICFAIL;
3231
    //return Error(IDLoc, "invalid instruction mnemonic '" + Mnemonic + "'",
3232
    //             Ranges, MatchingInlineAsm);
3233
3.20k
    return true;
3234
3.20k
  }
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
43.0k
  unsigned NumSuccessfulMatches =
3240
43.0k
      std::count(std::begin(Match), std::end(Match), Match_Success);
3241
43.0k
  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
42.3k
    if (!MatchingInlineAsm)
3246
42.3k
      while (processInstruction(Inst, Operands))
3247
0
        ;
3248
42.3k
    Inst.setLoc(IDLoc);
3249
42.3k
    if (!MatchingInlineAsm) {
3250
42.3k
      EmitInstruction(Inst, Operands, Out, ErrorCode);
3251
42.3k
      if (ErrorCode)
3252
12
          return true;
3253
42.3k
    }
3254
42.3k
    Opcode = Inst.getOpcode();
3255
42.3k
    Address = Inst.getAddress(); // Keystone update address
3256
42.3k
    return false;
3257
42.3k
  } else if (NumSuccessfulMatches > 1) {
3258
50
    assert(UnsizedMemOp &&
3259
50
           "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
50
    ErrorCode = KS_ERR_ASM_X86_INVALIDOPERAND;
3269
50
    return true;
3270
50
  }
3271
3272
  // If one instruction matched with a missing feature, report this as a
3273
  // missing feature.
3274
676
  if (std::count(std::begin(Match), std::end(Match),
3275
676
                 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
675
  if (std::count(std::begin(Match), std::end(Match),
3286
675
                 Match_InvalidOperand) == 1) {
3287
    //printf("*** >>> InvalidOperand 66\n");
3288
675
    ErrorCode = KS_ERR_ASM_X86_INVALIDOPERAND;
3289
    //return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
3290
    //             MatchingInlineAsm);
3291
675
    return true;
3292
675
  }
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
675
}
3300
3301
0
bool X86AsmParser::OmitRegisterFromClobberLists(unsigned RegNo) {
3302
0
  return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo);
3303
0
}
3304
3305
300k
bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
3306
300k
  MCAsmParser &Parser = getParser();
3307
300k
  StringRef IDVal = DirectiveID.getIdentifier();
3308
300k
  if (IDVal == ".word")
3309
19.7k
    return ParseDirectiveWord(2, DirectiveID.getLoc());
3310
280k
  else if (IDVal.startswith(".code"))
3311
4.74k
    return ParseDirectiveCode(IDVal, DirectiveID.getLoc());
3312
276k
  else if (IDVal.startswith(".att_syntax")) {
3313
65
    if (getLexer().isNot(AsmToken::EndOfStatement)) {
3314
54
      if (Parser.getTok().getString() == "prefix")
3315
0
        Parser.Lex();
3316
54
      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
54
    }
3322
65
    getParser().setAssemblerDialect(0);
3323
65
    return false;
3324
276k
  } else if (IDVal.startswith(".intel_syntax")) {
3325
72
    getParser().setAssemblerDialect(1);
3326
72
    if (getLexer().isNot(AsmToken::EndOfStatement)) {
3327
41
      if (Parser.getTok().getString() == "noprefix")
3328
0
        Parser.Lex();
3329
41
      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
41
    }
3335
72
    return false;
3336
276k
  } else if (IDVal == ".even")
3337
1.48k
    return parseDirectiveEven(DirectiveID.getLoc());
3338
274k
  return true;
3339
300k
}
3340
3341
/// parseDirectiveEven
3342
///  ::= .even
3343
1.48k
bool X86AsmParser::parseDirectiveEven(SMLoc L) {
3344
1.48k
  const MCSection *Section = getStreamer().getCurrentSection().first;
3345
1.48k
  if (getLexer().isNot(AsmToken::EndOfStatement)) {
3346
657
    TokError("unexpected token in directive");
3347
657
    return false;  
3348
657
  }
3349
831
  if (!Section) {
3350
0
    getStreamer().InitSections(false);
3351
0
    Section = getStreamer().getCurrentSection().first;
3352
0
  }
3353
831
  if (Section->UseCodeAlign())
3354
722
    getStreamer().EmitCodeAlignment(2, 0);
3355
109
  else
3356
109
    getStreamer().EmitValueToAlignment(2, 0, 1, 0);
3357
831
  return false;
3358
1.48k
}
3359
/// ParseDirectiveWord
3360
///  ::= .word [ expression (, expression)* ]
3361
19.7k
bool X86AsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
3362
19.7k
  MCAsmParser &Parser = getParser();
3363
19.7k
  if (getLexer().isNot(AsmToken::EndOfStatement)) {
3364
40.2k
    for (;;) {
3365
40.2k
      const MCExpr *Value;
3366
40.2k
      SMLoc ExprLoc = getLexer().getLoc();
3367
40.2k
      if (getParser().parseExpression(Value))
3368
515
        return false;
3369
3370
39.7k
      if (const auto *MCE = dyn_cast<MCConstantExpr>(Value)) {
3371
3.97k
        bool Error;
3372
        //assert(Size <= 8 && "Invalid size");
3373
3.97k
        if (Size > 8)
3374
0
            return true;
3375
3.97k
        uint64_t IntValue = MCE->getValue();
3376
3.97k
        if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))
3377
          //return Error(ExprLoc, "literal value out of range for directive");
3378
214
          return true;
3379
3.75k
        getStreamer().EmitIntValue(IntValue, Size, Error);
3380
3.75k
        if (Error)
3381
0
            return true;
3382
35.7k
      } else {
3383
35.7k
        getStreamer().EmitValue(Value, Size, ExprLoc);
3384
35.7k
      }
3385
3386
39.4k
      if (getLexer().is(AsmToken::EndOfStatement))
3387
15.9k
        break;
3388
3389
      // FIXME: Improve diagnostic.
3390
23.5k
      if (getLexer().isNot(AsmToken::Comma)) {
3391
        //Error(L, "unexpected token in directive");
3392
929
        return false;
3393
929
      }
3394
22.5k
      Parser.Lex();
3395
22.5k
    }
3396
17.6k
  }
3397
3398
18.0k
  Parser.Lex();
3399
18.0k
  return false;
3400
19.7k
}
3401
3402
/// ParseDirectiveCode
3403
///  ::= .code16 | .code32 | .code64
3404
4.74k
bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
3405
4.74k
  MCAsmParser &Parser = getParser();
3406
4.74k
  if (IDVal == ".code16") {
3407
34
    Parser.Lex();
3408
34
    if (!is16BitMode()) {
3409
21
      SwitchMode(X86::Mode16Bit);
3410
21
      getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
3411
21
    }
3412
4.71k
  } else if (IDVal == ".code32") {
3413
1.14k
    Parser.Lex();
3414
1.14k
    if (!is32BitMode()) {
3415
169
      SwitchMode(X86::Mode32Bit);
3416
169
      getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
3417
169
    }
3418
3.57k
  } else if (IDVal == ".code64") {
3419
807
    Parser.Lex();
3420
807
    if (!is64BitMode()) {
3421
342
      SwitchMode(X86::Mode64Bit);
3422
342
      getParser().getStreamer().EmitAssemblerFlag(MCAF_Code64);
3423
342
    }
3424
2.76k
  } else {
3425
    //Error(L, "unknown directive " + IDVal);
3426
2.76k
    return false;
3427
2.76k
  }
3428
3429
1.98k
  return false;
3430
4.74k
}
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"