HexagonMCInstrInfo.cpp revision 327952
1283625Sdim//===- HexagonMCInstrInfo.cpp - Hexagon sub-class of MCInst ---------------===// 2283625Sdim// 3283625Sdim// The LLVM Compiler Infrastructure 4283625Sdim// 5283625Sdim// This file is distributed under the University of Illinois Open Source 6283625Sdim// License. See LICENSE.TXT for details. 7283625Sdim// 8283625Sdim//===----------------------------------------------------------------------===// 9283625Sdim// 10283625Sdim// This class extends MCInstrInfo to allow Hexagon specific MCInstr queries 11283625Sdim// 12283625Sdim//===----------------------------------------------------------------------===// 13283625Sdim 14327952Sdim#include "MCTargetDesc/HexagonMCInstrInfo.h" 15284236Sdim#include "Hexagon.h" 16327952Sdim#include "MCTargetDesc/HexagonBaseInfo.h" 17327952Sdim#include "MCTargetDesc/HexagonMCChecker.h" 18327952Sdim#include "MCTargetDesc/HexagonMCExpr.h" 19327952Sdim#include "MCTargetDesc/HexagonMCShuffler.h" 20327952Sdim#include "MCTargetDesc/HexagonMCTargetDesc.h" 21327952Sdim#include "llvm/ADT/SmallVector.h" 22284236Sdim#include "llvm/MC/MCContext.h" 23327952Sdim#include "llvm/MC/MCExpr.h" 24327952Sdim#include "llvm/MC/MCInst.h" 25284236Sdim#include "llvm/MC/MCInstrInfo.h" 26321369Sdim#include "llvm/MC/MCInstrItineraries.h" 27284236Sdim#include "llvm/MC/MCSubtargetInfo.h" 28327952Sdim#include "llvm/Support/Casting.h" 29327952Sdim#include "llvm/Support/ErrorHandling.h" 30327952Sdim#include <cassert> 31327952Sdim#include <cstdint> 32327952Sdim#include <limits> 33284236Sdim 34327952Sdimusing namespace llvm; 35321369Sdim 36327952Sdimbool HexagonMCInstrInfo::PredicateInfo::isPredicated() const { 37327952Sdim return Register != Hexagon::NoRegister; 38327952Sdim} 39327952Sdim 40321369SdimHexagon::PacketIterator::PacketIterator(MCInstrInfo const &MCII, 41321369Sdim MCInst const &Inst) 42321369Sdim : MCII(MCII), BundleCurrent(Inst.begin() + 43321369Sdim HexagonMCInstrInfo::bundleInstructionsOffset), 44321369Sdim BundleEnd(Inst.end()), DuplexCurrent(Inst.end()), DuplexEnd(Inst.end()) {} 45321369Sdim 46321369SdimHexagon::PacketIterator::PacketIterator(MCInstrInfo const &MCII, 47321369Sdim MCInst const &Inst, std::nullptr_t) 48321369Sdim : MCII(MCII), BundleCurrent(Inst.end()), BundleEnd(Inst.end()), 49321369Sdim DuplexCurrent(Inst.end()), DuplexEnd(Inst.end()) {} 50321369Sdim 51321369SdimHexagon::PacketIterator &Hexagon::PacketIterator::operator++() { 52321369Sdim if (DuplexCurrent != DuplexEnd) { 53321369Sdim ++DuplexCurrent; 54321369Sdim if (DuplexCurrent == DuplexEnd) { 55321369Sdim DuplexCurrent = BundleEnd; 56321369Sdim DuplexEnd = BundleEnd; 57327952Sdim ++BundleCurrent; 58321369Sdim } 59321369Sdim return *this; 60321369Sdim } 61321369Sdim ++BundleCurrent; 62321369Sdim if (BundleCurrent != BundleEnd) { 63321369Sdim MCInst const &Inst = *BundleCurrent->getInst(); 64321369Sdim if (HexagonMCInstrInfo::isDuplex(MCII, Inst)) { 65321369Sdim DuplexCurrent = Inst.begin(); 66321369Sdim DuplexEnd = Inst.end(); 67321369Sdim } 68321369Sdim } 69321369Sdim return *this; 70321369Sdim} 71321369Sdim 72321369SdimMCInst const &Hexagon::PacketIterator::operator*() const { 73321369Sdim if (DuplexCurrent != DuplexEnd) 74321369Sdim return *DuplexCurrent->getInst(); 75321369Sdim return *BundleCurrent->getInst(); 76321369Sdim} 77321369Sdim 78321369Sdimbool Hexagon::PacketIterator::operator==(PacketIterator const &Other) const { 79321369Sdim return BundleCurrent == Other.BundleCurrent && BundleEnd == Other.BundleEnd && 80321369Sdim DuplexCurrent == Other.DuplexCurrent && DuplexEnd == Other.DuplexEnd; 81321369Sdim} 82321369Sdim 83296417Sdimvoid HexagonMCInstrInfo::addConstant(MCInst &MI, uint64_t Value, 84296417Sdim MCContext &Context) { 85296417Sdim MI.addOperand(MCOperand::createExpr(MCConstantExpr::create(Value, Context))); 86296417Sdim} 87296417Sdim 88296417Sdimvoid HexagonMCInstrInfo::addConstExtender(MCContext &Context, 89296417Sdim MCInstrInfo const &MCII, MCInst &MCB, 90296417Sdim MCInst const &MCI) { 91296417Sdim assert(HexagonMCInstrInfo::isBundle(MCB)); 92296417Sdim MCOperand const &exOp = 93296417Sdim MCI.getOperand(HexagonMCInstrInfo::getExtendableOp(MCII, MCI)); 94296417Sdim 95296417Sdim // Create the extender. 96296417Sdim MCInst *XMCI = 97296417Sdim new (Context) MCInst(HexagonMCInstrInfo::deriveExtender(MCII, MCI, exOp)); 98327952Sdim XMCI->setLoc(MCI.getLoc()); 99296417Sdim 100296417Sdim MCB.addOperand(MCOperand::createInst(XMCI)); 101296417Sdim} 102296417Sdim 103321369Sdimiterator_range<Hexagon::PacketIterator> 104321369SdimHexagonMCInstrInfo::bundleInstructions(MCInstrInfo const &MCII, 105321369Sdim MCInst const &MCI) { 106321369Sdim assert(isBundle(MCI)); 107321369Sdim return make_range(Hexagon::PacketIterator(MCII, MCI), 108321369Sdim Hexagon::PacketIterator(MCII, MCI, nullptr)); 109321369Sdim} 110321369Sdim 111284236Sdimiterator_range<MCInst::const_iterator> 112284236SdimHexagonMCInstrInfo::bundleInstructions(MCInst const &MCI) { 113284236Sdim assert(isBundle(MCI)); 114296417Sdim return make_range(MCI.begin() + bundleInstructionsOffset, MCI.end()); 115283625Sdim} 116283625Sdim 117284236Sdimsize_t HexagonMCInstrInfo::bundleSize(MCInst const &MCI) { 118284236Sdim if (HexagonMCInstrInfo::isBundle(MCI)) 119284236Sdim return (MCI.size() - bundleInstructionsOffset); 120284236Sdim else 121284236Sdim return (1); 122284236Sdim} 123284236Sdim 124296417Sdimbool HexagonMCInstrInfo::canonicalizePacket(MCInstrInfo const &MCII, 125296417Sdim MCSubtargetInfo const &STI, 126296417Sdim MCContext &Context, MCInst &MCB, 127296417Sdim HexagonMCChecker *Check) { 128321369Sdim // Check the bundle for errors. 129321369Sdim bool CheckOk = Check ? Check->check(false) : true; 130321369Sdim if (!CheckOk) 131321369Sdim return false; 132296417Sdim // Examine the packet and convert pairs of instructions to compound 133296417Sdim // instructions when possible. 134296417Sdim if (!HexagonDisableCompound) 135321369Sdim HexagonMCInstrInfo::tryCompound(MCII, STI, Context, MCB); 136321369Sdim HexagonMCShuffle(Context, false, MCII, STI, MCB); 137296417Sdim // Examine the packet and convert pairs of instructions to duplex 138296417Sdim // instructions when possible. 139296417Sdim MCInst InstBundlePreDuplex = MCInst(MCB); 140327952Sdim if (STI.getFeatureBits() [Hexagon::FeatureDuplex]) { 141296417Sdim SmallVector<DuplexCandidate, 8> possibleDuplexes; 142321369Sdim possibleDuplexes = 143321369Sdim HexagonMCInstrInfo::getDuplexPossibilties(MCII, STI, MCB); 144321369Sdim HexagonMCShuffle(Context, MCII, STI, MCB, possibleDuplexes); 145296417Sdim } 146296417Sdim // Examines packet and pad the packet, if needed, when an 147296417Sdim // end-loop is in the bundle. 148321369Sdim HexagonMCInstrInfo::padEndloop(MCB, Context); 149296417Sdim // If compounding and duplexing didn't reduce the size below 150296417Sdim // 4 or less we have a packet that is too big. 151296417Sdim if (HexagonMCInstrInfo::bundleSize(MCB) > HEXAGON_PACKET_SIZE) 152296417Sdim return false; 153321369Sdim // Check the bundle for errors. 154321369Sdim CheckOk = Check ? Check->check(true) : true; 155321369Sdim if (!CheckOk) 156321369Sdim return false; 157321369Sdim HexagonMCShuffle(Context, true, MCII, STI, MCB); 158296417Sdim return true; 159296417Sdim} 160296417Sdim 161296417Sdimvoid HexagonMCInstrInfo::clampExtended(MCInstrInfo const &MCII, 162296417Sdim MCContext &Context, MCInst &MCI) { 163284734Sdim assert(HexagonMCInstrInfo::isExtendable(MCII, MCI) || 164284734Sdim HexagonMCInstrInfo::isExtended(MCII, MCI)); 165284734Sdim MCOperand &exOp = 166284734Sdim MCI.getOperand(HexagonMCInstrInfo::getExtendableOp(MCII, MCI)); 167284734Sdim // If the extended value is a constant, then use it for the extended and 168284734Sdim // for the extender instructions, masking off the lower 6 bits and 169284734Sdim // including the assumed bits. 170296417Sdim int64_t Value; 171296417Sdim if (exOp.getExpr()->evaluateAsAbsolute(Value)) { 172284734Sdim unsigned Shift = HexagonMCInstrInfo::getExtentAlignment(MCII, MCI); 173309124Sdim exOp.setExpr(HexagonMCExpr::create( 174309124Sdim MCConstantExpr::create((Value & 0x3f) << Shift, Context), Context)); 175284734Sdim } 176284734Sdim} 177284734Sdim 178296417SdimMCInst HexagonMCInstrInfo::deriveExtender(MCInstrInfo const &MCII, 179296417Sdim MCInst const &Inst, 180296417Sdim MCOperand const &MO) { 181296417Sdim assert(HexagonMCInstrInfo::isExtendable(MCII, Inst) || 182296417Sdim HexagonMCInstrInfo::isExtended(MCII, Inst)); 183296417Sdim 184296417Sdim MCInst XMI; 185321369Sdim XMI.setOpcode(Hexagon::A4_ext); 186296417Sdim if (MO.isImm()) 187296417Sdim XMI.addOperand(MCOperand::createImm(MO.getImm() & (~0x3f))); 188296417Sdim else if (MO.isExpr()) 189296417Sdim XMI.addOperand(MCOperand::createExpr(MO.getExpr())); 190296417Sdim else 191296417Sdim llvm_unreachable("invalid extendable operand"); 192296417Sdim return XMI; 193296417Sdim} 194296417Sdim 195321369SdimMCInst *HexagonMCInstrInfo::deriveDuplex(MCContext &Context, unsigned iClass, 196321369Sdim MCInst const &inst0, 197321369Sdim MCInst const &inst1) { 198321369Sdim assert((iClass <= 0xf) && "iClass must have range of 0 to 0xf"); 199321369Sdim MCInst *duplexInst = new (Context) MCInst; 200321369Sdim duplexInst->setOpcode(Hexagon::DuplexIClass0 + iClass); 201321369Sdim 202321369Sdim MCInst *SubInst0 = new (Context) MCInst(deriveSubInst(inst0)); 203321369Sdim MCInst *SubInst1 = new (Context) MCInst(deriveSubInst(inst1)); 204321369Sdim duplexInst->addOperand(MCOperand::createInst(SubInst0)); 205321369Sdim duplexInst->addOperand(MCOperand::createInst(SubInst1)); 206321369Sdim return duplexInst; 207321369Sdim} 208321369Sdim 209284236SdimMCInst const *HexagonMCInstrInfo::extenderForIndex(MCInst const &MCB, 210284236Sdim size_t Index) { 211284236Sdim assert(Index <= bundleSize(MCB)); 212284236Sdim if (Index == 0) 213284236Sdim return nullptr; 214284236Sdim MCInst const *Inst = 215284236Sdim MCB.getOperand(Index + bundleInstructionsOffset - 1).getInst(); 216284236Sdim if (isImmext(*Inst)) 217284236Sdim return Inst; 218284236Sdim return nullptr; 219284236Sdim} 220284236Sdim 221296417Sdimvoid HexagonMCInstrInfo::extendIfNeeded(MCContext &Context, 222296417Sdim MCInstrInfo const &MCII, MCInst &MCB, 223309124Sdim MCInst const &MCI) { 224309124Sdim if (isConstExtended(MCII, MCI)) 225296417Sdim addConstExtender(Context, MCII, MCB, MCI); 226296417Sdim} 227296417Sdim 228327952Sdimunsigned HexagonMCInstrInfo::getMemAccessSize(MCInstrInfo const &MCII, 229327952Sdim MCInst const &MCI) { 230327952Sdim uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 231327952Sdim unsigned S = (F >> HexagonII::MemAccessSizePos) & HexagonII::MemAccesSizeMask; 232327952Sdim return HexagonII::getMemAccessSizeInBytes(HexagonII::MemAccessSize(S)); 233327952Sdim} 234327952Sdim 235327952Sdimunsigned HexagonMCInstrInfo::getAddrMode(MCInstrInfo const &MCII, 236327952Sdim MCInst const &MCI) { 237283625Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 238327952Sdim return static_cast<unsigned>((F >> HexagonII::AddrModePos) & 239327952Sdim HexagonII::AddrModeMask); 240283625Sdim} 241283625Sdim 242283625SdimMCInstrDesc const &HexagonMCInstrInfo::getDesc(MCInstrInfo const &MCII, 243283625Sdim MCInst const &MCI) { 244321369Sdim return MCII.get(MCI.getOpcode()); 245283625Sdim} 246283625Sdim 247309124Sdimunsigned HexagonMCInstrInfo::getDuplexRegisterNumbering(unsigned Reg) { 248309124Sdim using namespace Hexagon; 249327952Sdim 250309124Sdim switch (Reg) { 251309124Sdim default: 252309124Sdim llvm_unreachable("unknown duplex register"); 253309124Sdim // Rs Rss 254309124Sdim case R0: 255309124Sdim case D0: 256309124Sdim return 0; 257309124Sdim case R1: 258309124Sdim case D1: 259309124Sdim return 1; 260309124Sdim case R2: 261309124Sdim case D2: 262309124Sdim return 2; 263309124Sdim case R3: 264309124Sdim case D3: 265309124Sdim return 3; 266309124Sdim case R4: 267309124Sdim case D8: 268309124Sdim return 4; 269309124Sdim case R5: 270309124Sdim case D9: 271309124Sdim return 5; 272309124Sdim case R6: 273309124Sdim case D10: 274309124Sdim return 6; 275309124Sdim case R7: 276309124Sdim case D11: 277309124Sdim return 7; 278309124Sdim case R16: 279309124Sdim return 8; 280309124Sdim case R17: 281309124Sdim return 9; 282309124Sdim case R18: 283309124Sdim return 10; 284309124Sdim case R19: 285309124Sdim return 11; 286309124Sdim case R20: 287309124Sdim return 12; 288309124Sdim case R21: 289309124Sdim return 13; 290309124Sdim case R22: 291309124Sdim return 14; 292309124Sdim case R23: 293309124Sdim return 15; 294309124Sdim } 295309124Sdim} 296309124Sdim 297309124SdimMCExpr const &HexagonMCInstrInfo::getExpr(MCExpr const &Expr) { 298309124Sdim const auto &HExpr = cast<HexagonMCExpr>(Expr); 299309124Sdim assert(HExpr.getExpr()); 300309124Sdim return *HExpr.getExpr(); 301309124Sdim} 302309124Sdim 303284236Sdimunsigned short HexagonMCInstrInfo::getExtendableOp(MCInstrInfo const &MCII, 304284236Sdim MCInst const &MCI) { 305284236Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 306284236Sdim return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask); 307284236Sdim} 308284236Sdim 309284236SdimMCOperand const & 310284236SdimHexagonMCInstrInfo::getExtendableOperand(MCInstrInfo const &MCII, 311284236Sdim MCInst const &MCI) { 312284236Sdim unsigned O = HexagonMCInstrInfo::getExtendableOp(MCII, MCI); 313284236Sdim MCOperand const &MO = MCI.getOperand(O); 314284236Sdim 315284236Sdim assert((HexagonMCInstrInfo::isExtendable(MCII, MCI) || 316284236Sdim HexagonMCInstrInfo::isExtended(MCII, MCI)) && 317284236Sdim (MO.isImm() || MO.isExpr())); 318284236Sdim return (MO); 319284236Sdim} 320284236Sdim 321283625Sdimunsigned HexagonMCInstrInfo::getExtentAlignment(MCInstrInfo const &MCII, 322283625Sdim MCInst const &MCI) { 323283625Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 324283625Sdim return ((F >> HexagonII::ExtentAlignPos) & HexagonII::ExtentAlignMask); 325283625Sdim} 326283625Sdim 327283625Sdimunsigned HexagonMCInstrInfo::getExtentBits(MCInstrInfo const &MCII, 328283625Sdim MCInst const &MCI) { 329283625Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 330283625Sdim return ((F >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask); 331283625Sdim} 332283625Sdim 333321369Sdim/// Return the maximum value of an extendable operand. 334283625Sdimint HexagonMCInstrInfo::getMaxValue(MCInstrInfo const &MCII, 335283625Sdim MCInst const &MCI) { 336321369Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 337321369Sdim bool S = (F >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask; 338283625Sdim 339321369Sdim assert(HexagonMCInstrInfo::isExtendable(MCII, MCI) || 340321369Sdim HexagonMCInstrInfo::isExtended(MCII, MCI)); 341321369Sdim 342321369Sdim if (S) // if value is signed 343321369Sdim return (1 << (HexagonMCInstrInfo::getExtentBits(MCII, MCI) - 1)) - 1; 344321369Sdim return (1 << HexagonMCInstrInfo::getExtentBits(MCII, MCI)) - 1; 345283625Sdim} 346283625Sdim 347321369Sdim/// Return the minimum value of an extendable operand. 348283625Sdimint HexagonMCInstrInfo::getMinValue(MCInstrInfo const &MCII, 349283625Sdim MCInst const &MCI) { 350321369Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 351321369Sdim bool S = (F >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask; 352283625Sdim 353321369Sdim assert(HexagonMCInstrInfo::isExtendable(MCII, MCI) || 354321369Sdim HexagonMCInstrInfo::isExtended(MCII, MCI)); 355321369Sdim 356321369Sdim if (S) // if value is signed 357321369Sdim return -(1 << (HexagonMCInstrInfo::getExtentBits(MCII, MCI) - 1)); 358321369Sdim return 0; 359283625Sdim} 360283625Sdim 361314564SdimStringRef HexagonMCInstrInfo::getName(MCInstrInfo const &MCII, 362321369Sdim MCInst const &MCI) { 363283625Sdim return MCII.getName(MCI.getOpcode()); 364283625Sdim} 365283625Sdim 366284236Sdimunsigned short HexagonMCInstrInfo::getNewValueOp(MCInstrInfo const &MCII, 367283625Sdim MCInst const &MCI) { 368284236Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 369284236Sdim return ((F >> HexagonII::NewValueOpPos) & HexagonII::NewValueOpMask); 370284236Sdim} 371284236Sdim 372284236SdimMCOperand const &HexagonMCInstrInfo::getNewValueOperand(MCInstrInfo const &MCII, 373284236Sdim MCInst const &MCI) { 374327952Sdim if (HexagonMCInstrInfo::hasTmpDst(MCII, MCI)) { 375327952Sdim // VTMP doesn't actually exist in the encodings for these 184 376327952Sdim // 3 instructions so go ahead and create it here. 377327952Sdim static MCOperand MCO = MCOperand::createReg(Hexagon::VTMP); 378327952Sdim return (MCO); 379327952Sdim } else { 380327952Sdim unsigned O = HexagonMCInstrInfo::getNewValueOp(MCII, MCI); 381327952Sdim MCOperand const &MCO = MCI.getOperand(O); 382283625Sdim 383327952Sdim assert((HexagonMCInstrInfo::isNewValue(MCII, MCI) || 384327952Sdim HexagonMCInstrInfo::hasNewValue(MCII, MCI)) && 385327952Sdim MCO.isReg()); 386327952Sdim return (MCO); 387327952Sdim } 388283625Sdim} 389283625Sdim 390296417Sdim/// Return the new value or the newly produced value. 391296417Sdimunsigned short HexagonMCInstrInfo::getNewValueOp2(MCInstrInfo const &MCII, 392296417Sdim MCInst const &MCI) { 393296417Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 394296417Sdim return ((F >> HexagonII::NewValueOpPos2) & HexagonII::NewValueOpMask2); 395296417Sdim} 396296417Sdim 397296417SdimMCOperand const & 398296417SdimHexagonMCInstrInfo::getNewValueOperand2(MCInstrInfo const &MCII, 399296417Sdim MCInst const &MCI) { 400296417Sdim unsigned O = HexagonMCInstrInfo::getNewValueOp2(MCII, MCI); 401296417Sdim MCOperand const &MCO = MCI.getOperand(O); 402296417Sdim 403296417Sdim assert((HexagonMCInstrInfo::isNewValue(MCII, MCI) || 404296417Sdim HexagonMCInstrInfo::hasNewValue2(MCII, MCI)) && 405296417Sdim MCO.isReg()); 406296417Sdim return (MCO); 407296417Sdim} 408296417Sdim 409321369Sdim/// Return the Hexagon ISA class for the insn. 410283625Sdimunsigned HexagonMCInstrInfo::getType(MCInstrInfo const &MCII, 411283625Sdim MCInst const &MCI) { 412321369Sdim const uint64_t F = MCII.get(MCI.getOpcode()).TSFlags; 413283625Sdim return ((F >> HexagonII::TypePos) & HexagonII::TypeMask); 414283625Sdim} 415283625Sdim 416321369Sdim/// Return the slots this instruction can execute out of 417284236Sdimunsigned HexagonMCInstrInfo::getUnits(MCInstrInfo const &MCII, 418284236Sdim MCSubtargetInfo const &STI, 419284236Sdim MCInst const &MCI) { 420284236Sdim const InstrItinerary *II = STI.getSchedModel().InstrItineraries; 421284236Sdim int SchedClass = HexagonMCInstrInfo::getDesc(MCII, MCI).getSchedClass(); 422284236Sdim return ((II[SchedClass].FirstStage + HexagonStages)->getUnits()); 423284236Sdim} 424284236Sdim 425321369Sdim/// Return the slots this instruction consumes in addition to 426321369Sdim/// the slot(s) it can execute out of 427321369Sdim 428321369Sdimunsigned HexagonMCInstrInfo::getOtherReservedSlots(MCInstrInfo const &MCII, 429321369Sdim MCSubtargetInfo const &STI, 430321369Sdim MCInst const &MCI) { 431321369Sdim const InstrItinerary *II = STI.getSchedModel().InstrItineraries; 432321369Sdim int SchedClass = HexagonMCInstrInfo::getDesc(MCII, MCI).getSchedClass(); 433321369Sdim unsigned Slots = 0; 434321369Sdim 435321369Sdim // FirstStage are slots that this instruction can execute in. 436321369Sdim // FirstStage+1 are slots that are also consumed by this instruction. 437321369Sdim // For example: vmemu can only execute in slot 0 but also consumes slot 1. 438321369Sdim for (unsigned Stage = II[SchedClass].FirstStage + 1; 439321369Sdim Stage < II[SchedClass].LastStage; ++Stage) { 440321369Sdim unsigned Units = (Stage + HexagonStages)->getUnits(); 441321369Sdim if (Units > HexagonGetLastSlot()) 442321369Sdim break; 443321369Sdim // fyi: getUnits() will return 0x1, 0x2, 0x4 or 0x8 444321369Sdim Slots |= Units; 445321369Sdim } 446321369Sdim 447321369Sdim // if 0 is returned, then no additional slots are consumed by this inst. 448321369Sdim return Slots; 449321369Sdim} 450321369Sdim 451321369Sdimbool HexagonMCInstrInfo::hasDuplex(MCInstrInfo const &MCII, MCInst const &MCI) { 452284236Sdim if (!HexagonMCInstrInfo::isBundle(MCI)) 453284236Sdim return false; 454284236Sdim 455327952Sdim for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCI)) { 456327952Sdim if (HexagonMCInstrInfo::isDuplex(MCII, *I.getInst())) 457284236Sdim return true; 458284236Sdim } 459284236Sdim 460284236Sdim return false; 461284236Sdim} 462284236Sdim 463284236Sdimbool HexagonMCInstrInfo::hasExtenderForIndex(MCInst const &MCB, size_t Index) { 464284236Sdim return extenderForIndex(MCB, Index) != nullptr; 465284236Sdim} 466284236Sdim 467327952Sdimbool HexagonMCInstrInfo::hasImmExt(MCInst const &MCI) { 468321369Sdim if (!HexagonMCInstrInfo::isBundle(MCI)) 469321369Sdim return false; 470321369Sdim 471321369Sdim for (const auto &I : HexagonMCInstrInfo::bundleInstructions(MCI)) { 472321369Sdim if (isImmext(*I.getInst())) 473321369Sdim return true; 474321369Sdim } 475321369Sdim 476321369Sdim return false; 477321369Sdim} 478321369Sdim 479321369Sdim/// Return whether the insn produces a value. 480283625Sdimbool HexagonMCInstrInfo::hasNewValue(MCInstrInfo const &MCII, 481283625Sdim MCInst const &MCI) { 482283625Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 483283625Sdim return ((F >> HexagonII::hasNewValuePos) & HexagonII::hasNewValueMask); 484283625Sdim} 485283625Sdim 486296417Sdim/// Return whether the insn produces a second value. 487296417Sdimbool HexagonMCInstrInfo::hasNewValue2(MCInstrInfo const &MCII, 488296417Sdim MCInst const &MCI) { 489296417Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 490296417Sdim return ((F >> HexagonII::hasNewValuePos2) & HexagonII::hasNewValueMask2); 491296417Sdim} 492296417Sdim 493284236SdimMCInst const &HexagonMCInstrInfo::instruction(MCInst const &MCB, size_t Index) { 494284236Sdim assert(isBundle(MCB)); 495284236Sdim assert(Index < HEXAGON_PACKET_SIZE); 496284236Sdim return *MCB.getOperand(bundleInstructionsOffset + Index).getInst(); 497284236Sdim} 498284236Sdim 499321369Sdim/// Return where the instruction is an accumulator. 500321369Sdimbool HexagonMCInstrInfo::isAccumulator(MCInstrInfo const &MCII, 501321369Sdim MCInst const &MCI) { 502321369Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 503321369Sdim return ((F >> HexagonII::AccumulatorPos) & HexagonII::AccumulatorMask); 504321369Sdim} 505321369Sdim 506284236Sdimbool HexagonMCInstrInfo::isBundle(MCInst const &MCI) { 507284236Sdim auto Result = Hexagon::BUNDLE == MCI.getOpcode(); 508284236Sdim assert(!Result || (MCI.size() > 0 && MCI.getOperand(0).isImm())); 509284236Sdim return Result; 510284236Sdim} 511284236Sdim 512283625Sdimbool HexagonMCInstrInfo::isConstExtended(MCInstrInfo const &MCII, 513283625Sdim MCInst const &MCI) { 514283625Sdim if (HexagonMCInstrInfo::isExtended(MCII, MCI)) 515283625Sdim return true; 516309124Sdim if (!HexagonMCInstrInfo::isExtendable(MCII, MCI)) 517309124Sdim return false; 518309124Sdim MCOperand const &MO = HexagonMCInstrInfo::getExtendableOperand(MCII, MCI); 519309124Sdim if (isa<HexagonMCExpr>(MO.getExpr()) && 520309124Sdim HexagonMCInstrInfo::mustExtend(*MO.getExpr())) 521309124Sdim return true; 522296417Sdim // Branch insns are handled as necessary by relaxation. 523296417Sdim if ((HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeJ) || 524321369Sdim (HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeCJ && 525296417Sdim HexagonMCInstrInfo::getDesc(MCII, MCI).isBranch()) || 526321369Sdim (HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeNCJ && 527296417Sdim HexagonMCInstrInfo::getDesc(MCII, MCI).isBranch())) 528283625Sdim return false; 529296417Sdim // Otherwise loop instructions and other CR insts are handled by relaxation 530296417Sdim else if ((HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeCR) && 531296417Sdim (MCI.getOpcode() != Hexagon::C4_addipc)) 532296417Sdim return false; 533283625Sdim 534296417Sdim assert(!MO.isImm()); 535309124Sdim if (isa<HexagonMCExpr>(MO.getExpr()) && 536309124Sdim HexagonMCInstrInfo::mustNotExtend(*MO.getExpr())) 537309124Sdim return false; 538296417Sdim int64_t Value; 539296417Sdim if (!MO.getExpr()->evaluateAsAbsolute(Value)) 540283625Sdim return true; 541296417Sdim int MinValue = HexagonMCInstrInfo::getMinValue(MCII, MCI); 542296417Sdim int MaxValue = HexagonMCInstrInfo::getMaxValue(MCII, MCI); 543296417Sdim return (MinValue > Value || Value > MaxValue); 544283625Sdim} 545283625Sdim 546321369Sdimbool HexagonMCInstrInfo::isCanon(MCInstrInfo const &MCII, MCInst const &MCI) { 547321369Sdim return !HexagonMCInstrInfo::getDesc(MCII, MCI).isPseudo() && 548321369Sdim !HexagonMCInstrInfo::isPrefix(MCII, MCI); 549321369Sdim} 550321369Sdim 551321369Sdimbool HexagonMCInstrInfo::isCofMax1(MCInstrInfo const &MCII, MCInst const &MCI) { 552321369Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 553321369Sdim return ((F >> HexagonII::CofMax1Pos) & HexagonII::CofMax1Mask); 554321369Sdim} 555321369Sdim 556327952Sdimbool HexagonMCInstrInfo::isCofRelax1(MCInstrInfo const &MCII, 557327952Sdim MCInst const &MCI) { 558327952Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 559327952Sdim return ((F >> HexagonII::CofRelax1Pos) & HexagonII::CofRelax1Mask); 560327952Sdim} 561327952Sdim 562327952Sdimbool HexagonMCInstrInfo::isCofRelax2(MCInstrInfo const &MCII, 563327952Sdim MCInst const &MCI) { 564327952Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 565327952Sdim return ((F >> HexagonII::CofRelax2Pos) & HexagonII::CofRelax2Mask); 566327952Sdim} 567327952Sdim 568321369Sdimbool HexagonMCInstrInfo::isCompound(MCInstrInfo const &MCII, 569321369Sdim MCInst const &MCI) { 570321369Sdim return (getType(MCII, MCI) == HexagonII::TypeCJ); 571321369Sdim} 572321369Sdim 573321369Sdimbool HexagonMCInstrInfo::isCVINew(MCInstrInfo const &MCII, MCInst const &MCI) { 574321369Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 575321369Sdim return ((F >> HexagonII::CVINewPos) & HexagonII::CVINewMask); 576321369Sdim} 577321369Sdim 578321369Sdimbool HexagonMCInstrInfo::isDblRegForSubInst(unsigned Reg) { 579321369Sdim return ((Reg >= Hexagon::D0 && Reg <= Hexagon::D3) || 580321369Sdim (Reg >= Hexagon::D8 && Reg <= Hexagon::D11)); 581321369Sdim} 582321369Sdim 583321369Sdimbool HexagonMCInstrInfo::isDuplex(MCInstrInfo const &MCII, MCInst const &MCI) { 584321369Sdim return HexagonII::TypeDUPLEX == HexagonMCInstrInfo::getType(MCII, MCI); 585321369Sdim} 586321369Sdim 587283625Sdimbool HexagonMCInstrInfo::isExtendable(MCInstrInfo const &MCII, 588283625Sdim MCInst const &MCI) { 589283625Sdim uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 590283625Sdim return (F >> HexagonII::ExtendablePos) & HexagonII::ExtendableMask; 591283625Sdim} 592283625Sdim 593283625Sdimbool HexagonMCInstrInfo::isExtended(MCInstrInfo const &MCII, 594283625Sdim MCInst const &MCI) { 595283625Sdim uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 596283625Sdim return (F >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask; 597283625Sdim} 598283625Sdim 599284236Sdimbool HexagonMCInstrInfo::isFloat(MCInstrInfo const &MCII, MCInst const &MCI) { 600284236Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 601284236Sdim return ((F >> HexagonII::FPPos) & HexagonII::FPMask); 602284236Sdim} 603284236Sdim 604327952Sdimbool HexagonMCInstrInfo::isHVX(MCInstrInfo const &MCII, MCInst const &MCI) { 605327952Sdim const uint64_t V = getType(MCII, MCI); 606327952Sdim return HexagonII::TypeCVI_FIRST <= V && V <= HexagonII::TypeCVI_LAST; 607327952Sdim} 608327952Sdim 609284236Sdimbool HexagonMCInstrInfo::isImmext(MCInst const &MCI) { 610321369Sdim return MCI.getOpcode() == Hexagon::A4_ext; 611284236Sdim} 612284236Sdim 613284236Sdimbool HexagonMCInstrInfo::isInnerLoop(MCInst const &MCI) { 614284236Sdim assert(isBundle(MCI)); 615284236Sdim int64_t Flags = MCI.getOperand(0).getImm(); 616284236Sdim return (Flags & innerLoopMask) != 0; 617284236Sdim} 618284236Sdim 619284236Sdimbool HexagonMCInstrInfo::isIntReg(unsigned Reg) { 620284236Sdim return (Reg >= Hexagon::R0 && Reg <= Hexagon::R31); 621284236Sdim} 622284236Sdim 623284236Sdimbool HexagonMCInstrInfo::isIntRegForSubInst(unsigned Reg) { 624284236Sdim return ((Reg >= Hexagon::R0 && Reg <= Hexagon::R7) || 625284236Sdim (Reg >= Hexagon::R16 && Reg <= Hexagon::R23)); 626284236Sdim} 627284236Sdim 628321369Sdim/// Return whether the insn expects newly produced value. 629283625Sdimbool HexagonMCInstrInfo::isNewValue(MCInstrInfo const &MCII, 630283625Sdim MCInst const &MCI) { 631283625Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 632283625Sdim return ((F >> HexagonII::NewValuePos) & HexagonII::NewValueMask); 633283625Sdim} 634283625Sdim 635321369Sdim/// Return whether the operand is extendable. 636321369Sdimbool HexagonMCInstrInfo::isOpExtendable(MCInstrInfo const &MCII, 637321369Sdim MCInst const &MCI, unsigned short O) { 638321369Sdim return (O == HexagonMCInstrInfo::getExtendableOp(MCII, MCI)); 639283625Sdim} 640283625Sdim 641284236Sdimbool HexagonMCInstrInfo::isOuterLoop(MCInst const &MCI) { 642284236Sdim assert(isBundle(MCI)); 643284236Sdim int64_t Flags = MCI.getOperand(0).getImm(); 644284236Sdim return (Flags & outerLoopMask) != 0; 645283625Sdim} 646283625Sdim 647284236Sdimbool HexagonMCInstrInfo::isPredicated(MCInstrInfo const &MCII, 648284236Sdim MCInst const &MCI) { 649284236Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 650284236Sdim return ((F >> HexagonII::PredicatedPos) & HexagonII::PredicatedMask); 651283625Sdim} 652283625Sdim 653321369Sdimbool HexagonMCInstrInfo::isPrefix(MCInstrInfo const &MCII, MCInst const &MCI) { 654321369Sdim return HexagonII::TypeEXTENDER == HexagonMCInstrInfo::getType(MCII, MCI); 655321369Sdim} 656321369Sdim 657296417Sdimbool HexagonMCInstrInfo::isPredicateLate(MCInstrInfo const &MCII, 658296417Sdim MCInst const &MCI) { 659296417Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 660296417Sdim return (F >> HexagonII::PredicateLatePos & HexagonII::PredicateLateMask); 661296417Sdim} 662296417Sdim 663296417Sdim/// Return whether the insn is newly predicated. 664296417Sdimbool HexagonMCInstrInfo::isPredicatedNew(MCInstrInfo const &MCII, 665296417Sdim MCInst const &MCI) { 666296417Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 667296417Sdim return ((F >> HexagonII::PredicatedNewPos) & HexagonII::PredicatedNewMask); 668296417Sdim} 669296417Sdim 670284236Sdimbool HexagonMCInstrInfo::isPredicatedTrue(MCInstrInfo const &MCII, 671284236Sdim MCInst const &MCI) { 672284236Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 673284236Sdim return ( 674284236Sdim !((F >> HexagonII::PredicatedFalsePos) & HexagonII::PredicatedFalseMask)); 675284236Sdim} 676284236Sdim 677284236Sdimbool HexagonMCInstrInfo::isPredReg(unsigned Reg) { 678284236Sdim return (Reg >= Hexagon::P0 && Reg <= Hexagon::P3_0); 679284236Sdim} 680284236Sdim 681321369Sdim/// Return whether the insn can be packaged only with A and X-type insns. 682321369Sdimbool HexagonMCInstrInfo::isSoloAX(MCInstrInfo const &MCII, MCInst const &MCI) { 683321369Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 684321369Sdim return ((F >> HexagonII::SoloAXPos) & HexagonII::SoloAXMask); 685283625Sdim} 686283625Sdim 687321369Sdim/// Return whether the insn can be packaged only with an A-type insn in slot #1. 688327952Sdimbool HexagonMCInstrInfo::isRestrictSlot1AOK(MCInstrInfo const &MCII, 689327952Sdim MCInst const &MCI) { 690321369Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 691327952Sdim return ((F >> HexagonII::RestrictSlot1AOKPos) & 692327952Sdim HexagonII::RestrictSlot1AOKMask); 693321369Sdim} 694321369Sdim 695327952Sdimbool HexagonMCInstrInfo::isRestrictNoSlot1Store(MCInstrInfo const &MCII, 696327952Sdim MCInst const &MCI) { 697327952Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 698327952Sdim return ((F >> HexagonII::RestrictNoSlot1StorePos) & 699327952Sdim HexagonII::RestrictNoSlot1StoreMask); 700327952Sdim} 701327952Sdim 702321369Sdim/// Return whether the insn is solo, i.e., cannot be in a packet. 703283625Sdimbool HexagonMCInstrInfo::isSolo(MCInstrInfo const &MCII, MCInst const &MCI) { 704321369Sdim const uint64_t F = MCII.get(MCI.getOpcode()).TSFlags; 705283625Sdim return ((F >> HexagonII::SoloPos) & HexagonII::SoloMask); 706283625Sdim} 707283625Sdim 708296417Sdimbool HexagonMCInstrInfo::isMemReorderDisabled(MCInst const &MCI) { 709296417Sdim assert(isBundle(MCI)); 710296417Sdim auto Flags = MCI.getOperand(0).getImm(); 711296417Sdim return (Flags & memReorderDisabledMask) != 0; 712296417Sdim} 713296417Sdim 714309124Sdimbool HexagonMCInstrInfo::isSubInstruction(MCInst const &MCI) { 715309124Sdim switch (MCI.getOpcode()) { 716309124Sdim default: 717309124Sdim return false; 718314564Sdim case Hexagon::SA1_addi: 719314564Sdim case Hexagon::SA1_addrx: 720314564Sdim case Hexagon::SA1_addsp: 721314564Sdim case Hexagon::SA1_and1: 722314564Sdim case Hexagon::SA1_clrf: 723314564Sdim case Hexagon::SA1_clrfnew: 724314564Sdim case Hexagon::SA1_clrt: 725314564Sdim case Hexagon::SA1_clrtnew: 726314564Sdim case Hexagon::SA1_cmpeqi: 727314564Sdim case Hexagon::SA1_combine0i: 728314564Sdim case Hexagon::SA1_combine1i: 729314564Sdim case Hexagon::SA1_combine2i: 730314564Sdim case Hexagon::SA1_combine3i: 731314564Sdim case Hexagon::SA1_combinerz: 732314564Sdim case Hexagon::SA1_combinezr: 733314564Sdim case Hexagon::SA1_dec: 734314564Sdim case Hexagon::SA1_inc: 735314564Sdim case Hexagon::SA1_seti: 736314564Sdim case Hexagon::SA1_setin1: 737314564Sdim case Hexagon::SA1_sxtb: 738314564Sdim case Hexagon::SA1_sxth: 739314564Sdim case Hexagon::SA1_tfr: 740314564Sdim case Hexagon::SA1_zxtb: 741314564Sdim case Hexagon::SA1_zxth: 742314564Sdim case Hexagon::SL1_loadri_io: 743314564Sdim case Hexagon::SL1_loadrub_io: 744314564Sdim case Hexagon::SL2_deallocframe: 745314564Sdim case Hexagon::SL2_jumpr31: 746314564Sdim case Hexagon::SL2_jumpr31_f: 747314564Sdim case Hexagon::SL2_jumpr31_fnew: 748314564Sdim case Hexagon::SL2_jumpr31_t: 749314564Sdim case Hexagon::SL2_jumpr31_tnew: 750314564Sdim case Hexagon::SL2_loadrb_io: 751314564Sdim case Hexagon::SL2_loadrd_sp: 752314564Sdim case Hexagon::SL2_loadrh_io: 753314564Sdim case Hexagon::SL2_loadri_sp: 754314564Sdim case Hexagon::SL2_loadruh_io: 755314564Sdim case Hexagon::SL2_return: 756314564Sdim case Hexagon::SL2_return_f: 757314564Sdim case Hexagon::SL2_return_fnew: 758314564Sdim case Hexagon::SL2_return_t: 759314564Sdim case Hexagon::SL2_return_tnew: 760314564Sdim case Hexagon::SS1_storeb_io: 761314564Sdim case Hexagon::SS1_storew_io: 762314564Sdim case Hexagon::SS2_allocframe: 763314564Sdim case Hexagon::SS2_storebi0: 764314564Sdim case Hexagon::SS2_storebi1: 765314564Sdim case Hexagon::SS2_stored_sp: 766314564Sdim case Hexagon::SS2_storeh_io: 767314564Sdim case Hexagon::SS2_storew_sp: 768314564Sdim case Hexagon::SS2_storewi0: 769314564Sdim case Hexagon::SS2_storewi1: 770309124Sdim return true; 771309124Sdim } 772309124Sdim} 773309124Sdim 774296417Sdimbool HexagonMCInstrInfo::isVector(MCInstrInfo const &MCII, MCInst const &MCI) { 775296417Sdim if ((getType(MCII, MCI) <= HexagonII::TypeCVI_LAST) && 776296417Sdim (getType(MCII, MCI) >= HexagonII::TypeCVI_FIRST)) 777296417Sdim return true; 778296417Sdim return false; 779296417Sdim} 780296417Sdim 781296417Sdimint64_t HexagonMCInstrInfo::minConstant(MCInst const &MCI, size_t Index) { 782296417Sdim auto Sentinal = static_cast<int64_t>(std::numeric_limits<uint32_t>::max()) 783296417Sdim << 8; 784296417Sdim if (MCI.size() <= Index) 785296417Sdim return Sentinal; 786296417Sdim MCOperand const &MCO = MCI.getOperand(Index); 787296417Sdim if (!MCO.isExpr()) 788296417Sdim return Sentinal; 789296417Sdim int64_t Value; 790296417Sdim if (!MCO.getExpr()->evaluateAsAbsolute(Value)) 791296417Sdim return Sentinal; 792296417Sdim return Value; 793296417Sdim} 794296417Sdim 795309124Sdimvoid HexagonMCInstrInfo::setMustExtend(MCExpr const &Expr, bool Val) { 796309124Sdim HexagonMCExpr &HExpr = const_cast<HexagonMCExpr &>(cast<HexagonMCExpr>(Expr)); 797309124Sdim HExpr.setMustExtend(Val); 798309124Sdim} 799309124Sdim 800309124Sdimbool HexagonMCInstrInfo::mustExtend(MCExpr const &Expr) { 801309124Sdim HexagonMCExpr const &HExpr = cast<HexagonMCExpr>(Expr); 802309124Sdim return HExpr.mustExtend(); 803309124Sdim} 804309124Sdimvoid HexagonMCInstrInfo::setMustNotExtend(MCExpr const &Expr, bool Val) { 805321369Sdim HexagonMCExpr &HExpr = const_cast<HexagonMCExpr &>(cast<HexagonMCExpr>(Expr)); 806309124Sdim HExpr.setMustNotExtend(Val); 807309124Sdim} 808309124Sdimbool HexagonMCInstrInfo::mustNotExtend(MCExpr const &Expr) { 809309124Sdim HexagonMCExpr const &HExpr = cast<HexagonMCExpr>(Expr); 810309124Sdim return HExpr.mustNotExtend(); 811309124Sdim} 812321369Sdimvoid HexagonMCInstrInfo::setS27_2_reloc(MCExpr const &Expr, bool Val) { 813321369Sdim HexagonMCExpr &HExpr = 814327952Sdim const_cast<HexagonMCExpr &>(*cast<HexagonMCExpr>(&Expr)); 815321369Sdim HExpr.setS27_2_reloc(Val); 816321369Sdim} 817321369Sdimbool HexagonMCInstrInfo::s27_2_reloc(MCExpr const &Expr) { 818327952Sdim HexagonMCExpr const *HExpr = dyn_cast<HexagonMCExpr>(&Expr); 819321369Sdim if (!HExpr) 820321369Sdim return false; 821321369Sdim return HExpr->s27_2_reloc(); 822321369Sdim} 823309124Sdim 824321369Sdimvoid HexagonMCInstrInfo::padEndloop(MCInst &MCB, MCContext &Context) { 825284236Sdim MCInst Nop; 826284236Sdim Nop.setOpcode(Hexagon::A2_nop); 827284236Sdim assert(isBundle(MCB)); 828284236Sdim while ((HexagonMCInstrInfo::isInnerLoop(MCB) && 829284236Sdim (HexagonMCInstrInfo::bundleSize(MCB) < HEXAGON_PACKET_INNER_SIZE)) || 830284236Sdim ((HexagonMCInstrInfo::isOuterLoop(MCB) && 831284236Sdim (HexagonMCInstrInfo::bundleSize(MCB) < HEXAGON_PACKET_OUTER_SIZE)))) 832296417Sdim MCB.addOperand(MCOperand::createInst(new (Context) MCInst(Nop))); 833283625Sdim} 834283625Sdim 835327952SdimHexagonMCInstrInfo::PredicateInfo 836327952SdimHexagonMCInstrInfo::predicateInfo(MCInstrInfo const &MCII, MCInst const &MCI) { 837327952Sdim if (!isPredicated(MCII, MCI)) 838327952Sdim return {0, 0, false}; 839327952Sdim MCInstrDesc const &Desc = getDesc(MCII, MCI); 840327952Sdim for (auto I = Desc.getNumDefs(), N = Desc.getNumOperands(); I != N; ++I) 841327952Sdim if (Desc.OpInfo[I].RegClass == Hexagon::PredRegsRegClassID) 842327952Sdim return {MCI.getOperand(I).getReg(), I, isPredicatedTrue(MCII, MCI)}; 843327952Sdim return {0, 0, false}; 844327952Sdim} 845327952Sdim 846284236Sdimbool HexagonMCInstrInfo::prefersSlot3(MCInstrInfo const &MCII, 847284236Sdim MCInst const &MCI) { 848321369Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 849321369Sdim return (F >> HexagonII::PrefersSlot3Pos) & HexagonII::PrefersSlot3Mask; 850283625Sdim} 851284236Sdim 852327952Sdim/// return true if instruction has hasTmpDst attribute. 853327952Sdimbool HexagonMCInstrInfo::hasTmpDst(MCInstrInfo const &MCII, MCInst const &MCI) { 854327952Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 855327952Sdim return (F >> HexagonII::HasTmpDstPos) & HexagonII::HasTmpDstMask; 856327952Sdim} 857327952Sdim 858284236Sdimvoid HexagonMCInstrInfo::replaceDuplex(MCContext &Context, MCInst &MCB, 859284236Sdim DuplexCandidate Candidate) { 860284236Sdim assert(Candidate.packetIndexI < MCB.size()); 861284236Sdim assert(Candidate.packetIndexJ < MCB.size()); 862284236Sdim assert(isBundle(MCB)); 863284236Sdim MCInst *Duplex = 864284236Sdim deriveDuplex(Context, Candidate.iClass, 865284236Sdim *MCB.getOperand(Candidate.packetIndexJ).getInst(), 866284236Sdim *MCB.getOperand(Candidate.packetIndexI).getInst()); 867284236Sdim assert(Duplex != nullptr); 868284236Sdim MCB.getOperand(Candidate.packetIndexI).setInst(Duplex); 869284236Sdim MCB.erase(MCB.begin() + Candidate.packetIndexJ); 870283625Sdim} 871284236Sdim 872284236Sdimvoid HexagonMCInstrInfo::setInnerLoop(MCInst &MCI) { 873284236Sdim assert(isBundle(MCI)); 874284236Sdim MCOperand &Operand = MCI.getOperand(0); 875284236Sdim Operand.setImm(Operand.getImm() | innerLoopMask); 876284236Sdim} 877284236Sdim 878296417Sdimvoid HexagonMCInstrInfo::setMemReorderDisabled(MCInst &MCI) { 879296417Sdim assert(isBundle(MCI)); 880296417Sdim MCOperand &Operand = MCI.getOperand(0); 881296417Sdim Operand.setImm(Operand.getImm() | memReorderDisabledMask); 882296417Sdim assert(isMemReorderDisabled(MCI)); 883296417Sdim} 884296417Sdim 885284236Sdimvoid HexagonMCInstrInfo::setOuterLoop(MCInst &MCI) { 886284236Sdim assert(isBundle(MCI)); 887284236Sdim MCOperand &Operand = MCI.getOperand(0); 888284236Sdim Operand.setImm(Operand.getImm() | outerLoopMask); 889284236Sdim} 890309124Sdim 891309124Sdimunsigned HexagonMCInstrInfo::SubregisterBit(unsigned Consumer, 892309124Sdim unsigned Producer, 893309124Sdim unsigned Producer2) { 894309124Sdim // If we're a single vector consumer of a double producer, set subreg bit 895309124Sdim // based on if we're accessing the lower or upper register component 896309124Sdim if (Producer >= Hexagon::W0 && Producer <= Hexagon::W15) 897309124Sdim if (Consumer >= Hexagon::V0 && Consumer <= Hexagon::V31) 898309124Sdim return (Consumer - Hexagon::V0) & 0x1; 899327952Sdim if (Producer2 != Hexagon::NoRegister) 900327952Sdim return Consumer == Producer; 901309124Sdim return 0; 902285181Sdim} 903