//===- bolt/Target/X86/X86MCPlusBuilder.cpp -------------------------------===//
//
// 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 provides X86-specific MCPlus builder.
//
//===----------------------------------------------------------------------===//

#include "MCTargetDesc/X86BaseInfo.h"
#include "MCTargetDesc/X86EncodingOptimization.h"
#include "MCTargetDesc/X86MCTargetDesc.h"
#include "X86MCSymbolizer.h"
#include "bolt/Core/MCPlus.h"
#include "bolt/Core/MCPlusBuilder.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstBuilder.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegister.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ErrorOr.h"
#include <set>

#define DEBUG_TYPE "mcplus"

using namespace llvm;
using namespace bolt;

namespace opts {

extern cl::OptionCategory BoltOptCategory;

static cl::opt<bool> X86StripRedundantAddressSize(
    "x86-strip-redundant-address-size",
    cl::desc("Remove redundant Address-Size override prefix"), cl::init(true),
    cl::cat(BoltOptCategory));

} // namespace opts

namespace {

bool isMOVSX64rm32(const MCInst &Inst) {
  return Inst.getOpcode() == X86::MOVSX64rm32;
}

bool isADD64rr(const MCInst &Inst) { return Inst.getOpcode() == X86::ADD64rr; }

bool isADDri(const MCInst &Inst) {
  return Inst.getOpcode() == X86::ADD64ri32 ||
         Inst.getOpcode() == X86::ADD64ri8;
}

// Create instruction to increment contents of target by 1
static InstructionListType createIncMemory(const MCSymbol *Target,
                                           MCContext *Ctx) {
  InstructionListType Insts;
  Insts.emplace_back();
  Insts.back().setOpcode(X86::LOCK_INC64m);
  Insts.back().clear();
  Insts.back().addOperand(MCOperand::createReg(X86::RIP));        // BaseReg
  Insts.back().addOperand(MCOperand::createImm(1));               // ScaleAmt
  Insts.back().addOperand(MCOperand::createReg(X86::NoRegister)); // IndexReg

  Insts.back().addOperand(
      MCOperand::createExpr(MCSymbolRefExpr::create(Target,
                                                    *Ctx))); // Displacement
  Insts.back().addOperand(
      MCOperand::createReg(X86::NoRegister)); // AddrSegmentReg
  return Insts;
}

#define GET_INSTRINFO_OPERAND_TYPES_ENUM
#define GET_INSTRINFO_OPERAND_TYPE
#define GET_INSTRINFO_MEM_OPERAND_SIZE
#include "X86GenInstrInfo.inc"

class X86MCPlusBuilder : public MCPlusBuilder {
public:
  using MCPlusBuilder::MCPlusBuilder;

  std::unique_ptr<MCSymbolizer>
  createTargetSymbolizer(BinaryFunction &Function,
                         bool CreateNewSymbols) const override {
    return std::make_unique<X86MCSymbolizer>(Function, CreateNewSymbols);
  }

  bool isBranch(const MCInst &Inst) const override {
    return Analysis->isBranch(Inst) && !isTailCall(Inst);
  }

  bool isNoop(const MCInst &Inst) const override {
    return X86::isNOP(Inst.getOpcode());
  }

  unsigned getCondCode(const MCInst &Inst) const override {
    unsigned Opcode = Inst.getOpcode();
    if (X86::isJCC(Opcode))
      return Inst.getOperand(Info->get(Opcode).NumOperands - 1).getImm();
    return X86::COND_INVALID;
  }

  unsigned getInvertedCondCode(unsigned CC) const override {
    switch (CC) {
    default: return X86::COND_INVALID;
    case X86::COND_E:  return X86::COND_NE;
    case X86::COND_NE: return X86::COND_E;
    case X86::COND_L:  return X86::COND_GE;
    case X86::COND_LE: return X86::COND_G;
    case X86::COND_G:  return X86::COND_LE;
    case X86::COND_GE: return X86::COND_L;
    case X86::COND_B:  return X86::COND_AE;
    case X86::COND_BE: return X86::COND_A;
    case X86::COND_A:  return X86::COND_BE;
    case X86::COND_AE: return X86::COND_B;
    case X86::COND_S:  return X86::COND_NS;
    case X86::COND_NS: return X86::COND_S;
    case X86::COND_P:  return X86::COND_NP;
    case X86::COND_NP: return X86::COND_P;
    case X86::COND_O:  return X86::COND_NO;
    case X86::COND_NO: return X86::COND_O;
    }
  }

  unsigned getCondCodesLogicalOr(unsigned CC1, unsigned CC2) const override {
    enum DecodedCondCode : uint8_t {
      DCC_EQUAL = 0x1,
      DCC_GREATER = 0x2,
      DCC_LESSER = 0x4,
      DCC_GREATER_OR_LESSER = 0x6,
      DCC_UNSIGNED = 0x8,
      DCC_SIGNED = 0x10,
      DCC_INVALID = 0x20,
    };

    auto decodeCondCode = [&](unsigned CC) -> uint8_t {
      switch (CC) {
      default: return DCC_INVALID;
      case X86::COND_E: return DCC_EQUAL;
      case X86::COND_NE: return DCC_GREATER | DCC_LESSER;
      case X86::COND_L: return DCC_LESSER | DCC_SIGNED;
      case X86::COND_LE: return DCC_EQUAL | DCC_LESSER | DCC_SIGNED;
      case X86::COND_G: return DCC_GREATER | DCC_SIGNED;
      case X86::COND_GE: return DCC_GREATER | DCC_EQUAL | DCC_SIGNED;
      case X86::COND_B: return DCC_LESSER | DCC_UNSIGNED;
      case X86::COND_BE: return DCC_EQUAL | DCC_LESSER | DCC_UNSIGNED;
      case X86::COND_A: return DCC_GREATER | DCC_UNSIGNED;
      case X86::COND_AE: return DCC_GREATER | DCC_EQUAL | DCC_UNSIGNED;
      }
    };

    uint8_t DCC = decodeCondCode(CC1) | decodeCondCode(CC2);

    if (DCC & DCC_INVALID)
      return X86::COND_INVALID;

    if (DCC & DCC_SIGNED && DCC & DCC_UNSIGNED)
      return X86::COND_INVALID;

    switch (DCC) {
    default: return X86::COND_INVALID;
    case DCC_EQUAL | DCC_LESSER | DCC_SIGNED: return X86::COND_LE;
    case DCC_EQUAL | DCC_LESSER | DCC_UNSIGNED: return X86::COND_BE;
    case DCC_EQUAL | DCC_GREATER | DCC_SIGNED: return X86::COND_GE;
    case DCC_EQUAL | DCC_GREATER | DCC_UNSIGNED: return X86::COND_AE;
    case DCC_GREATER | DCC_LESSER | DCC_SIGNED: return X86::COND_NE;
    case DCC_GREATER | DCC_LESSER | DCC_UNSIGNED: return X86::COND_NE;
    case DCC_GREATER | DCC_LESSER: return X86::COND_NE;
    case DCC_EQUAL | DCC_SIGNED: return X86::COND_E;
    case DCC_EQUAL | DCC_UNSIGNED: return X86::COND_E;
    case DCC_EQUAL: return X86::COND_E;
    case DCC_LESSER | DCC_SIGNED: return X86::COND_L;
    case DCC_LESSER | DCC_UNSIGNED: return X86::COND_B;
    case DCC_GREATER | DCC_SIGNED: return X86::COND_G;
    case DCC_GREATER | DCC_UNSIGNED: return X86::COND_A;
    }
  }

  bool isValidCondCode(unsigned CC) const override {
    return (CC != X86::COND_INVALID);
  }

  bool isBreakpoint(const MCInst &Inst) const override {
    return Inst.getOpcode() == X86::INT3;
  }

  bool isPrefix(const MCInst &Inst) const override {
    const MCInstrDesc &Desc = Info->get(Inst.getOpcode());
    return X86II::isPrefix(Desc.TSFlags);
  }

  bool isRep(const MCInst &Inst) const override {
    return Inst.getFlags() == X86::IP_HAS_REPEAT;
  }

  bool deleteREPPrefix(MCInst &Inst) const override {
    if (Inst.getFlags() == X86::IP_HAS_REPEAT) {
      Inst.setFlags(0);
      return true;
    }
    return false;
  }

  bool isIndirectCall(const MCInst &Inst) const override {
    return isCall(Inst) &&
           ((getMemoryOperandNo(Inst) != -1) || Inst.getOperand(0).isReg());
  }

  bool isPop(const MCInst &Inst) const override {
    return getPopSize(Inst) == 0 ? false : true;
  }

  bool isEpilogue(const BinaryBasicBlock &BB) const override {
    return ::llvm::any_of(BB, [&](const MCInst &Instr) {
      return isLeave(Instr) || isPop(Instr);
    });
  }

  bool isTerminateBranch(const MCInst &Inst) const override {
    return Inst.getOpcode() == X86::ENDBR32 || Inst.getOpcode() == X86::ENDBR64;
  }

  bool isX86HLT(const MCInst &Inst) const override {
    return Inst.getOpcode() == X86::HLT;
  }

  int getPopSize(const MCInst &Inst) const override {
    switch (Inst.getOpcode()) {
    case X86::POP16r:
    case X86::POP16rmm:
    case X86::POP16rmr:
    case X86::POPF16:
    case X86::POPA16:
    case X86::POPDS16:
    case X86::POPES16:
    case X86::POPFS16:
    case X86::POPGS16:
    case X86::POPSS16:
      return 2;
    case X86::POP32r:
    case X86::POP32rmm:
    case X86::POP32rmr:
    case X86::POPA32:
    case X86::POPDS32:
    case X86::POPES32:
    case X86::POPF32:
    case X86::POPFS32:
    case X86::POPGS32:
    case X86::POPSS32:
      return 4;
    case X86::POP64r:
    case X86::POP64rmm:
    case X86::POP64rmr:
    case X86::POPF64:
    case X86::POPFS64:
    case X86::POPGS64:
      return 8;
    }
    return 0;
  }

  bool isPush(const MCInst &Inst) const override {
    return getPushSize(Inst) == 0 ? false : true;
  }

  int getPushSize(const MCInst &Inst) const override {
    switch (Inst.getOpcode()) {
    case X86::PUSH16i8:
    case X86::PUSH16r:
    case X86::PUSH16rmm:
    case X86::PUSH16rmr:
    case X86::PUSHA16:
    case X86::PUSHCS16:
    case X86::PUSHDS16:
    case X86::PUSHES16:
    case X86::PUSHF16:
    case X86::PUSHFS16:
    case X86::PUSHGS16:
    case X86::PUSHSS16:
    case X86::PUSH16i:
      return 2;
    case X86::PUSH32i8:
    case X86::PUSH32r:
    case X86::PUSH32rmm:
    case X86::PUSH32rmr:
    case X86::PUSHA32:
    case X86::PUSHCS32:
    case X86::PUSHDS32:
    case X86::PUSHES32:
    case X86::PUSHF32:
    case X86::PUSHFS32:
    case X86::PUSHGS32:
    case X86::PUSHSS32:
    case X86::PUSH32i:
      return 4;
    case X86::PUSH64i32:
    case X86::PUSH64i8:
    case X86::PUSH64r:
    case X86::PUSH64rmm:
    case X86::PUSH64rmr:
    case X86::PUSHF64:
    case X86::PUSHFS64:
    case X86::PUSHGS64:
      return 8;
    }
    return 0;
  }

  bool isSUB(const MCInst &Inst) const override {
    return X86::isSUB(Inst.getOpcode());
  }

  bool isLEA64r(const MCInst &Inst) const override {
    return Inst.getOpcode() == X86::LEA64r;
  }

  bool isLeave(const MCInst &Inst) const override {
    return Inst.getOpcode() == X86::LEAVE || Inst.getOpcode() == X86::LEAVE64;
  }

  bool isMoveMem2Reg(const MCInst &Inst) const override {
    switch (Inst.getOpcode()) {
    case X86::MOV16rm:
    case X86::MOV32rm:
    case X86::MOV64rm:
      return true;
    }
    return false;
  }

  bool isUnsupportedInstruction(const MCInst &Inst) const override {
    switch (Inst.getOpcode()) {
    default:
      return false;

    case X86::LOOP:
    case X86::LOOPE:
    case X86::LOOPNE:
    case X86::JECXZ:
    case X86::JRCXZ:
      // These have a short displacement, and therefore (often) break after
      // basic block relayout.
      return true;
    }
  }

  bool mayLoad(const MCInst &Inst) const override {
    if (isPop(Inst))
      return true;

    int MemOpNo = getMemoryOperandNo(Inst);
    const MCInstrDesc &MCII = Info->get(Inst.getOpcode());

    if (MemOpNo == -1)
      return false;

    return MCII.mayLoad();
  }

  bool mayStore(const MCInst &Inst) const override {
    if (isPush(Inst))
      return true;

    int MemOpNo = getMemoryOperandNo(Inst);
    const MCInstrDesc &MCII = Info->get(Inst.getOpcode());

    if (MemOpNo == -1)
      return false;

    return MCII.mayStore();
  }

  bool isCleanRegXOR(const MCInst &Inst) const override {
    switch (Inst.getOpcode()) {
    case X86::XOR16rr:
    case X86::XOR32rr:
    case X86::XOR64rr:
      break;
    default:
      return false;
    }
    return (Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg());
  }

  bool isPacked(const MCInst &Inst) const override {
    const MCInstrDesc &Desc = Info->get(Inst.getOpcode());
    return (Desc.TSFlags & X86II::OpPrefixMask) == X86II::PD;
  }

  bool shouldRecordCodeRelocation(uint32_t RelType) const override {
    switch (RelType) {
    case ELF::R_X86_64_8:
    case ELF::R_X86_64_16:
    case ELF::R_X86_64_32:
    case ELF::R_X86_64_32S:
    case ELF::R_X86_64_64:
    case ELF::R_X86_64_PC8:
    case ELF::R_X86_64_PC32:
    case ELF::R_X86_64_PC64:
    case ELF::R_X86_64_GOTPC64:
    case ELF::R_X86_64_GOTPCRELX:
    case ELF::R_X86_64_REX_GOTPCRELX:
      return true;
    case ELF::R_X86_64_PLT32:
    case ELF::R_X86_64_GOTPCREL:
    case ELF::R_X86_64_TPOFF32:
    case ELF::R_X86_64_GOTTPOFF:
      return false;
    default:
      llvm_unreachable("Unexpected x86 relocation type in code");
    }
  }

  StringRef getTrapFillValue() const override { return StringRef("\314", 1); }

  struct IndJmpMatcherFrag1 : MCInstMatcher {
    std::unique_ptr<MCInstMatcher> Base;
    std::unique_ptr<MCInstMatcher> Scale;
    std::unique_ptr<MCInstMatcher> Index;
    std::unique_ptr<MCInstMatcher> Offset;

    IndJmpMatcherFrag1(std::unique_ptr<MCInstMatcher> Base,
                       std::unique_ptr<MCInstMatcher> Scale,
                       std::unique_ptr<MCInstMatcher> Index,
                       std::unique_ptr<MCInstMatcher> Offset)
        : Base(std::move(Base)), Scale(std::move(Scale)),
          Index(std::move(Index)), Offset(std::move(Offset)) {}

    bool match(const MCRegisterInfo &MRI, MCPlusBuilder &MIB,
               MutableArrayRef<MCInst> InInstrWindow, int OpNum) override {
      if (!MCInstMatcher::match(MRI, MIB, InInstrWindow, OpNum))
        return false;

      if (CurInst->getOpcode() != X86::JMP64m)
        return false;

      int MemOpNo = MIB.getMemoryOperandNo(*CurInst);
      if (MemOpNo == -1)
        return false;

      if (!Base->match(MRI, MIB, this->InstrWindow, MemOpNo + X86::AddrBaseReg))
        return false;
      if (!Scale->match(MRI, MIB, this->InstrWindow,
                        MemOpNo + X86::AddrScaleAmt))
        return false;
      if (!Index->match(MRI, MIB, this->InstrWindow,
                        MemOpNo + X86::AddrIndexReg))
        return false;
      if (!Offset->match(MRI, MIB, this->InstrWindow, MemOpNo + X86::AddrDisp))
        return false;
      return true;
    }

    void annotate(MCPlusBuilder &MIB, StringRef Annotation) override {
      MIB.addAnnotation(*CurInst, Annotation, true);
      Base->annotate(MIB, Annotation);
      Scale->annotate(MIB, Annotation);
      Index->annotate(MIB, Annotation);
      Offset->annotate(MIB, Annotation);
    }
  };

  std::unique_ptr<MCInstMatcher>
  matchIndJmp(std::unique_ptr<MCInstMatcher> Base,
              std::unique_ptr<MCInstMatcher> Scale,
              std::unique_ptr<MCInstMatcher> Index,
              std::unique_ptr<MCInstMatcher> Offset) const override {
    return std::unique_ptr<MCInstMatcher>(
        new IndJmpMatcherFrag1(std::move(Base), std::move(Scale),
                               std::move(Index), std::move(Offset)));
  }

  struct IndJmpMatcherFrag2 : MCInstMatcher {
    std::unique_ptr<MCInstMatcher> Reg;

    IndJmpMatcherFrag2(std::unique_ptr<MCInstMatcher> Reg)
        : Reg(std::move(Reg)) {}

    bool match(const MCRegisterInfo &MRI, MCPlusBuilder &MIB,
               MutableArrayRef<MCInst> InInstrWindow, int OpNum) override {
      if (!MCInstMatcher::match(MRI, MIB, InInstrWindow, OpNum))
        return false;

      if (CurInst->getOpcode() != X86::JMP64r)
        return false;

      return Reg->match(MRI, MIB, this->InstrWindow, 0);
    }

    void annotate(MCPlusBuilder &MIB, StringRef Annotation) override {
      MIB.addAnnotation(*CurInst, Annotation, true);
      Reg->annotate(MIB, Annotation);
    }
  };

  std::unique_ptr<MCInstMatcher>
  matchIndJmp(std::unique_ptr<MCInstMatcher> Target) const override {
    return std::unique_ptr<MCInstMatcher>(
        new IndJmpMatcherFrag2(std::move(Target)));
  }

  struct LoadMatcherFrag1 : MCInstMatcher {
    std::unique_ptr<MCInstMatcher> Base;
    std::unique_ptr<MCInstMatcher> Scale;
    std::unique_ptr<MCInstMatcher> Index;
    std::unique_ptr<MCInstMatcher> Offset;

    LoadMatcherFrag1(std::unique_ptr<MCInstMatcher> Base,
                     std::unique_ptr<MCInstMatcher> Scale,
                     std::unique_ptr<MCInstMatcher> Index,
                     std::unique_ptr<MCInstMatcher> Offset)
        : Base(std::move(Base)), Scale(std::move(Scale)),
          Index(std::move(Index)), Offset(std::move(Offset)) {}

    bool match(const MCRegisterInfo &MRI, MCPlusBuilder &MIB,
               MutableArrayRef<MCInst> InInstrWindow, int OpNum) override {
      if (!MCInstMatcher::match(MRI, MIB, InInstrWindow, OpNum))
        return false;

      if (CurInst->getOpcode() != X86::MOV64rm &&
          CurInst->getOpcode() != X86::MOVSX64rm32)
        return false;

      int MemOpNo = MIB.getMemoryOperandNo(*CurInst);
      if (MemOpNo == -1)
        return false;

      if (!Base->match(MRI, MIB, this->InstrWindow, MemOpNo + X86::AddrBaseReg))
        return false;
      if (!Scale->match(MRI, MIB, this->InstrWindow,
                        MemOpNo + X86::AddrScaleAmt))
        return false;
      if (!Index->match(MRI, MIB, this->InstrWindow,
                        MemOpNo + X86::AddrIndexReg))
        return false;
      if (!Offset->match(MRI, MIB, this->InstrWindow, MemOpNo + X86::AddrDisp))
        return false;
      return true;
    }

    void annotate(MCPlusBuilder &MIB, StringRef Annotation) override {
      MIB.addAnnotation(*CurInst, Annotation, true);
      Base->annotate(MIB, Annotation);
      Scale->annotate(MIB, Annotation);
      Index->annotate(MIB, Annotation);
      Offset->annotate(MIB, Annotation);
    }
  };

  std::unique_ptr<MCInstMatcher>
  matchLoad(std::unique_ptr<MCInstMatcher> Base,
            std::unique_ptr<MCInstMatcher> Scale,
            std::unique_ptr<MCInstMatcher> Index,
            std::unique_ptr<MCInstMatcher> Offset) const override {
    return std::unique_ptr<MCInstMatcher>(
        new LoadMatcherFrag1(std::move(Base), std::move(Scale),
                             std::move(Index), std::move(Offset)));
  }

  struct AddMatcher : MCInstMatcher {
    std::unique_ptr<MCInstMatcher> A;
    std::unique_ptr<MCInstMatcher> B;

    AddMatcher(std::unique_ptr<MCInstMatcher> A,
               std::unique_ptr<MCInstMatcher> B)
        : A(std::move(A)), B(std::move(B)) {}

    bool match(const MCRegisterInfo &MRI, MCPlusBuilder &MIB,
               MutableArrayRef<MCInst> InInstrWindow, int OpNum) override {
      if (!MCInstMatcher::match(MRI, MIB, InInstrWindow, OpNum))
        return false;

      if (CurInst->getOpcode() == X86::ADD64rr ||
          CurInst->getOpcode() == X86::ADD64rr_DB ||
          CurInst->getOpcode() == X86::ADD64rr_REV) {
        if (!A->match(MRI, MIB, this->InstrWindow, 1)) {
          if (!B->match(MRI, MIB, this->InstrWindow, 1))
            return false;
          return A->match(MRI, MIB, this->InstrWindow, 2);
        }

        if (B->match(MRI, MIB, this->InstrWindow, 2))
          return true;

        if (!B->match(MRI, MIB, this->InstrWindow, 1))
          return false;
        return A->match(MRI, MIB, this->InstrWindow, 2);
      }

      return false;
    }

    void annotate(MCPlusBuilder &MIB, StringRef Annotation) override {
      MIB.addAnnotation(*CurInst, Annotation, true);
      A->annotate(MIB, Annotation);
      B->annotate(MIB, Annotation);
    }
  };

  std::unique_ptr<MCInstMatcher>
  matchAdd(std::unique_ptr<MCInstMatcher> A,
           std::unique_ptr<MCInstMatcher> B) const override {
    return std::unique_ptr<MCInstMatcher>(
        new AddMatcher(std::move(A), std::move(B)));
  }

  struct LEAMatcher : MCInstMatcher {
    std::unique_ptr<MCInstMatcher> Target;

    LEAMatcher(std::unique_ptr<MCInstMatcher> Target)
        : Target(std::move(Target)) {}

    bool match(const MCRegisterInfo &MRI, MCPlusBuilder &MIB,
               MutableArrayRef<MCInst> InInstrWindow, int OpNum) override {
      if (!MCInstMatcher::match(MRI, MIB, InInstrWindow, OpNum))
        return false;

      if (CurInst->getOpcode() != X86::LEA64r)
        return false;

      if (CurInst->getOperand(1 + X86::AddrScaleAmt).getImm() != 1 ||
          CurInst->getOperand(1 + X86::AddrIndexReg).getReg() !=
              X86::NoRegister ||
          (CurInst->getOperand(1 + X86::AddrBaseReg).getReg() !=
               X86::NoRegister &&
           CurInst->getOperand(1 + X86::AddrBaseReg).getReg() != X86::RIP))
        return false;

      return Target->match(MRI, MIB, this->InstrWindow, 1 + X86::AddrDisp);
    }

    void annotate(MCPlusBuilder &MIB, StringRef Annotation) override {
      MIB.addAnnotation(*CurInst, Annotation, true);
      Target->annotate(MIB, Annotation);
    }
  };

  std::unique_ptr<MCInstMatcher>
  matchLoadAddr(std::unique_ptr<MCInstMatcher> Target) const override {
    return std::unique_ptr<MCInstMatcher>(new LEAMatcher(std::move(Target)));
  }

  bool hasPCRelOperand(const MCInst &Inst) const override {
    for (const MCOperand &Operand : Inst)
      if (Operand.isReg() && Operand.getReg() == X86::RIP)
        return true;
    return false;
  }

  int getMemoryOperandNo(const MCInst &Inst) const override {
    unsigned Opcode = Inst.getOpcode();
    const MCInstrDesc &Desc = Info->get(Opcode);
    int MemOpNo = X86II::getMemoryOperandNo(Desc.TSFlags);
    if (MemOpNo >= 0)
      MemOpNo += X86II::getOperandBias(Desc);
    return MemOpNo;
  }

  bool hasEVEXEncoding(const MCInst &Inst) const override {
    const MCInstrDesc &Desc = Info->get(Inst.getOpcode());
    return (Desc.TSFlags & X86II::EncodingMask) == X86II::EVEX;
  }

  std::optional<X86MemOperand>
  evaluateX86MemoryOperand(const MCInst &Inst) const override {
    int MemOpNo = getMemoryOperandNo(Inst);
    if (MemOpNo < 0)
      return std::nullopt;
    unsigned MemOpOffset = static_cast<unsigned>(MemOpNo);

    if (MemOpOffset + X86::AddrSegmentReg >= MCPlus::getNumPrimeOperands(Inst))
      return std::nullopt;

    const MCOperand &Base = Inst.getOperand(MemOpOffset + X86::AddrBaseReg);
    const MCOperand &Scale = Inst.getOperand(MemOpOffset + X86::AddrScaleAmt);
    const MCOperand &Index = Inst.getOperand(MemOpOffset + X86::AddrIndexReg);
    const MCOperand &Disp = Inst.getOperand(MemOpOffset + X86::AddrDisp);
    const MCOperand &Segment =
        Inst.getOperand(MemOpOffset + X86::AddrSegmentReg);

    // Make sure it is a well-formed memory operand.
    if (!Base.isReg() || !Scale.isImm() || !Index.isReg() ||
        (!Disp.isImm() && !Disp.isExpr()) || !Segment.isReg())
      return std::nullopt;

    X86MemOperand MO;
    MO.BaseRegNum = Base.getReg();
    MO.ScaleImm = Scale.getImm();
    MO.IndexRegNum = Index.getReg();
    MO.DispImm = Disp.isImm() ? Disp.getImm() : 0;
    MO.DispExpr = Disp.isExpr() ? Disp.getExpr() : nullptr;
    MO.SegRegNum = Segment.getReg();
    return MO;
  }

  bool evaluateMemOperandTarget(const MCInst &Inst, uint64_t &Target,
                                uint64_t Address,
                                uint64_t Size) const override {
    std::optional<X86MemOperand> MO = evaluateX86MemoryOperand(Inst);
    if (!MO)
      return false;

    // Make sure it's a well-formed addressing we can statically evaluate.
    if ((MO->BaseRegNum != X86::RIP && MO->BaseRegNum != X86::NoRegister) ||
        MO->IndexRegNum != X86::NoRegister ||
        MO->SegRegNum != X86::NoRegister || MO->DispExpr)
      return false;

    Target = MO->DispImm;
    if (MO->BaseRegNum == X86::RIP) {
      assert(Size != 0 && "instruction size required in order to statically "
                          "evaluate RIP-relative address");
      Target += Address + Size;
    }
    return true;
  }

  MCInst::iterator getMemOperandDisp(MCInst &Inst) const override {
    int MemOpNo = getMemoryOperandNo(Inst);
    if (MemOpNo < 0)
      return Inst.end();
    return Inst.begin() + (MemOpNo + X86::AddrDisp);
  }

  bool replaceMemOperandDisp(MCInst &Inst, MCOperand Operand) const override {
    MCOperand *OI = getMemOperandDisp(Inst);
    if (OI == Inst.end())
      return false;
    *OI = Operand;
    return true;
  }

  /// Get the registers used as function parameters.
  /// This function is specific to the x86_64 abi on Linux.
  BitVector getRegsUsedAsParams() const override {
    BitVector Regs = BitVector(RegInfo->getNumRegs(), false);
    Regs |= getAliases(X86::RSI);
    Regs |= getAliases(X86::RDI);
    Regs |= getAliases(X86::RDX);
    Regs |= getAliases(X86::RCX);
    Regs |= getAliases(X86::R8);
    Regs |= getAliases(X86::R9);
    return Regs;
  }

  void getCalleeSavedRegs(BitVector &Regs) const override {
    Regs |= getAliases(X86::RBX);
    Regs |= getAliases(X86::RBP);
    Regs |= getAliases(X86::R12);
    Regs |= getAliases(X86::R13);
    Regs |= getAliases(X86::R14);
    Regs |= getAliases(X86::R15);
  }

  void getDefaultDefIn(BitVector &Regs) const override {
    assert(Regs.size() >= RegInfo->getNumRegs() &&
           "The size of BitVector is less than RegInfo->getNumRegs().");
    Regs.set(X86::RAX);
    Regs.set(X86::RCX);
    Regs.set(X86::RDX);
    Regs.set(X86::RSI);
    Regs.set(X86::RDI);
    Regs.set(X86::R8);
    Regs.set(X86::R9);
    Regs.set(X86::XMM0);
    Regs.set(X86::XMM1);
    Regs.set(X86::XMM2);
    Regs.set(X86::XMM3);
    Regs.set(X86::XMM4);
    Regs.set(X86::XMM5);
    Regs.set(X86::XMM6);
    Regs.set(X86::XMM7);
  }

  void getDefaultLiveOut(BitVector &Regs) const override {
    assert(Regs.size() >= RegInfo->getNumRegs() &&
           "The size of BitVector is less than RegInfo->getNumRegs().");
    Regs |= getAliases(X86::RAX);
    Regs |= getAliases(X86::RDX);
    Regs |= getAliases(X86::RCX);
    Regs |= getAliases(X86::XMM0);
    Regs |= getAliases(X86::XMM1);
  }

  void getGPRegs(BitVector &Regs, bool IncludeAlias) const override {
    if (IncludeAlias) {
      Regs |= getAliases(X86::RAX);
      Regs |= getAliases(X86::RBX);
      Regs |= getAliases(X86::RBP);
      Regs |= getAliases(X86::RSI);
      Regs |= getAliases(X86::RDI);
      Regs |= getAliases(X86::RDX);
      Regs |= getAliases(X86::RCX);
      Regs |= getAliases(X86::R8);
      Regs |= getAliases(X86::R9);
      Regs |= getAliases(X86::R10);
      Regs |= getAliases(X86::R11);
      Regs |= getAliases(X86::R12);
      Regs |= getAliases(X86::R13);
      Regs |= getAliases(X86::R14);
      Regs |= getAliases(X86::R15);
      return;
    }
    Regs.set(X86::RAX);
    Regs.set(X86::RBX);
    Regs.set(X86::RBP);
    Regs.set(X86::RSI);
    Regs.set(X86::RDI);
    Regs.set(X86::RDX);
    Regs.set(X86::RCX);
    Regs.set(X86::R8);
    Regs.set(X86::R9);
    Regs.set(X86::R10);
    Regs.set(X86::R11);
    Regs.set(X86::R12);
    Regs.set(X86::R13);
    Regs.set(X86::R14);
    Regs.set(X86::R15);
  }

  void removeNonScavengeableRegs(BitVector &Regs) const override {
    BitVector FP = getAliases(X86::RBP);
    FP.flip();
    Regs &= FP;
  }

  void getClassicGPRegs(BitVector &Regs) const override {
    Regs |= getAliases(X86::RAX);
    Regs |= getAliases(X86::RBX);
    Regs |= getAliases(X86::RBP);
    Regs |= getAliases(X86::RSI);
    Regs |= getAliases(X86::RDI);
    Regs |= getAliases(X86::RDX);
    Regs |= getAliases(X86::RCX);
  }

  void getRepRegs(BitVector &Regs) const override {
    Regs |= getAliases(X86::RCX);
  }

  MCPhysReg getAliasSized(MCPhysReg Reg, uint8_t Size) const override {
    Reg = getX86SubSuperRegister(Reg, Size * 8);
    assert((Reg != X86::NoRegister) && "Invalid register");
    return Reg;
  }

  bool isUpper8BitReg(MCPhysReg Reg) const override {
    switch (Reg) {
    case X86::AH:
    case X86::BH:
    case X86::CH:
    case X86::DH:
      return true;
    default:
      return false;
    }
  }

  bool cannotUseREX(const MCInst &Inst) const override {
    switch (Inst.getOpcode()) {
    case X86::MOV8mr_NOREX:
    case X86::MOV8rm_NOREX:
    case X86::MOV8rr_NOREX:
    case X86::MOVSX32rm8_NOREX:
    case X86::MOVSX32rr8_NOREX:
    case X86::MOVZX32rm8_NOREX:
    case X86::MOVZX32rr8_NOREX:
    case X86::MOV8mr:
    case X86::MOV8rm:
    case X86::MOV8rr:
    case X86::MOVSX32rm8:
    case X86::MOVSX32rr8:
    case X86::MOVZX32rm8:
    case X86::MOVZX32rr8:
    case X86::TEST8ri:
      for (const MCOperand &Operand : MCPlus::primeOperands(Inst)) {
        if (!Operand.isReg())
          continue;
        if (isUpper8BitReg(Operand.getReg()))
          return true;
      }
      [[fallthrough]];
    default:
      return false;
    }
  }

  static uint8_t getMemDataSize(const MCInst &Inst, int MemOpNo) {
    using namespace llvm::X86;
    int OpType = getOperandType(Inst.getOpcode(), MemOpNo);
    return getMemOperandSize(OpType) / 8;
  }

  /// Classifying a stack access as *not* "SIMPLE" here means we don't know how
  /// to change this instruction memory access. It will disable any changes to
  /// the stack layout, so we can't do the most aggressive form of shrink
  /// wrapping. We must do so in a way that keeps the original stack layout.
  /// Otherwise you need to adjust the offset of all instructions accessing the
  /// stack: we can't do that anymore because there is one instruction that is
  /// not simple. There are other implications as well. We have heuristics to
  /// detect when a register is callee-saved and thus eligible for shrink
  /// wrapping. If you are restoring a register using a non-simple stack access,
  /// then it is classified as NOT callee-saved, and it disables shrink wrapping
  /// for *that* register (but not for others).
  ///
  /// Classifying a stack access as "size 0" or detecting an indexed memory
  /// access (to address a vector, for example) here means we know there is a
  /// stack access, but we can't quite understand how wide is the access in
  /// bytes. This is very serious because we can't understand how memory
  /// accesses alias with each other for this function. This will essentially
  /// disable not only shrink wrapping but all frame analysis, it will fail it
  /// as "we don't understand this function and we give up on it".
  bool isStackAccess(const MCInst &Inst, bool &IsLoad, bool &IsStore,
                     bool &IsStoreFromReg, MCPhysReg &Reg, int32_t &SrcImm,
                     uint16_t &StackPtrReg, int64_t &StackOffset, uint8_t &Size,
                     bool &IsSimple, bool &IsIndexed) const override {
    // Detect simple push/pop cases first
    if (int Sz = getPushSize(Inst)) {
      IsLoad = false;
      IsStore = true;
      IsStoreFromReg = true;
      StackPtrReg = X86::RSP;
      StackOffset = -Sz;
      Size = Sz;
      IsSimple = true;
      if (Inst.getOperand(0).isImm())
        SrcImm = Inst.getOperand(0).getImm();
      else if (Inst.getOperand(0).isReg())
        Reg = Inst.getOperand(0).getReg();
      else
        IsSimple = false;

      return true;
    }
    if (int Sz = getPopSize(Inst)) {
      IsLoad = true;
      IsStore = false;
      if (Inst.getNumOperands() == 0 || !Inst.getOperand(0).isReg()) {
        IsSimple = false;
      } else {
        Reg = Inst.getOperand(0).getReg();
        IsSimple = true;
      }
      StackPtrReg = X86::RSP;
      StackOffset = 0;
      Size = Sz;
      return true;
    }

    struct InstInfo {
      // Size in bytes that Inst loads from memory.
      uint8_t DataSize;
      bool IsLoad;
      bool IsStore;
      bool StoreFromReg;
      bool Simple;
    };

    InstInfo I;
    int MemOpNo = getMemoryOperandNo(Inst);
    const MCInstrDesc &MCII = Info->get(Inst.getOpcode());
    // If it is not dealing with a memory operand, we discard it
    if (MemOpNo == -1 || MCII.isCall())
      return false;

    switch (Inst.getOpcode()) {
    default: {
      bool IsLoad = MCII.mayLoad();
      bool IsStore = MCII.mayStore();
      // Is it LEA? (deals with memory but is not loading nor storing)
      if (!IsLoad && !IsStore) {
        I = {0, IsLoad, IsStore, false, false};
        break;
      }
      uint8_t Sz = getMemDataSize(Inst, MemOpNo);
      I = {Sz, IsLoad, IsStore, false, false};
      break;
    }
    // Report simple stack accesses
    case X86::MOV8rm: I = {1, true, false, false, true}; break;
    case X86::MOV16rm: I = {2, true, false, false, true}; break;
    case X86::MOV32rm: I = {4, true, false, false, true}; break;
    case X86::MOV64rm: I = {8, true, false, false, true}; break;
    case X86::MOV8mr: I = {1, false, true, true, true};  break;
    case X86::MOV16mr: I = {2, false, true, true, true};  break;
    case X86::MOV32mr: I = {4, false, true, true, true};  break;
    case X86::MOV64mr: I = {8, false, true, true, true};  break;
    case X86::MOV8mi: I = {1, false, true, false, true}; break;
    case X86::MOV16mi: I = {2, false, true, false, true}; break;
    case X86::MOV32mi: I = {4, false, true, false, true}; break;
    } // end switch (Inst.getOpcode())

    std::optional<X86MemOperand> MO = evaluateX86MemoryOperand(Inst);
    if (!MO) {
      LLVM_DEBUG(dbgs() << "Evaluate failed on ");
      LLVM_DEBUG(Inst.dump());
      return false;
    }

    // Make sure it's a stack access
    if (MO->BaseRegNum != X86::RBP && MO->BaseRegNum != X86::RSP)
      return false;

    IsLoad = I.IsLoad;
    IsStore = I.IsStore;
    IsStoreFromReg = I.StoreFromReg;
    Size = I.DataSize;
    IsSimple = I.Simple;
    StackPtrReg = MO->BaseRegNum;
    StackOffset = MO->DispImm;
    IsIndexed =
        MO->IndexRegNum != X86::NoRegister || MO->SegRegNum != X86::NoRegister;

    if (!I.Simple)
      return true;

    // Retrieve related register in simple MOV from/to stack operations.
    unsigned MemOpOffset = static_cast<unsigned>(MemOpNo);
    if (I.IsLoad) {
      MCOperand RegOpnd = Inst.getOperand(0);
      assert(RegOpnd.isReg() && "unexpected destination operand");
      Reg = RegOpnd.getReg();
    } else if (I.IsStore) {
      MCOperand SrcOpnd =
          Inst.getOperand(MemOpOffset + X86::AddrSegmentReg + 1);
      if (I.StoreFromReg) {
        assert(SrcOpnd.isReg() && "unexpected source operand");
        Reg = SrcOpnd.getReg();
      } else {
        assert(SrcOpnd.isImm() && "unexpected source operand");
        SrcImm = SrcOpnd.getImm();
      }
    }

    return true;
  }

  void changeToPushOrPop(MCInst &Inst) const override {
    assert(!isPush(Inst) && !isPop(Inst));

    struct InstInfo {
      // Size in bytes that Inst loads from memory.
      uint8_t DataSize;
      bool IsLoad;
      bool StoreFromReg;
    };

    InstInfo I;
    switch (Inst.getOpcode()) {
    default: {
      llvm_unreachable("Unhandled opcode");
      return;
    }
    case X86::MOV16rm: I = {2, true, false}; break;
    case X86::MOV32rm: I = {4, true, false}; break;
    case X86::MOV64rm: I = {8, true, false}; break;
    case X86::MOV16mr: I = {2, false, true};  break;
    case X86::MOV32mr: I = {4, false, true};  break;
    case X86::MOV64mr: I = {8, false, true};  break;
    case X86::MOV16mi: I = {2, false, false}; break;
    case X86::MOV32mi: I = {4, false, false}; break;
    } // end switch (Inst.getOpcode())

    std::optional<X86MemOperand> MO = evaluateX86MemoryOperand(Inst);
    if (!MO) {
      llvm_unreachable("Evaluate failed");
      return;
    }
    // Make sure it's a stack access
    if (MO->BaseRegNum != X86::RBP && MO->BaseRegNum != X86::RSP) {
      llvm_unreachable("Not a stack access");
      return;
    }

    unsigned MemOpOffset = getMemoryOperandNo(Inst);
    unsigned NewOpcode = 0;
    if (I.IsLoad) {
      switch (I.DataSize) {
      case 2: NewOpcode = X86::POP16r; break;
      case 4: NewOpcode = X86::POP32r; break;
      case 8: NewOpcode = X86::POP64r; break;
      default:
        llvm_unreachable("Unexpected size");
      }
      unsigned RegOpndNum = Inst.getOperand(0).getReg();
      Inst.clear();
      Inst.setOpcode(NewOpcode);
      Inst.addOperand(MCOperand::createReg(RegOpndNum));
    } else {
      MCOperand SrcOpnd =
          Inst.getOperand(MemOpOffset + X86::AddrSegmentReg + 1);
      if (I.StoreFromReg) {
        switch (I.DataSize) {
        case 2: NewOpcode = X86::PUSH16r; break;
        case 4: NewOpcode = X86::PUSH32r; break;
        case 8: NewOpcode = X86::PUSH64r; break;
        default:
          llvm_unreachable("Unexpected size");
        }
        assert(SrcOpnd.isReg() && "Unexpected source operand");
        unsigned RegOpndNum = SrcOpnd.getReg();
        Inst.clear();
        Inst.setOpcode(NewOpcode);
        Inst.addOperand(MCOperand::createReg(RegOpndNum));
      } else {
        switch (I.DataSize) {
        case 2: NewOpcode = X86::PUSH16i8; break;
        case 4: NewOpcode = X86::PUSH32i8; break;
        case 8: NewOpcode = X86::PUSH64i32; break;
        default:
          llvm_unreachable("Unexpected size");
        }
        assert(SrcOpnd.isImm() && "Unexpected source operand");
        int64_t SrcImm = SrcOpnd.getImm();
        Inst.clear();
        Inst.setOpcode(NewOpcode);
        Inst.addOperand(MCOperand::createImm(SrcImm));
      }
    }
  }

  bool isStackAdjustment(const MCInst &Inst) const override {
    switch (Inst.getOpcode()) {
    default:
      return false;
    case X86::SUB64ri32:
    case X86::SUB64ri8:
    case X86::ADD64ri32:
    case X86::ADD64ri8:
    case X86::LEA64r:
      break;
    }

    return any_of(defOperands(Inst), [](const MCOperand &Op) {
      return Op.isReg() && Op.getReg() == X86::RSP;
    });
  }

  bool
  evaluateStackOffsetExpr(const MCInst &Inst, int64_t &Output,
                          std::pair<MCPhysReg, int64_t> Input1,
                          std::pair<MCPhysReg, int64_t> Input2) const override {

    auto getOperandVal = [&](MCPhysReg Reg) -> ErrorOr<int64_t> {
      if (Reg == Input1.first)
        return Input1.second;
      if (Reg == Input2.first)
        return Input2.second;
      return make_error_code(errc::result_out_of_range);
    };

    switch (Inst.getOpcode()) {
    default:
      return false;

    case X86::SUB64ri32:
    case X86::SUB64ri8:
      if (!Inst.getOperand(2).isImm())
        return false;
      if (ErrorOr<int64_t> InputVal =
              getOperandVal(Inst.getOperand(1).getReg()))
        Output = *InputVal - Inst.getOperand(2).getImm();
      else
        return false;
      break;
    case X86::ADD64ri32:
    case X86::ADD64ri8:
      if (!Inst.getOperand(2).isImm())
        return false;
      if (ErrorOr<int64_t> InputVal =
              getOperandVal(Inst.getOperand(1).getReg()))
        Output = *InputVal + Inst.getOperand(2).getImm();
      else
        return false;
      break;
    case X86::ADD64i32:
      if (!Inst.getOperand(0).isImm())
        return false;
      if (ErrorOr<int64_t> InputVal = getOperandVal(X86::RAX))
        Output = *InputVal + Inst.getOperand(0).getImm();
      else
        return false;
      break;

    case X86::LEA64r: {
      std::optional<X86MemOperand> MO = evaluateX86MemoryOperand(Inst);
      if (!MO)
        return false;

      if (MO->BaseRegNum == X86::NoRegister ||
          MO->IndexRegNum != X86::NoRegister ||
          MO->SegRegNum != X86::NoRegister || MO->DispExpr)
        return false;

      if (ErrorOr<int64_t> InputVal = getOperandVal(MO->BaseRegNum))
        Output = *InputVal + MO->DispImm;
      else
        return false;

      break;
    }
    }
    return true;
  }

  bool isRegToRegMove(const MCInst &Inst, MCPhysReg &From,
                      MCPhysReg &To) const override {
    switch (Inst.getOpcode()) {
    default:
      return false;
    case X86::LEAVE:
    case X86::LEAVE64:
      To = getStackPointer();
      From = getFramePointer();
      return true;
    case X86::MOV64rr:
      To = Inst.getOperand(0).getReg();
      From = Inst.getOperand(1).getReg();
      return true;
    }
  }

  MCPhysReg getStackPointer() const override { return X86::RSP; }
  MCPhysReg getFramePointer() const override { return X86::RBP; }
  MCPhysReg getFlagsReg() const override { return X86::EFLAGS; }

  bool escapesVariable(const MCInst &Inst,
                       bool HasFramePointer) const override {
    int MemOpNo = getMemoryOperandNo(Inst);
    const MCInstrDesc &MCII = Info->get(Inst.getOpcode());
    const unsigned NumDefs = MCII.getNumDefs();
    static BitVector SPBPAliases(BitVector(getAliases(X86::RSP)) |=
                                 getAliases(X86::RBP));
    static BitVector SPAliases(getAliases(X86::RSP));

    // FIXME: PUSH can be technically a leak, but let's ignore this for now
    // because a lot of harmless prologue code will spill SP to the stack.
    // Unless push is clearly pushing an object address to the stack as
    // demonstrated by having a MemOp.
    bool IsPush = isPush(Inst);
    if (IsPush && MemOpNo == -1)
      return false;

    // We use this to detect LEA (has memop but does not access mem)
    bool AccessMem = MCII.mayLoad() || MCII.mayStore();
    bool DoesLeak = false;
    for (int I = 0, E = MCPlus::getNumPrimeOperands(Inst); I != E; ++I) {
      // Ignore if SP/BP is used to dereference memory -- that's fine
      if (MemOpNo != -1 && !IsPush && AccessMem && I >= MemOpNo &&
          I <= MemOpNo + 5)
        continue;
      // Ignore if someone is writing to SP/BP
      if (I < static_cast<int>(NumDefs))
        continue;

      const MCOperand &Operand = Inst.getOperand(I);
      if (HasFramePointer && Operand.isReg() && SPBPAliases[Operand.getReg()]) {
        DoesLeak = true;
        break;
      }
      if (!HasFramePointer && Operand.isReg() && SPAliases[Operand.getReg()]) {
        DoesLeak = true;
        break;
      }
    }

    // If potential leak, check if it is not just writing to itself/sp/bp
    if (DoesLeak) {
      DoesLeak = !any_of(defOperands(Inst), [&](const MCOperand &Operand) {
        assert(Operand.isReg());
        MCPhysReg Reg = Operand.getReg();
        return HasFramePointer ? SPBPAliases[Reg] : SPAliases[Reg];
      });
    }
    return DoesLeak;
  }

  bool addToImm(MCInst &Inst, int64_t &Amt, MCContext *Ctx) const override {
    unsigned ImmOpNo = -1U;
    int MemOpNo = getMemoryOperandNo(Inst);
    if (MemOpNo != -1)
      ImmOpNo = MemOpNo + X86::AddrDisp;
    else
      for (unsigned Index = 0; Index < MCPlus::getNumPrimeOperands(Inst);
           ++Index)
        if (Inst.getOperand(Index).isImm())
          ImmOpNo = Index;
    if (ImmOpNo == -1U)
      return false;

    MCOperand &Operand = Inst.getOperand(ImmOpNo);
    Amt += Operand.getImm();
    Operand.setImm(Amt);
    // Check for the need for relaxation
    if (int64_t(Amt) == int64_t(int8_t(Amt)))
      return true;

    // Relax instruction
    switch (Inst.getOpcode()) {
    case X86::SUB64ri8:
      Inst.setOpcode(X86::SUB64ri32);
      break;
    case X86::ADD64ri8:
      Inst.setOpcode(X86::ADD64ri32);
      break;
    default:
      // No need for relaxation
      break;
    }
    return true;
  }

  /// TODO: this implementation currently works for the most common opcodes that
  /// load from memory. It can be extended to work with memory store opcodes as
  /// well as more memory load opcodes.
  bool replaceMemOperandWithImm(MCInst &Inst, StringRef ConstantData,
                                uint64_t Offset) const override {
    enum CheckSignExt : uint8_t {
      NOCHECK = 0,
      CHECK8,
      CHECK32,
    };

    using CheckList = std::vector<std::pair<CheckSignExt, unsigned>>;
    struct InstInfo {
      // Size in bytes that Inst loads from memory.
      uint8_t DataSize;

      // True when the target operand has to be duplicated because the opcode
      // expects a LHS operand.
      bool HasLHS;

      // List of checks and corresponding opcodes to be used. We try to use the
      // smallest possible immediate value when various sizes are available,
      // hence we may need to check whether a larger constant fits in a smaller
      // immediate.
      CheckList Checks;
    };

    InstInfo I;

    switch (Inst.getOpcode()) {
    default: {
      switch (getPopSize(Inst)) {
      case 2:            I = {2, false, {{NOCHECK, X86::MOV16ri}}};  break;
      case 4:            I = {4, false, {{NOCHECK, X86::MOV32ri}}};  break;
      case 8:            I = {8, false, {{CHECK32, X86::MOV64ri32},
                                         {NOCHECK, X86::MOV64rm}}};  break;
      default:           return false;
      }
      break;
    }

    // MOV
    case X86::MOV8rm:      I = {1, false, {{NOCHECK, X86::MOV8ri}}};   break;
    case X86::MOV16rm:     I = {2, false, {{NOCHECK, X86::MOV16ri}}};  break;
    case X86::MOV32rm:     I = {4, false, {{NOCHECK, X86::MOV32ri}}};  break;
    case X86::MOV64rm:     I = {8, false, {{CHECK32, X86::MOV64ri32},
                                           {NOCHECK, X86::MOV64rm}}};  break;

    // MOVZX
    case X86::MOVZX16rm8:  I = {1, false, {{NOCHECK, X86::MOV16ri}}};  break;
    case X86::MOVZX32rm8:  I = {1, false, {{NOCHECK, X86::MOV32ri}}};  break;
    case X86::MOVZX32rm16: I = {2, false, {{NOCHECK, X86::MOV32ri}}};  break;

    // CMP
    case X86::CMP8rm:      I = {1, false, {{NOCHECK, X86::CMP8ri}}};   break;
    case X86::CMP16rm:     I = {2, false, {{CHECK8,  X86::CMP16ri8},
                                           {NOCHECK, X86::CMP16ri}}};  break;
    case X86::CMP32rm:     I = {4, false, {{CHECK8,  X86::CMP32ri8},
                                           {NOCHECK, X86::CMP32ri}}};  break;
    case X86::CMP64rm:     I = {8, false, {{CHECK8,  X86::CMP64ri8},
                                           {CHECK32, X86::CMP64ri32},
                                           {NOCHECK, X86::CMP64rm}}};  break;

    // TEST
    case X86::TEST8mr:     I = {1, false, {{NOCHECK, X86::TEST8ri}}};  break;
    case X86::TEST16mr:    I = {2, false, {{NOCHECK, X86::TEST16ri}}}; break;
    case X86::TEST32mr:    I = {4, false, {{NOCHECK, X86::TEST32ri}}}; break;
    case X86::TEST64mr:    I = {8, false, {{CHECK32, X86::TEST64ri32},
                                           {NOCHECK, X86::TEST64mr}}}; break;

    // ADD
    case X86::ADD8rm:      I = {1, true,  {{NOCHECK, X86::ADD8ri}}};   break;
    case X86::ADD16rm:     I = {2, true,  {{CHECK8,  X86::ADD16ri8},
                                           {NOCHECK, X86::ADD16ri}}};  break;
    case X86::ADD32rm:     I = {4, true,  {{CHECK8,  X86::ADD32ri8},
                                           {NOCHECK, X86::ADD32ri}}};  break;
    case X86::ADD64rm:     I = {8, true,  {{CHECK8,  X86::ADD64ri8},
                                           {CHECK32, X86::ADD64ri32},
                                           {NOCHECK, X86::ADD64rm}}};  break;

    // SUB
    case X86::SUB8rm:      I = {1, true,  {{NOCHECK, X86::SUB8ri}}};   break;
    case X86::SUB16rm:     I = {2, true,  {{CHECK8,  X86::SUB16ri8},
                                           {NOCHECK, X86::SUB16ri}}};  break;
    case X86::SUB32rm:     I = {4, true,  {{CHECK8,  X86::SUB32ri8},
                                           {NOCHECK, X86::SUB32ri}}};  break;
    case X86::SUB64rm:     I = {8, true,  {{CHECK8,  X86::SUB64ri8},
                                           {CHECK32, X86::SUB64ri32},
                                           {NOCHECK, X86::SUB64rm}}};  break;

    // AND
    case X86::AND8rm:      I = {1, true,  {{NOCHECK, X86::AND8ri}}};   break;
    case X86::AND16rm:     I = {2, true,  {{CHECK8,  X86::AND16ri8},
                                           {NOCHECK, X86::AND16ri}}};  break;
    case X86::AND32rm:     I = {4, true,  {{CHECK8,  X86::AND32ri8},
                                           {NOCHECK, X86::AND32ri}}};  break;
    case X86::AND64rm:     I = {8, true,  {{CHECK8,  X86::AND64ri8},
                                           {CHECK32, X86::AND64ri32},
                                           {NOCHECK, X86::AND64rm}}};  break;

    // OR
    case X86::OR8rm:       I = {1, true,  {{NOCHECK, X86::OR8ri}}};    break;
    case X86::OR16rm:      I = {2, true,  {{CHECK8,  X86::OR16ri8},
                                           {NOCHECK, X86::OR16ri}}};   break;
    case X86::OR32rm:      I = {4, true,  {{CHECK8,  X86::OR32ri8},
                                           {NOCHECK, X86::OR32ri}}};   break;
    case X86::OR64rm:      I = {8, true,  {{CHECK8,  X86::OR64ri8},
                                           {CHECK32, X86::OR64ri32},
                                           {NOCHECK, X86::OR64rm}}};   break;

    // XOR
    case X86::XOR8rm:      I = {1, true,  {{NOCHECK, X86::XOR8ri}}};   break;
    case X86::XOR16rm:     I = {2, true,  {{CHECK8,  X86::XOR16ri8},
                                           {NOCHECK, X86::XOR16ri}}};  break;
    case X86::XOR32rm:     I = {4, true,  {{CHECK8,  X86::XOR32ri8},
                                           {NOCHECK, X86::XOR32ri}}};  break;
    case X86::XOR64rm:     I = {8, true,  {{CHECK8,  X86::XOR64ri8},
                                           {CHECK32, X86::XOR64ri32},
                                           {NOCHECK, X86::XOR64rm}}};  break;
    }

    // Compute the immediate value.
    assert(Offset + I.DataSize <= ConstantData.size() &&
           "invalid offset for given constant data");
    int64_t ImmVal =
        DataExtractor(ConstantData, true).getSigned(&Offset, I.DataSize);

    // Compute the new opcode.
    unsigned NewOpcode = 0;
    for (const std::pair<CheckSignExt, unsigned> &Check : I.Checks) {
      NewOpcode = Check.second;
      if (Check.first == NOCHECK)
        break;
      if (Check.first == CHECK8 && isInt<8>(ImmVal))
        break;
      if (Check.first == CHECK32 && isInt<32>(ImmVal))
        break;
    }
    if (NewOpcode == Inst.getOpcode())
      return false;

    // Modify the instruction.
    MCOperand ImmOp = MCOperand::createImm(ImmVal);
    uint32_t TargetOpNum = 0;
    // Test instruction does not follow the regular pattern of putting the
    // memory reference of a load (5 MCOperands) last in the list of operands.
    // Since it is not modifying the register operand, it is not treated as
    // a destination operand and it is not the first operand as it is in the
    // other instructions we treat here.
    if (NewOpcode == X86::TEST8ri || NewOpcode == X86::TEST16ri ||
        NewOpcode == X86::TEST32ri || NewOpcode == X86::TEST64ri32)
      TargetOpNum = getMemoryOperandNo(Inst) + X86::AddrNumOperands;

    MCOperand TargetOp = Inst.getOperand(TargetOpNum);
    Inst.clear();
    Inst.setOpcode(NewOpcode);
    Inst.addOperand(TargetOp);
    if (I.HasLHS)
      Inst.addOperand(TargetOp);
    Inst.addOperand(ImmOp);

    return true;
  }

  /// TODO: this implementation currently works for the most common opcodes that
  /// load from memory. It can be extended to work with memory store opcodes as
  /// well as more memory load opcodes.
  bool replaceMemOperandWithReg(MCInst &Inst, MCPhysReg RegNum) const override {
    unsigned NewOpcode;

    switch (Inst.getOpcode()) {
    default: {
      switch (getPopSize(Inst)) {
      case 2:            NewOpcode = X86::MOV16rr; break;
      case 4:            NewOpcode = X86::MOV32rr; break;
      case 8:            NewOpcode = X86::MOV64rr; break;
      default:           return false;
      }
      break;
    }

    // MOV
    case X86::MOV8rm:      NewOpcode = X86::MOV8rr;   break;
    case X86::MOV16rm:     NewOpcode = X86::MOV16rr;  break;
    case X86::MOV32rm:     NewOpcode = X86::MOV32rr;  break;
    case X86::MOV64rm:     NewOpcode = X86::MOV64rr;  break;
    }

    // Modify the instruction.
    MCOperand RegOp = MCOperand::createReg(RegNum);
    MCOperand TargetOp = Inst.getOperand(0);
    Inst.clear();
    Inst.setOpcode(NewOpcode);
    Inst.addOperand(TargetOp);
    Inst.addOperand(RegOp);

    return true;
  }

  bool isRedundantMove(const MCInst &Inst) const override {
    switch (Inst.getOpcode()) {
    default:
      return false;

    // MOV
    case X86::MOV8rr:
    case X86::MOV16rr:
    case X86::MOV32rr:
    case X86::MOV64rr:
      break;
    }

    assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg());
    return Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg();
  }

  bool requiresAlignedAddress(const MCInst &Inst) const override {
    const MCInstrDesc &Desc = Info->get(Inst.getOpcode());
    for (unsigned int I = 0; I < Desc.getNumOperands(); ++I) {
      const MCOperandInfo &Op = Desc.operands()[I];
      if (Op.OperandType != MCOI::OPERAND_REGISTER)
        continue;
      if (Op.RegClass == X86::VR128RegClassID)
        return true;
    }
    return false;
  }

  bool convertJmpToTailCall(MCInst &Inst) override {
    if (isTailCall(Inst))
      return false;

    int NewOpcode;
    switch (Inst.getOpcode()) {
    default:
      return false;
    case X86::JMP_1:
    case X86::JMP_2:
    case X86::JMP_4:
      NewOpcode = X86::JMP_4;
      break;
    case X86::JMP16m:
    case X86::JMP32m:
    case X86::JMP64m:
      NewOpcode = X86::JMP32m;
      break;
    case X86::JMP16r:
    case X86::JMP32r:
    case X86::JMP64r:
      NewOpcode = X86::JMP32r;
      break;
    }

    Inst.setOpcode(NewOpcode);
    setTailCall(Inst);
    return true;
  }

  bool convertTailCallToJmp(MCInst &Inst) override {
    int NewOpcode;
    switch (Inst.getOpcode()) {
    default:
      return false;
    case X86::JMP_4:
      NewOpcode = X86::JMP_1;
      break;
    case X86::JMP32m:
      NewOpcode = X86::JMP64m;
      break;
    case X86::JMP32r:
      NewOpcode = X86::JMP64r;
      break;
    }

    Inst.setOpcode(NewOpcode);
    removeAnnotation(Inst, MCPlus::MCAnnotation::kTailCall);
    clearOffset(Inst);
    return true;
  }

  bool convertTailCallToCall(MCInst &Inst) override {
    int NewOpcode;
    switch (Inst.getOpcode()) {
    default:
      return false;
    case X86::JMP_4:
      NewOpcode = X86::CALL64pcrel32;
      break;
    case X86::JMP32m:
      NewOpcode = X86::CALL64m;
      break;
    case X86::JMP32r:
      NewOpcode = X86::CALL64r;
      break;
    }

    Inst.setOpcode(NewOpcode);
    removeAnnotation(Inst, MCPlus::MCAnnotation::kTailCall);
    return true;
  }

  InstructionListType createIndirectPLTCall(MCInst &&DirectCall,
                                            const MCSymbol *TargetLocation,
                                            MCContext *Ctx) override {
    assert((DirectCall.getOpcode() == X86::CALL64pcrel32 ||
            (DirectCall.getOpcode() == X86::JMP_4 && isTailCall(DirectCall))) &&
           "64-bit direct (tail) call instruction expected");

    InstructionListType Code;
    // Create a new indirect call by converting the previous direct call.
    MCInst Inst = DirectCall;
    const auto NewOpcode =
        (Inst.getOpcode() == X86::CALL64pcrel32) ? X86::CALL64m : X86::JMP32m;
    Inst.setOpcode(NewOpcode);

    // Replace the first operand and preserve auxiliary operands of
    // the instruction.
    Inst.erase(Inst.begin());
    Inst.insert(Inst.begin(),
                MCOperand::createReg(X86::NoRegister)); // AddrSegmentReg
    Inst.insert(Inst.begin(),
                MCOperand::createExpr( // Displacement
                    MCSymbolRefExpr::create(TargetLocation, *Ctx)));
    Inst.insert(Inst.begin(),
                MCOperand::createReg(X86::NoRegister)); // IndexReg
    Inst.insert(Inst.begin(),
                MCOperand::createImm(1));               // ScaleAmt
    Inst.insert(Inst.begin(),
                MCOperand::createReg(X86::RIP));        // BaseReg

    Code.emplace_back(Inst);
    return Code;
  }

  void convertIndirectCallToLoad(MCInst &Inst, MCPhysReg Reg) override {
    bool IsTailCall = isTailCall(Inst);
    if (IsTailCall)
      removeAnnotation(Inst, MCPlus::MCAnnotation::kTailCall);
    if (Inst.getOpcode() == X86::CALL64m ||
        (Inst.getOpcode() == X86::JMP32m && IsTailCall)) {
      Inst.setOpcode(X86::MOV64rm);
      Inst.insert(Inst.begin(), MCOperand::createReg(Reg));
      return;
    }
    if (Inst.getOpcode() == X86::CALL64r ||
        (Inst.getOpcode() == X86::JMP32r && IsTailCall)) {
      Inst.setOpcode(X86::MOV64rr);
      Inst.insert(Inst.begin(), MCOperand::createReg(Reg));
      return;
    }
    LLVM_DEBUG(Inst.dump());
    llvm_unreachable("not implemented");
  }

  bool shortenInstruction(MCInst &Inst,
                          const MCSubtargetInfo &STI) const override {
    unsigned OldOpcode = Inst.getOpcode();
    unsigned NewOpcode = OldOpcode;

    int MemOpNo = getMemoryOperandNo(Inst);

    // Check and remove redundant Address-Size override prefix.
    if (opts::X86StripRedundantAddressSize) {
      uint64_t TSFlags = Info->get(OldOpcode).TSFlags;
      unsigned Flags = Inst.getFlags();

      if (!X86_MC::needsAddressSizeOverride(Inst, STI, MemOpNo, TSFlags) &&
          Flags & X86::IP_HAS_AD_SIZE)
        Inst.setFlags(Flags ^ X86::IP_HAS_AD_SIZE);
    }

    // Check and remove EIZ/RIZ. These cases represent ambiguous cases where
    // SIB byte is present, but no index is used and modrm alone should have
    // been enough. Converting to NoRegister effectively removes the SIB byte.
    if (MemOpNo >= 0) {
      MCOperand &IndexOp =
          Inst.getOperand(static_cast<unsigned>(MemOpNo) + X86::AddrIndexReg);
      if (IndexOp.getReg() == X86::EIZ || IndexOp.getReg() == X86::RIZ)
        IndexOp = MCOperand::createReg(X86::NoRegister);
    }

    if (isBranch(Inst)) {
      NewOpcode = getShortBranchOpcode(OldOpcode);
    } else if (OldOpcode == X86::MOV64ri) {
      if (Inst.getOperand(MCPlus::getNumPrimeOperands(Inst) - 1).isImm()) {
        const int64_t Imm =
            Inst.getOperand(MCPlus::getNumPrimeOperands(Inst) - 1).getImm();
        if (int64_t(Imm) == int64_t(int32_t(Imm)))
          NewOpcode = X86::MOV64ri32;
      }
    } else {
      // If it's arithmetic instruction check if signed operand fits in 1 byte.
      const unsigned ShortOpcode = X86::getOpcodeForShortImmediateForm(OldOpcode);
      if (ShortOpcode != OldOpcode &&
          Inst.getOperand(MCPlus::getNumPrimeOperands(Inst) - 1).isImm()) {
        int64_t Imm =
            Inst.getOperand(MCPlus::getNumPrimeOperands(Inst) - 1).getImm();
        if (int64_t(Imm) == int64_t(int8_t(Imm)))
          NewOpcode = ShortOpcode;
      }
    }

    if (NewOpcode == OldOpcode)
      return false;

    Inst.setOpcode(NewOpcode);
    return true;
  }

  bool
  convertMoveToConditionalMove(MCInst &Inst, unsigned CC, bool AllowStackMemOp,
                               bool AllowBasePtrStackMemOp) const override {
    // - Register-register moves are OK
    // - Stores are filtered out by opcode (no store CMOV)
    // - Non-stack loads are prohibited (generally unsafe)
    // - Stack loads are OK if AllowStackMemOp is true
    // - Stack loads with RBP are OK if AllowBasePtrStackMemOp is true
    if (mayLoad(Inst)) {
      // If stack memory operands are not allowed, no loads are allowed
      if (!AllowStackMemOp)
        return false;

      // If stack memory operands are allowed, check if it's a load from stack
      bool IsLoad, IsStore, IsStoreFromReg, IsSimple, IsIndexed;
      MCPhysReg Reg;
      int32_t SrcImm;
      uint16_t StackPtrReg;
      int64_t StackOffset;
      uint8_t Size;
      bool IsStackAccess =
          isStackAccess(Inst, IsLoad, IsStore, IsStoreFromReg, Reg, SrcImm,
                        StackPtrReg, StackOffset, Size, IsSimple, IsIndexed);
      // Prohibit non-stack-based loads
      if (!IsStackAccess)
        return false;
      // If stack memory operands are allowed, check if it's RBP-based
      if (!AllowBasePtrStackMemOp &&
          RegInfo->isSubRegisterEq(X86::RBP, StackPtrReg))
        return false;
    }

    unsigned NewOpcode = 0;
    switch (Inst.getOpcode()) {
    case X86::MOV16rr:
      NewOpcode = X86::CMOV16rr;
      break;
    case X86::MOV16rm:
      NewOpcode = X86::CMOV16rm;
      break;
    case X86::MOV32rr:
      NewOpcode = X86::CMOV32rr;
      break;
    case X86::MOV32rm:
      NewOpcode = X86::CMOV32rm;
      break;
    case X86::MOV64rr:
      NewOpcode = X86::CMOV64rr;
      break;
    case X86::MOV64rm:
      NewOpcode = X86::CMOV64rm;
      break;
    default:
      return false;
    }
    Inst.setOpcode(NewOpcode);
    // Insert CC at the end of prime operands, before annotations
    Inst.insert(Inst.begin() + MCPlus::getNumPrimeOperands(Inst),
                MCOperand::createImm(CC));
    // CMOV is a 3-operand MCInst, so duplicate the destination as src1
    Inst.insert(Inst.begin(), Inst.getOperand(0));
    return true;
  }

  bool lowerTailCall(MCInst &Inst) override {
    if (Inst.getOpcode() == X86::JMP_4 && isTailCall(Inst)) {
      Inst.setOpcode(X86::JMP_1);
      removeAnnotation(Inst, MCPlus::MCAnnotation::kTailCall);
      return true;
    }
    return false;
  }

  const MCSymbol *getTargetSymbol(const MCInst &Inst,
                                  unsigned OpNum = 0) const override {
    if (OpNum >= MCPlus::getNumPrimeOperands(Inst))
      return nullptr;

    const MCOperand &Op = Inst.getOperand(OpNum);
    if (!Op.isExpr())
      return nullptr;

    return MCPlusBuilder::getTargetSymbol(Op.getExpr());
  }

  bool analyzeBranch(InstructionIterator Begin, InstructionIterator End,
                     const MCSymbol *&TBB, const MCSymbol *&FBB,
                     MCInst *&CondBranch,
                     MCInst *&UncondBranch) const override {
    auto I = End;

    // Bottom-up analysis
    while (I != Begin) {
      --I;

      // Ignore nops and CFIs
      if (isPseudo(*I))
        continue;

      // Stop when we find the first non-terminator
      if (!isTerminator(*I))
        break;

      if (!isBranch(*I))
        break;

      // Handle unconditional branches.
      if ((I->getOpcode() == X86::JMP_1 || I->getOpcode() == X86::JMP_2 ||
           I->getOpcode() == X86::JMP_4) &&
          !isTailCall(*I)) {
        // If any code was seen after this unconditional branch, we've seen
        // unreachable code. Ignore them.
        CondBranch = nullptr;
        UncondBranch = &*I;
        const MCSymbol *Sym = getTargetSymbol(*I);
        assert(Sym != nullptr &&
               "Couldn't extract BB symbol from jump operand");
        TBB = Sym;
        continue;
      }

      // Ignore indirect branches
      if (getCondCode(*I) == X86::COND_INVALID)
        return false;

      if (CondBranch == nullptr) {
        const MCSymbol *TargetBB = getTargetSymbol(*I);
        if (TargetBB == nullptr) {
          // Unrecognized branch target
          return false;
        }
        FBB = TBB;
        TBB = TargetBB;
        CondBranch = &*I;
        continue;
      }

      llvm_unreachable("multiple conditional branches in one BB");
    }
    return true;
  }

  /// Analyzes PIC-style jump table code template and return identified
  /// IndirectBranchType, MemLocInstr (all cases) and FixedEntryLoadInstr
  /// (POSSIBLE_PIC_FIXED_BRANCH case).
  template <typename Itr>
  std::tuple<IndirectBranchType, MCInst *, MCInst *>
  analyzePICJumpTable(Itr II, Itr IE, MCPhysReg R1, MCPhysReg R2) const {
    // Analyze PIC-style jump table code template:
    //
    //    lea PIC_JUMP_TABLE(%rip), {%r1|%r2}     <- MemLocInstr
    //    mov ({%r1|%r2}, %index, 4), {%r2|%r1}
    //    add %r2, %r1
    //    jmp *%r1
    //
    // or a fixed indirect jump template:
    //
    //    movslq En(%rip), {%r2|%r1}              <- FixedEntryLoadInstr
    //    lea PIC_JUMP_TABLE(%rip), {%r1|%r2}     <- MemLocInstr
    //    add %r2, %r1
    //    jmp *%r1
    //
    // (with any irrelevant instructions in-between)
    //
    // When we call this helper we've already determined %r1 and %r2, and
    // reverse instruction iterator \p II is pointing to the ADD instruction.
    //
    // PIC jump table looks like following:
    //
    //   JT:  ----------
    //    E1:| L1 - JT  |
    //       |----------|
    //    E2:| L2 - JT  |
    //       |----------|
    //       |          |
    //          ......
    //    En:| Ln - JT  |
    //        ----------
    //
    // Where L1, L2, ..., Ln represent labels in the function.
    //
    // The actual relocations in the table will be of the form:
    //
    //   Ln - JT
    //    = (Ln - En) + (En - JT)
    //    = R_X86_64_PC32(Ln) + En - JT
    //    = R_X86_64_PC32(Ln + offsetof(En))
    //
    auto isRIPRel = [&](X86MemOperand &MO) {
      // NB: DispExpr should be set
      return MO.DispExpr != nullptr &&
             MO.BaseRegNum == RegInfo->getProgramCounter() &&
             MO.IndexRegNum == X86::NoRegister &&
             MO.SegRegNum == X86::NoRegister;
    };
    auto isIndexed = [](X86MemOperand &MO, MCPhysReg R) {
      // NB: IndexRegNum should be set.
      return MO.IndexRegNum != X86::NoRegister && MO.BaseRegNum == R &&
             MO.ScaleImm == 4 && MO.DispImm == 0 &&
             MO.SegRegNum == X86::NoRegister;
    };
    LLVM_DEBUG(dbgs() << "Checking for PIC jump table\n");
    MCInst *FirstInstr = nullptr;
    MCInst *SecondInstr = nullptr;
    enum {
      NOMATCH = 0,
      MATCH_JUMP_TABLE,
      MATCH_FIXED_BRANCH,
    } MatchingState = NOMATCH;
    while (++II != IE) {
      MCInst &Instr = *II;
      const MCInstrDesc &InstrDesc = Info->get(Instr.getOpcode());
      if (!InstrDesc.hasDefOfPhysReg(Instr, R1, *RegInfo) &&
          !InstrDesc.hasDefOfPhysReg(Instr, R2, *RegInfo)) {
        // Ignore instructions that don't affect R1, R2 registers.
        continue;
      }
      const bool IsMOVSXInstr = isMOVSX64rm32(Instr);
      const bool IsLEAInstr = isLEA64r(Instr);
      if (MatchingState == NOMATCH) {
        if (IsMOVSXInstr)
          MatchingState = MATCH_JUMP_TABLE;
        else if (IsLEAInstr)
          MatchingState = MATCH_FIXED_BRANCH;
        else
          break;

        // Check if the first instruction is setting %r1 or %r2. In canonical
        // form lea sets %r1 and mov sets %r2. If it's the opposite - rename so
        // we have to only check a single form.
        unsigned DestReg = Instr.getOperand(0).getReg();
        MCPhysReg &ExpectReg = MatchingState == MATCH_JUMP_TABLE ? R2 : R1;
        if (DestReg != ExpectReg)
          std::swap(R1, R2);
        if (DestReg != ExpectReg)
          break;

        // Verify operands
        std::optional<X86MemOperand> MO = evaluateX86MemoryOperand(Instr);
        if (!MO)
          break;
        if ((MatchingState == MATCH_JUMP_TABLE && isIndexed(*MO, R1)) ||
            (MatchingState == MATCH_FIXED_BRANCH && isRIPRel(*MO)))
          FirstInstr = &Instr;
        else
          break;
      } else {
        unsigned ExpectReg = MatchingState == MATCH_JUMP_TABLE ? R1 : R2;
        if (!InstrDesc.hasDefOfPhysReg(Instr, ExpectReg, *RegInfo))
          continue;
        if ((MatchingState == MATCH_JUMP_TABLE && !IsLEAInstr) ||
            (MatchingState == MATCH_FIXED_BRANCH && !IsMOVSXInstr))
          break;
        if (Instr.getOperand(0).getReg() != ExpectReg)
          break;

        // Verify operands.
        std::optional<X86MemOperand> MO = evaluateX86MemoryOperand(Instr);
        if (!MO)
          break;
        if (!isRIPRel(*MO))
          break;
        SecondInstr = &Instr;
        break;
      }
    }

    if (!SecondInstr)
      return std::make_tuple(IndirectBranchType::UNKNOWN, nullptr, nullptr);

    if (MatchingState == MATCH_FIXED_BRANCH) {
      LLVM_DEBUG(dbgs() << "checking potential fixed indirect branch\n");
      return std::make_tuple(IndirectBranchType::POSSIBLE_PIC_FIXED_BRANCH,
                             FirstInstr, SecondInstr);
    }
    LLVM_DEBUG(dbgs() << "checking potential PIC jump table\n");
    return std::make_tuple(IndirectBranchType::POSSIBLE_PIC_JUMP_TABLE,
                           SecondInstr, nullptr);
  }

  IndirectBranchType
  analyzeIndirectBranch(MCInst &Instruction, InstructionIterator Begin,
                        InstructionIterator End, const unsigned PtrSize,
                        MCInst *&MemLocInstrOut, unsigned &BaseRegNumOut,
                        unsigned &IndexRegNumOut, int64_t &DispValueOut,
                        const MCExpr *&DispExprOut, MCInst *&PCRelBaseOut,
                        MCInst *&FixedEntryLoadInst) const override {
    // Try to find a (base) memory location from where the address for
    // the indirect branch is loaded. For X86-64 the memory will be specified
    // in the following format:
    //
    //   {%rip}/{%basereg} + Imm + IndexReg * Scale
    //
    // We are interested in the cases where Scale == sizeof(uintptr_t) and
    // the contents of the memory are presumably an array of pointers to code.
    //
    // Normal jump table:
    //
    //    jmp *(JUMP_TABLE, %index, Scale)        <- MemLocInstr
    //
    //    or
    //
    //    mov (JUMP_TABLE, %index, Scale), %r1    <- MemLocInstr
    //    ...
    //    jmp %r1
    //
    // We handle PIC-style jump tables separately.
    //
    MemLocInstrOut = nullptr;
    BaseRegNumOut = X86::NoRegister;
    IndexRegNumOut = X86::NoRegister;
    DispValueOut = 0;
    DispExprOut = nullptr;
    FixedEntryLoadInst = nullptr;

    std::reverse_iterator<InstructionIterator> II(End);
    std::reverse_iterator<InstructionIterator> IE(Begin);

    IndirectBranchType Type = IndirectBranchType::UNKNOWN;

    // An instruction referencing memory used by jump instruction (directly or
    // via register). This location could be an array of function pointers
    // in case of indirect tail call, or a jump table.
    MCInst *MemLocInstr = nullptr;

    if (MCPlus::getNumPrimeOperands(Instruction) == 1) {
      // If the indirect jump is on register - try to detect if the
      // register value is loaded from a memory location.
      assert(Instruction.getOperand(0).isReg() && "register operand expected");
      const unsigned R1 = Instruction.getOperand(0).getReg();
      // Check if one of the previous instructions defines the jump-on register.
      for (auto PrevII = II; PrevII != IE; ++PrevII) {
        MCInst &PrevInstr = *PrevII;
        const MCInstrDesc &PrevInstrDesc = Info->get(PrevInstr.getOpcode());

        if (!PrevInstrDesc.hasDefOfPhysReg(PrevInstr, R1, *RegInfo))
          continue;

        if (isMoveMem2Reg(PrevInstr)) {
          MemLocInstr = &PrevInstr;
          break;
        }
        if (isADD64rr(PrevInstr)) {
          unsigned R2 = PrevInstr.getOperand(2).getReg();
          if (R1 == R2)
            return IndirectBranchType::UNKNOWN;
          std::tie(Type, MemLocInstr, FixedEntryLoadInst) =
              analyzePICJumpTable(PrevII, IE, R1, R2);
          break;
        }
        return IndirectBranchType::UNKNOWN;
      }
      if (!MemLocInstr) {
        // No definition seen for the register in this function so far. Could be
        // an input parameter - which means it is an external code reference.
        // It also could be that the definition happens to be in the code that
        // we haven't processed yet. Since we have to be conservative, return
        // as UNKNOWN case.
        return IndirectBranchType::UNKNOWN;
      }
    } else {
      MemLocInstr = &Instruction;
    }

    const MCRegister RIPRegister = RegInfo->getProgramCounter();

    // Analyze the memory location.
    std::optional<X86MemOperand> MO = evaluateX86MemoryOperand(*MemLocInstr);
    if (!MO)
      return IndirectBranchType::UNKNOWN;

    BaseRegNumOut = MO->BaseRegNum;
    IndexRegNumOut = MO->IndexRegNum;
    DispValueOut = MO->DispImm;
    DispExprOut = MO->DispExpr;

    if ((MO->BaseRegNum != X86::NoRegister && MO->BaseRegNum != RIPRegister) ||
        MO->SegRegNum != X86::NoRegister)
      return IndirectBranchType::UNKNOWN;

    if (MemLocInstr == &Instruction &&
        (!MO->ScaleImm || MO->IndexRegNum == X86::NoRegister)) {
      MemLocInstrOut = MemLocInstr;
      return IndirectBranchType::POSSIBLE_FIXED_BRANCH;
    }

    switch (Type) {
    case IndirectBranchType::POSSIBLE_PIC_JUMP_TABLE:
      if (MO->ScaleImm != 1 || MO->BaseRegNum != RIPRegister)
        return IndirectBranchType::UNKNOWN;
      break;
    case IndirectBranchType::POSSIBLE_PIC_FIXED_BRANCH:
      break;
    default:
      if (MO->ScaleImm != PtrSize)
        return IndirectBranchType::UNKNOWN;
    }

    MemLocInstrOut = MemLocInstr;

    return Type;
  }

  /// Analyze a callsite to see if it could be a virtual method call.  This only
  /// checks to see if the overall pattern is satisfied, it does not guarantee
  /// that the callsite is a true virtual method call.
  /// The format of virtual method calls that are recognized is one of the
  /// following:
  ///
  ///  Form 1: (found in debug code)
  ///    add METHOD_OFFSET, %VtableReg
  ///    mov (%VtableReg), %MethodReg
  ///    ...
  ///    call or jmp *%MethodReg
  ///
  ///  Form 2:
  ///    mov METHOD_OFFSET(%VtableReg), %MethodReg
  ///    ...
  ///    call or jmp *%MethodReg
  ///
  ///  Form 3:
  ///    ...
  ///    call or jmp *METHOD_OFFSET(%VtableReg)
  ///
  bool analyzeVirtualMethodCall(InstructionIterator ForwardBegin,
                                InstructionIterator ForwardEnd,
                                std::vector<MCInst *> &MethodFetchInsns,
                                unsigned &VtableRegNum, unsigned &MethodRegNum,
                                uint64_t &MethodOffset) const override {
    VtableRegNum = X86::NoRegister;
    MethodRegNum = X86::NoRegister;
    MethodOffset = 0;

    std::reverse_iterator<InstructionIterator> Itr(ForwardEnd);
    std::reverse_iterator<InstructionIterator> End(ForwardBegin);

    MCInst &CallInst = *Itr++;
    assert(isIndirectBranch(CallInst) || isCall(CallInst));

    // The call can just be jmp offset(reg)
    if (std::optional<X86MemOperand> MO = evaluateX86MemoryOperand(CallInst)) {
      if (!MO->DispExpr && MO->BaseRegNum != X86::RIP &&
          MO->BaseRegNum != X86::RBP && MO->BaseRegNum != X86::NoRegister) {
        MethodRegNum = MO->BaseRegNum;
        if (MO->ScaleImm == 1 && MO->IndexRegNum == X86::NoRegister &&
            MO->SegRegNum == X86::NoRegister) {
          VtableRegNum = MethodRegNum;
          MethodOffset = MO->DispImm;
          MethodFetchInsns.push_back(&CallInst);
          return true;
        }
      }
      return false;
    }
    if (CallInst.getOperand(0).isReg())
      MethodRegNum = CallInst.getOperand(0).getReg();
    else
      return false;

    if (MethodRegNum == X86::RIP || MethodRegNum == X86::RBP) {
      VtableRegNum = X86::NoRegister;
      MethodRegNum = X86::NoRegister;
      return false;
    }

    // find load from vtable, this may or may not include the method offset
    while (Itr != End) {
      MCInst &CurInst = *Itr++;
      const MCInstrDesc &Desc = Info->get(CurInst.getOpcode());
      if (Desc.hasDefOfPhysReg(CurInst, MethodRegNum, *RegInfo)) {
        if (!mayLoad(CurInst))
          return false;
        if (std::optional<X86MemOperand> MO =
                evaluateX86MemoryOperand(CurInst)) {
          if (!MO->DispExpr && MO->ScaleImm == 1 &&
              MO->BaseRegNum != X86::RIP && MO->BaseRegNum != X86::RBP &&
              MO->BaseRegNum != X86::NoRegister &&
              MO->IndexRegNum == X86::NoRegister &&
              MO->SegRegNum == X86::NoRegister) {
            VtableRegNum = MO->BaseRegNum;
            MethodOffset = MO->DispImm;
            MethodFetchInsns.push_back(&CurInst);
            if (MethodOffset != 0)
              return true;
            break;
          }
        }
        return false;
      }
    }

    if (!VtableRegNum)
      return false;

    // look for any adds affecting the method register.
    while (Itr != End) {
      MCInst &CurInst = *Itr++;
      const MCInstrDesc &Desc = Info->get(CurInst.getOpcode());
      if (Desc.hasDefOfPhysReg(CurInst, VtableRegNum, *RegInfo)) {
        if (isADDri(CurInst)) {
          assert(!MethodOffset);
          MethodOffset = CurInst.getOperand(2).getImm();
          MethodFetchInsns.insert(MethodFetchInsns.begin(), &CurInst);
          break;
        }
      }
    }

    return true;
  }

  void createStackPointerIncrement(MCInst &Inst, int Size,
                                   bool NoFlagsClobber) const override {
    if (NoFlagsClobber) {
      Inst.setOpcode(X86::LEA64r);
      Inst.clear();
      Inst.addOperand(MCOperand::createReg(X86::RSP));
      Inst.addOperand(MCOperand::createReg(X86::RSP));        // BaseReg
      Inst.addOperand(MCOperand::createImm(1));               // ScaleAmt
      Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // IndexReg
      Inst.addOperand(MCOperand::createImm(-Size));           // Displacement
      Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // AddrSegmentReg
      return;
    }
    Inst.setOpcode(X86::SUB64ri8);
    Inst.clear();
    Inst.addOperand(MCOperand::createReg(X86::RSP));
    Inst.addOperand(MCOperand::createReg(X86::RSP));
    Inst.addOperand(MCOperand::createImm(Size));
  }

  void createStackPointerDecrement(MCInst &Inst, int Size,
                                   bool NoFlagsClobber) const override {
    if (NoFlagsClobber) {
      Inst.setOpcode(X86::LEA64r);
      Inst.clear();
      Inst.addOperand(MCOperand::createReg(X86::RSP));
      Inst.addOperand(MCOperand::createReg(X86::RSP));        // BaseReg
      Inst.addOperand(MCOperand::createImm(1));               // ScaleAmt
      Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // IndexReg
      Inst.addOperand(MCOperand::createImm(Size));            // Displacement
      Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // AddrSegmentReg
      return;
    }
    Inst.setOpcode(X86::ADD64ri8);
    Inst.clear();
    Inst.addOperand(MCOperand::createReg(X86::RSP));
    Inst.addOperand(MCOperand::createReg(X86::RSP));
    Inst.addOperand(MCOperand::createImm(Size));
  }

  void createSaveToStack(MCInst &Inst, const MCPhysReg &StackReg, int Offset,
                         const MCPhysReg &SrcReg, int Size) const override {
    unsigned NewOpcode;
    switch (Size) {
    default:
      llvm_unreachable("Invalid operand size");
      return;
    case 2:      NewOpcode = X86::MOV16mr; break;
    case 4:      NewOpcode = X86::MOV32mr; break;
    case 8:      NewOpcode = X86::MOV64mr; break;
    }
    Inst.setOpcode(NewOpcode);
    Inst.clear();
    Inst.addOperand(MCOperand::createReg(StackReg));        // BaseReg
    Inst.addOperand(MCOperand::createImm(1));               // ScaleAmt
    Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // IndexReg
    Inst.addOperand(MCOperand::createImm(Offset));          // Displacement
    Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // AddrSegmentReg
    Inst.addOperand(MCOperand::createReg(SrcReg));
  }

  void createRestoreFromStack(MCInst &Inst, const MCPhysReg &StackReg,
                              int Offset, const MCPhysReg &DstReg,
                              int Size) const override {
    return createLoad(Inst, StackReg, /*Scale=*/1, /*IndexReg=*/X86::NoRegister,
                      Offset, nullptr, /*AddrSegmentReg=*/X86::NoRegister,
                      DstReg, Size);
  }

  void createLoad(MCInst &Inst, const MCPhysReg &BaseReg, int64_t Scale,
                  const MCPhysReg &IndexReg, int64_t Offset,
                  const MCExpr *OffsetExpr, const MCPhysReg &AddrSegmentReg,
                  const MCPhysReg &DstReg, int Size) const override {
    unsigned NewOpcode;
    switch (Size) {
    default:
      llvm_unreachable("Invalid operand size");
      return;
    case 2:      NewOpcode = X86::MOV16rm; break;
    case 4:      NewOpcode = X86::MOV32rm; break;
    case 8:      NewOpcode = X86::MOV64rm; break;
    }
    Inst.setOpcode(NewOpcode);
    Inst.clear();
    Inst.addOperand(MCOperand::createReg(DstReg));
    Inst.addOperand(MCOperand::createReg(BaseReg));
    Inst.addOperand(MCOperand::createImm(Scale));
    Inst.addOperand(MCOperand::createReg(IndexReg));
    if (OffsetExpr)
      Inst.addOperand(MCOperand::createExpr(OffsetExpr)); // Displacement
    else
      Inst.addOperand(MCOperand::createImm(Offset)); // Displacement
    Inst.addOperand(MCOperand::createReg(AddrSegmentReg)); // AddrSegmentReg
  }

  InstructionListType createLoadImmediate(const MCPhysReg Dest,
                                          uint64_t Imm) const override {
    InstructionListType Insts;
    Insts.emplace_back();
    Insts.back().setOpcode(X86::MOV64ri32);
    Insts.back().clear();
    Insts.back().addOperand(MCOperand::createReg(Dest));
    Insts.back().addOperand(MCOperand::createImm(Imm));
    return Insts;
  }

  void createIJmp32Frag(SmallVectorImpl<MCInst> &Insts,
                        const MCOperand &BaseReg, const MCOperand &Scale,
                        const MCOperand &IndexReg, const MCOperand &Offset,
                        const MCOperand &TmpReg) const override {
    // The code fragment we emit here is:
    //
    //  mov32 (%base, %index, scale), %tmpreg
    //  ijmp *(%tmpreg)
    //
    MCInst IJmp;
    IJmp.setOpcode(X86::JMP64r);
    IJmp.addOperand(TmpReg);

    MCInst Load;
    Load.setOpcode(X86::MOV32rm);
    Load.addOperand(TmpReg);
    Load.addOperand(BaseReg);
    Load.addOperand(Scale);
    Load.addOperand(IndexReg);
    Load.addOperand(Offset);
    Load.addOperand(MCOperand::createReg(X86::NoRegister));

    Insts.push_back(Load);
    Insts.push_back(IJmp);
  }

  void createNoop(MCInst &Inst) const override {
    Inst.setOpcode(X86::NOOP);
    Inst.clear();
  }

  void createReturn(MCInst &Inst) const override {
    Inst.setOpcode(X86::RET64);
    Inst.clear();
  }

  InstructionListType createInlineMemcpy(bool ReturnEnd) const override {
    InstructionListType Code;
    if (ReturnEnd)
      Code.emplace_back(MCInstBuilder(X86::LEA64r)
                            .addReg(X86::RAX)
                            .addReg(X86::RDI)
                            .addImm(1)
                            .addReg(X86::RDX)
                            .addImm(0)
                            .addReg(X86::NoRegister));
    else
      Code.emplace_back(MCInstBuilder(X86::MOV64rr)
                            .addReg(X86::RAX)
                            .addReg(X86::RDI));

    Code.emplace_back(MCInstBuilder(X86::MOV32rr)
                          .addReg(X86::ECX)
                          .addReg(X86::EDX));
    Code.emplace_back(MCInstBuilder(X86::REP_MOVSB_64));

    return Code;
  }

  InstructionListType createOneByteMemcpy() const override {
    InstructionListType Code;
    Code.emplace_back(MCInstBuilder(X86::MOV8rm)
                          .addReg(X86::CL)
                          .addReg(X86::RSI)
                          .addImm(0)
                          .addReg(X86::NoRegister)
                          .addImm(0)
                          .addReg(X86::NoRegister));
    Code.emplace_back(MCInstBuilder(X86::MOV8mr)
                          .addReg(X86::RDI)
                          .addImm(0)
                          .addReg(X86::NoRegister)
                          .addImm(0)
                          .addReg(X86::NoRegister)
                          .addReg(X86::CL));
    Code.emplace_back(MCInstBuilder(X86::MOV64rr)
                          .addReg(X86::RAX)
                          .addReg(X86::RDI));
    return Code;
  }

  InstructionListType createCmpJE(MCPhysReg RegNo, int64_t Imm,
                                  const MCSymbol *Target,
                                  MCContext *Ctx) const override {
    InstructionListType Code;
    Code.emplace_back(MCInstBuilder(X86::CMP64ri8)
                          .addReg(RegNo)
                          .addImm(Imm));
    Code.emplace_back(MCInstBuilder(X86::JCC_1)
                          .addExpr(MCSymbolRefExpr::create(Target, *Ctx))
                          .addImm(X86::COND_E));
    return Code;
  }

  InstructionListType createCmpJNE(MCPhysReg RegNo, int64_t Imm,
                                   const MCSymbol *Target,
                                   MCContext *Ctx) const override {
    InstructionListType Code;
    Code.emplace_back(MCInstBuilder(X86::CMP64ri8).addReg(RegNo).addImm(Imm));
    Code.emplace_back(MCInstBuilder(X86::JCC_1)
                          .addExpr(MCSymbolRefExpr::create(Target, *Ctx))
                          .addImm(X86::COND_NE));
    return Code;
  }

  std::optional<Relocation>
  createRelocation(const MCFixup &Fixup,
                   const MCAsmBackend &MAB) const override {
    MCFixupKindInfo FKI = MAB.getFixupKindInfo(Fixup.getKind());

    assert(FKI.TargetOffset == 0 && "0-bit relocation offset expected");
    const uint64_t RelOffset = Fixup.getOffset();
    auto [RelSymbol, RelAddend] = extractFixupExpr(Fixup);

    uint32_t RelType;
    if (Fixup.isPCRel()) {
      switch (FKI.TargetSize) {
      default:
        return std::nullopt;
      case  8: RelType = ELF::R_X86_64_PC8; break;
      case 16: RelType = ELF::R_X86_64_PC16; break;
      case 32: RelType = ELF::R_X86_64_PC32; break;
      case 64: RelType = ELF::R_X86_64_PC64; break;
      }
      // Adjust PC-relative fixup offsets, which are calculated from the start
      // of the next instruction.
      RelAddend -= FKI.TargetSize / 8;
    } else {
      switch (FKI.TargetSize) {
      default:
        return std::nullopt;
      case  8: RelType = ELF::R_X86_64_8; break;
      case 16: RelType = ELF::R_X86_64_16; break;
      case 32: RelType = ELF::R_X86_64_32; break;
      case 64: RelType = ELF::R_X86_64_64; break;
      }
    }

    return Relocation({RelOffset, RelSymbol, RelType, RelAddend, 0});
  }

  bool replaceImmWithSymbolRef(MCInst &Inst, const MCSymbol *Symbol,
                               int64_t Addend, MCContext *Ctx, int64_t &Value,
                               uint32_t RelType) const override {
    unsigned ImmOpNo = -1U;

    for (unsigned Index = 0; Index < MCPlus::getNumPrimeOperands(Inst);
         ++Index) {
      if (Inst.getOperand(Index).isImm()) {
        ImmOpNo = Index;
        // TODO: this is a bit hacky.  It finds the correct operand by
        // searching for a specific immediate value.  If no value is
        // provided it defaults to the last immediate operand found.
        // This could lead to unexpected results if the instruction
        // has more than one immediate with the same value.
        if (Inst.getOperand(ImmOpNo).getImm() == Value)
          break;
      }
    }

    if (ImmOpNo == -1U)
      return false;

    Value = Inst.getOperand(ImmOpNo).getImm();

    setOperandToSymbolRef(Inst, ImmOpNo, Symbol, Addend, Ctx, RelType);

    return true;
  }

  bool replaceRegWithImm(MCInst &Inst, unsigned Register,
                         int64_t Imm) const override {

    enum CheckSignExt : uint8_t {
      NOCHECK = 0,
      CHECK8,
      CHECK32,
    };

    using CheckList = std::vector<std::pair<CheckSignExt, unsigned>>;
    struct InstInfo {
      // Size in bytes that Inst loads from memory.
      uint8_t DataSize;

      // True when the target operand has to be duplicated because the opcode
      // expects a LHS operand.
      bool HasLHS;

      // List of checks and corresponding opcodes to be used. We try to use the
      // smallest possible immediate value when various sizes are available,
      // hence we may need to check whether a larger constant fits in a smaller
      // immediate.
      CheckList Checks;
    };

    InstInfo I;

    switch (Inst.getOpcode()) {
    default: {
      switch (getPushSize(Inst)) {

      case 2: I = {2, false, {{CHECK8, X86::PUSH16i8}, {NOCHECK, X86::PUSH16i}}}; break;
      case 4: I = {4, false, {{CHECK8, X86::PUSH32i8}, {NOCHECK, X86::PUSH32i}}}; break;
      case 8: I = {8, false, {{CHECK8, X86::PUSH64i8},
                              {CHECK32, X86::PUSH64i32},
                              {NOCHECK, Inst.getOpcode()}}}; break;
      default: return false;
      }
      break;
    }

    // MOV
    case X86::MOV8rr:       I = {1, false, {{NOCHECK, X86::MOV8ri}}}; break;
    case X86::MOV16rr:      I = {2, false, {{NOCHECK, X86::MOV16ri}}}; break;
    case X86::MOV32rr:      I = {4, false, {{NOCHECK, X86::MOV32ri}}}; break;
    case X86::MOV64rr:      I = {8, false, {{CHECK32, X86::MOV64ri32},
                                            {NOCHECK, X86::MOV64ri}}}; break;

    case X86::MOV8mr:       I = {1, false, {{NOCHECK, X86::MOV8mi}}}; break;
    case X86::MOV16mr:      I = {2, false, {{NOCHECK, X86::MOV16mi}}}; break;
    case X86::MOV32mr:      I = {4, false, {{NOCHECK, X86::MOV32mi}}}; break;
    case X86::MOV64mr:      I = {8, false, {{CHECK32, X86::MOV64mi32},
                                            {NOCHECK, X86::MOV64mr}}}; break;

    // MOVZX
    case X86::MOVZX16rr8:   I = {1, false, {{NOCHECK, X86::MOV16ri}}}; break;
    case X86::MOVZX32rr8:   I = {1, false, {{NOCHECK, X86::MOV32ri}}}; break;
    case X86::MOVZX32rr16:  I = {2, false, {{NOCHECK, X86::MOV32ri}}}; break;

    // CMP
    case X86::CMP8rr:       I = {1, false, {{NOCHECK, X86::CMP8ri}}}; break;
    case X86::CMP16rr:      I = {2, false, {{CHECK8, X86::CMP16ri8},
                                            {NOCHECK, X86::CMP16ri}}}; break;
    case X86::CMP32rr:      I = {4, false, {{CHECK8, X86::CMP32ri8},
                                            {NOCHECK, X86::CMP32ri}}}; break;
    case X86::CMP64rr:      I = {8, false, {{CHECK8, X86::CMP64ri8},
                                            {CHECK32, X86::CMP64ri32},
                                            {NOCHECK, X86::CMP64rr}}}; break;

    // TEST
    case X86::TEST8rr:      I = {1, false, {{NOCHECK, X86::TEST8ri}}}; break;
    case X86::TEST16rr:     I = {2, false, {{NOCHECK, X86::TEST16ri}}}; break;
    case X86::TEST32rr:     I = {4, false, {{NOCHECK, X86::TEST32ri}}}; break;
    case X86::TEST64rr:     I = {8, false, {{CHECK32, X86::TEST64ri32},
                                            {NOCHECK, X86::TEST64rr}}}; break;

    // ADD
    case X86::ADD8rr:       I = {1, true, {{NOCHECK, X86::ADD8ri}}}; break;
    case X86::ADD16rr:      I = {2, true, {{CHECK8, X86::ADD16ri8},
                                           {NOCHECK, X86::ADD16ri}}}; break;
    case X86::ADD32rr:      I = {4, true, {{CHECK8, X86::ADD32ri8},
                                           {NOCHECK, X86::ADD32ri}}}; break;
    case X86::ADD64rr:      I = {8, true, {{CHECK8, X86::ADD64ri8},
                                           {CHECK32, X86::ADD64ri32},
                                           {NOCHECK, X86::ADD64rr}}}; break;

    // SUB
    case X86::SUB8rr:       I = {1, true, {{NOCHECK, X86::SUB8ri}}}; break;
    case X86::SUB16rr:      I = {2, true, {{CHECK8, X86::SUB16ri8},
                                           {NOCHECK, X86::SUB16ri}}}; break;
    case X86::SUB32rr:      I = {4, true, {{CHECK8, X86::SUB32ri8},
                                           {NOCHECK, X86::SUB32ri}}}; break;
    case X86::SUB64rr:      I = {8, true, {{CHECK8, X86::SUB64ri8},
                                           {CHECK32, X86::SUB64ri32},
                                           {NOCHECK, X86::SUB64rr}}}; break;

    // AND
    case X86::AND8rr:       I = {1, true, {{NOCHECK, X86::AND8ri}}}; break;
    case X86::AND16rr:      I = {2, true, {{CHECK8, X86::AND16ri8},
                                           {NOCHECK, X86::AND16ri}}}; break;
    case X86::AND32rr:      I = {4, true, {{CHECK8, X86::AND32ri8},
                                           {NOCHECK, X86::AND32ri}}}; break;
    case X86::AND64rr:      I = {8, true, {{CHECK8, X86::AND64ri8},
                                           {CHECK32, X86::AND64ri32},
                                           {NOCHECK, X86::AND64rr}}}; break;

    // OR
    case X86::OR8rr:        I = {1, true, {{NOCHECK, X86::OR8ri}}}; break;
    case X86::OR16rr:       I = {2, true, {{CHECK8, X86::OR16ri8},
                                           {NOCHECK, X86::OR16ri}}}; break;
    case X86::OR32rr:       I = {4, true, {{CHECK8, X86::OR32ri8},
                                           {NOCHECK, X86::OR32ri}}}; break;
    case X86::OR64rr:       I = {8, true, {{CHECK8, X86::OR64ri8},
                                           {CHECK32, X86::OR64ri32},
                                           {NOCHECK, X86::OR64rr}}}; break;

    // XOR
    case X86::XOR8rr:       I = {1, true, {{NOCHECK, X86::XOR8ri}}}; break;
    case X86::XOR16rr:      I = {2, true, {{CHECK8, X86::XOR16ri8},
                                           {NOCHECK, X86::XOR16ri}}}; break;
    case X86::XOR32rr:      I = {4, true, {{CHECK8, X86::XOR32ri8},
                                           {NOCHECK, X86::XOR32ri}}}; break;
    case X86::XOR64rr:      I = {8, true, {{CHECK8, X86::XOR64ri8},
                                           {CHECK32, X86::XOR64ri32},
                                           {NOCHECK, X86::XOR64rr}}}; break;
    }

    // Compute the new opcode.
    unsigned NewOpcode = 0;
    for (const std::pair<CheckSignExt, unsigned> &Check : I.Checks) {
      NewOpcode = Check.second;
      if (Check.first == NOCHECK)
        break;
      if (Check.first == CHECK8 && isInt<8>(Imm))
        break;
      if (Check.first == CHECK32 && isInt<32>(Imm))
        break;
    }
    if (NewOpcode == Inst.getOpcode())
      return false;

    const MCInstrDesc &InstDesc = Info->get(Inst.getOpcode());

    unsigned NumFound = 0;
    for (unsigned Index = InstDesc.getNumDefs() + (I.HasLHS ? 1 : 0),
                  E = InstDesc.getNumOperands();
         Index != E; ++Index)
      if (Inst.getOperand(Index).isReg() &&
          Inst.getOperand(Index).getReg() == Register)
        NumFound++;

    if (NumFound != 1)
      return false;

    MCOperand TargetOp = Inst.getOperand(0);
    Inst.clear();
    Inst.setOpcode(NewOpcode);
    Inst.addOperand(TargetOp);
    if (I.HasLHS)
      Inst.addOperand(TargetOp);
    Inst.addOperand(MCOperand::createImm(Imm));

    return true;
  }

  bool replaceRegWithReg(MCInst &Inst, unsigned ToReplace,
                         unsigned ReplaceWith) const override {

    // Get the HasLHS value so that iteration can be done
    bool HasLHS;
    if (X86::isAND(Inst.getOpcode()) || X86::isADD(Inst.getOpcode()) ||
        X86::isSUB(Inst.getOpcode())) {
      HasLHS = true;
    } else if (isPop(Inst) || isPush(Inst) || X86::isCMP(Inst.getOpcode()) ||
               X86::isTEST(Inst.getOpcode())) {
      HasLHS = false;
    } else {
      switch (Inst.getOpcode()) {
      case X86::MOV8rr:
      case X86::MOV8rm:
      case X86::MOV8mr:
      case X86::MOV8ri:
      case X86::MOV16rr:
      case X86::MOV16rm:
      case X86::MOV16mr:
      case X86::MOV16ri:
      case X86::MOV32rr:
      case X86::MOV32rm:
      case X86::MOV32mr:
      case X86::MOV32ri:
      case X86::MOV64rr:
      case X86::MOV64rm:
      case X86::MOV64mr:
      case X86::MOV64ri:
      case X86::MOVZX16rr8:
      case X86::MOVZX32rr8:
      case X86::MOVZX32rr16:
      case X86::MOVSX32rm8:
      case X86::MOVSX32rr8:
      case X86::MOVSX64rm32:
      case X86::LEA64r:
        HasLHS = false;
        break;
      default:
        return false;
      }
    }

    const MCInstrDesc &InstDesc = Info->get(Inst.getOpcode());

    bool FoundOne = false;

    // Iterate only through src operands that aren't also dest operands
    for (unsigned Index = InstDesc.getNumDefs() + (HasLHS ? 1 : 0),
                  E = InstDesc.getNumOperands();
         Index != E; ++Index) {
      BitVector RegAliases = getAliases(ToReplace, true);
      if (!Inst.getOperand(Index).isReg() ||
          !RegAliases.test(Inst.getOperand(Index).getReg()))
        continue;
      // Resize register if needed
      unsigned SizedReplaceWith = getAliasSized(
          ReplaceWith, getRegSize(Inst.getOperand(Index).getReg()));
      MCOperand NewOperand = MCOperand::createReg(SizedReplaceWith);
      Inst.getOperand(Index) = NewOperand;
      FoundOne = true;
    }

    // Return true if at least one operand was replaced
    return FoundOne;
  }

  void createUncondBranch(MCInst &Inst, const MCSymbol *TBB,
                          MCContext *Ctx) const override {
    Inst.clear();
    Inst.setOpcode(X86::JMP_1);
    Inst.clear();
    Inst.addOperand(MCOperand::createExpr(MCSymbolRefExpr::create(TBB, *Ctx)));
  }

  void createLongUncondBranch(MCInst &Inst, const MCSymbol *Target,
                              MCContext *Ctx) const override {
    Inst.setOpcode(X86::JMP_4);
    Inst.clear();
    Inst.addOperand(
        MCOperand::createExpr(MCSymbolRefExpr::create(Target, *Ctx)));
  }

  void createCall(MCInst &Inst, const MCSymbol *Target,
                  MCContext *Ctx) override {
    Inst.setOpcode(X86::CALL64pcrel32);
    Inst.clear();
    Inst.addOperand(
        MCOperand::createExpr(MCSymbolRefExpr::create(Target, *Ctx)));
  }

  void createTailCall(MCInst &Inst, const MCSymbol *Target,
                      MCContext *Ctx) override {
    return createDirectCall(Inst, Target, Ctx, /*IsTailCall*/ true);
  }

  void createLongTailCall(InstructionListType &Seq, const MCSymbol *Target,
                          MCContext *Ctx) override {
    Seq.clear();
    Seq.emplace_back();
    createDirectCall(Seq.back(), Target, Ctx, /*IsTailCall*/ true);
  }

  void createTrap(MCInst &Inst) const override {
    Inst.clear();
    Inst.setOpcode(X86::TRAP);
  }

  void createCondBranch(MCInst &Inst, const MCSymbol *Target, unsigned CC,
                        MCContext *Ctx) const override {
    Inst.setOpcode(X86::JCC_1);
    Inst.clear();
    Inst.addOperand(
        MCOperand::createExpr(MCSymbolRefExpr::create(Target, *Ctx)));
    Inst.addOperand(MCOperand::createImm(CC));
  }

  void createLongCondBranch(MCInst &Inst, const MCSymbol *Target, unsigned CC,
                            MCContext *Ctx) const override {
    Inst.setOpcode(X86::JCC_4);
    Inst.clear();
    Inst.addOperand(
        MCOperand::createExpr(MCSymbolRefExpr::create(Target, *Ctx)));
    Inst.addOperand(MCOperand::createImm(CC));
  }

  void reverseBranchCondition(MCInst &Inst, const MCSymbol *TBB,
                              MCContext *Ctx) const override {
    unsigned InvCC = getInvertedCondCode(getCondCode(Inst));
    assert(InvCC != X86::COND_INVALID && "invalid branch instruction");
    Inst.getOperand(Info->get(Inst.getOpcode()).NumOperands - 1).setImm(InvCC);
    Inst.getOperand(0) =
        MCOperand::createExpr(MCSymbolRefExpr::create(TBB, *Ctx));
  }

  bool replaceBranchCondition(MCInst &Inst, const MCSymbol *TBB, MCContext *Ctx,
                              unsigned CC) const override {
    if (CC == X86::COND_INVALID)
      return false;
    Inst.getOperand(Info->get(Inst.getOpcode()).NumOperands - 1).setImm(CC);
    Inst.getOperand(0) =
        MCOperand::createExpr(MCSymbolRefExpr::create(TBB, *Ctx));
    return true;
  }

  unsigned getCanonicalBranchCondCode(unsigned CC) const override {
    switch (CC) {
    default:           return X86::COND_INVALID;

    case X86::COND_E:  return X86::COND_E;
    case X86::COND_NE: return X86::COND_E;

    case X86::COND_L:  return X86::COND_L;
    case X86::COND_GE: return X86::COND_L;

    case X86::COND_LE: return X86::COND_G;
    case X86::COND_G:  return X86::COND_G;

    case X86::COND_B:  return X86::COND_B;
    case X86::COND_AE: return X86::COND_B;

    case X86::COND_BE: return X86::COND_A;
    case X86::COND_A:  return X86::COND_A;

    case X86::COND_S:  return X86::COND_S;
    case X86::COND_NS: return X86::COND_S;

    case X86::COND_P:  return X86::COND_P;
    case X86::COND_NP: return X86::COND_P;

    case X86::COND_O:  return X86::COND_O;
    case X86::COND_NO: return X86::COND_O;
    }
  }

  void replaceBranchTarget(MCInst &Inst, const MCSymbol *TBB,
                           MCContext *Ctx) const override {
    assert((isCall(Inst) || isBranch(Inst)) && !isIndirectBranch(Inst) &&
           "Invalid instruction");
    Inst.getOperand(0) =
        MCOperand::createExpr(MCSymbolRefExpr::create(TBB, *Ctx));
  }

  MCPhysReg getX86R11() const override { return X86::R11; }

  unsigned getShortBranchOpcode(unsigned Opcode) const override {
    switch (Opcode) {
    default:
      return Opcode;
    case X86::JMP_2:
      return X86::JMP_1;
    case X86::JMP_4:
      return X86::JMP_1;
    case X86::JCC_2:
      return X86::JCC_1;
    case X86::JCC_4:
      return X86::JCC_1;
    }
  }

  MCPhysReg getIntArgRegister(unsigned ArgNo) const override {
    // FIXME: this should depend on the calling convention.
    switch (ArgNo) {
    case 0:   return X86::RDI;
    case 1:   return X86::RSI;
    case 2:   return X86::RDX;
    case 3:   return X86::RCX;
    case 4:   return X86::R8;
    case 5:   return X86::R9;
    default:  return getNoRegister();
    }
  }

  void createPause(MCInst &Inst) const override {
    Inst.clear();
    Inst.setOpcode(X86::PAUSE);
  }

  void createLfence(MCInst &Inst) const override {
    Inst.clear();
    Inst.setOpcode(X86::LFENCE);
  }

  void createDirectCall(MCInst &Inst, const MCSymbol *Target, MCContext *Ctx,
                        bool IsTailCall) override {
    Inst.clear();
    Inst.setOpcode(IsTailCall ? X86::JMP_4 : X86::CALL64pcrel32);
    Inst.addOperand(
        MCOperand::createExpr(MCSymbolRefExpr::create(Target, *Ctx)));
    if (IsTailCall)
      setTailCall(Inst);
  }

  void createShortJmp(InstructionListType &Seq, const MCSymbol *Target,
                      MCContext *Ctx, bool IsTailCall) override {
    Seq.clear();
    MCInst Inst;
    Inst.setOpcode(X86::JMP_1);
    Inst.addOperand(
        MCOperand::createExpr(MCSymbolRefExpr::create(Target, *Ctx)));
    if (IsTailCall)
      setTailCall(Inst);
    Seq.emplace_back(Inst);
  }

  bool isConditionalMove(const MCInst &Inst) const override {
    unsigned OpCode = Inst.getOpcode();
    return (OpCode == X86::CMOV16rr || OpCode == X86::CMOV32rr ||
            OpCode == X86::CMOV64rr);
  }

  bool isBranchOnMem(const MCInst &Inst) const override {
    unsigned OpCode = Inst.getOpcode();
    if (OpCode == X86::CALL64m || (OpCode == X86::JMP32m && isTailCall(Inst)) ||
        OpCode == X86::JMP64m)
      return true;

    return false;
  }

  bool isBranchOnReg(const MCInst &Inst) const override {
    unsigned OpCode = Inst.getOpcode();
    if (OpCode == X86::CALL64r || (OpCode == X86::JMP32r && isTailCall(Inst)) ||
        OpCode == X86::JMP64r)
      return true;

    return false;
  }

  void createPushRegister(MCInst &Inst, MCPhysReg Reg,
                          unsigned Size) const override {
    Inst.clear();
    unsigned NewOpcode = 0;
    if (Reg == X86::EFLAGS) {
      switch (Size) {
      case 2: NewOpcode = X86::PUSHF16;  break;
      case 4: NewOpcode = X86::PUSHF32;  break;
      case 8: NewOpcode = X86::PUSHF64;  break;
      default:
        llvm_unreachable("Unexpected size");
      }
      Inst.setOpcode(NewOpcode);
      return;
    }
    switch (Size) {
    case 2: NewOpcode = X86::PUSH16r;  break;
    case 4: NewOpcode = X86::PUSH32r;  break;
    case 8: NewOpcode = X86::PUSH64r;  break;
    default:
      llvm_unreachable("Unexpected size");
    }
    Inst.setOpcode(NewOpcode);
    Inst.addOperand(MCOperand::createReg(Reg));
  }

  void createPopRegister(MCInst &Inst, MCPhysReg Reg,
                         unsigned Size) const override {
    Inst.clear();
    unsigned NewOpcode = 0;
    if (Reg == X86::EFLAGS) {
      switch (Size) {
      case 2: NewOpcode = X86::POPF16;  break;
      case 4: NewOpcode = X86::POPF32;  break;
      case 8: NewOpcode = X86::POPF64;  break;
      default:
        llvm_unreachable("Unexpected size");
      }
      Inst.setOpcode(NewOpcode);
      return;
    }
    switch (Size) {
    case 2: NewOpcode = X86::POP16r;  break;
    case 4: NewOpcode = X86::POP32r;  break;
    case 8: NewOpcode = X86::POP64r;  break;
    default:
      llvm_unreachable("Unexpected size");
    }
    Inst.setOpcode(NewOpcode);
    Inst.addOperand(MCOperand::createReg(Reg));
  }

  void createPushFlags(MCInst &Inst, unsigned Size) const override {
    return createPushRegister(Inst, X86::EFLAGS, Size);
  }

  void createPopFlags(MCInst &Inst, unsigned Size) const override {
    return createPopRegister(Inst, X86::EFLAGS, Size);
  }

  void createAddRegImm(MCInst &Inst, MCPhysReg Reg, int64_t Value,
                       unsigned Size) const {
    unsigned int Opcode;
    switch (Size) {
    case 1: Opcode = X86::ADD8ri; break;
    case 2: Opcode = X86::ADD16ri; break;
    case 4: Opcode = X86::ADD32ri; break;
    default:
      llvm_unreachable("Unexpected size");
    }
    Inst.setOpcode(Opcode);
    Inst.clear();
    Inst.addOperand(MCOperand::createReg(Reg));
    Inst.addOperand(MCOperand::createReg(Reg));
    Inst.addOperand(MCOperand::createImm(Value));
  }

  void createClearRegWithNoEFlagsUpdate(MCInst &Inst, MCPhysReg Reg,
                                        unsigned Size) const {
    unsigned int Opcode;
    switch (Size) {
    case 1: Opcode = X86::MOV8ri; break;
    case 2: Opcode = X86::MOV16ri; break;
    case 4: Opcode = X86::MOV32ri; break;
    // Writing to a 32-bit register always zeros the upper 32 bits of the
    // full-width register
    case 8:
      Opcode = X86::MOV32ri;
      Reg = getAliasSized(Reg, 4);
      break;
    default:
      llvm_unreachable("Unexpected size");
    }
    Inst.setOpcode(Opcode);
    Inst.clear();
    Inst.addOperand(MCOperand::createReg(Reg));
    Inst.addOperand(MCOperand::createImm(0));
  }

  void createX86SaveOVFlagToRegister(MCInst &Inst, MCPhysReg Reg) const {
    Inst.setOpcode(X86::SETCCr);
    Inst.clear();
    Inst.addOperand(MCOperand::createReg(Reg));
    Inst.addOperand(MCOperand::createImm(X86::COND_O));
  }

  void createX86Lahf(MCInst &Inst) const {
    Inst.setOpcode(X86::LAHF);
    Inst.clear();
  }

  void createX86Sahf(MCInst &Inst) const {
    Inst.setOpcode(X86::SAHF);
    Inst.clear();
  }

  InstructionListType createInstrIncMemory(const MCSymbol *Target,
                                           MCContext *Ctx, bool IsLeaf,
                                           unsigned CodePointerSize) override {
    InstructionListType Instrs(IsLeaf ? 13 : 11);
    unsigned int I = 0;

    // Don't clobber application red zone (ABI dependent)
    if (IsLeaf)
      createStackPointerIncrement(Instrs[I++], 128,
                                  /*NoFlagsClobber=*/true);

    // Performance improvements based on the optimization discussed at
    // https://reviews.llvm.org/D6629
    // LAHF/SAHF are used instead of PUSHF/POPF
    // PUSHF
    createPushRegister(Instrs[I++], X86::RAX, 8);
    createClearRegWithNoEFlagsUpdate(Instrs[I++], X86::RAX, 8);
    createX86Lahf(Instrs[I++]);
    createPushRegister(Instrs[I++], X86::RAX, 8);
    createClearRegWithNoEFlagsUpdate(Instrs[I++], X86::RAX, 8);
    createX86SaveOVFlagToRegister(Instrs[I++], X86::AL);
    // LOCK INC
    InstructionListType IncMem = createIncMemory(Target, Ctx);
    assert(IncMem.size() == 1 && "Invalid IncMem size");
    std::copy(IncMem.begin(), IncMem.end(), Instrs.begin() + I);
    I += IncMem.size();
    // POPF
    createAddRegImm(Instrs[I++], X86::AL, 127, 1);
    createPopRegister(Instrs[I++], X86::RAX, 8);
    createX86Sahf(Instrs[I++]);
    createPopRegister(Instrs[I++], X86::RAX, 8);

    if (IsLeaf)
      createStackPointerDecrement(Instrs[I], 128,
                                  /*NoFlagsClobber=*/true);
    return Instrs;
  }

  void createSwap(MCInst &Inst, MCPhysReg Source, MCPhysReg MemBaseReg,
                  int64_t Disp) const {
    Inst.setOpcode(X86::XCHG64rm);
    Inst.clear();
    Inst.addOperand(MCOperand::createReg(Source));
    Inst.addOperand(MCOperand::createReg(Source));
    Inst.addOperand(MCOperand::createReg(MemBaseReg));      // BaseReg
    Inst.addOperand(MCOperand::createImm(1));               // ScaleAmt
    Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // IndexReg
    Inst.addOperand(MCOperand::createImm(Disp));            // Displacement
    Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // AddrSegmentReg
  }

  void createIndirectBranch(MCInst &Inst, MCPhysReg MemBaseReg,
                            int64_t Disp) const {
    Inst.setOpcode(X86::JMP64m);
    Inst.clear();
    Inst.addOperand(MCOperand::createReg(MemBaseReg));      // BaseReg
    Inst.addOperand(MCOperand::createImm(1));               // ScaleAmt
    Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // IndexReg
    Inst.addOperand(MCOperand::createImm(Disp));            // Displacement
    Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // AddrSegmentReg
  }

  InstructionListType createInstrumentedIndirectCall(MCInst &&CallInst,
                                                     MCSymbol *HandlerFuncAddr,
                                                     size_t CallSiteID,
                                                     MCContext *Ctx) override {
    // Check if the target address expression used in the original indirect call
    // uses the stack pointer, which we are going to clobber.
    static BitVector SPAliases(getAliases(X86::RSP));
    bool UsesSP = any_of(useOperands(CallInst), [&](const MCOperand &Op) {
      return Op.isReg() && SPAliases[Op.getReg()];
    });

    InstructionListType Insts;
    MCPhysReg TempReg = getIntArgRegister(0);
    // Code sequence used to enter indirect call instrumentation helper:
    //   push %rdi
    //   add $8, %rsp       ;; $rsp may be used in target, so fix it to prev val
    //   movq target, %rdi  ;; via convertIndirectCallTargetToLoad
    //   sub $8, %rsp       ;; restore correct stack value
    //   push %rdi
    //   movq $CallSiteID, %rdi
    //   push %rdi
    //   callq/jmp HandlerFuncAddr
    Insts.emplace_back();
    createPushRegister(Insts.back(), TempReg, 8);
    if (UsesSP) { // Only adjust SP if we really need to
      Insts.emplace_back();
      createStackPointerDecrement(Insts.back(), 8, /*NoFlagsClobber=*/false);
    }
    Insts.emplace_back(CallInst);
    // Insts.back() and CallInst now share the same annotation instruction.
    // Strip it from Insts.back(), only preserving tail call annotation.
    stripAnnotations(Insts.back(), /*KeepTC=*/true);
    convertIndirectCallToLoad(Insts.back(), TempReg);
    if (UsesSP) {
      Insts.emplace_back();
      createStackPointerIncrement(Insts.back(), 8, /*NoFlagsClobber=*/false);
    }
    Insts.emplace_back();
    createPushRegister(Insts.back(), TempReg, 8);
    InstructionListType LoadImm = createLoadImmediate(TempReg, CallSiteID);
    Insts.insert(Insts.end(), LoadImm.begin(), LoadImm.end());
    Insts.emplace_back();
    createPushRegister(Insts.back(), TempReg, 8);

    MCInst &NewCallInst = Insts.emplace_back();
    createDirectCall(NewCallInst, HandlerFuncAddr, Ctx, isTailCall(CallInst));

    // Carry over metadata including tail call marker if present.
    stripAnnotations(NewCallInst);
    moveAnnotations(std::move(CallInst), NewCallInst);

    return Insts;
  }

  InstructionListType createInstrumentedIndCallHandlerExitBB() const override {
    const MCPhysReg TempReg = getIntArgRegister(0);
    // We just need to undo the sequence created for every ind call in
    // instrumentIndirectTarget(), which can be accomplished minimally with:
    //   popfq
    //   pop %rdi
    //   add $16, %rsp
    //   xchg (%rsp), %rdi
    //   jmp *-8(%rsp)
    InstructionListType Insts(5);
    createPopFlags(Insts[0], 8);
    createPopRegister(Insts[1], TempReg, 8);
    createStackPointerDecrement(Insts[2], 16, /*NoFlagsClobber=*/false);
    createSwap(Insts[3], TempReg, X86::RSP, 0);
    createIndirectBranch(Insts[4], X86::RSP, -8);
    return Insts;
  }

  InstructionListType
  createInstrumentedIndTailCallHandlerExitBB() const override {
    const MCPhysReg TempReg = getIntArgRegister(0);
    // Same thing as above, but for tail calls
    //   popfq
    //   add $16, %rsp
    //   pop %rdi
    //   jmp *-16(%rsp)
    InstructionListType Insts(4);
    createPopFlags(Insts[0], 8);
    createStackPointerDecrement(Insts[1], 16, /*NoFlagsClobber=*/false);
    createPopRegister(Insts[2], TempReg, 8);
    createIndirectBranch(Insts[3], X86::RSP, -16);
    return Insts;
  }

  InstructionListType
  createInstrumentedIndCallHandlerEntryBB(const MCSymbol *InstrTrampoline,
                                          const MCSymbol *IndCallHandler,
                                          MCContext *Ctx) override {
    const MCPhysReg TempReg = getIntArgRegister(0);
    // Code sequence used to check whether InstrTampoline was initialized
    // and call it if so, returns via IndCallHandler.
    //   pushfq
    //   mov    InstrTrampoline,%rdi
    //   cmp    $0x0,%rdi
    //   je     IndCallHandler
    //   callq  *%rdi
    //   jmpq   IndCallHandler
    InstructionListType Insts;
    Insts.emplace_back();
    createPushFlags(Insts.back(), 8);
    Insts.emplace_back();
    createMove(Insts.back(), InstrTrampoline, TempReg, Ctx);
    InstructionListType cmpJmp = createCmpJE(TempReg, 0, IndCallHandler, Ctx);
    Insts.insert(Insts.end(), cmpJmp.begin(), cmpJmp.end());
    Insts.emplace_back();
    Insts.back().setOpcode(X86::CALL64r);
    Insts.back().addOperand(MCOperand::createReg(TempReg));
    Insts.emplace_back();
    createDirectCall(Insts.back(), IndCallHandler, Ctx, /*IsTailCall*/ true);
    return Insts;
  }

  InstructionListType createNumCountersGetter(MCContext *Ctx) const override {
    InstructionListType Insts(2);
    MCSymbol *NumLocs = Ctx->getOrCreateSymbol("__bolt_num_counters");
    createMove(Insts[0], NumLocs, X86::EAX, Ctx);
    createReturn(Insts[1]);
    return Insts;
  }

  InstructionListType
  createInstrLocationsGetter(MCContext *Ctx) const override {
    InstructionListType Insts(2);
    MCSymbol *Locs = Ctx->getOrCreateSymbol("__bolt_instr_locations");
    createLea(Insts[0], Locs, X86::EAX, Ctx);
    createReturn(Insts[1]);
    return Insts;
  }

  InstructionListType createInstrTablesGetter(MCContext *Ctx) const override {
    InstructionListType Insts(2);
    MCSymbol *Locs = Ctx->getOrCreateSymbol("__bolt_instr_tables");
    createLea(Insts[0], Locs, X86::EAX, Ctx);
    createReturn(Insts[1]);
    return Insts;
  }

  InstructionListType createInstrNumFuncsGetter(MCContext *Ctx) const override {
    InstructionListType Insts(2);
    MCSymbol *NumFuncs = Ctx->getOrCreateSymbol("__bolt_instr_num_funcs");
    createMove(Insts[0], NumFuncs, X86::EAX, Ctx);
    createReturn(Insts[1]);
    return Insts;
  }

  InstructionListType createSymbolTrampoline(const MCSymbol *TgtSym,
                                             MCContext *Ctx) override {
    InstructionListType Insts(1);
    createUncondBranch(Insts[0], TgtSym, Ctx);
    return Insts;
  }

  BlocksVectorTy indirectCallPromotion(
      const MCInst &CallInst,
      const std::vector<std::pair<MCSymbol *, uint64_t>> &Targets,
      const std::vector<std::pair<MCSymbol *, uint64_t>> &VtableSyms,
      const std::vector<MCInst *> &MethodFetchInsns,
      const bool MinimizeCodeSize, MCContext *Ctx) override {
    const bool IsTailCall = isTailCall(CallInst);
    const bool IsJumpTable = getJumpTable(CallInst) != 0;
    BlocksVectorTy Results;

    // Label for the current code block.
    MCSymbol *NextTarget = nullptr;

    // The join block which contains all the instructions following CallInst.
    // MergeBlock remains null if CallInst is a tail call.
    MCSymbol *MergeBlock = nullptr;

    unsigned FuncAddrReg = X86::R10;

    const bool LoadElim = !VtableSyms.empty();
    assert((!LoadElim || VtableSyms.size() == Targets.size()) &&
           "There must be a vtable entry for every method "
           "in the targets vector.");

    if (MinimizeCodeSize && !LoadElim) {
      std::set<unsigned> UsedRegs;

      for (unsigned int I = 0; I < MCPlus::getNumPrimeOperands(CallInst); ++I) {
        const MCOperand &Op = CallInst.getOperand(I);
        if (Op.isReg())
          UsedRegs.insert(Op.getReg());
      }

      if (UsedRegs.count(X86::R10) == 0)
        FuncAddrReg = X86::R10;
      else if (UsedRegs.count(X86::R11) == 0)
        FuncAddrReg = X86::R11;
      else
        return Results;
    }

    const auto jumpToMergeBlock = [&](InstructionListType &NewCall) {
      assert(MergeBlock);
      NewCall.push_back(CallInst);
      MCInst &Merge = NewCall.back();
      Merge.clear();
      createUncondBranch(Merge, MergeBlock, Ctx);
    };

    for (unsigned int i = 0; i < Targets.size(); ++i) {
      Results.emplace_back(NextTarget, InstructionListType());
      InstructionListType *NewCall = &Results.back().second;

      if (MinimizeCodeSize && !LoadElim) {
        // Load the call target into FuncAddrReg.
        NewCall->push_back(CallInst); // Copy CallInst in order to get SMLoc
        MCInst &Target = NewCall->back();
        Target.clear();
        Target.setOpcode(X86::MOV64ri32);
        Target.addOperand(MCOperand::createReg(FuncAddrReg));
        if (Targets[i].first) {
          // Is this OK?
          Target.addOperand(MCOperand::createExpr(
              MCSymbolRefExpr::create(Targets[i].first, *Ctx)));
        } else {
          const uint64_t Addr = Targets[i].second;
          // Immediate address is out of sign extended 32 bit range.
          if (int64_t(Addr) != int64_t(int32_t(Addr)))
            return BlocksVectorTy();

          Target.addOperand(MCOperand::createImm(Addr));
        }

        // Compare current call target to a specific address.
        NewCall->push_back(CallInst);
        MCInst &Compare = NewCall->back();
        Compare.clear();
        if (isBranchOnReg(CallInst))
          Compare.setOpcode(X86::CMP64rr);
        else if (CallInst.getOpcode() == X86::CALL64pcrel32)
          Compare.setOpcode(X86::CMP64ri32);
        else
          Compare.setOpcode(X86::CMP64rm);

        Compare.addOperand(MCOperand::createReg(FuncAddrReg));

        // TODO: Would be preferable to only load this value once.
        for (unsigned i = 0;
             i < Info->get(CallInst.getOpcode()).getNumOperands(); ++i)
          if (!CallInst.getOperand(i).isInst())
            Compare.addOperand(CallInst.getOperand(i));
      } else {
        // Compare current call target to a specific address.
        NewCall->push_back(CallInst);
        MCInst &Compare = NewCall->back();
        Compare.clear();
        if (isBranchOnReg(CallInst))
          Compare.setOpcode(X86::CMP64ri32);
        else
          Compare.setOpcode(X86::CMP64mi32);

        // Original call address.
        for (unsigned i = 0;
             i < Info->get(CallInst.getOpcode()).getNumOperands(); ++i)
          if (!CallInst.getOperand(i).isInst())
            Compare.addOperand(CallInst.getOperand(i));

        // Target address.
        if (Targets[i].first || LoadElim) {
          const MCSymbol *Sym =
              LoadElim ? VtableSyms[i].first : Targets[i].first;
          const uint64_t Addend = LoadElim ? VtableSyms[i].second : 0;
          const MCExpr *Expr = MCSymbolRefExpr::create(Sym, *Ctx);
          if (Addend)
            Expr = MCBinaryExpr::createAdd(
                Expr, MCConstantExpr::create(Addend, *Ctx), *Ctx);
          Compare.addOperand(MCOperand::createExpr(Expr));
        } else {
          const uint64_t Addr = Targets[i].second;
          // Immediate address is out of sign extended 32 bit range.
          if (int64_t(Addr) != int64_t(int32_t(Addr)))
            return BlocksVectorTy();

          Compare.addOperand(MCOperand::createImm(Addr));
        }
      }

      // jump to next target compare.
      NextTarget =
          Ctx->createNamedTempSymbol(); // generate label for the next block
      NewCall->push_back(CallInst);

      if (IsJumpTable) {
        MCInst &Je = NewCall->back();

        // Jump to next compare if target addresses don't match.
        Je.clear();
        Je.setOpcode(X86::JCC_1);
        if (Targets[i].first)
          Je.addOperand(MCOperand::createExpr(
              MCSymbolRefExpr::create(Targets[i].first, *Ctx)));
        else
          Je.addOperand(MCOperand::createImm(Targets[i].second));

        Je.addOperand(MCOperand::createImm(X86::COND_E));
        assert(!isInvoke(CallInst));
      } else {
        MCInst &Jne = NewCall->back();

        // Jump to next compare if target addresses don't match.
        Jne.clear();
        Jne.setOpcode(X86::JCC_1);
        Jne.addOperand(
            MCOperand::createExpr(MCSymbolRefExpr::create(NextTarget, *Ctx)));
        Jne.addOperand(MCOperand::createImm(X86::COND_NE));

        // Call specific target directly.
        Results.emplace_back(Ctx->createNamedTempSymbol(),
                             InstructionListType());
        NewCall = &Results.back().second;
        NewCall->push_back(CallInst);
        MCInst &CallOrJmp = NewCall->back();

        CallOrJmp.clear();

        if (MinimizeCodeSize && !LoadElim) {
          CallOrJmp.setOpcode(IsTailCall ? X86::JMP32r : X86::CALL64r);
          CallOrJmp.addOperand(MCOperand::createReg(FuncAddrReg));
        } else {
          CallOrJmp.setOpcode(IsTailCall ? X86::JMP_4 : X86::CALL64pcrel32);

          if (Targets[i].first)
            CallOrJmp.addOperand(MCOperand::createExpr(
                MCSymbolRefExpr::create(Targets[i].first, *Ctx)));
          else
            CallOrJmp.addOperand(MCOperand::createImm(Targets[i].second));
        }
        if (IsTailCall)
          setTailCall(CallOrJmp);

        if (CallOrJmp.getOpcode() == X86::CALL64r ||
            CallOrJmp.getOpcode() == X86::CALL64pcrel32) {
          if (std::optional<uint32_t> Offset = getOffset(CallInst))
            // Annotated as duplicated call
            setOffset(CallOrJmp, *Offset);
        }

        if (isInvoke(CallInst) && !isInvoke(CallOrJmp)) {
          // Copy over any EH or GNU args size information from the original
          // call.
          std::optional<MCPlus::MCLandingPad> EHInfo = getEHInfo(CallInst);
          if (EHInfo)
            addEHInfo(CallOrJmp, *EHInfo);
          int64_t GnuArgsSize = getGnuArgsSize(CallInst);
          if (GnuArgsSize >= 0)
            addGnuArgsSize(CallOrJmp, GnuArgsSize);
        }

        if (!IsTailCall) {
          // The fallthrough block for the most common target should be
          // the merge block.
          if (i == 0) {
            // Fallthrough to merge block.
            MergeBlock = Ctx->createNamedTempSymbol();
          } else {
            // Insert jump to the merge block if we are not doing a fallthrough.
            jumpToMergeBlock(*NewCall);
          }
        }
      }
    }

    // Cold call block.
    Results.emplace_back(NextTarget, InstructionListType());
    InstructionListType &NewCall = Results.back().second;
    for (const MCInst *Inst : MethodFetchInsns)
      if (Inst != &CallInst)
        NewCall.push_back(*Inst);
    NewCall.push_back(CallInst);

    // Jump to merge block from cold call block
    if (!IsTailCall && !IsJumpTable) {
      jumpToMergeBlock(NewCall);

      // Record merge block
      Results.emplace_back(MergeBlock, InstructionListType());
    }

    return Results;
  }

  BlocksVectorTy jumpTablePromotion(
      const MCInst &IJmpInst,
      const std::vector<std::pair<MCSymbol *, uint64_t>> &Targets,
      const std::vector<MCInst *> &TargetFetchInsns,
      MCContext *Ctx) const override {
    assert(getJumpTable(IJmpInst) != 0);
    uint16_t IndexReg = getAnnotationAs<uint16_t>(IJmpInst, "JTIndexReg");
    if (IndexReg == 0)
      return BlocksVectorTy();

    BlocksVectorTy Results;

    // Label for the current code block.
    MCSymbol *NextTarget = nullptr;

    for (unsigned int i = 0; i < Targets.size(); ++i) {
      Results.emplace_back(NextTarget, InstructionListType());
      InstructionListType *CurBB = &Results.back().second;

      // Compare current index to a specific index.
      CurBB->emplace_back(MCInst());
      MCInst &CompareInst = CurBB->back();
      CompareInst.setLoc(IJmpInst.getLoc());
      CompareInst.setOpcode(X86::CMP64ri32);
      CompareInst.addOperand(MCOperand::createReg(IndexReg));

      const uint64_t CaseIdx = Targets[i].second;
      // Immediate address is out of sign extended 32 bit range.
      if (int64_t(CaseIdx) != int64_t(int32_t(CaseIdx)))
        return BlocksVectorTy();

      CompareInst.addOperand(MCOperand::createImm(CaseIdx));
      shortenInstruction(CompareInst, *Ctx->getSubtargetInfo());

      // jump to next target compare.
      NextTarget =
          Ctx->createNamedTempSymbol(); // generate label for the next block
      CurBB->push_back(MCInst());

      MCInst &JEInst = CurBB->back();
      JEInst.setLoc(IJmpInst.getLoc());

      // Jump to target if indices match
      JEInst.setOpcode(X86::JCC_1);
      JEInst.addOperand(MCOperand::createExpr(
          MCSymbolRefExpr::create(Targets[i].first, *Ctx)));
      JEInst.addOperand(MCOperand::createImm(X86::COND_E));
    }

    // Cold call block.
    Results.emplace_back(NextTarget, InstructionListType());
    InstructionListType &CurBB = Results.back().second;
    for (const MCInst *Inst : TargetFetchInsns)
      if (Inst != &IJmpInst)
        CurBB.push_back(*Inst);

    CurBB.push_back(IJmpInst);

    return Results;
  }

private:
  void createMove(MCInst &Inst, const MCSymbol *Src, unsigned Reg,
                  MCContext *Ctx) const {
    Inst.setOpcode(X86::MOV64rm);
    Inst.clear();
    Inst.addOperand(MCOperand::createReg(Reg));
    Inst.addOperand(MCOperand::createReg(X86::RIP));        // BaseReg
    Inst.addOperand(MCOperand::createImm(1));               // ScaleAmt
    Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // IndexReg
    Inst.addOperand(
        MCOperand::createExpr(MCSymbolRefExpr::create(Src,
                                                      *Ctx))); // Displacement
    Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // AddrSegmentReg
  }

  void createLea(MCInst &Inst, const MCSymbol *Src, unsigned Reg,
                 MCContext *Ctx) const {
    Inst.setOpcode(X86::LEA64r);
    Inst.clear();
    Inst.addOperand(MCOperand::createReg(Reg));
    Inst.addOperand(MCOperand::createReg(X86::RIP));        // BaseReg
    Inst.addOperand(MCOperand::createImm(1));               // ScaleAmt
    Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // IndexReg
    Inst.addOperand(
        MCOperand::createExpr(MCSymbolRefExpr::create(Src,
                                                      *Ctx))); // Displacement
    Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // AddrSegmentReg
  }
};

} // namespace

namespace llvm {
namespace bolt {

MCPlusBuilder *createX86MCPlusBuilder(const MCInstrAnalysis *Analysis,
                                      const MCInstrInfo *Info,
                                      const MCRegisterInfo *RegInfo,
                                      const MCSubtargetInfo *STI) {
  return new X86MCPlusBuilder(Analysis, Info, RegInfo, STI);
}

} // namespace bolt
} // namespace llvm
