1//===- X86Operand.h - Parsed X86 machine instruction ------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H
10#define LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H
11
12#include "MCTargetDesc/X86IntelInstPrinter.h"
13#include "MCTargetDesc/X86MCTargetDesc.h"
14#include "X86AsmParserCommon.h"
15#include "llvm/ADT/STLExtras.h"
16#include "llvm/ADT/StringRef.h"
17#include "llvm/MC/MCExpr.h"
18#include "llvm/MC/MCInst.h"
19#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
20#include "llvm/MC/MCRegisterInfo.h"
21#include "llvm/Support/Casting.h"
22#include "llvm/Support/ErrorHandling.h"
23#include "llvm/Support/SMLoc.h"
24#include <cassert>
25#include <memory>
26
27namespace llvm {
28
29/// X86Operand - Instances of this class represent a parsed X86 machine
30/// instruction.
31struct X86Operand final : public MCParsedAsmOperand {
32  enum KindTy { Token, Register, Immediate, Memory, Prefix, DXRegister } Kind;
33
34  SMLoc StartLoc, EndLoc;
35  SMLoc OffsetOfLoc;
36  StringRef SymName;
37  void *OpDecl;
38  bool AddressOf;
39  bool CallOperand;
40
41  struct TokOp {
42    const char *Data;
43    unsigned Length;
44  };
45
46  struct RegOp {
47    unsigned RegNo;
48  };
49
50  struct PrefOp {
51    unsigned Prefixes;
52  };
53
54  struct ImmOp {
55    const MCExpr *Val;
56    bool LocalRef;
57  };
58
59  struct MemOp {
60    unsigned SegReg;
61    const MCExpr *Disp;
62    unsigned BaseReg;
63    unsigned IndexReg;
64    unsigned Scale;
65    unsigned Size;
66    unsigned ModeSize;
67
68    /// If the memory operand is unsized and there are multiple instruction
69    /// matches, prefer the one with this size.
70    unsigned FrontendSize;
71  };
72
73  union {
74    struct TokOp Tok;
75    struct RegOp Reg;
76    struct ImmOp Imm;
77    struct MemOp Mem;
78    struct PrefOp Pref;
79  };
80
81  X86Operand(KindTy K, SMLoc Start, SMLoc End)
82      : Kind(K), StartLoc(Start), EndLoc(End), CallOperand(false) {}
83
84  StringRef getSymName() override { return SymName; }
85  void *getOpDecl() override { return OpDecl; }
86
87  /// getStartLoc - Get the location of the first token of this operand.
88  SMLoc getStartLoc() const override { return StartLoc; }
89
90  /// getEndLoc - Get the location of the last token of this operand.
91  SMLoc getEndLoc() const override { return EndLoc; }
92
93  /// getLocRange - Get the range between the first and last token of this
94  /// operand.
95  SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
96
97  /// getOffsetOfLoc - Get the location of the offset operator.
98  SMLoc getOffsetOfLoc() const override { return OffsetOfLoc; }
99
100  void print(raw_ostream &OS) const override {
101
102    auto PrintImmValue = [&](const MCExpr *Val, const char *VName) {
103      if (Val->getKind() == MCExpr::Constant) {
104        if (auto Imm = cast<MCConstantExpr>(Val)->getValue())
105          OS << VName << Imm;
106      } else if (Val->getKind() == MCExpr::SymbolRef) {
107        if (auto *SRE = dyn_cast<MCSymbolRefExpr>(Val)) {
108          const MCSymbol &Sym = SRE->getSymbol();
109          if (const char *SymNameStr = Sym.getName().data())
110            OS << VName << SymNameStr;
111        }
112      }
113    };
114
115    switch (Kind) {
116    case Token:
117      OS << Tok.Data;
118      break;
119    case Register:
120      OS << "Reg:" << X86IntelInstPrinter::getRegisterName(Reg.RegNo);
121      break;
122    case DXRegister:
123      OS << "DXReg";
124      break;
125    case Immediate:
126      PrintImmValue(Imm.Val, "Imm:");
127      break;
128    case Prefix:
129      OS << "Prefix:" << Pref.Prefixes;
130      break;
131    case Memory:
132      OS << "Memory: ModeSize=" << Mem.ModeSize;
133      if (Mem.Size)
134        OS << ",Size=" << Mem.Size;
135      if (Mem.BaseReg)
136        OS << ",BaseReg=" << X86IntelInstPrinter::getRegisterName(Mem.BaseReg);
137      if (Mem.IndexReg)
138        OS << ",IndexReg="
139           << X86IntelInstPrinter::getRegisterName(Mem.IndexReg);
140      if (Mem.Scale)
141        OS << ",Scale=" << Mem.Scale;
142      if (Mem.Disp)
143        PrintImmValue(Mem.Disp, ",Disp=");
144      if (Mem.SegReg)
145        OS << ",SegReg=" << X86IntelInstPrinter::getRegisterName(Mem.SegReg);
146      break;
147    }
148  }
149
150  StringRef getToken() const {
151    assert(Kind == Token && "Invalid access!");
152    return StringRef(Tok.Data, Tok.Length);
153  }
154  void setTokenValue(StringRef Value) {
155    assert(Kind == Token && "Invalid access!");
156    Tok.Data = Value.data();
157    Tok.Length = Value.size();
158  }
159
160  unsigned getReg() const override {
161    assert(Kind == Register && "Invalid access!");
162    return Reg.RegNo;
163  }
164
165  unsigned getPrefix() const {
166    assert(Kind == Prefix && "Invalid access!");
167    return Pref.Prefixes;
168  }
169
170  const MCExpr *getImm() const {
171    assert(Kind == Immediate && "Invalid access!");
172    return Imm.Val;
173  }
174
175  const MCExpr *getMemDisp() const {
176    assert(Kind == Memory && "Invalid access!");
177    return Mem.Disp;
178  }
179  unsigned getMemSegReg() const {
180    assert(Kind == Memory && "Invalid access!");
181    return Mem.SegReg;
182  }
183  unsigned getMemBaseReg() const {
184    assert(Kind == Memory && "Invalid access!");
185    return Mem.BaseReg;
186  }
187  unsigned getMemIndexReg() const {
188    assert(Kind == Memory && "Invalid access!");
189    return Mem.IndexReg;
190  }
191  unsigned getMemScale() const {
192    assert(Kind == Memory && "Invalid access!");
193    return Mem.Scale;
194  }
195  unsigned getMemModeSize() const {
196    assert(Kind == Memory && "Invalid access!");
197    return Mem.ModeSize;
198  }
199  unsigned getMemFrontendSize() const {
200    assert(Kind == Memory && "Invalid access!");
201    return Mem.FrontendSize;
202  }
203
204  bool isToken() const override {return Kind == Token; }
205
206  bool isImm() const override { return Kind == Immediate; }
207
208  bool isImmSExti16i8() const {
209    if (!isImm())
210      return false;
211
212    // If this isn't a constant expr, just assume it fits and let relaxation
213    // handle it.
214    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
215    if (!CE)
216      return true;
217
218    // Otherwise, check the value is in a range that makes sense for this
219    // extension.
220    return isImmSExti16i8Value(CE->getValue());
221  }
222  bool isImmSExti32i8() const {
223    if (!isImm())
224      return false;
225
226    // If this isn't a constant expr, just assume it fits and let relaxation
227    // handle it.
228    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
229    if (!CE)
230      return true;
231
232    // Otherwise, check the value is in a range that makes sense for this
233    // extension.
234    return isImmSExti32i8Value(CE->getValue());
235  }
236  bool isImmSExti64i8() const {
237    if (!isImm())
238      return false;
239
240    // If this isn't a constant expr, just assume it fits and let relaxation
241    // handle it.
242    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
243    if (!CE)
244      return true;
245
246    // Otherwise, check the value is in a range that makes sense for this
247    // extension.
248    return isImmSExti64i8Value(CE->getValue());
249  }
250  bool isImmSExti64i32() const {
251    if (!isImm())
252      return false;
253
254    // If this isn't a constant expr, just assume it fits and let relaxation
255    // handle it.
256    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
257    if (!CE)
258      return true;
259
260    // Otherwise, check the value is in a range that makes sense for this
261    // extension.
262    return isImmSExti64i32Value(CE->getValue());
263  }
264
265  bool isImmUnsignedi4() const {
266    if (!isImm()) return false;
267    // If this isn't a constant expr, reject it. The immediate byte is shared
268    // with a register encoding. We can't have it affected by a relocation.
269    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
270    if (!CE) return false;
271    return isImmUnsignedi4Value(CE->getValue());
272  }
273
274  bool isImmUnsignedi8() const {
275    if (!isImm()) return false;
276    // If this isn't a constant expr, just assume it fits and let relaxation
277    // handle it.
278    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
279    if (!CE) return true;
280    return isImmUnsignedi8Value(CE->getValue());
281  }
282
283  bool isOffsetOfLocal() const override { return isImm() && Imm.LocalRef; }
284
285  bool needAddressOf() const override { return AddressOf; }
286
287  bool isMem() const override { return Kind == Memory; }
288  bool isMemUnsized() const {
289    return Kind == Memory && Mem.Size == 0;
290  }
291  bool isMem8() const {
292    return Kind == Memory && (!Mem.Size || Mem.Size == 8);
293  }
294  bool isMem16() const {
295    return Kind == Memory && (!Mem.Size || Mem.Size == 16);
296  }
297  bool isMem32() const {
298    return Kind == Memory && (!Mem.Size || Mem.Size == 32);
299  }
300  bool isMem64() const {
301    return Kind == Memory && (!Mem.Size || Mem.Size == 64);
302  }
303  bool isMem80() const {
304    return Kind == Memory && (!Mem.Size || Mem.Size == 80);
305  }
306  bool isMem128() const {
307    return Kind == Memory && (!Mem.Size || Mem.Size == 128);
308  }
309  bool isMem256() const {
310    return Kind == Memory && (!Mem.Size || Mem.Size == 256);
311  }
312  bool isMem512() const {
313    return Kind == Memory && (!Mem.Size || Mem.Size == 512);
314  }
315  bool isMemIndexReg(unsigned LowR, unsigned HighR) const {
316    assert(Kind == Memory && "Invalid access!");
317    return Mem.IndexReg >= LowR && Mem.IndexReg <= HighR;
318  }
319
320  bool isMem64_RC128() const {
321    return isMem64() && isMemIndexReg(X86::XMM0, X86::XMM15);
322  }
323  bool isMem128_RC128() const {
324    return isMem128() && isMemIndexReg(X86::XMM0, X86::XMM15);
325  }
326  bool isMem128_RC256() const {
327    return isMem128() && isMemIndexReg(X86::YMM0, X86::YMM15);
328  }
329  bool isMem256_RC128() const {
330    return isMem256() && isMemIndexReg(X86::XMM0, X86::XMM15);
331  }
332  bool isMem256_RC256() const {
333    return isMem256() && isMemIndexReg(X86::YMM0, X86::YMM15);
334  }
335
336  bool isMem64_RC128X() const {
337    return isMem64() && isMemIndexReg(X86::XMM0, X86::XMM31);
338  }
339  bool isMem128_RC128X() const {
340    return isMem128() && isMemIndexReg(X86::XMM0, X86::XMM31);
341  }
342  bool isMem128_RC256X() const {
343    return isMem128() && isMemIndexReg(X86::YMM0, X86::YMM31);
344  }
345  bool isMem256_RC128X() const {
346    return isMem256() && isMemIndexReg(X86::XMM0, X86::XMM31);
347  }
348  bool isMem256_RC256X() const {
349    return isMem256() && isMemIndexReg(X86::YMM0, X86::YMM31);
350  }
351  bool isMem256_RC512() const {
352    return isMem256() && isMemIndexReg(X86::ZMM0, X86::ZMM31);
353  }
354  bool isMem512_RC256X() const {
355    return isMem512() && isMemIndexReg(X86::YMM0, X86::YMM31);
356  }
357  bool isMem512_RC512() const {
358    return isMem512() && isMemIndexReg(X86::ZMM0, X86::ZMM31);
359  }
360
361  bool isAbsMem() const {
362    return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
363      !getMemIndexReg() && getMemScale() == 1;
364  }
365  bool isAVX512RC() const{
366      return isImm();
367  }
368
369  bool isAbsMem16() const {
370    return isAbsMem() && Mem.ModeSize == 16;
371  }
372
373  bool isSrcIdx() const {
374    return !getMemIndexReg() && getMemScale() == 1 &&
375      (getMemBaseReg() == X86::RSI || getMemBaseReg() == X86::ESI ||
376       getMemBaseReg() == X86::SI) && isa<MCConstantExpr>(getMemDisp()) &&
377      cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
378  }
379  bool isSrcIdx8() const {
380    return isMem8() && isSrcIdx();
381  }
382  bool isSrcIdx16() const {
383    return isMem16() && isSrcIdx();
384  }
385  bool isSrcIdx32() const {
386    return isMem32() && isSrcIdx();
387  }
388  bool isSrcIdx64() const {
389    return isMem64() && isSrcIdx();
390  }
391
392  bool isDstIdx() const {
393    return !getMemIndexReg() && getMemScale() == 1 &&
394      (getMemSegReg() == 0 || getMemSegReg() == X86::ES) &&
395      (getMemBaseReg() == X86::RDI || getMemBaseReg() == X86::EDI ||
396       getMemBaseReg() == X86::DI) && isa<MCConstantExpr>(getMemDisp()) &&
397      cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
398  }
399  bool isDstIdx8() const {
400    return isMem8() && isDstIdx();
401  }
402  bool isDstIdx16() const {
403    return isMem16() && isDstIdx();
404  }
405  bool isDstIdx32() const {
406    return isMem32() && isDstIdx();
407  }
408  bool isDstIdx64() const {
409    return isMem64() && isDstIdx();
410  }
411
412  bool isMemOffs() const {
413    return Kind == Memory && !getMemBaseReg() && !getMemIndexReg() &&
414      getMemScale() == 1;
415  }
416
417  bool isMemOffs16_8() const {
418    return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 8);
419  }
420  bool isMemOffs16_16() const {
421    return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 16);
422  }
423  bool isMemOffs16_32() const {
424    return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 32);
425  }
426  bool isMemOffs32_8() const {
427    return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 8);
428  }
429  bool isMemOffs32_16() const {
430    return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 16);
431  }
432  bool isMemOffs32_32() const {
433    return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 32);
434  }
435  bool isMemOffs32_64() const {
436    return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 64);
437  }
438  bool isMemOffs64_8() const {
439    return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 8);
440  }
441  bool isMemOffs64_16() const {
442    return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 16);
443  }
444  bool isMemOffs64_32() const {
445    return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 32);
446  }
447  bool isMemOffs64_64() const {
448    return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 64);
449  }
450
451  bool isPrefix() const { return Kind == Prefix; }
452  bool isReg() const override { return Kind == Register; }
453  bool isDXReg() const { return Kind == DXRegister; }
454
455  bool isGR32orGR64() const {
456    return Kind == Register &&
457      (X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||
458      X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
459  }
460
461  bool isVK1Pair() const {
462    return Kind == Register &&
463      X86MCRegisterClasses[X86::VK1RegClassID].contains(getReg());
464  }
465
466  bool isVK2Pair() const {
467    return Kind == Register &&
468      X86MCRegisterClasses[X86::VK2RegClassID].contains(getReg());
469  }
470
471  bool isVK4Pair() const {
472    return Kind == Register &&
473      X86MCRegisterClasses[X86::VK4RegClassID].contains(getReg());
474  }
475
476  bool isVK8Pair() const {
477    return Kind == Register &&
478      X86MCRegisterClasses[X86::VK8RegClassID].contains(getReg());
479  }
480
481  bool isVK16Pair() const {
482    return Kind == Register &&
483      X86MCRegisterClasses[X86::VK16RegClassID].contains(getReg());
484  }
485
486  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
487    // Add as immediates when possible.
488    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
489      Inst.addOperand(MCOperand::createImm(CE->getValue()));
490    else
491      Inst.addOperand(MCOperand::createExpr(Expr));
492  }
493
494  void addRegOperands(MCInst &Inst, unsigned N) const {
495    assert(N == 1 && "Invalid number of operands!");
496    Inst.addOperand(MCOperand::createReg(getReg()));
497  }
498
499  void addGR32orGR64Operands(MCInst &Inst, unsigned N) const {
500    assert(N == 1 && "Invalid number of operands!");
501    MCRegister RegNo = getReg();
502    if (X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
503      RegNo = getX86SubSuperRegister(RegNo, 32);
504    Inst.addOperand(MCOperand::createReg(RegNo));
505  }
506
507  void addAVX512RCOperands(MCInst &Inst, unsigned N) const {
508    assert(N == 1 && "Invalid number of operands!");
509    addExpr(Inst, getImm());
510  }
511
512  void addImmOperands(MCInst &Inst, unsigned N) const {
513    assert(N == 1 && "Invalid number of operands!");
514    addExpr(Inst, getImm());
515  }
516
517  void addMaskPairOperands(MCInst &Inst, unsigned N) const {
518    assert(N == 1 && "Invalid number of operands!");
519    unsigned Reg = getReg();
520    switch (Reg) {
521    case X86::K0:
522    case X86::K1:
523      Reg = X86::K0_K1;
524      break;
525    case X86::K2:
526    case X86::K3:
527      Reg = X86::K2_K3;
528      break;
529    case X86::K4:
530    case X86::K5:
531      Reg = X86::K4_K5;
532      break;
533    case X86::K6:
534    case X86::K7:
535      Reg = X86::K6_K7;
536      break;
537    }
538    Inst.addOperand(MCOperand::createReg(Reg));
539  }
540
541  void addMemOperands(MCInst &Inst, unsigned N) const {
542    assert((N == 5) && "Invalid number of operands!");
543    Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
544    Inst.addOperand(MCOperand::createImm(getMemScale()));
545    Inst.addOperand(MCOperand::createReg(getMemIndexReg()));
546    addExpr(Inst, getMemDisp());
547    Inst.addOperand(MCOperand::createReg(getMemSegReg()));
548  }
549
550  void addAbsMemOperands(MCInst &Inst, unsigned N) const {
551    assert((N == 1) && "Invalid number of operands!");
552    // Add as immediates when possible.
553    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
554      Inst.addOperand(MCOperand::createImm(CE->getValue()));
555    else
556      Inst.addOperand(MCOperand::createExpr(getMemDisp()));
557  }
558
559  void addSrcIdxOperands(MCInst &Inst, unsigned N) const {
560    assert((N == 2) && "Invalid number of operands!");
561    Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
562    Inst.addOperand(MCOperand::createReg(getMemSegReg()));
563  }
564
565  void addDstIdxOperands(MCInst &Inst, unsigned N) const {
566    assert((N == 1) && "Invalid number of operands!");
567    Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
568  }
569
570  void addMemOffsOperands(MCInst &Inst, unsigned N) const {
571    assert((N == 2) && "Invalid number of operands!");
572    // Add as immediates when possible.
573    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
574      Inst.addOperand(MCOperand::createImm(CE->getValue()));
575    else
576      Inst.addOperand(MCOperand::createExpr(getMemDisp()));
577    Inst.addOperand(MCOperand::createReg(getMemSegReg()));
578  }
579
580  static std::unique_ptr<X86Operand> CreateToken(StringRef Str, SMLoc Loc) {
581    SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size());
582    auto Res = std::make_unique<X86Operand>(Token, Loc, EndLoc);
583    Res->Tok.Data = Str.data();
584    Res->Tok.Length = Str.size();
585    return Res;
586  }
587
588  static std::unique_ptr<X86Operand>
589  CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc,
590            bool AddressOf = false, SMLoc OffsetOfLoc = SMLoc(),
591            StringRef SymName = StringRef(), void *OpDecl = nullptr) {
592    auto Res = std::make_unique<X86Operand>(Register, StartLoc, EndLoc);
593    Res->Reg.RegNo = RegNo;
594    Res->AddressOf = AddressOf;
595    Res->OffsetOfLoc = OffsetOfLoc;
596    Res->SymName = SymName;
597    Res->OpDecl = OpDecl;
598    return Res;
599  }
600
601  static std::unique_ptr<X86Operand>
602  CreateDXReg(SMLoc StartLoc, SMLoc EndLoc) {
603    return std::make_unique<X86Operand>(DXRegister, StartLoc, EndLoc);
604  }
605
606  static std::unique_ptr<X86Operand>
607  CreatePrefix(unsigned Prefixes, SMLoc StartLoc, SMLoc EndLoc) {
608    auto Res = std::make_unique<X86Operand>(Prefix, StartLoc, EndLoc);
609    Res->Pref.Prefixes = Prefixes;
610    return Res;
611  }
612
613  static std::unique_ptr<X86Operand> CreateImm(const MCExpr *Val,
614                                               SMLoc StartLoc, SMLoc EndLoc,
615                                               StringRef SymName = StringRef(),
616                                               void *OpDecl = nullptr,
617                                               bool GlobalRef = true) {
618    auto Res = std::make_unique<X86Operand>(Immediate, StartLoc, EndLoc);
619    Res->Imm.Val      = Val;
620    Res->Imm.LocalRef = !GlobalRef;
621    Res->SymName      = SymName;
622    Res->OpDecl       = OpDecl;
623    Res->AddressOf    = true;
624    return Res;
625  }
626
627  /// Create an absolute memory operand.
628  static std::unique_ptr<X86Operand>
629  CreateMem(unsigned ModeSize, const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc,
630            unsigned Size = 0, StringRef SymName = StringRef(),
631            void *OpDecl = nullptr, unsigned FrontendSize = 0) {
632    auto Res = std::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
633    Res->Mem.SegReg   = 0;
634    Res->Mem.Disp     = Disp;
635    Res->Mem.BaseReg  = 0;
636    Res->Mem.IndexReg = 0;
637    Res->Mem.Scale    = 1;
638    Res->Mem.Size     = Size;
639    Res->Mem.ModeSize = ModeSize;
640    Res->Mem.FrontendSize = FrontendSize;
641    Res->SymName      = SymName;
642    Res->OpDecl       = OpDecl;
643    Res->AddressOf    = false;
644    return Res;
645  }
646
647  /// Create a generalized memory operand.
648  static std::unique_ptr<X86Operand>
649  CreateMem(unsigned ModeSize, unsigned SegReg, const MCExpr *Disp,
650            unsigned BaseReg, unsigned IndexReg, unsigned Scale, SMLoc StartLoc,
651            SMLoc EndLoc, unsigned Size = 0, StringRef SymName = StringRef(),
652            void *OpDecl = nullptr, unsigned FrontendSize = 0) {
653    // We should never just have a displacement, that should be parsed as an
654    // absolute memory operand.
655    assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
656
657    // The scale should always be one of {1,2,4,8}.
658    assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
659           "Invalid scale!");
660    auto Res = std::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
661    Res->Mem.SegReg   = SegReg;
662    Res->Mem.Disp     = Disp;
663    Res->Mem.BaseReg  = BaseReg;
664    Res->Mem.IndexReg = IndexReg;
665    Res->Mem.Scale    = Scale;
666    Res->Mem.Size     = Size;
667    Res->Mem.ModeSize = ModeSize;
668    Res->Mem.FrontendSize = FrontendSize;
669    Res->SymName      = SymName;
670    Res->OpDecl       = OpDecl;
671    Res->AddressOf    = false;
672    return Res;
673  }
674};
675
676} // end namespace llvm
677
678#endif // LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H
679