1283625Sdim//===- HexagonMCInstrInfo.cpp - Hexagon sub-class of MCInst ---------------===// 2283625Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6283625Sdim// 7283625Sdim//===----------------------------------------------------------------------===// 8283625Sdim// 9283625Sdim// This class extends MCInstrInfo to allow Hexagon specific MCInstr queries 10283625Sdim// 11283625Sdim//===----------------------------------------------------------------------===// 12283625Sdim 13327952Sdim#include "MCTargetDesc/HexagonMCInstrInfo.h" 14327952Sdim#include "MCTargetDesc/HexagonBaseInfo.h" 15327952Sdim#include "MCTargetDesc/HexagonMCChecker.h" 16327952Sdim#include "MCTargetDesc/HexagonMCExpr.h" 17327952Sdim#include "MCTargetDesc/HexagonMCShuffler.h" 18327952Sdim#include "MCTargetDesc/HexagonMCTargetDesc.h" 19327952Sdim#include "llvm/ADT/SmallVector.h" 20284236Sdim#include "llvm/MC/MCContext.h" 21327952Sdim#include "llvm/MC/MCExpr.h" 22327952Sdim#include "llvm/MC/MCInst.h" 23284236Sdim#include "llvm/MC/MCInstrInfo.h" 24321369Sdim#include "llvm/MC/MCInstrItineraries.h" 25284236Sdim#include "llvm/MC/MCSubtargetInfo.h" 26327952Sdim#include "llvm/Support/Casting.h" 27327952Sdim#include "llvm/Support/ErrorHandling.h" 28327952Sdim#include <cassert> 29327952Sdim#include <cstdint> 30327952Sdim#include <limits> 31284236Sdim 32327952Sdimusing namespace llvm; 33321369Sdim 34327952Sdimbool HexagonMCInstrInfo::PredicateInfo::isPredicated() const { 35327952Sdim return Register != Hexagon::NoRegister; 36327952Sdim} 37327952Sdim 38321369SdimHexagon::PacketIterator::PacketIterator(MCInstrInfo const &MCII, 39321369Sdim MCInst const &Inst) 40321369Sdim : MCII(MCII), BundleCurrent(Inst.begin() + 41321369Sdim HexagonMCInstrInfo::bundleInstructionsOffset), 42321369Sdim BundleEnd(Inst.end()), DuplexCurrent(Inst.end()), DuplexEnd(Inst.end()) {} 43321369Sdim 44321369SdimHexagon::PacketIterator::PacketIterator(MCInstrInfo const &MCII, 45321369Sdim MCInst const &Inst, std::nullptr_t) 46321369Sdim : MCII(MCII), BundleCurrent(Inst.end()), BundleEnd(Inst.end()), 47321369Sdim DuplexCurrent(Inst.end()), DuplexEnd(Inst.end()) {} 48321369Sdim 49321369SdimHexagon::PacketIterator &Hexagon::PacketIterator::operator++() { 50321369Sdim if (DuplexCurrent != DuplexEnd) { 51321369Sdim ++DuplexCurrent; 52321369Sdim if (DuplexCurrent == DuplexEnd) { 53321369Sdim DuplexCurrent = BundleEnd; 54321369Sdim DuplexEnd = BundleEnd; 55327952Sdim ++BundleCurrent; 56321369Sdim } 57321369Sdim return *this; 58321369Sdim } 59321369Sdim ++BundleCurrent; 60321369Sdim if (BundleCurrent != BundleEnd) { 61321369Sdim MCInst const &Inst = *BundleCurrent->getInst(); 62321369Sdim if (HexagonMCInstrInfo::isDuplex(MCII, Inst)) { 63321369Sdim DuplexCurrent = Inst.begin(); 64321369Sdim DuplexEnd = Inst.end(); 65321369Sdim } 66321369Sdim } 67321369Sdim return *this; 68321369Sdim} 69321369Sdim 70321369SdimMCInst const &Hexagon::PacketIterator::operator*() const { 71321369Sdim if (DuplexCurrent != DuplexEnd) 72321369Sdim return *DuplexCurrent->getInst(); 73321369Sdim return *BundleCurrent->getInst(); 74321369Sdim} 75321369Sdim 76321369Sdimbool Hexagon::PacketIterator::operator==(PacketIterator const &Other) const { 77321369Sdim return BundleCurrent == Other.BundleCurrent && BundleEnd == Other.BundleEnd && 78321369Sdim DuplexCurrent == Other.DuplexCurrent && DuplexEnd == Other.DuplexEnd; 79321369Sdim} 80321369Sdim 81296417Sdimvoid HexagonMCInstrInfo::addConstant(MCInst &MI, uint64_t Value, 82296417Sdim MCContext &Context) { 83296417Sdim MI.addOperand(MCOperand::createExpr(MCConstantExpr::create(Value, Context))); 84296417Sdim} 85296417Sdim 86296417Sdimvoid HexagonMCInstrInfo::addConstExtender(MCContext &Context, 87296417Sdim MCInstrInfo const &MCII, MCInst &MCB, 88296417Sdim MCInst const &MCI) { 89296417Sdim assert(HexagonMCInstrInfo::isBundle(MCB)); 90296417Sdim MCOperand const &exOp = 91296417Sdim MCI.getOperand(HexagonMCInstrInfo::getExtendableOp(MCII, MCI)); 92296417Sdim 93296417Sdim // Create the extender. 94296417Sdim MCInst *XMCI = 95296417Sdim new (Context) MCInst(HexagonMCInstrInfo::deriveExtender(MCII, MCI, exOp)); 96327952Sdim XMCI->setLoc(MCI.getLoc()); 97296417Sdim 98296417Sdim MCB.addOperand(MCOperand::createInst(XMCI)); 99296417Sdim} 100296417Sdim 101321369Sdimiterator_range<Hexagon::PacketIterator> 102321369SdimHexagonMCInstrInfo::bundleInstructions(MCInstrInfo const &MCII, 103321369Sdim MCInst const &MCI) { 104321369Sdim assert(isBundle(MCI)); 105321369Sdim return make_range(Hexagon::PacketIterator(MCII, MCI), 106321369Sdim Hexagon::PacketIterator(MCII, MCI, nullptr)); 107321369Sdim} 108321369Sdim 109284236Sdimiterator_range<MCInst::const_iterator> 110284236SdimHexagonMCInstrInfo::bundleInstructions(MCInst const &MCI) { 111284236Sdim assert(isBundle(MCI)); 112296417Sdim return make_range(MCI.begin() + bundleInstructionsOffset, MCI.end()); 113283625Sdim} 114283625Sdim 115284236Sdimsize_t HexagonMCInstrInfo::bundleSize(MCInst const &MCI) { 116284236Sdim if (HexagonMCInstrInfo::isBundle(MCI)) 117284236Sdim return (MCI.size() - bundleInstructionsOffset); 118284236Sdim else 119284236Sdim return (1); 120284236Sdim} 121284236Sdim 122296417Sdimbool HexagonMCInstrInfo::canonicalizePacket(MCInstrInfo const &MCII, 123296417Sdim MCSubtargetInfo const &STI, 124296417Sdim MCContext &Context, MCInst &MCB, 125296417Sdim HexagonMCChecker *Check) { 126321369Sdim // Check the bundle for errors. 127321369Sdim bool CheckOk = Check ? Check->check(false) : true; 128321369Sdim if (!CheckOk) 129321369Sdim return false; 130296417Sdim // Examine the packet and convert pairs of instructions to compound 131296417Sdim // instructions when possible. 132296417Sdim if (!HexagonDisableCompound) 133321369Sdim HexagonMCInstrInfo::tryCompound(MCII, STI, Context, MCB); 134321369Sdim HexagonMCShuffle(Context, false, MCII, STI, MCB); 135296417Sdim // Examine the packet and convert pairs of instructions to duplex 136296417Sdim // instructions when possible. 137296417Sdim MCInst InstBundlePreDuplex = MCInst(MCB); 138327952Sdim if (STI.getFeatureBits() [Hexagon::FeatureDuplex]) { 139296417Sdim SmallVector<DuplexCandidate, 8> possibleDuplexes; 140321369Sdim possibleDuplexes = 141321369Sdim HexagonMCInstrInfo::getDuplexPossibilties(MCII, STI, MCB); 142321369Sdim HexagonMCShuffle(Context, MCII, STI, MCB, possibleDuplexes); 143296417Sdim } 144296417Sdim // Examines packet and pad the packet, if needed, when an 145296417Sdim // end-loop is in the bundle. 146321369Sdim HexagonMCInstrInfo::padEndloop(MCB, Context); 147296417Sdim // If compounding and duplexing didn't reduce the size below 148296417Sdim // 4 or less we have a packet that is too big. 149296417Sdim if (HexagonMCInstrInfo::bundleSize(MCB) > HEXAGON_PACKET_SIZE) 150296417Sdim return false; 151321369Sdim // Check the bundle for errors. 152321369Sdim CheckOk = Check ? Check->check(true) : true; 153321369Sdim if (!CheckOk) 154321369Sdim return false; 155321369Sdim HexagonMCShuffle(Context, true, MCII, STI, MCB); 156296417Sdim return true; 157296417Sdim} 158296417Sdim 159296417SdimMCInst HexagonMCInstrInfo::deriveExtender(MCInstrInfo const &MCII, 160296417Sdim MCInst const &Inst, 161296417Sdim MCOperand const &MO) { 162296417Sdim assert(HexagonMCInstrInfo::isExtendable(MCII, Inst) || 163296417Sdim HexagonMCInstrInfo::isExtended(MCII, Inst)); 164296417Sdim 165296417Sdim MCInst XMI; 166321369Sdim XMI.setOpcode(Hexagon::A4_ext); 167296417Sdim if (MO.isImm()) 168296417Sdim XMI.addOperand(MCOperand::createImm(MO.getImm() & (~0x3f))); 169296417Sdim else if (MO.isExpr()) 170296417Sdim XMI.addOperand(MCOperand::createExpr(MO.getExpr())); 171296417Sdim else 172296417Sdim llvm_unreachable("invalid extendable operand"); 173296417Sdim return XMI; 174296417Sdim} 175296417Sdim 176321369SdimMCInst *HexagonMCInstrInfo::deriveDuplex(MCContext &Context, unsigned iClass, 177321369Sdim MCInst const &inst0, 178321369Sdim MCInst const &inst1) { 179321369Sdim assert((iClass <= 0xf) && "iClass must have range of 0 to 0xf"); 180321369Sdim MCInst *duplexInst = new (Context) MCInst; 181321369Sdim duplexInst->setOpcode(Hexagon::DuplexIClass0 + iClass); 182321369Sdim 183321369Sdim MCInst *SubInst0 = new (Context) MCInst(deriveSubInst(inst0)); 184321369Sdim MCInst *SubInst1 = new (Context) MCInst(deriveSubInst(inst1)); 185321369Sdim duplexInst->addOperand(MCOperand::createInst(SubInst0)); 186321369Sdim duplexInst->addOperand(MCOperand::createInst(SubInst1)); 187321369Sdim return duplexInst; 188321369Sdim} 189321369Sdim 190284236SdimMCInst const *HexagonMCInstrInfo::extenderForIndex(MCInst const &MCB, 191284236Sdim size_t Index) { 192284236Sdim assert(Index <= bundleSize(MCB)); 193284236Sdim if (Index == 0) 194284236Sdim return nullptr; 195284236Sdim MCInst const *Inst = 196284236Sdim MCB.getOperand(Index + bundleInstructionsOffset - 1).getInst(); 197284236Sdim if (isImmext(*Inst)) 198284236Sdim return Inst; 199284236Sdim return nullptr; 200284236Sdim} 201284236Sdim 202296417Sdimvoid HexagonMCInstrInfo::extendIfNeeded(MCContext &Context, 203296417Sdim MCInstrInfo const &MCII, MCInst &MCB, 204309124Sdim MCInst const &MCI) { 205309124Sdim if (isConstExtended(MCII, MCI)) 206296417Sdim addConstExtender(Context, MCII, MCB, MCI); 207296417Sdim} 208296417Sdim 209327952Sdimunsigned HexagonMCInstrInfo::getMemAccessSize(MCInstrInfo const &MCII, 210327952Sdim MCInst const &MCI) { 211327952Sdim uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 212327952Sdim unsigned S = (F >> HexagonII::MemAccessSizePos) & HexagonII::MemAccesSizeMask; 213327952Sdim return HexagonII::getMemAccessSizeInBytes(HexagonII::MemAccessSize(S)); 214327952Sdim} 215327952Sdim 216327952Sdimunsigned HexagonMCInstrInfo::getAddrMode(MCInstrInfo const &MCII, 217327952Sdim MCInst const &MCI) { 218283625Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 219327952Sdim return static_cast<unsigned>((F >> HexagonII::AddrModePos) & 220327952Sdim HexagonII::AddrModeMask); 221283625Sdim} 222283625Sdim 223283625SdimMCInstrDesc const &HexagonMCInstrInfo::getDesc(MCInstrInfo const &MCII, 224283625Sdim MCInst const &MCI) { 225321369Sdim return MCII.get(MCI.getOpcode()); 226283625Sdim} 227283625Sdim 228309124Sdimunsigned HexagonMCInstrInfo::getDuplexRegisterNumbering(unsigned Reg) { 229309124Sdim using namespace Hexagon; 230327952Sdim 231309124Sdim switch (Reg) { 232309124Sdim default: 233309124Sdim llvm_unreachable("unknown duplex register"); 234309124Sdim // Rs Rss 235309124Sdim case R0: 236309124Sdim case D0: 237309124Sdim return 0; 238309124Sdim case R1: 239309124Sdim case D1: 240309124Sdim return 1; 241309124Sdim case R2: 242309124Sdim case D2: 243309124Sdim return 2; 244309124Sdim case R3: 245309124Sdim case D3: 246309124Sdim return 3; 247309124Sdim case R4: 248309124Sdim case D8: 249309124Sdim return 4; 250309124Sdim case R5: 251309124Sdim case D9: 252309124Sdim return 5; 253309124Sdim case R6: 254309124Sdim case D10: 255309124Sdim return 6; 256309124Sdim case R7: 257309124Sdim case D11: 258309124Sdim return 7; 259309124Sdim case R16: 260309124Sdim return 8; 261309124Sdim case R17: 262309124Sdim return 9; 263309124Sdim case R18: 264309124Sdim return 10; 265309124Sdim case R19: 266309124Sdim return 11; 267309124Sdim case R20: 268309124Sdim return 12; 269309124Sdim case R21: 270309124Sdim return 13; 271309124Sdim case R22: 272309124Sdim return 14; 273309124Sdim case R23: 274309124Sdim return 15; 275309124Sdim } 276309124Sdim} 277309124Sdim 278309124SdimMCExpr const &HexagonMCInstrInfo::getExpr(MCExpr const &Expr) { 279309124Sdim const auto &HExpr = cast<HexagonMCExpr>(Expr); 280309124Sdim assert(HExpr.getExpr()); 281309124Sdim return *HExpr.getExpr(); 282309124Sdim} 283309124Sdim 284284236Sdimunsigned short HexagonMCInstrInfo::getExtendableOp(MCInstrInfo const &MCII, 285284236Sdim MCInst const &MCI) { 286284236Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 287284236Sdim return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask); 288284236Sdim} 289284236Sdim 290284236SdimMCOperand const & 291284236SdimHexagonMCInstrInfo::getExtendableOperand(MCInstrInfo const &MCII, 292284236Sdim MCInst const &MCI) { 293284236Sdim unsigned O = HexagonMCInstrInfo::getExtendableOp(MCII, MCI); 294284236Sdim MCOperand const &MO = MCI.getOperand(O); 295284236Sdim 296284236Sdim assert((HexagonMCInstrInfo::isExtendable(MCII, MCI) || 297284236Sdim HexagonMCInstrInfo::isExtended(MCII, MCI)) && 298284236Sdim (MO.isImm() || MO.isExpr())); 299284236Sdim return (MO); 300284236Sdim} 301284236Sdim 302283625Sdimunsigned HexagonMCInstrInfo::getExtentAlignment(MCInstrInfo const &MCII, 303283625Sdim MCInst const &MCI) { 304283625Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 305283625Sdim return ((F >> HexagonII::ExtentAlignPos) & HexagonII::ExtentAlignMask); 306283625Sdim} 307283625Sdim 308283625Sdimunsigned HexagonMCInstrInfo::getExtentBits(MCInstrInfo const &MCII, 309283625Sdim MCInst const &MCI) { 310283625Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 311283625Sdim return ((F >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask); 312283625Sdim} 313283625Sdim 314341825Sdimbool HexagonMCInstrInfo::isExtentSigned(MCInstrInfo const &MCII, 315341825Sdim MCInst const &MCI) { 316341825Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 317341825Sdim return (F >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask; 318341825Sdim} 319341825Sdim 320321369Sdim/// Return the maximum value of an extendable operand. 321283625Sdimint HexagonMCInstrInfo::getMaxValue(MCInstrInfo const &MCII, 322283625Sdim MCInst const &MCI) { 323321369Sdim assert(HexagonMCInstrInfo::isExtendable(MCII, MCI) || 324321369Sdim HexagonMCInstrInfo::isExtended(MCII, MCI)); 325321369Sdim 326341825Sdim if (HexagonMCInstrInfo::isExtentSigned(MCII, MCI)) // if value is signed 327321369Sdim return (1 << (HexagonMCInstrInfo::getExtentBits(MCII, MCI) - 1)) - 1; 328321369Sdim return (1 << HexagonMCInstrInfo::getExtentBits(MCII, MCI)) - 1; 329283625Sdim} 330283625Sdim 331321369Sdim/// Return the minimum value of an extendable operand. 332283625Sdimint HexagonMCInstrInfo::getMinValue(MCInstrInfo const &MCII, 333283625Sdim MCInst const &MCI) { 334321369Sdim assert(HexagonMCInstrInfo::isExtendable(MCII, MCI) || 335321369Sdim HexagonMCInstrInfo::isExtended(MCII, MCI)); 336321369Sdim 337341825Sdim if (HexagonMCInstrInfo::isExtentSigned(MCII, MCI)) // if value is signed 338321369Sdim return -(1 << (HexagonMCInstrInfo::getExtentBits(MCII, MCI) - 1)); 339321369Sdim return 0; 340283625Sdim} 341283625Sdim 342314564SdimStringRef HexagonMCInstrInfo::getName(MCInstrInfo const &MCII, 343321369Sdim MCInst const &MCI) { 344283625Sdim return MCII.getName(MCI.getOpcode()); 345283625Sdim} 346283625Sdim 347284236Sdimunsigned short HexagonMCInstrInfo::getNewValueOp(MCInstrInfo const &MCII, 348283625Sdim MCInst const &MCI) { 349284236Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 350284236Sdim return ((F >> HexagonII::NewValueOpPos) & HexagonII::NewValueOpMask); 351284236Sdim} 352284236Sdim 353284236SdimMCOperand const &HexagonMCInstrInfo::getNewValueOperand(MCInstrInfo const &MCII, 354284236Sdim MCInst const &MCI) { 355327952Sdim if (HexagonMCInstrInfo::hasTmpDst(MCII, MCI)) { 356327952Sdim // VTMP doesn't actually exist in the encodings for these 184 357327952Sdim // 3 instructions so go ahead and create it here. 358327952Sdim static MCOperand MCO = MCOperand::createReg(Hexagon::VTMP); 359327952Sdim return (MCO); 360327952Sdim } else { 361327952Sdim unsigned O = HexagonMCInstrInfo::getNewValueOp(MCII, MCI); 362327952Sdim MCOperand const &MCO = MCI.getOperand(O); 363283625Sdim 364327952Sdim assert((HexagonMCInstrInfo::isNewValue(MCII, MCI) || 365327952Sdim HexagonMCInstrInfo::hasNewValue(MCII, MCI)) && 366327952Sdim MCO.isReg()); 367327952Sdim return (MCO); 368327952Sdim } 369283625Sdim} 370283625Sdim 371296417Sdim/// Return the new value or the newly produced value. 372296417Sdimunsigned short HexagonMCInstrInfo::getNewValueOp2(MCInstrInfo const &MCII, 373296417Sdim MCInst const &MCI) { 374296417Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 375296417Sdim return ((F >> HexagonII::NewValueOpPos2) & HexagonII::NewValueOpMask2); 376296417Sdim} 377296417Sdim 378296417SdimMCOperand const & 379296417SdimHexagonMCInstrInfo::getNewValueOperand2(MCInstrInfo const &MCII, 380296417Sdim MCInst const &MCI) { 381296417Sdim unsigned O = HexagonMCInstrInfo::getNewValueOp2(MCII, MCI); 382296417Sdim MCOperand const &MCO = MCI.getOperand(O); 383296417Sdim 384296417Sdim assert((HexagonMCInstrInfo::isNewValue(MCII, MCI) || 385296417Sdim HexagonMCInstrInfo::hasNewValue2(MCII, MCI)) && 386296417Sdim MCO.isReg()); 387296417Sdim return (MCO); 388296417Sdim} 389296417Sdim 390321369Sdim/// Return the Hexagon ISA class for the insn. 391283625Sdimunsigned HexagonMCInstrInfo::getType(MCInstrInfo const &MCII, 392283625Sdim MCInst const &MCI) { 393321369Sdim const uint64_t F = MCII.get(MCI.getOpcode()).TSFlags; 394283625Sdim return ((F >> HexagonII::TypePos) & HexagonII::TypeMask); 395283625Sdim} 396283625Sdim 397321369Sdim/// Return the slots this instruction can execute out of 398284236Sdimunsigned HexagonMCInstrInfo::getUnits(MCInstrInfo const &MCII, 399284236Sdim MCSubtargetInfo const &STI, 400284236Sdim MCInst const &MCI) { 401284236Sdim const InstrItinerary *II = STI.getSchedModel().InstrItineraries; 402284236Sdim int SchedClass = HexagonMCInstrInfo::getDesc(MCII, MCI).getSchedClass(); 403284236Sdim return ((II[SchedClass].FirstStage + HexagonStages)->getUnits()); 404284236Sdim} 405284236Sdim 406321369Sdim/// Return the slots this instruction consumes in addition to 407321369Sdim/// the slot(s) it can execute out of 408321369Sdim 409321369Sdimunsigned HexagonMCInstrInfo::getOtherReservedSlots(MCInstrInfo const &MCII, 410321369Sdim MCSubtargetInfo const &STI, 411321369Sdim MCInst const &MCI) { 412321369Sdim const InstrItinerary *II = STI.getSchedModel().InstrItineraries; 413321369Sdim int SchedClass = HexagonMCInstrInfo::getDesc(MCII, MCI).getSchedClass(); 414321369Sdim unsigned Slots = 0; 415321369Sdim 416321369Sdim // FirstStage are slots that this instruction can execute in. 417321369Sdim // FirstStage+1 are slots that are also consumed by this instruction. 418321369Sdim // For example: vmemu can only execute in slot 0 but also consumes slot 1. 419321369Sdim for (unsigned Stage = II[SchedClass].FirstStage + 1; 420321369Sdim Stage < II[SchedClass].LastStage; ++Stage) { 421321369Sdim unsigned Units = (Stage + HexagonStages)->getUnits(); 422321369Sdim if (Units > HexagonGetLastSlot()) 423321369Sdim break; 424321369Sdim // fyi: getUnits() will return 0x1, 0x2, 0x4 or 0x8 425321369Sdim Slots |= Units; 426321369Sdim } 427321369Sdim 428321369Sdim // if 0 is returned, then no additional slots are consumed by this inst. 429321369Sdim return Slots; 430321369Sdim} 431321369Sdim 432321369Sdimbool HexagonMCInstrInfo::hasDuplex(MCInstrInfo const &MCII, MCInst const &MCI) { 433284236Sdim if (!HexagonMCInstrInfo::isBundle(MCI)) 434284236Sdim return false; 435284236Sdim 436327952Sdim for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCI)) { 437327952Sdim if (HexagonMCInstrInfo::isDuplex(MCII, *I.getInst())) 438284236Sdim return true; 439284236Sdim } 440284236Sdim 441284236Sdim return false; 442284236Sdim} 443284236Sdim 444284236Sdimbool HexagonMCInstrInfo::hasExtenderForIndex(MCInst const &MCB, size_t Index) { 445284236Sdim return extenderForIndex(MCB, Index) != nullptr; 446284236Sdim} 447284236Sdim 448327952Sdimbool HexagonMCInstrInfo::hasImmExt(MCInst const &MCI) { 449321369Sdim if (!HexagonMCInstrInfo::isBundle(MCI)) 450321369Sdim return false; 451321369Sdim 452321369Sdim for (const auto &I : HexagonMCInstrInfo::bundleInstructions(MCI)) { 453321369Sdim if (isImmext(*I.getInst())) 454321369Sdim return true; 455321369Sdim } 456321369Sdim 457321369Sdim return false; 458321369Sdim} 459321369Sdim 460321369Sdim/// Return whether the insn produces a value. 461283625Sdimbool HexagonMCInstrInfo::hasNewValue(MCInstrInfo const &MCII, 462283625Sdim MCInst const &MCI) { 463283625Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 464283625Sdim return ((F >> HexagonII::hasNewValuePos) & HexagonII::hasNewValueMask); 465283625Sdim} 466283625Sdim 467296417Sdim/// Return whether the insn produces a second value. 468296417Sdimbool HexagonMCInstrInfo::hasNewValue2(MCInstrInfo const &MCII, 469296417Sdim MCInst const &MCI) { 470296417Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 471296417Sdim return ((F >> HexagonII::hasNewValuePos2) & HexagonII::hasNewValueMask2); 472296417Sdim} 473296417Sdim 474284236SdimMCInst const &HexagonMCInstrInfo::instruction(MCInst const &MCB, size_t Index) { 475284236Sdim assert(isBundle(MCB)); 476284236Sdim assert(Index < HEXAGON_PACKET_SIZE); 477284236Sdim return *MCB.getOperand(bundleInstructionsOffset + Index).getInst(); 478284236Sdim} 479284236Sdim 480321369Sdim/// Return where the instruction is an accumulator. 481321369Sdimbool HexagonMCInstrInfo::isAccumulator(MCInstrInfo const &MCII, 482321369Sdim MCInst const &MCI) { 483321369Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 484321369Sdim return ((F >> HexagonII::AccumulatorPos) & HexagonII::AccumulatorMask); 485321369Sdim} 486321369Sdim 487284236Sdimbool HexagonMCInstrInfo::isBundle(MCInst const &MCI) { 488284236Sdim auto Result = Hexagon::BUNDLE == MCI.getOpcode(); 489284236Sdim assert(!Result || (MCI.size() > 0 && MCI.getOperand(0).isImm())); 490284236Sdim return Result; 491284236Sdim} 492284236Sdim 493283625Sdimbool HexagonMCInstrInfo::isConstExtended(MCInstrInfo const &MCII, 494283625Sdim MCInst const &MCI) { 495283625Sdim if (HexagonMCInstrInfo::isExtended(MCII, MCI)) 496283625Sdim return true; 497309124Sdim if (!HexagonMCInstrInfo::isExtendable(MCII, MCI)) 498309124Sdim return false; 499309124Sdim MCOperand const &MO = HexagonMCInstrInfo::getExtendableOperand(MCII, MCI); 500309124Sdim if (isa<HexagonMCExpr>(MO.getExpr()) && 501309124Sdim HexagonMCInstrInfo::mustExtend(*MO.getExpr())) 502309124Sdim return true; 503296417Sdim // Branch insns are handled as necessary by relaxation. 504296417Sdim if ((HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeJ) || 505321369Sdim (HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeCJ && 506296417Sdim HexagonMCInstrInfo::getDesc(MCII, MCI).isBranch()) || 507321369Sdim (HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeNCJ && 508296417Sdim HexagonMCInstrInfo::getDesc(MCII, MCI).isBranch())) 509283625Sdim return false; 510296417Sdim // Otherwise loop instructions and other CR insts are handled by relaxation 511296417Sdim else if ((HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeCR) && 512296417Sdim (MCI.getOpcode() != Hexagon::C4_addipc)) 513296417Sdim return false; 514283625Sdim 515296417Sdim assert(!MO.isImm()); 516309124Sdim if (isa<HexagonMCExpr>(MO.getExpr()) && 517309124Sdim HexagonMCInstrInfo::mustNotExtend(*MO.getExpr())) 518309124Sdim return false; 519296417Sdim int64_t Value; 520296417Sdim if (!MO.getExpr()->evaluateAsAbsolute(Value)) 521283625Sdim return true; 522296417Sdim int MinValue = HexagonMCInstrInfo::getMinValue(MCII, MCI); 523296417Sdim int MaxValue = HexagonMCInstrInfo::getMaxValue(MCII, MCI); 524296417Sdim return (MinValue > Value || Value > MaxValue); 525283625Sdim} 526283625Sdim 527321369Sdimbool HexagonMCInstrInfo::isCanon(MCInstrInfo const &MCII, MCInst const &MCI) { 528321369Sdim return !HexagonMCInstrInfo::getDesc(MCII, MCI).isPseudo() && 529321369Sdim !HexagonMCInstrInfo::isPrefix(MCII, MCI); 530321369Sdim} 531321369Sdim 532321369Sdimbool HexagonMCInstrInfo::isCofMax1(MCInstrInfo const &MCII, MCInst const &MCI) { 533321369Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 534321369Sdim return ((F >> HexagonII::CofMax1Pos) & HexagonII::CofMax1Mask); 535321369Sdim} 536321369Sdim 537327952Sdimbool HexagonMCInstrInfo::isCofRelax1(MCInstrInfo const &MCII, 538327952Sdim MCInst const &MCI) { 539327952Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 540327952Sdim return ((F >> HexagonII::CofRelax1Pos) & HexagonII::CofRelax1Mask); 541327952Sdim} 542327952Sdim 543327952Sdimbool HexagonMCInstrInfo::isCofRelax2(MCInstrInfo const &MCII, 544327952Sdim MCInst const &MCI) { 545327952Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 546327952Sdim return ((F >> HexagonII::CofRelax2Pos) & HexagonII::CofRelax2Mask); 547327952Sdim} 548327952Sdim 549321369Sdimbool HexagonMCInstrInfo::isCompound(MCInstrInfo const &MCII, 550321369Sdim MCInst const &MCI) { 551321369Sdim return (getType(MCII, MCI) == HexagonII::TypeCJ); 552321369Sdim} 553321369Sdim 554321369Sdimbool HexagonMCInstrInfo::isCVINew(MCInstrInfo const &MCII, MCInst const &MCI) { 555321369Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 556321369Sdim return ((F >> HexagonII::CVINewPos) & HexagonII::CVINewMask); 557321369Sdim} 558321369Sdim 559321369Sdimbool HexagonMCInstrInfo::isDblRegForSubInst(unsigned Reg) { 560321369Sdim return ((Reg >= Hexagon::D0 && Reg <= Hexagon::D3) || 561321369Sdim (Reg >= Hexagon::D8 && Reg <= Hexagon::D11)); 562321369Sdim} 563321369Sdim 564321369Sdimbool HexagonMCInstrInfo::isDuplex(MCInstrInfo const &MCII, MCInst const &MCI) { 565321369Sdim return HexagonII::TypeDUPLEX == HexagonMCInstrInfo::getType(MCII, MCI); 566321369Sdim} 567321369Sdim 568283625Sdimbool HexagonMCInstrInfo::isExtendable(MCInstrInfo const &MCII, 569283625Sdim MCInst const &MCI) { 570283625Sdim uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 571283625Sdim return (F >> HexagonII::ExtendablePos) & HexagonII::ExtendableMask; 572283625Sdim} 573283625Sdim 574283625Sdimbool HexagonMCInstrInfo::isExtended(MCInstrInfo const &MCII, 575283625Sdim MCInst const &MCI) { 576283625Sdim uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 577283625Sdim return (F >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask; 578283625Sdim} 579283625Sdim 580284236Sdimbool HexagonMCInstrInfo::isFloat(MCInstrInfo const &MCII, MCInst const &MCI) { 581284236Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 582284236Sdim return ((F >> HexagonII::FPPos) & HexagonII::FPMask); 583284236Sdim} 584284236Sdim 585327952Sdimbool HexagonMCInstrInfo::isHVX(MCInstrInfo const &MCII, MCInst const &MCI) { 586327952Sdim const uint64_t V = getType(MCII, MCI); 587327952Sdim return HexagonII::TypeCVI_FIRST <= V && V <= HexagonII::TypeCVI_LAST; 588327952Sdim} 589327952Sdim 590284236Sdimbool HexagonMCInstrInfo::isImmext(MCInst const &MCI) { 591321369Sdim return MCI.getOpcode() == Hexagon::A4_ext; 592284236Sdim} 593284236Sdim 594284236Sdimbool HexagonMCInstrInfo::isInnerLoop(MCInst const &MCI) { 595284236Sdim assert(isBundle(MCI)); 596284236Sdim int64_t Flags = MCI.getOperand(0).getImm(); 597284236Sdim return (Flags & innerLoopMask) != 0; 598284236Sdim} 599284236Sdim 600284236Sdimbool HexagonMCInstrInfo::isIntReg(unsigned Reg) { 601284236Sdim return (Reg >= Hexagon::R0 && Reg <= Hexagon::R31); 602284236Sdim} 603284236Sdim 604284236Sdimbool HexagonMCInstrInfo::isIntRegForSubInst(unsigned Reg) { 605284236Sdim return ((Reg >= Hexagon::R0 && Reg <= Hexagon::R7) || 606284236Sdim (Reg >= Hexagon::R16 && Reg <= Hexagon::R23)); 607284236Sdim} 608284236Sdim 609321369Sdim/// Return whether the insn expects newly produced value. 610283625Sdimbool HexagonMCInstrInfo::isNewValue(MCInstrInfo const &MCII, 611283625Sdim MCInst const &MCI) { 612283625Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 613283625Sdim return ((F >> HexagonII::NewValuePos) & HexagonII::NewValueMask); 614283625Sdim} 615283625Sdim 616321369Sdim/// Return whether the operand is extendable. 617321369Sdimbool HexagonMCInstrInfo::isOpExtendable(MCInstrInfo const &MCII, 618321369Sdim MCInst const &MCI, unsigned short O) { 619321369Sdim return (O == HexagonMCInstrInfo::getExtendableOp(MCII, MCI)); 620283625Sdim} 621283625Sdim 622284236Sdimbool HexagonMCInstrInfo::isOuterLoop(MCInst const &MCI) { 623284236Sdim assert(isBundle(MCI)); 624284236Sdim int64_t Flags = MCI.getOperand(0).getImm(); 625284236Sdim return (Flags & outerLoopMask) != 0; 626283625Sdim} 627283625Sdim 628284236Sdimbool HexagonMCInstrInfo::isPredicated(MCInstrInfo const &MCII, 629284236Sdim MCInst const &MCI) { 630284236Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 631284236Sdim return ((F >> HexagonII::PredicatedPos) & HexagonII::PredicatedMask); 632283625Sdim} 633283625Sdim 634321369Sdimbool HexagonMCInstrInfo::isPrefix(MCInstrInfo const &MCII, MCInst const &MCI) { 635321369Sdim return HexagonII::TypeEXTENDER == HexagonMCInstrInfo::getType(MCII, MCI); 636321369Sdim} 637321369Sdim 638296417Sdimbool HexagonMCInstrInfo::isPredicateLate(MCInstrInfo const &MCII, 639296417Sdim MCInst const &MCI) { 640296417Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 641296417Sdim return (F >> HexagonII::PredicateLatePos & HexagonII::PredicateLateMask); 642296417Sdim} 643296417Sdim 644296417Sdim/// Return whether the insn is newly predicated. 645296417Sdimbool HexagonMCInstrInfo::isPredicatedNew(MCInstrInfo const &MCII, 646296417Sdim MCInst const &MCI) { 647296417Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 648296417Sdim return ((F >> HexagonII::PredicatedNewPos) & HexagonII::PredicatedNewMask); 649296417Sdim} 650296417Sdim 651284236Sdimbool HexagonMCInstrInfo::isPredicatedTrue(MCInstrInfo const &MCII, 652284236Sdim MCInst const &MCI) { 653284236Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 654284236Sdim return ( 655284236Sdim !((F >> HexagonII::PredicatedFalsePos) & HexagonII::PredicatedFalseMask)); 656284236Sdim} 657284236Sdim 658284236Sdimbool HexagonMCInstrInfo::isPredReg(unsigned Reg) { 659284236Sdim return (Reg >= Hexagon::P0 && Reg <= Hexagon::P3_0); 660284236Sdim} 661284236Sdim 662321369Sdim/// Return whether the insn can be packaged only with A and X-type insns. 663321369Sdimbool HexagonMCInstrInfo::isSoloAX(MCInstrInfo const &MCII, MCInst const &MCI) { 664321369Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 665321369Sdim return ((F >> HexagonII::SoloAXPos) & HexagonII::SoloAXMask); 666283625Sdim} 667283625Sdim 668321369Sdim/// Return whether the insn can be packaged only with an A-type insn in slot #1. 669327952Sdimbool HexagonMCInstrInfo::isRestrictSlot1AOK(MCInstrInfo const &MCII, 670327952Sdim MCInst const &MCI) { 671321369Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 672327952Sdim return ((F >> HexagonII::RestrictSlot1AOKPos) & 673327952Sdim HexagonII::RestrictSlot1AOKMask); 674321369Sdim} 675321369Sdim 676327952Sdimbool HexagonMCInstrInfo::isRestrictNoSlot1Store(MCInstrInfo const &MCII, 677327952Sdim MCInst const &MCI) { 678327952Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 679327952Sdim return ((F >> HexagonII::RestrictNoSlot1StorePos) & 680327952Sdim HexagonII::RestrictNoSlot1StoreMask); 681327952Sdim} 682327952Sdim 683321369Sdim/// Return whether the insn is solo, i.e., cannot be in a packet. 684283625Sdimbool HexagonMCInstrInfo::isSolo(MCInstrInfo const &MCII, MCInst const &MCI) { 685321369Sdim const uint64_t F = MCII.get(MCI.getOpcode()).TSFlags; 686283625Sdim return ((F >> HexagonII::SoloPos) & HexagonII::SoloMask); 687283625Sdim} 688283625Sdim 689296417Sdimbool HexagonMCInstrInfo::isMemReorderDisabled(MCInst const &MCI) { 690296417Sdim assert(isBundle(MCI)); 691296417Sdim auto Flags = MCI.getOperand(0).getImm(); 692296417Sdim return (Flags & memReorderDisabledMask) != 0; 693296417Sdim} 694296417Sdim 695309124Sdimbool HexagonMCInstrInfo::isSubInstruction(MCInst const &MCI) { 696309124Sdim switch (MCI.getOpcode()) { 697309124Sdim default: 698309124Sdim return false; 699314564Sdim case Hexagon::SA1_addi: 700314564Sdim case Hexagon::SA1_addrx: 701314564Sdim case Hexagon::SA1_addsp: 702314564Sdim case Hexagon::SA1_and1: 703314564Sdim case Hexagon::SA1_clrf: 704314564Sdim case Hexagon::SA1_clrfnew: 705314564Sdim case Hexagon::SA1_clrt: 706314564Sdim case Hexagon::SA1_clrtnew: 707314564Sdim case Hexagon::SA1_cmpeqi: 708314564Sdim case Hexagon::SA1_combine0i: 709314564Sdim case Hexagon::SA1_combine1i: 710314564Sdim case Hexagon::SA1_combine2i: 711314564Sdim case Hexagon::SA1_combine3i: 712314564Sdim case Hexagon::SA1_combinerz: 713314564Sdim case Hexagon::SA1_combinezr: 714314564Sdim case Hexagon::SA1_dec: 715314564Sdim case Hexagon::SA1_inc: 716314564Sdim case Hexagon::SA1_seti: 717314564Sdim case Hexagon::SA1_setin1: 718314564Sdim case Hexagon::SA1_sxtb: 719314564Sdim case Hexagon::SA1_sxth: 720314564Sdim case Hexagon::SA1_tfr: 721314564Sdim case Hexagon::SA1_zxtb: 722314564Sdim case Hexagon::SA1_zxth: 723314564Sdim case Hexagon::SL1_loadri_io: 724314564Sdim case Hexagon::SL1_loadrub_io: 725314564Sdim case Hexagon::SL2_deallocframe: 726314564Sdim case Hexagon::SL2_jumpr31: 727314564Sdim case Hexagon::SL2_jumpr31_f: 728314564Sdim case Hexagon::SL2_jumpr31_fnew: 729314564Sdim case Hexagon::SL2_jumpr31_t: 730314564Sdim case Hexagon::SL2_jumpr31_tnew: 731314564Sdim case Hexagon::SL2_loadrb_io: 732314564Sdim case Hexagon::SL2_loadrd_sp: 733314564Sdim case Hexagon::SL2_loadrh_io: 734314564Sdim case Hexagon::SL2_loadri_sp: 735314564Sdim case Hexagon::SL2_loadruh_io: 736314564Sdim case Hexagon::SL2_return: 737314564Sdim case Hexagon::SL2_return_f: 738314564Sdim case Hexagon::SL2_return_fnew: 739314564Sdim case Hexagon::SL2_return_t: 740314564Sdim case Hexagon::SL2_return_tnew: 741314564Sdim case Hexagon::SS1_storeb_io: 742314564Sdim case Hexagon::SS1_storew_io: 743314564Sdim case Hexagon::SS2_allocframe: 744314564Sdim case Hexagon::SS2_storebi0: 745314564Sdim case Hexagon::SS2_storebi1: 746314564Sdim case Hexagon::SS2_stored_sp: 747314564Sdim case Hexagon::SS2_storeh_io: 748314564Sdim case Hexagon::SS2_storew_sp: 749314564Sdim case Hexagon::SS2_storewi0: 750314564Sdim case Hexagon::SS2_storewi1: 751309124Sdim return true; 752309124Sdim } 753309124Sdim} 754309124Sdim 755296417Sdimbool HexagonMCInstrInfo::isVector(MCInstrInfo const &MCII, MCInst const &MCI) { 756296417Sdim if ((getType(MCII, MCI) <= HexagonII::TypeCVI_LAST) && 757296417Sdim (getType(MCII, MCI) >= HexagonII::TypeCVI_FIRST)) 758296417Sdim return true; 759296417Sdim return false; 760296417Sdim} 761296417Sdim 762296417Sdimint64_t HexagonMCInstrInfo::minConstant(MCInst const &MCI, size_t Index) { 763296417Sdim auto Sentinal = static_cast<int64_t>(std::numeric_limits<uint32_t>::max()) 764296417Sdim << 8; 765296417Sdim if (MCI.size() <= Index) 766296417Sdim return Sentinal; 767296417Sdim MCOperand const &MCO = MCI.getOperand(Index); 768296417Sdim if (!MCO.isExpr()) 769296417Sdim return Sentinal; 770296417Sdim int64_t Value; 771296417Sdim if (!MCO.getExpr()->evaluateAsAbsolute(Value)) 772296417Sdim return Sentinal; 773296417Sdim return Value; 774296417Sdim} 775296417Sdim 776309124Sdimvoid HexagonMCInstrInfo::setMustExtend(MCExpr const &Expr, bool Val) { 777309124Sdim HexagonMCExpr &HExpr = const_cast<HexagonMCExpr &>(cast<HexagonMCExpr>(Expr)); 778309124Sdim HExpr.setMustExtend(Val); 779309124Sdim} 780309124Sdim 781309124Sdimbool HexagonMCInstrInfo::mustExtend(MCExpr const &Expr) { 782309124Sdim HexagonMCExpr const &HExpr = cast<HexagonMCExpr>(Expr); 783309124Sdim return HExpr.mustExtend(); 784309124Sdim} 785309124Sdimvoid HexagonMCInstrInfo::setMustNotExtend(MCExpr const &Expr, bool Val) { 786321369Sdim HexagonMCExpr &HExpr = const_cast<HexagonMCExpr &>(cast<HexagonMCExpr>(Expr)); 787309124Sdim HExpr.setMustNotExtend(Val); 788309124Sdim} 789309124Sdimbool HexagonMCInstrInfo::mustNotExtend(MCExpr const &Expr) { 790309124Sdim HexagonMCExpr const &HExpr = cast<HexagonMCExpr>(Expr); 791309124Sdim return HExpr.mustNotExtend(); 792309124Sdim} 793321369Sdimvoid HexagonMCInstrInfo::setS27_2_reloc(MCExpr const &Expr, bool Val) { 794321369Sdim HexagonMCExpr &HExpr = 795327952Sdim const_cast<HexagonMCExpr &>(*cast<HexagonMCExpr>(&Expr)); 796321369Sdim HExpr.setS27_2_reloc(Val); 797321369Sdim} 798321369Sdimbool HexagonMCInstrInfo::s27_2_reloc(MCExpr const &Expr) { 799327952Sdim HexagonMCExpr const *HExpr = dyn_cast<HexagonMCExpr>(&Expr); 800321369Sdim if (!HExpr) 801321369Sdim return false; 802321369Sdim return HExpr->s27_2_reloc(); 803321369Sdim} 804309124Sdim 805321369Sdimvoid HexagonMCInstrInfo::padEndloop(MCInst &MCB, MCContext &Context) { 806284236Sdim MCInst Nop; 807284236Sdim Nop.setOpcode(Hexagon::A2_nop); 808284236Sdim assert(isBundle(MCB)); 809284236Sdim while ((HexagonMCInstrInfo::isInnerLoop(MCB) && 810284236Sdim (HexagonMCInstrInfo::bundleSize(MCB) < HEXAGON_PACKET_INNER_SIZE)) || 811284236Sdim ((HexagonMCInstrInfo::isOuterLoop(MCB) && 812284236Sdim (HexagonMCInstrInfo::bundleSize(MCB) < HEXAGON_PACKET_OUTER_SIZE)))) 813296417Sdim MCB.addOperand(MCOperand::createInst(new (Context) MCInst(Nop))); 814283625Sdim} 815283625Sdim 816327952SdimHexagonMCInstrInfo::PredicateInfo 817327952SdimHexagonMCInstrInfo::predicateInfo(MCInstrInfo const &MCII, MCInst const &MCI) { 818327952Sdim if (!isPredicated(MCII, MCI)) 819327952Sdim return {0, 0, false}; 820327952Sdim MCInstrDesc const &Desc = getDesc(MCII, MCI); 821327952Sdim for (auto I = Desc.getNumDefs(), N = Desc.getNumOperands(); I != N; ++I) 822327952Sdim if (Desc.OpInfo[I].RegClass == Hexagon::PredRegsRegClassID) 823327952Sdim return {MCI.getOperand(I).getReg(), I, isPredicatedTrue(MCII, MCI)}; 824327952Sdim return {0, 0, false}; 825327952Sdim} 826327952Sdim 827284236Sdimbool HexagonMCInstrInfo::prefersSlot3(MCInstrInfo const &MCII, 828284236Sdim MCInst const &MCI) { 829321369Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 830321369Sdim return (F >> HexagonII::PrefersSlot3Pos) & HexagonII::PrefersSlot3Mask; 831283625Sdim} 832284236Sdim 833327952Sdim/// return true if instruction has hasTmpDst attribute. 834327952Sdimbool HexagonMCInstrInfo::hasTmpDst(MCInstrInfo const &MCII, MCInst const &MCI) { 835327952Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 836327952Sdim return (F >> HexagonII::HasTmpDstPos) & HexagonII::HasTmpDstMask; 837327952Sdim} 838327952Sdim 839284236Sdimvoid HexagonMCInstrInfo::replaceDuplex(MCContext &Context, MCInst &MCB, 840284236Sdim DuplexCandidate Candidate) { 841284236Sdim assert(Candidate.packetIndexI < MCB.size()); 842284236Sdim assert(Candidate.packetIndexJ < MCB.size()); 843284236Sdim assert(isBundle(MCB)); 844284236Sdim MCInst *Duplex = 845284236Sdim deriveDuplex(Context, Candidate.iClass, 846284236Sdim *MCB.getOperand(Candidate.packetIndexJ).getInst(), 847284236Sdim *MCB.getOperand(Candidate.packetIndexI).getInst()); 848284236Sdim assert(Duplex != nullptr); 849284236Sdim MCB.getOperand(Candidate.packetIndexI).setInst(Duplex); 850284236Sdim MCB.erase(MCB.begin() + Candidate.packetIndexJ); 851283625Sdim} 852284236Sdim 853284236Sdimvoid HexagonMCInstrInfo::setInnerLoop(MCInst &MCI) { 854284236Sdim assert(isBundle(MCI)); 855284236Sdim MCOperand &Operand = MCI.getOperand(0); 856284236Sdim Operand.setImm(Operand.getImm() | innerLoopMask); 857284236Sdim} 858284236Sdim 859296417Sdimvoid HexagonMCInstrInfo::setMemReorderDisabled(MCInst &MCI) { 860296417Sdim assert(isBundle(MCI)); 861296417Sdim MCOperand &Operand = MCI.getOperand(0); 862296417Sdim Operand.setImm(Operand.getImm() | memReorderDisabledMask); 863296417Sdim assert(isMemReorderDisabled(MCI)); 864296417Sdim} 865296417Sdim 866284236Sdimvoid HexagonMCInstrInfo::setOuterLoop(MCInst &MCI) { 867284236Sdim assert(isBundle(MCI)); 868284236Sdim MCOperand &Operand = MCI.getOperand(0); 869284236Sdim Operand.setImm(Operand.getImm() | outerLoopMask); 870284236Sdim} 871309124Sdim 872309124Sdimunsigned HexagonMCInstrInfo::SubregisterBit(unsigned Consumer, 873309124Sdim unsigned Producer, 874309124Sdim unsigned Producer2) { 875309124Sdim // If we're a single vector consumer of a double producer, set subreg bit 876309124Sdim // based on if we're accessing the lower or upper register component 877309124Sdim if (Producer >= Hexagon::W0 && Producer <= Hexagon::W15) 878309124Sdim if (Consumer >= Hexagon::V0 && Consumer <= Hexagon::V31) 879309124Sdim return (Consumer - Hexagon::V0) & 0x1; 880327952Sdim if (Producer2 != Hexagon::NoRegister) 881327952Sdim return Consumer == Producer; 882309124Sdim return 0; 883285181Sdim} 884