//===-- X86MCCodeEmitter.cpp - Convert X86 code to machine code -----------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This file implements the X86MCCodeEmitter class.
//
//===----------------------------------------------------------------------===//

#include "MCTargetDesc/X86BaseInfo.h"
#include "MCTargetDesc/X86FixupKinds.h"
#include "MCTargetDesc/X86MCTargetDesc.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCFixup.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrDesc.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <cstdint>
#include <cstdlib>

using namespace llvm;

#define DEBUG_TYPE "mccodeemitter"

namespace {

class X86MCCodeEmitter : public MCCodeEmitter {
  const MCInstrInfo &MCII;
  MCContext &Ctx;

public:
  X86MCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx)
      : MCII(mcii), Ctx(ctx) {}
  X86MCCodeEmitter(const X86MCCodeEmitter &) = delete;
  X86MCCodeEmitter &operator=(const X86MCCodeEmitter &) = delete;
  ~X86MCCodeEmitter() override = default;

  void emitPrefix(const MCInst &MI, raw_ostream &OS,
                  const MCSubtargetInfo &STI) const override;

  void encodeInstruction(const MCInst &MI, raw_ostream &OS,
                         SmallVectorImpl<MCFixup> &Fixups,
                         const MCSubtargetInfo &STI) const override;

private:
  unsigned getX86RegNum(const MCOperand &MO) const;

  unsigned getX86RegEncoding(const MCInst &MI, unsigned OpNum) const;

  /// \param MI a single low-level machine instruction.
  /// \param OpNum the operand #.
  /// \returns true if the OpNumth operand of MI  require a bit to be set in
  /// REX prefix.
  bool isREXExtendedReg(const MCInst &MI, unsigned OpNum) const;

  void emitImmediate(const MCOperand &Disp, SMLoc Loc, unsigned ImmSize,
                     MCFixupKind FixupKind, uint64_t StartByte, raw_ostream &OS,
                     SmallVectorImpl<MCFixup> &Fixups, int ImmOffset = 0) const;

  void emitRegModRMByte(const MCOperand &ModRMReg, unsigned RegOpcodeFld,
                        raw_ostream &OS) const;

  void emitSIBByte(unsigned SS, unsigned Index, unsigned Base,
                   raw_ostream &OS) const;

  void emitMemModRMByte(const MCInst &MI, unsigned Op, unsigned RegOpcodeField,
                        uint64_t TSFlags, bool HasREX, uint64_t StartByte,
                        raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups,
                        const MCSubtargetInfo &STI,
                        bool ForceSIB = false) const;

  bool emitPrefixImpl(unsigned &CurOp, const MCInst &MI,
                      const MCSubtargetInfo &STI, raw_ostream &OS) const;

  void emitVEXOpcodePrefix(int MemOperand, const MCInst &MI,
                           raw_ostream &OS) const;

  void emitSegmentOverridePrefix(unsigned SegOperand, const MCInst &MI,
                                 raw_ostream &OS) const;

  bool emitOpcodePrefix(int MemOperand, const MCInst &MI,
                        const MCSubtargetInfo &STI, raw_ostream &OS) const;

  bool emitREXPrefix(int MemOperand, const MCInst &MI,
                     const MCSubtargetInfo &STI, raw_ostream &OS) const;
};

} // end anonymous namespace

static uint8_t modRMByte(unsigned Mod, unsigned RegOpcode, unsigned RM) {
  assert(Mod < 4 && RegOpcode < 8 && RM < 8 && "ModRM Fields out of range!");
  return RM | (RegOpcode << 3) | (Mod << 6);
}

static void emitByte(uint8_t C, raw_ostream &OS) { OS << static_cast<char>(C); }

static void emitConstant(uint64_t Val, unsigned Size, raw_ostream &OS) {
  // Output the constant in little endian byte order.
  for (unsigned i = 0; i != Size; ++i) {
    emitByte(Val & 255, OS);
    Val >>= 8;
  }
}

/// Determine if this immediate can fit in a disp8 or a compressed disp8 for
/// EVEX instructions. \p will be set to the value to pass to the ImmOffset
/// parameter of emitImmediate.
static bool isDispOrCDisp8(uint64_t TSFlags, int Value, int &ImmOffset) {
  bool HasEVEX = (TSFlags & X86II::EncodingMask) == X86II::EVEX;

  int CD8_Scale =
      (TSFlags & X86II::CD8_Scale_Mask) >> X86II::CD8_Scale_Shift;
  if (!HasEVEX || CD8_Scale == 0)
    return isInt<8>(Value);

  assert(isPowerOf2_32(CD8_Scale) && "Unexpected CD8 scale!");
  if (Value & (CD8_Scale - 1)) // Unaligned offset
    return false;

  int CDisp8 = Value / CD8_Scale;
  if (!isInt<8>(CDisp8))
    return false;

  // ImmOffset will be added to Value in emitImmediate leaving just CDisp8.
  ImmOffset = CDisp8 - Value;
  return true;
}

/// \returns the appropriate fixup kind to use for an immediate in an
/// instruction with the specified TSFlags.
static MCFixupKind getImmFixupKind(uint64_t TSFlags) {
  unsigned Size = X86II::getSizeOfImm(TSFlags);
  bool isPCRel = X86II::isImmPCRel(TSFlags);

  if (X86II::isImmSigned(TSFlags)) {
    switch (Size) {
    default:
      llvm_unreachable("Unsupported signed fixup size!");
    case 4:
      return MCFixupKind(X86::reloc_signed_4byte);
    }
  }
  return MCFixup::getKindForSize(Size, isPCRel);
}

/// \param Op operand # of the memory operand.
///
/// \returns true if the specified instruction has a 16-bit memory operand.
static bool is16BitMemOperand(const MCInst &MI, unsigned Op,
                              const MCSubtargetInfo &STI) {
  const MCOperand &Base = MI.getOperand(Op + X86::AddrBaseReg);
  const MCOperand &Index = MI.getOperand(Op + X86::AddrIndexReg);

  unsigned BaseReg = Base.getReg();
  unsigned IndexReg = Index.getReg();

  if (STI.hasFeature(X86::Mode16Bit) && BaseReg == 0 && IndexReg == 0)
    return true;
  if ((BaseReg != 0 &&
       X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg)) ||
      (IndexReg != 0 &&
       X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg)))
    return true;
  return false;
}

/// \param Op operand # of the memory operand.
///
/// \returns true if the specified instruction has a 32-bit memory operand.
static bool is32BitMemOperand(const MCInst &MI, unsigned Op) {
  const MCOperand &BaseReg = MI.getOperand(Op + X86::AddrBaseReg);
  const MCOperand &IndexReg = MI.getOperand(Op + X86::AddrIndexReg);

  if ((BaseReg.getReg() != 0 &&
       X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg.getReg())) ||
      (IndexReg.getReg() != 0 &&
       X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg.getReg())))
    return true;
  if (BaseReg.getReg() == X86::EIP) {
    assert(IndexReg.getReg() == 0 && "Invalid eip-based address.");
    return true;
  }
  if (IndexReg.getReg() == X86::EIZ)
    return true;
  return false;
}

/// \param Op operand # of the memory operand.
///
/// \returns true if the specified instruction has a 64-bit memory operand.
#ifndef NDEBUG
static bool is64BitMemOperand(const MCInst &MI, unsigned Op) {
  const MCOperand &BaseReg = MI.getOperand(Op + X86::AddrBaseReg);
  const MCOperand &IndexReg = MI.getOperand(Op + X86::AddrIndexReg);

  if ((BaseReg.getReg() != 0 &&
       X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg.getReg())) ||
      (IndexReg.getReg() != 0 &&
       X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg.getReg())))
    return true;
  return false;
}
#endif

enum GlobalOffsetTableExprKind { GOT_None, GOT_Normal, GOT_SymDiff };

/// Check if this expression starts with  _GLOBAL_OFFSET_TABLE_ and if it is
/// of the form _GLOBAL_OFFSET_TABLE_-symbol. This is needed to support PIC on
/// ELF i386 as _GLOBAL_OFFSET_TABLE_ is magical. We check only simple case that
/// are know to be used: _GLOBAL_OFFSET_TABLE_ by itself or at the start of a
/// binary expression.
static GlobalOffsetTableExprKind
startsWithGlobalOffsetTable(const MCExpr *Expr) {
  const MCExpr *RHS = nullptr;
  if (Expr->getKind() == MCExpr::Binary) {
    const MCBinaryExpr *BE = static_cast<const MCBinaryExpr *>(Expr);
    Expr = BE->getLHS();
    RHS = BE->getRHS();
  }

  if (Expr->getKind() != MCExpr::SymbolRef)
    return GOT_None;

  const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
  const MCSymbol &S = Ref->getSymbol();
  if (S.getName() != "_GLOBAL_OFFSET_TABLE_")
    return GOT_None;
  if (RHS && RHS->getKind() == MCExpr::SymbolRef)
    return GOT_SymDiff;
  return GOT_Normal;
}

static bool hasSecRelSymbolRef(const MCExpr *Expr) {
  if (Expr->getKind() == MCExpr::SymbolRef) {
    const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
    return Ref->getKind() == MCSymbolRefExpr::VK_SECREL;
  }
  return false;
}

static bool isPCRel32Branch(const MCInst &MI, const MCInstrInfo &MCII) {
  unsigned Opcode = MI.getOpcode();
  const MCInstrDesc &Desc = MCII.get(Opcode);
  if ((Opcode != X86::CALL64pcrel32 && Opcode != X86::JMP_4 &&
       Opcode != X86::JCC_4) ||
      getImmFixupKind(Desc.TSFlags) != FK_PCRel_4)
    return false;

  unsigned CurOp = X86II::getOperandBias(Desc);
  const MCOperand &Op = MI.getOperand(CurOp);
  if (!Op.isExpr())
    return false;

  const MCSymbolRefExpr *Ref = dyn_cast<MCSymbolRefExpr>(Op.getExpr());
  return Ref && Ref->getKind() == MCSymbolRefExpr::VK_None;
}

unsigned X86MCCodeEmitter::getX86RegNum(const MCOperand &MO) const {
  return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg()) & 0x7;
}

unsigned X86MCCodeEmitter::getX86RegEncoding(const MCInst &MI,
                                             unsigned OpNum) const {
  return Ctx.getRegisterInfo()->getEncodingValue(MI.getOperand(OpNum).getReg());
}

/// \param MI a single low-level machine instruction.
/// \param OpNum the operand #.
/// \returns true if the OpNumth operand of MI  require a bit to be set in
/// REX prefix.
bool X86MCCodeEmitter::isREXExtendedReg(const MCInst &MI,
                                        unsigned OpNum) const {
  return (getX86RegEncoding(MI, OpNum) >> 3) & 1;
}

void X86MCCodeEmitter::emitImmediate(const MCOperand &DispOp, SMLoc Loc,
                                     unsigned Size, MCFixupKind FixupKind,
                                     uint64_t StartByte, raw_ostream &OS,
                                     SmallVectorImpl<MCFixup> &Fixups,
                                     int ImmOffset) const {
  const MCExpr *Expr = nullptr;
  if (DispOp.isImm()) {
    // If this is a simple integer displacement that doesn't require a
    // relocation, emit it now.
    if (FixupKind != FK_PCRel_1 && FixupKind != FK_PCRel_2 &&
        FixupKind != FK_PCRel_4) {
      emitConstant(DispOp.getImm() + ImmOffset, Size, OS);
      return;
    }
    Expr = MCConstantExpr::create(DispOp.getImm(), Ctx);
  } else {
    Expr = DispOp.getExpr();
  }

  // If we have an immoffset, add it to the expression.
  if ((FixupKind == FK_Data_4 || FixupKind == FK_Data_8 ||
       FixupKind == MCFixupKind(X86::reloc_signed_4byte))) {
    GlobalOffsetTableExprKind Kind = startsWithGlobalOffsetTable(Expr);
    if (Kind != GOT_None) {
      assert(ImmOffset == 0);

      if (Size == 8) {
        FixupKind = MCFixupKind(X86::reloc_global_offset_table8);
      } else {
        assert(Size == 4);
        FixupKind = MCFixupKind(X86::reloc_global_offset_table);
      }

      if (Kind == GOT_Normal)
        ImmOffset = static_cast<int>(OS.tell() - StartByte);
    } else if (Expr->getKind() == MCExpr::SymbolRef) {
      if (hasSecRelSymbolRef(Expr)) {
        FixupKind = MCFixupKind(FK_SecRel_4);
      }
    } else if (Expr->getKind() == MCExpr::Binary) {
      const MCBinaryExpr *Bin = static_cast<const MCBinaryExpr *>(Expr);
      if (hasSecRelSymbolRef(Bin->getLHS()) ||
          hasSecRelSymbolRef(Bin->getRHS())) {
        FixupKind = MCFixupKind(FK_SecRel_4);
      }
    }
  }

  // If the fixup is pc-relative, we need to bias the value to be relative to
  // the start of the field, not the end of the field.
  if (FixupKind == FK_PCRel_4 ||
      FixupKind == MCFixupKind(X86::reloc_riprel_4byte) ||
      FixupKind == MCFixupKind(X86::reloc_riprel_4byte_movq_load) ||
      FixupKind == MCFixupKind(X86::reloc_riprel_4byte_relax) ||
      FixupKind == MCFixupKind(X86::reloc_riprel_4byte_relax_rex) ||
      FixupKind == MCFixupKind(X86::reloc_branch_4byte_pcrel)) {
    ImmOffset -= 4;
    // If this is a pc-relative load off _GLOBAL_OFFSET_TABLE_:
    // leaq _GLOBAL_OFFSET_TABLE_(%rip), %r15
    // this needs to be a GOTPC32 relocation.
    if (startsWithGlobalOffsetTable(Expr) != GOT_None)
      FixupKind = MCFixupKind(X86::reloc_global_offset_table);
  }
  if (FixupKind == FK_PCRel_2)
    ImmOffset -= 2;
  if (FixupKind == FK_PCRel_1)
    ImmOffset -= 1;

  if (ImmOffset)
    Expr = MCBinaryExpr::createAdd(Expr, MCConstantExpr::create(ImmOffset, Ctx),
                                   Ctx);

  // Emit a symbolic constant as a fixup and 4 zeros.
  Fixups.push_back(MCFixup::create(static_cast<uint32_t>(OS.tell() - StartByte),
                                   Expr, FixupKind, Loc));
  emitConstant(0, Size, OS);
}

void X86MCCodeEmitter::emitRegModRMByte(const MCOperand &ModRMReg,
                                        unsigned RegOpcodeFld,
                                        raw_ostream &OS) const {
  emitByte(modRMByte(3, RegOpcodeFld, getX86RegNum(ModRMReg)), OS);
}

void X86MCCodeEmitter::emitSIBByte(unsigned SS, unsigned Index, unsigned Base,
                                   raw_ostream &OS) const {
  // SIB byte is in the same format as the modRMByte.
  emitByte(modRMByte(SS, Index, Base), OS);
}

void X86MCCodeEmitter::emitMemModRMByte(const MCInst &MI, unsigned Op,
                                        unsigned RegOpcodeField,
                                        uint64_t TSFlags, bool HasREX,
                                        uint64_t StartByte, raw_ostream &OS,
                                        SmallVectorImpl<MCFixup> &Fixups,
                                        const MCSubtargetInfo &STI,
                                        bool ForceSIB) const {
  const MCOperand &Disp = MI.getOperand(Op + X86::AddrDisp);
  const MCOperand &Base = MI.getOperand(Op + X86::AddrBaseReg);
  const MCOperand &Scale = MI.getOperand(Op + X86::AddrScaleAmt);
  const MCOperand &IndexReg = MI.getOperand(Op + X86::AddrIndexReg);
  unsigned BaseReg = Base.getReg();

  // Handle %rip relative addressing.
  if (BaseReg == X86::RIP ||
      BaseReg == X86::EIP) { // [disp32+rIP] in X86-64 mode
    assert(STI.hasFeature(X86::Mode64Bit) &&
           "Rip-relative addressing requires 64-bit mode");
    assert(IndexReg.getReg() == 0 && !ForceSIB &&
           "Invalid rip-relative address");
    emitByte(modRMByte(0, RegOpcodeField, 5), OS);

    unsigned Opcode = MI.getOpcode();
    unsigned FixupKind = [&]() {
      // Enable relaxed relocation only for a MCSymbolRefExpr.  We cannot use a
      // relaxed relocation if an offset is present (e.g. x@GOTPCREL+4).
      if (!(Disp.isExpr() && isa<MCSymbolRefExpr>(Disp.getExpr())))
        return X86::reloc_riprel_4byte;

      // Certain loads for GOT references can be relocated against the symbol
      // directly if the symbol ends up in the same linkage unit.
      switch (Opcode) {
      default:
        return X86::reloc_riprel_4byte;
      case X86::MOV64rm:
        // movq loads is a subset of reloc_riprel_4byte_relax_rex. It is a
        // special case because COFF and Mach-O don't support ELF's more
        // flexible R_X86_64_REX_GOTPCRELX relaxation.
        assert(HasREX);
        return X86::reloc_riprel_4byte_movq_load;
      case X86::ADC32rm:
      case X86::ADD32rm:
      case X86::AND32rm:
      case X86::CMP32rm:
      case X86::MOV32rm:
      case X86::OR32rm:
      case X86::SBB32rm:
      case X86::SUB32rm:
      case X86::TEST32mr:
      case X86::XOR32rm:
      case X86::CALL64m:
      case X86::JMP64m:
      case X86::TAILJMPm64:
      case X86::TEST64mr:
      case X86::ADC64rm:
      case X86::ADD64rm:
      case X86::AND64rm:
      case X86::CMP64rm:
      case X86::OR64rm:
      case X86::SBB64rm:
      case X86::SUB64rm:
      case X86::XOR64rm:
        return HasREX ? X86::reloc_riprel_4byte_relax_rex
                      : X86::reloc_riprel_4byte_relax;
      }
    }();

    // rip-relative addressing is actually relative to the *next* instruction.
    // Since an immediate can follow the mod/rm byte for an instruction, this
    // means that we need to bias the displacement field of the instruction with
    // the size of the immediate field. If we have this case, add it into the
    // expression to emit.
    // Note: rip-relative addressing using immediate displacement values should
    // not be adjusted, assuming it was the user's intent.
    int ImmSize = !Disp.isImm() && X86II::hasImm(TSFlags)
                      ? X86II::getSizeOfImm(TSFlags)
                      : 0;

    emitImmediate(Disp, MI.getLoc(), 4, MCFixupKind(FixupKind), StartByte, OS,
                  Fixups, -ImmSize);
    return;
  }

  unsigned BaseRegNo = BaseReg ? getX86RegNum(Base) : -1U;

  // 16-bit addressing forms of the ModR/M byte have a different encoding for
  // the R/M field and are far more limited in which registers can be used.
  if (is16BitMemOperand(MI, Op, STI)) {
    if (BaseReg) {
      // For 32-bit addressing, the row and column values in Table 2-2 are
      // basically the same. It's AX/CX/DX/BX/SP/BP/SI/DI in that order, with
      // some special cases. And getX86RegNum reflects that numbering.
      // For 16-bit addressing it's more fun, as shown in the SDM Vol 2A,
      // Table 2-1 "16-Bit Addressing Forms with the ModR/M byte". We can only
      // use SI/DI/BP/BX, which have "row" values 4-7 in no particular order,
      // while values 0-3 indicate the allowed combinations (base+index) of
      // those: 0 for BX+SI, 1 for BX+DI, 2 for BP+SI, 3 for BP+DI.
      //
      // R16Table[] is a lookup from the normal RegNo, to the row values from
      // Table 2-1 for 16-bit addressing modes. Where zero means disallowed.
      static const unsigned R16Table[] = {0, 0, 0, 7, 0, 6, 4, 5};
      unsigned RMfield = R16Table[BaseRegNo];

      assert(RMfield && "invalid 16-bit base register");

      if (IndexReg.getReg()) {
        unsigned IndexReg16 = R16Table[getX86RegNum(IndexReg)];

        assert(IndexReg16 && "invalid 16-bit index register");
        // We must have one of SI/DI (4,5), and one of BP/BX (6,7).
        assert(((IndexReg16 ^ RMfield) & 2) &&
               "invalid 16-bit base/index register combination");
        assert(Scale.getImm() == 1 &&
               "invalid scale for 16-bit memory reference");

        // Allow base/index to appear in either order (although GAS doesn't).
        if (IndexReg16 & 2)
          RMfield = (RMfield & 1) | ((7 - IndexReg16) << 1);
        else
          RMfield = (IndexReg16 & 1) | ((7 - RMfield) << 1);
      }

      if (Disp.isImm() && isInt<8>(Disp.getImm())) {
        if (Disp.getImm() == 0 && RMfield != 6) {
          // There is no displacement; just the register.
          emitByte(modRMByte(0, RegOpcodeField, RMfield), OS);
          return;
        }
        // Use the [REG]+disp8 form, including for [BP] which cannot be encoded.
        emitByte(modRMByte(1, RegOpcodeField, RMfield), OS);
        emitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, StartByte, OS, Fixups);
        return;
      }
      // This is the [REG]+disp16 case.
      emitByte(modRMByte(2, RegOpcodeField, RMfield), OS);
    } else {
      assert(IndexReg.getReg() == 0 && "Unexpected index register!");
      // There is no BaseReg; this is the plain [disp16] case.
      emitByte(modRMByte(0, RegOpcodeField, 6), OS);
    }

    // Emit 16-bit displacement for plain disp16 or [REG]+disp16 cases.
    emitImmediate(Disp, MI.getLoc(), 2, FK_Data_2, StartByte, OS, Fixups);
    return;
  }

  // Check for presence of {disp8} or {disp32} pseudo prefixes.
  bool UseDisp8 = MI.getFlags() & X86::IP_USE_DISP8;
  bool UseDisp32 = MI.getFlags() & X86::IP_USE_DISP32;

  // We only allow no displacement if no pseudo prefix is present.
  bool AllowNoDisp = !UseDisp8 && !UseDisp32;
  // Disp8 is allowed unless the {disp32} prefix is present.
  bool AllowDisp8 = !UseDisp32;

  // Determine whether a SIB byte is needed.
  if (// The SIB byte must be used if there is an index register or the
      // encoding requires a SIB byte.
      !ForceSIB && IndexReg.getReg() == 0 &&
      // The SIB byte must be used if the base is ESP/RSP/R12, all of which
      // encode to an R/M value of 4, which indicates that a SIB byte is
      // present.
      BaseRegNo != N86::ESP &&
      // If there is no base register and we're in 64-bit mode, we need a SIB
      // byte to emit an addr that is just 'disp32' (the non-RIP relative form).
      (!STI.hasFeature(X86::Mode64Bit) || BaseReg != 0)) {

    if (BaseReg == 0) { // [disp32]     in X86-32 mode
      emitByte(modRMByte(0, RegOpcodeField, 5), OS);
      emitImmediate(Disp, MI.getLoc(), 4, FK_Data_4, StartByte, OS, Fixups);
      return;
    }

    // If the base is not EBP/ESP/R12/R13 and there is no displacement, use
    // simple indirect register encoding, this handles addresses like [EAX].
    // The encoding for [EBP] or[R13] with no displacement means [disp32] so we
    // handle it by emitting a displacement of 0 later.
    if (BaseRegNo != N86::EBP) {
      if (Disp.isImm() && Disp.getImm() == 0 && AllowNoDisp) {
        emitByte(modRMByte(0, RegOpcodeField, BaseRegNo), OS);
        return;
      }

      // If the displacement is @tlscall, treat it as a zero.
      if (Disp.isExpr()) {
        auto *Sym = dyn_cast<MCSymbolRefExpr>(Disp.getExpr());
        if (Sym && Sym->getKind() == MCSymbolRefExpr::VK_TLSCALL) {
          // This is exclusively used by call *a@tlscall(base). The relocation
          // (R_386_TLSCALL or R_X86_64_TLSCALL) applies to the beginning.
          Fixups.push_back(MCFixup::create(0, Sym, FK_NONE, MI.getLoc()));
          emitByte(modRMByte(0, RegOpcodeField, BaseRegNo), OS);
          return;
        }
      }
    }

    // Otherwise, if the displacement fits in a byte, encode as [REG+disp8].
    // Including a compressed disp8 for EVEX instructions that support it.
    // This also handles the 0 displacement for [EBP] or [R13]. We can't use
    // disp8 if the {disp32} pseudo prefix is present.
    if (Disp.isImm() && AllowDisp8) {
      int ImmOffset = 0;
      if (isDispOrCDisp8(TSFlags, Disp.getImm(), ImmOffset)) {
        emitByte(modRMByte(1, RegOpcodeField, BaseRegNo), OS);
        emitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, StartByte, OS, Fixups,
                      ImmOffset);
        return;
      }
    }

    // Otherwise, emit the most general non-SIB encoding: [REG+disp32].
    // Displacement may be 0 for [EBP] or [R13] case if {disp32} pseudo prefix
    // prevented using disp8 above.
    emitByte(modRMByte(2, RegOpcodeField, BaseRegNo), OS);
    unsigned Opcode = MI.getOpcode();
    unsigned FixupKind = Opcode == X86::MOV32rm ? X86::reloc_signed_4byte_relax
                                                : X86::reloc_signed_4byte;
    emitImmediate(Disp, MI.getLoc(), 4, MCFixupKind(FixupKind), StartByte, OS,
                  Fixups);
    return;
  }

  // We need a SIB byte, so start by outputting the ModR/M byte first
  assert(IndexReg.getReg() != X86::ESP && IndexReg.getReg() != X86::RSP &&
         "Cannot use ESP as index reg!");

  bool ForceDisp32 = false;
  bool ForceDisp8 = false;
  int ImmOffset = 0;
  if (BaseReg == 0) {
    // If there is no base register, we emit the special case SIB byte with
    // MOD=0, BASE=5, to JUST get the index, scale, and displacement.
    BaseRegNo = 5;
    emitByte(modRMByte(0, RegOpcodeField, 4), OS);
    ForceDisp32 = true;
  } else if (Disp.isImm() && Disp.getImm() == 0 && AllowNoDisp &&
             // Base reg can't be EBP/RBP/R13 as that would end up with '5' as
             // the base field, but that is the magic [*] nomenclature that
             // indicates no base when mod=0. For these cases we'll emit a 0
             // displacement instead.
             BaseRegNo != N86::EBP) {
    // Emit no displacement ModR/M byte
    emitByte(modRMByte(0, RegOpcodeField, 4), OS);
  } else if (Disp.isImm() && AllowDisp8 &&
             isDispOrCDisp8(TSFlags, Disp.getImm(), ImmOffset)) {
    // Displacement fits in a byte or matches an EVEX compressed disp8, use
    // disp8 encoding. This also handles EBP/R13 base with 0 displacement unless
    // {disp32} pseudo prefix was used.
    emitByte(modRMByte(1, RegOpcodeField, 4), OS);
    ForceDisp8 = true;
  } else {
    // Otherwise, emit the normal disp32 encoding.
    emitByte(modRMByte(2, RegOpcodeField, 4), OS);
    ForceDisp32 = true;
  }

  // Calculate what the SS field value should be...
  static const unsigned SSTable[] = {~0U, 0, 1, ~0U, 2, ~0U, ~0U, ~0U, 3};
  unsigned SS = SSTable[Scale.getImm()];

  unsigned IndexRegNo = IndexReg.getReg() ? getX86RegNum(IndexReg) : 4;

  emitSIBByte(SS, IndexRegNo, BaseRegNo, OS);

  // Do we need to output a displacement?
  if (ForceDisp8)
    emitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, StartByte, OS, Fixups,
                  ImmOffset);
  else if (ForceDisp32)
    emitImmediate(Disp, MI.getLoc(), 4, MCFixupKind(X86::reloc_signed_4byte),
                  StartByte, OS, Fixups);
}

/// Emit all instruction prefixes.
///
/// \returns true if REX prefix is used, otherwise returns false.
bool X86MCCodeEmitter::emitPrefixImpl(unsigned &CurOp, const MCInst &MI,
                                      const MCSubtargetInfo &STI,
                                      raw_ostream &OS) const {
  uint64_t TSFlags = MCII.get(MI.getOpcode()).TSFlags;
  // Determine where the memory operand starts, if present.
  int MemoryOperand = X86II::getMemoryOperandNo(TSFlags);
  // Emit segment override opcode prefix as needed.
  if (MemoryOperand != -1) {
    MemoryOperand += CurOp;
    emitSegmentOverridePrefix(MemoryOperand + X86::AddrSegmentReg, MI, OS);
  }

  // Emit the repeat opcode prefix as needed.
  unsigned Flags = MI.getFlags();
  if (TSFlags & X86II::REP || Flags & X86::IP_HAS_REPEAT)
    emitByte(0xF3, OS);
  if (Flags & X86::IP_HAS_REPEAT_NE)
    emitByte(0xF2, OS);

  // Emit the address size opcode prefix as needed.
  bool NeedAddressOverride;
  uint64_t AdSize = TSFlags & X86II::AdSizeMask;
  if ((STI.hasFeature(X86::Mode16Bit) && AdSize == X86II::AdSize32) ||
      (STI.hasFeature(X86::Mode32Bit) && AdSize == X86II::AdSize16) ||
      (STI.hasFeature(X86::Mode64Bit) && AdSize == X86II::AdSize32)) {
    NeedAddressOverride = true;
  } else if (MemoryOperand < 0) {
    NeedAddressOverride = false;
  } else if (STI.hasFeature(X86::Mode64Bit)) {
    assert(!is16BitMemOperand(MI, MemoryOperand, STI));
    NeedAddressOverride = is32BitMemOperand(MI, MemoryOperand);
  } else if (STI.hasFeature(X86::Mode32Bit)) {
    assert(!is64BitMemOperand(MI, MemoryOperand));
    NeedAddressOverride = is16BitMemOperand(MI, MemoryOperand, STI);
  } else {
    assert(STI.hasFeature(X86::Mode16Bit));
    assert(!is64BitMemOperand(MI, MemoryOperand));
    NeedAddressOverride = !is16BitMemOperand(MI, MemoryOperand, STI);
  }

  if (NeedAddressOverride)
    emitByte(0x67, OS);

  // Encoding type for this instruction.
  uint64_t Encoding = TSFlags & X86II::EncodingMask;
  bool HasREX = false;
  if (Encoding)
    emitVEXOpcodePrefix(MemoryOperand, MI, OS);
  else
    HasREX = emitOpcodePrefix(MemoryOperand, MI, STI, OS);

  uint64_t Form = TSFlags & X86II::FormMask;
  switch (Form) {
  default:
    break;
  case X86II::RawFrmDstSrc: {
    unsigned siReg = MI.getOperand(1).getReg();
    assert(((siReg == X86::SI && MI.getOperand(0).getReg() == X86::DI) ||
            (siReg == X86::ESI && MI.getOperand(0).getReg() == X86::EDI) ||
            (siReg == X86::RSI && MI.getOperand(0).getReg() == X86::RDI)) &&
           "SI and DI register sizes do not match");
    // Emit segment override opcode prefix as needed (not for %ds).
    if (MI.getOperand(2).getReg() != X86::DS)
      emitSegmentOverridePrefix(2, MI, OS);
    // Emit AdSize prefix as needed.
    if ((!STI.hasFeature(X86::Mode32Bit) && siReg == X86::ESI) ||
        (STI.hasFeature(X86::Mode32Bit) && siReg == X86::SI))
      emitByte(0x67, OS);
    CurOp += 3; // Consume operands.
    break;
  }
  case X86II::RawFrmSrc: {
    unsigned siReg = MI.getOperand(0).getReg();
    // Emit segment override opcode prefix as needed (not for %ds).
    if (MI.getOperand(1).getReg() != X86::DS)
      emitSegmentOverridePrefix(1, MI, OS);
    // Emit AdSize prefix as needed.
    if ((!STI.hasFeature(X86::Mode32Bit) && siReg == X86::ESI) ||
        (STI.hasFeature(X86::Mode32Bit) && siReg == X86::SI))
      emitByte(0x67, OS);
    CurOp += 2; // Consume operands.
    break;
  }
  case X86II::RawFrmDst: {
    unsigned siReg = MI.getOperand(0).getReg();
    // Emit AdSize prefix as needed.
    if ((!STI.hasFeature(X86::Mode32Bit) && siReg == X86::EDI) ||
        (STI.hasFeature(X86::Mode32Bit) && siReg == X86::DI))
      emitByte(0x67, OS);
    ++CurOp; // Consume operand.
    break;
  }
  case X86II::RawFrmMemOffs: {
    // Emit segment override opcode prefix as needed.
    emitSegmentOverridePrefix(1, MI, OS);
    break;
  }
  }

  return HasREX;
}

/// AVX instructions are encoded using a opcode prefix called VEX.
void X86MCCodeEmitter::emitVEXOpcodePrefix(int MemOperand, const MCInst &MI,
                                           raw_ostream &OS) const {
  const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
  uint64_t TSFlags = Desc.TSFlags;

  assert(!(TSFlags & X86II::LOCK) && "Can't have LOCK VEX.");

  uint64_t Encoding = TSFlags & X86II::EncodingMask;
  bool HasEVEX_K = TSFlags & X86II::EVEX_K;
  bool HasVEX_4V = TSFlags & X86II::VEX_4V;
  bool HasEVEX_RC = TSFlags & X86II::EVEX_RC;

  // VEX_R: opcode externsion equivalent to REX.R in
  // 1's complement (inverted) form
  //
  //  1: Same as REX_R=0 (must be 1 in 32-bit mode)
  //  0: Same as REX_R=1 (64 bit mode only)
  //
  uint8_t VEX_R = 0x1;
  uint8_t EVEX_R2 = 0x1;

  // VEX_X: equivalent to REX.X, only used when a
  // register is used for index in SIB Byte.
  //
  //  1: Same as REX.X=0 (must be 1 in 32-bit mode)
  //  0: Same as REX.X=1 (64-bit mode only)
  uint8_t VEX_X = 0x1;

  // VEX_B:
  //
  //  1: Same as REX_B=0 (ignored in 32-bit mode)
  //  0: Same as REX_B=1 (64 bit mode only)
  //
  uint8_t VEX_B = 0x1;

  // VEX_W: opcode specific (use like REX.W, or used for
  // opcode extension, or ignored, depending on the opcode byte)
  uint8_t VEX_W = (TSFlags & X86II::VEX_W) ? 1 : 0;

  // VEX_5M (VEX m-mmmmm field):
  //
  //  0b00000: Reserved for future use
  //  0b00001: implied 0F leading opcode
  //  0b00010: implied 0F 38 leading opcode bytes
  //  0b00011: implied 0F 3A leading opcode bytes
  //  0b00100-0b11111: Reserved for future use
  //  0b01000: XOP map select - 08h instructions with imm byte
  //  0b01001: XOP map select - 09h instructions with no imm byte
  //  0b01010: XOP map select - 0Ah instructions with imm dword
  uint8_t VEX_5M;
  switch (TSFlags & X86II::OpMapMask) {
  default:
    llvm_unreachable("Invalid prefix!");
  case X86II::TB:
    VEX_5M = 0x1;
    break; // 0F
  case X86II::T8:
    VEX_5M = 0x2;
    break; // 0F 38
  case X86II::TA:
    VEX_5M = 0x3;
    break; // 0F 3A
  case X86II::XOP8:
    VEX_5M = 0x8;
    break;
  case X86II::XOP9:
    VEX_5M = 0x9;
    break;
  case X86II::XOPA:
    VEX_5M = 0xA;
    break;
  }

  // VEX_4V (VEX vvvv field): a register specifier
  // (in 1's complement form) or 1111 if unused.
  uint8_t VEX_4V = 0xf;
  uint8_t EVEX_V2 = 0x1;

  // EVEX_L2/VEX_L (Vector Length):
  //
  // L2 L
  //  0 0: scalar or 128-bit vector
  //  0 1: 256-bit vector
  //  1 0: 512-bit vector
  //
  uint8_t VEX_L = (TSFlags & X86II::VEX_L) ? 1 : 0;
  uint8_t EVEX_L2 = (TSFlags & X86II::EVEX_L2) ? 1 : 0;

  // VEX_PP: opcode extension providing equivalent
  // functionality of a SIMD prefix
  //
  //  0b00: None
  //  0b01: 66
  //  0b10: F3
  //  0b11: F2
  //
  uint8_t VEX_PP = 0;
  switch (TSFlags & X86II::OpPrefixMask) {
  case X86II::PD:
    VEX_PP = 0x1;
    break; // 66
  case X86II::XS:
    VEX_PP = 0x2;
    break; // F3
  case X86II::XD:
    VEX_PP = 0x3;
    break; // F2
  }

  // EVEX_U
  uint8_t EVEX_U = 1; // Always '1' so far

  // EVEX_z
  uint8_t EVEX_z = (HasEVEX_K && (TSFlags & X86II::EVEX_Z)) ? 1 : 0;

  // EVEX_b
  uint8_t EVEX_b = (TSFlags & X86II::EVEX_B) ? 1 : 0;

  // EVEX_rc
  uint8_t EVEX_rc = 0;

  // EVEX_aaa
  uint8_t EVEX_aaa = 0;

  bool EncodeRC = false;

  // Classify VEX_B, VEX_4V, VEX_R, VEX_X
  unsigned NumOps = Desc.getNumOperands();
  unsigned CurOp = X86II::getOperandBias(Desc);

  switch (TSFlags & X86II::FormMask) {
  default:
    llvm_unreachable("Unexpected form in emitVEXOpcodePrefix!");
  case X86II::MRM_C0:
  case X86II::RawFrm:
  case X86II::PrefixByte:
    break;
  case X86II::MRMDestMemFSIB:
  case X86II::MRMDestMem: {
    // MRMDestMem instructions forms:
    //  MemAddr, src1(ModR/M)
    //  MemAddr, src1(VEX_4V), src2(ModR/M)
    //  MemAddr, src1(ModR/M), imm8
    //
    unsigned BaseRegEnc = getX86RegEncoding(MI, MemOperand + X86::AddrBaseReg);
    VEX_B = ~(BaseRegEnc >> 3) & 1;
    unsigned IndexRegEnc =
        getX86RegEncoding(MI, MemOperand + X86::AddrIndexReg);
    VEX_X = ~(IndexRegEnc >> 3) & 1;
    if (!HasVEX_4V) // Only needed with VSIB which don't use VVVV.
      EVEX_V2 = ~(IndexRegEnc >> 4) & 1;

    CurOp += X86::AddrNumOperands;

    if (HasEVEX_K)
      EVEX_aaa = getX86RegEncoding(MI, CurOp++);

    if (HasVEX_4V) {
      unsigned VRegEnc = getX86RegEncoding(MI, CurOp++);
      VEX_4V = ~VRegEnc & 0xf;
      EVEX_V2 = ~(VRegEnc >> 4) & 1;
    }

    unsigned RegEnc = getX86RegEncoding(MI, CurOp++);
    VEX_R = ~(RegEnc >> 3) & 1;
    EVEX_R2 = ~(RegEnc >> 4) & 1;
    break;
  }
  case X86II::MRMSrcMemFSIB:
  case X86II::MRMSrcMem: {
    // MRMSrcMem instructions forms:
    //  src1(ModR/M), MemAddr
    //  src1(ModR/M), src2(VEX_4V), MemAddr
    //  src1(ModR/M), MemAddr, imm8
    //  src1(ModR/M), MemAddr, src2(Imm[7:4])
    //
    //  FMA4:
    //  dst(ModR/M.reg), src1(VEX_4V), src2(ModR/M), src3(Imm[7:4])
    unsigned RegEnc = getX86RegEncoding(MI, CurOp++);
    VEX_R = ~(RegEnc >> 3) & 1;
    EVEX_R2 = ~(RegEnc >> 4) & 1;

    if (HasEVEX_K)
      EVEX_aaa = getX86RegEncoding(MI, CurOp++);

    if (HasVEX_4V) {
      unsigned VRegEnc = getX86RegEncoding(MI, CurOp++);
      VEX_4V = ~VRegEnc & 0xf;
      EVEX_V2 = ~(VRegEnc >> 4) & 1;
    }

    unsigned BaseRegEnc = getX86RegEncoding(MI, MemOperand + X86::AddrBaseReg);
    VEX_B = ~(BaseRegEnc >> 3) & 1;
    unsigned IndexRegEnc =
        getX86RegEncoding(MI, MemOperand + X86::AddrIndexReg);
    VEX_X = ~(IndexRegEnc >> 3) & 1;
    if (!HasVEX_4V) // Only needed with VSIB which don't use VVVV.
      EVEX_V2 = ~(IndexRegEnc >> 4) & 1;

    break;
  }
  case X86II::MRMSrcMem4VOp3: {
    // Instruction format for 4VOp3:
    //   src1(ModR/M), MemAddr, src3(VEX_4V)
    unsigned RegEnc = getX86RegEncoding(MI, CurOp++);
    VEX_R = ~(RegEnc >> 3) & 1;

    unsigned BaseRegEnc = getX86RegEncoding(MI, MemOperand + X86::AddrBaseReg);
    VEX_B = ~(BaseRegEnc >> 3) & 1;
    unsigned IndexRegEnc =
        getX86RegEncoding(MI, MemOperand + X86::AddrIndexReg);
    VEX_X = ~(IndexRegEnc >> 3) & 1;

    VEX_4V = ~getX86RegEncoding(MI, CurOp + X86::AddrNumOperands) & 0xf;
    break;
  }
  case X86II::MRMSrcMemOp4: {
    //  dst(ModR/M.reg), src1(VEX_4V), src2(Imm[7:4]), src3(ModR/M),
    unsigned RegEnc = getX86RegEncoding(MI, CurOp++);
    VEX_R = ~(RegEnc >> 3) & 1;

    unsigned VRegEnc = getX86RegEncoding(MI, CurOp++);
    VEX_4V = ~VRegEnc & 0xf;

    unsigned BaseRegEnc = getX86RegEncoding(MI, MemOperand + X86::AddrBaseReg);
    VEX_B = ~(BaseRegEnc >> 3) & 1;
    unsigned IndexRegEnc =
        getX86RegEncoding(MI, MemOperand + X86::AddrIndexReg);
    VEX_X = ~(IndexRegEnc >> 3) & 1;
    break;
  }
  case X86II::MRM0m:
  case X86II::MRM1m:
  case X86II::MRM2m:
  case X86II::MRM3m:
  case X86II::MRM4m:
  case X86II::MRM5m:
  case X86II::MRM6m:
  case X86II::MRM7m: {
    // MRM[0-9]m instructions forms:
    //  MemAddr
    //  src1(VEX_4V), MemAddr
    if (HasVEX_4V) {
      unsigned VRegEnc = getX86RegEncoding(MI, CurOp++);
      VEX_4V = ~VRegEnc & 0xf;
      EVEX_V2 = ~(VRegEnc >> 4) & 1;
    }

    if (HasEVEX_K)
      EVEX_aaa = getX86RegEncoding(MI, CurOp++);

    unsigned BaseRegEnc = getX86RegEncoding(MI, MemOperand + X86::AddrBaseReg);
    VEX_B = ~(BaseRegEnc >> 3) & 1;
    unsigned IndexRegEnc =
        getX86RegEncoding(MI, MemOperand + X86::AddrIndexReg);
    VEX_X = ~(IndexRegEnc >> 3) & 1;
    if (!HasVEX_4V) // Only needed with VSIB which don't use VVVV.
      EVEX_V2 = ~(IndexRegEnc >> 4) & 1;

    break;
  }
  case X86II::MRMSrcReg: {
    // MRMSrcReg instructions forms:
    //  dst(ModR/M), src1(VEX_4V), src2(ModR/M), src3(Imm[7:4])
    //  dst(ModR/M), src1(ModR/M)
    //  dst(ModR/M), src1(ModR/M), imm8
    //
    //  FMA4:
    //  dst(ModR/M.reg), src1(VEX_4V), src2(Imm[7:4]), src3(ModR/M),
    unsigned RegEnc = getX86RegEncoding(MI, CurOp++);
    VEX_R = ~(RegEnc >> 3) & 1;
    EVEX_R2 = ~(RegEnc >> 4) & 1;

    if (HasEVEX_K)
      EVEX_aaa = getX86RegEncoding(MI, CurOp++);

    if (HasVEX_4V) {
      unsigned VRegEnc = getX86RegEncoding(MI, CurOp++);
      VEX_4V = ~VRegEnc & 0xf;
      EVEX_V2 = ~(VRegEnc >> 4) & 1;
    }

    RegEnc = getX86RegEncoding(MI, CurOp++);
    VEX_B = ~(RegEnc >> 3) & 1;
    VEX_X = ~(RegEnc >> 4) & 1;

    if (EVEX_b) {
      if (HasEVEX_RC) {
        unsigned RcOperand = NumOps - 1;
        assert(RcOperand >= CurOp);
        EVEX_rc = MI.getOperand(RcOperand).getImm();
        assert(EVEX_rc <= 3 && "Invalid rounding control!");
      }
      EncodeRC = true;
    }
    break;
  }
  case X86II::MRMSrcReg4VOp3: {
    // Instruction format for 4VOp3:
    //   src1(ModR/M), src2(ModR/M), src3(VEX_4V)
    unsigned RegEnc = getX86RegEncoding(MI, CurOp++);
    VEX_R = ~(RegEnc >> 3) & 1;

    RegEnc = getX86RegEncoding(MI, CurOp++);
    VEX_B = ~(RegEnc >> 3) & 1;

    VEX_4V = ~getX86RegEncoding(MI, CurOp++) & 0xf;
    break;
  }
  case X86II::MRMSrcRegOp4: {
    //  dst(ModR/M.reg), src1(VEX_4V), src2(Imm[7:4]), src3(ModR/M),
    unsigned RegEnc = getX86RegEncoding(MI, CurOp++);
    VEX_R = ~(RegEnc >> 3) & 1;

    unsigned VRegEnc = getX86RegEncoding(MI, CurOp++);
    VEX_4V = ~VRegEnc & 0xf;

    // Skip second register source (encoded in Imm[7:4])
    ++CurOp;

    RegEnc = getX86RegEncoding(MI, CurOp++);
    VEX_B = ~(RegEnc >> 3) & 1;
    VEX_X = ~(RegEnc >> 4) & 1;
    break;
  }
  case X86II::MRMDestReg: {
    // MRMDestReg instructions forms:
    //  dst(ModR/M), src(ModR/M)
    //  dst(ModR/M), src(ModR/M), imm8
    //  dst(ModR/M), src1(VEX_4V), src2(ModR/M)
    unsigned RegEnc = getX86RegEncoding(MI, CurOp++);
    VEX_B = ~(RegEnc >> 3) & 1;
    VEX_X = ~(RegEnc >> 4) & 1;

    if (HasEVEX_K)
      EVEX_aaa = getX86RegEncoding(MI, CurOp++);

    if (HasVEX_4V) {
      unsigned VRegEnc = getX86RegEncoding(MI, CurOp++);
      VEX_4V = ~VRegEnc & 0xf;
      EVEX_V2 = ~(VRegEnc >> 4) & 1;
    }

    RegEnc = getX86RegEncoding(MI, CurOp++);
    VEX_R = ~(RegEnc >> 3) & 1;
    EVEX_R2 = ~(RegEnc >> 4) & 1;
    if (EVEX_b)
      EncodeRC = true;
    break;
  }
  case X86II::MRMr0: {
    // MRMr0 instructions forms:
    //  11:rrr:000
    //  dst(ModR/M)
    unsigned RegEnc = getX86RegEncoding(MI, CurOp++);
    VEX_R = ~(RegEnc >> 3) & 1;
    EVEX_R2 = ~(RegEnc >> 4) & 1;
    break;
  }
  case X86II::MRM0r:
  case X86II::MRM1r:
  case X86II::MRM2r:
  case X86II::MRM3r:
  case X86II::MRM4r:
  case X86II::MRM5r:
  case X86II::MRM6r:
  case X86II::MRM7r: {
    // MRM0r-MRM7r instructions forms:
    //  dst(VEX_4V), src(ModR/M), imm8
    if (HasVEX_4V) {
      unsigned VRegEnc = getX86RegEncoding(MI, CurOp++);
      VEX_4V = ~VRegEnc & 0xf;
      EVEX_V2 = ~(VRegEnc >> 4) & 1;
    }
    if (HasEVEX_K)
      EVEX_aaa = getX86RegEncoding(MI, CurOp++);

    unsigned RegEnc = getX86RegEncoding(MI, CurOp++);
    VEX_B = ~(RegEnc >> 3) & 1;
    VEX_X = ~(RegEnc >> 4) & 1;
    break;
  }
  }

  if (Encoding == X86II::VEX || Encoding == X86II::XOP) {
    // VEX opcode prefix can have 2 or 3 bytes
    //
    //  3 bytes:
    //    +-----+ +--------------+ +-------------------+
    //    | C4h | | RXB | m-mmmm | | W | vvvv | L | pp |
    //    +-----+ +--------------+ +-------------------+
    //  2 bytes:
    //    +-----+ +-------------------+
    //    | C5h | | R | vvvv | L | pp |
    //    +-----+ +-------------------+
    //
    //  XOP uses a similar prefix:
    //    +-----+ +--------------+ +-------------------+
    //    | 8Fh | | RXB | m-mmmm | | W | vvvv | L | pp |
    //    +-----+ +--------------+ +-------------------+
    uint8_t LastByte = VEX_PP | (VEX_L << 2) | (VEX_4V << 3);

    // Can we use the 2 byte VEX prefix?
    if (!(MI.getFlags() & X86::IP_USE_VEX3) && Encoding == X86II::VEX &&
        VEX_B && VEX_X && !VEX_W && (VEX_5M == 1)) {
      emitByte(0xC5, OS);
      emitByte(LastByte | (VEX_R << 7), OS);
      return;
    }

    // 3 byte VEX prefix
    emitByte(Encoding == X86II::XOP ? 0x8F : 0xC4, OS);
    emitByte(VEX_R << 7 | VEX_X << 6 | VEX_B << 5 | VEX_5M, OS);
    emitByte(LastByte | (VEX_W << 7), OS);
  } else {
    assert(Encoding == X86II::EVEX && "unknown encoding!");
    // EVEX opcode prefix can have 4 bytes
    //
    // +-----+ +--------------+ +-------------------+ +------------------------+
    // | 62h | | RXBR' | 00mm | | W | vvvv | U | pp | | z | L'L | b | v' | aaa |
    // +-----+ +--------------+ +-------------------+ +------------------------+
    assert((VEX_5M & 0x3) == VEX_5M &&
           "More than 2 significant bits in VEX.m-mmmm fields for EVEX!");

    emitByte(0x62, OS);
    emitByte((VEX_R << 7) | (VEX_X << 6) | (VEX_B << 5) | (EVEX_R2 << 4) |
                 VEX_5M,
             OS);
    emitByte((VEX_W << 7) | (VEX_4V << 3) | (EVEX_U << 2) | VEX_PP, OS);
    if (EncodeRC)
      emitByte((EVEX_z << 7) | (EVEX_rc << 5) | (EVEX_b << 4) | (EVEX_V2 << 3) |
                   EVEX_aaa,
               OS);
    else
      emitByte((EVEX_z << 7) | (EVEX_L2 << 6) | (VEX_L << 5) | (EVEX_b << 4) |
                   (EVEX_V2 << 3) | EVEX_aaa,
               OS);
  }
}

/// Emit REX prefix which specifies
///   1) 64-bit instructions,
///   2) non-default operand size, and
///   3) use of X86-64 extended registers.
///
/// \returns true if REX prefix is used, otherwise returns false.
bool X86MCCodeEmitter::emitREXPrefix(int MemOperand, const MCInst &MI,
                                     const MCSubtargetInfo &STI,
                                     raw_ostream &OS) const {
  uint8_t REX = [&, MemOperand]() {
    uint8_t REX = 0;
    bool UsesHighByteReg = false;

    const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
    uint64_t TSFlags = Desc.TSFlags;

    if (TSFlags & X86II::REX_W)
      REX |= 1 << 3; // set REX.W

    if (MI.getNumOperands() == 0)
      return REX;

    unsigned NumOps = MI.getNumOperands();
    unsigned CurOp = X86II::getOperandBias(Desc);

    // If it accesses SPL, BPL, SIL, or DIL, then it requires a 0x40 REX prefix.
    for (unsigned i = CurOp; i != NumOps; ++i) {
      const MCOperand &MO = MI.getOperand(i);
      if (MO.isReg()) {
        unsigned Reg = MO.getReg();
        if (Reg == X86::AH || Reg == X86::BH || Reg == X86::CH ||
            Reg == X86::DH)
          UsesHighByteReg = true;
        if (X86II::isX86_64NonExtLowByteReg(Reg))
          // FIXME: The caller of determineREXPrefix slaps this prefix onto
          // anything that returns non-zero.
          REX |= 0x40; // REX fixed encoding prefix
      } else if (MO.isExpr() &&
                 STI.getTargetTriple().getEnvironment() == Triple::GNUX32) {
        // GOTTPOFF and TLSDESC relocations require a REX prefix to allow
        // linker optimizations: even if the instructions we see may not require
        // any prefix, they may be replaced by instructions that do. This is
        // handled as a special case here so that it also works for hand-written
        // assembly without the user needing to write REX, as with GNU as.
        const auto *Ref = dyn_cast<MCSymbolRefExpr>(MO.getExpr());
        if (Ref && (Ref->getKind() == MCSymbolRefExpr::VK_GOTTPOFF ||
                    Ref->getKind() == MCSymbolRefExpr::VK_TLSDESC)) {
          REX |= 0x40; // REX fixed encoding prefix
        }
      }
    }

    switch (TSFlags & X86II::FormMask) {
    case X86II::AddRegFrm:
      REX |= isREXExtendedReg(MI, CurOp++) << 0; // REX.B
      break;
    case X86II::MRMSrcReg:
    case X86II::MRMSrcRegCC:
      REX |= isREXExtendedReg(MI, CurOp++) << 2; // REX.R
      REX |= isREXExtendedReg(MI, CurOp++) << 0; // REX.B
      break;
    case X86II::MRMSrcMem:
    case X86II::MRMSrcMemCC:
      REX |= isREXExtendedReg(MI, CurOp++) << 2;                        // REX.R
      REX |= isREXExtendedReg(MI, MemOperand + X86::AddrBaseReg) << 0;  // REX.B
      REX |= isREXExtendedReg(MI, MemOperand + X86::AddrIndexReg) << 1; // REX.X
      CurOp += X86::AddrNumOperands;
      break;
    case X86II::MRMDestReg:
      REX |= isREXExtendedReg(MI, CurOp++) << 0; // REX.B
      REX |= isREXExtendedReg(MI, CurOp++) << 2; // REX.R
      break;
    case X86II::MRMDestMem:
      REX |= isREXExtendedReg(MI, MemOperand + X86::AddrBaseReg) << 0;  // REX.B
      REX |= isREXExtendedReg(MI, MemOperand + X86::AddrIndexReg) << 1; // REX.X
      CurOp += X86::AddrNumOperands;
      REX |= isREXExtendedReg(MI, CurOp++) << 2; // REX.R
      break;
    case X86II::MRMXmCC:
    case X86II::MRMXm:
    case X86II::MRM0m:
    case X86II::MRM1m:
    case X86II::MRM2m:
    case X86II::MRM3m:
    case X86II::MRM4m:
    case X86II::MRM5m:
    case X86II::MRM6m:
    case X86II::MRM7m:
      REX |= isREXExtendedReg(MI, MemOperand + X86::AddrBaseReg) << 0;  // REX.B
      REX |= isREXExtendedReg(MI, MemOperand + X86::AddrIndexReg) << 1; // REX.X
      break;
    case X86II::MRMXrCC:
    case X86II::MRMXr:
    case X86II::MRM0r:
    case X86II::MRM1r:
    case X86II::MRM2r:
    case X86II::MRM3r:
    case X86II::MRM4r:
    case X86II::MRM5r:
    case X86II::MRM6r:
    case X86II::MRM7r:
      REX |= isREXExtendedReg(MI, CurOp++) << 0; // REX.B
      break;
    case X86II::MRMr0:
      REX |= isREXExtendedReg(MI, CurOp++) << 2; // REX.R
      break;
    case X86II::MRMDestMemFSIB:
      llvm_unreachable("FSIB format never need REX prefix!");
    }
    if (REX && UsesHighByteReg)
      report_fatal_error(
          "Cannot encode high byte register in REX-prefixed instruction");
    return REX;
  }();

  if (!REX)
    return false;

  emitByte(0x40 | REX, OS);
  return true;
}

/// Emit segment override opcode prefix as needed.
void X86MCCodeEmitter::emitSegmentOverridePrefix(unsigned SegOperand,
                                                 const MCInst &MI,
                                                 raw_ostream &OS) const {
  // Check for explicit segment override on memory operand.
  if (unsigned Reg = MI.getOperand(SegOperand).getReg())
    emitByte(X86::getSegmentOverridePrefixForReg(Reg), OS);
}

/// Emit all instruction prefixes prior to the opcode.
///
/// \param MemOperand the operand # of the start of a memory operand if present.
/// If not present, it is -1.
///
/// \returns true if REX prefix is used, otherwise returns false.
bool X86MCCodeEmitter::emitOpcodePrefix(int MemOperand, const MCInst &MI,
                                        const MCSubtargetInfo &STI,
                                        raw_ostream &OS) const {
  const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
  uint64_t TSFlags = Desc.TSFlags;

  // Emit the operand size opcode prefix as needed.
  if ((TSFlags & X86II::OpSizeMask) ==
      (STI.hasFeature(X86::Mode16Bit) ? X86II::OpSize32 : X86II::OpSize16))
    emitByte(0x66, OS);

  // Emit the LOCK opcode prefix.
  if (TSFlags & X86II::LOCK || MI.getFlags() & X86::IP_HAS_LOCK)
    emitByte(0xF0, OS);

  // Emit the NOTRACK opcode prefix.
  if (TSFlags & X86II::NOTRACK || MI.getFlags() & X86::IP_HAS_NOTRACK)
    emitByte(0x3E, OS);

  switch (TSFlags & X86II::OpPrefixMask) {
  case X86II::PD: // 66
    emitByte(0x66, OS);
    break;
  case X86II::XS: // F3
    emitByte(0xF3, OS);
    break;
  case X86II::XD: // F2
    emitByte(0xF2, OS);
    break;
  }

  // Handle REX prefix.
  assert((STI.hasFeature(X86::Mode64Bit) || !(TSFlags & X86II::REX_W)) &&
         "REX.W requires 64bit mode.");
  bool HasREX = STI.hasFeature(X86::Mode64Bit)
                    ? emitREXPrefix(MemOperand, MI, STI, OS)
                    : false;

  // 0x0F escape code must be emitted just before the opcode.
  switch (TSFlags & X86II::OpMapMask) {
  case X86II::TB:        // Two-byte opcode map
  case X86II::T8:        // 0F 38
  case X86II::TA:        // 0F 3A
  case X86II::ThreeDNow: // 0F 0F, second 0F emitted by caller.
    emitByte(0x0F, OS);
    break;
  }

  switch (TSFlags & X86II::OpMapMask) {
  case X86II::T8: // 0F 38
    emitByte(0x38, OS);
    break;
  case X86II::TA: // 0F 3A
    emitByte(0x3A, OS);
    break;
  }

  return HasREX;
}

void X86MCCodeEmitter::emitPrefix(const MCInst &MI, raw_ostream &OS,
                                  const MCSubtargetInfo &STI) const {
  unsigned Opcode = MI.getOpcode();
  const MCInstrDesc &Desc = MCII.get(Opcode);
  uint64_t TSFlags = Desc.TSFlags;

  // Pseudo instructions don't get encoded.
  if (X86II::isPseudo(TSFlags))
    return;

  unsigned CurOp = X86II::getOperandBias(Desc);

  emitPrefixImpl(CurOp, MI, STI, OS);
}

void X86MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
                                         SmallVectorImpl<MCFixup> &Fixups,
                                         const MCSubtargetInfo &STI) const {
  unsigned Opcode = MI.getOpcode();
  const MCInstrDesc &Desc = MCII.get(Opcode);
  uint64_t TSFlags = Desc.TSFlags;

  // Pseudo instructions don't get encoded.
  if (X86II::isPseudo(TSFlags))
    return;

  unsigned NumOps = Desc.getNumOperands();
  unsigned CurOp = X86II::getOperandBias(Desc);

  uint64_t StartByte = OS.tell();

  bool HasREX = emitPrefixImpl(CurOp, MI, STI, OS);

  // It uses the VEX.VVVV field?
  bool HasVEX_4V = TSFlags & X86II::VEX_4V;
  bool HasVEX_I8Reg = (TSFlags & X86II::ImmMask) == X86II::Imm8Reg;

  // It uses the EVEX.aaa field?
  bool HasEVEX_K = TSFlags & X86II::EVEX_K;
  bool HasEVEX_RC = TSFlags & X86II::EVEX_RC;

  // Used if a register is encoded in 7:4 of immediate.
  unsigned I8RegNum = 0;

  uint8_t BaseOpcode = X86II::getBaseOpcodeFor(TSFlags);

  if ((TSFlags & X86II::OpMapMask) == X86II::ThreeDNow)
    BaseOpcode = 0x0F; // Weird 3DNow! encoding.

  unsigned OpcodeOffset = 0;

  uint64_t Form = TSFlags & X86II::FormMask;
  switch (Form) {
  default:
    errs() << "FORM: " << Form << "\n";
    llvm_unreachable("Unknown FormMask value in X86MCCodeEmitter!");
  case X86II::Pseudo:
    llvm_unreachable("Pseudo instruction shouldn't be emitted");
  case X86II::RawFrmDstSrc:
  case X86II::RawFrmSrc:
  case X86II::RawFrmDst:
  case X86II::PrefixByte:
    emitByte(BaseOpcode, OS);
    break;
  case X86II::AddCCFrm: {
    // This will be added to the opcode in the fallthrough.
    OpcodeOffset = MI.getOperand(NumOps - 1).getImm();
    assert(OpcodeOffset < 16 && "Unexpected opcode offset!");
    --NumOps; // Drop the operand from the end.
    LLVM_FALLTHROUGH;
  case X86II::RawFrm:
    emitByte(BaseOpcode + OpcodeOffset, OS);

    if (!STI.hasFeature(X86::Mode64Bit) || !isPCRel32Branch(MI, MCII))
      break;

    const MCOperand &Op = MI.getOperand(CurOp++);
    emitImmediate(Op, MI.getLoc(), X86II::getSizeOfImm(TSFlags),
                  MCFixupKind(X86::reloc_branch_4byte_pcrel), StartByte, OS,
                  Fixups);
    break;
  }
  case X86II::RawFrmMemOffs:
    emitByte(BaseOpcode, OS);
    emitImmediate(MI.getOperand(CurOp++), MI.getLoc(),
                  X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags),
                  StartByte, OS, Fixups);
    ++CurOp; // skip segment operand
    break;
  case X86II::RawFrmImm8:
    emitByte(BaseOpcode, OS);
    emitImmediate(MI.getOperand(CurOp++), MI.getLoc(),
                  X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags),
                  StartByte, OS, Fixups);
    emitImmediate(MI.getOperand(CurOp++), MI.getLoc(), 1, FK_Data_1, StartByte,
                  OS, Fixups);
    break;
  case X86II::RawFrmImm16:
    emitByte(BaseOpcode, OS);
    emitImmediate(MI.getOperand(CurOp++), MI.getLoc(),
                  X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags),
                  StartByte, OS, Fixups);
    emitImmediate(MI.getOperand(CurOp++), MI.getLoc(), 2, FK_Data_2, StartByte,
                  OS, Fixups);
    break;

  case X86II::AddRegFrm:
    emitByte(BaseOpcode + getX86RegNum(MI.getOperand(CurOp++)), OS);
    break;

  case X86II::MRMDestReg: {
    emitByte(BaseOpcode, OS);
    unsigned SrcRegNum = CurOp + 1;

    if (HasEVEX_K) // Skip writemask
      ++SrcRegNum;

    if (HasVEX_4V) // Skip 1st src (which is encoded in VEX_VVVV)
      ++SrcRegNum;

    emitRegModRMByte(MI.getOperand(CurOp),
                     getX86RegNum(MI.getOperand(SrcRegNum)), OS);
    CurOp = SrcRegNum + 1;
    break;
  }
  case X86II::MRMDestMemFSIB:
  case X86II::MRMDestMem: {
    emitByte(BaseOpcode, OS);
    unsigned SrcRegNum = CurOp + X86::AddrNumOperands;

    if (HasEVEX_K) // Skip writemask
      ++SrcRegNum;

    if (HasVEX_4V) // Skip 1st src (which is encoded in VEX_VVVV)
      ++SrcRegNum;

    bool ForceSIB = (Form == X86II::MRMDestMemFSIB);
    emitMemModRMByte(MI, CurOp, getX86RegNum(MI.getOperand(SrcRegNum)), TSFlags,
                     HasREX, StartByte, OS, Fixups, STI, ForceSIB);
    CurOp = SrcRegNum + 1;
    break;
  }
  case X86II::MRMSrcReg: {
    emitByte(BaseOpcode, OS);
    unsigned SrcRegNum = CurOp + 1;

    if (HasEVEX_K) // Skip writemask
      ++SrcRegNum;

    if (HasVEX_4V) // Skip 1st src (which is encoded in VEX_VVVV)
      ++SrcRegNum;

    emitRegModRMByte(MI.getOperand(SrcRegNum),
                     getX86RegNum(MI.getOperand(CurOp)), OS);
    CurOp = SrcRegNum + 1;
    if (HasVEX_I8Reg)
      I8RegNum = getX86RegEncoding(MI, CurOp++);
    // do not count the rounding control operand
    if (HasEVEX_RC)
      --NumOps;
    break;
  }
  case X86II::MRMSrcReg4VOp3: {
    emitByte(BaseOpcode, OS);
    unsigned SrcRegNum = CurOp + 1;

    emitRegModRMByte(MI.getOperand(SrcRegNum),
                     getX86RegNum(MI.getOperand(CurOp)), OS);
    CurOp = SrcRegNum + 1;
    ++CurOp; // Encoded in VEX.VVVV
    break;
  }
  case X86II::MRMSrcRegOp4: {
    emitByte(BaseOpcode, OS);
    unsigned SrcRegNum = CurOp + 1;

    // Skip 1st src (which is encoded in VEX_VVVV)
    ++SrcRegNum;

    // Capture 2nd src (which is encoded in Imm[7:4])
    assert(HasVEX_I8Reg && "MRMSrcRegOp4 should imply VEX_I8Reg");
    I8RegNum = getX86RegEncoding(MI, SrcRegNum++);

    emitRegModRMByte(MI.getOperand(SrcRegNum),
                     getX86RegNum(MI.getOperand(CurOp)), OS);
    CurOp = SrcRegNum + 1;
    break;
  }
  case X86II::MRMSrcRegCC: {
    unsigned FirstOp = CurOp++;
    unsigned SecondOp = CurOp++;

    unsigned CC = MI.getOperand(CurOp++).getImm();
    emitByte(BaseOpcode + CC, OS);

    emitRegModRMByte(MI.getOperand(SecondOp),
                     getX86RegNum(MI.getOperand(FirstOp)), OS);
    break;
  }
  case X86II::MRMSrcMemFSIB:
  case X86II::MRMSrcMem: {
    unsigned FirstMemOp = CurOp + 1;

    if (HasEVEX_K) // Skip writemask
      ++FirstMemOp;

    if (HasVEX_4V)
      ++FirstMemOp; // Skip the register source (which is encoded in VEX_VVVV).

    emitByte(BaseOpcode, OS);

    bool ForceSIB = (Form == X86II::MRMSrcMemFSIB);
    emitMemModRMByte(MI, FirstMemOp, getX86RegNum(MI.getOperand(CurOp)),
                     TSFlags, HasREX, StartByte, OS, Fixups, STI, ForceSIB);
    CurOp = FirstMemOp + X86::AddrNumOperands;
    if (HasVEX_I8Reg)
      I8RegNum = getX86RegEncoding(MI, CurOp++);
    break;
  }
  case X86II::MRMSrcMem4VOp3: {
    unsigned FirstMemOp = CurOp + 1;

    emitByte(BaseOpcode, OS);

    emitMemModRMByte(MI, FirstMemOp, getX86RegNum(MI.getOperand(CurOp)),
                     TSFlags, HasREX, StartByte, OS, Fixups, STI);
    CurOp = FirstMemOp + X86::AddrNumOperands;
    ++CurOp; // Encoded in VEX.VVVV.
    break;
  }
  case X86II::MRMSrcMemOp4: {
    unsigned FirstMemOp = CurOp + 1;

    ++FirstMemOp; // Skip the register source (which is encoded in VEX_VVVV).

    // Capture second register source (encoded in Imm[7:4])
    assert(HasVEX_I8Reg && "MRMSrcRegOp4 should imply VEX_I8Reg");
    I8RegNum = getX86RegEncoding(MI, FirstMemOp++);

    emitByte(BaseOpcode, OS);

    emitMemModRMByte(MI, FirstMemOp, getX86RegNum(MI.getOperand(CurOp)),
                     TSFlags, HasREX, StartByte, OS, Fixups, STI);
    CurOp = FirstMemOp + X86::AddrNumOperands;
    break;
  }
  case X86II::MRMSrcMemCC: {
    unsigned RegOp = CurOp++;
    unsigned FirstMemOp = CurOp;
    CurOp = FirstMemOp + X86::AddrNumOperands;

    unsigned CC = MI.getOperand(CurOp++).getImm();
    emitByte(BaseOpcode + CC, OS);

    emitMemModRMByte(MI, FirstMemOp, getX86RegNum(MI.getOperand(RegOp)),
                     TSFlags, HasREX, StartByte, OS, Fixups, STI);
    break;
  }

  case X86II::MRMXrCC: {
    unsigned RegOp = CurOp++;

    unsigned CC = MI.getOperand(CurOp++).getImm();
    emitByte(BaseOpcode + CC, OS);
    emitRegModRMByte(MI.getOperand(RegOp), 0, OS);
    break;
  }

  case X86II::MRMXr:
  case X86II::MRM0r:
  case X86II::MRM1r:
  case X86II::MRM2r:
  case X86II::MRM3r:
  case X86II::MRM4r:
  case X86II::MRM5r:
  case X86II::MRM6r:
  case X86II::MRM7r:
    if (HasVEX_4V) // Skip the register dst (which is encoded in VEX_VVVV).
      ++CurOp;
    if (HasEVEX_K) // Skip writemask
      ++CurOp;
    emitByte(BaseOpcode, OS);
    emitRegModRMByte(MI.getOperand(CurOp++),
                     (Form == X86II::MRMXr) ? 0 : Form - X86II::MRM0r, OS);
    break;
  case X86II::MRMr0:
    emitByte(BaseOpcode, OS);
    emitByte(modRMByte(3, getX86RegNum(MI.getOperand(CurOp++)),0), OS);
    break;

  case X86II::MRMXmCC: {
    unsigned FirstMemOp = CurOp;
    CurOp = FirstMemOp + X86::AddrNumOperands;

    unsigned CC = MI.getOperand(CurOp++).getImm();
    emitByte(BaseOpcode + CC, OS);

    emitMemModRMByte(MI, FirstMemOp, 0, TSFlags, HasREX, StartByte, OS, Fixups,
                     STI);
    break;
  }

  case X86II::MRMXm:
  case X86II::MRM0m:
  case X86II::MRM1m:
  case X86II::MRM2m:
  case X86II::MRM3m:
  case X86II::MRM4m:
  case X86II::MRM5m:
  case X86II::MRM6m:
  case X86II::MRM7m:
    if (HasVEX_4V) // Skip the register dst (which is encoded in VEX_VVVV).
      ++CurOp;
    if (HasEVEX_K) // Skip writemask
      ++CurOp;
    emitByte(BaseOpcode, OS);
    emitMemModRMByte(MI, CurOp,
                     (Form == X86II::MRMXm) ? 0 : Form - X86II::MRM0m, TSFlags,
                     HasREX, StartByte, OS, Fixups, STI);
    CurOp += X86::AddrNumOperands;
    break;

  case X86II::MRM0X:
  case X86II::MRM1X:
  case X86II::MRM2X:
  case X86II::MRM3X:
  case X86II::MRM4X:
  case X86II::MRM5X:
  case X86II::MRM6X:
  case X86II::MRM7X:
    emitByte(BaseOpcode, OS);
    emitByte(0xC0 + ((Form - X86II::MRM0X) << 3), OS);
    break;

  case X86II::MRM_C0:
  case X86II::MRM_C1:
  case X86II::MRM_C2:
  case X86II::MRM_C3:
  case X86II::MRM_C4:
  case X86II::MRM_C5:
  case X86II::MRM_C6:
  case X86II::MRM_C7:
  case X86II::MRM_C8:
  case X86II::MRM_C9:
  case X86II::MRM_CA:
  case X86II::MRM_CB:
  case X86II::MRM_CC:
  case X86II::MRM_CD:
  case X86II::MRM_CE:
  case X86II::MRM_CF:
  case X86II::MRM_D0:
  case X86II::MRM_D1:
  case X86II::MRM_D2:
  case X86II::MRM_D3:
  case X86II::MRM_D4:
  case X86II::MRM_D5:
  case X86II::MRM_D6:
  case X86II::MRM_D7:
  case X86II::MRM_D8:
  case X86II::MRM_D9:
  case X86II::MRM_DA:
  case X86II::MRM_DB:
  case X86II::MRM_DC:
  case X86II::MRM_DD:
  case X86II::MRM_DE:
  case X86II::MRM_DF:
  case X86II::MRM_E0:
  case X86II::MRM_E1:
  case X86II::MRM_E2:
  case X86II::MRM_E3:
  case X86II::MRM_E4:
  case X86II::MRM_E5:
  case X86II::MRM_E6:
  case X86II::MRM_E7:
  case X86II::MRM_E8:
  case X86II::MRM_E9:
  case X86II::MRM_EA:
  case X86II::MRM_EB:
  case X86II::MRM_EC:
  case X86II::MRM_ED:
  case X86II::MRM_EE:
  case X86II::MRM_EF:
  case X86II::MRM_F0:
  case X86II::MRM_F1:
  case X86II::MRM_F2:
  case X86II::MRM_F3:
  case X86II::MRM_F4:
  case X86II::MRM_F5:
  case X86II::MRM_F6:
  case X86II::MRM_F7:
  case X86II::MRM_F8:
  case X86II::MRM_F9:
  case X86II::MRM_FA:
  case X86II::MRM_FB:
  case X86II::MRM_FC:
  case X86II::MRM_FD:
  case X86II::MRM_FE:
  case X86II::MRM_FF:
    emitByte(BaseOpcode, OS);
    emitByte(0xC0 + Form - X86II::MRM_C0, OS);
    break;
  }

  if (HasVEX_I8Reg) {
    // The last source register of a 4 operand instruction in AVX is encoded
    // in bits[7:4] of a immediate byte.
    assert(I8RegNum < 16 && "Register encoding out of range");
    I8RegNum <<= 4;
    if (CurOp != NumOps) {
      unsigned Val = MI.getOperand(CurOp++).getImm();
      assert(Val < 16 && "Immediate operand value out of range");
      I8RegNum |= Val;
    }
    emitImmediate(MCOperand::createImm(I8RegNum), MI.getLoc(), 1, FK_Data_1,
                  StartByte, OS, Fixups);
  } else {
    // If there is a remaining operand, it must be a trailing immediate. Emit it
    // according to the right size for the instruction. Some instructions
    // (SSE4a extrq and insertq) have two trailing immediates.
    while (CurOp != NumOps && NumOps - CurOp <= 2) {
      emitImmediate(MI.getOperand(CurOp++), MI.getLoc(),
                    X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags),
                    StartByte, OS, Fixups);
    }
  }

  if ((TSFlags & X86II::OpMapMask) == X86II::ThreeDNow)
    emitByte(X86II::getBaseOpcodeFor(TSFlags), OS);

  assert(OS.tell() - StartByte <= 15 &&
         "The size of instruction must be no longer than 15.");
#ifndef NDEBUG
  // FIXME: Verify.
  if (/*!Desc.isVariadic() &&*/ CurOp != NumOps) {
    errs() << "Cannot encode all operands of: ";
    MI.dump();
    errs() << '\n';
    abort();
  }
#endif
}

MCCodeEmitter *llvm::createX86MCCodeEmitter(const MCInstrInfo &MCII,
                                            const MCRegisterInfo &MRI,
                                            MCContext &Ctx) {
  return new X86MCCodeEmitter(MCII, Ctx);
}
