diff options
Diffstat (limited to 'contrib/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp')
-rw-r--r-- | contrib/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp | 408 |
1 files changed, 225 insertions, 183 deletions
diff --git a/contrib/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp b/contrib/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp index e627f02..5fe638a 100644 --- a/contrib/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp +++ b/contrib/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp @@ -16,13 +16,55 @@ #include "Hexagon.h" #include "HexagonBaseInfo.h" #include "HexagonMCChecker.h" - #include "llvm/MC/MCContext.h" -#include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInstrInfo.h" +#include "llvm/MC/MCInstrItineraries.h" #include "llvm/MC/MCSubtargetInfo.h" namespace llvm { + +Hexagon::PacketIterator::PacketIterator(MCInstrInfo const &MCII, + MCInst const &Inst) + : MCII(MCII), BundleCurrent(Inst.begin() + + HexagonMCInstrInfo::bundleInstructionsOffset), + BundleEnd(Inst.end()), DuplexCurrent(Inst.end()), DuplexEnd(Inst.end()) {} + +Hexagon::PacketIterator::PacketIterator(MCInstrInfo const &MCII, + MCInst const &Inst, std::nullptr_t) + : MCII(MCII), BundleCurrent(Inst.end()), BundleEnd(Inst.end()), + DuplexCurrent(Inst.end()), DuplexEnd(Inst.end()) {} + +Hexagon::PacketIterator &Hexagon::PacketIterator::operator++() { + if (DuplexCurrent != DuplexEnd) { + ++DuplexCurrent; + if (DuplexCurrent == DuplexEnd) { + DuplexCurrent = BundleEnd; + DuplexEnd = BundleEnd; + } + return *this; + } + ++BundleCurrent; + if (BundleCurrent != BundleEnd) { + MCInst const &Inst = *BundleCurrent->getInst(); + if (HexagonMCInstrInfo::isDuplex(MCII, Inst)) { + DuplexCurrent = Inst.begin(); + DuplexEnd = Inst.end(); + } + } + return *this; +} + +MCInst const &Hexagon::PacketIterator::operator*() const { + if (DuplexCurrent != DuplexEnd) + return *DuplexCurrent->getInst(); + return *BundleCurrent->getInst(); +} + +bool Hexagon::PacketIterator::operator==(PacketIterator const &Other) const { + return BundleCurrent == Other.BundleCurrent && BundleEnd == Other.BundleEnd && + DuplexCurrent == Other.DuplexCurrent && DuplexEnd == Other.DuplexEnd; +} + void HexagonMCInstrInfo::addConstant(MCInst &MI, uint64_t Value, MCContext &Context) { MI.addOperand(MCOperand::createExpr(MCConstantExpr::create(Value, Context))); @@ -42,6 +84,14 @@ void HexagonMCInstrInfo::addConstExtender(MCContext &Context, MCB.addOperand(MCOperand::createInst(XMCI)); } +iterator_range<Hexagon::PacketIterator> +HexagonMCInstrInfo::bundleInstructions(MCInstrInfo const &MCII, + MCInst const &MCI) { + assert(isBundle(MCI)); + return make_range(Hexagon::PacketIterator(MCII, MCI), + Hexagon::PacketIterator(MCII, MCI, nullptr)); +} + iterator_range<MCInst::const_iterator> HexagonMCInstrInfo::bundleInstructions(MCInst const &MCI) { assert(isBundle(MCI)); @@ -59,31 +109,36 @@ bool HexagonMCInstrInfo::canonicalizePacket(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCContext &Context, MCInst &MCB, HexagonMCChecker *Check) { - // Examine the packet and convert pairs of instructions to compound - // instructions when possible. - if (!HexagonDisableCompound) - HexagonMCInstrInfo::tryCompound(MCII, Context, MCB); // Check the bundle for errors. - bool CheckOk = Check ? Check->check() : true; + bool CheckOk = Check ? Check->check(false) : true; if (!CheckOk) return false; - HexagonMCShuffle(MCII, STI, MCB); + // Examine the packet and convert pairs of instructions to compound + // instructions when possible. + if (!HexagonDisableCompound) + HexagonMCInstrInfo::tryCompound(MCII, STI, Context, MCB); + HexagonMCShuffle(Context, false, MCII, STI, MCB); // Examine the packet and convert pairs of instructions to duplex // instructions when possible. MCInst InstBundlePreDuplex = MCInst(MCB); if (!HexagonDisableDuplex) { SmallVector<DuplexCandidate, 8> possibleDuplexes; - possibleDuplexes = HexagonMCInstrInfo::getDuplexPossibilties(MCII, MCB); - HexagonMCShuffle(MCII, STI, Context, MCB, possibleDuplexes); + possibleDuplexes = + HexagonMCInstrInfo::getDuplexPossibilties(MCII, STI, MCB); + HexagonMCShuffle(Context, MCII, STI, MCB, possibleDuplexes); } // Examines packet and pad the packet, if needed, when an // end-loop is in the bundle. - HexagonMCInstrInfo::padEndloop(Context, MCB); + HexagonMCInstrInfo::padEndloop(MCB, Context); // If compounding and duplexing didn't reduce the size below // 4 or less we have a packet that is too big. if (HexagonMCInstrInfo::bundleSize(MCB) > HEXAGON_PACKET_SIZE) return false; - HexagonMCShuffle(MCII, STI, MCB); + // Check the bundle for errors. + CheckOk = Check ? Check->check(true) : true; + if (!CheckOk) + return false; + HexagonMCShuffle(Context, true, MCII, STI, MCB); return true; } @@ -111,32 +166,14 @@ MCInst HexagonMCInstrInfo::createBundle() { return Result; } -MCInst *HexagonMCInstrInfo::deriveDuplex(MCContext &Context, unsigned iClass, - MCInst const &inst0, - MCInst const &inst1) { - assert((iClass <= 0xf) && "iClass must have range of 0 to 0xf"); - MCInst *duplexInst = new (Context) MCInst; - duplexInst->setOpcode(Hexagon::DuplexIClass0 + iClass); - - MCInst *SubInst0 = new (Context) MCInst(deriveSubInst(inst0)); - MCInst *SubInst1 = new (Context) MCInst(deriveSubInst(inst1)); - duplexInst->addOperand(MCOperand::createInst(SubInst0)); - duplexInst->addOperand(MCOperand::createInst(SubInst1)); - return duplexInst; -} - MCInst HexagonMCInstrInfo::deriveExtender(MCInstrInfo const &MCII, MCInst const &Inst, MCOperand const &MO) { assert(HexagonMCInstrInfo::isExtendable(MCII, Inst) || HexagonMCInstrInfo::isExtended(MCII, Inst)); - MCInstrDesc const &Desc = HexagonMCInstrInfo::getDesc(MCII, Inst); MCInst XMI; - XMI.setOpcode((Desc.isBranch() || Desc.isCall() || - HexagonMCInstrInfo::getType(MCII, Inst) == HexagonII::TypeCR) - ? Hexagon::A4_ext_b - : Hexagon::A4_ext); + XMI.setOpcode(Hexagon::A4_ext); if (MO.isImm()) XMI.addOperand(MCOperand::createImm(MO.getImm() & (~0x3f))); else if (MO.isExpr()) @@ -146,6 +183,20 @@ MCInst HexagonMCInstrInfo::deriveExtender(MCInstrInfo const &MCII, return XMI; } +MCInst *HexagonMCInstrInfo::deriveDuplex(MCContext &Context, unsigned iClass, + MCInst const &inst0, + MCInst const &inst1) { + assert((iClass <= 0xf) && "iClass must have range of 0 to 0xf"); + MCInst *duplexInst = new (Context) MCInst; + duplexInst->setOpcode(Hexagon::DuplexIClass0 + iClass); + + MCInst *SubInst0 = new (Context) MCInst(deriveSubInst(inst0)); + MCInst *SubInst1 = new (Context) MCInst(deriveSubInst(inst1)); + duplexInst->addOperand(MCOperand::createInst(SubInst0)); + duplexInst->addOperand(MCOperand::createInst(SubInst1)); + return duplexInst; +} + MCInst const *HexagonMCInstrInfo::extenderForIndex(MCInst const &MCB, size_t Index) { assert(Index <= bundleSize(MCB)); @@ -173,22 +224,9 @@ HexagonMCInstrInfo::getAccessSize(MCInstrInfo const &MCII, MCInst const &MCI) { HexagonII::MemAccesSizeMask)); } -unsigned HexagonMCInstrInfo::getBitCount(MCInstrInfo const &MCII, - MCInst const &MCI) { - uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; - return ((F >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask); -} - -// Return constant extended operand number. -unsigned short HexagonMCInstrInfo::getCExtOpNum(MCInstrInfo const &MCII, - MCInst const &MCI) { - const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; - return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask); -} - MCInstrDesc const &HexagonMCInstrInfo::getDesc(MCInstrInfo const &MCII, MCInst const &MCI) { - return (MCII.get(MCI.getOpcode())); + return MCII.get(MCI.getOpcode()); } unsigned HexagonMCInstrInfo::getDuplexRegisterNumbering(unsigned Reg) { @@ -276,38 +314,36 @@ unsigned HexagonMCInstrInfo::getExtentBits(MCInstrInfo const &MCII, return ((F >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask); } -// Return the max value that a constant extendable operand can have -// without being extended. +/// Return the maximum value of an extendable operand. int HexagonMCInstrInfo::getMaxValue(MCInstrInfo const &MCII, MCInst const &MCI) { - uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; - unsigned isSigned = - (F >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask; - unsigned bits = (F >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask; + const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; + bool S = (F >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask; - if (isSigned) // if value is signed - return ~(-1U << (bits - 1)); - else - return ~(-1U << bits); + assert(HexagonMCInstrInfo::isExtendable(MCII, MCI) || + HexagonMCInstrInfo::isExtended(MCII, MCI)); + + if (S) // if value is signed + return (1 << (HexagonMCInstrInfo::getExtentBits(MCII, MCI) - 1)) - 1; + return (1 << HexagonMCInstrInfo::getExtentBits(MCII, MCI)) - 1; } -// Return the min value that a constant extendable operand can have -// without being extended. +/// Return the minimum value of an extendable operand. int HexagonMCInstrInfo::getMinValue(MCInstrInfo const &MCII, MCInst const &MCI) { - uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; - unsigned isSigned = - (F >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask; - unsigned bits = (F >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask; + const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; + bool S = (F >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask; - if (isSigned) // if value is signed - return -1U << (bits - 1); - else - return 0; + assert(HexagonMCInstrInfo::isExtendable(MCII, MCI) || + HexagonMCInstrInfo::isExtended(MCII, MCI)); + + if (S) // if value is signed + return -(1 << (HexagonMCInstrInfo::getExtentBits(MCII, MCI) - 1)); + return 0; } StringRef HexagonMCInstrInfo::getName(MCInstrInfo const &MCII, - MCInst const &MCI) { + MCInst const &MCI) { return MCII.getName(MCI.getOpcode()); } @@ -319,9 +355,7 @@ unsigned short HexagonMCInstrInfo::getNewValueOp(MCInstrInfo const &MCII, MCOperand const &HexagonMCInstrInfo::getNewValueOperand(MCInstrInfo const &MCII, MCInst const &MCI) { - uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; - unsigned const O = - (F >> HexagonII::NewValueOpPos) & HexagonII::NewValueOpMask; + unsigned O = HexagonMCInstrInfo::getNewValueOp(MCII, MCI); MCOperand const &MCO = MCI.getOperand(O); assert((HexagonMCInstrInfo::isNewValue(MCII, MCI) || @@ -349,45 +383,54 @@ HexagonMCInstrInfo::getNewValueOperand2(MCInstrInfo const &MCII, return (MCO); } -int HexagonMCInstrInfo::getSubTarget(MCInstrInfo const &MCII, - MCInst const &MCI) { - const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; - - HexagonII::SubTarget Target = static_cast<HexagonII::SubTarget>( - (F >> HexagonII::validSubTargetPos) & HexagonII::validSubTargetMask); - - switch (Target) { - default: - return Hexagon::ArchV4; - case HexagonII::HasV5SubT: - return Hexagon::ArchV5; - } -} - -// Return the Hexagon ISA class for the insn. +/// Return the Hexagon ISA class for the insn. unsigned HexagonMCInstrInfo::getType(MCInstrInfo const &MCII, MCInst const &MCI) { - const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; - + const uint64_t F = MCII.get(MCI.getOpcode()).TSFlags; return ((F >> HexagonII::TypePos) & HexagonII::TypeMask); } +/// Return the slots this instruction can execute out of unsigned HexagonMCInstrInfo::getUnits(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCInst const &MCI) { - const InstrItinerary *II = STI.getSchedModel().InstrItineraries; int SchedClass = HexagonMCInstrInfo::getDesc(MCII, MCI).getSchedClass(); return ((II[SchedClass].FirstStage + HexagonStages)->getUnits()); } -bool HexagonMCInstrInfo::hasImmExt(MCInst const &MCI) { +/// Return the slots this instruction consumes in addition to +/// the slot(s) it can execute out of + +unsigned HexagonMCInstrInfo::getOtherReservedSlots(MCInstrInfo const &MCII, + MCSubtargetInfo const &STI, + MCInst const &MCI) { + const InstrItinerary *II = STI.getSchedModel().InstrItineraries; + int SchedClass = HexagonMCInstrInfo::getDesc(MCII, MCI).getSchedClass(); + unsigned Slots = 0; + + // FirstStage are slots that this instruction can execute in. + // FirstStage+1 are slots that are also consumed by this instruction. + // For example: vmemu can only execute in slot 0 but also consumes slot 1. + for (unsigned Stage = II[SchedClass].FirstStage + 1; + Stage < II[SchedClass].LastStage; ++Stage) { + unsigned Units = (Stage + HexagonStages)->getUnits(); + if (Units > HexagonGetLastSlot()) + break; + // fyi: getUnits() will return 0x1, 0x2, 0x4 or 0x8 + Slots |= Units; + } + + // if 0 is returned, then no additional slots are consumed by this inst. + return Slots; +} + +bool HexagonMCInstrInfo::hasDuplex(MCInstrInfo const &MCII, MCInst const &MCI) { if (!HexagonMCInstrInfo::isBundle(MCI)) return false; - for (const auto &I : HexagonMCInstrInfo::bundleInstructions(MCI)) { - auto MI = I.getInst(); - if (isImmext(*MI)) + for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCII, MCI)) { + if (HexagonMCInstrInfo::isDuplex(MCII, I)) return true; } @@ -398,7 +441,19 @@ bool HexagonMCInstrInfo::hasExtenderForIndex(MCInst const &MCB, size_t Index) { return extenderForIndex(MCB, Index) != nullptr; } -// Return whether the instruction is a legal new-value producer. +bool HexagonMCInstrInfo::hasImmExt( MCInst const &MCI) { + if (!HexagonMCInstrInfo::isBundle(MCI)) + return false; + + for (const auto &I : HexagonMCInstrInfo::bundleInstructions(MCI)) { + if (isImmext(*I.getInst())) + return true; + } + + return false; +} + +/// Return whether the insn produces a value. bool HexagonMCInstrInfo::hasNewValue(MCInstrInfo const &MCII, MCInst const &MCI) { const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; @@ -418,46 +473,19 @@ MCInst const &HexagonMCInstrInfo::instruction(MCInst const &MCB, size_t Index) { return *MCB.getOperand(bundleInstructionsOffset + Index).getInst(); } +/// Return where the instruction is an accumulator. +bool HexagonMCInstrInfo::isAccumulator(MCInstrInfo const &MCII, + MCInst const &MCI) { + const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; + return ((F >> HexagonII::AccumulatorPos) & HexagonII::AccumulatorMask); +} + bool HexagonMCInstrInfo::isBundle(MCInst const &MCI) { auto Result = Hexagon::BUNDLE == MCI.getOpcode(); assert(!Result || (MCI.size() > 0 && MCI.getOperand(0).isImm())); return Result; } -// Return whether the insn is an actual insn. -bool HexagonMCInstrInfo::isCanon(MCInstrInfo const &MCII, MCInst const &MCI) { - return (!HexagonMCInstrInfo::getDesc(MCII, MCI).isPseudo() && - !HexagonMCInstrInfo::isPrefix(MCII, MCI) && - HexagonMCInstrInfo::getType(MCII, MCI) != HexagonII::TypeENDLOOP); -} - -bool HexagonMCInstrInfo::isCofMax1(MCInstrInfo const &MCII, MCInst const &MCI) { - const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; - return ((F >> HexagonII::CofMax1Pos) & HexagonII::CofMax1Mask); -} - -bool HexagonMCInstrInfo::isCompound(MCInstrInfo const &MCII, - MCInst const &MCI) { - return (getType(MCII, MCI) == HexagonII::TypeCOMPOUND); -} - -bool HexagonMCInstrInfo::isDblRegForSubInst(unsigned Reg) { - return ((Reg >= Hexagon::D0 && Reg <= Hexagon::D3) || - (Reg >= Hexagon::D8 && Reg <= Hexagon::D11)); -} - -bool HexagonMCInstrInfo::isDuplex(MCInstrInfo const &MCII, MCInst const &MCI) { - return HexagonII::TypeDUPLEX == HexagonMCInstrInfo::getType(MCII, MCI); -} - -// Return whether the instruction needs to be constant extended. -// 1) Always return true if the instruction has 'isExtended' flag set. -// -// isExtendable: -// 2) For immediate extended operands, return true only if the value is -// out-of-range. -// 3) For global address, always return true. - bool HexagonMCInstrInfo::isConstExtended(MCInstrInfo const &MCII, MCInst const &MCI) { if (HexagonMCInstrInfo::isExtended(MCII, MCI)) @@ -470,9 +498,9 @@ bool HexagonMCInstrInfo::isConstExtended(MCInstrInfo const &MCII, return true; // Branch insns are handled as necessary by relaxation. if ((HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeJ) || - (HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeCOMPOUND && + (HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeCJ && HexagonMCInstrInfo::getDesc(MCII, MCI).isBranch()) || - (HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeNV && + (HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeNCJ && HexagonMCInstrInfo::getDesc(MCII, MCI).isBranch())) return false; // Otherwise loop instructions and other CR insts are handled by relaxation @@ -492,6 +520,35 @@ bool HexagonMCInstrInfo::isConstExtended(MCInstrInfo const &MCII, return (MinValue > Value || Value > MaxValue); } +bool HexagonMCInstrInfo::isCanon(MCInstrInfo const &MCII, MCInst const &MCI) { + return !HexagonMCInstrInfo::getDesc(MCII, MCI).isPseudo() && + !HexagonMCInstrInfo::isPrefix(MCII, MCI); +} + +bool HexagonMCInstrInfo::isCofMax1(MCInstrInfo const &MCII, MCInst const &MCI) { + const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; + return ((F >> HexagonII::CofMax1Pos) & HexagonII::CofMax1Mask); +} + +bool HexagonMCInstrInfo::isCompound(MCInstrInfo const &MCII, + MCInst const &MCI) { + return (getType(MCII, MCI) == HexagonII::TypeCJ); +} + +bool HexagonMCInstrInfo::isCVINew(MCInstrInfo const &MCII, MCInst const &MCI) { + const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; + return ((F >> HexagonII::CVINewPos) & HexagonII::CVINewMask); +} + +bool HexagonMCInstrInfo::isDblRegForSubInst(unsigned Reg) { + return ((Reg >= Hexagon::D0 && Reg <= Hexagon::D3) || + (Reg >= Hexagon::D8 && Reg <= Hexagon::D11)); +} + +bool HexagonMCInstrInfo::isDuplex(MCInstrInfo const &MCII, MCInst const &MCI) { + return HexagonII::TypeDUPLEX == HexagonMCInstrInfo::getType(MCII, MCI); +} + bool HexagonMCInstrInfo::isExtendable(MCInstrInfo const &MCII, MCInst const &MCI) { uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; @@ -510,9 +567,7 @@ bool HexagonMCInstrInfo::isFloat(MCInstrInfo const &MCII, MCInst const &MCI) { } bool HexagonMCInstrInfo::isImmext(MCInst const &MCI) { - auto Op = MCI.getOpcode(); - return (Op == Hexagon::A4_ext_b || Op == Hexagon::A4_ext_c || - Op == Hexagon::A4_ext_g || Op == Hexagon::A4_ext); + return MCI.getOpcode() == Hexagon::A4_ext; } bool HexagonMCInstrInfo::isInnerLoop(MCInst const &MCI) { @@ -530,20 +585,17 @@ bool HexagonMCInstrInfo::isIntRegForSubInst(unsigned Reg) { (Reg >= Hexagon::R16 && Reg <= Hexagon::R23)); } -// Return whether the insn is a new-value consumer. +/// Return whether the insn expects newly produced value. bool HexagonMCInstrInfo::isNewValue(MCInstrInfo const &MCII, MCInst const &MCI) { const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; return ((F >> HexagonII::NewValuePos) & HexagonII::NewValueMask); } -// Return whether the operand can be constant extended. -bool HexagonMCInstrInfo::isOperandExtended(MCInstrInfo const &MCII, - MCInst const &MCI, - unsigned short OperandNum) { - uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; - return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask) == - OperandNum; +/// Return whether the operand is extendable. +bool HexagonMCInstrInfo::isOpExtendable(MCInstrInfo const &MCII, + MCInst const &MCI, unsigned short O) { + return (O == HexagonMCInstrInfo::getExtendableOp(MCII, MCI)); } bool HexagonMCInstrInfo::isOuterLoop(MCInst const &MCI) { @@ -558,6 +610,10 @@ bool HexagonMCInstrInfo::isPredicated(MCInstrInfo const &MCII, return ((F >> HexagonII::PredicatedPos) & HexagonII::PredicatedMask); } +bool HexagonMCInstrInfo::isPrefix(MCInstrInfo const &MCII, MCInst const &MCI) { + return HexagonII::TypeEXTENDER == HexagonMCInstrInfo::getType(MCII, MCI); +} + bool HexagonMCInstrInfo::isPredicateLate(MCInstrInfo const &MCII, MCInst const &MCI) { const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; @@ -582,12 +638,22 @@ bool HexagonMCInstrInfo::isPredReg(unsigned Reg) { return (Reg >= Hexagon::P0 && Reg <= Hexagon::P3_0); } -bool HexagonMCInstrInfo::isPrefix(MCInstrInfo const &MCII, MCInst const &MCI) { - return (HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypePREFIX); +/// Return whether the insn can be packaged only with A and X-type insns. +bool HexagonMCInstrInfo::isSoloAX(MCInstrInfo const &MCII, MCInst const &MCI) { + const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; + return ((F >> HexagonII::SoloAXPos) & HexagonII::SoloAXMask); } -bool HexagonMCInstrInfo::isSolo(MCInstrInfo const &MCII, MCInst const &MCI) { +/// Return whether the insn can be packaged only with an A-type insn in slot #1. +bool HexagonMCInstrInfo::isSoloAin1(MCInstrInfo const &MCII, + MCInst const &MCI) { const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; + return ((F >> HexagonII::SoloAin1Pos) & HexagonII::SoloAin1Mask); +} + +/// Return whether the insn is solo, i.e., cannot be in a packet. +bool HexagonMCInstrInfo::isSolo(MCInstrInfo const &MCII, MCInst const &MCI) { + const uint64_t F = MCII.get(MCI.getOpcode()).TSFlags; return ((F >> HexagonII::SoloPos) & HexagonII::SoloMask); } @@ -663,17 +729,6 @@ bool HexagonMCInstrInfo::isSubInstruction(MCInst const &MCI) { } } -bool HexagonMCInstrInfo::isSoloAX(MCInstrInfo const &MCII, MCInst const &MCI) { - const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; - return ((F >> HexagonII::SoloAXPos) & HexagonII::SoloAXMask); -} - -bool HexagonMCInstrInfo::isSoloAin1(MCInstrInfo const &MCII, - MCInst const &MCI) { - const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; - return ((F >> HexagonII::SoloAin1Pos) & HexagonII::SoloAin1Mask); -} - bool HexagonMCInstrInfo::isVector(MCInstrInfo const &MCII, MCInst const &MCI) { if ((getType(MCII, MCI) <= HexagonII::TypeCVI_LAST) && (getType(MCII, MCI) >= HexagonII::TypeCVI_FIRST)) @@ -705,16 +760,26 @@ bool HexagonMCInstrInfo::mustExtend(MCExpr const &Expr) { return HExpr.mustExtend(); } void HexagonMCInstrInfo::setMustNotExtend(MCExpr const &Expr, bool Val) { - HexagonMCExpr &HExpr = - const_cast<HexagonMCExpr &>(cast<HexagonMCExpr>(Expr)); + HexagonMCExpr &HExpr = const_cast<HexagonMCExpr &>(cast<HexagonMCExpr>(Expr)); HExpr.setMustNotExtend(Val); } bool HexagonMCInstrInfo::mustNotExtend(MCExpr const &Expr) { HexagonMCExpr const &HExpr = cast<HexagonMCExpr>(Expr); return HExpr.mustNotExtend(); } +void HexagonMCInstrInfo::setS27_2_reloc(MCExpr const &Expr, bool Val) { + HexagonMCExpr &HExpr = + const_cast<HexagonMCExpr &>(*llvm::cast<HexagonMCExpr>(&Expr)); + HExpr.setS27_2_reloc(Val); +} +bool HexagonMCInstrInfo::s27_2_reloc(MCExpr const &Expr) { + HexagonMCExpr const *HExpr = llvm::dyn_cast<HexagonMCExpr>(&Expr); + if (!HExpr) + return false; + return HExpr->s27_2_reloc(); +} -void HexagonMCInstrInfo::padEndloop(MCContext &Context, MCInst &MCB) { +void HexagonMCInstrInfo::padEndloop(MCInst &MCB, MCContext &Context) { MCInst Nop; Nop.setOpcode(Hexagon::A2_nop); assert(isBundle(MCB)); @@ -727,22 +792,8 @@ void HexagonMCInstrInfo::padEndloop(MCContext &Context, MCInst &MCB) { bool HexagonMCInstrInfo::prefersSlot3(MCInstrInfo const &MCII, MCInst const &MCI) { - if (HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeCR) - return false; - - unsigned SchedClass = HexagonMCInstrInfo::getDesc(MCII, MCI).getSchedClass(); - switch (SchedClass) { - case Hexagon::Sched::ALU32_3op_tc_2_SLOT0123: - case Hexagon::Sched::ALU64_tc_2_SLOT23: - case Hexagon::Sched::ALU64_tc_3x_SLOT23: - case Hexagon::Sched::M_tc_2_SLOT23: - case Hexagon::Sched::M_tc_3x_SLOT23: - case Hexagon::Sched::S_2op_tc_2_SLOT23: - case Hexagon::Sched::S_3op_tc_2_SLOT23: - case Hexagon::Sched::S_3op_tc_3x_SLOT23: - return true; - } - return false; + const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; + return (F >> HexagonII::PrefersSlot3Pos) & HexagonII::PrefersSlot3Mask; } void HexagonMCInstrInfo::replaceDuplex(MCContext &Context, MCInst &MCB, @@ -778,15 +829,6 @@ void HexagonMCInstrInfo::setMemStoreReorderEnabled(MCInst &MCI) { Operand.setImm(Operand.getImm() | memStoreReorderEnabledMask); assert(isMemStoreReorderEnabled(MCI)); } -void HexagonMCInstrInfo::setS23_2_reloc(MCExpr const &Expr, bool Val) { - HexagonMCExpr &HExpr = - const_cast<HexagonMCExpr &>(*llvm::cast<HexagonMCExpr>(&Expr)); - HExpr.setS23_2_reloc(Val); -} -bool HexagonMCInstrInfo::s23_2_reloc(MCExpr const &Expr) { - HexagonMCExpr const &HExpr = *llvm::cast<HexagonMCExpr>(&Expr); - return HExpr.s23_2_reloc(); -} void HexagonMCInstrInfo::setOuterLoop(MCInst &MCI) { assert(isBundle(MCI)); @@ -806,4 +848,4 @@ unsigned HexagonMCInstrInfo::SubregisterBit(unsigned Consumer, return 0x1; return 0; } -} +} // namespace llvm |