//===-- 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;

  bool is64BitMode(const MCSubtargetInfo &STI) const {
    return STI.getFeatureBits()[X86::Mode64Bit];
  }

  bool is32BitMode(const MCSubtargetInfo &STI) const {
    return STI.getFeatureBits()[X86::Mode32Bit];
  }

  bool is16BitMode(const MCSubtargetInfo &STI) const {
    return STI.getFeatureBits()[X86::Mode16Bit];
  }

  /// Is16BitMemOperand - Return true if the specified instruction has
  /// a 16-bit memory operand. Op specifies the operand # of the memoperand.
  bool Is16BitMemOperand(const MCInst &MI, unsigned Op,
                         const MCSubtargetInfo &STI) const {
    const MCOperand &BaseReg  = MI.getOperand(Op+X86::AddrBaseReg);
    const MCOperand &IndexReg = MI.getOperand(Op+X86::AddrIndexReg);
    const MCOperand &Disp     = MI.getOperand(Op+X86::AddrDisp);

    if (is16BitMode(STI) && BaseReg.getReg() == 0 &&
        Disp.isImm() && Disp.getImm() < 0x10000)
      return true;
    if ((BaseReg.getReg() != 0 &&
         X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg.getReg())) ||
        (IndexReg.getReg() != 0 &&
         X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg.getReg())))
      return true;
    return false;
  }

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

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

  // Does this register require a bit to be set in REX prefix.
  bool isREXExtendedReg(const MCInst &MI, unsigned OpNum) const {
    return (getX86RegEncoding(MI, OpNum) >> 3) & 1;
  }

  void EmitByte(uint8_t C, unsigned &CurByte, raw_ostream &OS) const {
    OS << (char)C;
    ++CurByte;
  }

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

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

  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);
  }

  void EmitRegModRMByte(const MCOperand &ModRMReg, unsigned RegOpcodeFld,
                        unsigned &CurByte, raw_ostream &OS) const {
    EmitByte(ModRMByte(3, RegOpcodeFld, GetX86RegNum(ModRMReg)), CurByte, OS);
  }

  void EmitSIBByte(unsigned SS, unsigned Index, unsigned Base,
                   unsigned &CurByte, raw_ostream &OS) const {
    // SIB byte is in the same format as the ModRMByte.
    EmitByte(ModRMByte(SS, Index, Base), CurByte, OS);
  }

  void emitMemModRMByte(const MCInst &MI, unsigned Op, unsigned RegOpcodeField,
                        uint64_t TSFlags, bool Rex, unsigned &CurByte,
                        raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups,
                        const MCSubtargetInfo &STI) const;

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

  void EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, int MemOperand,
                           const MCInst &MI, const MCInstrDesc &Desc,
                           raw_ostream &OS) const;

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

  bool emitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, int MemOperand,
                        const MCInst &MI, const MCInstrDesc &Desc,
                        const MCSubtargetInfo &STI, raw_ostream &OS) const;

  uint8_t DetermineREXPrefix(const MCInst &MI, uint64_t TSFlags,
                             int MemOperand, const MCInstrDesc &Desc) const;

  bool isPCRel32Branch(const MCInst &MI) const;
};

} // end anonymous namespace

/// isDisp8 - Return true if this signed displacement fits in a 8-bit
/// sign-extended field.
static bool isDisp8(int Value) {
  return Value == (int8_t)Value;
}

/// isCDisp8 - Return true if this signed displacement fits in a 8-bit
/// compressed dispacement field.
static bool isCDisp8(uint64_t TSFlags, int Value, int& CValue) {
  assert(((TSFlags & X86II::EncodingMask) == X86II::EVEX) &&
         "Compressed 8-bit displacement is only valid for EVEX inst.");

  unsigned CD8_Scale =
    (TSFlags & X86II::CD8_Scale_Mask) >> X86II::CD8_Scale_Shift;
  if (CD8_Scale == 0) {
    CValue = Value;
    return isDisp8(Value);
  }

  unsigned Mask = CD8_Scale - 1;
  assert((CD8_Scale & Mask) == 0 && "Invalid memory object size.");
  if (Value & Mask) // Unaligned offset
    return false;
  Value /= (int)CD8_Scale;
  bool Ret = (Value == (int8_t)Value);

  if (Ret)
    CValue = Value;
  return Ret;
}

/// getImmFixupKind - Return 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);
}

/// Is32BitMemOperand - Return true if the specified instruction has
/// a 32-bit memory operand. Op specifies the operand # of the memoperand.
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;
}

/// Is64BitMemOperand - Return true if the specified instruction has
/// a 64-bit memory operand. Op specifies the operand # of the memoperand.
#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

/// StartsWithGlobalOffsetTable - 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.
enum GlobalOffsetTableExprKind {
  GOT_None,
  GOT_Normal,
  GOT_SymDiff
};
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;
}

bool X86MCCodeEmitter::isPCRel32Branch(const MCInst &MI) const {
  unsigned Opcode = MI.getOpcode();
  const MCInstrDesc &Desc = MCII.get(Opcode);
  if ((Opcode != X86::CALL64pcrel32 && Opcode != X86::JMP_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;
}

void X86MCCodeEmitter::
EmitImmediate(const MCOperand &DispOp, SMLoc Loc, unsigned Size,
              MCFixupKind FixupKind, unsigned &CurByte, 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, CurByte, 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 = CurByte;
    } 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(CurByte, Expr, FixupKind, Loc));
  EmitConstant(0, Size, CurByte, OS);
}

void X86MCCodeEmitter::emitMemModRMByte(const MCInst &MI, unsigned Op,
                                        unsigned RegOpcodeField,
                                        uint64_t TSFlags, bool Rex,
                                        unsigned &CurByte, raw_ostream &OS,
                                        SmallVectorImpl<MCFixup> &Fixups,
                                        const MCSubtargetInfo &STI) 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();
  bool HasEVEX = (TSFlags & X86II::EncodingMask) == X86II::EVEX;

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

    unsigned Opcode = MI.getOpcode();
    // movq loads are handled with a special relocation form which allows the
    // linker to eliminate some loads for GOT references which end up in the
    // same linkage unit.
    unsigned FixupKind = [=]() {
      switch (Opcode) {
      default:
        return X86::reloc_riprel_4byte;
      case X86::MOV64rm:
        assert(Rex);
        return X86::reloc_riprel_4byte_movq_load;
      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 Rex ? 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),
                  CurByte, 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() && isDisp8(Disp.getImm())) {
        if (Disp.getImm() == 0 && RMfield != 6) {
          // There is no displacement; just the register.
          EmitByte(ModRMByte(0, RegOpcodeField, RMfield), CurByte, OS);
          return;
        }
        // Use the [REG]+disp8 form, including for [BP] which cannot be encoded.
        EmitByte(ModRMByte(1, RegOpcodeField, RMfield), CurByte, OS);
        EmitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, CurByte, OS, Fixups);
        return;
      }
      // This is the [REG]+disp16 case.
      EmitByte(ModRMByte(2, RegOpcodeField, RMfield), CurByte, OS);
    } else {
      // There is no BaseReg; this is the plain [disp16] case.
      EmitByte(ModRMByte(0, RegOpcodeField, 6), CurByte, OS);
    }

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

  // Determine whether a SIB byte is needed.
  // If no BaseReg, issue a RIP relative instruction only if the MCE can
  // resolve addresses on-the-fly, otherwise use SIB (Intel Manual 2A, table
  // 2-7) and absolute references.

  if (// The SIB byte must be used if there is an index register.
      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).
      (!is64BitMode(STI) || BaseReg != 0)) {

    if (BaseReg == 0) {          // [disp32]     in X86-32 mode
      EmitByte(ModRMByte(0, RegOpcodeField, 5), CurByte, OS);
      EmitImmediate(Disp, MI.getLoc(), 4, FK_Data_4, CurByte, OS, Fixups);
      return;
    }

    // If the base is not EBP/ESP and there is no displacement, use simple
    // indirect register encoding, this handles addresses like [EAX].  The
    // encoding for [EBP] with no displacement means [disp32] so we handle it
    // by emitting a displacement of 0 below.
    if (BaseRegNo != N86::EBP) {
      if (Disp.isImm() && Disp.getImm() == 0) {
        EmitByte(ModRMByte(0, RegOpcodeField, BaseRegNo), CurByte, 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), CurByte, OS);
          return;
        }
      }
    }

    // Otherwise, if the displacement fits in a byte, encode as [REG+disp8].
    if (Disp.isImm()) {
      if (!HasEVEX && isDisp8(Disp.getImm())) {
        EmitByte(ModRMByte(1, RegOpcodeField, BaseRegNo), CurByte, OS);
        EmitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, CurByte, OS, Fixups);
        return;
      }
      // Try EVEX compressed 8-bit displacement first; if failed, fall back to
      // 32-bit displacement.
      int CDisp8 = 0;
      if (HasEVEX && isCDisp8(TSFlags, Disp.getImm(), CDisp8)) {
        EmitByte(ModRMByte(1, RegOpcodeField, BaseRegNo), CurByte, OS);
        EmitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, CurByte, OS, Fixups,
                      CDisp8 - Disp.getImm());
        return;
      }
    }

    // Otherwise, emit the most general non-SIB encoding: [REG+disp32]
    EmitByte(ModRMByte(2, RegOpcodeField, BaseRegNo), CurByte, 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), CurByte, 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 CDisp8 = 0;
  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.
    EmitByte(ModRMByte(0, RegOpcodeField, 4), CurByte, OS);
    ForceDisp32 = true;
  } else if (!Disp.isImm()) {
    // Emit the normal disp32 encoding.
    EmitByte(ModRMByte(2, RegOpcodeField, 4), CurByte, OS);
    ForceDisp32 = true;
  } else if (Disp.getImm() == 0 &&
             // Base reg can't be anything that ends up with '5' as the base
             // reg, it is the magic [*] nomenclature that indicates no base.
             BaseRegNo != N86::EBP) {
    // Emit no displacement ModR/M byte
    EmitByte(ModRMByte(0, RegOpcodeField, 4), CurByte, OS);
  } else if (!HasEVEX && isDisp8(Disp.getImm())) {
    // Emit the disp8 encoding.
    EmitByte(ModRMByte(1, RegOpcodeField, 4), CurByte, OS);
    ForceDisp8 = true;           // Make sure to force 8 bit disp if Base=EBP
  } else if (HasEVEX && isCDisp8(TSFlags, Disp.getImm(), CDisp8)) {
    // Emit the disp8 encoding.
    EmitByte(ModRMByte(1, RegOpcodeField, 4), CurByte, OS);
    ForceDisp8 = true;           // Make sure to force 8 bit disp if Base=EBP
    ImmOffset = CDisp8 - Disp.getImm();
  } else {
    // Emit the normal disp32 encoding.
    EmitByte(ModRMByte(2, RegOpcodeField, 4), CurByte, OS);
  }

  // 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()];

  if (BaseReg == 0) {
    // Handle the SIB byte for the case where there is no base, see Intel
    // Manual 2A, table 2-7. The displacement has already been output.
    unsigned IndexRegNo;
    if (IndexReg.getReg())
      IndexRegNo = GetX86RegNum(IndexReg);
    else // Examples: [ESP+1*<noreg>+4] or [scaled idx]+disp32 (MOD=0,BASE=5)
      IndexRegNo = 4;
    EmitSIBByte(SS, IndexRegNo, 5, CurByte, OS);
  } else {
    unsigned IndexRegNo;
    if (IndexReg.getReg())
      IndexRegNo = GetX86RegNum(IndexReg);
    else
      IndexRegNo = 4;   // For example [ESP+1*<noreg>+4]
    EmitSIBByte(SS, IndexRegNo, GetX86RegNum(Base), CurByte, OS);
  }

  // Do we need to output a displacement?
  if (ForceDisp8)
    EmitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, CurByte, OS, Fixups, ImmOffset);
  else if (ForceDisp32 || Disp.getImm() != 0)
    EmitImmediate(Disp, MI.getLoc(), 4, MCFixupKind(X86::reloc_signed_4byte),
                  CurByte, OS, Fixups);
}

/// EmitVEXOpcodePrefix - AVX instructions are encoded using a opcode prefix
/// called VEX.
void X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
                                           int MemOperand, const MCInst &MI,
                                           const MCInstrDesc &Desc,
                                           raw_ostream &OS) const {
  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::RawFrm:
    break;
  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::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::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, CurByte, OS);
      EmitByte(LastByte | (VEX_R << 7), CurByte, OS);
      return;
    }

    // 3 byte VEX prefix
    EmitByte(Encoding == X86II::XOP ? 0x8F : 0xC4, CurByte, OS);
    EmitByte(VEX_R << 7 | VEX_X << 6 | VEX_B << 5 | VEX_5M, CurByte, OS);
    EmitByte(LastByte | (VEX_W << 7), CurByte, 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, CurByte, OS);
    EmitByte((VEX_R   << 7) |
             (VEX_X   << 6) |
             (VEX_B   << 5) |
             (EVEX_R2 << 4) |
             VEX_5M, CurByte, OS);
    EmitByte((VEX_W   << 7) |
             (VEX_4V  << 3) |
             (EVEX_U  << 2) |
             VEX_PP, CurByte, OS);
    if (EncodeRC)
      EmitByte((EVEX_z  << 7) |
               (EVEX_rc << 5) |
               (EVEX_b  << 4) |
               (EVEX_V2 << 3) |
               EVEX_aaa, CurByte, OS);
    else
      EmitByte((EVEX_z  << 7) |
               (EVEX_L2 << 6) |
               (VEX_L   << 5) |
               (EVEX_b  << 4) |
               (EVEX_V2 << 3) |
               EVEX_aaa, CurByte, OS);
  }
}

/// DetermineREXPrefix - Determine if the MCInst has to be encoded with a X86-64
/// REX prefix which specifies 1) 64-bit instructions, 2) non-default operand
/// size, and 3) use of X86-64 extended registers.
uint8_t X86MCCodeEmitter::DetermineREXPrefix(const MCInst &MI, uint64_t TSFlags,
                                             int MemOperand,
                                             const MCInstrDesc &Desc) const {
  uint8_t REX = 0;
  bool UsesHighByteReg = false;

  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()) continue;
    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
  }

  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;
  }
  if (REX && UsesHighByteReg)
    report_fatal_error("Cannot encode high byte register in REX-prefixed instruction");

  return REX;
}

/// EmitSegmentOverridePrefix - Emit segment override opcode prefix as needed
void X86MCCodeEmitter::EmitSegmentOverridePrefix(unsigned &CurByte,
                                                 unsigned SegOperand,
                                                 const MCInst &MI,
                                                 raw_ostream &OS) const {
  // Check for explicit segment override on memory operand.
  switch (MI.getOperand(SegOperand).getReg()) {
  default: llvm_unreachable("Unknown segment register!");
  case 0: break;
  case X86::CS: EmitByte(0x2E, CurByte, OS); break;
  case X86::SS: EmitByte(0x36, CurByte, OS); break;
  case X86::DS: EmitByte(0x3E, CurByte, OS); break;
  case X86::ES: EmitByte(0x26, CurByte, OS); break;
  case X86::FS: EmitByte(0x64, CurByte, OS); break;
  case X86::GS: EmitByte(0x65, CurByte, OS); break;
  }
}

/// Emit all instruction prefixes prior to the opcode.
///
/// MemOperand is the operand # of the start of a memory operand if present.  If
/// Not present, it is -1.
///
/// Returns true if a REX prefix was used.
bool X86MCCodeEmitter::emitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
                                        int MemOperand, const MCInst &MI,
                                        const MCInstrDesc &Desc,
                                        const MCSubtargetInfo &STI,
                                        raw_ostream &OS) const {
  bool Ret = false;
  // Emit the operand size opcode prefix as needed.
  if ((TSFlags & X86II::OpSizeMask) == (is16BitMode(STI) ? X86II::OpSize32
                                                         : X86II::OpSize16))
    EmitByte(0x66, CurByte, OS);

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

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

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

  // Handle REX prefix.
  // FIXME: Can this come before F2 etc to simplify emission?
  if (is64BitMode(STI)) {
    if (uint8_t REX = DetermineREXPrefix(MI, TSFlags, MemOperand, Desc)) {
      EmitByte(0x40 | REX, CurByte, OS);
      Ret = true;
    }
  } else {
    assert(!(TSFlags & X86II::REX_W) && "REX.W requires 64bit mode.");
  }

  // 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, CurByte, OS);
    break;
  }

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

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;
  unsigned Flags = MI.getFlags();

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

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

  // Keep track of the current byte being emitted.
  unsigned CurByte = 0;

  // Encoding type for this instruction.
  uint64_t Encoding = TSFlags & X86II::EncodingMask;

  // 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;

  // Determine where the memory operand starts, if present.
  int MemoryOperand = X86II::getMemoryOperandNo(TSFlags);
  if (MemoryOperand != -1) MemoryOperand += CurOp;

  // Emit segment override opcode prefix as needed.
  if (MemoryOperand >= 0)
    EmitSegmentOverridePrefix(CurByte, MemoryOperand+X86::AddrSegmentReg,
                              MI, OS);

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

  // Emit the address size opcode prefix as needed.
  bool need_address_override;
  uint64_t AdSize = TSFlags & X86II::AdSizeMask;
  if ((is16BitMode(STI) && AdSize == X86II::AdSize32) ||
      (is32BitMode(STI) && AdSize == X86II::AdSize16) ||
      (is64BitMode(STI) && AdSize == X86II::AdSize32)) {
    need_address_override = true;
  } else if (MemoryOperand < 0) {
    need_address_override = false;
  } else if (is64BitMode(STI)) {
    assert(!Is16BitMemOperand(MI, MemoryOperand, STI));
    need_address_override = Is32BitMemOperand(MI, MemoryOperand);
  } else if (is32BitMode(STI)) {
    assert(!Is64BitMemOperand(MI, MemoryOperand));
    need_address_override = Is16BitMemOperand(MI, MemoryOperand, STI);
  } else {
    assert(is16BitMode(STI));
    assert(!Is64BitMemOperand(MI, MemoryOperand));
    need_address_override = !Is16BitMemOperand(MI, MemoryOperand, STI);
  }

  if (need_address_override)
    EmitByte(0x67, CurByte, OS);

  bool Rex = false;
  if (Encoding == 0)
    Rex = emitOpcodePrefix(TSFlags, CurByte, MemoryOperand, MI, Desc, STI, OS);
  else
    EmitVEXOpcodePrefix(TSFlags, CurByte, MemoryOperand, MI, Desc, OS);

  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: {
    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(CurByte, 2, MI, OS);
    // Emit AdSize prefix as needed.
    if ((!is32BitMode(STI) && siReg == X86::ESI) ||
        (is32BitMode(STI) && siReg == X86::SI))
      EmitByte(0x67, CurByte, OS);
    CurOp += 3; // Consume operands.
    EmitByte(BaseOpcode, CurByte, OS);
    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(CurByte, 1, MI, OS);
    // Emit AdSize prefix as needed.
    if ((!is32BitMode(STI) && siReg == X86::ESI) ||
        (is32BitMode(STI) && siReg == X86::SI))
      EmitByte(0x67, CurByte, OS);
    CurOp += 2; // Consume operands.
    EmitByte(BaseOpcode, CurByte, OS);
    break;
  }
  case X86II::RawFrmDst: {
    unsigned siReg = MI.getOperand(0).getReg();
    // Emit AdSize prefix as needed.
    if ((!is32BitMode(STI) && siReg == X86::EDI) ||
        (is32BitMode(STI) && siReg == X86::DI))
      EmitByte(0x67, CurByte, OS);
    ++CurOp; // Consume operand.
    EmitByte(BaseOpcode, CurByte, 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, CurByte, OS);

    if (!is64BitMode(STI) || !isPCRel32Branch(MI))
      break;

    const MCOperand &Op = MI.getOperand(CurOp++);
    EmitImmediate(Op, MI.getLoc(), X86II::getSizeOfImm(TSFlags),
                  MCFixupKind(X86::reloc_branch_4byte_pcrel), CurByte, OS,
                  Fixups);
    break;
  }
  case X86II::RawFrmMemOffs:
    // Emit segment override opcode prefix as needed.
    EmitSegmentOverridePrefix(CurByte, 1, MI, OS);
    EmitByte(BaseOpcode, CurByte, OS);
    EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(),
                  X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags),
                  CurByte, OS, Fixups);
    ++CurOp; // skip segment operand
    break;
  case X86II::RawFrmImm8:
    EmitByte(BaseOpcode, CurByte, OS);
    EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(),
                  X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags),
                  CurByte, OS, Fixups);
    EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(), 1, FK_Data_1, CurByte,
                  OS, Fixups);
    break;
  case X86II::RawFrmImm16:
    EmitByte(BaseOpcode, CurByte, OS);
    EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(),
                  X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags),
                  CurByte, OS, Fixups);
    EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(), 2, FK_Data_2, CurByte,
                  OS, Fixups);
    break;

  case X86II::AddRegFrm:
    EmitByte(BaseOpcode + GetX86RegNum(MI.getOperand(CurOp++)), CurByte, OS);
    break;

  case X86II::MRMDestReg: {
    EmitByte(BaseOpcode, CurByte, 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)), CurByte, OS);
    CurOp = SrcRegNum + 1;
    break;
  }
  case X86II::MRMDestMem: {
    EmitByte(BaseOpcode, CurByte, 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;

    emitMemModRMByte(MI, CurOp, GetX86RegNum(MI.getOperand(SrcRegNum)), TSFlags,
                     Rex, CurByte, OS, Fixups, STI);
    CurOp = SrcRegNum + 1;
    break;
  }
  case X86II::MRMSrcReg: {
    EmitByte(BaseOpcode, CurByte, 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)), CurByte, 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, CurByte, OS);
    unsigned SrcRegNum = CurOp + 1;

    EmitRegModRMByte(MI.getOperand(SrcRegNum),
                     GetX86RegNum(MI.getOperand(CurOp)), CurByte, OS);
    CurOp = SrcRegNum + 1;
    ++CurOp; // Encoded in VEX.VVVV
    break;
  }
  case X86II::MRMSrcRegOp4: {
    EmitByte(BaseOpcode, CurByte, 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)), CurByte, OS);
    CurOp = SrcRegNum + 1;
    break;
  }
  case X86II::MRMSrcRegCC: {
    unsigned FirstOp = CurOp++;
    unsigned SecondOp = CurOp++;

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

    EmitRegModRMByte(MI.getOperand(SecondOp),
                     GetX86RegNum(MI.getOperand(FirstOp)), CurByte, OS);
    break;
  }
  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, CurByte, OS);

    emitMemModRMByte(MI, FirstMemOp, GetX86RegNum(MI.getOperand(CurOp)),
                     TSFlags, Rex, CurByte, OS, Fixups, STI);
    CurOp = FirstMemOp + X86::AddrNumOperands;
    if (HasVEX_I8Reg)
      I8RegNum = getX86RegEncoding(MI, CurOp++);
    break;
  }
  case X86II::MRMSrcMem4VOp3: {
    unsigned FirstMemOp = CurOp+1;

    EmitByte(BaseOpcode, CurByte, OS);

    emitMemModRMByte(MI, FirstMemOp, GetX86RegNum(MI.getOperand(CurOp)),
                     TSFlags, Rex, CurByte, 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, CurByte, OS);

    emitMemModRMByte(MI, FirstMemOp, GetX86RegNum(MI.getOperand(CurOp)),
                     TSFlags, Rex, CurByte, 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, CurByte, OS);

    emitMemModRMByte(MI, FirstMemOp, GetX86RegNum(MI.getOperand(RegOp)),
                     TSFlags, Rex, CurByte, OS, Fixups, STI);
    break;
  }

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

    unsigned CC = MI.getOperand(CurOp++).getImm();
    EmitByte(BaseOpcode + CC, CurByte, OS);
    EmitRegModRMByte(MI.getOperand(RegOp), 0, CurByte, 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, CurByte, OS);
    EmitRegModRMByte(MI.getOperand(CurOp++),
                     (Form == X86II::MRMXr) ? 0 : Form-X86II::MRM0r,
                     CurByte, OS);
    break;

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

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

    emitMemModRMByte(MI, FirstMemOp, 0, TSFlags, Rex, CurByte, 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, CurByte, OS);
    emitMemModRMByte(MI, CurOp,
                     (Form == X86II::MRMXm) ? 0 : Form - X86II::MRM0m, TSFlags,
                     Rex, CurByte, OS, Fixups, STI);
    CurOp += X86::AddrNumOperands;
    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, CurByte, OS);
    EmitByte(0xC0 + Form - X86II::MRM_C0, CurByte, 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,
                  CurByte, 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),
                    CurByte, OS, Fixups);
    }
  }

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

#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);
}
