Coverage Report

Created: 2026-09-14 06:12

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/keystone/llvm/lib/Target/X86/AsmParser/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
560k
    : 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
849
  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
676k
  StringRef getToken() const {
88
676k
    assert(Kind == Token && "Invalid access!");
89
676k
    return StringRef(Tok.Data, Tok.Length);
90
676k
  }
91
9.26k
  void setTokenValue(StringRef Value) {
92
9.26k
    assert(Kind == Token && "Invalid access!");
93
9.26k
    Tok.Data = Value.data();
94
9.26k
    Tok.Length = Value.size();
95
9.26k
  }
96
97
543k
  unsigned getReg() const override {
98
543k
    assert(Kind == Register && "Invalid access!");
99
543k
    return Reg.RegNo;
100
543k
  }
101
102
3.24k
  const MCExpr *getImm() const {
103
3.24k
    assert(Kind == Immediate && "Invalid access!");
104
3.24k
    return Imm.Val;
105
3.24k
  }
106
107
345k
  const MCExpr *getMemDisp() const {
108
345k
    assert(Kind == Memory && "Invalid access!");
109
345k
    return Mem.Disp;
110
345k
  }
111
264k
  unsigned getMemSegReg() const {
112
264k
    assert(Kind == Memory && "Invalid access!");
113
264k
    return Mem.SegReg;
114
264k
  }
115
415k
  unsigned getMemBaseReg() const {
116
415k
    assert(Kind == Memory && "Invalid access!");
117
415k
    return Mem.BaseReg;
118
415k
  }
119
291k
  unsigned getMemIndexReg() const {
120
291k
    assert(Kind == Memory && "Invalid access!");
121
291k
    return Mem.IndexReg;
122
291k
  }
123
291k
  unsigned getMemScale() const {
124
291k
    assert(Kind == Memory && "Invalid access!");
125
291k
    return Mem.Scale;
126
291k
  }
127
0
  unsigned getMemModeSize() const {
128
0
    assert(Kind == Memory && "Invalid access!");
129
0
    return Mem.ModeSize;
130
0
  }
131
132
1.49M
  bool isToken() const override {return Kind == Token; }
133
134
31.4k
  bool isImm() const override { return Kind == Immediate; }
135
136
1.32k
  bool isImmSExti16i8() const {
137
1.32k
    if (!isImm())
138
722
      return false;
139
140
    // If this isn't a constant expr, just assume it fits and let relaxation
141
    // handle it.
142
600
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
143
600
    if (!CE)
144
284
      return true;
145
146
    // Otherwise, check the value is in a range that makes sense for this
147
    // extension.
148
316
    return isImmSExti16i8Value(CE->getValue());
149
600
  }
150
1.49k
  bool isImmSExti32i8() const {
151
1.49k
    if (!isImm())
152
1.12k
      return false;
153
154
    // If this isn't a constant expr, just assume it fits and let relaxation
155
    // handle it.
156
373
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
157
373
    if (!CE)
158
88
      return true;
159
160
    // Otherwise, check the value is in a range that makes sense for this
161
    // extension.
162
285
    return isImmSExti32i8Value(CE->getValue());
163
373
  }
164
1.54k
  bool isImmSExti64i8() const {
165
1.54k
    if (!isImm())
166
997
      return false;
167
168
    // If this isn't a constant expr, just assume it fits and let relaxation
169
    // handle it.
170
546
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
171
546
    if (!CE)
172
267
      return true;
173
174
    // Otherwise, check the value is in a range that makes sense for this
175
    // extension.
176
279
    return isImmSExti64i8Value(CE->getValue());
177
546
  }
178
1.40k
  bool isImmSExti64i32() const {
179
1.40k
    if (!isImm())
180
1.14k
      return false;
181
182
    // If this isn't a constant expr, just assume it fits and let relaxation
183
    // handle it.
184
264
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
185
264
    if (!CE)
186
58
      return true;
187
188
    // Otherwise, check the value is in a range that makes sense for this
189
    // extension.
190
206
    return isImmSExti64i32Value(CE->getValue());
191
264
  }
192
193
1.51k
  bool isImmUnsignedi8() const {
194
1.51k
    if (!isImm()) return false;
195
514
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
196
514
    if (!CE) return false;
197
407
    return isImmUnsignedi8Value(CE->getValue());
198
514
  }
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.72k
  bool isMem() const override { return Kind == Memory; }
209
249k
  bool isMemUnsized() const {
210
249k
    return Kind == Memory && Mem.Size == 0;
211
249k
  }
212
129k
  bool isMem8() const {
213
129k
    return Kind == Memory && (!Mem.Size || Mem.Size == 8);
214
129k
  }
215
128k
  bool isMem16() const {
216
128k
    return Kind == Memory && (!Mem.Size || Mem.Size == 16);
217
128k
  }
218
107k
  bool isMem32() const {
219
107k
    return Kind == Memory && (!Mem.Size || Mem.Size == 32);
220
107k
  }
221
98.0k
  bool isMem64() const {
222
98.0k
    return Kind == Memory && (!Mem.Size || Mem.Size == 64);
223
98.0k
  }
224
24
  bool isMem80() const {
225
24
    return Kind == Memory && (!Mem.Size || Mem.Size == 80);
226
24
  }
227
104
  bool isMem128() const {
228
104
    return Kind == Memory && (!Mem.Size || Mem.Size == 128);
229
104
  }
230
96
  bool isMem256() const {
231
96
    return Kind == Memory && (!Mem.Size || Mem.Size == 256);
232
96
  }
233
60
  bool isMem512() const {
234
60
    return Kind == Memory && (!Mem.Size || Mem.Size == 512);
235
60
  }
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
177k
  bool isAbsMem() const {
279
177k
    return (Kind == Memory) && !getMemSegReg() && !getMemBaseReg() &&
280
175k
      !getMemIndexReg() && (getMemScale() == 1) && (Mem.ModeSize == 0 || Mem.Size == 0);
281
177k
  }
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
38.4k
  bool isSrcIdx() const {
291
38.4k
    return !getMemIndexReg() && getMemScale() == 1 &&
292
38.4k
      (getMemBaseReg() == X86::RSI || getMemBaseReg() == X86::ESI ||
293
38.3k
       getMemBaseReg() == X86::SI) && isa<MCConstantExpr>(getMemDisp()) &&
294
38.3k
      cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
295
38.4k
  }
296
105k
  bool isSrcIdx8() const {
297
105k
    return isMem8() && isSrcIdx();
298
105k
  }
299
39.4k
  bool isSrcIdx16() const {
300
39.4k
    return isMem16() && isSrcIdx();
301
39.4k
  }
302
73.0k
  bool isSrcIdx32() const {
303
73.0k
    return isMem32() && isSrcIdx();
304
73.0k
  }
305
38.1k
  bool isSrcIdx64() const {
306
38.1k
    return isMem64() && isSrcIdx();
307
38.1k
  }
308
309
38.3k
  bool isDstIdx() const {
310
38.3k
    return !getMemIndexReg() && getMemScale() == 1 &&
311
38.2k
      (getMemSegReg() == 0 || getMemSegReg() == X86::ES) &&
312
38.2k
      (getMemBaseReg() == X86::RDI || getMemBaseReg() == X86::EDI ||
313
37.7k
       getMemBaseReg() == X86::DI) && isa<MCConstantExpr>(getMemDisp()) &&
314
37.6k
      cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
315
38.3k
  }
316
3.23k
  bool isDstIdx8() const {
317
3.23k
    return isMem8() && isDstIdx();
318
3.23k
  }
319
8.78k
  bool isDstIdx16() const {
320
8.78k
    return isMem16() && isDstIdx();
321
8.78k
  }
322
3.70k
  bool isDstIdx32() const {
323
3.70k
    return isMem32() && isDstIdx();
324
3.70k
  }
325
38.5k
  bool isDstIdx64() const {
326
38.5k
    return isMem64() && isDstIdx();
327
38.5k
  }
328
329
82.8k
  bool isMemOffs() const {
330
82.8k
    return Kind == Memory && !getMemBaseReg() && !getMemIndexReg() &&
331
24.2k
      getMemScale() == 1;
332
82.8k
  }
333
334
6.67k
  bool isMemOffs16_8() const {
335
6.67k
    return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 8);
336
6.67k
  }
337
10.6k
  bool isMemOffs16_16() const {
338
10.6k
    return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 16);
339
10.6k
  }
340
6.39k
  bool isMemOffs16_32() const {
341
6.39k
    return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 32);
342
6.39k
  }
343
6.66k
  bool isMemOffs32_8() const {
344
6.66k
    return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 8);
345
6.66k
  }
346
10.1k
  bool isMemOffs32_16() const {
347
10.1k
    return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 16);
348
10.1k
  }
349
6.39k
  bool isMemOffs32_32() const {
350
6.39k
    return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 32);
351
6.39k
  }
352
6.38k
  bool isMemOffs32_64() const {
353
6.38k
    return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 64);
354
6.38k
  }
355
6.65k
  bool isMemOffs64_8() const {
356
6.65k
    return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 8);
357
6.65k
  }
358
10.1k
  bool isMemOffs64_16() const {
359
10.1k
    return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 16);
360
10.1k
  }
361
6.39k
  bool isMemOffs64_32() const {
362
6.39k
    return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 32);
363
6.39k
  }
364
6.38k
  bool isMemOffs64_64() const {
365
6.38k
    return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 64);
366
6.38k
  }
367
368
1.13M
  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
15.9k
  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
377
    // Add as immediates when possible.
378
15.9k
    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
379
3.57k
      Inst.addOperand(MCOperand::createImm(CE->getValue()));
380
12.4k
    else
381
12.4k
      Inst.addOperand(MCOperand::createExpr(Expr));
382
15.9k
  }
383
384
927
  void addRegOperands(MCInst &Inst, unsigned N) const {
385
927
    assert(N == 1 && "Invalid number of operands!");
386
927
    Inst.addOperand(MCOperand::createReg(getReg()));
387
927
  }
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
860
  void addImmOperands(MCInst &Inst, unsigned N) const {
424
860
    assert(N == 1 && "Invalid number of operands!");
425
860
    addExpr(Inst, getImm());
426
860
  }
427
428
15.1k
  void addMemOperands(MCInst &Inst, unsigned N) const {
429
15.1k
    assert((N == 5) && "Invalid number of operands!");
430
15.1k
    Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
431
15.1k
    Inst.addOperand(MCOperand::createImm(getMemScale()));
432
15.1k
    Inst.addOperand(MCOperand::createReg(getMemIndexReg()));
433
15.1k
    addExpr(Inst, getMemDisp());
434
15.1k
    Inst.addOperand(MCOperand::createReg(getMemSegReg()));
435
15.1k
  }
436
437
148k
  void addAbsMemOperands(MCInst &Inst, unsigned N) const {
438
148k
    assert((N == 1) && "Invalid number of operands!");
439
    // Add as immediates when possible.
440
148k
    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
441
119k
      Inst.addOperand(MCOperand::createImm(CE->getValue()));
442
28.8k
    else
443
28.8k
      Inst.addOperand(MCOperand::createExpr(getMemDisp()));
444
148k
  }
445
446
32.6k
  void addSrcIdxOperands(MCInst &Inst, unsigned N) const {
447
32.6k
    assert((N == 2) && "Invalid number of operands!");
448
32.6k
    Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
449
32.6k
    Inst.addOperand(MCOperand::createReg(getMemSegReg()));
450
32.6k
  }
451
6.69k
  void addDstIdxOperands(MCInst &Inst, unsigned N) const {
452
6.69k
    assert((N == 1) && "Invalid number of operands!");
453
6.69k
    Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
454
6.69k
  }
455
456
556
  void addMemOffsOperands(MCInst &Inst, unsigned N) const {
457
556
    assert((N == 2) && "Invalid number of operands!");
458
    // Add as immediates when possible.
459
556
    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
460
12
      Inst.addOperand(MCOperand::createImm(CE->getValue()));
461
544
    else
462
544
      Inst.addOperand(MCOperand::createExpr(getMemDisp()));
463
556
    Inst.addOperand(MCOperand::createReg(getMemSegReg()));
464
556
  }
465
466
419k
  static std::unique_ptr<X86Operand> CreateToken(StringRef Str, SMLoc Loc) {
467
419k
    SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size());
468
419k
    auto Res = llvm_ks::make_unique<X86Operand>(Token, Loc, EndLoc);
469
419k
    Res->Tok.Data = Str.data();
470
419k
    Res->Tok.Length = Str.size();
471
419k
    return Res;
472
419k
  }
473
474
  static std::unique_ptr<X86Operand>
475
  CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc,
476
            bool AddressOf = false, SMLoc OffsetOfLoc = SMLoc(),
477
20.6k
            StringRef SymName = StringRef(), void *OpDecl = nullptr) {
478
20.6k
    auto Res = llvm_ks::make_unique<X86Operand>(Register, StartLoc, EndLoc);
479
20.6k
    Res->Reg.RegNo = RegNo;
480
20.6k
    Res->AddressOf = AddressOf;
481
20.6k
    Res->OffsetOfLoc = OffsetOfLoc;
482
20.6k
    Res->SymName = SymName;
483
20.6k
    Res->OpDecl = OpDecl;
484
20.6k
    return Res;
485
20.6k
  }
486
487
  static std::unique_ptr<X86Operand> CreateImm(const MCExpr *Val,
488
31.6k
                                               SMLoc StartLoc, SMLoc EndLoc) {
489
31.6k
    auto Res = llvm_ks::make_unique<X86Operand>(Immediate, StartLoc, EndLoc);
490
31.6k
    Res->Imm.Val = Val;
491
31.6k
    return Res;
492
31.6k
  }
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
30.8k
            void *OpDecl = nullptr) {
499
30.8k
    auto Res = llvm_ks::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
500
30.8k
    Res->Mem.SegReg   = 0;
501
30.8k
    Res->Mem.Disp     = Disp;
502
30.8k
    Res->Mem.BaseReg  = 0;
503
30.8k
    Res->Mem.IndexReg = 0;
504
30.8k
    Res->Mem.Scale    = 1;
505
30.8k
    Res->Mem.Size     = Size;
506
30.8k
    Res->Mem.ModeSize = ModeSize;
507
30.8k
    Res->SymName      = SymName;
508
30.8k
    Res->OpDecl       = OpDecl;
509
30.8k
    Res->AddressOf    = false;
510
30.8k
    return Res;
511
30.8k
  }
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
57.4k
            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
57.4k
    assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
525
57.4k
           "Invalid scale!");
526
57.4k
    auto Res = llvm_ks::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
527
57.4k
    Res->Mem.SegReg   = SegReg;
528
57.4k
    Res->Mem.Disp     = Disp;
529
57.4k
    Res->Mem.BaseReg  = BaseReg;
530
57.4k
    Res->Mem.IndexReg = IndexReg;
531
57.4k
    Res->Mem.Scale    = Scale;
532
57.4k
    Res->Mem.Size     = Size;
533
57.4k
    Res->Mem.ModeSize = ModeSize;
534
57.4k
    Res->SymName      = SymName;
535
57.4k
    Res->OpDecl       = OpDecl;
536
57.4k
    Res->AddressOf    = false;
537
57.4k
    return Res;
538
57.4k
  }
539
};
540
541
} // End of namespace llvm_ks
542
543
#endif