Coverage Report

Created: 2026-04-01 07:47

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