//===-- X86Disassembler.cpp - Disassembler for x86 and x86_64 -------------===//
//
// 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 is part of the X86 Disassembler.
// It contains code to translate the data produced by the decoder into
//  MCInsts.
//
//
// The X86 disassembler is a table-driven disassembler for the 16-, 32-, and
// 64-bit X86 instruction sets.  The main decode sequence for an assembly
// instruction in this disassembler is:
//
// 1. Read the prefix bytes and determine the attributes of the instruction.
//    These attributes, recorded in enum attributeBits
//    (X86DisassemblerDecoderCommon.h), form a bitmask.  The table CONTEXTS_SYM
//    provides a mapping from bitmasks to contexts, which are represented by
//    enum InstructionContext (ibid.).
//
// 2. Read the opcode, and determine what kind of opcode it is.  The
//    disassembler distinguishes four kinds of opcodes, which are enumerated in
//    OpcodeType (X86DisassemblerDecoderCommon.h): one-byte (0xnn), two-byte
//    (0x0f 0xnn), three-byte-38 (0x0f 0x38 0xnn), or three-byte-3a
//    (0x0f 0x3a 0xnn).  Mandatory prefixes are treated as part of the context.
//
// 3. Depending on the opcode type, look in one of four ClassDecision structures
//    (X86DisassemblerDecoderCommon.h).  Use the opcode class to determine which
//    OpcodeDecision (ibid.) to look the opcode in.  Look up the opcode, to get
//    a ModRMDecision (ibid.).
//
// 4. Some instructions, such as escape opcodes or extended opcodes, or even
//    instructions that have ModRM*Reg / ModRM*Mem forms in LLVM, need the
//    ModR/M byte to complete decode.  The ModRMDecision's type is an entry from
//    ModRMDecisionType (X86DisassemblerDecoderCommon.h) that indicates if the
//    ModR/M byte is required and how to interpret it.
//
// 5. After resolving the ModRMDecision, the disassembler has a unique ID
//    of type InstrUID (X86DisassemblerDecoderCommon.h).  Looking this ID up in
//    INSTRUCTIONS_SYM yields the name of the instruction and the encodings and
//    meanings of its operands.
//
// 6. For each operand, its encoding is an entry from OperandEncoding
//    (X86DisassemblerDecoderCommon.h) and its type is an entry from
//    OperandType (ibid.).  The encoding indicates how to read it from the
//    instruction; the type indicates how to interpret the value once it has
//    been read.  For example, a register operand could be stored in the R/M
//    field of the ModR/M byte, the REG field of the ModR/M byte, or added to
//    the main opcode.  This is orthogonal from its meaning (an GPR or an XMM
//    register, for instance).  Given this information, the operands can be
//    extracted and interpreted.
//
// 7. As the last step, the disassembler translates the instruction information
//    and operands into a format understandable by the client - in this case, an
//    MCInst for use by the MC infrastructure.
//
// The disassembler is broken broadly into two parts: the table emitter that
// emits the instruction decode tables discussed above during compilation, and
// the disassembler itself.  The table emitter is documented in more detail in
// utils/TableGen/X86DisassemblerEmitter.h.
//
// X86Disassembler.cpp contains the code responsible for step 7, and for
//   invoking the decoder to execute steps 1-6.
// X86DisassemblerDecoderCommon.h contains the definitions needed by both the
//   table emitter and the disassembler.
// X86DisassemblerDecoder.h contains the public interface of the decoder,
//   factored out into C for possible use by other projects.
// X86DisassemblerDecoder.c contains the source code of the decoder, which is
//   responsible for steps 1-6.
//
//===----------------------------------------------------------------------===//

#include "MCTargetDesc/X86BaseInfo.h"
#include "MCTargetDesc/X86MCTargetDesc.h"
#include "TargetInfo/X86TargetInfo.h"
#include "X86DisassemblerDecoder.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;
using namespace llvm::X86Disassembler;

#define DEBUG_TYPE "x86-disassembler"

#define debug(s) LLVM_DEBUG(dbgs() << __LINE__ << ": " << s);

// Specifies whether a ModR/M byte is needed and (if so) which
// instruction each possible value of the ModR/M byte corresponds to.  Once
// this information is known, we have narrowed down to a single instruction.
struct ModRMDecision {
  uint8_t modrm_type;
  uint16_t instructionIDs;
};

// Specifies which set of ModR/M->instruction tables to look at
// given a particular opcode.
struct OpcodeDecision {
  ModRMDecision modRMDecisions[256];
};

// Specifies which opcode->instruction tables to look at given
// a particular context (set of attributes).  Since there are many possible
// contexts, the decoder first uses CONTEXTS_SYM to determine which context
// applies given a specific set of attributes.  Hence there are only IC_max
// entries in this table, rather than 2^(ATTR_max).
struct ContextDecision {
  OpcodeDecision opcodeDecisions[IC_max];
};

#include "X86GenDisassemblerTables.inc"

static InstrUID decode(OpcodeType type, InstructionContext insnContext,
                       uint8_t opcode, uint8_t modRM) {
  const struct ModRMDecision *dec;

  switch (type) {
  case ONEBYTE:
    dec = &ONEBYTE_SYM.opcodeDecisions[insnContext].modRMDecisions[opcode];
    break;
  case TWOBYTE:
    dec = &TWOBYTE_SYM.opcodeDecisions[insnContext].modRMDecisions[opcode];
    break;
  case THREEBYTE_38:
    dec = &THREEBYTE38_SYM.opcodeDecisions[insnContext].modRMDecisions[opcode];
    break;
  case THREEBYTE_3A:
    dec = &THREEBYTE3A_SYM.opcodeDecisions[insnContext].modRMDecisions[opcode];
    break;
  case XOP8_MAP:
    dec = &XOP8_MAP_SYM.opcodeDecisions[insnContext].modRMDecisions[opcode];
    break;
  case XOP9_MAP:
    dec = &XOP9_MAP_SYM.opcodeDecisions[insnContext].modRMDecisions[opcode];
    break;
  case XOPA_MAP:
    dec = &XOPA_MAP_SYM.opcodeDecisions[insnContext].modRMDecisions[opcode];
    break;
  case THREEDNOW_MAP:
    dec =
        &THREEDNOW_MAP_SYM.opcodeDecisions[insnContext].modRMDecisions[opcode];
    break;
  case MAP5:
    dec = &MAP5_SYM.opcodeDecisions[insnContext].modRMDecisions[opcode];
    break;
  case MAP6:
    dec = &MAP6_SYM.opcodeDecisions[insnContext].modRMDecisions[opcode];
    break;
  }

  switch (dec->modrm_type) {
  default:
    llvm_unreachable("Corrupt table!  Unknown modrm_type");
    return 0;
  case MODRM_ONEENTRY:
    return modRMTable[dec->instructionIDs];
  case MODRM_SPLITRM:
    if (modFromModRM(modRM) == 0x3)
      return modRMTable[dec->instructionIDs + 1];
    return modRMTable[dec->instructionIDs];
  case MODRM_SPLITREG:
    if (modFromModRM(modRM) == 0x3)
      return modRMTable[dec->instructionIDs + ((modRM & 0x38) >> 3) + 8];
    return modRMTable[dec->instructionIDs + ((modRM & 0x38) >> 3)];
  case MODRM_SPLITMISC:
    if (modFromModRM(modRM) == 0x3)
      return modRMTable[dec->instructionIDs + (modRM & 0x3f) + 8];
    return modRMTable[dec->instructionIDs + ((modRM & 0x38) >> 3)];
  case MODRM_FULL:
    return modRMTable[dec->instructionIDs + modRM];
  }
}

static bool peek(struct InternalInstruction *insn, uint8_t &byte) {
  uint64_t offset = insn->readerCursor - insn->startLocation;
  if (offset >= insn->bytes.size())
    return true;
  byte = insn->bytes[offset];
  return false;
}

template <typename T> static bool consume(InternalInstruction *insn, T &ptr) {
  auto r = insn->bytes;
  uint64_t offset = insn->readerCursor - insn->startLocation;
  if (offset + sizeof(T) > r.size())
    return true;
  T ret = 0;
  for (unsigned i = 0; i < sizeof(T); ++i)
    ret |= (uint64_t)r[offset + i] << (i * 8);
  ptr = ret;
  insn->readerCursor += sizeof(T);
  return false;
}

static bool isREX(struct InternalInstruction *insn, uint8_t prefix) {
  return insn->mode == MODE_64BIT && prefix >= 0x40 && prefix <= 0x4f;
}

// Consumes all of an instruction's prefix bytes, and marks the
// instruction as having them.  Also sets the instruction's default operand,
// address, and other relevant data sizes to report operands correctly.
//
// insn must not be empty.
static int readPrefixes(struct InternalInstruction *insn) {
  bool isPrefix = true;
  uint8_t byte = 0;
  uint8_t nextByte;

  LLVM_DEBUG(dbgs() << "readPrefixes()");

  while (isPrefix) {
    // If we fail reading prefixes, just stop here and let the opcode reader
    // deal with it.
    if (consume(insn, byte))
      break;

    // If the byte is a LOCK/REP/REPNE prefix and not a part of the opcode, then
    // break and let it be disassembled as a normal "instruction".
    if (insn->readerCursor - 1 == insn->startLocation && byte == 0xf0) // LOCK
      break;

    if ((byte == 0xf2 || byte == 0xf3) && !peek(insn, nextByte)) {
      // If the byte is 0xf2 or 0xf3, and any of the following conditions are
      // met:
      // - it is followed by a LOCK (0xf0) prefix
      // - it is followed by an xchg instruction
      // then it should be disassembled as a xacquire/xrelease not repne/rep.
      if (((nextByte == 0xf0) ||
           ((nextByte & 0xfe) == 0x86 || (nextByte & 0xf8) == 0x90))) {
        insn->xAcquireRelease = true;
        if (!(byte == 0xf3 && nextByte == 0x90)) // PAUSE instruction support
          break;
      }
      // Also if the byte is 0xf3, and the following condition is met:
      // - it is followed by a "mov mem, reg" (opcode 0x88/0x89) or
      //                       "mov mem, imm" (opcode 0xc6/0xc7) instructions.
      // then it should be disassembled as an xrelease not rep.
      if (byte == 0xf3 && (nextByte == 0x88 || nextByte == 0x89 ||
                           nextByte == 0xc6 || nextByte == 0xc7)) {
        insn->xAcquireRelease = true;
        break;
      }
      if (isREX(insn, nextByte)) {
        uint8_t nnextByte;
        // Go to REX prefix after the current one
        if (consume(insn, nnextByte))
          return -1;
        // We should be able to read next byte after REX prefix
        if (peek(insn, nnextByte))
          return -1;
        --insn->readerCursor;
      }
    }

    switch (byte) {
    case 0xf0: // LOCK
      insn->hasLockPrefix = true;
      break;
    case 0xf2: // REPNE/REPNZ
    case 0xf3: { // REP or REPE/REPZ
      uint8_t nextByte;
      if (peek(insn, nextByte))
        break;
      // TODO:
      //  1. There could be several 0x66
      //  2. if (nextByte == 0x66) and nextNextByte != 0x0f then
      //      it's not mandatory prefix
      //  3. if (nextByte >= 0x40 && nextByte <= 0x4f) it's REX and we need
      //     0x0f exactly after it to be mandatory prefix
      if (isREX(insn, nextByte) || nextByte == 0x0f || nextByte == 0x66)
        // The last of 0xf2 /0xf3 is mandatory prefix
        insn->mandatoryPrefix = byte;
      insn->repeatPrefix = byte;
      break;
    }
    case 0x2e: // CS segment override -OR- Branch not taken
      insn->segmentOverride = SEG_OVERRIDE_CS;
      break;
    case 0x36: // SS segment override -OR- Branch taken
      insn->segmentOverride = SEG_OVERRIDE_SS;
      break;
    case 0x3e: // DS segment override
      insn->segmentOverride = SEG_OVERRIDE_DS;
      break;
    case 0x26: // ES segment override
      insn->segmentOverride = SEG_OVERRIDE_ES;
      break;
    case 0x64: // FS segment override
      insn->segmentOverride = SEG_OVERRIDE_FS;
      break;
    case 0x65: // GS segment override
      insn->segmentOverride = SEG_OVERRIDE_GS;
      break;
    case 0x66: { // Operand-size override {
      uint8_t nextByte;
      insn->hasOpSize = true;
      if (peek(insn, nextByte))
        break;
      // 0x66 can't overwrite existing mandatory prefix and should be ignored
      if (!insn->mandatoryPrefix && (nextByte == 0x0f || isREX(insn, nextByte)))
        insn->mandatoryPrefix = byte;
      break;
    }
    case 0x67: // Address-size override
      insn->hasAdSize = true;
      break;
    default: // Not a prefix byte
      isPrefix = false;
      break;
    }

    if (isPrefix)
      LLVM_DEBUG(dbgs() << format("Found prefix 0x%hhx", byte));
  }

  insn->vectorExtensionType = TYPE_NO_VEX_XOP;

  if (byte == 0x62) {
    uint8_t byte1, byte2;
    if (consume(insn, byte1)) {
      LLVM_DEBUG(dbgs() << "Couldn't read second byte of EVEX prefix");
      return -1;
    }

    if (peek(insn, byte2)) {
      LLVM_DEBUG(dbgs() << "Couldn't read third byte of EVEX prefix");
      return -1;
    }

    if ((insn->mode == MODE_64BIT || (byte1 & 0xc0) == 0xc0) &&
        ((~byte1 & 0x8) == 0x8) && ((byte2 & 0x4) == 0x4)) {
      insn->vectorExtensionType = TYPE_EVEX;
    } else {
      --insn->readerCursor; // unconsume byte1
      --insn->readerCursor; // unconsume byte
    }

    if (insn->vectorExtensionType == TYPE_EVEX) {
      insn->vectorExtensionPrefix[0] = byte;
      insn->vectorExtensionPrefix[1] = byte1;
      if (consume(insn, insn->vectorExtensionPrefix[2])) {
        LLVM_DEBUG(dbgs() << "Couldn't read third byte of EVEX prefix");
        return -1;
      }
      if (consume(insn, insn->vectorExtensionPrefix[3])) {
        LLVM_DEBUG(dbgs() << "Couldn't read fourth byte of EVEX prefix");
        return -1;
      }

      // We simulate the REX prefix for simplicity's sake
      if (insn->mode == MODE_64BIT) {
        insn->rexPrefix = 0x40 |
                          (wFromEVEX3of4(insn->vectorExtensionPrefix[2]) << 3) |
                          (rFromEVEX2of4(insn->vectorExtensionPrefix[1]) << 2) |
                          (xFromEVEX2of4(insn->vectorExtensionPrefix[1]) << 1) |
                          (bFromEVEX2of4(insn->vectorExtensionPrefix[1]) << 0);
      }

      LLVM_DEBUG(
          dbgs() << format(
              "Found EVEX prefix 0x%hhx 0x%hhx 0x%hhx 0x%hhx",
              insn->vectorExtensionPrefix[0], insn->vectorExtensionPrefix[1],
              insn->vectorExtensionPrefix[2], insn->vectorExtensionPrefix[3]));
    }
  } else if (byte == 0xc4) {
    uint8_t byte1;
    if (peek(insn, byte1)) {
      LLVM_DEBUG(dbgs() << "Couldn't read second byte of VEX");
      return -1;
    }

    if (insn->mode == MODE_64BIT || (byte1 & 0xc0) == 0xc0)
      insn->vectorExtensionType = TYPE_VEX_3B;
    else
      --insn->readerCursor;

    if (insn->vectorExtensionType == TYPE_VEX_3B) {
      insn->vectorExtensionPrefix[0] = byte;
      consume(insn, insn->vectorExtensionPrefix[1]);
      consume(insn, insn->vectorExtensionPrefix[2]);

      // We simulate the REX prefix for simplicity's sake

      if (insn->mode == MODE_64BIT)
        insn->rexPrefix = 0x40 |
                          (wFromVEX3of3(insn->vectorExtensionPrefix[2]) << 3) |
                          (rFromVEX2of3(insn->vectorExtensionPrefix[1]) << 2) |
                          (xFromVEX2of3(insn->vectorExtensionPrefix[1]) << 1) |
                          (bFromVEX2of3(insn->vectorExtensionPrefix[1]) << 0);

      LLVM_DEBUG(dbgs() << format("Found VEX prefix 0x%hhx 0x%hhx 0x%hhx",
                                  insn->vectorExtensionPrefix[0],
                                  insn->vectorExtensionPrefix[1],
                                  insn->vectorExtensionPrefix[2]));
    }
  } else if (byte == 0xc5) {
    uint8_t byte1;
    if (peek(insn, byte1)) {
      LLVM_DEBUG(dbgs() << "Couldn't read second byte of VEX");
      return -1;
    }

    if (insn->mode == MODE_64BIT || (byte1 & 0xc0) == 0xc0)
      insn->vectorExtensionType = TYPE_VEX_2B;
    else
      --insn->readerCursor;

    if (insn->vectorExtensionType == TYPE_VEX_2B) {
      insn->vectorExtensionPrefix[0] = byte;
      consume(insn, insn->vectorExtensionPrefix[1]);

      if (insn->mode == MODE_64BIT)
        insn->rexPrefix =
            0x40 | (rFromVEX2of2(insn->vectorExtensionPrefix[1]) << 2);

      switch (ppFromVEX2of2(insn->vectorExtensionPrefix[1])) {
      default:
        break;
      case VEX_PREFIX_66:
        insn->hasOpSize = true;
        break;
      }

      LLVM_DEBUG(dbgs() << format("Found VEX prefix 0x%hhx 0x%hhx",
                                  insn->vectorExtensionPrefix[0],
                                  insn->vectorExtensionPrefix[1]));
    }
  } else if (byte == 0x8f) {
    uint8_t byte1;
    if (peek(insn, byte1)) {
      LLVM_DEBUG(dbgs() << "Couldn't read second byte of XOP");
      return -1;
    }

    if ((byte1 & 0x38) != 0x0) // 0 in these 3 bits is a POP instruction.
      insn->vectorExtensionType = TYPE_XOP;
    else
      --insn->readerCursor;

    if (insn->vectorExtensionType == TYPE_XOP) {
      insn->vectorExtensionPrefix[0] = byte;
      consume(insn, insn->vectorExtensionPrefix[1]);
      consume(insn, insn->vectorExtensionPrefix[2]);

      // We simulate the REX prefix for simplicity's sake

      if (insn->mode == MODE_64BIT)
        insn->rexPrefix = 0x40 |
                          (wFromXOP3of3(insn->vectorExtensionPrefix[2]) << 3) |
                          (rFromXOP2of3(insn->vectorExtensionPrefix[1]) << 2) |
                          (xFromXOP2of3(insn->vectorExtensionPrefix[1]) << 1) |
                          (bFromXOP2of3(insn->vectorExtensionPrefix[1]) << 0);

      switch (ppFromXOP3of3(insn->vectorExtensionPrefix[2])) {
      default:
        break;
      case VEX_PREFIX_66:
        insn->hasOpSize = true;
        break;
      }

      LLVM_DEBUG(dbgs() << format("Found XOP prefix 0x%hhx 0x%hhx 0x%hhx",
                                  insn->vectorExtensionPrefix[0],
                                  insn->vectorExtensionPrefix[1],
                                  insn->vectorExtensionPrefix[2]));
    }
  } else if (isREX(insn, byte)) {
    if (peek(insn, nextByte))
      return -1;
    insn->rexPrefix = byte;
    LLVM_DEBUG(dbgs() << format("Found REX prefix 0x%hhx", byte));
  } else
    --insn->readerCursor;

  if (insn->mode == MODE_16BIT) {
    insn->registerSize = (insn->hasOpSize ? 4 : 2);
    insn->addressSize = (insn->hasAdSize ? 4 : 2);
    insn->displacementSize = (insn->hasAdSize ? 4 : 2);
    insn->immediateSize = (insn->hasOpSize ? 4 : 2);
  } else if (insn->mode == MODE_32BIT) {
    insn->registerSize = (insn->hasOpSize ? 2 : 4);
    insn->addressSize = (insn->hasAdSize ? 2 : 4);
    insn->displacementSize = (insn->hasAdSize ? 2 : 4);
    insn->immediateSize = (insn->hasOpSize ? 2 : 4);
  } else if (insn->mode == MODE_64BIT) {
    if (insn->rexPrefix && wFromREX(insn->rexPrefix)) {
      insn->registerSize = 8;
      insn->addressSize = (insn->hasAdSize ? 4 : 8);
      insn->displacementSize = 4;
      insn->immediateSize = 4;
      insn->hasOpSize = false;
    } else {
      insn->registerSize = (insn->hasOpSize ? 2 : 4);
      insn->addressSize = (insn->hasAdSize ? 4 : 8);
      insn->displacementSize = (insn->hasOpSize ? 2 : 4);
      insn->immediateSize = (insn->hasOpSize ? 2 : 4);
    }
  }

  return 0;
}

// Consumes the SIB byte to determine addressing information.
static int readSIB(struct InternalInstruction *insn) {
  SIBBase sibBaseBase = SIB_BASE_NONE;
  uint8_t index, base;

  LLVM_DEBUG(dbgs() << "readSIB()");
  switch (insn->addressSize) {
  case 2:
  default:
    llvm_unreachable("SIB-based addressing doesn't work in 16-bit mode");
  case 4:
    insn->sibIndexBase = SIB_INDEX_EAX;
    sibBaseBase = SIB_BASE_EAX;
    break;
  case 8:
    insn->sibIndexBase = SIB_INDEX_RAX;
    sibBaseBase = SIB_BASE_RAX;
    break;
  }

  if (consume(insn, insn->sib))
    return -1;

  index = indexFromSIB(insn->sib) | (xFromREX(insn->rexPrefix) << 3);

  if (index == 0x4) {
    insn->sibIndex = SIB_INDEX_NONE;
  } else {
    insn->sibIndex = (SIBIndex)(insn->sibIndexBase + index);
  }

  insn->sibScale = 1 << scaleFromSIB(insn->sib);

  base = baseFromSIB(insn->sib) | (bFromREX(insn->rexPrefix) << 3);

  switch (base) {
  case 0x5:
  case 0xd:
    switch (modFromModRM(insn->modRM)) {
    case 0x0:
      insn->eaDisplacement = EA_DISP_32;
      insn->sibBase = SIB_BASE_NONE;
      break;
    case 0x1:
      insn->eaDisplacement = EA_DISP_8;
      insn->sibBase = (SIBBase)(sibBaseBase + base);
      break;
    case 0x2:
      insn->eaDisplacement = EA_DISP_32;
      insn->sibBase = (SIBBase)(sibBaseBase + base);
      break;
    default:
      llvm_unreachable("Cannot have Mod = 0b11 and a SIB byte");
    }
    break;
  default:
    insn->sibBase = (SIBBase)(sibBaseBase + base);
    break;
  }

  return 0;
}

static int readDisplacement(struct InternalInstruction *insn) {
  int8_t d8;
  int16_t d16;
  int32_t d32;
  LLVM_DEBUG(dbgs() << "readDisplacement()");

  insn->displacementOffset = insn->readerCursor - insn->startLocation;
  switch (insn->eaDisplacement) {
  case EA_DISP_NONE:
    break;
  case EA_DISP_8:
    if (consume(insn, d8))
      return -1;
    insn->displacement = d8;
    break;
  case EA_DISP_16:
    if (consume(insn, d16))
      return -1;
    insn->displacement = d16;
    break;
  case EA_DISP_32:
    if (consume(insn, d32))
      return -1;
    insn->displacement = d32;
    break;
  }

  return 0;
}

// Consumes all addressing information (ModR/M byte, SIB byte, and displacement.
static int readModRM(struct InternalInstruction *insn) {
  uint8_t mod, rm, reg, evexrm;
  LLVM_DEBUG(dbgs() << "readModRM()");

  if (insn->consumedModRM)
    return 0;

  if (consume(insn, insn->modRM))
    return -1;
  insn->consumedModRM = true;

  mod = modFromModRM(insn->modRM);
  rm = rmFromModRM(insn->modRM);
  reg = regFromModRM(insn->modRM);

  // This goes by insn->registerSize to pick the correct register, which messes
  // up if we're using (say) XMM or 8-bit register operands. That gets fixed in
  // fixupReg().
  switch (insn->registerSize) {
  case 2:
    insn->regBase = MODRM_REG_AX;
    insn->eaRegBase = EA_REG_AX;
    break;
  case 4:
    insn->regBase = MODRM_REG_EAX;
    insn->eaRegBase = EA_REG_EAX;
    break;
  case 8:
    insn->regBase = MODRM_REG_RAX;
    insn->eaRegBase = EA_REG_RAX;
    break;
  }

  reg |= rFromREX(insn->rexPrefix) << 3;
  rm |= bFromREX(insn->rexPrefix) << 3;

  evexrm = 0;
  if (insn->vectorExtensionType == TYPE_EVEX && insn->mode == MODE_64BIT) {
    reg |= r2FromEVEX2of4(insn->vectorExtensionPrefix[1]) << 4;
    evexrm = xFromEVEX2of4(insn->vectorExtensionPrefix[1]) << 4;
  }

  insn->reg = (Reg)(insn->regBase + reg);

  switch (insn->addressSize) {
  case 2: {
    EABase eaBaseBase = EA_BASE_BX_SI;

    switch (mod) {
    case 0x0:
      if (rm == 0x6) {
        insn->eaBase = EA_BASE_NONE;
        insn->eaDisplacement = EA_DISP_16;
        if (readDisplacement(insn))
          return -1;
      } else {
        insn->eaBase = (EABase)(eaBaseBase + rm);
        insn->eaDisplacement = EA_DISP_NONE;
      }
      break;
    case 0x1:
      insn->eaBase = (EABase)(eaBaseBase + rm);
      insn->eaDisplacement = EA_DISP_8;
      insn->displacementSize = 1;
      if (readDisplacement(insn))
        return -1;
      break;
    case 0x2:
      insn->eaBase = (EABase)(eaBaseBase + rm);
      insn->eaDisplacement = EA_DISP_16;
      if (readDisplacement(insn))
        return -1;
      break;
    case 0x3:
      insn->eaBase = (EABase)(insn->eaRegBase + rm);
      if (readDisplacement(insn))
        return -1;
      break;
    }
    break;
  }
  case 4:
  case 8: {
    EABase eaBaseBase = (insn->addressSize == 4 ? EA_BASE_EAX : EA_BASE_RAX);

    switch (mod) {
    case 0x0:
      insn->eaDisplacement = EA_DISP_NONE; // readSIB may override this
      // In determining whether RIP-relative mode is used (rm=5),
      // or whether a SIB byte is present (rm=4),
      // the extension bits (REX.b and EVEX.x) are ignored.
      switch (rm & 7) {
      case 0x4: // SIB byte is present
        insn->eaBase = (insn->addressSize == 4 ? EA_BASE_sib : EA_BASE_sib64);
        if (readSIB(insn) || readDisplacement(insn))
          return -1;
        break;
      case 0x5: // RIP-relative
        insn->eaBase = EA_BASE_NONE;
        insn->eaDisplacement = EA_DISP_32;
        if (readDisplacement(insn))
          return -1;
        break;
      default:
        insn->eaBase = (EABase)(eaBaseBase + rm);
        break;
      }
      break;
    case 0x1:
      insn->displacementSize = 1;
      LLVM_FALLTHROUGH;
    case 0x2:
      insn->eaDisplacement = (mod == 0x1 ? EA_DISP_8 : EA_DISP_32);
      switch (rm & 7) {
      case 0x4: // SIB byte is present
        insn->eaBase = EA_BASE_sib;
        if (readSIB(insn) || readDisplacement(insn))
          return -1;
        break;
      default:
        insn->eaBase = (EABase)(eaBaseBase + rm);
        if (readDisplacement(insn))
          return -1;
        break;
      }
      break;
    case 0x3:
      insn->eaDisplacement = EA_DISP_NONE;
      insn->eaBase = (EABase)(insn->eaRegBase + rm + evexrm);
      break;
    }
    break;
  }
  } // switch (insn->addressSize)

  return 0;
}

#define GENERIC_FIXUP_FUNC(name, base, prefix, mask)                           \
  static uint16_t name(struct InternalInstruction *insn, OperandType type,     \
                       uint8_t index, uint8_t *valid) {                        \
    *valid = 1;                                                                \
    switch (type) {                                                            \
    default:                                                                   \
      debug("Unhandled register type");                                        \
      *valid = 0;                                                              \
      return 0;                                                                \
    case TYPE_Rv:                                                              \
      return base + index;                                                     \
    case TYPE_R8:                                                              \
      index &= mask;                                                           \
      if (index > 0xf)                                                         \
        *valid = 0;                                                            \
      if (insn->rexPrefix && index >= 4 && index <= 7) {                       \
        return prefix##_SPL + (index - 4);                                     \
      } else {                                                                 \
        return prefix##_AL + index;                                            \
      }                                                                        \
    case TYPE_R16:                                                             \
      index &= mask;                                                           \
      if (index > 0xf)                                                         \
        *valid = 0;                                                            \
      return prefix##_AX + index;                                              \
    case TYPE_R32:                                                             \
      index &= mask;                                                           \
      if (index > 0xf)                                                         \
        *valid = 0;                                                            \
      return prefix##_EAX + index;                                             \
    case TYPE_R64:                                                             \
      index &= mask;                                                           \
      if (index > 0xf)                                                         \
        *valid = 0;                                                            \
      return prefix##_RAX + index;                                             \
    case TYPE_ZMM:                                                             \
      return prefix##_ZMM0 + index;                                            \
    case TYPE_YMM:                                                             \
      return prefix##_YMM0 + index;                                            \
    case TYPE_XMM:                                                             \
      return prefix##_XMM0 + index;                                            \
    case TYPE_TMM:                                                             \
      if (index > 7)                                                           \
        *valid = 0;                                                            \
      return prefix##_TMM0 + index;                                            \
    case TYPE_VK:                                                              \
      index &= 0xf;                                                            \
      if (index > 7)                                                           \
        *valid = 0;                                                            \
      return prefix##_K0 + index;                                              \
    case TYPE_VK_PAIR:                                                         \
      if (index > 7)                                                           \
        *valid = 0;                                                            \
      return prefix##_K0_K1 + (index / 2);                                     \
    case TYPE_MM64:                                                            \
      return prefix##_MM0 + (index & 0x7);                                     \
    case TYPE_SEGMENTREG:                                                      \
      if ((index & 7) > 5)                                                     \
        *valid = 0;                                                            \
      return prefix##_ES + (index & 7);                                        \
    case TYPE_DEBUGREG:                                                        \
      return prefix##_DR0 + index;                                             \
    case TYPE_CONTROLREG:                                                      \
      return prefix##_CR0 + index;                                             \
    case TYPE_MVSIBX:                                                          \
      return prefix##_XMM0 + index;                                            \
    case TYPE_MVSIBY:                                                          \
      return prefix##_YMM0 + index;                                            \
    case TYPE_MVSIBZ:                                                          \
      return prefix##_ZMM0 + index;                                            \
    }                                                                          \
  }

// Consult an operand type to determine the meaning of the reg or R/M field. If
// the operand is an XMM operand, for example, an operand would be XMM0 instead
// of AX, which readModRM() would otherwise misinterpret it as.
//
// @param insn  - The instruction containing the operand.
// @param type  - The operand type.
// @param index - The existing value of the field as reported by readModRM().
// @param valid - The address of a uint8_t.  The target is set to 1 if the
//                field is valid for the register class; 0 if not.
// @return      - The proper value.
GENERIC_FIXUP_FUNC(fixupRegValue, insn->regBase, MODRM_REG, 0x1f)
GENERIC_FIXUP_FUNC(fixupRMValue, insn->eaRegBase, EA_REG, 0xf)

// Consult an operand specifier to determine which of the fixup*Value functions
// to use in correcting readModRM()'ss interpretation.
//
// @param insn  - See fixup*Value().
// @param op    - The operand specifier.
// @return      - 0 if fixup was successful; -1 if the register returned was
//                invalid for its class.
static int fixupReg(struct InternalInstruction *insn,
                    const struct OperandSpecifier *op) {
  uint8_t valid;
  LLVM_DEBUG(dbgs() << "fixupReg()");

  switch ((OperandEncoding)op->encoding) {
  default:
    debug("Expected a REG or R/M encoding in fixupReg");
    return -1;
  case ENCODING_VVVV:
    insn->vvvv =
        (Reg)fixupRegValue(insn, (OperandType)op->type, insn->vvvv, &valid);
    if (!valid)
      return -1;
    break;
  case ENCODING_REG:
    insn->reg = (Reg)fixupRegValue(insn, (OperandType)op->type,
                                   insn->reg - insn->regBase, &valid);
    if (!valid)
      return -1;
    break;
  case ENCODING_SIB:
  CASE_ENCODING_RM:
    if (insn->eaBase >= insn->eaRegBase) {
      insn->eaBase = (EABase)fixupRMValue(
          insn, (OperandType)op->type, insn->eaBase - insn->eaRegBase, &valid);
      if (!valid)
        return -1;
    }
    break;
  }

  return 0;
}

// Read the opcode (except the ModR/M byte in the case of extended or escape
// opcodes).
static bool readOpcode(struct InternalInstruction *insn) {
  uint8_t current;
  LLVM_DEBUG(dbgs() << "readOpcode()");

  insn->opcodeType = ONEBYTE;
  if (insn->vectorExtensionType == TYPE_EVEX) {
    switch (mmmFromEVEX2of4(insn->vectorExtensionPrefix[1])) {
    default:
      LLVM_DEBUG(
          dbgs() << format("Unhandled mmm field for instruction (0x%hhx)",
                           mmmFromEVEX2of4(insn->vectorExtensionPrefix[1])));
      return true;
    case VEX_LOB_0F:
      insn->opcodeType = TWOBYTE;
      return consume(insn, insn->opcode);
    case VEX_LOB_0F38:
      insn->opcodeType = THREEBYTE_38;
      return consume(insn, insn->opcode);
    case VEX_LOB_0F3A:
      insn->opcodeType = THREEBYTE_3A;
      return consume(insn, insn->opcode);
    case VEX_LOB_MAP5:
      insn->opcodeType = MAP5;
      return consume(insn, insn->opcode);
    case VEX_LOB_MAP6:
      insn->opcodeType = MAP6;
      return consume(insn, insn->opcode);
    }
  } else if (insn->vectorExtensionType == TYPE_VEX_3B) {
    switch (mmmmmFromVEX2of3(insn->vectorExtensionPrefix[1])) {
    default:
      LLVM_DEBUG(
          dbgs() << format("Unhandled m-mmmm field for instruction (0x%hhx)",
                           mmmmmFromVEX2of3(insn->vectorExtensionPrefix[1])));
      return true;
    case VEX_LOB_0F:
      insn->opcodeType = TWOBYTE;
      return consume(insn, insn->opcode);
    case VEX_LOB_0F38:
      insn->opcodeType = THREEBYTE_38;
      return consume(insn, insn->opcode);
    case VEX_LOB_0F3A:
      insn->opcodeType = THREEBYTE_3A;
      return consume(insn, insn->opcode);
    case VEX_LOB_MAP5:
      insn->opcodeType = MAP5;
      return consume(insn, insn->opcode);
    case VEX_LOB_MAP6:
      insn->opcodeType = MAP6;
      return consume(insn, insn->opcode);
    }
  } else if (insn->vectorExtensionType == TYPE_VEX_2B) {
    insn->opcodeType = TWOBYTE;
    return consume(insn, insn->opcode);
  } else if (insn->vectorExtensionType == TYPE_XOP) {
    switch (mmmmmFromXOP2of3(insn->vectorExtensionPrefix[1])) {
    default:
      LLVM_DEBUG(
          dbgs() << format("Unhandled m-mmmm field for instruction (0x%hhx)",
                           mmmmmFromVEX2of3(insn->vectorExtensionPrefix[1])));
      return true;
    case XOP_MAP_SELECT_8:
      insn->opcodeType = XOP8_MAP;
      return consume(insn, insn->opcode);
    case XOP_MAP_SELECT_9:
      insn->opcodeType = XOP9_MAP;
      return consume(insn, insn->opcode);
    case XOP_MAP_SELECT_A:
      insn->opcodeType = XOPA_MAP;
      return consume(insn, insn->opcode);
    }
  }

  if (consume(insn, current))
    return true;

  if (current == 0x0f) {
    LLVM_DEBUG(
        dbgs() << format("Found a two-byte escape prefix (0x%hhx)", current));
    if (consume(insn, current))
      return true;

    if (current == 0x38) {
      LLVM_DEBUG(dbgs() << format("Found a three-byte escape prefix (0x%hhx)",
                                  current));
      if (consume(insn, current))
        return true;

      insn->opcodeType = THREEBYTE_38;
    } else if (current == 0x3a) {
      LLVM_DEBUG(dbgs() << format("Found a three-byte escape prefix (0x%hhx)",
                                  current));
      if (consume(insn, current))
        return true;

      insn->opcodeType = THREEBYTE_3A;
    } else if (current == 0x0f) {
      LLVM_DEBUG(
          dbgs() << format("Found a 3dnow escape prefix (0x%hhx)", current));

      // Consume operands before the opcode to comply with the 3DNow encoding
      if (readModRM(insn))
        return true;

      if (consume(insn, current))
        return true;

      insn->opcodeType = THREEDNOW_MAP;
    } else {
      LLVM_DEBUG(dbgs() << "Didn't find a three-byte escape prefix");
      insn->opcodeType = TWOBYTE;
    }
  } else if (insn->mandatoryPrefix)
    // The opcode with mandatory prefix must start with opcode escape.
    // If not it's legacy repeat prefix
    insn->mandatoryPrefix = 0;

  // At this point we have consumed the full opcode.
  // Anything we consume from here on must be unconsumed.
  insn->opcode = current;

  return false;
}

// Determine whether equiv is the 16-bit equivalent of orig (32-bit or 64-bit).
static bool is16BitEquivalent(const char *orig, const char *equiv) {
  for (int i = 0;; i++) {
    if (orig[i] == '\0' && equiv[i] == '\0')
      return true;
    if (orig[i] == '\0' || equiv[i] == '\0')
      return false;
    if (orig[i] != equiv[i]) {
      if ((orig[i] == 'Q' || orig[i] == 'L') && equiv[i] == 'W')
        continue;
      if ((orig[i] == '6' || orig[i] == '3') && equiv[i] == '1')
        continue;
      if ((orig[i] == '4' || orig[i] == '2') && equiv[i] == '6')
        continue;
      return false;
    }
  }
}

// Determine whether this instruction is a 64-bit instruction.
static bool is64Bit(const char *name) {
  for (int i = 0;; ++i) {
    if (name[i] == '\0')
      return false;
    if (name[i] == '6' && name[i + 1] == '4')
      return true;
  }
}

// Determine the ID of an instruction, consuming the ModR/M byte as appropriate
// for extended and escape opcodes, and using a supplied attribute mask.
static int getInstructionIDWithAttrMask(uint16_t *instructionID,
                                        struct InternalInstruction *insn,
                                        uint16_t attrMask) {
  auto insnCtx = InstructionContext(x86DisassemblerContexts[attrMask]);
  const ContextDecision *decision;
  switch (insn->opcodeType) {
  case ONEBYTE:
    decision = &ONEBYTE_SYM;
    break;
  case TWOBYTE:
    decision = &TWOBYTE_SYM;
    break;
  case THREEBYTE_38:
    decision = &THREEBYTE38_SYM;
    break;
  case THREEBYTE_3A:
    decision = &THREEBYTE3A_SYM;
    break;
  case XOP8_MAP:
    decision = &XOP8_MAP_SYM;
    break;
  case XOP9_MAP:
    decision = &XOP9_MAP_SYM;
    break;
  case XOPA_MAP:
    decision = &XOPA_MAP_SYM;
    break;
  case THREEDNOW_MAP:
    decision = &THREEDNOW_MAP_SYM;
    break;
  case MAP5:
    decision = &MAP5_SYM;
    break;
  case MAP6:
    decision = &MAP6_SYM;
    break;
  }

  if (decision->opcodeDecisions[insnCtx]
          .modRMDecisions[insn->opcode]
          .modrm_type != MODRM_ONEENTRY) {
    if (readModRM(insn))
      return -1;
    *instructionID =
        decode(insn->opcodeType, insnCtx, insn->opcode, insn->modRM);
  } else {
    *instructionID = decode(insn->opcodeType, insnCtx, insn->opcode, 0);
  }

  return 0;
}

// Determine the ID of an instruction, consuming the ModR/M byte as appropriate
// for extended and escape opcodes. Determines the attributes and context for
// the instruction before doing so.
static int getInstructionID(struct InternalInstruction *insn,
                            const MCInstrInfo *mii) {
  uint16_t attrMask;
  uint16_t instructionID;

  LLVM_DEBUG(dbgs() << "getID()");

  attrMask = ATTR_NONE;

  if (insn->mode == MODE_64BIT)
    attrMask |= ATTR_64BIT;

  if (insn->vectorExtensionType != TYPE_NO_VEX_XOP) {
    attrMask |= (insn->vectorExtensionType == TYPE_EVEX) ? ATTR_EVEX : ATTR_VEX;

    if (insn->vectorExtensionType == TYPE_EVEX) {
      switch (ppFromEVEX3of4(insn->vectorExtensionPrefix[2])) {
      case VEX_PREFIX_66:
        attrMask |= ATTR_OPSIZE;
        break;
      case VEX_PREFIX_F3:
        attrMask |= ATTR_XS;
        break;
      case VEX_PREFIX_F2:
        attrMask |= ATTR_XD;
        break;
      }

      if (zFromEVEX4of4(insn->vectorExtensionPrefix[3]))
        attrMask |= ATTR_EVEXKZ;
      if (bFromEVEX4of4(insn->vectorExtensionPrefix[3]))
        attrMask |= ATTR_EVEXB;
      if (aaaFromEVEX4of4(insn->vectorExtensionPrefix[3]))
        attrMask |= ATTR_EVEXK;
      if (lFromEVEX4of4(insn->vectorExtensionPrefix[3]))
        attrMask |= ATTR_VEXL;
      if (l2FromEVEX4of4(insn->vectorExtensionPrefix[3]))
        attrMask |= ATTR_EVEXL2;
    } else if (insn->vectorExtensionType == TYPE_VEX_3B) {
      switch (ppFromVEX3of3(insn->vectorExtensionPrefix[2])) {
      case VEX_PREFIX_66:
        attrMask |= ATTR_OPSIZE;
        break;
      case VEX_PREFIX_F3:
        attrMask |= ATTR_XS;
        break;
      case VEX_PREFIX_F2:
        attrMask |= ATTR_XD;
        break;
      }

      if (lFromVEX3of3(insn->vectorExtensionPrefix[2]))
        attrMask |= ATTR_VEXL;
    } else if (insn->vectorExtensionType == TYPE_VEX_2B) {
      switch (ppFromVEX2of2(insn->vectorExtensionPrefix[1])) {
      case VEX_PREFIX_66:
        attrMask |= ATTR_OPSIZE;
        if (insn->hasAdSize)
          attrMask |= ATTR_ADSIZE;
        break;
      case VEX_PREFIX_F3:
        attrMask |= ATTR_XS;
        break;
      case VEX_PREFIX_F2:
        attrMask |= ATTR_XD;
        break;
      }

      if (lFromVEX2of2(insn->vectorExtensionPrefix[1]))
        attrMask |= ATTR_VEXL;
    } else if (insn->vectorExtensionType == TYPE_XOP) {
      switch (ppFromXOP3of3(insn->vectorExtensionPrefix[2])) {
      case VEX_PREFIX_66:
        attrMask |= ATTR_OPSIZE;
        break;
      case VEX_PREFIX_F3:
        attrMask |= ATTR_XS;
        break;
      case VEX_PREFIX_F2:
        attrMask |= ATTR_XD;
        break;
      }

      if (lFromXOP3of3(insn->vectorExtensionPrefix[2]))
        attrMask |= ATTR_VEXL;
    } else {
      return -1;
    }
  } else if (!insn->mandatoryPrefix) {
    // If we don't have mandatory prefix we should use legacy prefixes here
    if (insn->hasOpSize && (insn->mode != MODE_16BIT))
      attrMask |= ATTR_OPSIZE;
    if (insn->hasAdSize)
      attrMask |= ATTR_ADSIZE;
    if (insn->opcodeType == ONEBYTE) {
      if (insn->repeatPrefix == 0xf3 && (insn->opcode == 0x90))
        // Special support for PAUSE
        attrMask |= ATTR_XS;
    } else {
      if (insn->repeatPrefix == 0xf2)
        attrMask |= ATTR_XD;
      else if (insn->repeatPrefix == 0xf3)
        attrMask |= ATTR_XS;
    }
  } else {
    switch (insn->mandatoryPrefix) {
    case 0xf2:
      attrMask |= ATTR_XD;
      break;
    case 0xf3:
      attrMask |= ATTR_XS;
      break;
    case 0x66:
      if (insn->mode != MODE_16BIT)
        attrMask |= ATTR_OPSIZE;
      if (insn->hasAdSize)
        attrMask |= ATTR_ADSIZE;
      break;
    case 0x67:
      attrMask |= ATTR_ADSIZE;
      break;
    }
  }

  if (insn->rexPrefix & 0x08) {
    attrMask |= ATTR_REXW;
    attrMask &= ~ATTR_ADSIZE;
  }

  if (insn->mode == MODE_16BIT) {
    // JCXZ/JECXZ need special handling for 16-bit mode because the meaning
    // of the AdSize prefix is inverted w.r.t. 32-bit mode.
    if (insn->opcodeType == ONEBYTE && insn->opcode == 0xE3)
      attrMask ^= ATTR_ADSIZE;
    // If we're in 16-bit mode and this is one of the relative jumps and opsize
    // prefix isn't present, we need to force the opsize attribute since the
    // prefix is inverted relative to 32-bit mode.
    if (!insn->hasOpSize && insn->opcodeType == ONEBYTE &&
        (insn->opcode == 0xE8 || insn->opcode == 0xE9))
      attrMask |= ATTR_OPSIZE;

    if (!insn->hasOpSize && insn->opcodeType == TWOBYTE &&
        insn->opcode >= 0x80 && insn->opcode <= 0x8F)
      attrMask |= ATTR_OPSIZE;
  }


  if (getInstructionIDWithAttrMask(&instructionID, insn, attrMask))
    return -1;

  // The following clauses compensate for limitations of the tables.

  if (insn->mode != MODE_64BIT &&
      insn->vectorExtensionType != TYPE_NO_VEX_XOP) {
    // The tables can't distinquish between cases where the W-bit is used to
    // select register size and cases where its a required part of the opcode.
    if ((insn->vectorExtensionType == TYPE_EVEX &&
         wFromEVEX3of4(insn->vectorExtensionPrefix[2])) ||
        (insn->vectorExtensionType == TYPE_VEX_3B &&
         wFromVEX3of3(insn->vectorExtensionPrefix[2])) ||
        (insn->vectorExtensionType == TYPE_XOP &&
         wFromXOP3of3(insn->vectorExtensionPrefix[2]))) {

      uint16_t instructionIDWithREXW;
      if (getInstructionIDWithAttrMask(&instructionIDWithREXW, insn,
                                       attrMask | ATTR_REXW)) {
        insn->instructionID = instructionID;
        insn->spec = &INSTRUCTIONS_SYM[instructionID];
        return 0;
      }

      auto SpecName = mii->getName(instructionIDWithREXW);
      // If not a 64-bit instruction. Switch the opcode.
      if (!is64Bit(SpecName.data())) {
        insn->instructionID = instructionIDWithREXW;
        insn->spec = &INSTRUCTIONS_SYM[instructionIDWithREXW];
        return 0;
      }
    }
  }

  // Absolute moves, umonitor, and movdir64b need special handling.
  // -For 16-bit mode because the meaning of the AdSize and OpSize prefixes are
  //  inverted w.r.t.
  // -For 32-bit mode we need to ensure the ADSIZE prefix is observed in
  //  any position.
  if ((insn->opcodeType == ONEBYTE && ((insn->opcode & 0xFC) == 0xA0)) ||
      (insn->opcodeType == TWOBYTE && (insn->opcode == 0xAE)) ||
      (insn->opcodeType == THREEBYTE_38 && insn->opcode == 0xF8)) {
    // Make sure we observed the prefixes in any position.
    if (insn->hasAdSize)
      attrMask |= ATTR_ADSIZE;
    if (insn->hasOpSize)
      attrMask |= ATTR_OPSIZE;

    // In 16-bit, invert the attributes.
    if (insn->mode == MODE_16BIT) {
      attrMask ^= ATTR_ADSIZE;

      // The OpSize attribute is only valid with the absolute moves.
      if (insn->opcodeType == ONEBYTE && ((insn->opcode & 0xFC) == 0xA0))
        attrMask ^= ATTR_OPSIZE;
    }

    if (getInstructionIDWithAttrMask(&instructionID, insn, attrMask))
      return -1;

    insn->instructionID = instructionID;
    insn->spec = &INSTRUCTIONS_SYM[instructionID];
    return 0;
  }

  if ((insn->mode == MODE_16BIT || insn->hasOpSize) &&
      !(attrMask & ATTR_OPSIZE)) {
    // The instruction tables make no distinction between instructions that
    // allow OpSize anywhere (i.e., 16-bit operations) and that need it in a
    // particular spot (i.e., many MMX operations). In general we're
    // conservative, but in the specific case where OpSize is present but not in
    // the right place we check if there's a 16-bit operation.
    const struct InstructionSpecifier *spec;
    uint16_t instructionIDWithOpsize;
    llvm::StringRef specName, specWithOpSizeName;

    spec = &INSTRUCTIONS_SYM[instructionID];

    if (getInstructionIDWithAttrMask(&instructionIDWithOpsize, insn,
                                     attrMask | ATTR_OPSIZE)) {
      // ModRM required with OpSize but not present. Give up and return the
      // version without OpSize set.
      insn->instructionID = instructionID;
      insn->spec = spec;
      return 0;
    }

    specName = mii->getName(instructionID);
    specWithOpSizeName = mii->getName(instructionIDWithOpsize);

    if (is16BitEquivalent(specName.data(), specWithOpSizeName.data()) &&
        (insn->mode == MODE_16BIT) ^ insn->hasOpSize) {
      insn->instructionID = instructionIDWithOpsize;
      insn->spec = &INSTRUCTIONS_SYM[instructionIDWithOpsize];
    } else {
      insn->instructionID = instructionID;
      insn->spec = spec;
    }
    return 0;
  }

  if (insn->opcodeType == ONEBYTE && insn->opcode == 0x90 &&
      insn->rexPrefix & 0x01) {
    // NOOP shouldn't decode as NOOP if REX.b is set. Instead it should decode
    // as XCHG %r8, %eax.
    const struct InstructionSpecifier *spec;
    uint16_t instructionIDWithNewOpcode;
    const struct InstructionSpecifier *specWithNewOpcode;

    spec = &INSTRUCTIONS_SYM[instructionID];

    // Borrow opcode from one of the other XCHGar opcodes
    insn->opcode = 0x91;

    if (getInstructionIDWithAttrMask(&instructionIDWithNewOpcode, insn,
                                     attrMask)) {
      insn->opcode = 0x90;

      insn->instructionID = instructionID;
      insn->spec = spec;
      return 0;
    }

    specWithNewOpcode = &INSTRUCTIONS_SYM[instructionIDWithNewOpcode];

    // Change back
    insn->opcode = 0x90;

    insn->instructionID = instructionIDWithNewOpcode;
    insn->spec = specWithNewOpcode;

    return 0;
  }

  insn->instructionID = instructionID;
  insn->spec = &INSTRUCTIONS_SYM[insn->instructionID];

  return 0;
}

// Read an operand from the opcode field of an instruction and interprets it
// appropriately given the operand width. Handles AddRegFrm instructions.
//
// @param insn  - the instruction whose opcode field is to be read.
// @param size  - The width (in bytes) of the register being specified.
//                1 means AL and friends, 2 means AX, 4 means EAX, and 8 means
//                RAX.
// @return      - 0 on success; nonzero otherwise.
static int readOpcodeRegister(struct InternalInstruction *insn, uint8_t size) {
  LLVM_DEBUG(dbgs() << "readOpcodeRegister()");

  if (size == 0)
    size = insn->registerSize;

  switch (size) {
  case 1:
    insn->opcodeRegister = (Reg)(
        MODRM_REG_AL + ((bFromREX(insn->rexPrefix) << 3) | (insn->opcode & 7)));
    if (insn->rexPrefix && insn->opcodeRegister >= MODRM_REG_AL + 0x4 &&
        insn->opcodeRegister < MODRM_REG_AL + 0x8) {
      insn->opcodeRegister =
          (Reg)(MODRM_REG_SPL + (insn->opcodeRegister - MODRM_REG_AL - 4));
    }

    break;
  case 2:
    insn->opcodeRegister = (Reg)(
        MODRM_REG_AX + ((bFromREX(insn->rexPrefix) << 3) | (insn->opcode & 7)));
    break;
  case 4:
    insn->opcodeRegister =
        (Reg)(MODRM_REG_EAX +
              ((bFromREX(insn->rexPrefix) << 3) | (insn->opcode & 7)));
    break;
  case 8:
    insn->opcodeRegister =
        (Reg)(MODRM_REG_RAX +
              ((bFromREX(insn->rexPrefix) << 3) | (insn->opcode & 7)));
    break;
  }

  return 0;
}

// Consume an immediate operand from an instruction, given the desired operand
// size.
//
// @param insn  - The instruction whose operand is to be read.
// @param size  - The width (in bytes) of the operand.
// @return      - 0 if the immediate was successfully consumed; nonzero
//                otherwise.
static int readImmediate(struct InternalInstruction *insn, uint8_t size) {
  uint8_t imm8;
  uint16_t imm16;
  uint32_t imm32;
  uint64_t imm64;

  LLVM_DEBUG(dbgs() << "readImmediate()");

  assert(insn->numImmediatesConsumed < 2 && "Already consumed two immediates");

  insn->immediateSize = size;
  insn->immediateOffset = insn->readerCursor - insn->startLocation;

  switch (size) {
  case 1:
    if (consume(insn, imm8))
      return -1;
    insn->immediates[insn->numImmediatesConsumed] = imm8;
    break;
  case 2:
    if (consume(insn, imm16))
      return -1;
    insn->immediates[insn->numImmediatesConsumed] = imm16;
    break;
  case 4:
    if (consume(insn, imm32))
      return -1;
    insn->immediates[insn->numImmediatesConsumed] = imm32;
    break;
  case 8:
    if (consume(insn, imm64))
      return -1;
    insn->immediates[insn->numImmediatesConsumed] = imm64;
    break;
  default:
    llvm_unreachable("invalid size");
  }

  insn->numImmediatesConsumed++;

  return 0;
}

// Consume vvvv from an instruction if it has a VEX prefix.
static int readVVVV(struct InternalInstruction *insn) {
  LLVM_DEBUG(dbgs() << "readVVVV()");

  int vvvv;
  if (insn->vectorExtensionType == TYPE_EVEX)
    vvvv = (v2FromEVEX4of4(insn->vectorExtensionPrefix[3]) << 4 |
            vvvvFromEVEX3of4(insn->vectorExtensionPrefix[2]));
  else if (insn->vectorExtensionType == TYPE_VEX_3B)
    vvvv = vvvvFromVEX3of3(insn->vectorExtensionPrefix[2]);
  else if (insn->vectorExtensionType == TYPE_VEX_2B)
    vvvv = vvvvFromVEX2of2(insn->vectorExtensionPrefix[1]);
  else if (insn->vectorExtensionType == TYPE_XOP)
    vvvv = vvvvFromXOP3of3(insn->vectorExtensionPrefix[2]);
  else
    return -1;

  if (insn->mode != MODE_64BIT)
    vvvv &= 0xf; // Can only clear bit 4. Bit 3 must be cleared later.

  insn->vvvv = static_cast<Reg>(vvvv);
  return 0;
}

// Read an mask register from the opcode field of an instruction.
//
// @param insn    - The instruction whose opcode field is to be read.
// @return        - 0 on success; nonzero otherwise.
static int readMaskRegister(struct InternalInstruction *insn) {
  LLVM_DEBUG(dbgs() << "readMaskRegister()");

  if (insn->vectorExtensionType != TYPE_EVEX)
    return -1;

  insn->writemask =
      static_cast<Reg>(aaaFromEVEX4of4(insn->vectorExtensionPrefix[3]));
  return 0;
}

// Consults the specifier for an instruction and consumes all
// operands for that instruction, interpreting them as it goes.
static int readOperands(struct InternalInstruction *insn) {
  int hasVVVV, needVVVV;
  int sawRegImm = 0;

  LLVM_DEBUG(dbgs() << "readOperands()");

  // If non-zero vvvv specified, make sure one of the operands uses it.
  hasVVVV = !readVVVV(insn);
  needVVVV = hasVVVV && (insn->vvvv != 0);

  for (const auto &Op : x86OperandSets[insn->spec->operands]) {
    switch (Op.encoding) {
    case ENCODING_NONE:
    case ENCODING_SI:
    case ENCODING_DI:
      break;
    CASE_ENCODING_VSIB:
      // VSIB can use the V2 bit so check only the other bits.
      if (needVVVV)
        needVVVV = hasVVVV & ((insn->vvvv & 0xf) != 0);
      if (readModRM(insn))
        return -1;

      // Reject if SIB wasn't used.
      if (insn->eaBase != EA_BASE_sib && insn->eaBase != EA_BASE_sib64)
        return -1;

      // If sibIndex was set to SIB_INDEX_NONE, index offset is 4.
      if (insn->sibIndex == SIB_INDEX_NONE)
        insn->sibIndex = (SIBIndex)(insn->sibIndexBase + 4);

      // If EVEX.v2 is set this is one of the 16-31 registers.
      if (insn->vectorExtensionType == TYPE_EVEX && insn->mode == MODE_64BIT &&
          v2FromEVEX4of4(insn->vectorExtensionPrefix[3]))
        insn->sibIndex = (SIBIndex)(insn->sibIndex + 16);

      // Adjust the index register to the correct size.
      switch ((OperandType)Op.type) {
      default:
        debug("Unhandled VSIB index type");
        return -1;
      case TYPE_MVSIBX:
        insn->sibIndex =
            (SIBIndex)(SIB_INDEX_XMM0 + (insn->sibIndex - insn->sibIndexBase));
        break;
      case TYPE_MVSIBY:
        insn->sibIndex =
            (SIBIndex)(SIB_INDEX_YMM0 + (insn->sibIndex - insn->sibIndexBase));
        break;
      case TYPE_MVSIBZ:
        insn->sibIndex =
            (SIBIndex)(SIB_INDEX_ZMM0 + (insn->sibIndex - insn->sibIndexBase));
        break;
      }

      // Apply the AVX512 compressed displacement scaling factor.
      if (Op.encoding != ENCODING_REG && insn->eaDisplacement == EA_DISP_8)
        insn->displacement *= 1 << (Op.encoding - ENCODING_VSIB);
      break;
    case ENCODING_SIB:
      // Reject if SIB wasn't used.
      if (insn->eaBase != EA_BASE_sib && insn->eaBase != EA_BASE_sib64)
        return -1;
      if (readModRM(insn))
        return -1;
      if (fixupReg(insn, &Op))
        return -1;
      break;
    case ENCODING_REG:
    CASE_ENCODING_RM:
      if (readModRM(insn))
        return -1;
      if (fixupReg(insn, &Op))
        return -1;
      // Apply the AVX512 compressed displacement scaling factor.
      if (Op.encoding != ENCODING_REG && insn->eaDisplacement == EA_DISP_8)
        insn->displacement *= 1 << (Op.encoding - ENCODING_RM);
      break;
    case ENCODING_IB:
      if (sawRegImm) {
        // Saw a register immediate so don't read again and instead split the
        // previous immediate. FIXME: This is a hack.
        insn->immediates[insn->numImmediatesConsumed] =
            insn->immediates[insn->numImmediatesConsumed - 1] & 0xf;
        ++insn->numImmediatesConsumed;
        break;
      }
      if (readImmediate(insn, 1))
        return -1;
      if (Op.type == TYPE_XMM || Op.type == TYPE_YMM)
        sawRegImm = 1;
      break;
    case ENCODING_IW:
      if (readImmediate(insn, 2))
        return -1;
      break;
    case ENCODING_ID:
      if (readImmediate(insn, 4))
        return -1;
      break;
    case ENCODING_IO:
      if (readImmediate(insn, 8))
        return -1;
      break;
    case ENCODING_Iv:
      if (readImmediate(insn, insn->immediateSize))
        return -1;
      break;
    case ENCODING_Ia:
      if (readImmediate(insn, insn->addressSize))
        return -1;
      break;
    case ENCODING_IRC:
      insn->RC = (l2FromEVEX4of4(insn->vectorExtensionPrefix[3]) << 1) |
                 lFromEVEX4of4(insn->vectorExtensionPrefix[3]);
      break;
    case ENCODING_RB:
      if (readOpcodeRegister(insn, 1))
        return -1;
      break;
    case ENCODING_RW:
      if (readOpcodeRegister(insn, 2))
        return -1;
      break;
    case ENCODING_RD:
      if (readOpcodeRegister(insn, 4))
        return -1;
      break;
    case ENCODING_RO:
      if (readOpcodeRegister(insn, 8))
        return -1;
      break;
    case ENCODING_Rv:
      if (readOpcodeRegister(insn, 0))
        return -1;
      break;
    case ENCODING_CC:
      insn->immediates[1] = insn->opcode & 0xf;
      break;
    case ENCODING_FP:
      break;
    case ENCODING_VVVV:
      needVVVV = 0; // Mark that we have found a VVVV operand.
      if (!hasVVVV)
        return -1;
      if (insn->mode != MODE_64BIT)
        insn->vvvv = static_cast<Reg>(insn->vvvv & 0x7);
      if (fixupReg(insn, &Op))
        return -1;
      break;
    case ENCODING_WRITEMASK:
      if (readMaskRegister(insn))
        return -1;
      break;
    case ENCODING_DUP:
      break;
    default:
      LLVM_DEBUG(dbgs() << "Encountered an operand with an unknown encoding.");
      return -1;
    }
  }

  // If we didn't find ENCODING_VVVV operand, but non-zero vvvv present, fail
  if (needVVVV)
    return -1;

  return 0;
}

namespace llvm {

// Fill-ins to make the compiler happy. These constants are never actually
// assigned; they are just filler to make an automatically-generated switch
// statement work.
namespace X86 {
  enum {
    BX_SI = 500,
    BX_DI = 501,
    BP_SI = 502,
    BP_DI = 503,
    sib   = 504,
    sib64 = 505
  };
} // namespace X86

} // namespace llvm

static bool translateInstruction(MCInst &target,
                                InternalInstruction &source,
                                const MCDisassembler *Dis);

namespace {

/// Generic disassembler for all X86 platforms. All each platform class should
/// have to do is subclass the constructor, and provide a different
/// disassemblerMode value.
class X86GenericDisassembler : public MCDisassembler {
  std::unique_ptr<const MCInstrInfo> MII;
public:
  X86GenericDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
                         std::unique_ptr<const MCInstrInfo> MII);
public:
  DecodeStatus getInstruction(MCInst &instr, uint64_t &size,
                              ArrayRef<uint8_t> Bytes, uint64_t Address,
                              raw_ostream &cStream) const override;

private:
  DisassemblerMode              fMode;
};

} // namespace

X86GenericDisassembler::X86GenericDisassembler(
                                         const MCSubtargetInfo &STI,
                                         MCContext &Ctx,
                                         std::unique_ptr<const MCInstrInfo> MII)
  : MCDisassembler(STI, Ctx), MII(std::move(MII)) {
  const FeatureBitset &FB = STI.getFeatureBits();
  if (FB[X86::Mode16Bit]) {
    fMode = MODE_16BIT;
    return;
  } else if (FB[X86::Mode32Bit]) {
    fMode = MODE_32BIT;
    return;
  } else if (FB[X86::Mode64Bit]) {
    fMode = MODE_64BIT;
    return;
  }

  llvm_unreachable("Invalid CPU mode");
}

MCDisassembler::DecodeStatus X86GenericDisassembler::getInstruction(
    MCInst &Instr, uint64_t &Size, ArrayRef<uint8_t> Bytes, uint64_t Address,
    raw_ostream &CStream) const {
  CommentStream = &CStream;

  InternalInstruction Insn;
  memset(&Insn, 0, sizeof(InternalInstruction));
  Insn.bytes = Bytes;
  Insn.startLocation = Address;
  Insn.readerCursor = Address;
  Insn.mode = fMode;

  if (Bytes.empty() || readPrefixes(&Insn) || readOpcode(&Insn) ||
      getInstructionID(&Insn, MII.get()) || Insn.instructionID == 0 ||
      readOperands(&Insn)) {
    Size = Insn.readerCursor - Address;
    return Fail;
  }

  Insn.operands = x86OperandSets[Insn.spec->operands];
  Insn.length = Insn.readerCursor - Insn.startLocation;
  Size = Insn.length;
  if (Size > 15)
    LLVM_DEBUG(dbgs() << "Instruction exceeds 15-byte limit");

  bool Ret = translateInstruction(Instr, Insn, this);
  if (!Ret) {
    unsigned Flags = X86::IP_NO_PREFIX;
    if (Insn.hasAdSize)
      Flags |= X86::IP_HAS_AD_SIZE;
    if (!Insn.mandatoryPrefix) {
      if (Insn.hasOpSize)
        Flags |= X86::IP_HAS_OP_SIZE;
      if (Insn.repeatPrefix == 0xf2)
        Flags |= X86::IP_HAS_REPEAT_NE;
      else if (Insn.repeatPrefix == 0xf3 &&
               // It should not be 'pause' f3 90
               Insn.opcode != 0x90)
        Flags |= X86::IP_HAS_REPEAT;
      if (Insn.hasLockPrefix)
        Flags |= X86::IP_HAS_LOCK;
    }
    Instr.setFlags(Flags);
  }
  return (!Ret) ? Success : Fail;
}

//
// Private code that translates from struct InternalInstructions to MCInsts.
//

/// translateRegister - Translates an internal register to the appropriate LLVM
///   register, and appends it as an operand to an MCInst.
///
/// @param mcInst     - The MCInst to append to.
/// @param reg        - The Reg to append.
static void translateRegister(MCInst &mcInst, Reg reg) {
#define ENTRY(x) X86::x,
  static constexpr MCPhysReg llvmRegnums[] = {ALL_REGS};
#undef ENTRY

  MCPhysReg llvmRegnum = llvmRegnums[reg];
  mcInst.addOperand(MCOperand::createReg(llvmRegnum));
}

/// tryAddingSymbolicOperand - trys to add a symbolic operand in place of the
/// immediate Value in the MCInst.
///
/// @param Value      - The immediate Value, has had any PC adjustment made by
///                     the caller.
/// @param isBranch   - If the instruction is a branch instruction
/// @param Address    - The starting address of the instruction
/// @param Offset     - The byte offset to this immediate in the instruction
/// @param Width      - The byte width of this immediate in the instruction
///
/// If the getOpInfo() function was set when setupForSymbolicDisassembly() was
/// called then that function is called to get any symbolic information for the
/// immediate in the instruction using the Address, Offset and Width.  If that
/// returns non-zero then the symbolic information it returns is used to create
/// an MCExpr and that is added as an operand to the MCInst.  If getOpInfo()
/// returns zero and isBranch is true then a symbol look up for immediate Value
/// is done and if a symbol is found an MCExpr is created with that, else
/// an MCExpr with the immediate Value is created.  This function returns true
/// if it adds an operand to the MCInst and false otherwise.
static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch,
                                     uint64_t Address, uint64_t Offset,
                                     uint64_t Width, MCInst &MI,
                                     const MCDisassembler *Dis) {
  return Dis->tryAddingSymbolicOperand(MI, Value, Address, isBranch,
                                       Offset, Width);
}

/// tryAddingPcLoadReferenceComment - trys to add a comment as to what is being
/// referenced by a load instruction with the base register that is the rip.
/// These can often be addresses in a literal pool.  The Address of the
/// instruction and its immediate Value are used to determine the address
/// being referenced in the literal pool entry.  The SymbolLookUp call back will
/// return a pointer to a literal 'C' string if the referenced address is an
/// address into a section with 'C' string literals.
static void tryAddingPcLoadReferenceComment(uint64_t Address, uint64_t Value,
                                            const void *Decoder) {
  const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
  Dis->tryAddingPcLoadReferenceComment(Value, Address);
}

static const uint8_t segmentRegnums[SEG_OVERRIDE_max] = {
  0,        // SEG_OVERRIDE_NONE
  X86::CS,
  X86::SS,
  X86::DS,
  X86::ES,
  X86::FS,
  X86::GS
};

/// translateSrcIndex   - Appends a source index operand to an MCInst.
///
/// @param mcInst       - The MCInst to append to.
/// @param insn         - The internal instruction.
static bool translateSrcIndex(MCInst &mcInst, InternalInstruction &insn) {
  unsigned baseRegNo;

  if (insn.mode == MODE_64BIT)
    baseRegNo = insn.hasAdSize ? X86::ESI : X86::RSI;
  else if (insn.mode == MODE_32BIT)
    baseRegNo = insn.hasAdSize ? X86::SI : X86::ESI;
  else {
    assert(insn.mode == MODE_16BIT);
    baseRegNo = insn.hasAdSize ? X86::ESI : X86::SI;
  }
  MCOperand baseReg = MCOperand::createReg(baseRegNo);
  mcInst.addOperand(baseReg);

  MCOperand segmentReg;
  segmentReg = MCOperand::createReg(segmentRegnums[insn.segmentOverride]);
  mcInst.addOperand(segmentReg);
  return false;
}

/// translateDstIndex   - Appends a destination index operand to an MCInst.
///
/// @param mcInst       - The MCInst to append to.
/// @param insn         - The internal instruction.

static bool translateDstIndex(MCInst &mcInst, InternalInstruction &insn) {
  unsigned baseRegNo;

  if (insn.mode == MODE_64BIT)
    baseRegNo = insn.hasAdSize ? X86::EDI : X86::RDI;
  else if (insn.mode == MODE_32BIT)
    baseRegNo = insn.hasAdSize ? X86::DI : X86::EDI;
  else {
    assert(insn.mode == MODE_16BIT);
    baseRegNo = insn.hasAdSize ? X86::EDI : X86::DI;
  }
  MCOperand baseReg = MCOperand::createReg(baseRegNo);
  mcInst.addOperand(baseReg);
  return false;
}

/// translateImmediate  - Appends an immediate operand to an MCInst.
///
/// @param mcInst       - The MCInst to append to.
/// @param immediate    - The immediate value to append.
/// @param operand      - The operand, as stored in the descriptor table.
/// @param insn         - The internal instruction.
static void translateImmediate(MCInst &mcInst, uint64_t immediate,
                               const OperandSpecifier &operand,
                               InternalInstruction &insn,
                               const MCDisassembler *Dis) {
  // Sign-extend the immediate if necessary.

  OperandType type = (OperandType)operand.type;

  bool isBranch = false;
  uint64_t pcrel = 0;
  if (type == TYPE_REL) {
    isBranch = true;
    pcrel = insn.startLocation +
            insn.immediateOffset + insn.immediateSize;
    switch (operand.encoding) {
    default:
      break;
    case ENCODING_Iv:
      switch (insn.displacementSize) {
      default:
        break;
      case 1:
        if(immediate & 0x80)
          immediate |= ~(0xffull);
        break;
      case 2:
        if(immediate & 0x8000)
          immediate |= ~(0xffffull);
        break;
      case 4:
        if(immediate & 0x80000000)
          immediate |= ~(0xffffffffull);
        break;
      case 8:
        break;
      }
      break;
    case ENCODING_IB:
      if(immediate & 0x80)
        immediate |= ~(0xffull);
      break;
    case ENCODING_IW:
      if(immediate & 0x8000)
        immediate |= ~(0xffffull);
      break;
    case ENCODING_ID:
      if(immediate & 0x80000000)
        immediate |= ~(0xffffffffull);
      break;
    }
  }
  // By default sign-extend all X86 immediates based on their encoding.
  else if (type == TYPE_IMM) {
    switch (operand.encoding) {
    default:
      break;
    case ENCODING_IB:
      if(immediate & 0x80)
        immediate |= ~(0xffull);
      break;
    case ENCODING_IW:
      if(immediate & 0x8000)
        immediate |= ~(0xffffull);
      break;
    case ENCODING_ID:
      if(immediate & 0x80000000)
        immediate |= ~(0xffffffffull);
      break;
    case ENCODING_IO:
      break;
    }
  }

  switch (type) {
  case TYPE_XMM:
    mcInst.addOperand(MCOperand::createReg(X86::XMM0 + (immediate >> 4)));
    return;
  case TYPE_YMM:
    mcInst.addOperand(MCOperand::createReg(X86::YMM0 + (immediate >> 4)));
    return;
  case TYPE_ZMM:
    mcInst.addOperand(MCOperand::createReg(X86::ZMM0 + (immediate >> 4)));
    return;
  default:
    // operand is 64 bits wide.  Do nothing.
    break;
  }

  if(!tryAddingSymbolicOperand(immediate + pcrel, isBranch, insn.startLocation,
                               insn.immediateOffset, insn.immediateSize,
                               mcInst, Dis))
    mcInst.addOperand(MCOperand::createImm(immediate));

  if (type == TYPE_MOFFS) {
    MCOperand segmentReg;
    segmentReg = MCOperand::createReg(segmentRegnums[insn.segmentOverride]);
    mcInst.addOperand(segmentReg);
  }
}

/// translateRMRegister - Translates a register stored in the R/M field of the
///   ModR/M byte to its LLVM equivalent and appends it to an MCInst.
/// @param mcInst       - The MCInst to append to.
/// @param insn         - The internal instruction to extract the R/M field
///                       from.
/// @return             - 0 on success; -1 otherwise
static bool translateRMRegister(MCInst &mcInst,
                                InternalInstruction &insn) {
  if (insn.eaBase == EA_BASE_sib || insn.eaBase == EA_BASE_sib64) {
    debug("A R/M register operand may not have a SIB byte");
    return true;
  }

  switch (insn.eaBase) {
  default:
    debug("Unexpected EA base register");
    return true;
  case EA_BASE_NONE:
    debug("EA_BASE_NONE for ModR/M base");
    return true;
#define ENTRY(x) case EA_BASE_##x:
  ALL_EA_BASES
#undef ENTRY
    debug("A R/M register operand may not have a base; "
          "the operand must be a register.");
    return true;
#define ENTRY(x)                                                      \
  case EA_REG_##x:                                                    \
    mcInst.addOperand(MCOperand::createReg(X86::x)); break;
  ALL_REGS
#undef ENTRY
  }

  return false;
}

/// translateRMMemory - Translates a memory operand stored in the Mod and R/M
///   fields of an internal instruction (and possibly its SIB byte) to a memory
///   operand in LLVM's format, and appends it to an MCInst.
///
/// @param mcInst       - The MCInst to append to.
/// @param insn         - The instruction to extract Mod, R/M, and SIB fields
///                       from.
/// @param ForceSIB     - The instruction must use SIB.
/// @return             - 0 on success; nonzero otherwise
static bool translateRMMemory(MCInst &mcInst, InternalInstruction &insn,
                              const MCDisassembler *Dis,
                              bool ForceSIB = false) {
  // Addresses in an MCInst are represented as five operands:
  //   1. basereg       (register)  The R/M base, or (if there is a SIB) the
  //                                SIB base
  //   2. scaleamount   (immediate) 1, or (if there is a SIB) the specified
  //                                scale amount
  //   3. indexreg      (register)  x86_registerNONE, or (if there is a SIB)
  //                                the index (which is multiplied by the
  //                                scale amount)
  //   4. displacement  (immediate) 0, or the displacement if there is one
  //   5. segmentreg    (register)  x86_registerNONE for now, but could be set
  //                                if we have segment overrides

  MCOperand baseReg;
  MCOperand scaleAmount;
  MCOperand indexReg;
  MCOperand displacement;
  MCOperand segmentReg;
  uint64_t pcrel = 0;

  if (insn.eaBase == EA_BASE_sib || insn.eaBase == EA_BASE_sib64) {
    if (insn.sibBase != SIB_BASE_NONE) {
      switch (insn.sibBase) {
      default:
        debug("Unexpected sibBase");
        return true;
#define ENTRY(x)                                          \
      case SIB_BASE_##x:                                  \
        baseReg = MCOperand::createReg(X86::x); break;
      ALL_SIB_BASES
#undef ENTRY
      }
    } else {
      baseReg = MCOperand::createReg(X86::NoRegister);
    }

    if (insn.sibIndex != SIB_INDEX_NONE) {
      switch (insn.sibIndex) {
      default:
        debug("Unexpected sibIndex");
        return true;
#define ENTRY(x)                                          \
      case SIB_INDEX_##x:                                 \
        indexReg = MCOperand::createReg(X86::x); break;
      EA_BASES_32BIT
      EA_BASES_64BIT
      REGS_XMM
      REGS_YMM
      REGS_ZMM
#undef ENTRY
      }
    } else {
      // Use EIZ/RIZ for a few ambiguous cases where the SIB byte is present,
      // but no index is used and modrm alone should have been enough.
      // -No base register in 32-bit mode. In 64-bit mode this is used to
      //  avoid rip-relative addressing.
      // -Any base register used other than ESP/RSP/R12D/R12. Using these as a
      //  base always requires a SIB byte.
      // -A scale other than 1 is used.
      if (!ForceSIB &&
          (insn.sibScale != 1 ||
           (insn.sibBase == SIB_BASE_NONE && insn.mode != MODE_64BIT) ||
           (insn.sibBase != SIB_BASE_NONE &&
            insn.sibBase != SIB_BASE_ESP && insn.sibBase != SIB_BASE_RSP &&
            insn.sibBase != SIB_BASE_R12D && insn.sibBase != SIB_BASE_R12))) {
        indexReg = MCOperand::createReg(insn.addressSize == 4 ? X86::EIZ :
                                                                X86::RIZ);
      } else
        indexReg = MCOperand::createReg(X86::NoRegister);
    }

    scaleAmount = MCOperand::createImm(insn.sibScale);
  } else {
    switch (insn.eaBase) {
    case EA_BASE_NONE:
      if (insn.eaDisplacement == EA_DISP_NONE) {
        debug("EA_BASE_NONE and EA_DISP_NONE for ModR/M base");
        return true;
      }
      if (insn.mode == MODE_64BIT){
        pcrel = insn.startLocation +
                insn.displacementOffset + insn.displacementSize;
        tryAddingPcLoadReferenceComment(insn.startLocation +
                                        insn.displacementOffset,
                                        insn.displacement + pcrel, Dis);
        // Section 2.2.1.6
        baseReg = MCOperand::createReg(insn.addressSize == 4 ? X86::EIP :
                                                               X86::RIP);
      }
      else
        baseReg = MCOperand::createReg(X86::NoRegister);

      indexReg = MCOperand::createReg(X86::NoRegister);
      break;
    case EA_BASE_BX_SI:
      baseReg = MCOperand::createReg(X86::BX);
      indexReg = MCOperand::createReg(X86::SI);
      break;
    case EA_BASE_BX_DI:
      baseReg = MCOperand::createReg(X86::BX);
      indexReg = MCOperand::createReg(X86::DI);
      break;
    case EA_BASE_BP_SI:
      baseReg = MCOperand::createReg(X86::BP);
      indexReg = MCOperand::createReg(X86::SI);
      break;
    case EA_BASE_BP_DI:
      baseReg = MCOperand::createReg(X86::BP);
      indexReg = MCOperand::createReg(X86::DI);
      break;
    default:
      indexReg = MCOperand::createReg(X86::NoRegister);
      switch (insn.eaBase) {
      default:
        debug("Unexpected eaBase");
        return true;
        // Here, we will use the fill-ins defined above.  However,
        //   BX_SI, BX_DI, BP_SI, and BP_DI are all handled above and
        //   sib and sib64 were handled in the top-level if, so they're only
        //   placeholders to keep the compiler happy.
#define ENTRY(x)                                        \
      case EA_BASE_##x:                                 \
        baseReg = MCOperand::createReg(X86::x); break;
      ALL_EA_BASES
#undef ENTRY
#define ENTRY(x) case EA_REG_##x:
      ALL_REGS
#undef ENTRY
        debug("A R/M memory operand may not be a register; "
              "the base field must be a base.");
        return true;
      }
    }

    scaleAmount = MCOperand::createImm(1);
  }

  displacement = MCOperand::createImm(insn.displacement);

  segmentReg = MCOperand::createReg(segmentRegnums[insn.segmentOverride]);

  mcInst.addOperand(baseReg);
  mcInst.addOperand(scaleAmount);
  mcInst.addOperand(indexReg);
  if(!tryAddingSymbolicOperand(insn.displacement + pcrel, false,
                               insn.startLocation, insn.displacementOffset,
                               insn.displacementSize, mcInst, Dis))
    mcInst.addOperand(displacement);
  mcInst.addOperand(segmentReg);
  return false;
}

/// translateRM - Translates an operand stored in the R/M (and possibly SIB)
///   byte of an instruction to LLVM form, and appends it to an MCInst.
///
/// @param mcInst       - The MCInst to append to.
/// @param operand      - The operand, as stored in the descriptor table.
/// @param insn         - The instruction to extract Mod, R/M, and SIB fields
///                       from.
/// @return             - 0 on success; nonzero otherwise
static bool translateRM(MCInst &mcInst, const OperandSpecifier &operand,
                        InternalInstruction &insn, const MCDisassembler *Dis) {
  switch (operand.type) {
  default:
    debug("Unexpected type for a R/M operand");
    return true;
  case TYPE_R8:
  case TYPE_R16:
  case TYPE_R32:
  case TYPE_R64:
  case TYPE_Rv:
  case TYPE_MM64:
  case TYPE_XMM:
  case TYPE_YMM:
  case TYPE_ZMM:
  case TYPE_TMM:
  case TYPE_VK_PAIR:
  case TYPE_VK:
  case TYPE_DEBUGREG:
  case TYPE_CONTROLREG:
  case TYPE_BNDR:
    return translateRMRegister(mcInst, insn);
  case TYPE_M:
  case TYPE_MVSIBX:
  case TYPE_MVSIBY:
  case TYPE_MVSIBZ:
    return translateRMMemory(mcInst, insn, Dis);
  case TYPE_MSIB:
    return translateRMMemory(mcInst, insn, Dis, true);
  }
}

/// translateFPRegister - Translates a stack position on the FPU stack to its
///   LLVM form, and appends it to an MCInst.
///
/// @param mcInst       - The MCInst to append to.
/// @param stackPos     - The stack position to translate.
static void translateFPRegister(MCInst &mcInst,
                                uint8_t stackPos) {
  mcInst.addOperand(MCOperand::createReg(X86::ST0 + stackPos));
}

/// translateMaskRegister - Translates a 3-bit mask register number to
///   LLVM form, and appends it to an MCInst.
///
/// @param mcInst       - The MCInst to append to.
/// @param maskRegNum   - Number of mask register from 0 to 7.
/// @return             - false on success; true otherwise.
static bool translateMaskRegister(MCInst &mcInst,
                                uint8_t maskRegNum) {
  if (maskRegNum >= 8) {
    debug("Invalid mask register number");
    return true;
  }

  mcInst.addOperand(MCOperand::createReg(X86::K0 + maskRegNum));
  return false;
}

/// translateOperand - Translates an operand stored in an internal instruction
///   to LLVM's format and appends it to an MCInst.
///
/// @param mcInst       - The MCInst to append to.
/// @param operand      - The operand, as stored in the descriptor table.
/// @param insn         - The internal instruction.
/// @return             - false on success; true otherwise.
static bool translateOperand(MCInst &mcInst, const OperandSpecifier &operand,
                             InternalInstruction &insn,
                             const MCDisassembler *Dis) {
  switch (operand.encoding) {
  default:
    debug("Unhandled operand encoding during translation");
    return true;
  case ENCODING_REG:
    translateRegister(mcInst, insn.reg);
    return false;
  case ENCODING_WRITEMASK:
    return translateMaskRegister(mcInst, insn.writemask);
  case ENCODING_SIB:
  CASE_ENCODING_RM:
  CASE_ENCODING_VSIB:
    return translateRM(mcInst, operand, insn, Dis);
  case ENCODING_IB:
  case ENCODING_IW:
  case ENCODING_ID:
  case ENCODING_IO:
  case ENCODING_Iv:
  case ENCODING_Ia:
    translateImmediate(mcInst,
                       insn.immediates[insn.numImmediatesTranslated++],
                       operand,
                       insn,
                       Dis);
    return false;
  case ENCODING_IRC:
    mcInst.addOperand(MCOperand::createImm(insn.RC));
    return false;
  case ENCODING_SI:
    return translateSrcIndex(mcInst, insn);
  case ENCODING_DI:
    return translateDstIndex(mcInst, insn);
  case ENCODING_RB:
  case ENCODING_RW:
  case ENCODING_RD:
  case ENCODING_RO:
  case ENCODING_Rv:
    translateRegister(mcInst, insn.opcodeRegister);
    return false;
  case ENCODING_CC:
    mcInst.addOperand(MCOperand::createImm(insn.immediates[1]));
    return false;
  case ENCODING_FP:
    translateFPRegister(mcInst, insn.modRM & 7);
    return false;
  case ENCODING_VVVV:
    translateRegister(mcInst, insn.vvvv);
    return false;
  case ENCODING_DUP:
    return translateOperand(mcInst, insn.operands[operand.type - TYPE_DUP0],
                            insn, Dis);
  }
}

/// translateInstruction - Translates an internal instruction and all its
///   operands to an MCInst.
///
/// @param mcInst       - The MCInst to populate with the instruction's data.
/// @param insn         - The internal instruction.
/// @return             - false on success; true otherwise.
static bool translateInstruction(MCInst &mcInst,
                                InternalInstruction &insn,
                                const MCDisassembler *Dis) {
  if (!insn.spec) {
    debug("Instruction has no specification");
    return true;
  }

  mcInst.clear();
  mcInst.setOpcode(insn.instructionID);
  // If when reading the prefix bytes we determined the overlapping 0xf2 or 0xf3
  // prefix bytes should be disassembled as xrelease and xacquire then set the
  // opcode to those instead of the rep and repne opcodes.
  if (insn.xAcquireRelease) {
    if(mcInst.getOpcode() == X86::REP_PREFIX)
      mcInst.setOpcode(X86::XRELEASE_PREFIX);
    else if(mcInst.getOpcode() == X86::REPNE_PREFIX)
      mcInst.setOpcode(X86::XACQUIRE_PREFIX);
  }

  insn.numImmediatesTranslated = 0;

  for (const auto &Op : insn.operands) {
    if (Op.encoding != ENCODING_NONE) {
      if (translateOperand(mcInst, Op, insn, Dis)) {
        return true;
      }
    }
  }

  return false;
}

static MCDisassembler *createX86Disassembler(const Target &T,
                                             const MCSubtargetInfo &STI,
                                             MCContext &Ctx) {
  std::unique_ptr<const MCInstrInfo> MII(T.createMCInstrInfo());
  return new X86GenericDisassembler(STI, Ctx, std::move(MII));
}

extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeX86Disassembler() {
  // Register the disassembler.
  TargetRegistry::RegisterMCDisassembler(getTheX86_32Target(),
                                         createX86Disassembler);
  TargetRegistry::RegisterMCDisassembler(getTheX86_64Target(),
                                         createX86Disassembler);
}
