//===- X86Operand.h - Parsed X86 machine instruction ------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H
#define LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H

#include "MCTargetDesc/X86IntelInstPrinter.h"
#include "MCTargetDesc/X86MCTargetDesc.h"
#include "X86AsmParserCommon.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/SMLoc.h"
#include <cassert>
#include <memory>

namespace llvm {

/// X86Operand - Instances of this class represent a parsed X86 machine
/// instruction.
struct X86Operand final : public MCParsedAsmOperand {
  enum KindTy { Token, Register, Immediate, Memory, Prefix, DXRegister } Kind;

  SMLoc StartLoc, EndLoc;
  SMLoc OffsetOfLoc;
  StringRef SymName;
  void *OpDecl;
  bool AddressOf;

  struct TokOp {
    const char *Data;
    unsigned Length;
  };

  struct RegOp {
    unsigned RegNo;
  };

  struct PrefOp {
    unsigned Prefixes;
  };

  struct ImmOp {
    const MCExpr *Val;
    bool LocalRef;
  };

  struct MemOp {
    unsigned SegReg;
    const MCExpr *Disp;
    unsigned BaseReg;
    unsigned DefaultBaseReg;
    unsigned IndexReg;
    unsigned Scale;
    unsigned Size;
    unsigned ModeSize;

    /// If the memory operand is unsized and there are multiple instruction
    /// matches, prefer the one with this size.
    unsigned FrontendSize;
  };

  union {
    struct TokOp Tok;
    struct RegOp Reg;
    struct ImmOp Imm;
    struct MemOp Mem;
    struct PrefOp Pref;
  };

  X86Operand(KindTy K, SMLoc Start, SMLoc End)
      : Kind(K), StartLoc(Start), EndLoc(End), OpDecl(nullptr),
        AddressOf(false) {}

  StringRef getSymName() override { return SymName; }
  void *getOpDecl() override { return OpDecl; }

  /// getStartLoc - Get the location of the first token of this operand.
  SMLoc getStartLoc() const override { return StartLoc; }

  /// getEndLoc - Get the location of the last token of this operand.
  SMLoc getEndLoc() const override { return EndLoc; }

  /// getLocRange - Get the range between the first and last token of this
  /// operand.
  SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }

  /// getOffsetOfLoc - Get the location of the offset operator.
  SMLoc getOffsetOfLoc() const override { return OffsetOfLoc; }

  void print(raw_ostream &OS) const override {

    auto PrintImmValue = [&](const MCExpr *Val, const char *VName) {
      if (Val->getKind() == MCExpr::Constant) {
        if (auto Imm = cast<MCConstantExpr>(Val)->getValue())
          OS << VName << Imm;
      } else if (Val->getKind() == MCExpr::SymbolRef) {
        if (auto *SRE = dyn_cast<MCSymbolRefExpr>(Val)) {
          const MCSymbol &Sym = SRE->getSymbol();
          if (const char *SymNameStr = Sym.getName().data())
            OS << VName << SymNameStr;
        }
      }
    };

    switch (Kind) {
    case Token:
      OS << Tok.Data;
      break;
    case Register:
      OS << "Reg:" << X86IntelInstPrinter::getRegisterName(Reg.RegNo);
      break;
    case DXRegister:
      OS << "DXReg";
      break;
    case Immediate:
      PrintImmValue(Imm.Val, "Imm:");
      break;
    case Prefix:
      OS << "Prefix:" << Pref.Prefixes;
      break;
    case Memory:
      OS << "Memory: ModeSize=" << Mem.ModeSize;
      if (Mem.Size)
        OS << ",Size=" << Mem.Size;
      if (Mem.BaseReg)
        OS << ",BaseReg=" << X86IntelInstPrinter::getRegisterName(Mem.BaseReg);
      if (Mem.IndexReg)
        OS << ",IndexReg="
           << X86IntelInstPrinter::getRegisterName(Mem.IndexReg);
      if (Mem.Scale)
        OS << ",Scale=" << Mem.Scale;
      if (Mem.Disp)
        PrintImmValue(Mem.Disp, ",Disp=");
      if (Mem.SegReg)
        OS << ",SegReg=" << X86IntelInstPrinter::getRegisterName(Mem.SegReg);
      break;
    }
  }

  StringRef getToken() const {
    assert(Kind == Token && "Invalid access!");
    return StringRef(Tok.Data, Tok.Length);
  }
  void setTokenValue(StringRef Value) {
    assert(Kind == Token && "Invalid access!");
    Tok.Data = Value.data();
    Tok.Length = Value.size();
  }

  unsigned getReg() const override {
    assert(Kind == Register && "Invalid access!");
    return Reg.RegNo;
  }

  unsigned getPrefix() const {
    assert(Kind == Prefix && "Invalid access!");
    return Pref.Prefixes;
  }

  const MCExpr *getImm() const {
    assert(Kind == Immediate && "Invalid access!");
    return Imm.Val;
  }

  const MCExpr *getMemDisp() const {
    assert(Kind == Memory && "Invalid access!");
    return Mem.Disp;
  }
  unsigned getMemSegReg() const {
    assert(Kind == Memory && "Invalid access!");
    return Mem.SegReg;
  }
  unsigned getMemBaseReg() const {
    assert(Kind == Memory && "Invalid access!");
    return Mem.BaseReg;
  }
  unsigned getMemDefaultBaseReg() const {
    assert(Kind == Memory && "Invalid access!");
    return Mem.DefaultBaseReg;
  }
  unsigned getMemIndexReg() const {
    assert(Kind == Memory && "Invalid access!");
    return Mem.IndexReg;
  }
  unsigned getMemScale() const {
    assert(Kind == Memory && "Invalid access!");
    return Mem.Scale;
  }
  unsigned getMemModeSize() const {
    assert(Kind == Memory && "Invalid access!");
    return Mem.ModeSize;
  }
  unsigned getMemFrontendSize() const {
    assert(Kind == Memory && "Invalid access!");
    return Mem.FrontendSize;
  }

  bool isToken() const override {return Kind == Token; }

  bool isImm() const override { return Kind == Immediate; }

  bool isImmSExti16i8() const {
    if (!isImm())
      return false;

    // If this isn't a constant expr, just assume it fits and let relaxation
    // handle it.
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    if (!CE)
      return true;

    // Otherwise, check the value is in a range that makes sense for this
    // extension.
    return isImmSExti16i8Value(CE->getValue());
  }
  bool isImmSExti32i8() const {
    if (!isImm())
      return false;

    // If this isn't a constant expr, just assume it fits and let relaxation
    // handle it.
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    if (!CE)
      return true;

    // Otherwise, check the value is in a range that makes sense for this
    // extension.
    return isImmSExti32i8Value(CE->getValue());
  }
  bool isImmSExti64i8() const {
    if (!isImm())
      return false;

    // If this isn't a constant expr, just assume it fits and let relaxation
    // handle it.
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    if (!CE)
      return true;

    // Otherwise, check the value is in a range that makes sense for this
    // extension.
    return isImmSExti64i8Value(CE->getValue());
  }
  bool isImmSExti64i32() const {
    if (!isImm())
      return false;

    // If this isn't a constant expr, just assume it fits and let relaxation
    // handle it.
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    if (!CE)
      return true;

    // Otherwise, check the value is in a range that makes sense for this
    // extension.
    return isImmSExti64i32Value(CE->getValue());
  }

  bool isImmUnsignedi4() const {
    if (!isImm()) return false;
    // If this isn't a constant expr, reject it. The immediate byte is shared
    // with a register encoding. We can't have it affected by a relocation.
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    if (!CE) return false;
    return isImmUnsignedi4Value(CE->getValue());
  }

  bool isImmUnsignedi8() const {
    if (!isImm()) return false;
    // If this isn't a constant expr, just assume it fits and let relaxation
    // handle it.
    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    if (!CE) return true;
    return isImmUnsignedi8Value(CE->getValue());
  }

  bool isOffsetOfLocal() const override { return isImm() && Imm.LocalRef; }

  bool needAddressOf() const override { return AddressOf; }

  bool isMem() const override { return Kind == Memory; }
  bool isMemUnsized() const {
    return Kind == Memory && Mem.Size == 0;
  }
  bool isMem8() const {
    return Kind == Memory && (!Mem.Size || Mem.Size == 8);
  }
  bool isMem16() const {
    return Kind == Memory && (!Mem.Size || Mem.Size == 16);
  }
  bool isMem32() const {
    return Kind == Memory && (!Mem.Size || Mem.Size == 32);
  }
  bool isMem64() const {
    return Kind == Memory && (!Mem.Size || Mem.Size == 64);
  }
  bool isMem80() const {
    return Kind == Memory && (!Mem.Size || Mem.Size == 80);
  }
  bool isMem128() const {
    return Kind == Memory && (!Mem.Size || Mem.Size == 128);
  }
  bool isMem256() const {
    return Kind == Memory && (!Mem.Size || Mem.Size == 256);
  }
  bool isMem512() const {
    return Kind == Memory && (!Mem.Size || Mem.Size == 512);
  }

  bool isSibMem() const {
    return isMem() && Mem.BaseReg != X86::RIP && Mem.BaseReg != X86::EIP;
  }

  bool isMemIndexReg(unsigned LowR, unsigned HighR) const {
    assert(Kind == Memory && "Invalid access!");
    return Mem.IndexReg >= LowR && Mem.IndexReg <= HighR;
  }

  bool isMem64_RC128() const {
    return isMem64() && isMemIndexReg(X86::XMM0, X86::XMM15);
  }
  bool isMem128_RC128() const {
    return isMem128() && isMemIndexReg(X86::XMM0, X86::XMM15);
  }
  bool isMem128_RC256() const {
    return isMem128() && isMemIndexReg(X86::YMM0, X86::YMM15);
  }
  bool isMem256_RC128() const {
    return isMem256() && isMemIndexReg(X86::XMM0, X86::XMM15);
  }
  bool isMem256_RC256() const {
    return isMem256() && isMemIndexReg(X86::YMM0, X86::YMM15);
  }

  bool isMem64_RC128X() const {
    return isMem64() && isMemIndexReg(X86::XMM0, X86::XMM31);
  }
  bool isMem128_RC128X() const {
    return isMem128() && isMemIndexReg(X86::XMM0, X86::XMM31);
  }
  bool isMem128_RC256X() const {
    return isMem128() && isMemIndexReg(X86::YMM0, X86::YMM31);
  }
  bool isMem256_RC128X() const {
    return isMem256() && isMemIndexReg(X86::XMM0, X86::XMM31);
  }
  bool isMem256_RC256X() const {
    return isMem256() && isMemIndexReg(X86::YMM0, X86::YMM31);
  }
  bool isMem256_RC512() const {
    return isMem256() && isMemIndexReg(X86::ZMM0, X86::ZMM31);
  }
  bool isMem512_RC256X() const {
    return isMem512() && isMemIndexReg(X86::YMM0, X86::YMM31);
  }
  bool isMem512_RC512() const {
    return isMem512() && isMemIndexReg(X86::ZMM0, X86::ZMM31);
  }

  bool isAbsMem() const {
    return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
      !getMemIndexReg() && getMemScale() == 1;
  }
  bool isAVX512RC() const{
      return isImm();
  }

  bool isAbsMem16() const {
    return isAbsMem() && Mem.ModeSize == 16;
  }

  bool isSrcIdx() const {
    return !getMemIndexReg() && getMemScale() == 1 &&
      (getMemBaseReg() == X86::RSI || getMemBaseReg() == X86::ESI ||
       getMemBaseReg() == X86::SI) && isa<MCConstantExpr>(getMemDisp()) &&
      cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
  }
  bool isSrcIdx8() const {
    return isMem8() && isSrcIdx();
  }
  bool isSrcIdx16() const {
    return isMem16() && isSrcIdx();
  }
  bool isSrcIdx32() const {
    return isMem32() && isSrcIdx();
  }
  bool isSrcIdx64() const {
    return isMem64() && isSrcIdx();
  }

  bool isDstIdx() const {
    return !getMemIndexReg() && getMemScale() == 1 &&
      (getMemSegReg() == 0 || getMemSegReg() == X86::ES) &&
      (getMemBaseReg() == X86::RDI || getMemBaseReg() == X86::EDI ||
       getMemBaseReg() == X86::DI) && isa<MCConstantExpr>(getMemDisp()) &&
      cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
  }
  bool isDstIdx8() const {
    return isMem8() && isDstIdx();
  }
  bool isDstIdx16() const {
    return isMem16() && isDstIdx();
  }
  bool isDstIdx32() const {
    return isMem32() && isDstIdx();
  }
  bool isDstIdx64() const {
    return isMem64() && isDstIdx();
  }

  bool isMemOffs() const {
    return Kind == Memory && !getMemBaseReg() && !getMemIndexReg() &&
      getMemScale() == 1;
  }

  bool isMemOffs16_8() const {
    return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 8);
  }
  bool isMemOffs16_16() const {
    return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 16);
  }
  bool isMemOffs16_32() const {
    return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 32);
  }
  bool isMemOffs32_8() const {
    return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 8);
  }
  bool isMemOffs32_16() const {
    return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 16);
  }
  bool isMemOffs32_32() const {
    return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 32);
  }
  bool isMemOffs32_64() const {
    return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 64);
  }
  bool isMemOffs64_8() const {
    return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 8);
  }
  bool isMemOffs64_16() const {
    return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 16);
  }
  bool isMemOffs64_32() const {
    return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 32);
  }
  bool isMemOffs64_64() const {
    return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 64);
  }

  bool isPrefix() const { return Kind == Prefix; }
  bool isReg() const override { return Kind == Register; }
  bool isDXReg() const { return Kind == DXRegister; }

  bool isGR32orGR64() const {
    return Kind == Register &&
      (X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||
       X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
  }

  bool isGR16orGR32orGR64() const {
    return Kind == Register &&
      (X86MCRegisterClasses[X86::GR16RegClassID].contains(getReg()) ||
       X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||
       X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
  }

  bool isVectorReg() const {
    return Kind == Register &&
           (X86MCRegisterClasses[X86::VR64RegClassID].contains(getReg()) ||
            X86MCRegisterClasses[X86::VR128XRegClassID].contains(getReg()) ||
            X86MCRegisterClasses[X86::VR256XRegClassID].contains(getReg()) ||
            X86MCRegisterClasses[X86::VR512RegClassID].contains(getReg()));
  }

  bool isVK1Pair() const {
    return Kind == Register &&
      X86MCRegisterClasses[X86::VK1RegClassID].contains(getReg());
  }

  bool isVK2Pair() const {
    return Kind == Register &&
      X86MCRegisterClasses[X86::VK2RegClassID].contains(getReg());
  }

  bool isVK4Pair() const {
    return Kind == Register &&
      X86MCRegisterClasses[X86::VK4RegClassID].contains(getReg());
  }

  bool isVK8Pair() const {
    return Kind == Register &&
      X86MCRegisterClasses[X86::VK8RegClassID].contains(getReg());
  }

  bool isVK16Pair() const {
    return Kind == Register &&
      X86MCRegisterClasses[X86::VK16RegClassID].contains(getReg());
  }

  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
    // Add as immediates when possible.
    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
      Inst.addOperand(MCOperand::createImm(CE->getValue()));
    else
      Inst.addOperand(MCOperand::createExpr(Expr));
  }

  void addRegOperands(MCInst &Inst, unsigned N) const {
    assert(N == 1 && "Invalid number of operands!");
    Inst.addOperand(MCOperand::createReg(getReg()));
  }

  void addGR32orGR64Operands(MCInst &Inst, unsigned N) const {
    assert(N == 1 && "Invalid number of operands!");
    MCRegister RegNo = getReg();
    if (X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
      RegNo = getX86SubSuperRegister(RegNo, 32);
    Inst.addOperand(MCOperand::createReg(RegNo));
  }

  void addGR16orGR32orGR64Operands(MCInst &Inst, unsigned N) const {
    assert(N == 1 && "Invalid number of operands!");
    MCRegister RegNo = getReg();
    if (X86MCRegisterClasses[X86::GR32RegClassID].contains(RegNo) ||
        X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
      RegNo = getX86SubSuperRegister(RegNo, 16);
    Inst.addOperand(MCOperand::createReg(RegNo));
  }

  void addAVX512RCOperands(MCInst &Inst, unsigned N) const {
    assert(N == 1 && "Invalid number of operands!");
    addExpr(Inst, getImm());
  }

  void addImmOperands(MCInst &Inst, unsigned N) const {
    assert(N == 1 && "Invalid number of operands!");
    addExpr(Inst, getImm());
  }

  void addMaskPairOperands(MCInst &Inst, unsigned N) const {
    assert(N == 1 && "Invalid number of operands!");
    unsigned Reg = getReg();
    switch (Reg) {
    case X86::K0:
    case X86::K1:
      Reg = X86::K0_K1;
      break;
    case X86::K2:
    case X86::K3:
      Reg = X86::K2_K3;
      break;
    case X86::K4:
    case X86::K5:
      Reg = X86::K4_K5;
      break;
    case X86::K6:
    case X86::K7:
      Reg = X86::K6_K7;
      break;
    }
    Inst.addOperand(MCOperand::createReg(Reg));
  }

  void addMemOperands(MCInst &Inst, unsigned N) const {
    assert((N == 5) && "Invalid number of operands!");
    if (getMemBaseReg())
      Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
    else
      Inst.addOperand(MCOperand::createReg(getMemDefaultBaseReg()));
    Inst.addOperand(MCOperand::createImm(getMemScale()));
    Inst.addOperand(MCOperand::createReg(getMemIndexReg()));
    addExpr(Inst, getMemDisp());
    Inst.addOperand(MCOperand::createReg(getMemSegReg()));
  }

  void addAbsMemOperands(MCInst &Inst, unsigned N) const {
    assert((N == 1) && "Invalid number of operands!");
    // Add as immediates when possible.
    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
      Inst.addOperand(MCOperand::createImm(CE->getValue()));
    else
      Inst.addOperand(MCOperand::createExpr(getMemDisp()));
  }

  void addSrcIdxOperands(MCInst &Inst, unsigned N) const {
    assert((N == 2) && "Invalid number of operands!");
    Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
    Inst.addOperand(MCOperand::createReg(getMemSegReg()));
  }

  void addDstIdxOperands(MCInst &Inst, unsigned N) const {
    assert((N == 1) && "Invalid number of operands!");
    Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
  }

  void addMemOffsOperands(MCInst &Inst, unsigned N) const {
    assert((N == 2) && "Invalid number of operands!");
    // Add as immediates when possible.
    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
      Inst.addOperand(MCOperand::createImm(CE->getValue()));
    else
      Inst.addOperand(MCOperand::createExpr(getMemDisp()));
    Inst.addOperand(MCOperand::createReg(getMemSegReg()));
  }

  static std::unique_ptr<X86Operand> CreateToken(StringRef Str, SMLoc Loc) {
    SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size());
    auto Res = std::make_unique<X86Operand>(Token, Loc, EndLoc);
    Res->Tok.Data = Str.data();
    Res->Tok.Length = Str.size();
    return Res;
  }

  static std::unique_ptr<X86Operand>
  CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc,
            bool AddressOf = false, SMLoc OffsetOfLoc = SMLoc(),
            StringRef SymName = StringRef(), void *OpDecl = nullptr) {
    auto Res = std::make_unique<X86Operand>(Register, StartLoc, EndLoc);
    Res->Reg.RegNo = RegNo;
    Res->AddressOf = AddressOf;
    Res->OffsetOfLoc = OffsetOfLoc;
    Res->SymName = SymName;
    Res->OpDecl = OpDecl;
    return Res;
  }

  static std::unique_ptr<X86Operand>
  CreateDXReg(SMLoc StartLoc, SMLoc EndLoc) {
    return std::make_unique<X86Operand>(DXRegister, StartLoc, EndLoc);
  }

  static std::unique_ptr<X86Operand>
  CreatePrefix(unsigned Prefixes, SMLoc StartLoc, SMLoc EndLoc) {
    auto Res = std::make_unique<X86Operand>(Prefix, StartLoc, EndLoc);
    Res->Pref.Prefixes = Prefixes;
    return Res;
  }

  static std::unique_ptr<X86Operand> CreateImm(const MCExpr *Val,
                                               SMLoc StartLoc, SMLoc EndLoc,
                                               StringRef SymName = StringRef(),
                                               void *OpDecl = nullptr,
                                               bool GlobalRef = true) {
    auto Res = std::make_unique<X86Operand>(Immediate, StartLoc, EndLoc);
    Res->Imm.Val      = Val;
    Res->Imm.LocalRef = !GlobalRef;
    Res->SymName      = SymName;
    Res->OpDecl       = OpDecl;
    Res->AddressOf    = true;
    return Res;
  }

  /// Create an absolute memory operand.
  static std::unique_ptr<X86Operand>
  CreateMem(unsigned ModeSize, const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc,
            unsigned Size = 0, StringRef SymName = StringRef(),
            void *OpDecl = nullptr, unsigned FrontendSize = 0) {
    auto Res = std::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
    Res->Mem.SegReg   = 0;
    Res->Mem.Disp     = Disp;
    Res->Mem.BaseReg  = 0;
    Res->Mem.DefaultBaseReg = 0;
    Res->Mem.IndexReg = 0;
    Res->Mem.Scale    = 1;
    Res->Mem.Size     = Size;
    Res->Mem.ModeSize = ModeSize;
    Res->Mem.FrontendSize = FrontendSize;
    Res->SymName      = SymName;
    Res->OpDecl       = OpDecl;
    Res->AddressOf    = false;
    return Res;
  }

  /// Create a generalized memory operand.
  static std::unique_ptr<X86Operand>
  CreateMem(unsigned ModeSize, unsigned SegReg, const MCExpr *Disp,
            unsigned BaseReg, unsigned IndexReg, unsigned Scale, SMLoc StartLoc,
            SMLoc EndLoc, unsigned Size = 0,
            unsigned DefaultBaseReg = X86::NoRegister,
            StringRef SymName = StringRef(), void *OpDecl = nullptr,
            unsigned FrontendSize = 0) {
    // We should never just have a displacement, that should be parsed as an
    // absolute memory operand.
    assert((SegReg || BaseReg || IndexReg || DefaultBaseReg) &&
           "Invalid memory operand!");

    // The scale should always be one of {1,2,4,8}.
    assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
           "Invalid scale!");
    auto Res = std::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
    Res->Mem.SegReg   = SegReg;
    Res->Mem.Disp     = Disp;
    Res->Mem.BaseReg  = BaseReg;
    Res->Mem.DefaultBaseReg = DefaultBaseReg;
    Res->Mem.IndexReg = IndexReg;
    Res->Mem.Scale    = Scale;
    Res->Mem.Size     = Size;
    Res->Mem.ModeSize = ModeSize;
    Res->Mem.FrontendSize = FrontendSize;
    Res->SymName      = SymName;
    Res->OpDecl       = OpDecl;
    Res->AddressOf    = false;
    return Res;
  }
};

} // end namespace llvm

#endif // LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H
