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

  // Examine the packet and convert pairs of instructions to duplex
  // instructions when possible.
  if (STI.getFeatureBits() [Hexagon::FeatureDuplex]) {
    SmallVector<DuplexCandidate, 8> possibleDuplexes;
    possibleDuplexes =
        HexagonMCInstrInfo::getDuplexPossibilties(MCII, STI, MCB);
    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.OpInfo[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 Sentinal = static_cast<int64_t>(std::numeric_limits<uint32_t>::max())
                  << 8;
  if (MCI.size() <= Index)
    return Sentinal;
  MCOperand const &MCO = MCI.getOperand(Index);
  if (!MCO.isExpr())
    return Sentinal;
  int64_t Value;
  if (!MCO.getExpr()->evaluateAsAbsolute(Value))
    return Sentinal;
  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 ((HexagonMCInstrInfo::isInnerLoop(MCB) &&
          (HexagonMCInstrInfo::bundleSize(MCB) < HEXAGON_PACKET_INNER_SIZE)) ||
         ((HexagonMCInstrInfo::isOuterLoop(MCB) &&
           (HexagonMCInstrInfo::bundleSize(MCB) < HEXAGON_PACKET_OUTER_SIZE))))
    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.OpInfo[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;
}

/// return true if instruction has hasTmpDst attribute.
bool HexagonMCInstrInfo::hasTmpDst(MCInstrInfo const &MCII, MCInst const &MCI) {
  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
  return (F >> HexagonII::HasTmpDstPos) & HexagonII::HasTmpDstMask;
}

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