HexagonMCInstrInfo.cpp revision 314564
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 14283625Sdim#include "HexagonMCInstrInfo.h" 15284236Sdim 16284236Sdim#include "Hexagon.h" 17283625Sdim#include "HexagonBaseInfo.h" 18296417Sdim#include "HexagonMCChecker.h" 19283625Sdim 20284236Sdim#include "llvm/MC/MCContext.h" 21296417Sdim#include "llvm/MC/MCExpr.h" 22284236Sdim#include "llvm/MC/MCInstrInfo.h" 23284236Sdim#include "llvm/MC/MCSubtargetInfo.h" 24284236Sdim 25283625Sdimnamespace llvm { 26296417Sdimvoid HexagonMCInstrInfo::addConstant(MCInst &MI, uint64_t Value, 27296417Sdim MCContext &Context) { 28296417Sdim MI.addOperand(MCOperand::createExpr(MCConstantExpr::create(Value, Context))); 29296417Sdim} 30296417Sdim 31296417Sdimvoid HexagonMCInstrInfo::addConstExtender(MCContext &Context, 32296417Sdim MCInstrInfo const &MCII, MCInst &MCB, 33296417Sdim MCInst const &MCI) { 34296417Sdim assert(HexagonMCInstrInfo::isBundle(MCB)); 35296417Sdim MCOperand const &exOp = 36296417Sdim MCI.getOperand(HexagonMCInstrInfo::getExtendableOp(MCII, MCI)); 37296417Sdim 38296417Sdim // Create the extender. 39296417Sdim MCInst *XMCI = 40296417Sdim new (Context) MCInst(HexagonMCInstrInfo::deriveExtender(MCII, MCI, exOp)); 41296417Sdim 42296417Sdim MCB.addOperand(MCOperand::createInst(XMCI)); 43296417Sdim} 44296417Sdim 45284236Sdimiterator_range<MCInst::const_iterator> 46284236SdimHexagonMCInstrInfo::bundleInstructions(MCInst const &MCI) { 47284236Sdim assert(isBundle(MCI)); 48296417Sdim return make_range(MCI.begin() + bundleInstructionsOffset, MCI.end()); 49283625Sdim} 50283625Sdim 51284236Sdimsize_t HexagonMCInstrInfo::bundleSize(MCInst const &MCI) { 52284236Sdim if (HexagonMCInstrInfo::isBundle(MCI)) 53284236Sdim return (MCI.size() - bundleInstructionsOffset); 54284236Sdim else 55284236Sdim return (1); 56284236Sdim} 57284236Sdim 58296417Sdimbool HexagonMCInstrInfo::canonicalizePacket(MCInstrInfo const &MCII, 59296417Sdim MCSubtargetInfo const &STI, 60296417Sdim MCContext &Context, MCInst &MCB, 61296417Sdim HexagonMCChecker *Check) { 62296417Sdim // Examine the packet and convert pairs of instructions to compound 63296417Sdim // instructions when possible. 64296417Sdim if (!HexagonDisableCompound) 65296417Sdim HexagonMCInstrInfo::tryCompound(MCII, Context, MCB); 66296417Sdim // Check the bundle for errors. 67296417Sdim bool CheckOk = Check ? Check->check() : true; 68296417Sdim if (!CheckOk) 69296417Sdim return false; 70296417Sdim HexagonMCShuffle(MCII, STI, MCB); 71296417Sdim // Examine the packet and convert pairs of instructions to duplex 72296417Sdim // instructions when possible. 73296417Sdim MCInst InstBundlePreDuplex = MCInst(MCB); 74296417Sdim if (!HexagonDisableDuplex) { 75296417Sdim SmallVector<DuplexCandidate, 8> possibleDuplexes; 76296417Sdim possibleDuplexes = HexagonMCInstrInfo::getDuplexPossibilties(MCII, MCB); 77296417Sdim HexagonMCShuffle(MCII, STI, Context, MCB, possibleDuplexes); 78296417Sdim } 79296417Sdim // Examines packet and pad the packet, if needed, when an 80296417Sdim // end-loop is in the bundle. 81296417Sdim HexagonMCInstrInfo::padEndloop(Context, MCB); 82296417Sdim // If compounding and duplexing didn't reduce the size below 83296417Sdim // 4 or less we have a packet that is too big. 84296417Sdim if (HexagonMCInstrInfo::bundleSize(MCB) > HEXAGON_PACKET_SIZE) 85296417Sdim return false; 86296417Sdim HexagonMCShuffle(MCII, STI, MCB); 87296417Sdim return true; 88296417Sdim} 89296417Sdim 90296417Sdimvoid HexagonMCInstrInfo::clampExtended(MCInstrInfo const &MCII, 91296417Sdim MCContext &Context, MCInst &MCI) { 92284734Sdim assert(HexagonMCInstrInfo::isExtendable(MCII, MCI) || 93284734Sdim HexagonMCInstrInfo::isExtended(MCII, MCI)); 94284734Sdim MCOperand &exOp = 95284734Sdim MCI.getOperand(HexagonMCInstrInfo::getExtendableOp(MCII, MCI)); 96284734Sdim // If the extended value is a constant, then use it for the extended and 97284734Sdim // for the extender instructions, masking off the lower 6 bits and 98284734Sdim // including the assumed bits. 99296417Sdim int64_t Value; 100296417Sdim if (exOp.getExpr()->evaluateAsAbsolute(Value)) { 101284734Sdim unsigned Shift = HexagonMCInstrInfo::getExtentAlignment(MCII, MCI); 102309124Sdim exOp.setExpr(HexagonMCExpr::create( 103309124Sdim MCConstantExpr::create((Value & 0x3f) << Shift, Context), Context)); 104284734Sdim } 105284734Sdim} 106284734Sdim 107296417SdimMCInst HexagonMCInstrInfo::createBundle() { 108296417Sdim MCInst Result; 109296417Sdim Result.setOpcode(Hexagon::BUNDLE); 110296417Sdim Result.addOperand(MCOperand::createImm(0)); 111296417Sdim return Result; 112296417Sdim} 113296417Sdim 114284236SdimMCInst *HexagonMCInstrInfo::deriveDuplex(MCContext &Context, unsigned iClass, 115284236Sdim MCInst const &inst0, 116284236Sdim MCInst const &inst1) { 117284236Sdim assert((iClass <= 0xf) && "iClass must have range of 0 to 0xf"); 118284236Sdim MCInst *duplexInst = new (Context) MCInst; 119284236Sdim duplexInst->setOpcode(Hexagon::DuplexIClass0 + iClass); 120284236Sdim 121284236Sdim MCInst *SubInst0 = new (Context) MCInst(deriveSubInst(inst0)); 122284236Sdim MCInst *SubInst1 = new (Context) MCInst(deriveSubInst(inst1)); 123284236Sdim duplexInst->addOperand(MCOperand::createInst(SubInst0)); 124284236Sdim duplexInst->addOperand(MCOperand::createInst(SubInst1)); 125284236Sdim return duplexInst; 126284236Sdim} 127284236Sdim 128296417SdimMCInst HexagonMCInstrInfo::deriveExtender(MCInstrInfo const &MCII, 129296417Sdim MCInst const &Inst, 130296417Sdim MCOperand const &MO) { 131296417Sdim assert(HexagonMCInstrInfo::isExtendable(MCII, Inst) || 132296417Sdim HexagonMCInstrInfo::isExtended(MCII, Inst)); 133296417Sdim 134296417Sdim MCInstrDesc const &Desc = HexagonMCInstrInfo::getDesc(MCII, Inst); 135296417Sdim MCInst XMI; 136296417Sdim XMI.setOpcode((Desc.isBranch() || Desc.isCall() || 137296417Sdim HexagonMCInstrInfo::getType(MCII, Inst) == HexagonII::TypeCR) 138296417Sdim ? Hexagon::A4_ext_b 139296417Sdim : Hexagon::A4_ext); 140296417Sdim if (MO.isImm()) 141296417Sdim XMI.addOperand(MCOperand::createImm(MO.getImm() & (~0x3f))); 142296417Sdim else if (MO.isExpr()) 143296417Sdim XMI.addOperand(MCOperand::createExpr(MO.getExpr())); 144296417Sdim else 145296417Sdim llvm_unreachable("invalid extendable operand"); 146296417Sdim return XMI; 147296417Sdim} 148296417Sdim 149284236SdimMCInst const *HexagonMCInstrInfo::extenderForIndex(MCInst const &MCB, 150284236Sdim size_t Index) { 151284236Sdim assert(Index <= bundleSize(MCB)); 152284236Sdim if (Index == 0) 153284236Sdim return nullptr; 154284236Sdim MCInst const *Inst = 155284236Sdim MCB.getOperand(Index + bundleInstructionsOffset - 1).getInst(); 156284236Sdim if (isImmext(*Inst)) 157284236Sdim return Inst; 158284236Sdim return nullptr; 159284236Sdim} 160284236Sdim 161296417Sdimvoid HexagonMCInstrInfo::extendIfNeeded(MCContext &Context, 162296417Sdim MCInstrInfo const &MCII, MCInst &MCB, 163309124Sdim MCInst const &MCI) { 164309124Sdim if (isConstExtended(MCII, MCI)) 165296417Sdim addConstExtender(Context, MCII, MCB, MCI); 166296417Sdim} 167296417Sdim 168283625SdimHexagonII::MemAccessSize 169283625SdimHexagonMCInstrInfo::getAccessSize(MCInstrInfo const &MCII, MCInst const &MCI) { 170283625Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 171283625Sdim 172283625Sdim return (HexagonII::MemAccessSize((F >> HexagonII::MemAccessSizePos) & 173283625Sdim HexagonII::MemAccesSizeMask)); 174283625Sdim} 175283625Sdim 176283625Sdimunsigned HexagonMCInstrInfo::getBitCount(MCInstrInfo const &MCII, 177283625Sdim MCInst const &MCI) { 178283625Sdim uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 179283625Sdim return ((F >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask); 180283625Sdim} 181283625Sdim 182283625Sdim// Return constant extended operand number. 183283625Sdimunsigned short HexagonMCInstrInfo::getCExtOpNum(MCInstrInfo const &MCII, 184283625Sdim MCInst const &MCI) { 185283625Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 186283625Sdim return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask); 187283625Sdim} 188283625Sdim 189283625SdimMCInstrDesc const &HexagonMCInstrInfo::getDesc(MCInstrInfo const &MCII, 190283625Sdim MCInst const &MCI) { 191283625Sdim return (MCII.get(MCI.getOpcode())); 192283625Sdim} 193283625Sdim 194309124Sdimunsigned HexagonMCInstrInfo::getDuplexRegisterNumbering(unsigned Reg) { 195309124Sdim using namespace Hexagon; 196309124Sdim switch (Reg) { 197309124Sdim default: 198309124Sdim llvm_unreachable("unknown duplex register"); 199309124Sdim // Rs Rss 200309124Sdim case R0: 201309124Sdim case D0: 202309124Sdim return 0; 203309124Sdim case R1: 204309124Sdim case D1: 205309124Sdim return 1; 206309124Sdim case R2: 207309124Sdim case D2: 208309124Sdim return 2; 209309124Sdim case R3: 210309124Sdim case D3: 211309124Sdim return 3; 212309124Sdim case R4: 213309124Sdim case D8: 214309124Sdim return 4; 215309124Sdim case R5: 216309124Sdim case D9: 217309124Sdim return 5; 218309124Sdim case R6: 219309124Sdim case D10: 220309124Sdim return 6; 221309124Sdim case R7: 222309124Sdim case D11: 223309124Sdim return 7; 224309124Sdim case R16: 225309124Sdim return 8; 226309124Sdim case R17: 227309124Sdim return 9; 228309124Sdim case R18: 229309124Sdim return 10; 230309124Sdim case R19: 231309124Sdim return 11; 232309124Sdim case R20: 233309124Sdim return 12; 234309124Sdim case R21: 235309124Sdim return 13; 236309124Sdim case R22: 237309124Sdim return 14; 238309124Sdim case R23: 239309124Sdim return 15; 240309124Sdim } 241309124Sdim} 242309124Sdim 243309124SdimMCExpr const &HexagonMCInstrInfo::getExpr(MCExpr const &Expr) { 244309124Sdim const auto &HExpr = cast<HexagonMCExpr>(Expr); 245309124Sdim assert(HExpr.getExpr()); 246309124Sdim return *HExpr.getExpr(); 247309124Sdim} 248309124Sdim 249284236Sdimunsigned short HexagonMCInstrInfo::getExtendableOp(MCInstrInfo const &MCII, 250284236Sdim MCInst const &MCI) { 251284236Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 252284236Sdim return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask); 253284236Sdim} 254284236Sdim 255284236SdimMCOperand const & 256284236SdimHexagonMCInstrInfo::getExtendableOperand(MCInstrInfo const &MCII, 257284236Sdim MCInst const &MCI) { 258284236Sdim unsigned O = HexagonMCInstrInfo::getExtendableOp(MCII, MCI); 259284236Sdim MCOperand const &MO = MCI.getOperand(O); 260284236Sdim 261284236Sdim assert((HexagonMCInstrInfo::isExtendable(MCII, MCI) || 262284236Sdim HexagonMCInstrInfo::isExtended(MCII, MCI)) && 263284236Sdim (MO.isImm() || MO.isExpr())); 264284236Sdim return (MO); 265284236Sdim} 266284236Sdim 267283625Sdimunsigned HexagonMCInstrInfo::getExtentAlignment(MCInstrInfo const &MCII, 268283625Sdim MCInst const &MCI) { 269283625Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 270283625Sdim return ((F >> HexagonII::ExtentAlignPos) & HexagonII::ExtentAlignMask); 271283625Sdim} 272283625Sdim 273283625Sdimunsigned HexagonMCInstrInfo::getExtentBits(MCInstrInfo const &MCII, 274283625Sdim MCInst const &MCI) { 275283625Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 276283625Sdim return ((F >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask); 277283625Sdim} 278283625Sdim 279283625Sdim// Return the max value that a constant extendable operand can have 280283625Sdim// without being extended. 281283625Sdimint HexagonMCInstrInfo::getMaxValue(MCInstrInfo const &MCII, 282283625Sdim MCInst const &MCI) { 283283625Sdim uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 284283625Sdim unsigned isSigned = 285283625Sdim (F >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask; 286283625Sdim unsigned bits = (F >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask; 287283625Sdim 288283625Sdim if (isSigned) // if value is signed 289283625Sdim return ~(-1U << (bits - 1)); 290283625Sdim else 291283625Sdim return ~(-1U << bits); 292283625Sdim} 293283625Sdim 294283625Sdim// Return the min value that a constant extendable operand can have 295283625Sdim// without being extended. 296283625Sdimint HexagonMCInstrInfo::getMinValue(MCInstrInfo const &MCII, 297283625Sdim MCInst const &MCI) { 298283625Sdim uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 299283625Sdim unsigned isSigned = 300283625Sdim (F >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask; 301283625Sdim unsigned bits = (F >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask; 302283625Sdim 303283625Sdim if (isSigned) // if value is signed 304283625Sdim return -1U << (bits - 1); 305283625Sdim else 306283625Sdim return 0; 307283625Sdim} 308283625Sdim 309314564SdimStringRef HexagonMCInstrInfo::getName(MCInstrInfo const &MCII, 310283625Sdim MCInst const &MCI) { 311283625Sdim return MCII.getName(MCI.getOpcode()); 312283625Sdim} 313283625Sdim 314284236Sdimunsigned short HexagonMCInstrInfo::getNewValueOp(MCInstrInfo const &MCII, 315283625Sdim MCInst const &MCI) { 316284236Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 317284236Sdim return ((F >> HexagonII::NewValueOpPos) & HexagonII::NewValueOpMask); 318284236Sdim} 319284236Sdim 320284236SdimMCOperand const &HexagonMCInstrInfo::getNewValueOperand(MCInstrInfo const &MCII, 321284236Sdim MCInst const &MCI) { 322283625Sdim uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 323283625Sdim unsigned const O = 324283625Sdim (F >> HexagonII::NewValueOpPos) & HexagonII::NewValueOpMask; 325283625Sdim MCOperand const &MCO = MCI.getOperand(O); 326283625Sdim 327283625Sdim assert((HexagonMCInstrInfo::isNewValue(MCII, MCI) || 328283625Sdim HexagonMCInstrInfo::hasNewValue(MCII, MCI)) && 329283625Sdim MCO.isReg()); 330283625Sdim return (MCO); 331283625Sdim} 332283625Sdim 333296417Sdim/// Return the new value or the newly produced value. 334296417Sdimunsigned short HexagonMCInstrInfo::getNewValueOp2(MCInstrInfo const &MCII, 335296417Sdim MCInst const &MCI) { 336296417Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 337296417Sdim return ((F >> HexagonII::NewValueOpPos2) & HexagonII::NewValueOpMask2); 338296417Sdim} 339296417Sdim 340296417SdimMCOperand const & 341296417SdimHexagonMCInstrInfo::getNewValueOperand2(MCInstrInfo const &MCII, 342296417Sdim MCInst const &MCI) { 343296417Sdim unsigned O = HexagonMCInstrInfo::getNewValueOp2(MCII, MCI); 344296417Sdim MCOperand const &MCO = MCI.getOperand(O); 345296417Sdim 346296417Sdim assert((HexagonMCInstrInfo::isNewValue(MCII, MCI) || 347296417Sdim HexagonMCInstrInfo::hasNewValue2(MCII, MCI)) && 348296417Sdim MCO.isReg()); 349296417Sdim return (MCO); 350296417Sdim} 351296417Sdim 352284236Sdimint HexagonMCInstrInfo::getSubTarget(MCInstrInfo const &MCII, 353284236Sdim MCInst const &MCI) { 354284236Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 355284236Sdim 356284236Sdim HexagonII::SubTarget Target = static_cast<HexagonII::SubTarget>( 357284236Sdim (F >> HexagonII::validSubTargetPos) & HexagonII::validSubTargetMask); 358284236Sdim 359284236Sdim switch (Target) { 360284236Sdim default: 361284236Sdim return Hexagon::ArchV4; 362284236Sdim case HexagonII::HasV5SubT: 363284236Sdim return Hexagon::ArchV5; 364284236Sdim } 365284236Sdim} 366284236Sdim 367283625Sdim// Return the Hexagon ISA class for the insn. 368283625Sdimunsigned HexagonMCInstrInfo::getType(MCInstrInfo const &MCII, 369283625Sdim MCInst const &MCI) { 370283625Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 371283625Sdim 372283625Sdim return ((F >> HexagonII::TypePos) & HexagonII::TypeMask); 373283625Sdim} 374283625Sdim 375284236Sdimunsigned HexagonMCInstrInfo::getUnits(MCInstrInfo const &MCII, 376284236Sdim MCSubtargetInfo const &STI, 377284236Sdim MCInst const &MCI) { 378284236Sdim 379284236Sdim const InstrItinerary *II = STI.getSchedModel().InstrItineraries; 380284236Sdim int SchedClass = HexagonMCInstrInfo::getDesc(MCII, MCI).getSchedClass(); 381284236Sdim return ((II[SchedClass].FirstStage + HexagonStages)->getUnits()); 382284236Sdim} 383284236Sdim 384284236Sdimbool HexagonMCInstrInfo::hasImmExt(MCInst const &MCI) { 385284236Sdim if (!HexagonMCInstrInfo::isBundle(MCI)) 386284236Sdim return false; 387284236Sdim 388284236Sdim for (const auto &I : HexagonMCInstrInfo::bundleInstructions(MCI)) { 389284236Sdim auto MI = I.getInst(); 390284236Sdim if (isImmext(*MI)) 391284236Sdim return true; 392284236Sdim } 393284236Sdim 394284236Sdim return false; 395284236Sdim} 396284236Sdim 397284236Sdimbool HexagonMCInstrInfo::hasExtenderForIndex(MCInst const &MCB, size_t Index) { 398284236Sdim return extenderForIndex(MCB, Index) != nullptr; 399284236Sdim} 400284236Sdim 401283625Sdim// Return whether the instruction is a legal new-value producer. 402283625Sdimbool HexagonMCInstrInfo::hasNewValue(MCInstrInfo const &MCII, 403283625Sdim MCInst const &MCI) { 404283625Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 405283625Sdim return ((F >> HexagonII::hasNewValuePos) & HexagonII::hasNewValueMask); 406283625Sdim} 407283625Sdim 408296417Sdim/// Return whether the insn produces a second value. 409296417Sdimbool HexagonMCInstrInfo::hasNewValue2(MCInstrInfo const &MCII, 410296417Sdim MCInst const &MCI) { 411296417Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 412296417Sdim return ((F >> HexagonII::hasNewValuePos2) & HexagonII::hasNewValueMask2); 413296417Sdim} 414296417Sdim 415284236SdimMCInst const &HexagonMCInstrInfo::instruction(MCInst const &MCB, size_t Index) { 416284236Sdim assert(isBundle(MCB)); 417284236Sdim assert(Index < HEXAGON_PACKET_SIZE); 418284236Sdim return *MCB.getOperand(bundleInstructionsOffset + Index).getInst(); 419284236Sdim} 420284236Sdim 421284236Sdimbool HexagonMCInstrInfo::isBundle(MCInst const &MCI) { 422284236Sdim auto Result = Hexagon::BUNDLE == MCI.getOpcode(); 423284236Sdim assert(!Result || (MCI.size() > 0 && MCI.getOperand(0).isImm())); 424284236Sdim return Result; 425284236Sdim} 426284236Sdim 427283625Sdim// Return whether the insn is an actual insn. 428283625Sdimbool HexagonMCInstrInfo::isCanon(MCInstrInfo const &MCII, MCInst const &MCI) { 429283625Sdim return (!HexagonMCInstrInfo::getDesc(MCII, MCI).isPseudo() && 430283625Sdim !HexagonMCInstrInfo::isPrefix(MCII, MCI) && 431283625Sdim HexagonMCInstrInfo::getType(MCII, MCI) != HexagonII::TypeENDLOOP); 432283625Sdim} 433283625Sdim 434314564Sdimbool HexagonMCInstrInfo::isCofMax1(MCInstrInfo const &MCII, MCInst const &MCI) { 435314564Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 436314564Sdim return ((F >> HexagonII::CofMax1Pos) & HexagonII::CofMax1Mask); 437314564Sdim} 438314564Sdim 439296417Sdimbool HexagonMCInstrInfo::isCompound(MCInstrInfo const &MCII, 440296417Sdim MCInst const &MCI) { 441296417Sdim return (getType(MCII, MCI) == HexagonII::TypeCOMPOUND); 442296417Sdim} 443296417Sdim 444284236Sdimbool HexagonMCInstrInfo::isDblRegForSubInst(unsigned Reg) { 445284236Sdim return ((Reg >= Hexagon::D0 && Reg <= Hexagon::D3) || 446284236Sdim (Reg >= Hexagon::D8 && Reg <= Hexagon::D11)); 447284236Sdim} 448284236Sdim 449284236Sdimbool HexagonMCInstrInfo::isDuplex(MCInstrInfo const &MCII, MCInst const &MCI) { 450284236Sdim return HexagonII::TypeDUPLEX == HexagonMCInstrInfo::getType(MCII, MCI); 451284236Sdim} 452284236Sdim 453283625Sdim// Return whether the instruction needs to be constant extended. 454283625Sdim// 1) Always return true if the instruction has 'isExtended' flag set. 455283625Sdim// 456283625Sdim// isExtendable: 457283625Sdim// 2) For immediate extended operands, return true only if the value is 458283625Sdim// out-of-range. 459283625Sdim// 3) For global address, always return true. 460283625Sdim 461283625Sdimbool HexagonMCInstrInfo::isConstExtended(MCInstrInfo const &MCII, 462283625Sdim MCInst const &MCI) { 463283625Sdim if (HexagonMCInstrInfo::isExtended(MCII, MCI)) 464283625Sdim return true; 465309124Sdim if (!HexagonMCInstrInfo::isExtendable(MCII, MCI)) 466309124Sdim return false; 467309124Sdim MCOperand const &MO = HexagonMCInstrInfo::getExtendableOperand(MCII, MCI); 468309124Sdim if (isa<HexagonMCExpr>(MO.getExpr()) && 469309124Sdim HexagonMCInstrInfo::mustExtend(*MO.getExpr())) 470309124Sdim return true; 471296417Sdim // Branch insns are handled as necessary by relaxation. 472296417Sdim if ((HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeJ) || 473296417Sdim (HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeCOMPOUND && 474296417Sdim HexagonMCInstrInfo::getDesc(MCII, MCI).isBranch()) || 475296417Sdim (HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeNV && 476296417Sdim HexagonMCInstrInfo::getDesc(MCII, MCI).isBranch())) 477283625Sdim return false; 478296417Sdim // Otherwise loop instructions and other CR insts are handled by relaxation 479296417Sdim else if ((HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeCR) && 480296417Sdim (MCI.getOpcode() != Hexagon::C4_addipc)) 481296417Sdim return false; 482283625Sdim 483296417Sdim assert(!MO.isImm()); 484309124Sdim if (isa<HexagonMCExpr>(MO.getExpr()) && 485309124Sdim HexagonMCInstrInfo::mustNotExtend(*MO.getExpr())) 486309124Sdim return false; 487296417Sdim int64_t Value; 488296417Sdim if (!MO.getExpr()->evaluateAsAbsolute(Value)) 489283625Sdim return true; 490296417Sdim int MinValue = HexagonMCInstrInfo::getMinValue(MCII, MCI); 491296417Sdim int MaxValue = HexagonMCInstrInfo::getMaxValue(MCII, MCI); 492296417Sdim return (MinValue > Value || Value > MaxValue); 493283625Sdim} 494283625Sdim 495283625Sdimbool HexagonMCInstrInfo::isExtendable(MCInstrInfo const &MCII, 496283625Sdim MCInst const &MCI) { 497283625Sdim uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 498283625Sdim return (F >> HexagonII::ExtendablePos) & HexagonII::ExtendableMask; 499283625Sdim} 500283625Sdim 501283625Sdimbool HexagonMCInstrInfo::isExtended(MCInstrInfo const &MCII, 502283625Sdim MCInst const &MCI) { 503283625Sdim uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 504283625Sdim return (F >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask; 505283625Sdim} 506283625Sdim 507284236Sdimbool HexagonMCInstrInfo::isFloat(MCInstrInfo const &MCII, MCInst const &MCI) { 508284236Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 509284236Sdim return ((F >> HexagonII::FPPos) & HexagonII::FPMask); 510284236Sdim} 511284236Sdim 512284236Sdimbool HexagonMCInstrInfo::isImmext(MCInst const &MCI) { 513284236Sdim auto Op = MCI.getOpcode(); 514284236Sdim return (Op == Hexagon::A4_ext_b || Op == Hexagon::A4_ext_c || 515284236Sdim Op == Hexagon::A4_ext_g || Op == Hexagon::A4_ext); 516284236Sdim} 517284236Sdim 518284236Sdimbool HexagonMCInstrInfo::isInnerLoop(MCInst const &MCI) { 519284236Sdim assert(isBundle(MCI)); 520284236Sdim int64_t Flags = MCI.getOperand(0).getImm(); 521284236Sdim return (Flags & innerLoopMask) != 0; 522284236Sdim} 523284236Sdim 524284236Sdimbool HexagonMCInstrInfo::isIntReg(unsigned Reg) { 525284236Sdim return (Reg >= Hexagon::R0 && Reg <= Hexagon::R31); 526284236Sdim} 527284236Sdim 528284236Sdimbool HexagonMCInstrInfo::isIntRegForSubInst(unsigned Reg) { 529284236Sdim return ((Reg >= Hexagon::R0 && Reg <= Hexagon::R7) || 530284236Sdim (Reg >= Hexagon::R16 && Reg <= Hexagon::R23)); 531284236Sdim} 532284236Sdim 533283625Sdim// Return whether the insn is a new-value consumer. 534283625Sdimbool HexagonMCInstrInfo::isNewValue(MCInstrInfo const &MCII, 535283625Sdim MCInst const &MCI) { 536283625Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 537283625Sdim return ((F >> HexagonII::NewValuePos) & HexagonII::NewValueMask); 538283625Sdim} 539283625Sdim 540283625Sdim// Return whether the operand can be constant extended. 541283625Sdimbool HexagonMCInstrInfo::isOperandExtended(MCInstrInfo const &MCII, 542283625Sdim MCInst const &MCI, 543283625Sdim unsigned short OperandNum) { 544283625Sdim uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 545283625Sdim return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask) == 546283625Sdim OperandNum; 547283625Sdim} 548283625Sdim 549284236Sdimbool HexagonMCInstrInfo::isOuterLoop(MCInst const &MCI) { 550284236Sdim assert(isBundle(MCI)); 551284236Sdim int64_t Flags = MCI.getOperand(0).getImm(); 552284236Sdim return (Flags & outerLoopMask) != 0; 553283625Sdim} 554283625Sdim 555284236Sdimbool HexagonMCInstrInfo::isPredicated(MCInstrInfo const &MCII, 556284236Sdim MCInst const &MCI) { 557284236Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 558284236Sdim return ((F >> HexagonII::PredicatedPos) & HexagonII::PredicatedMask); 559283625Sdim} 560283625Sdim 561296417Sdimbool HexagonMCInstrInfo::isPredicateLate(MCInstrInfo const &MCII, 562296417Sdim MCInst const &MCI) { 563296417Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 564296417Sdim return (F >> HexagonII::PredicateLatePos & HexagonII::PredicateLateMask); 565296417Sdim} 566296417Sdim 567296417Sdim/// Return whether the insn is newly predicated. 568296417Sdimbool HexagonMCInstrInfo::isPredicatedNew(MCInstrInfo const &MCII, 569296417Sdim MCInst const &MCI) { 570296417Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 571296417Sdim return ((F >> HexagonII::PredicatedNewPos) & HexagonII::PredicatedNewMask); 572296417Sdim} 573296417Sdim 574284236Sdimbool HexagonMCInstrInfo::isPredicatedTrue(MCInstrInfo const &MCII, 575284236Sdim MCInst const &MCI) { 576284236Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 577284236Sdim return ( 578284236Sdim !((F >> HexagonII::PredicatedFalsePos) & HexagonII::PredicatedFalseMask)); 579284236Sdim} 580284236Sdim 581284236Sdimbool HexagonMCInstrInfo::isPredReg(unsigned Reg) { 582284236Sdim return (Reg >= Hexagon::P0 && Reg <= Hexagon::P3_0); 583284236Sdim} 584284236Sdim 585283625Sdimbool HexagonMCInstrInfo::isPrefix(MCInstrInfo const &MCII, MCInst const &MCI) { 586283625Sdim return (HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypePREFIX); 587283625Sdim} 588283625Sdim 589283625Sdimbool HexagonMCInstrInfo::isSolo(MCInstrInfo const &MCII, MCInst const &MCI) { 590283625Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 591283625Sdim return ((F >> HexagonII::SoloPos) & HexagonII::SoloMask); 592283625Sdim} 593283625Sdim 594296417Sdimbool HexagonMCInstrInfo::isMemReorderDisabled(MCInst const &MCI) { 595296417Sdim assert(isBundle(MCI)); 596296417Sdim auto Flags = MCI.getOperand(0).getImm(); 597296417Sdim return (Flags & memReorderDisabledMask) != 0; 598296417Sdim} 599296417Sdim 600296417Sdimbool HexagonMCInstrInfo::isMemStoreReorderEnabled(MCInst const &MCI) { 601296417Sdim assert(isBundle(MCI)); 602296417Sdim auto Flags = MCI.getOperand(0).getImm(); 603296417Sdim return (Flags & memStoreReorderEnabledMask) != 0; 604296417Sdim} 605296417Sdim 606309124Sdimbool HexagonMCInstrInfo::isSubInstruction(MCInst const &MCI) { 607309124Sdim switch (MCI.getOpcode()) { 608309124Sdim default: 609309124Sdim return false; 610314564Sdim case Hexagon::SA1_addi: 611314564Sdim case Hexagon::SA1_addrx: 612314564Sdim case Hexagon::SA1_addsp: 613314564Sdim case Hexagon::SA1_and1: 614314564Sdim case Hexagon::SA1_clrf: 615314564Sdim case Hexagon::SA1_clrfnew: 616314564Sdim case Hexagon::SA1_clrt: 617314564Sdim case Hexagon::SA1_clrtnew: 618314564Sdim case Hexagon::SA1_cmpeqi: 619314564Sdim case Hexagon::SA1_combine0i: 620314564Sdim case Hexagon::SA1_combine1i: 621314564Sdim case Hexagon::SA1_combine2i: 622314564Sdim case Hexagon::SA1_combine3i: 623314564Sdim case Hexagon::SA1_combinerz: 624314564Sdim case Hexagon::SA1_combinezr: 625314564Sdim case Hexagon::SA1_dec: 626314564Sdim case Hexagon::SA1_inc: 627314564Sdim case Hexagon::SA1_seti: 628314564Sdim case Hexagon::SA1_setin1: 629314564Sdim case Hexagon::SA1_sxtb: 630314564Sdim case Hexagon::SA1_sxth: 631314564Sdim case Hexagon::SA1_tfr: 632314564Sdim case Hexagon::SA1_zxtb: 633314564Sdim case Hexagon::SA1_zxth: 634314564Sdim case Hexagon::SL1_loadri_io: 635314564Sdim case Hexagon::SL1_loadrub_io: 636314564Sdim case Hexagon::SL2_deallocframe: 637314564Sdim case Hexagon::SL2_jumpr31: 638314564Sdim case Hexagon::SL2_jumpr31_f: 639314564Sdim case Hexagon::SL2_jumpr31_fnew: 640314564Sdim case Hexagon::SL2_jumpr31_t: 641314564Sdim case Hexagon::SL2_jumpr31_tnew: 642314564Sdim case Hexagon::SL2_loadrb_io: 643314564Sdim case Hexagon::SL2_loadrd_sp: 644314564Sdim case Hexagon::SL2_loadrh_io: 645314564Sdim case Hexagon::SL2_loadri_sp: 646314564Sdim case Hexagon::SL2_loadruh_io: 647314564Sdim case Hexagon::SL2_return: 648314564Sdim case Hexagon::SL2_return_f: 649314564Sdim case Hexagon::SL2_return_fnew: 650314564Sdim case Hexagon::SL2_return_t: 651314564Sdim case Hexagon::SL2_return_tnew: 652314564Sdim case Hexagon::SS1_storeb_io: 653314564Sdim case Hexagon::SS1_storew_io: 654314564Sdim case Hexagon::SS2_allocframe: 655314564Sdim case Hexagon::SS2_storebi0: 656314564Sdim case Hexagon::SS2_storebi1: 657314564Sdim case Hexagon::SS2_stored_sp: 658314564Sdim case Hexagon::SS2_storeh_io: 659314564Sdim case Hexagon::SS2_storew_sp: 660314564Sdim case Hexagon::SS2_storewi0: 661314564Sdim case Hexagon::SS2_storewi1: 662309124Sdim return true; 663309124Sdim } 664309124Sdim} 665309124Sdim 666284236Sdimbool HexagonMCInstrInfo::isSoloAX(MCInstrInfo const &MCII, MCInst const &MCI) { 667284236Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 668284236Sdim return ((F >> HexagonII::SoloAXPos) & HexagonII::SoloAXMask); 669283625Sdim} 670283625Sdim 671284236Sdimbool HexagonMCInstrInfo::isSoloAin1(MCInstrInfo const &MCII, 672284236Sdim MCInst const &MCI) { 673284236Sdim const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; 674284236Sdim return ((F >> HexagonII::SoloAin1Pos) & HexagonII::SoloAin1Mask); 675283625Sdim} 676283625Sdim 677296417Sdimbool HexagonMCInstrInfo::isVector(MCInstrInfo const &MCII, MCInst const &MCI) { 678296417Sdim if ((getType(MCII, MCI) <= HexagonII::TypeCVI_LAST) && 679296417Sdim (getType(MCII, MCI) >= HexagonII::TypeCVI_FIRST)) 680296417Sdim return true; 681296417Sdim return false; 682296417Sdim} 683296417Sdim 684296417Sdimint64_t HexagonMCInstrInfo::minConstant(MCInst const &MCI, size_t Index) { 685296417Sdim auto Sentinal = static_cast<int64_t>(std::numeric_limits<uint32_t>::max()) 686296417Sdim << 8; 687296417Sdim if (MCI.size() <= Index) 688296417Sdim return Sentinal; 689296417Sdim MCOperand const &MCO = MCI.getOperand(Index); 690296417Sdim if (!MCO.isExpr()) 691296417Sdim return Sentinal; 692296417Sdim int64_t Value; 693296417Sdim if (!MCO.getExpr()->evaluateAsAbsolute(Value)) 694296417Sdim return Sentinal; 695296417Sdim return Value; 696296417Sdim} 697296417Sdim 698309124Sdimvoid HexagonMCInstrInfo::setMustExtend(MCExpr const &Expr, bool Val) { 699309124Sdim HexagonMCExpr &HExpr = const_cast<HexagonMCExpr &>(cast<HexagonMCExpr>(Expr)); 700309124Sdim HExpr.setMustExtend(Val); 701309124Sdim} 702309124Sdim 703309124Sdimbool HexagonMCInstrInfo::mustExtend(MCExpr const &Expr) { 704309124Sdim HexagonMCExpr const &HExpr = cast<HexagonMCExpr>(Expr); 705309124Sdim return HExpr.mustExtend(); 706309124Sdim} 707309124Sdimvoid HexagonMCInstrInfo::setMustNotExtend(MCExpr const &Expr, bool Val) { 708309124Sdim HexagonMCExpr &HExpr = 709309124Sdim const_cast<HexagonMCExpr &>(cast<HexagonMCExpr>(Expr)); 710309124Sdim HExpr.setMustNotExtend(Val); 711309124Sdim} 712309124Sdimbool HexagonMCInstrInfo::mustNotExtend(MCExpr const &Expr) { 713309124Sdim HexagonMCExpr const &HExpr = cast<HexagonMCExpr>(Expr); 714309124Sdim return HExpr.mustNotExtend(); 715309124Sdim} 716309124Sdim 717296417Sdimvoid HexagonMCInstrInfo::padEndloop(MCContext &Context, MCInst &MCB) { 718284236Sdim MCInst Nop; 719284236Sdim Nop.setOpcode(Hexagon::A2_nop); 720284236Sdim assert(isBundle(MCB)); 721284236Sdim while ((HexagonMCInstrInfo::isInnerLoop(MCB) && 722284236Sdim (HexagonMCInstrInfo::bundleSize(MCB) < HEXAGON_PACKET_INNER_SIZE)) || 723284236Sdim ((HexagonMCInstrInfo::isOuterLoop(MCB) && 724284236Sdim (HexagonMCInstrInfo::bundleSize(MCB) < HEXAGON_PACKET_OUTER_SIZE)))) 725296417Sdim MCB.addOperand(MCOperand::createInst(new (Context) MCInst(Nop))); 726283625Sdim} 727283625Sdim 728284236Sdimbool HexagonMCInstrInfo::prefersSlot3(MCInstrInfo const &MCII, 729284236Sdim MCInst const &MCI) { 730284236Sdim if (HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeCR) 731284236Sdim return false; 732284236Sdim 733284236Sdim unsigned SchedClass = HexagonMCInstrInfo::getDesc(MCII, MCI).getSchedClass(); 734284236Sdim switch (SchedClass) { 735284236Sdim case Hexagon::Sched::ALU32_3op_tc_2_SLOT0123: 736284236Sdim case Hexagon::Sched::ALU64_tc_2_SLOT23: 737284236Sdim case Hexagon::Sched::ALU64_tc_3x_SLOT23: 738284236Sdim case Hexagon::Sched::M_tc_2_SLOT23: 739284236Sdim case Hexagon::Sched::M_tc_3x_SLOT23: 740284236Sdim case Hexagon::Sched::S_2op_tc_2_SLOT23: 741284236Sdim case Hexagon::Sched::S_3op_tc_2_SLOT23: 742284236Sdim case Hexagon::Sched::S_3op_tc_3x_SLOT23: 743284236Sdim return true; 744284236Sdim } 745284236Sdim return false; 746283625Sdim} 747284236Sdim 748284236Sdimvoid HexagonMCInstrInfo::replaceDuplex(MCContext &Context, MCInst &MCB, 749284236Sdim DuplexCandidate Candidate) { 750284236Sdim assert(Candidate.packetIndexI < MCB.size()); 751284236Sdim assert(Candidate.packetIndexJ < MCB.size()); 752284236Sdim assert(isBundle(MCB)); 753284236Sdim MCInst *Duplex = 754284236Sdim deriveDuplex(Context, Candidate.iClass, 755284236Sdim *MCB.getOperand(Candidate.packetIndexJ).getInst(), 756284236Sdim *MCB.getOperand(Candidate.packetIndexI).getInst()); 757284236Sdim assert(Duplex != nullptr); 758284236Sdim MCB.getOperand(Candidate.packetIndexI).setInst(Duplex); 759284236Sdim MCB.erase(MCB.begin() + Candidate.packetIndexJ); 760283625Sdim} 761284236Sdim 762284236Sdimvoid HexagonMCInstrInfo::setInnerLoop(MCInst &MCI) { 763284236Sdim assert(isBundle(MCI)); 764284236Sdim MCOperand &Operand = MCI.getOperand(0); 765284236Sdim Operand.setImm(Operand.getImm() | innerLoopMask); 766284236Sdim} 767284236Sdim 768296417Sdimvoid HexagonMCInstrInfo::setMemReorderDisabled(MCInst &MCI) { 769296417Sdim assert(isBundle(MCI)); 770296417Sdim MCOperand &Operand = MCI.getOperand(0); 771296417Sdim Operand.setImm(Operand.getImm() | memReorderDisabledMask); 772296417Sdim assert(isMemReorderDisabled(MCI)); 773296417Sdim} 774296417Sdim 775296417Sdimvoid HexagonMCInstrInfo::setMemStoreReorderEnabled(MCInst &MCI) { 776296417Sdim assert(isBundle(MCI)); 777296417Sdim MCOperand &Operand = MCI.getOperand(0); 778296417Sdim Operand.setImm(Operand.getImm() | memStoreReorderEnabledMask); 779296417Sdim assert(isMemStoreReorderEnabled(MCI)); 780296417Sdim} 781309124Sdimvoid HexagonMCInstrInfo::setS23_2_reloc(MCExpr const &Expr, bool Val) { 782309124Sdim HexagonMCExpr &HExpr = 783309124Sdim const_cast<HexagonMCExpr &>(*llvm::cast<HexagonMCExpr>(&Expr)); 784309124Sdim HExpr.setS23_2_reloc(Val); 785309124Sdim} 786309124Sdimbool HexagonMCInstrInfo::s23_2_reloc(MCExpr const &Expr) { 787309124Sdim HexagonMCExpr const &HExpr = *llvm::cast<HexagonMCExpr>(&Expr); 788309124Sdim return HExpr.s23_2_reloc(); 789309124Sdim} 790296417Sdim 791284236Sdimvoid HexagonMCInstrInfo::setOuterLoop(MCInst &MCI) { 792284236Sdim assert(isBundle(MCI)); 793284236Sdim MCOperand &Operand = MCI.getOperand(0); 794284236Sdim Operand.setImm(Operand.getImm() | outerLoopMask); 795284236Sdim} 796309124Sdim 797309124Sdimunsigned HexagonMCInstrInfo::SubregisterBit(unsigned Consumer, 798309124Sdim unsigned Producer, 799309124Sdim unsigned Producer2) { 800309124Sdim // If we're a single vector consumer of a double producer, set subreg bit 801309124Sdim // based on if we're accessing the lower or upper register component 802309124Sdim if (Producer >= Hexagon::W0 && Producer <= Hexagon::W15) 803309124Sdim if (Consumer >= Hexagon::V0 && Consumer <= Hexagon::V31) 804309124Sdim return (Consumer - Hexagon::V0) & 0x1; 805309124Sdim if (Consumer == Producer2) 806309124Sdim return 0x1; 807309124Sdim return 0; 808285181Sdim} 809309124Sdim} 810