brintos

brintos / llvm-project-archived public Read only

0
0
Text · 38.1 KiB · b27b8bb Raw
1063 lines · cpp
1//===- HexagonMCInstrInfo.cpp - Hexagon sub-class of MCInst ---------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This class extends MCInstrInfo to allow Hexagon specific MCInstr queries10//11//===----------------------------------------------------------------------===//12 13#include "MCTargetDesc/HexagonMCInstrInfo.h"14#include "MCTargetDesc/HexagonBaseInfo.h"15#include "MCTargetDesc/HexagonMCChecker.h"16#include "MCTargetDesc/HexagonMCExpr.h"17#include "MCTargetDesc/HexagonMCShuffler.h"18#include "MCTargetDesc/HexagonMCTargetDesc.h"19#include "llvm/ADT/SmallVector.h"20#include "llvm/ADT/StringSwitch.h"21#include "llvm/MC/MCContext.h"22#include "llvm/MC/MCExpr.h"23#include "llvm/MC/MCInst.h"24#include "llvm/MC/MCInstrInfo.h"25#include "llvm/MC/MCInstrItineraries.h"26#include "llvm/MC/MCSubtargetInfo.h"27#include "llvm/Support/Casting.h"28#include "llvm/Support/ErrorHandling.h"29#include <cassert>30#include <cstdint>31#include <limits>32 33using namespace llvm;34 35bool HexagonMCInstrInfo::PredicateInfo::isPredicated() const {36  return Register != Hexagon::NoRegister;37}38 39Hexagon::PacketIterator::PacketIterator(MCInstrInfo const &MCII,40                                        MCInst const &Inst)41    : MCII(MCII), BundleCurrent(Inst.begin() +42                                HexagonMCInstrInfo::bundleInstructionsOffset),43      BundleEnd(Inst.end()), DuplexCurrent(Inst.end()), DuplexEnd(Inst.end()) {}44 45Hexagon::PacketIterator::PacketIterator(MCInstrInfo const &MCII,46                                        MCInst const &Inst, std::nullptr_t)47    : MCII(MCII), BundleCurrent(Inst.end()), BundleEnd(Inst.end()),48      DuplexCurrent(Inst.end()), DuplexEnd(Inst.end()) {}49 50Hexagon::PacketIterator &Hexagon::PacketIterator::operator++() {51  if (DuplexCurrent != DuplexEnd) {52    ++DuplexCurrent;53    if (DuplexCurrent == DuplexEnd) {54      DuplexCurrent = BundleEnd;55      DuplexEnd = BundleEnd;56      ++BundleCurrent;57    }58    return *this;59  }60  ++BundleCurrent;61  if (BundleCurrent != BundleEnd) {62    MCInst const &Inst = *BundleCurrent->getInst();63    if (HexagonMCInstrInfo::isDuplex(MCII, Inst)) {64      DuplexCurrent = Inst.begin();65      DuplexEnd = Inst.end();66    }67  }68  return *this;69}70 71MCInst const &Hexagon::PacketIterator::operator*() const {72  if (DuplexCurrent != DuplexEnd)73    return *DuplexCurrent->getInst();74  return *BundleCurrent->getInst();75}76 77bool Hexagon::PacketIterator::operator==(PacketIterator const &Other) const {78  return BundleCurrent == Other.BundleCurrent && BundleEnd == Other.BundleEnd &&79         DuplexCurrent == Other.DuplexCurrent && DuplexEnd == Other.DuplexEnd;80}81 82void HexagonMCInstrInfo::addConstant(MCInst &MI, uint64_t Value,83                                     MCContext &Context) {84  MI.addOperand(MCOperand::createExpr(MCConstantExpr::create(Value, Context)));85}86 87void HexagonMCInstrInfo::addConstExtender(MCContext &Context,88                                          MCInstrInfo const &MCII, MCInst &MCB,89                                          MCInst const &MCI) {90  assert(HexagonMCInstrInfo::isBundle(MCB));91  MCOperand const &exOp =92      MCI.getOperand(HexagonMCInstrInfo::getExtendableOp(MCII, MCI));93 94  // Create the extender.95  MCInst *XMCI =96      new (Context) MCInst(HexagonMCInstrInfo::deriveExtender(MCII, MCI, exOp));97  XMCI->setLoc(MCI.getLoc());98 99  MCB.addOperand(MCOperand::createInst(XMCI));100}101 102iterator_range<Hexagon::PacketIterator>103HexagonMCInstrInfo::bundleInstructions(MCInstrInfo const &MCII,104                                       MCInst const &MCI) {105  assert(isBundle(MCI));106  return make_range(Hexagon::PacketIterator(MCII, MCI),107                    Hexagon::PacketIterator(MCII, MCI, nullptr));108}109 110iterator_range<MCInst::const_iterator>111HexagonMCInstrInfo::bundleInstructions(MCInst const &MCI) {112  assert(isBundle(MCI));113  return drop_begin(MCI, bundleInstructionsOffset);114}115 116size_t HexagonMCInstrInfo::bundleSize(MCInst const &MCI) {117  if (HexagonMCInstrInfo::isBundle(MCI))118    return (MCI.size() - bundleInstructionsOffset);119  else120    return (1);121}122 123namespace {124bool canonicalizePacketImpl(MCInstrInfo const &MCII, MCSubtargetInfo const &STI,125                            MCContext &Context, MCInst &MCB,126                            HexagonMCChecker *Check) {127  // Check the bundle for errors.128  bool CheckOk = Check ? Check->check(false) : true;129  if (!CheckOk)130    return false;131 132  MCInst OrigMCB = MCB;133 134  // Examine the packet and convert pairs of instructions to compound135  // instructions when possible.136  if (!HexagonDisableCompound)137    HexagonMCInstrInfo::tryCompound(MCII, STI, Context, MCB);138  HexagonMCShuffle(Context, false, MCII, STI, MCB);139 140  const SmallVector<DuplexCandidate, 8> possibleDuplexes =141      (STI.hasFeature(Hexagon::FeatureDuplex))142          ? HexagonMCInstrInfo::getDuplexPossibilties(MCII, STI, MCB)143          : SmallVector<DuplexCandidate, 8>();144 145  // Examine the packet and convert pairs of instructions to duplex146  // instructions when possible.147  HexagonMCShuffle(Context, MCII, STI, MCB, possibleDuplexes);148 149  // Examines packet and pad the packet, if needed, when an150  // end-loop is in the bundle.151  HexagonMCInstrInfo::padEndloop(MCB, Context);152 153  // If compounding and duplexing didn't reduce the size below154  // 4 or less we have a packet that is too big.155  if (HexagonMCInstrInfo::bundleSize(MCB) > HEXAGON_PACKET_SIZE) {156    if (Check)157      Check->reportError("invalid instruction packet: out of slots");158    return false;159  }160  // Check the bundle for errors.161  CheckOk = Check ? Check->check(true) : true;162  if (!CheckOk)163    return false;164 165  HexagonMCShuffle(Context, true, MCII, STI, MCB);166 167  return true;168}169} // namespace170 171bool HexagonMCInstrInfo::canonicalizePacket(MCInstrInfo const &MCII,172                                            MCSubtargetInfo const &STI,173                                            MCContext &Context, MCInst &MCB,174                                            HexagonMCChecker *Check,175                                            bool AttemptCompatibility) {176  auto ArchSTI = Hexagon_MC::getArchSubtarget(&STI);177  if (!AttemptCompatibility || ArchSTI == nullptr)178    return canonicalizePacketImpl(MCII, STI, Context, MCB, Check);179 180  const MCRegisterInfo *RI = Context.getRegisterInfo();181  HexagonMCChecker DefaultCheck(Context, MCII, STI, MCB, *RI, false);182  HexagonMCChecker *BaseCheck = (Check == nullptr) ? &DefaultCheck : Check;183  HexagonMCChecker PerfCheck(*BaseCheck, STI, false);184  if (canonicalizePacketImpl(MCII, STI, Context, MCB, &PerfCheck))185    return true;186 187  HexagonMCChecker ArchCheck(*BaseCheck, *ArchSTI, true);188  return canonicalizePacketImpl(MCII, *ArchSTI, Context, MCB, &ArchCheck);189}190 191MCInst HexagonMCInstrInfo::deriveExtender(MCInstrInfo const &MCII,192                                          MCInst const &Inst,193                                          MCOperand const &MO) {194  assert(HexagonMCInstrInfo::isExtendable(MCII, Inst) ||195         HexagonMCInstrInfo::isExtended(MCII, Inst));196 197  MCInst XMI;198  XMI.setOpcode(Hexagon::A4_ext);199  if (MO.isImm())200    XMI.addOperand(MCOperand::createImm(MO.getImm() & (~0x3f)));201  else if (MO.isExpr())202    XMI.addOperand(MCOperand::createExpr(MO.getExpr()));203  else204    llvm_unreachable("invalid extendable operand");205  return XMI;206}207 208MCInst *HexagonMCInstrInfo::deriveDuplex(MCContext &Context, unsigned iClass,209                                         MCInst const &inst0,210                                         MCInst const &inst1) {211  assert((iClass <= 0xf) && "iClass must have range of 0 to 0xf");212  MCInst *duplexInst = new (Context) MCInst;213  duplexInst->setOpcode(Hexagon::DuplexIClass0 + iClass);214 215  MCInst *SubInst0 = new (Context) MCInst(deriveSubInst(inst0));216  MCInst *SubInst1 = new (Context) MCInst(deriveSubInst(inst1));217  duplexInst->addOperand(MCOperand::createInst(SubInst0));218  duplexInst->addOperand(MCOperand::createInst(SubInst1));219  return duplexInst;220}221 222MCInst const *HexagonMCInstrInfo::extenderForIndex(MCInst const &MCB,223                                                   size_t Index) {224  assert(Index <= bundleSize(MCB));225  if (Index == 0)226    return nullptr;227  MCInst const *Inst =228      MCB.getOperand(Index + bundleInstructionsOffset - 1).getInst();229  if (isImmext(*Inst))230    return Inst;231  return nullptr;232}233 234void HexagonMCInstrInfo::extendIfNeeded(MCContext &Context,235                                        MCInstrInfo const &MCII, MCInst &MCB,236                                        MCInst const &MCI) {237  if (isConstExtended(MCII, MCI))238    addConstExtender(Context, MCII, MCB, MCI);239}240 241unsigned HexagonMCInstrInfo::getMemAccessSize(MCInstrInfo const &MCII,242      MCInst const &MCI) {243  uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;244  unsigned S = (F >> HexagonII::MemAccessSizePos) & HexagonII::MemAccesSizeMask;245  return HexagonII::getMemAccessSizeInBytes(HexagonII::MemAccessSize(S));246}247 248unsigned HexagonMCInstrInfo::getAddrMode(MCInstrInfo const &MCII,249                                         MCInst const &MCI) {250  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;251  return static_cast<unsigned>((F >> HexagonII::AddrModePos) &252                               HexagonII::AddrModeMask);253}254 255MCInstrDesc const &HexagonMCInstrInfo::getDesc(MCInstrInfo const &MCII,256                                               MCInst const &MCI) {257  return MCII.get(MCI.getOpcode());258}259 260unsigned HexagonMCInstrInfo::getDuplexRegisterNumbering(MCRegister Reg) {261  using namespace Hexagon;262 263  switch (Reg.id()) {264  default:265    llvm_unreachable("unknown duplex register");266  // Rs       Rss267  case R0:268  case D0:269    return 0;270  case R1:271  case D1:272    return 1;273  case R2:274  case D2:275    return 2;276  case R3:277  case D3:278    return 3;279  case R4:280  case D8:281    return 4;282  case R5:283  case D9:284    return 5;285  case R6:286  case D10:287    return 6;288  case R7:289  case D11:290    return 7;291  case R16:292    return 8;293  case R17:294    return 9;295  case R18:296    return 10;297  case R19:298    return 11;299  case R20:300    return 12;301  case R21:302    return 13;303  case R22:304    return 14;305  case R23:306    return 15;307  }308}309 310MCExpr const &HexagonMCInstrInfo::getExpr(MCExpr const &Expr) {311  const auto &HExpr = cast<HexagonMCExpr>(Expr);312  assert(HExpr.getExpr());313  return *HExpr.getExpr();314}315 316unsigned short HexagonMCInstrInfo::getExtendableOp(MCInstrInfo const &MCII,317                                                   MCInst const &MCI) {318  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;319  return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask);320}321 322MCOperand const &323HexagonMCInstrInfo::getExtendableOperand(MCInstrInfo const &MCII,324                                         MCInst const &MCI) {325  unsigned O = HexagonMCInstrInfo::getExtendableOp(MCII, MCI);326  MCOperand const &MO = MCI.getOperand(O);327 328  assert((HexagonMCInstrInfo::isExtendable(MCII, MCI) ||329          HexagonMCInstrInfo::isExtended(MCII, MCI)) &&330         (MO.isImm() || MO.isExpr()));331  return (MO);332}333 334unsigned HexagonMCInstrInfo::getExtentAlignment(MCInstrInfo const &MCII,335                                                MCInst const &MCI) {336  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;337  return ((F >> HexagonII::ExtentAlignPos) & HexagonII::ExtentAlignMask);338}339 340unsigned HexagonMCInstrInfo::getExtentBits(MCInstrInfo const &MCII,341                                           MCInst const &MCI) {342  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;343  return ((F >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask);344}345 346bool HexagonMCInstrInfo::isExtentSigned(MCInstrInfo const &MCII,347                                        MCInst const &MCI) {348  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;349  return (F >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask;350}351 352/// Return the maximum value of an extendable operand.353int HexagonMCInstrInfo::getMaxValue(MCInstrInfo const &MCII,354                                    MCInst const &MCI) {355  assert(HexagonMCInstrInfo::isExtendable(MCII, MCI) ||356         HexagonMCInstrInfo::isExtended(MCII, MCI));357 358  if (HexagonMCInstrInfo::isExtentSigned(MCII, MCI)) // if value is signed359    return (1 << (HexagonMCInstrInfo::getExtentBits(MCII, MCI) - 1)) - 1;360  return (1 << HexagonMCInstrInfo::getExtentBits(MCII, MCI)) - 1;361}362 363/// Return the minimum value of an extendable operand.364int HexagonMCInstrInfo::getMinValue(MCInstrInfo const &MCII,365                                    MCInst const &MCI) {366  assert(HexagonMCInstrInfo::isExtendable(MCII, MCI) ||367         HexagonMCInstrInfo::isExtended(MCII, MCI));368 369  if (HexagonMCInstrInfo::isExtentSigned(MCII, MCI)) // if value is signed370    return -(1 << (HexagonMCInstrInfo::getExtentBits(MCII, MCI) - 1));371  return 0;372}373 374StringRef HexagonMCInstrInfo::getName(MCInstrInfo const &MCII,375                                      MCInst const &MCI) {376  return MCII.getName(MCI.getOpcode());377}378 379unsigned short HexagonMCInstrInfo::getNewValueOp(MCInstrInfo const &MCII,380                                                 MCInst const &MCI) {381  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;382  return ((F >> HexagonII::NewValueOpPos) & HexagonII::NewValueOpMask);383}384 385MCOperand const &HexagonMCInstrInfo::getNewValueOperand(MCInstrInfo const &MCII,386                                                        MCInst const &MCI) {387  if (HexagonMCInstrInfo::hasTmpDst(MCII, MCI)) {388    // VTMP doesn't actually exist in the encodings for these 184389    // 3 instructions so go ahead and create it here.390    static MCOperand MCO = MCOperand::createReg(Hexagon::VTMP);391    return (MCO);392  } else {393    unsigned O = HexagonMCInstrInfo::getNewValueOp(MCII, MCI);394    MCOperand const &MCO = MCI.getOperand(O);395 396    assert((HexagonMCInstrInfo::isNewValue(MCII, MCI) ||397            HexagonMCInstrInfo::hasNewValue(MCII, MCI)) &&398           MCO.isReg());399    return (MCO);400  }401}402 403/// Return the new value or the newly produced value.404unsigned short HexagonMCInstrInfo::getNewValueOp2(MCInstrInfo const &MCII,405                                                  MCInst const &MCI) {406  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;407  return ((F >> HexagonII::NewValueOpPos2) & HexagonII::NewValueOpMask2);408}409 410MCOperand const &411HexagonMCInstrInfo::getNewValueOperand2(MCInstrInfo const &MCII,412                                        MCInst const &MCI) {413  unsigned O = HexagonMCInstrInfo::getNewValueOp2(MCII, MCI);414  MCOperand const &MCO = MCI.getOperand(O);415 416  assert((HexagonMCInstrInfo::isNewValue(MCII, MCI) ||417          HexagonMCInstrInfo::hasNewValue2(MCII, MCI)) &&418         MCO.isReg());419  return (MCO);420}421 422/// Return the Hexagon ISA class for the insn.423unsigned HexagonMCInstrInfo::getType(MCInstrInfo const &MCII,424                                     MCInst const &MCI) {425  const uint64_t F = MCII.get(MCI.getOpcode()).TSFlags;426  return ((F >> HexagonII::TypePos) & HexagonII::TypeMask);427}428 429/// Return the resources used by this instruction430unsigned HexagonMCInstrInfo::getCVIResources(MCInstrInfo const &MCII,431                                      MCSubtargetInfo const &STI,432                                      MCInst const &MCI) {433 434  const InstrItinerary *II = STI.getSchedModel().InstrItineraries;435  int SchedClass = HexagonMCInstrInfo::getDesc(MCII, MCI).getSchedClass();436  int Size = II[SchedClass].LastStage - II[SchedClass].FirstStage;437 438  // HVX resources used are currently located at the second to last stage.439  // This could also be done with a linear search of the stages looking for:440  // CVI_ALL, CVI_MPY01, CVI_XLSHF, CVI_MPY0, CVI_MPY1, CVI_SHIFT, CVI_XLANE,441  // CVI_ZW442  unsigned Stage = II[SchedClass].LastStage - 1;443 444  if (Size < 2)445    return 0;446  return ((Stage + HexagonStages)->getUnits());447}448 449/// Return the slots this instruction can execute out of450unsigned HexagonMCInstrInfo::getUnits(MCInstrInfo const &MCII,451                                      MCSubtargetInfo const &STI,452                                      MCInst const &MCI) {453  const InstrItinerary *II = STI.getSchedModel().InstrItineraries;454  int SchedClass = HexagonMCInstrInfo::getDesc(MCII, MCI).getSchedClass();455  return ((II[SchedClass].FirstStage + HexagonStages)->getUnits());456}457 458/// Return the slots this instruction consumes in addition to459/// the slot(s) it can execute out of460 461unsigned HexagonMCInstrInfo::getOtherReservedSlots(MCInstrInfo const &MCII,462                                                   MCSubtargetInfo const &STI,463                                                   MCInst const &MCI) {464  const InstrItinerary *II = STI.getSchedModel().InstrItineraries;465  int SchedClass = HexagonMCInstrInfo::getDesc(MCII, MCI).getSchedClass();466  unsigned Slots = 0;467 468  // FirstStage are slots that this instruction can execute in.469  // FirstStage+1 are slots that are also consumed by this instruction.470  // For example: vmemu can only execute in slot 0 but also consumes slot 1.471  for (unsigned Stage = II[SchedClass].FirstStage + 1;472       Stage < II[SchedClass].LastStage; ++Stage) {473    unsigned Units = (Stage + HexagonStages)->getUnits();474    if (Units > HexagonGetLastSlot())475      break;476    // fyi: getUnits() will return 0x1, 0x2, 0x4 or 0x8477    Slots |= Units;478  }479 480  // if 0 is returned, then no additional slots are consumed by this inst.481  return Slots;482}483 484bool HexagonMCInstrInfo::hasDuplex(MCInstrInfo const &MCII, MCInst const &MCI) {485  if (!HexagonMCInstrInfo::isBundle(MCI))486    return false;487 488  for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCI)) {489    if (HexagonMCInstrInfo::isDuplex(MCII, *I.getInst()))490      return true;491  }492 493  return false;494}495 496bool HexagonMCInstrInfo::hasExtenderForIndex(MCInst const &MCB, size_t Index) {497  return extenderForIndex(MCB, Index) != nullptr;498}499 500bool HexagonMCInstrInfo::hasImmExt(MCInst const &MCI) {501  if (!HexagonMCInstrInfo::isBundle(MCI))502    return false;503 504  for (const auto &I : HexagonMCInstrInfo::bundleInstructions(MCI)) {505    if (isImmext(*I.getInst()))506      return true;507  }508 509  return false;510}511 512/// Return whether the insn produces a value.513bool HexagonMCInstrInfo::hasNewValue(MCInstrInfo const &MCII,514                                     MCInst const &MCI) {515  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;516  return ((F >> HexagonII::hasNewValuePos) & HexagonII::hasNewValueMask);517}518 519/// Return whether the insn produces a second value.520bool HexagonMCInstrInfo::hasNewValue2(MCInstrInfo const &MCII,521                                      MCInst const &MCI) {522  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;523  return ((F >> HexagonII::hasNewValuePos2) & HexagonII::hasNewValueMask2);524}525 526MCInst const &HexagonMCInstrInfo::instruction(MCInst const &MCB, size_t Index) {527  assert(isBundle(MCB));528  assert(Index < HEXAGON_PRESHUFFLE_PACKET_SIZE);529  return *MCB.getOperand(bundleInstructionsOffset + Index).getInst();530}531 532/// Return where the instruction is an accumulator.533bool HexagonMCInstrInfo::isAccumulator(MCInstrInfo const &MCII,534                                       MCInst const &MCI) {535  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;536  return ((F >> HexagonII::AccumulatorPos) & HexagonII::AccumulatorMask);537}538 539bool HexagonMCInstrInfo::isBundle(MCInst const &MCI) {540  auto Result = Hexagon::BUNDLE == MCI.getOpcode();541  assert(!Result || (MCI.size() > 0 && MCI.getOperand(0).isImm()));542  return Result;543}544 545bool HexagonMCInstrInfo::isConstExtended(MCInstrInfo const &MCII,546                                         MCInst const &MCI) {547  if (HexagonMCInstrInfo::isExtended(MCII, MCI))548    return true;549  if (!HexagonMCInstrInfo::isExtendable(MCII, MCI))550    return false;551  MCOperand const &MO = HexagonMCInstrInfo::getExtendableOperand(MCII, MCI);552  if (isa<HexagonMCExpr>(MO.getExpr()) &&553      HexagonMCInstrInfo::mustExtend(*MO.getExpr()))554    return true;555  // Branch insns are handled as necessary by relaxation.556  if ((HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeJ) ||557      (HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeCJ &&558       HexagonMCInstrInfo::getDesc(MCII, MCI).isBranch()) ||559      (HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeNCJ &&560       HexagonMCInstrInfo::getDesc(MCII, MCI).isBranch()))561    return false;562  // Otherwise loop instructions and other CR insts are handled by relaxation563  else if ((HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeCR) &&564           (MCI.getOpcode() != Hexagon::C4_addipc))565    return false;566 567  assert(!MO.isImm());568  if (isa<HexagonMCExpr>(MO.getExpr()) &&569      HexagonMCInstrInfo::mustNotExtend(*MO.getExpr()))570    return false;571 572  int64_t Value;573  if (!MO.getExpr()->evaluateAsAbsolute(Value))574    return true;575  if (HexagonMCInstrInfo::isExtentSigned(MCII, MCI)) {576    int32_t SValue = Value;577    int32_t MinValue = HexagonMCInstrInfo::getMinValue(MCII, MCI);578    int32_t MaxValue = HexagonMCInstrInfo::getMaxValue(MCII, MCI);579    return SValue < MinValue || SValue > MaxValue;580  }581  uint32_t UValue = Value;582  uint32_t MinValue = HexagonMCInstrInfo::getMinValue(MCII, MCI);583  uint32_t MaxValue = HexagonMCInstrInfo::getMaxValue(MCII, MCI);584  return UValue < MinValue || UValue > MaxValue;585}586 587bool HexagonMCInstrInfo::isCanon(MCInstrInfo const &MCII, MCInst const &MCI) {588  return !HexagonMCInstrInfo::getDesc(MCII, MCI).isPseudo() &&589         !HexagonMCInstrInfo::isPrefix(MCII, MCI);590}591 592bool HexagonMCInstrInfo::isCofMax1(MCInstrInfo const &MCII, MCInst const &MCI) {593  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;594  return ((F >> HexagonII::CofMax1Pos) & HexagonII::CofMax1Mask);595}596 597bool HexagonMCInstrInfo::isCofRelax1(MCInstrInfo const &MCII,598                                     MCInst const &MCI) {599  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;600  return ((F >> HexagonII::CofRelax1Pos) & HexagonII::CofRelax1Mask);601}602 603bool HexagonMCInstrInfo::isCofRelax2(MCInstrInfo const &MCII,604                                     MCInst const &MCI) {605  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;606  return ((F >> HexagonII::CofRelax2Pos) & HexagonII::CofRelax2Mask);607}608 609bool HexagonMCInstrInfo::isCompound(MCInstrInfo const &MCII,610                                    MCInst const &MCI) {611  return (getType(MCII, MCI) == HexagonII::TypeCJ);612}613 614bool HexagonMCInstrInfo::isCVINew(MCInstrInfo const &MCII, MCInst const &MCI) {615  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;616  return ((F >> HexagonII::CVINewPos) & HexagonII::CVINewMask);617}618 619bool HexagonMCInstrInfo::isDblRegForSubInst(MCRegister Reg) {620  return ((Reg >= Hexagon::D0 && Reg <= Hexagon::D3) ||621          (Reg >= Hexagon::D8 && Reg <= Hexagon::D11));622}623 624bool HexagonMCInstrInfo::isDuplex(MCInstrInfo const &MCII, MCInst const &MCI) {625  return HexagonII::TypeDUPLEX == HexagonMCInstrInfo::getType(MCII, MCI);626}627 628bool HexagonMCInstrInfo::isExtendable(MCInstrInfo const &MCII,629                                      MCInst const &MCI) {630  uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;631  return (F >> HexagonII::ExtendablePos) & HexagonII::ExtendableMask;632}633 634bool HexagonMCInstrInfo::isExtended(MCInstrInfo const &MCII,635                                    MCInst const &MCI) {636  uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;637  return (F >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask;638}639 640bool HexagonMCInstrInfo::isFloat(MCInstrInfo const &MCII, MCInst const &MCI) {641  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;642  return ((F >> HexagonII::FPPos) & HexagonII::FPMask);643}644 645bool HexagonMCInstrInfo::isHVX(MCInstrInfo const &MCII, MCInst const &MCI) {646  const uint64_t V = getType(MCII, MCI);647  return HexagonII::TypeCVI_FIRST <= V && V <= HexagonII::TypeCVI_LAST;648}649 650bool HexagonMCInstrInfo::isImmext(MCInst const &MCI) {651  return MCI.getOpcode() == Hexagon::A4_ext;652}653 654bool HexagonMCInstrInfo::isInnerLoop(MCInst const &MCI) {655  assert(isBundle(MCI));656  int64_t Flags = MCI.getOperand(0).getImm();657  return (Flags & innerLoopMask) != 0;658}659 660bool HexagonMCInstrInfo::isIntReg(MCRegister Reg) {661  return (Reg >= Hexagon::R0 && Reg <= Hexagon::R31);662}663 664bool HexagonMCInstrInfo::isIntRegForSubInst(MCRegister Reg) {665  return ((Reg >= Hexagon::R0 && Reg <= Hexagon::R7) ||666          (Reg >= Hexagon::R16 && Reg <= Hexagon::R23));667}668 669/// Return whether the insn expects newly produced value.670bool HexagonMCInstrInfo::isNewValue(MCInstrInfo const &MCII,671                                    MCInst const &MCI) {672  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;673  return ((F >> HexagonII::NewValuePos) & HexagonII::NewValueMask);674}675 676bool HexagonMCInstrInfo::isNewValueStore(MCInstrInfo const &MCII,677                                         MCInst const &MCI) {678  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;679  return (F >> HexagonII::NVStorePos) & HexagonII::NVStoreMask;680}681 682/// Return whether the operand is extendable.683bool HexagonMCInstrInfo::isOpExtendable(MCInstrInfo const &MCII,684                                        MCInst const &MCI, unsigned short O) {685  return (O == HexagonMCInstrInfo::getExtendableOp(MCII, MCI));686}687 688bool HexagonMCInstrInfo::isOuterLoop(MCInst const &MCI) {689  assert(isBundle(MCI));690  int64_t Flags = MCI.getOperand(0).getImm();691  return (Flags & outerLoopMask) != 0;692}693 694bool HexagonMCInstrInfo::IsVecRegPair(MCRegister VecReg) {695  return (VecReg >= Hexagon::W0 && VecReg <= Hexagon::W15) ||696         (VecReg >= Hexagon::WR0 && VecReg <= Hexagon::WR15);697}698 699bool HexagonMCInstrInfo::IsReverseVecRegPair(MCRegister VecReg) {700  return (VecReg >= Hexagon::WR0 && VecReg <= Hexagon::WR15);701}702 703bool HexagonMCInstrInfo::IsVecRegSingle(MCRegister VecReg) {704  return (VecReg >= Hexagon::V0 && VecReg <= Hexagon::V31);705}706 707std::pair<unsigned, unsigned>708HexagonMCInstrInfo::GetVecRegPairIndices(MCRegister VecRegPair) {709  assert(IsVecRegPair(VecRegPair) &&710         "VecRegPair must be a vector register pair");711 712  const bool IsRev = IsReverseVecRegPair(VecRegPair);713  const unsigned PairIndex =714      2 * (IsRev ? VecRegPair - Hexagon::WR0 : VecRegPair - Hexagon::W0);715 716  return IsRev ? std::make_pair(PairIndex, PairIndex + 1)717               : std::make_pair(PairIndex + 1, PairIndex);718}719 720bool HexagonMCInstrInfo::IsSingleConsumerRefPairProducer(MCRegister Producer,721                                                         MCRegister Consumer) {722  if (IsVecRegPair(Producer) && IsVecRegSingle(Consumer)) {723    const unsigned ProdPairIndex = IsReverseVecRegPair(Producer)724                                       ? Producer - Hexagon::WR0725                                       : Producer - Hexagon::W0;726    const unsigned ConsumerSingleIndex = (Consumer - Hexagon::V0) >> 1;727 728    return ConsumerSingleIndex == ProdPairIndex;729  }730  return false;731}732 733bool HexagonMCInstrInfo::isPredicated(MCInstrInfo const &MCII,734                                      MCInst const &MCI) {735  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;736  return ((F >> HexagonII::PredicatedPos) & HexagonII::PredicatedMask);737}738 739bool HexagonMCInstrInfo::isPrefix(MCInstrInfo const &MCII, MCInst const &MCI) {740  return HexagonII::TypeEXTENDER == HexagonMCInstrInfo::getType(MCII, MCI);741}742 743bool HexagonMCInstrInfo::isPredicateLate(MCInstrInfo const &MCII,744                                         MCInst const &MCI) {745  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;746  return (F >> HexagonII::PredicateLatePos & HexagonII::PredicateLateMask);747}748 749/// Return whether the insn is newly predicated.750bool HexagonMCInstrInfo::isPredicatedNew(MCInstrInfo const &MCII,751                                         MCInst const &MCI) {752  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;753  return ((F >> HexagonII::PredicatedNewPos) & HexagonII::PredicatedNewMask);754}755 756bool HexagonMCInstrInfo::isPredicatedTrue(MCInstrInfo const &MCII,757                                          MCInst const &MCI) {758  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;759  return (760      !((F >> HexagonII::PredicatedFalsePos) & HexagonII::PredicatedFalseMask));761}762 763bool HexagonMCInstrInfo::isPredReg(MCRegisterInfo const &MRI, MCRegister Reg) {764  auto &PredRegClass = MRI.getRegClass(Hexagon::PredRegsRegClassID);765  return PredRegClass.contains(Reg);766}767 768bool HexagonMCInstrInfo::isPredRegister(MCInstrInfo const &MCII,769                                        MCInst const &Inst, unsigned I) {770  MCInstrDesc const &Desc = HexagonMCInstrInfo::getDesc(MCII, Inst);771 772  return Inst.getOperand(I).isReg() &&773         Desc.operands()[I].RegClass == Hexagon::PredRegsRegClassID;774}775 776/// Return whether the insn can be packaged only with A and X-type insns.777bool HexagonMCInstrInfo::isSoloAX(MCInstrInfo const &MCII, MCInst const &MCI) {778  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;779  return ((F >> HexagonII::SoloAXPos) & HexagonII::SoloAXMask);780}781 782/// Return whether the insn can be packaged only with an A-type insn in slot #1.783bool HexagonMCInstrInfo::isRestrictSlot1AOK(MCInstrInfo const &MCII,784                                            MCInst const &MCI) {785  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;786  return ((F >> HexagonII::RestrictSlot1AOKPos) &787          HexagonII::RestrictSlot1AOKMask);788}789 790bool HexagonMCInstrInfo::isRestrictNoSlot1Store(MCInstrInfo const &MCII,791                                                MCInst const &MCI) {792  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;793  return ((F >> HexagonII::RestrictNoSlot1StorePos) &794          HexagonII::RestrictNoSlot1StoreMask);795}796 797/// Return whether the insn is solo, i.e., cannot be in a packet.798bool HexagonMCInstrInfo::isSolo(MCInstrInfo const &MCII, MCInst const &MCI) {799  const uint64_t F = MCII.get(MCI.getOpcode()).TSFlags;800  return ((F >> HexagonII::SoloPos) & HexagonII::SoloMask);801}802 803bool HexagonMCInstrInfo::isMemReorderDisabled(MCInst const &MCI) {804  assert(isBundle(MCI));805  auto Flags = MCI.getOperand(0).getImm();806  return (Flags & memReorderDisabledMask) != 0;807}808 809bool HexagonMCInstrInfo::isSubInstruction(MCInst const &MCI) {810  switch (MCI.getOpcode()) {811  default:812    return false;813  case Hexagon::SA1_addi:814  case Hexagon::SA1_addrx:815  case Hexagon::SA1_addsp:816  case Hexagon::SA1_and1:817  case Hexagon::SA1_clrf:818  case Hexagon::SA1_clrfnew:819  case Hexagon::SA1_clrt:820  case Hexagon::SA1_clrtnew:821  case Hexagon::SA1_cmpeqi:822  case Hexagon::SA1_combine0i:823  case Hexagon::SA1_combine1i:824  case Hexagon::SA1_combine2i:825  case Hexagon::SA1_combine3i:826  case Hexagon::SA1_combinerz:827  case Hexagon::SA1_combinezr:828  case Hexagon::SA1_dec:829  case Hexagon::SA1_inc:830  case Hexagon::SA1_seti:831  case Hexagon::SA1_setin1:832  case Hexagon::SA1_sxtb:833  case Hexagon::SA1_sxth:834  case Hexagon::SA1_tfr:835  case Hexagon::SA1_zxtb:836  case Hexagon::SA1_zxth:837  case Hexagon::SL1_loadri_io:838  case Hexagon::SL1_loadrub_io:839  case Hexagon::SL2_deallocframe:840  case Hexagon::SL2_jumpr31:841  case Hexagon::SL2_jumpr31_f:842  case Hexagon::SL2_jumpr31_fnew:843  case Hexagon::SL2_jumpr31_t:844  case Hexagon::SL2_jumpr31_tnew:845  case Hexagon::SL2_loadrb_io:846  case Hexagon::SL2_loadrd_sp:847  case Hexagon::SL2_loadrh_io:848  case Hexagon::SL2_loadri_sp:849  case Hexagon::SL2_loadruh_io:850  case Hexagon::SL2_return:851  case Hexagon::SL2_return_f:852  case Hexagon::SL2_return_fnew:853  case Hexagon::SL2_return_t:854  case Hexagon::SL2_return_tnew:855  case Hexagon::SS1_storeb_io:856  case Hexagon::SS1_storew_io:857  case Hexagon::SS2_allocframe:858  case Hexagon::SS2_storebi0:859  case Hexagon::SS2_storebi1:860  case Hexagon::SS2_stored_sp:861  case Hexagon::SS2_storeh_io:862  case Hexagon::SS2_storew_sp:863  case Hexagon::SS2_storewi0:864  case Hexagon::SS2_storewi1:865    return true;866  }867}868 869bool HexagonMCInstrInfo::isVector(MCInstrInfo const &MCII, MCInst const &MCI) {870  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;871  return (F >> HexagonII::isCVIPos) & HexagonII::isCVIMask;872}873 874int64_t HexagonMCInstrInfo::minConstant(MCInst const &MCI, size_t Index) {875  auto Sentinel = static_cast<int64_t>(std::numeric_limits<uint32_t>::max())876                  << 8;877  if (MCI.size() <= Index)878    return Sentinel;879  MCOperand const &MCO = MCI.getOperand(Index);880  if (!MCO.isExpr())881    return Sentinel;882  int64_t Value;883  if (!MCO.getExpr()->evaluateAsAbsolute(Value))884    return Sentinel;885  return Value;886}887 888void HexagonMCInstrInfo::setMustExtend(MCExpr const &Expr, bool Val) {889  HexagonMCExpr &HExpr = const_cast<HexagonMCExpr &>(cast<HexagonMCExpr>(Expr));890  HExpr.setMustExtend(Val);891}892 893bool HexagonMCInstrInfo::mustExtend(MCExpr const &Expr) {894  HexagonMCExpr const &HExpr = cast<HexagonMCExpr>(Expr);895  return HExpr.mustExtend();896}897void HexagonMCInstrInfo::setMustNotExtend(MCExpr const &Expr, bool Val) {898  HexagonMCExpr &HExpr = const_cast<HexagonMCExpr &>(cast<HexagonMCExpr>(Expr));899  HExpr.setMustNotExtend(Val);900}901bool HexagonMCInstrInfo::mustNotExtend(MCExpr const &Expr) {902  HexagonMCExpr const &HExpr = cast<HexagonMCExpr>(Expr);903  return HExpr.mustNotExtend();904}905void HexagonMCInstrInfo::setS27_2_reloc(MCExpr const &Expr, bool Val) {906  HexagonMCExpr &HExpr =907      const_cast<HexagonMCExpr &>(*cast<HexagonMCExpr>(&Expr));908  HExpr.setS27_2_reloc(Val);909}910bool HexagonMCInstrInfo::s27_2_reloc(MCExpr const &Expr) {911  HexagonMCExpr const *HExpr = dyn_cast<HexagonMCExpr>(&Expr);912  if (!HExpr)913    return false;914  return HExpr->s27_2_reloc();915}916 917unsigned HexagonMCInstrInfo::packetSizeSlots(MCSubtargetInfo const &STI) {918  const bool IsTiny = STI.hasFeature(Hexagon::ProcTinyCore);919 920  return IsTiny ? (HEXAGON_PACKET_SIZE - 1) : HEXAGON_PACKET_SIZE;921}922 923unsigned HexagonMCInstrInfo::packetSize(StringRef CPU) {924  return llvm::StringSwitch<unsigned>(CPU)925      .Case("hexagonv67t", 3)926      .Default(4);927}928 929void HexagonMCInstrInfo::padEndloop(MCInst &MCB, MCContext &Context) {930  MCInst Nop;931  Nop.setOpcode(Hexagon::A2_nop);932  assert(isBundle(MCB));933  while (LoopNeedsPadding(MCB))934    MCB.addOperand(MCOperand::createInst(new (Context) MCInst(Nop)));935}936 937HexagonMCInstrInfo::PredicateInfo938HexagonMCInstrInfo::predicateInfo(MCInstrInfo const &MCII, MCInst const &MCI) {939  if (!isPredicated(MCII, MCI))940    return {0, 0, false};941  MCInstrDesc const &Desc = getDesc(MCII, MCI);942  for (auto I = Desc.getNumDefs(), N = Desc.getNumOperands(); I != N; ++I)943    if (Desc.operands()[I].RegClass == Hexagon::PredRegsRegClassID)944      return {MCI.getOperand(I).getReg(), I, isPredicatedTrue(MCII, MCI)};945  return {0, 0, false};946}947 948bool HexagonMCInstrInfo::prefersSlot3(MCInstrInfo const &MCII,949                                      MCInst const &MCI) {950  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;951  return (F >> HexagonII::PrefersSlot3Pos) & HexagonII::PrefersSlot3Mask;952}953 954bool HexagonMCInstrInfo::hasTmpDst(MCInstrInfo const &MCII, MCInst const &MCI) {955  switch (MCI.getOpcode()) {956  default:957    return false;958  case Hexagon::V6_vgathermh:959  case Hexagon::V6_vgathermhq:960  case Hexagon::V6_vgathermhw:961  case Hexagon::V6_vgathermhwq:962  case Hexagon::V6_vgathermw:963  case Hexagon::V6_vgathermwq:964    return true;965  }966  return false;967}968 969bool HexagonMCInstrInfo::hasHvxTmp(MCInstrInfo const &MCII, MCInst const &MCI) {970  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;971  return (F >> HexagonII::HasHvxTmpPos) & HexagonII::HasHvxTmpMask;972}973 974bool HexagonMCInstrInfo::requiresSlot(MCSubtargetInfo const &STI,975                                      MCInst const &MCI) {976  const unsigned OpCode = MCI.getOpcode();977  const bool IsTiny = STI.getFeatureBits() [Hexagon::ProcTinyCore];978  const bool NoSlotReqd = Hexagon::A4_ext == OpCode ||979                          (IsTiny && Hexagon::A2_nop == OpCode) ||980                          (IsTiny && Hexagon::J4_hintjumpr == OpCode);981 982  return !NoSlotReqd;983}984 985unsigned HexagonMCInstrInfo::slotsConsumed(MCInstrInfo const &MCII,986                                           MCSubtargetInfo const &STI,987                                           MCInst const &MCI) {988  unsigned slotsUsed = 0;989  for (auto HMI : bundleInstructions(MCI)) {990    MCInst const &MCI = *HMI.getInst();991    if (!requiresSlot(STI, MCI))992      continue;993    if (isDuplex(MCII, MCI))994      slotsUsed += 2;995    else996      ++slotsUsed;997  }998  return slotsUsed;999}1000 1001void HexagonMCInstrInfo::replaceDuplex(MCContext &Context, MCInst &MCB,1002                                       DuplexCandidate Candidate) {1003  assert(Candidate.packetIndexI < MCB.size());1004  assert(Candidate.packetIndexJ < MCB.size());1005  assert(isBundle(MCB));1006  MCInst *Duplex =1007      deriveDuplex(Context, Candidate.iClass,1008                   *MCB.getOperand(Candidate.packetIndexJ).getInst(),1009                   *MCB.getOperand(Candidate.packetIndexI).getInst());1010  assert(Duplex != nullptr);1011  MCB.getOperand(Candidate.packetIndexI).setInst(Duplex);1012  MCB.erase(MCB.begin() + Candidate.packetIndexJ);1013}1014 1015void HexagonMCInstrInfo::setInnerLoop(MCInst &MCI) {1016  assert(isBundle(MCI));1017  MCOperand &Operand = MCI.getOperand(0);1018  Operand.setImm(Operand.getImm() | innerLoopMask);1019}1020 1021void HexagonMCInstrInfo::setMemReorderDisabled(MCInst &MCI) {1022  assert(isBundle(MCI));1023  MCOperand &Operand = MCI.getOperand(0);1024  Operand.setImm(Operand.getImm() | memReorderDisabledMask);1025  assert(isMemReorderDisabled(MCI));1026}1027 1028void HexagonMCInstrInfo::setOuterLoop(MCInst &MCI) {1029  assert(isBundle(MCI));1030  MCOperand &Operand = MCI.getOperand(0);1031  Operand.setImm(Operand.getImm() | outerLoopMask);1032}1033 1034unsigned HexagonMCInstrInfo::SubregisterBit(MCRegister Consumer,1035                                            MCRegister Producer,1036                                            MCRegister Producer2) {1037  // If we're a single vector consumer of a double producer, set subreg bit1038  // based on if we're accessing the lower or upper register component1039  if (IsVecRegPair(Producer) && IsVecRegSingle(Consumer)) {1040    unsigned Rev = IsReverseVecRegPair(Producer);1041    return ((Consumer - Hexagon::V0) & 0x1) ^ Rev;1042  }1043  if (Producer2 != Hexagon::NoRegister)1044    return Consumer == Producer;1045  return 0;1046}1047 1048bool HexagonMCInstrInfo::LoopNeedsPadding(MCInst const &MCB) {1049  return (1050      (HexagonMCInstrInfo::isInnerLoop(MCB) &&1051       (HexagonMCInstrInfo::bundleSize(MCB) < HEXAGON_PACKET_INNER_SIZE)) ||1052      ((HexagonMCInstrInfo::isOuterLoop(MCB) &&1053        (HexagonMCInstrInfo::bundleSize(MCB) < HEXAGON_PACKET_OUTER_SIZE))));1054}1055 1056bool HexagonMCInstrInfo::IsABranchingInst(MCInstrInfo const &MCII,1057                                          MCSubtargetInfo const &STI,1058                                          MCInst const &I) {1059  assert(!HexagonMCInstrInfo::isBundle(I));1060  MCInstrDesc const &Desc = HexagonMCInstrInfo::getDesc(MCII, I);1061  return (Desc.isBranch() || Desc.isCall() || Desc.isReturn());1062}1063