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/X86Operand.h
Line
Count
Source
1
//===-- X86Operand.h - Parsed X86 machine instruction --------------------===//
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
#ifndef LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H
11
#define LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H
12
13
#include "X86AsmParserCommon.h"
14
#include "llvm/MC/MCExpr.h"
15
#include "llvm/MC/MCInst.h"
16
#include "llvm/MC/MCRegisterInfo.h"
17
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
18
#include "llvm/ADT/STLExtras.h"
19
#include "MCTargetDesc/X86MCTargetDesc.h"
20
21
namespace llvm_ks {
22
23
/// X86Operand - Instances of this class represent a parsed X86 machine
24
/// instruction.
25
struct X86Operand : public MCParsedAsmOperand {
26
  enum KindTy {
27
    Token,
28
    Register,
29
    Immediate,
30
    Memory
31
  } Kind;
32
33
  SMLoc StartLoc, EndLoc;
34
  SMLoc OffsetOfLoc;
35
  StringRef SymName;
36
  void *OpDecl;
37
  bool AddressOf;
38
39
  struct TokOp {
40
    const char *Data;
41
    unsigned Length;
42
  };
43
44
  struct RegOp {
45
    unsigned RegNo;
46
  };
47
48
  struct ImmOp {
49
    const MCExpr *Val;
50
  };
51
52
  struct MemOp {
53
    unsigned SegReg;
54
    const MCExpr *Disp;
55
    unsigned BaseReg;
56
    unsigned IndexReg;
57
    unsigned Scale;
58
    unsigned Size;
59
    unsigned ModeSize;
60
  };
61
62
  union {
63
    struct TokOp Tok;
64
    struct RegOp Reg;
65
    struct ImmOp Imm;
66
    struct MemOp Mem;
67
  };
68
69
  X86Operand(KindTy K, SMLoc Start, SMLoc End)
70
287k
    : Kind(K), StartLoc(Start), EndLoc(End) {}
71
72
0
  StringRef getSymName() override { return SymName; }
73
0
  void *getOpDecl() override { return OpDecl; }
74
75
  /// getStartLoc - Get the location of the first token of this operand.
76
180
  SMLoc getStartLoc() const override { return StartLoc; }
77
  /// getEndLoc - Get the location of the last token of this operand.
78
0
  SMLoc getEndLoc() const override { return EndLoc; }
79
  /// getLocRange - Get the range between the first and last token of this
80
  /// operand.
81
0
  SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
82
  /// getOffsetOfLoc - Get the location of the offset operator.
83
0
  SMLoc getOffsetOfLoc() const override { return OffsetOfLoc; }
84
85
0
  void print(raw_ostream &OS) const override {}
86
87
465k
  StringRef getToken() const {
88
465k
    assert(Kind == Token && "Invalid access!");
89
465k
    return StringRef(Tok.Data, Tok.Length);
90
465k
  }
91
7.49k
  void setTokenValue(StringRef Value) {
92
7.49k
    assert(Kind == Token && "Invalid access!");
93
7.49k
    Tok.Data = Value.data();
94
7.49k
    Tok.Length = Value.size();
95
7.49k
  }
96
97
372k
  unsigned getReg() const override {
98
372k
    assert(Kind == Register && "Invalid access!");
99
372k
    return Reg.RegNo;
100
372k
  }
101
102
2.31k
  const MCExpr *getImm() const {
103
2.31k
    assert(Kind == Immediate && "Invalid access!");
104
2.31k
    return Imm.Val;
105
2.31k
  }
106
107
247k
  const MCExpr *getMemDisp() const {
108
247k
    assert(Kind == Memory && "Invalid access!");
109
247k
    return Mem.Disp;
110
247k
  }
111
196k
  unsigned getMemSegReg() const {
112
196k
    assert(Kind == Memory && "Invalid access!");
113
196k
    return Mem.SegReg;
114
196k
  }
115
286k
  unsigned getMemBaseReg() const {
116
286k
    assert(Kind == Memory && "Invalid access!");
117
286k
    return Mem.BaseReg;
118
286k
  }
119
211k
  unsigned getMemIndexReg() const {
120
211k
    assert(Kind == Memory && "Invalid access!");
121
211k
    return Mem.IndexReg;
122
211k
  }
123
211k
  unsigned getMemScale() const {
124
211k
    assert(Kind == Memory && "Invalid access!");
125
211k
    return Mem.Scale;
126
211k
  }
127
0
  unsigned getMemModeSize() const {
128
0
    assert(Kind == Memory && "Invalid access!");
129
0
    return Mem.ModeSize;
130
0
  }
131
132
959k
  bool isToken() const override {return Kind == Token; }
133
134
17.9k
  bool isImm() const override { return Kind == Immediate; }
135
136
1.01k
  bool isImmSExti16i8() const {
137
1.01k
    if (!isImm())
138
542
      return false;
139
140
    // If this isn't a constant expr, just assume it fits and let relaxation
141
    // handle it.
142
468
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
143
468
    if (!CE)
144
258
      return true;
145
146
    // Otherwise, check the value is in a range that makes sense for this
147
    // extension.
148
210
    return isImmSExti16i8Value(CE->getValue());
149
468
  }
150
753
  bool isImmSExti32i8() const {
151
753
    if (!isImm())
152
504
      return false;
153
154
    // If this isn't a constant expr, just assume it fits and let relaxation
155
    // handle it.
156
249
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
157
249
    if (!CE)
158
87
      return true;
159
160
    // Otherwise, check the value is in a range that makes sense for this
161
    // extension.
162
162
    return isImmSExti32i8Value(CE->getValue());
163
249
  }
164
679
  bool isImmSExti64i8() const {
165
679
    if (!isImm())
166
314
      return false;
167
168
    // If this isn't a constant expr, just assume it fits and let relaxation
169
    // handle it.
170
365
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
171
365
    if (!CE)
172
178
      return true;
173
174
    // Otherwise, check the value is in a range that makes sense for this
175
    // extension.
176
187
    return isImmSExti64i8Value(CE->getValue());
177
365
  }
178
582
  bool isImmSExti64i32() const {
179
582
    if (!isImm())
180
403
      return false;
181
182
    // If this isn't a constant expr, just assume it fits and let relaxation
183
    // handle it.
184
179
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
185
179
    if (!CE)
186
37
      return true;
187
188
    // Otherwise, check the value is in a range that makes sense for this
189
    // extension.
190
142
    return isImmSExti64i32Value(CE->getValue());
191
179
  }
192
193
1.19k
  bool isImmUnsignedi8() const {
194
1.19k
    if (!isImm()) return false;
195
336
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
196
336
    if (!CE) return false;
197
227
    return isImmUnsignedi8Value(CE->getValue());
198
336
  }
199
200
0
  bool isOffsetOf() const override {
201
0
    return OffsetOfLoc.getPointer();
202
0
  }
203
204
0
  bool needAddressOf() const override {
205
0
    return AddressOf;
206
0
  }
207
208
2.39k
  bool isMem() const override { return Kind == Memory; }
209
181k
  bool isMemUnsized() const {
210
181k
    return Kind == Memory && Mem.Size == 0;
211
181k
  }
212
67.4k
  bool isMem8() const {
213
67.4k
    return Kind == Memory && (!Mem.Size || Mem.Size == 8);
214
67.4k
  }
215
59.7k
  bool isMem16() const {
216
59.7k
    return Kind == Memory && (!Mem.Size || Mem.Size == 16);
217
59.7k
  }
218
97.0k
  bool isMem32() const {
219
97.0k
    return Kind == Memory && (!Mem.Size || Mem.Size == 32);
220
97.0k
  }
221
61.2k
  bool isMem64() const {
222
61.2k
    return Kind == Memory && (!Mem.Size || Mem.Size == 64);
223
61.2k
  }
224
16
  bool isMem80() const {
225
16
    return Kind == Memory && (!Mem.Size || Mem.Size == 80);
226
16
  }
227
58
  bool isMem128() const {
228
58
    return Kind == Memory && (!Mem.Size || Mem.Size == 128);
229
58
  }
230
53
  bool isMem256() const {
231
53
    return Kind == Memory && (!Mem.Size || Mem.Size == 256);
232
53
  }
233
24
  bool isMem512() const {
234
24
    return Kind == Memory && (!Mem.Size || Mem.Size == 512);
235
24
  }
236
237
0
  bool isMemVX32() const {
238
0
    return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
239
0
      getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM15;
240
0
  }
241
0
  bool isMemVX32X() const {
242
0
    return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
243
0
      getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM31;
244
0
  }
245
0
  bool isMemVY32() const {
246
0
    return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
247
0
      getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM15;
248
0
  }
249
0
  bool isMemVY32X() const {
250
0
    return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
251
0
      getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM31;
252
0
  }
253
0
  bool isMemVX64() const {
254
0
    return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
255
0
      getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM15;
256
0
  }
257
0
  bool isMemVX64X() const {
258
0
    return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
259
0
      getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM31;
260
0
  }
261
0
  bool isMemVY64() const {
262
0
    return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
263
0
      getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM15;
264
0
  }
265
0
  bool isMemVY64X() const {
266
0
    return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
267
0
      getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM31;
268
0
  }
269
0
  bool isMemVZ32() const {
270
0
    return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
271
0
      getMemIndexReg() >= X86::ZMM0 && getMemIndexReg() <= X86::ZMM31;
272
0
  }
273
0
  bool isMemVZ64() const {
274
0
    return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
275
0
      getMemIndexReg() >= X86::ZMM0 && getMemIndexReg() <= X86::ZMM31;
276
0
  }
277
278
139k
  bool isAbsMem() const {
279
139k
    return (Kind == Memory) && !getMemSegReg() && !getMemBaseReg() &&
280
137k
      !getMemIndexReg() && (getMemScale() == 1) && (Mem.ModeSize == 0 || Mem.Size == 0);
281
139k
  }
282
3
  bool isAVX512RC() const{
283
3
      return isImm();
284
3
  }
285
286
0
  bool isAbsMem16() const {
287
0
    return isAbsMem() && Mem.ModeSize == 16;
288
0
  }
289
290
23.0k
  bool isSrcIdx() const {
291
23.0k
    return !getMemIndexReg() && getMemScale() == 1 &&
292
23.0k
      (getMemBaseReg() == X86::RSI || getMemBaseReg() == X86::ESI ||
293
22.9k
       getMemBaseReg() == X86::SI) && isa<MCConstantExpr>(getMemDisp()) &&
294
22.9k
      cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
295
23.0k
  }
296
54.2k
  bool isSrcIdx8() const {
297
54.2k
    return isMem8() && isSrcIdx();
298
54.2k
  }
299
2.11k
  bool isSrcIdx16() const {
300
2.11k
    return isMem16() && isSrcIdx();
301
2.11k
  }
302
74.4k
  bool isSrcIdx32() const {
303
74.4k
    return isMem32() && isSrcIdx();
304
74.4k
  }
305
24.4k
  bool isSrcIdx64() const {
306
24.4k
    return isMem64() && isSrcIdx();
307
24.4k
  }
308
309
25.5k
  bool isDstIdx() const {
310
25.5k
    return !getMemIndexReg() && getMemScale() == 1 &&
311
25.5k
      (getMemSegReg() == 0 || getMemSegReg() == X86::ES) &&
312
25.5k
      (getMemBaseReg() == X86::RDI || getMemBaseReg() == X86::EDI ||
313
25.2k
       getMemBaseReg() == X86::DI) && isa<MCConstantExpr>(getMemDisp()) &&
314
25.2k
      cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
315
25.5k
  }
316
1.67k
  bool isDstIdx8() const {
317
1.67k
    return isMem8() && isDstIdx();
318
1.67k
  }
319
7.26k
  bool isDstIdx16() const {
320
7.26k
    return isMem16() && isDstIdx();
321
7.26k
  }
322
2.62k
  bool isDstIdx32() const {
323
2.62k
    return isMem32() && isDstIdx();
324
2.62k
  }
325
24.8k
  bool isDstIdx64() const {
326
24.8k
    return isMem64() && isDstIdx();
327
24.8k
  }
328
329
52.4k
  bool isMemOffs() const {
330
52.4k
    return Kind == Memory && !getMemBaseReg() && !getMemIndexReg() &&
331
14.2k
      getMemScale() == 1;
332
52.4k
  }
333
334
4.43k
  bool isMemOffs16_8() const {
335
4.43k
    return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 8);
336
4.43k
  }
337
6.35k
  bool isMemOffs16_16() const {
338
6.35k
    return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 16);
339
6.35k
  }
340
4.12k
  bool isMemOffs16_32() const {
341
4.12k
    return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 32);
342
4.12k
  }
343
4.43k
  bool isMemOffs32_8() const {
344
4.43k
    return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 8);
345
4.43k
  }
346
6.09k
  bool isMemOffs32_16() const {
347
6.09k
    return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 16);
348
6.09k
  }
349
4.12k
  bool isMemOffs32_32() const {
350
4.12k
    return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 32);
351
4.12k
  }
352
4.12k
  bool isMemOffs32_64() const {
353
4.12k
    return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 64);
354
4.12k
  }
355
4.42k
  bool isMemOffs64_8() const {
356
4.42k
    return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 8);
357
4.42k
  }
358
6.09k
  bool isMemOffs64_16() const {
359
6.09k
    return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 16);
360
6.09k
  }
361
4.12k
  bool isMemOffs64_32() const {
362
4.12k
    return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 32);
363
4.12k
  }
364
4.12k
  bool isMemOffs64_64() const {
365
4.12k
    return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 64);
366
4.12k
  }
367
368
701k
  bool isReg() const override { return Kind == Register; }
369
370
0
  bool isGR32orGR64() const {
371
0
    return Kind == Register &&
372
0
      (X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||
373
0
      X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
374
0
  }
375
376
11.8k
  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
377
    // Add as immediates when possible.
378
11.8k
    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
379
2.20k
      Inst.addOperand(MCOperand::createImm(CE->getValue()));
380
9.64k
    else
381
9.64k
      Inst.addOperand(MCOperand::createExpr(Expr));
382
11.8k
  }
383
384
513
  void addRegOperands(MCInst &Inst, unsigned N) const {
385
513
    assert(N == 1 && "Invalid number of operands!");
386
513
    Inst.addOperand(MCOperand::createReg(getReg()));
387
513
  }
388
389
0
  static unsigned getGR32FromGR64(unsigned RegNo) {
390
0
    switch (RegNo) {
391
0
    default: llvm_unreachable("Unexpected register");
392
0
    case X86::RAX: return X86::EAX;
393
0
    case X86::RCX: return X86::ECX;
394
0
    case X86::RDX: return X86::EDX;
395
0
    case X86::RBX: return X86::EBX;
396
0
    case X86::RBP: return X86::EBP;
397
0
    case X86::RSP: return X86::ESP;
398
0
    case X86::RSI: return X86::ESI;
399
0
    case X86::RDI: return X86::EDI;
400
0
    case X86::R8: return X86::R8D;
401
0
    case X86::R9: return X86::R9D;
402
0
    case X86::R10: return X86::R10D;
403
0
    case X86::R11: return X86::R11D;
404
0
    case X86::R12: return X86::R12D;
405
0
    case X86::R13: return X86::R13D;
406
0
    case X86::R14: return X86::R14D;
407
0
    case X86::R15: return X86::R15D;
408
0
    case X86::RIP: return X86::EIP;
409
0
    }
410
0
  }
411
412
0
  void addGR32orGR64Operands(MCInst &Inst, unsigned N) const {
413
0
    assert(N == 1 && "Invalid number of operands!");
414
0
    unsigned RegNo = getReg();
415
0
    if (X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
416
0
      RegNo = getGR32FromGR64(RegNo);
417
0
    Inst.addOperand(MCOperand::createReg(RegNo));
418
0
  }
419
0
  void addAVX512RCOperands(MCInst &Inst, unsigned N) const {
420
0
    assert(N == 1 && "Invalid number of operands!");
421
0
    addExpr(Inst, getImm());
422
0
  }
423
608
  void addImmOperands(MCInst &Inst, unsigned N) const {
424
608
    assert(N == 1 && "Invalid number of operands!");
425
608
    addExpr(Inst, getImm());
426
608
  }
427
428
11.2k
  void addMemOperands(MCInst &Inst, unsigned N) const {
429
11.2k
    assert((N == 5) && "Invalid number of operands!");
430
11.2k
    Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
431
11.2k
    Inst.addOperand(MCOperand::createImm(getMemScale()));
432
11.2k
    Inst.addOperand(MCOperand::createReg(getMemIndexReg()));
433
11.2k
    addExpr(Inst, getMemDisp());
434
11.2k
    Inst.addOperand(MCOperand::createReg(getMemSegReg()));
435
11.2k
  }
436
437
115k
  void addAbsMemOperands(MCInst &Inst, unsigned N) const {
438
115k
    assert((N == 1) && "Invalid number of operands!");
439
    // Add as immediates when possible.
440
115k
    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
441
91.8k
      Inst.addOperand(MCOperand::createImm(CE->getValue()));
442
24.0k
    else
443
24.0k
      Inst.addOperand(MCOperand::createExpr(getMemDisp()));
444
115k
  }
445
446
19.9k
  void addSrcIdxOperands(MCInst &Inst, unsigned N) const {
447
19.9k
    assert((N == 2) && "Invalid number of operands!");
448
19.9k
    Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
449
19.9k
    Inst.addOperand(MCOperand::createReg(getMemSegReg()));
450
19.9k
  }
451
4.53k
  void addDstIdxOperands(MCInst &Inst, unsigned N) const {
452
4.53k
    assert((N == 1) && "Invalid number of operands!");
453
4.53k
    Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
454
4.53k
  }
455
456
307
  void addMemOffsOperands(MCInst &Inst, unsigned N) const {
457
307
    assert((N == 2) && "Invalid number of operands!");
458
    // Add as immediates when possible.
459
307
    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
460
18
      Inst.addOperand(MCOperand::createImm(CE->getValue()));
461
289
    else
462
289
      Inst.addOperand(MCOperand::createExpr(getMemDisp()));
463
307
    Inst.addOperand(MCOperand::createReg(getMemSegReg()));
464
307
  }
465
466
184k
  static std::unique_ptr<X86Operand> CreateToken(StringRef Str, SMLoc Loc) {
467
184k
    SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size());
468
184k
    auto Res = llvm_ks::make_unique<X86Operand>(Token, Loc, EndLoc);
469
184k
    Res->Tok.Data = Str.data();
470
184k
    Res->Tok.Length = Str.size();
471
184k
    return Res;
472
184k
  }
473
474
  static std::unique_ptr<X86Operand>
475
  CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc,
476
            bool AddressOf = false, SMLoc OffsetOfLoc = SMLoc(),
477
18.7k
            StringRef SymName = StringRef(), void *OpDecl = nullptr) {
478
18.7k
    auto Res = llvm_ks::make_unique<X86Operand>(Register, StartLoc, EndLoc);
479
18.7k
    Res->Reg.RegNo = RegNo;
480
18.7k
    Res->AddressOf = AddressOf;
481
18.7k
    Res->OffsetOfLoc = OffsetOfLoc;
482
18.7k
    Res->SymName = SymName;
483
18.7k
    Res->OpDecl = OpDecl;
484
18.7k
    return Res;
485
18.7k
  }
486
487
  static std::unique_ptr<X86Operand> CreateImm(const MCExpr *Val,
488
23.0k
                                               SMLoc StartLoc, SMLoc EndLoc) {
489
23.0k
    auto Res = llvm_ks::make_unique<X86Operand>(Immediate, StartLoc, EndLoc);
490
23.0k
    Res->Imm.Val = Val;
491
23.0k
    return Res;
492
23.0k
  }
493
494
  /// Create an absolute memory operand.
495
  static std::unique_ptr<X86Operand>
496
  CreateMem(unsigned ModeSize, const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc,
497
            unsigned Size = 0, StringRef SymName = StringRef(),
498
23.4k
            void *OpDecl = nullptr) {
499
23.4k
    auto Res = llvm_ks::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
500
23.4k
    Res->Mem.SegReg   = 0;
501
23.4k
    Res->Mem.Disp     = Disp;
502
23.4k
    Res->Mem.BaseReg  = 0;
503
23.4k
    Res->Mem.IndexReg = 0;
504
23.4k
    Res->Mem.Scale    = 1;
505
23.4k
    Res->Mem.Size     = Size;
506
23.4k
    Res->Mem.ModeSize = ModeSize;
507
23.4k
    Res->SymName      = SymName;
508
23.4k
    Res->OpDecl       = OpDecl;
509
23.4k
    Res->AddressOf    = false;
510
23.4k
    return Res;
511
23.4k
  }
512
513
  /// Create a generalized memory operand.
514
  static std::unique_ptr<X86Operand>
515
  CreateMem(unsigned ModeSize, unsigned SegReg, const MCExpr *Disp,
516
            unsigned BaseReg, unsigned IndexReg, unsigned Scale, SMLoc StartLoc,
517
            SMLoc EndLoc, unsigned Size = 0, StringRef SymName = StringRef(),
518
38.0k
            void *OpDecl = nullptr) {
519
    // We should never just have a displacement, that should be parsed as an
520
    // absolute memory operand.
521
    // assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
522
523
    // The scale should always be one of {1,2,4,8}.
524
38.0k
    assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
525
38.0k
           "Invalid scale!");
526
38.0k
    auto Res = llvm_ks::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
527
38.0k
    Res->Mem.SegReg   = SegReg;
528
38.0k
    Res->Mem.Disp     = Disp;
529
38.0k
    Res->Mem.BaseReg  = BaseReg;
530
38.0k
    Res->Mem.IndexReg = IndexReg;
531
38.0k
    Res->Mem.Scale    = Scale;
532
38.0k
    Res->Mem.Size     = Size;
533
38.0k
    Res->Mem.ModeSize = ModeSize;
534
38.0k
    Res->SymName      = SymName;
535
38.0k
    Res->OpDecl       = OpDecl;
536
38.0k
    Res->AddressOf    = false;
537
38.0k
    return Res;
538
38.0k
  }
539
};
540
541
} // End of namespace llvm_ks
542
543
#endif