summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp')
-rw-r--r--llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp114
1 files changed, 78 insertions, 36 deletions
diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp
index 94919b1e486..19308cd425e 100644
--- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp
+++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp
@@ -33,6 +33,10 @@
using namespace llvm;
+bool HexagonMCInstrInfo::PredicateInfo::isPredicated() const {
+ return Register != Hexagon::NoRegister;
+}
+
Hexagon::PacketIterator::PacketIterator(MCInstrInfo const &MCII,
MCInst const &Inst)
: MCII(MCII), BundleCurrent(Inst.begin() +
@@ -50,6 +54,7 @@ Hexagon::PacketIterator &Hexagon::PacketIterator::operator++() {
if (DuplexCurrent == DuplexEnd) {
DuplexCurrent = BundleEnd;
DuplexEnd = BundleEnd;
+ ++BundleCurrent;
}
return *this;
}
@@ -90,6 +95,7 @@ void HexagonMCInstrInfo::addConstExtender(MCContext &Context,
// Create the extender.
MCInst *XMCI =
new (Context) MCInst(HexagonMCInstrInfo::deriveExtender(MCII, MCI, exOp));
+ XMCI->setLoc(MCI.getLoc());
MCB.addOperand(MCOperand::createInst(XMCI));
}
@@ -131,7 +137,7 @@ bool HexagonMCInstrInfo::canonicalizePacket(MCInstrInfo const &MCII,
// Examine the packet and convert pairs of instructions to duplex
// instructions when possible.
MCInst InstBundlePreDuplex = MCInst(MCB);
- if (!HexagonDisableDuplex) {
+ if (STI.getFeatureBits() [Hexagon::FeatureDuplex]) {
SmallVector<DuplexCandidate, 8> possibleDuplexes;
possibleDuplexes =
HexagonMCInstrInfo::getDuplexPossibilties(MCII, STI, MCB);
@@ -169,13 +175,6 @@ void HexagonMCInstrInfo::clampExtended(MCInstrInfo const &MCII,
}
}
-MCInst HexagonMCInstrInfo::createBundle() {
- MCInst Result;
- Result.setOpcode(Hexagon::BUNDLE);
- Result.addOperand(MCOperand::createImm(0));
- return Result;
-}
-
MCInst HexagonMCInstrInfo::deriveExtender(MCInstrInfo const &MCII,
MCInst const &Inst,
MCOperand const &MO) {
@@ -233,6 +232,13 @@ unsigned HexagonMCInstrInfo::getMemAccessSize(MCInstrInfo const &MCII,
return HexagonII::getMemAccessSizeInBytes(HexagonII::MemAccessSize(S));
}
+unsigned HexagonMCInstrInfo::getAddrMode(MCInstrInfo const &MCII,
+ MCInst const &MCI) {
+ const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
+ return static_cast<unsigned>((F >> HexagonII::AddrModePos) &
+ HexagonII::AddrModeMask);
+}
+
MCInstrDesc const &HexagonMCInstrInfo::getDesc(MCInstrInfo const &MCII,
MCInst const &MCI) {
return MCII.get(MCI.getOpcode());
@@ -365,13 +371,20 @@ unsigned short HexagonMCInstrInfo::getNewValueOp(MCInstrInfo const &MCII,
MCOperand const &HexagonMCInstrInfo::getNewValueOperand(MCInstrInfo const &MCII,
MCInst const &MCI) {
- unsigned O = HexagonMCInstrInfo::getNewValueOp(MCII, MCI);
- MCOperand const &MCO = MCI.getOperand(O);
-
- assert((HexagonMCInstrInfo::isNewValue(MCII, MCI) ||
- HexagonMCInstrInfo::hasNewValue(MCII, MCI)) &&
- MCO.isReg());
- return (MCO);
+ if (HexagonMCInstrInfo::hasTmpDst(MCII, MCI)) {
+ // VTMP doesn't actually exist in the encodings for these 184
+ // 3 instructions so go ahead and create it here.
+ static MCOperand MCO = MCOperand::createReg(Hexagon::VTMP);
+ return (MCO);
+ } else {
+ unsigned O = HexagonMCInstrInfo::getNewValueOp(MCII, MCI);
+ MCOperand const &MCO = MCI.getOperand(O);
+
+ assert((HexagonMCInstrInfo::isNewValue(MCII, MCI) ||
+ HexagonMCInstrInfo::hasNewValue(MCII, MCI)) &&
+ MCO.isReg());
+ return (MCO);
+ }
}
/// Return the new value or the newly produced value.
@@ -439,8 +452,8 @@ bool HexagonMCInstrInfo::hasDuplex(MCInstrInfo const &MCII, MCInst const &MCI) {
if (!HexagonMCInstrInfo::isBundle(MCI))
return false;
- for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCII, MCI)) {
- if (HexagonMCInstrInfo::isDuplex(MCII, I))
+ for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCI)) {
+ if (HexagonMCInstrInfo::isDuplex(MCII, *I.getInst()))
return true;
}
@@ -451,7 +464,7 @@ bool HexagonMCInstrInfo::hasExtenderForIndex(MCInst const &MCB, size_t Index) {
return extenderForIndex(MCB, Index) != nullptr;
}
-bool HexagonMCInstrInfo::hasImmExt( MCInst const &MCI) {
+bool HexagonMCInstrInfo::hasImmExt(MCInst const &MCI) {
if (!HexagonMCInstrInfo::isBundle(MCI))
return false;
@@ -540,6 +553,18 @@ bool HexagonMCInstrInfo::isCofMax1(MCInstrInfo const &MCII, MCInst const &MCI) {
return ((F >> HexagonII::CofMax1Pos) & HexagonII::CofMax1Mask);
}
+bool HexagonMCInstrInfo::isCofRelax1(MCInstrInfo const &MCII,
+ MCInst const &MCI) {
+ const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
+ return ((F >> HexagonII::CofRelax1Pos) & HexagonII::CofRelax1Mask);
+}
+
+bool HexagonMCInstrInfo::isCofRelax2(MCInstrInfo const &MCII,
+ MCInst const &MCI) {
+ const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
+ return ((F >> HexagonII::CofRelax2Pos) & HexagonII::CofRelax2Mask);
+}
+
bool HexagonMCInstrInfo::isCompound(MCInstrInfo const &MCII,
MCInst const &MCI) {
return (getType(MCII, MCI) == HexagonII::TypeCJ);
@@ -576,6 +601,11 @@ bool HexagonMCInstrInfo::isFloat(MCInstrInfo const &MCII, MCInst const &MCI) {
return ((F >> HexagonII::FPPos) & HexagonII::FPMask);
}
+bool HexagonMCInstrInfo::isHVX(MCInstrInfo const &MCII, MCInst const &MCI) {
+ const uint64_t V = getType(MCII, MCI);
+ return HexagonII::TypeCVI_FIRST <= V && V <= HexagonII::TypeCVI_LAST;
+}
+
bool HexagonMCInstrInfo::isImmext(MCInst const &MCI) {
return MCI.getOpcode() == Hexagon::A4_ext;
}
@@ -655,10 +685,18 @@ bool HexagonMCInstrInfo::isSoloAX(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) {
+bool HexagonMCInstrInfo::isRestrictSlot1AOK(MCInstrInfo const &MCII,
+ MCInst const &MCI) {
const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
- return ((F >> HexagonII::SoloAin1Pos) & HexagonII::SoloAin1Mask);
+ return ((F >> HexagonII::RestrictSlot1AOKPos) &
+ HexagonII::RestrictSlot1AOKMask);
+}
+
+bool HexagonMCInstrInfo::isRestrictNoSlot1Store(MCInstrInfo const &MCII,
+ MCInst const &MCI) {
+ const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
+ return ((F >> HexagonII::RestrictNoSlot1StorePos) &
+ HexagonII::RestrictNoSlot1StoreMask);
}
/// Return whether the insn is solo, i.e., cannot be in a packet.
@@ -673,12 +711,6 @@ bool HexagonMCInstrInfo::isMemReorderDisabled(MCInst const &MCI) {
return (Flags & memReorderDisabledMask) != 0;
}
-bool HexagonMCInstrInfo::isMemStoreReorderEnabled(MCInst const &MCI) {
- assert(isBundle(MCI));
- auto Flags = MCI.getOperand(0).getImm();
- return (Flags & memStoreReorderEnabledMask) != 0;
-}
-
bool HexagonMCInstrInfo::isSubInstruction(MCInst const &MCI) {
switch (MCI.getOpcode()) {
default:
@@ -800,12 +832,29 @@ void HexagonMCInstrInfo::padEndloop(MCInst &MCB, MCContext &Context) {
MCB.addOperand(MCOperand::createInst(new (Context) MCInst(Nop)));
}
+HexagonMCInstrInfo::PredicateInfo
+HexagonMCInstrInfo::predicateInfo(MCInstrInfo const &MCII, MCInst const &MCI) {
+ if (!isPredicated(MCII, MCI))
+ return {0, 0, false};
+ MCInstrDesc const &Desc = getDesc(MCII, MCI);
+ for (auto I = Desc.getNumDefs(), N = Desc.getNumOperands(); I != N; ++I)
+ if (Desc.OpInfo[I].RegClass == Hexagon::PredRegsRegClassID)
+ return {MCI.getOperand(I).getReg(), I, isPredicatedTrue(MCII, MCI)};
+ return {0, 0, false};
+}
+
bool HexagonMCInstrInfo::prefersSlot3(MCInstrInfo const &MCII,
MCInst const &MCI) {
const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
return (F >> HexagonII::PrefersSlot3Pos) & HexagonII::PrefersSlot3Mask;
}
+/// return true if instruction has hasTmpDst attribute.
+bool HexagonMCInstrInfo::hasTmpDst(MCInstrInfo const &MCII, MCInst const &MCI) {
+ const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
+ return (F >> HexagonII::HasTmpDstPos) & HexagonII::HasTmpDstMask;
+}
+
void HexagonMCInstrInfo::replaceDuplex(MCContext &Context, MCInst &MCB,
DuplexCandidate Candidate) {
assert(Candidate.packetIndexI < MCB.size());
@@ -833,13 +882,6 @@ void HexagonMCInstrInfo::setMemReorderDisabled(MCInst &MCI) {
assert(isMemReorderDisabled(MCI));
}
-void HexagonMCInstrInfo::setMemStoreReorderEnabled(MCInst &MCI) {
- assert(isBundle(MCI));
- MCOperand &Operand = MCI.getOperand(0);
- Operand.setImm(Operand.getImm() | memStoreReorderEnabledMask);
- assert(isMemStoreReorderEnabled(MCI));
-}
-
void HexagonMCInstrInfo::setOuterLoop(MCInst &MCI) {
assert(isBundle(MCI));
MCOperand &Operand = MCI.getOperand(0);
@@ -854,7 +896,7 @@ unsigned HexagonMCInstrInfo::SubregisterBit(unsigned Consumer,
if (Producer >= Hexagon::W0 && Producer <= Hexagon::W15)
if (Consumer >= Hexagon::V0 && Consumer <= Hexagon::V31)
return (Consumer - Hexagon::V0) & 0x1;
- if (Consumer == Producer2)
- return 0x1;
+ if (Producer2 != Hexagon::NoRegister)
+ return Consumer == Producer;
return 0;
}
OpenPOWER on IntegriCloud