Coverage Report

Created: 2026-05-22 06:20

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