//===- HexagonMCInstrInfo.cpp - Hexagon sub-class of MCInst ---------------===//
//
// 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 class extends MCInstrInfo to allow Hexagon specific MCInstr queries
//
//===----------------------------------------------------------------------===//

#include "MCTargetDesc/HexagonMCInstrInfo.h"
#include "MCTargetDesc/HexagonBaseInfo.h"
#include "MCTargetDesc/HexagonMCChecker.h"
#include "MCTargetDesc/HexagonMCExpr.h"
#include "MCTargetDesc/HexagonMCShuffler.h"
#include "MCTargetDesc/HexagonMCTargetDesc.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCInstrItineraries.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include <cassert>
#include <cstdint>
#include <limits>

using namespace llvm;

bool HexagonMCInstrInfo::PredicateInfo::isPredicated() const {
  return Register != Hexagon::NoRegister;
}

Hexagon::PacketIterator::PacketIterator(MCInstrInfo const &MCII,
                                        MCInst const &Inst)
    : MCII(MCII), BundleCurrent(Inst.begin() +
                                HexagonMCInstrInfo::bundleInstructionsOffset),
      BundleEnd(Inst.end()), DuplexCurrent(Inst.end()), DuplexEnd(Inst.end()) {}

Hexagon::PacketIterator::PacketIterator(MCInstrInfo const &MCII,
                                        MCInst const &Inst, std::nullptr_t)
    : MCII(MCII), BundleCurrent(Inst.end()), BundleEnd(Inst.end()),
      DuplexCurrent(Inst.end()), DuplexEnd(Inst.end()) {}

Hexagon::PacketIterator &Hexagon::PacketIterator::operator++() {
  if (DuplexCurrent != DuplexEnd) {
    ++DuplexCurrent;
    if (DuplexCurrent == DuplexEnd) {
      DuplexCurrent = BundleEnd;
      DuplexEnd = BundleEnd;
      ++BundleCurrent;
    }
    return *this;
  }
  ++BundleCurrent;
  if (BundleCurrent != BundleEnd) {
    MCInst const &Inst = *BundleCurrent->getInst();
    if (HexagonMCInstrInfo::isDuplex(MCII, Inst)) {
      DuplexCurrent = Inst.begin();
      DuplexEnd = Inst.end();
    }
  }
  return *this;
}

MCInst const &Hexagon::PacketIterator::operator*() const {
  if (DuplexCurrent != DuplexEnd)
    return *DuplexCurrent->getInst();
  return *BundleCurrent->getInst();
}

bool Hexagon::PacketIterator::operator==(PacketIterator const &Other) const {
  return BundleCurrent == Other.BundleCurrent && BundleEnd == Other.BundleEnd &&
         DuplexCurrent == Other.DuplexCurrent && DuplexEnd == Other.DuplexEnd;
}

void HexagonMCInstrInfo::addConstant(MCInst &MI, uint64_t Value,
                                     MCContext &Context) {
  MI.addOperand(MCOperand::createExpr(MCConstantExpr::create(Value, Context)));
}

void HexagonMCInstrInfo::addConstExtender(MCContext &Context,
                                          MCInstrInfo const &MCII, MCInst &MCB,
                                          MCInst const &MCI) {
  assert(HexagonMCInstrInfo::isBundle(MCB));
  MCOperand const &exOp =
      MCI.getOperand(HexagonMCInstrInfo::getExtendableOp(MCII, MCI));

  // Create the extender.
  MCInst *XMCI =
      new (Context) MCInst(HexagonMCInstrInfo::deriveExtender(MCII, MCI, exOp));
  XMCI->setLoc(MCI.getLoc());

  MCB.addOperand(MCOperand::createInst(XMCI));
}

iterator_range<Hexagon::PacketIterator>
HexagonMCInstrInfo::bundleInstructions(MCInstrInfo const &MCII,
                                       MCInst const &MCI) {
  assert(isBundle(MCI));
  return make_range(Hexagon::PacketIterator(MCII, MCI),
                    Hexagon::PacketIterator(MCII, MCI, nullptr));
}

iterator_range<MCInst::const_iterator>
HexagonMCInstrInfo::bundleInstructions(MCInst const &MCI) {
  assert(isBundle(MCI));
  return drop_begin(MCI, bundleInstructionsOffset);
}

size_t HexagonMCInstrInfo::bundleSize(MCInst const &MCI) {
  if (HexagonMCInstrInfo::isBundle(MCI))
    return (MCI.size() - bundleInstructionsOffset);
  else
    return (1);
}

namespace {
bool canonicalizePacketImpl(MCInstrInfo const &MCII, MCSubtargetInfo const &STI,
                            MCContext &Context, MCInst &MCB,
                            HexagonMCChecker *Check) {
  // Check the bundle for errors.
  bool CheckOk = Check ? Check->check(false) : true;
  if (!CheckOk)
    return false;

  MCInst OrigMCB = MCB;

  // Examine the packet and convert pairs of instructions to compound
  // instructions when possible.
  if (!HexagonDisableCompound)
    HexagonMCInstrInfo::tryCompound(MCII, STI, Context, MCB);
  HexagonMCShuffle(Context, false, MCII, STI, MCB);

  const SmallVector<DuplexCandidate, 8> possibleDuplexes =
      (STI.getFeatureBits()[Hexagon::FeatureDuplex])
          ? HexagonMCInstrInfo::getDuplexPossibilties(MCII, STI, MCB)
          : SmallVector<DuplexCandidate, 8>();

  // Examine the packet and convert pairs of instructions to duplex
  // instructions when possible.
  HexagonMCShuffle(Context, MCII, STI, MCB, possibleDuplexes);

  // Examines packet and pad the packet, if needed, when an
  // end-loop is in the bundle.
  HexagonMCInstrInfo::padEndloop(MCB, Context);

  // If compounding and duplexing didn't reduce the size below
  // 4 or less we have a packet that is too big.
  if (HexagonMCInstrInfo::bundleSize(MCB) > HEXAGON_PACKET_SIZE) {
    if (Check)
      Check->reportError("invalid instruction packet: out of slots");
    return false;
  }
  // Check the bundle for errors.
  CheckOk = Check ? Check->check(true) : true;
  if (!CheckOk)
    return false;

  HexagonMCShuffle(Context, true, MCII, STI, MCB);

  return true;
}
} // namespace

bool HexagonMCInstrInfo::canonicalizePacket(MCInstrInfo const &MCII,
                                            MCSubtargetInfo const &STI,
                                            MCContext &Context, MCInst &MCB,
                                            HexagonMCChecker *Check,
                                            bool AttemptCompatibility) {
  auto ArchSTI = Hexagon_MC::getArchSubtarget(&STI);
  if (!AttemptCompatibility || ArchSTI == nullptr)
    return canonicalizePacketImpl(MCII, STI, Context, MCB, Check);

  const MCRegisterInfo *RI = Context.getRegisterInfo();
  HexagonMCChecker DefaultCheck(Context, MCII, STI, MCB, *RI, false);
  HexagonMCChecker *BaseCheck = (Check == nullptr) ? &DefaultCheck : Check;
  HexagonMCChecker PerfCheck(*BaseCheck, STI, false);
  if (canonicalizePacketImpl(MCII, STI, Context, MCB, &PerfCheck))
    return true;

  HexagonMCChecker ArchCheck(*BaseCheck, *ArchSTI, true);
  return canonicalizePacketImpl(MCII, *ArchSTI, Context, MCB, &ArchCheck);
}

MCInst HexagonMCInstrInfo::deriveExtender(MCInstrInfo const &MCII,
                                          MCInst const &Inst,
                                          MCOperand const &MO) {
  assert(HexagonMCInstrInfo::isExtendable(MCII, Inst) ||
         HexagonMCInstrInfo::isExtended(MCII, Inst));

  MCInst XMI;
  XMI.setOpcode(Hexagon::A4_ext);
  if (MO.isImm())
    XMI.addOperand(MCOperand::createImm(MO.getImm() & (~0x3f)));
  else if (MO.isExpr())
    XMI.addOperand(MCOperand::createExpr(MO.getExpr()));
  else
    llvm_unreachable("invalid extendable operand");
  return XMI;
}

MCInst *HexagonMCInstrInfo::deriveDuplex(MCContext &Context, unsigned iClass,
                                         MCInst const &inst0,
                                         MCInst const &inst1) {
  assert((iClass <= 0xf) && "iClass must have range of 0 to 0xf");
  MCInst *duplexInst = new (Context) MCInst;
  duplexInst->setOpcode(Hexagon::DuplexIClass0 + iClass);

  MCInst *SubInst0 = new (Context) MCInst(deriveSubInst(inst0));
  MCInst *SubInst1 = new (Context) MCInst(deriveSubInst(inst1));
  duplexInst->addOperand(MCOperand::createInst(SubInst0));
  duplexInst->addOperand(MCOperand::createInst(SubInst1));
  return duplexInst;
}

MCInst const *HexagonMCInstrInfo::extenderForIndex(MCInst const &MCB,
                                                   size_t Index) {
  assert(Index <= bundleSize(MCB));
  if (Index == 0)
    return nullptr;
  MCInst const *Inst =
      MCB.getOperand(Index + bundleInstructionsOffset - 1).getInst();
  if (isImmext(*Inst))
    return Inst;
  return nullptr;
}

void HexagonMCInstrInfo::extendIfNeeded(MCContext &Context,
                                        MCInstrInfo const &MCII, MCInst &MCB,
                                        MCInst const &MCI) {
  if (isConstExtended(MCII, MCI))
    addConstExtender(Context, MCII, MCB, MCI);
}

unsigned HexagonMCInstrInfo::getMemAccessSize(MCInstrInfo const &MCII,
      MCInst const &MCI) {
  uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
  unsigned S = (F >> HexagonII::MemAccessSizePos) & HexagonII::MemAccesSizeMask;
  return HexagonII::getMemAccessSizeInBytes(HexagonII::MemAccessSize(S));
}

unsigned HexagonMCInstrInfo::getAddrMode(MCInstrInfo const &MCII,
                                         MCInst const &MCI) {
  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
  return static_cast<unsigned>((F >> HexagonII::AddrModePos) &
                               HexagonII::AddrModeMask);
}

MCInstrDesc const &HexagonMCInstrInfo::getDesc(MCInstrInfo const &MCII,
                                               MCInst const &MCI) {
  return MCII.get(MCI.getOpcode());
}

unsigned HexagonMCInstrInfo::getDuplexRegisterNumbering(unsigned Reg) {
  using namespace Hexagon;

  switch (Reg) {
  default:
    llvm_unreachable("unknown duplex register");
  // Rs       Rss
  case R0:
  case D0:
    return 0;
  case R1:
  case D1:
    return 1;
  case R2:
  case D2:
    return 2;
  case R3:
  case D3:
    return 3;
  case R4:
  case D8:
    return 4;
  case R5:
  case D9:
    return 5;
  case R6:
  case D10:
    return 6;
  case R7:
  case D11:
    return 7;
  case R16:
    return 8;
  case R17:
    return 9;
  case R18:
    return 10;
  case R19:
    return 11;
  case R20:
    return 12;
  case R21:
    return 13;
  case R22:
    return 14;
  case R23:
    return 15;
  }
}

MCExpr const &HexagonMCInstrInfo::getExpr(MCExpr const &Expr) {
  const auto &HExpr = cast<HexagonMCExpr>(Expr);
  assert(HExpr.getExpr());
  return *HExpr.getExpr();
}

unsigned short HexagonMCInstrInfo::getExtendableOp(MCInstrInfo const &MCII,
                                                   MCInst const &MCI) {
  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
  return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask);
}

MCOperand const &
HexagonMCInstrInfo::getExtendableOperand(MCInstrInfo const &MCII,
                                         MCInst const &MCI) {
  unsigned O = HexagonMCInstrInfo::getExtendableOp(MCII, MCI);
  MCOperand const &MO = MCI.getOperand(O);

  assert((HexagonMCInstrInfo::isExtendable(MCII, MCI) ||
          HexagonMCInstrInfo::isExtended(MCII, MCI)) &&
         (MO.isImm() || MO.isExpr()));
  return (MO);
}

unsigned HexagonMCInstrInfo::getExtentAlignment(MCInstrInfo const &MCII,
                                                MCInst const &MCI) {
  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
  return ((F >> HexagonII::ExtentAlignPos) & HexagonII::ExtentAlignMask);
}

unsigned HexagonMCInstrInfo::getExtentBits(MCInstrInfo const &MCII,
                                           MCInst const &MCI) {
  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
  return ((F >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask);
}

bool HexagonMCInstrInfo::isExtentSigned(MCInstrInfo const &MCII,
                                        MCInst const &MCI) {
  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
  return (F >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask;
}

/// Return the maximum value of an extendable operand.
int HexagonMCInstrInfo::getMaxValue(MCInstrInfo const &MCII,
                                    MCInst const &MCI) {
  assert(HexagonMCInstrInfo::isExtendable(MCII, MCI) ||
         HexagonMCInstrInfo::isExtended(MCII, MCI));

  if (HexagonMCInstrInfo::isExtentSigned(MCII, MCI)) // if value is signed
    return (1 << (HexagonMCInstrInfo::getExtentBits(MCII, MCI) - 1)) - 1;
  return (1 << HexagonMCInstrInfo::getExtentBits(MCII, MCI)) - 1;
}

/// Return the minimum value of an extendable operand.
int HexagonMCInstrInfo::getMinValue(MCInstrInfo const &MCII,
                                    MCInst const &MCI) {
  assert(HexagonMCInstrInfo::isExtendable(MCII, MCI) ||
         HexagonMCInstrInfo::isExtended(MCII, MCI));

  if (HexagonMCInstrInfo::isExtentSigned(MCII, MCI)) // if value is signed
    return -(1 << (HexagonMCInstrInfo::getExtentBits(MCII, MCI) - 1));
  return 0;
}

StringRef HexagonMCInstrInfo::getName(MCInstrInfo const &MCII,
                                      MCInst const &MCI) {
  return MCII.getName(MCI.getOpcode());
}

unsigned short HexagonMCInstrInfo::getNewValueOp(MCInstrInfo const &MCII,
                                                 MCInst const &MCI) {
  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
  return ((F >> HexagonII::NewValueOpPos) & HexagonII::NewValueOpMask);
}

MCOperand const &HexagonMCInstrInfo::getNewValueOperand(MCInstrInfo const &MCII,
                                                        MCInst const &MCI) {
  if (HexagonMCInstrInfo::hasTmpDst(MCII, MCI)) {
    // VTMP doesn't actually exist in the encodings for these 184
    // 3 instructions so go ahead and create it here.
    static MCOperand MCO = MCOperand::createReg(Hexagon::VTMP);
    return (MCO);
  } else {
    unsigned O = HexagonMCInstrInfo::getNewValueOp(MCII, MCI);
    MCOperand const &MCO = MCI.getOperand(O);

    assert((HexagonMCInstrInfo::isNewValue(MCII, MCI) ||
            HexagonMCInstrInfo::hasNewValue(MCII, MCI)) &&
           MCO.isReg());
    return (MCO);
  }
}

/// Return the new value or the newly produced value.
unsigned short HexagonMCInstrInfo::getNewValueOp2(MCInstrInfo const &MCII,
                                                  MCInst const &MCI) {
  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
  return ((F >> HexagonII::NewValueOpPos2) & HexagonII::NewValueOpMask2);
}

MCOperand const &
HexagonMCInstrInfo::getNewValueOperand2(MCInstrInfo const &MCII,
                                        MCInst const &MCI) {
  unsigned O = HexagonMCInstrInfo::getNewValueOp2(MCII, MCI);
  MCOperand const &MCO = MCI.getOperand(O);

  assert((HexagonMCInstrInfo::isNewValue(MCII, MCI) ||
          HexagonMCInstrInfo::hasNewValue2(MCII, MCI)) &&
         MCO.isReg());
  return (MCO);
}

/// Return the Hexagon ISA class for the insn.
unsigned HexagonMCInstrInfo::getType(MCInstrInfo const &MCII,
                                     MCInst const &MCI) {
  const uint64_t F = MCII.get(MCI.getOpcode()).TSFlags;
  return ((F >> HexagonII::TypePos) & HexagonII::TypeMask);
}

/// Return the resources used by this instruction
unsigned HexagonMCInstrInfo::getCVIResources(MCInstrInfo const &MCII,
                                      MCSubtargetInfo const &STI,
                                      MCInst const &MCI) {

  const InstrItinerary *II = STI.getSchedModel().InstrItineraries;
  int SchedClass = HexagonMCInstrInfo::getDesc(MCII, MCI).getSchedClass();
  int Size = II[SchedClass].LastStage - II[SchedClass].FirstStage;

  // HVX resources used are currenty located at the second to last stage.
  // This could also be done with a linear search of the stages looking for:
  // CVI_ALL, CVI_MPY01, CVI_XLSHF, CVI_MPY0, CVI_MPY1, CVI_SHIFT, CVI_XLANE,
  // CVI_ZW
  unsigned Stage = II[SchedClass].LastStage - 1;

  if (Size < 2)
    return 0;
  return ((Stage + HexagonStages)->getUnits());
}

/// Return the slots this instruction can execute out of
unsigned HexagonMCInstrInfo::getUnits(MCInstrInfo const &MCII,
                                      MCSubtargetInfo const &STI,
                                      MCInst const &MCI) {
  const InstrItinerary *II = STI.getSchedModel().InstrItineraries;
  int SchedClass = HexagonMCInstrInfo::getDesc(MCII, MCI).getSchedClass();
  return ((II[SchedClass].FirstStage + HexagonStages)->getUnits());
}

/// Return the slots this instruction consumes in addition to
/// the slot(s) it can execute out of

unsigned HexagonMCInstrInfo::getOtherReservedSlots(MCInstrInfo const &MCII,
                                                   MCSubtargetInfo const &STI,
                                                   MCInst const &MCI) {
  const InstrItinerary *II = STI.getSchedModel().InstrItineraries;
  int SchedClass = HexagonMCInstrInfo::getDesc(MCII, MCI).getSchedClass();
  unsigned Slots = 0;

  // FirstStage are slots that this instruction can execute in.
  // FirstStage+1 are slots that are also consumed by this instruction.
  // For example: vmemu can only execute in slot 0 but also consumes slot 1.
  for (unsigned Stage = II[SchedClass].FirstStage + 1;
       Stage < II[SchedClass].LastStage; ++Stage) {
    unsigned Units = (Stage + HexagonStages)->getUnits();
    if (Units > HexagonGetLastSlot())
      break;
    // fyi: getUnits() will return 0x1, 0x2, 0x4 or 0x8
    Slots |= Units;
  }

  // if 0 is returned, then no additional slots are consumed by this inst.
  return Slots;
}

bool HexagonMCInstrInfo::hasDuplex(MCInstrInfo const &MCII, MCInst const &MCI) {
  if (!HexagonMCInstrInfo::isBundle(MCI))
    return false;

  for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCI)) {
    if (HexagonMCInstrInfo::isDuplex(MCII, *I.getInst()))
      return true;
  }

  return false;
}

bool HexagonMCInstrInfo::hasExtenderForIndex(MCInst const &MCB, size_t Index) {
  return extenderForIndex(MCB, Index) != nullptr;
}

bool HexagonMCInstrInfo::hasImmExt(MCInst const &MCI) {
  if (!HexagonMCInstrInfo::isBundle(MCI))
    return false;

  for (const auto &I : HexagonMCInstrInfo::bundleInstructions(MCI)) {
    if (isImmext(*I.getInst()))
      return true;
  }

  return false;
}

/// Return whether the insn produces a value.
bool HexagonMCInstrInfo::hasNewValue(MCInstrInfo const &MCII,
                                     MCInst const &MCI) {
  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
  return ((F >> HexagonII::hasNewValuePos) & HexagonII::hasNewValueMask);
}

/// Return whether the insn produces a second value.
bool HexagonMCInstrInfo::hasNewValue2(MCInstrInfo const &MCII,
                                      MCInst const &MCI) {
  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
  return ((F >> HexagonII::hasNewValuePos2) & HexagonII::hasNewValueMask2);
}

MCInst const &HexagonMCInstrInfo::instruction(MCInst const &MCB, size_t Index) {
  assert(isBundle(MCB));
  assert(Index < HEXAGON_PRESHUFFLE_PACKET_SIZE);
  return *MCB.getOperand(bundleInstructionsOffset + Index).getInst();
}

/// Return where the instruction is an accumulator.
bool HexagonMCInstrInfo::isAccumulator(MCInstrInfo const &MCII,
                                       MCInst const &MCI) {
  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
  return ((F >> HexagonII::AccumulatorPos) & HexagonII::AccumulatorMask);
}

bool HexagonMCInstrInfo::isBundle(MCInst const &MCI) {
  auto Result = Hexagon::BUNDLE == MCI.getOpcode();
  assert(!Result || (MCI.size() > 0 && MCI.getOperand(0).isImm()));
  return Result;
}

bool HexagonMCInstrInfo::isConstExtended(MCInstrInfo const &MCII,
                                         MCInst const &MCI) {
  if (HexagonMCInstrInfo::isExtended(MCII, MCI))
    return true;
  if (!HexagonMCInstrInfo::isExtendable(MCII, MCI))
    return false;
  MCOperand const &MO = HexagonMCInstrInfo::getExtendableOperand(MCII, MCI);
  if (isa<HexagonMCExpr>(MO.getExpr()) &&
      HexagonMCInstrInfo::mustExtend(*MO.getExpr()))
    return true;
  // Branch insns are handled as necessary by relaxation.
  if ((HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeJ) ||
      (HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeCJ &&
       HexagonMCInstrInfo::getDesc(MCII, MCI).isBranch()) ||
      (HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeNCJ &&
       HexagonMCInstrInfo::getDesc(MCII, MCI).isBranch()))
    return false;
  // Otherwise loop instructions and other CR insts are handled by relaxation
  else if ((HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeCR) &&
           (MCI.getOpcode() != Hexagon::C4_addipc))
    return false;

  assert(!MO.isImm());
  if (isa<HexagonMCExpr>(MO.getExpr()) &&
      HexagonMCInstrInfo::mustNotExtend(*MO.getExpr()))
    return false;
  int64_t Value;
  if (!MO.getExpr()->evaluateAsAbsolute(Value))
    return true;
  int MinValue = HexagonMCInstrInfo::getMinValue(MCII, MCI);
  int MaxValue = HexagonMCInstrInfo::getMaxValue(MCII, MCI);
  return (MinValue > Value || Value > MaxValue);
}

bool HexagonMCInstrInfo::isCanon(MCInstrInfo const &MCII, MCInst const &MCI) {
  return !HexagonMCInstrInfo::getDesc(MCII, MCI).isPseudo() &&
         !HexagonMCInstrInfo::isPrefix(MCII, MCI);
}

bool HexagonMCInstrInfo::isCofMax1(MCInstrInfo const &MCII, MCInst const &MCI) {
  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
  return ((F >> HexagonII::CofMax1Pos) & HexagonII::CofMax1Mask);
}

bool HexagonMCInstrInfo::isCofRelax1(MCInstrInfo const &MCII,
                                     MCInst const &MCI) {
  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
  return ((F >> HexagonII::CofRelax1Pos) & HexagonII::CofRelax1Mask);
}

bool HexagonMCInstrInfo::isCofRelax2(MCInstrInfo const &MCII,
                                     MCInst const &MCI) {
  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
  return ((F >> HexagonII::CofRelax2Pos) & HexagonII::CofRelax2Mask);
}

bool HexagonMCInstrInfo::isCompound(MCInstrInfo const &MCII,
                                    MCInst const &MCI) {
  return (getType(MCII, MCI) == HexagonII::TypeCJ);
}

bool HexagonMCInstrInfo::isCVINew(MCInstrInfo const &MCII, MCInst const &MCI) {
  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
  return ((F >> HexagonII::CVINewPos) & HexagonII::CVINewMask);
}

bool HexagonMCInstrInfo::isDblRegForSubInst(unsigned Reg) {
  return ((Reg >= Hexagon::D0 && Reg <= Hexagon::D3) ||
          (Reg >= Hexagon::D8 && Reg <= Hexagon::D11));
}

bool HexagonMCInstrInfo::isDuplex(MCInstrInfo const &MCII, MCInst const &MCI) {
  return HexagonII::TypeDUPLEX == HexagonMCInstrInfo::getType(MCII, MCI);
}

bool HexagonMCInstrInfo::isExtendable(MCInstrInfo const &MCII,
                                      MCInst const &MCI) {
  uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
  return (F >> HexagonII::ExtendablePos) & HexagonII::ExtendableMask;
}

bool HexagonMCInstrInfo::isExtended(MCInstrInfo const &MCII,
                                    MCInst const &MCI) {
  uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
  return (F >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask;
}

bool HexagonMCInstrInfo::isFloat(MCInstrInfo const &MCII, MCInst const &MCI) {
  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
  return ((F >> HexagonII::FPPos) & HexagonII::FPMask);
}

bool HexagonMCInstrInfo::isHVX(MCInstrInfo const &MCII, MCInst const &MCI) {
  const uint64_t V = getType(MCII, MCI);
  return HexagonII::TypeCVI_FIRST <= V && V <= HexagonII::TypeCVI_LAST;
}

bool HexagonMCInstrInfo::isImmext(MCInst const &MCI) {
  return MCI.getOpcode() == Hexagon::A4_ext;
}

bool HexagonMCInstrInfo::isInnerLoop(MCInst const &MCI) {
  assert(isBundle(MCI));
  int64_t Flags = MCI.getOperand(0).getImm();
  return (Flags & innerLoopMask) != 0;
}

bool HexagonMCInstrInfo::isIntReg(unsigned Reg) {
  return (Reg >= Hexagon::R0 && Reg <= Hexagon::R31);
}

bool HexagonMCInstrInfo::isIntRegForSubInst(unsigned Reg) {
  return ((Reg >= Hexagon::R0 && Reg <= Hexagon::R7) ||
          (Reg >= Hexagon::R16 && Reg <= Hexagon::R23));
}

/// Return whether the insn expects newly produced value.
bool HexagonMCInstrInfo::isNewValue(MCInstrInfo const &MCII,
                                    MCInst const &MCI) {
  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
  return ((F >> HexagonII::NewValuePos) & HexagonII::NewValueMask);
}

bool HexagonMCInstrInfo::isNewValueStore(MCInstrInfo const &MCII,
                                         MCInst const &MCI) {
  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
  return (F >> HexagonII::NVStorePos) & HexagonII::NVStoreMask;
}

/// Return whether the operand is extendable.
bool HexagonMCInstrInfo::isOpExtendable(MCInstrInfo const &MCII,
                                        MCInst const &MCI, unsigned short O) {
  return (O == HexagonMCInstrInfo::getExtendableOp(MCII, MCI));
}

bool HexagonMCInstrInfo::isOuterLoop(MCInst const &MCI) {
  assert(isBundle(MCI));
  int64_t Flags = MCI.getOperand(0).getImm();
  return (Flags & outerLoopMask) != 0;
}

bool HexagonMCInstrInfo::IsVecRegPair(unsigned VecReg) {
  return (VecReg >= Hexagon::W0 && VecReg <= Hexagon::W15) ||
         (VecReg >= Hexagon::WR0 && VecReg <= Hexagon::WR15);
}

bool HexagonMCInstrInfo::IsReverseVecRegPair(unsigned VecReg) {
  return (VecReg >= Hexagon::WR0 && VecReg <= Hexagon::WR15);
}

bool HexagonMCInstrInfo::IsVecRegSingle(unsigned VecReg) {
  return (VecReg >= Hexagon::V0 && VecReg <= Hexagon::V31);
}

std::pair<unsigned, unsigned>
HexagonMCInstrInfo::GetVecRegPairIndices(unsigned VecRegPair) {
  assert(IsVecRegPair(VecRegPair) &&
         "VecRegPair must be a vector register pair");

  const bool IsRev = IsReverseVecRegPair(VecRegPair);
  const unsigned PairIndex =
      2 * (IsRev ? VecRegPair - Hexagon::WR0 : VecRegPair - Hexagon::W0);

  return IsRev ? std::make_pair(PairIndex, PairIndex + 1)
               : std::make_pair(PairIndex + 1, PairIndex);
}

bool HexagonMCInstrInfo::IsSingleConsumerRefPairProducer(unsigned Producer,
                                                         unsigned Consumer) {
  if (IsVecRegPair(Producer) && IsVecRegSingle(Consumer)) {
    const unsigned ProdPairIndex = IsReverseVecRegPair(Producer)
                                       ? Producer - Hexagon::WR0
                                       : Producer - Hexagon::W0;
    const unsigned ConsumerSingleIndex = (Consumer - Hexagon::V0) >> 1;

    return ConsumerSingleIndex == ProdPairIndex;
  }
  return false;
}

bool HexagonMCInstrInfo::isPredicated(MCInstrInfo const &MCII,
                                      MCInst const &MCI) {
  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
  return ((F >> HexagonII::PredicatedPos) & HexagonII::PredicatedMask);
}

bool HexagonMCInstrInfo::isPrefix(MCInstrInfo const &MCII, MCInst const &MCI) {
  return HexagonII::TypeEXTENDER == HexagonMCInstrInfo::getType(MCII, MCI);
}

bool HexagonMCInstrInfo::isPredicateLate(MCInstrInfo const &MCII,
                                         MCInst const &MCI) {
  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
  return (F >> HexagonII::PredicateLatePos & HexagonII::PredicateLateMask);
}

/// Return whether the insn is newly predicated.
bool HexagonMCInstrInfo::isPredicatedNew(MCInstrInfo const &MCII,
                                         MCInst const &MCI) {
  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
  return ((F >> HexagonII::PredicatedNewPos) & HexagonII::PredicatedNewMask);
}

bool HexagonMCInstrInfo::isPredicatedTrue(MCInstrInfo const &MCII,
                                          MCInst const &MCI) {
  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
  return (
      !((F >> HexagonII::PredicatedFalsePos) & HexagonII::PredicatedFalseMask));
}

bool HexagonMCInstrInfo::isPredReg(MCRegisterInfo const &MRI, unsigned Reg) {
  auto &PredRegClass = MRI.getRegClass(Hexagon::PredRegsRegClassID);
  return PredRegClass.contains(Reg);
}

bool HexagonMCInstrInfo::isPredRegister(MCInstrInfo const &MCII,
                                        MCInst const &Inst, unsigned I) {
  MCInstrDesc const &Desc = HexagonMCInstrInfo::getDesc(MCII, Inst);

  return Inst.getOperand(I).isReg() &&
         Desc.operands()[I].RegClass == Hexagon::PredRegsRegClassID;
}

/// Return whether the insn can be packaged only with A and X-type insns.
bool HexagonMCInstrInfo::isSoloAX(MCInstrInfo const &MCII, MCInst const &MCI) {
  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
  return ((F >> HexagonII::SoloAXPos) & HexagonII::SoloAXMask);
}

/// Return whether the insn can be packaged only with an A-type insn in slot #1.
bool HexagonMCInstrInfo::isRestrictSlot1AOK(MCInstrInfo const &MCII,
                                            MCInst const &MCI) {
  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
  return ((F >> HexagonII::RestrictSlot1AOKPos) &
          HexagonII::RestrictSlot1AOKMask);
}

bool HexagonMCInstrInfo::isRestrictNoSlot1Store(MCInstrInfo const &MCII,
                                                MCInst const &MCI) {
  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
  return ((F >> HexagonII::RestrictNoSlot1StorePos) &
          HexagonII::RestrictNoSlot1StoreMask);
}

/// Return whether the insn is solo, i.e., cannot be in a packet.
bool HexagonMCInstrInfo::isSolo(MCInstrInfo const &MCII, MCInst const &MCI) {
  const uint64_t F = MCII.get(MCI.getOpcode()).TSFlags;
  return ((F >> HexagonII::SoloPos) & HexagonII::SoloMask);
}

bool HexagonMCInstrInfo::isMemReorderDisabled(MCInst const &MCI) {
  assert(isBundle(MCI));
  auto Flags = MCI.getOperand(0).getImm();
  return (Flags & memReorderDisabledMask) != 0;
}

bool HexagonMCInstrInfo::isSubInstruction(MCInst const &MCI) {
  switch (MCI.getOpcode()) {
  default:
    return false;
  case Hexagon::SA1_addi:
  case Hexagon::SA1_addrx:
  case Hexagon::SA1_addsp:
  case Hexagon::SA1_and1:
  case Hexagon::SA1_clrf:
  case Hexagon::SA1_clrfnew:
  case Hexagon::SA1_clrt:
  case Hexagon::SA1_clrtnew:
  case Hexagon::SA1_cmpeqi:
  case Hexagon::SA1_combine0i:
  case Hexagon::SA1_combine1i:
  case Hexagon::SA1_combine2i:
  case Hexagon::SA1_combine3i:
  case Hexagon::SA1_combinerz:
  case Hexagon::SA1_combinezr:
  case Hexagon::SA1_dec:
  case Hexagon::SA1_inc:
  case Hexagon::SA1_seti:
  case Hexagon::SA1_setin1:
  case Hexagon::SA1_sxtb:
  case Hexagon::SA1_sxth:
  case Hexagon::SA1_tfr:
  case Hexagon::SA1_zxtb:
  case Hexagon::SA1_zxth:
  case Hexagon::SL1_loadri_io:
  case Hexagon::SL1_loadrub_io:
  case Hexagon::SL2_deallocframe:
  case Hexagon::SL2_jumpr31:
  case Hexagon::SL2_jumpr31_f:
  case Hexagon::SL2_jumpr31_fnew:
  case Hexagon::SL2_jumpr31_t:
  case Hexagon::SL2_jumpr31_tnew:
  case Hexagon::SL2_loadrb_io:
  case Hexagon::SL2_loadrd_sp:
  case Hexagon::SL2_loadrh_io:
  case Hexagon::SL2_loadri_sp:
  case Hexagon::SL2_loadruh_io:
  case Hexagon::SL2_return:
  case Hexagon::SL2_return_f:
  case Hexagon::SL2_return_fnew:
  case Hexagon::SL2_return_t:
  case Hexagon::SL2_return_tnew:
  case Hexagon::SS1_storeb_io:
  case Hexagon::SS1_storew_io:
  case Hexagon::SS2_allocframe:
  case Hexagon::SS2_storebi0:
  case Hexagon::SS2_storebi1:
  case Hexagon::SS2_stored_sp:
  case Hexagon::SS2_storeh_io:
  case Hexagon::SS2_storew_sp:
  case Hexagon::SS2_storewi0:
  case Hexagon::SS2_storewi1:
    return true;
  }
}

bool HexagonMCInstrInfo::isVector(MCInstrInfo const &MCII, MCInst const &MCI) {
  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
  return (F >> HexagonII::isCVIPos) & HexagonII::isCVIMask;
}

int64_t HexagonMCInstrInfo::minConstant(MCInst const &MCI, size_t Index) {
  auto Sentinel = static_cast<int64_t>(std::numeric_limits<uint32_t>::max())
                  << 8;
  if (MCI.size() <= Index)
    return Sentinel;
  MCOperand const &MCO = MCI.getOperand(Index);
  if (!MCO.isExpr())
    return Sentinel;
  int64_t Value;
  if (!MCO.getExpr()->evaluateAsAbsolute(Value))
    return Sentinel;
  return Value;
}

void HexagonMCInstrInfo::setMustExtend(MCExpr const &Expr, bool Val) {
  HexagonMCExpr &HExpr = const_cast<HexagonMCExpr &>(cast<HexagonMCExpr>(Expr));
  HExpr.setMustExtend(Val);
}

bool HexagonMCInstrInfo::mustExtend(MCExpr const &Expr) {
  HexagonMCExpr const &HExpr = cast<HexagonMCExpr>(Expr);
  return HExpr.mustExtend();
}
void HexagonMCInstrInfo::setMustNotExtend(MCExpr const &Expr, bool Val) {
  HexagonMCExpr &HExpr = const_cast<HexagonMCExpr &>(cast<HexagonMCExpr>(Expr));
  HExpr.setMustNotExtend(Val);
}
bool HexagonMCInstrInfo::mustNotExtend(MCExpr const &Expr) {
  HexagonMCExpr const &HExpr = cast<HexagonMCExpr>(Expr);
  return HExpr.mustNotExtend();
}
void HexagonMCInstrInfo::setS27_2_reloc(MCExpr const &Expr, bool Val) {
  HexagonMCExpr &HExpr =
      const_cast<HexagonMCExpr &>(*cast<HexagonMCExpr>(&Expr));
  HExpr.setS27_2_reloc(Val);
}
bool HexagonMCInstrInfo::s27_2_reloc(MCExpr const &Expr) {
  HexagonMCExpr const *HExpr = dyn_cast<HexagonMCExpr>(&Expr);
  if (!HExpr)
    return false;
  return HExpr->s27_2_reloc();
}

unsigned HexagonMCInstrInfo::packetSizeSlots(MCSubtargetInfo const &STI) {
  const bool IsTiny = STI.getFeatureBits()[Hexagon::ProcTinyCore];

  return IsTiny ? (HEXAGON_PACKET_SIZE - 1) : HEXAGON_PACKET_SIZE;
}

unsigned HexagonMCInstrInfo::packetSize(StringRef CPU) {
  return llvm::StringSwitch<unsigned>(CPU)
      .Case("hexagonv67t", 3)
      .Default(4);
}

void HexagonMCInstrInfo::padEndloop(MCInst &MCB, MCContext &Context) {
  MCInst Nop;
  Nop.setOpcode(Hexagon::A2_nop);
  assert(isBundle(MCB));
  while (LoopNeedsPadding(MCB))
    MCB.addOperand(MCOperand::createInst(new (Context) MCInst(Nop)));
}

HexagonMCInstrInfo::PredicateInfo
HexagonMCInstrInfo::predicateInfo(MCInstrInfo const &MCII, MCInst const &MCI) {
  if (!isPredicated(MCII, MCI))
    return {0, 0, false};
  MCInstrDesc const &Desc = getDesc(MCII, MCI);
  for (auto I = Desc.getNumDefs(), N = Desc.getNumOperands(); I != N; ++I)
    if (Desc.operands()[I].RegClass == Hexagon::PredRegsRegClassID)
      return {MCI.getOperand(I).getReg(), I, isPredicatedTrue(MCII, MCI)};
  return {0, 0, false};
}

bool HexagonMCInstrInfo::prefersSlot3(MCInstrInfo const &MCII,
                                      MCInst const &MCI) {
  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
  return (F >> HexagonII::PrefersSlot3Pos) & HexagonII::PrefersSlot3Mask;
}

bool HexagonMCInstrInfo::hasTmpDst(MCInstrInfo const &MCII, MCInst const &MCI) {
  switch (MCI.getOpcode()) {
  default:
    return false;
  case Hexagon::V6_vgathermh:
  case Hexagon::V6_vgathermhq:
  case Hexagon::V6_vgathermhw:
  case Hexagon::V6_vgathermhwq:
  case Hexagon::V6_vgathermw:
  case Hexagon::V6_vgathermwq:
    return true;
  }
  return false;
}

bool HexagonMCInstrInfo::hasHvxTmp(MCInstrInfo const &MCII, MCInst const &MCI) {
  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
  return (F >> HexagonII::HasHvxTmpPos) & HexagonII::HasHvxTmpMask;
}

bool HexagonMCInstrInfo::requiresSlot(MCSubtargetInfo const &STI,
                                      MCInst const &MCI) {
  const unsigned OpCode = MCI.getOpcode();
  const bool IsTiny = STI.getFeatureBits() [Hexagon::ProcTinyCore];
  const bool NoSlotReqd = Hexagon::A4_ext == OpCode ||
                          (IsTiny && Hexagon::A2_nop == OpCode) ||
                          (IsTiny && Hexagon::J4_hintjumpr == OpCode);

  return !NoSlotReqd;
}

unsigned HexagonMCInstrInfo::slotsConsumed(MCInstrInfo const &MCII,
                                           MCSubtargetInfo const &STI,
                                           MCInst const &MCI) {
  unsigned slotsUsed = 0;
  for (auto HMI : bundleInstructions(MCI)) {
    MCInst const &MCI = *HMI.getInst();
    if (!requiresSlot(STI, MCI))
      continue;
    if (isDuplex(MCII, MCI))
      slotsUsed += 2;
    else
      ++slotsUsed;
  }
  return slotsUsed;
}

void HexagonMCInstrInfo::replaceDuplex(MCContext &Context, MCInst &MCB,
                                       DuplexCandidate Candidate) {
  assert(Candidate.packetIndexI < MCB.size());
  assert(Candidate.packetIndexJ < MCB.size());
  assert(isBundle(MCB));
  MCInst *Duplex =
      deriveDuplex(Context, Candidate.iClass,
                   *MCB.getOperand(Candidate.packetIndexJ).getInst(),
                   *MCB.getOperand(Candidate.packetIndexI).getInst());
  assert(Duplex != nullptr);
  MCB.getOperand(Candidate.packetIndexI).setInst(Duplex);
  MCB.erase(MCB.begin() + Candidate.packetIndexJ);
}

void HexagonMCInstrInfo::setInnerLoop(MCInst &MCI) {
  assert(isBundle(MCI));
  MCOperand &Operand = MCI.getOperand(0);
  Operand.setImm(Operand.getImm() | innerLoopMask);
}

void HexagonMCInstrInfo::setMemReorderDisabled(MCInst &MCI) {
  assert(isBundle(MCI));
  MCOperand &Operand = MCI.getOperand(0);
  Operand.setImm(Operand.getImm() | memReorderDisabledMask);
  assert(isMemReorderDisabled(MCI));
}

void HexagonMCInstrInfo::setOuterLoop(MCInst &MCI) {
  assert(isBundle(MCI));
  MCOperand &Operand = MCI.getOperand(0);
  Operand.setImm(Operand.getImm() | outerLoopMask);
}

unsigned HexagonMCInstrInfo::SubregisterBit(unsigned Consumer,
                                            unsigned Producer,
                                            unsigned Producer2) {
  // If we're a single vector consumer of a double producer, set subreg bit
  // based on if we're accessing the lower or upper register component
  if (IsVecRegPair(Producer) && IsVecRegSingle(Consumer))
    return (Consumer - Hexagon::V0) & 0x1;
  if (Producer2 != Hexagon::NoRegister)
    return Consumer == Producer;
  return 0;
}

bool HexagonMCInstrInfo::LoopNeedsPadding(MCInst const &MCB) {
  return (
      (HexagonMCInstrInfo::isInnerLoop(MCB) &&
       (HexagonMCInstrInfo::bundleSize(MCB) < HEXAGON_PACKET_INNER_SIZE)) ||
      ((HexagonMCInstrInfo::isOuterLoop(MCB) &&
        (HexagonMCInstrInfo::bundleSize(MCB) < HEXAGON_PACKET_OUTER_SIZE))));
}

bool HexagonMCInstrInfo::IsABranchingInst(MCInstrInfo const &MCII,
                                          MCSubtargetInfo const &STI,
                                          MCInst const &I) {
  assert(!HexagonMCInstrInfo::isBundle(I));
  MCInstrDesc const &Desc = HexagonMCInstrInfo::getDesc(MCII, I);
  return (Desc.isBranch() || Desc.isCall() || Desc.isReturn());
}
