xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp (revision 7a6dacaca14b62ca4b74406814becb87a3fefac0)
10b57cec5SDimitry Andric //===- HexagonMCInstrInfo.cpp - Hexagon sub-class of MCInst ---------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This class extends MCInstrInfo to allow Hexagon specific MCInstr queries
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "MCTargetDesc/HexagonMCInstrInfo.h"
140b57cec5SDimitry Andric #include "MCTargetDesc/HexagonBaseInfo.h"
150b57cec5SDimitry Andric #include "MCTargetDesc/HexagonMCChecker.h"
160b57cec5SDimitry Andric #include "MCTargetDesc/HexagonMCExpr.h"
170b57cec5SDimitry Andric #include "MCTargetDesc/HexagonMCShuffler.h"
180b57cec5SDimitry Andric #include "MCTargetDesc/HexagonMCTargetDesc.h"
190b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
205ffd83dbSDimitry Andric #include "llvm/ADT/StringSwitch.h"
210b57cec5SDimitry Andric #include "llvm/MC/MCContext.h"
220b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h"
230b57cec5SDimitry Andric #include "llvm/MC/MCInst.h"
240b57cec5SDimitry Andric #include "llvm/MC/MCInstrInfo.h"
250b57cec5SDimitry Andric #include "llvm/MC/MCInstrItineraries.h"
260b57cec5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
270b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
280b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
290b57cec5SDimitry Andric #include <cassert>
300b57cec5SDimitry Andric #include <cstdint>
310b57cec5SDimitry Andric #include <limits>
320b57cec5SDimitry Andric 
330b57cec5SDimitry Andric using namespace llvm;
340b57cec5SDimitry Andric 
isPredicated() const350b57cec5SDimitry Andric bool HexagonMCInstrInfo::PredicateInfo::isPredicated() const {
360b57cec5SDimitry Andric   return Register != Hexagon::NoRegister;
370b57cec5SDimitry Andric }
380b57cec5SDimitry Andric 
PacketIterator(MCInstrInfo const & MCII,MCInst const & Inst)390b57cec5SDimitry Andric Hexagon::PacketIterator::PacketIterator(MCInstrInfo const &MCII,
400b57cec5SDimitry Andric                                         MCInst const &Inst)
410b57cec5SDimitry Andric     : MCII(MCII), BundleCurrent(Inst.begin() +
420b57cec5SDimitry Andric                                 HexagonMCInstrInfo::bundleInstructionsOffset),
430b57cec5SDimitry Andric       BundleEnd(Inst.end()), DuplexCurrent(Inst.end()), DuplexEnd(Inst.end()) {}
440b57cec5SDimitry Andric 
PacketIterator(MCInstrInfo const & MCII,MCInst const & Inst,std::nullptr_t)450b57cec5SDimitry Andric Hexagon::PacketIterator::PacketIterator(MCInstrInfo const &MCII,
460b57cec5SDimitry Andric                                         MCInst const &Inst, std::nullptr_t)
470b57cec5SDimitry Andric     : MCII(MCII), BundleCurrent(Inst.end()), BundleEnd(Inst.end()),
480b57cec5SDimitry Andric       DuplexCurrent(Inst.end()), DuplexEnd(Inst.end()) {}
490b57cec5SDimitry Andric 
operator ++()500b57cec5SDimitry Andric Hexagon::PacketIterator &Hexagon::PacketIterator::operator++() {
510b57cec5SDimitry Andric   if (DuplexCurrent != DuplexEnd) {
520b57cec5SDimitry Andric     ++DuplexCurrent;
530b57cec5SDimitry Andric     if (DuplexCurrent == DuplexEnd) {
540b57cec5SDimitry Andric       DuplexCurrent = BundleEnd;
550b57cec5SDimitry Andric       DuplexEnd = BundleEnd;
560b57cec5SDimitry Andric       ++BundleCurrent;
570b57cec5SDimitry Andric     }
580b57cec5SDimitry Andric     return *this;
590b57cec5SDimitry Andric   }
600b57cec5SDimitry Andric   ++BundleCurrent;
610b57cec5SDimitry Andric   if (BundleCurrent != BundleEnd) {
620b57cec5SDimitry Andric     MCInst const &Inst = *BundleCurrent->getInst();
630b57cec5SDimitry Andric     if (HexagonMCInstrInfo::isDuplex(MCII, Inst)) {
640b57cec5SDimitry Andric       DuplexCurrent = Inst.begin();
650b57cec5SDimitry Andric       DuplexEnd = Inst.end();
660b57cec5SDimitry Andric     }
670b57cec5SDimitry Andric   }
680b57cec5SDimitry Andric   return *this;
690b57cec5SDimitry Andric }
700b57cec5SDimitry Andric 
operator *() const710b57cec5SDimitry Andric MCInst const &Hexagon::PacketIterator::operator*() const {
720b57cec5SDimitry Andric   if (DuplexCurrent != DuplexEnd)
730b57cec5SDimitry Andric     return *DuplexCurrent->getInst();
740b57cec5SDimitry Andric   return *BundleCurrent->getInst();
750b57cec5SDimitry Andric }
760b57cec5SDimitry Andric 
operator ==(PacketIterator const & Other) const770b57cec5SDimitry Andric bool Hexagon::PacketIterator::operator==(PacketIterator const &Other) const {
780b57cec5SDimitry Andric   return BundleCurrent == Other.BundleCurrent && BundleEnd == Other.BundleEnd &&
790b57cec5SDimitry Andric          DuplexCurrent == Other.DuplexCurrent && DuplexEnd == Other.DuplexEnd;
800b57cec5SDimitry Andric }
810b57cec5SDimitry Andric 
addConstant(MCInst & MI,uint64_t Value,MCContext & Context)820b57cec5SDimitry Andric void HexagonMCInstrInfo::addConstant(MCInst &MI, uint64_t Value,
830b57cec5SDimitry Andric                                      MCContext &Context) {
840b57cec5SDimitry Andric   MI.addOperand(MCOperand::createExpr(MCConstantExpr::create(Value, Context)));
850b57cec5SDimitry Andric }
860b57cec5SDimitry Andric 
addConstExtender(MCContext & Context,MCInstrInfo const & MCII,MCInst & MCB,MCInst const & MCI)870b57cec5SDimitry Andric void HexagonMCInstrInfo::addConstExtender(MCContext &Context,
880b57cec5SDimitry Andric                                           MCInstrInfo const &MCII, MCInst &MCB,
890b57cec5SDimitry Andric                                           MCInst const &MCI) {
900b57cec5SDimitry Andric   assert(HexagonMCInstrInfo::isBundle(MCB));
910b57cec5SDimitry Andric   MCOperand const &exOp =
920b57cec5SDimitry Andric       MCI.getOperand(HexagonMCInstrInfo::getExtendableOp(MCII, MCI));
930b57cec5SDimitry Andric 
940b57cec5SDimitry Andric   // Create the extender.
950b57cec5SDimitry Andric   MCInst *XMCI =
960b57cec5SDimitry Andric       new (Context) MCInst(HexagonMCInstrInfo::deriveExtender(MCII, MCI, exOp));
970b57cec5SDimitry Andric   XMCI->setLoc(MCI.getLoc());
980b57cec5SDimitry Andric 
990b57cec5SDimitry Andric   MCB.addOperand(MCOperand::createInst(XMCI));
1000b57cec5SDimitry Andric }
1010b57cec5SDimitry Andric 
1020b57cec5SDimitry Andric iterator_range<Hexagon::PacketIterator>
bundleInstructions(MCInstrInfo const & MCII,MCInst const & MCI)1030b57cec5SDimitry Andric HexagonMCInstrInfo::bundleInstructions(MCInstrInfo const &MCII,
1040b57cec5SDimitry Andric                                        MCInst const &MCI) {
1050b57cec5SDimitry Andric   assert(isBundle(MCI));
1060b57cec5SDimitry Andric   return make_range(Hexagon::PacketIterator(MCII, MCI),
1070b57cec5SDimitry Andric                     Hexagon::PacketIterator(MCII, MCI, nullptr));
1080b57cec5SDimitry Andric }
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric iterator_range<MCInst::const_iterator>
bundleInstructions(MCInst const & MCI)1110b57cec5SDimitry Andric HexagonMCInstrInfo::bundleInstructions(MCInst const &MCI) {
1120b57cec5SDimitry Andric   assert(isBundle(MCI));
113e8d8bef9SDimitry Andric   return drop_begin(MCI, bundleInstructionsOffset);
1140b57cec5SDimitry Andric }
1150b57cec5SDimitry Andric 
bundleSize(MCInst const & MCI)1160b57cec5SDimitry Andric size_t HexagonMCInstrInfo::bundleSize(MCInst const &MCI) {
1170b57cec5SDimitry Andric   if (HexagonMCInstrInfo::isBundle(MCI))
1180b57cec5SDimitry Andric     return (MCI.size() - bundleInstructionsOffset);
1190b57cec5SDimitry Andric   else
1200b57cec5SDimitry Andric     return (1);
1210b57cec5SDimitry Andric }
1220b57cec5SDimitry Andric 
1235ffd83dbSDimitry Andric namespace {
canonicalizePacketImpl(MCInstrInfo const & MCII,MCSubtargetInfo const & STI,MCContext & Context,MCInst & MCB,HexagonMCChecker * Check)1245ffd83dbSDimitry Andric bool canonicalizePacketImpl(MCInstrInfo const &MCII, MCSubtargetInfo const &STI,
1250b57cec5SDimitry Andric                             MCContext &Context, MCInst &MCB,
1260b57cec5SDimitry Andric                             HexagonMCChecker *Check) {
1270b57cec5SDimitry Andric   // Check the bundle for errors.
1280b57cec5SDimitry Andric   bool CheckOk = Check ? Check->check(false) : true;
1290b57cec5SDimitry Andric   if (!CheckOk)
1300b57cec5SDimitry Andric     return false;
13104eeddc0SDimitry Andric 
13204eeddc0SDimitry Andric   MCInst OrigMCB = MCB;
13304eeddc0SDimitry Andric 
1340b57cec5SDimitry Andric   // Examine the packet and convert pairs of instructions to compound
1350b57cec5SDimitry Andric   // instructions when possible.
1360b57cec5SDimitry Andric   if (!HexagonDisableCompound)
1370b57cec5SDimitry Andric     HexagonMCInstrInfo::tryCompound(MCII, STI, Context, MCB);
1380b57cec5SDimitry Andric   HexagonMCShuffle(Context, false, MCII, STI, MCB);
1395ffd83dbSDimitry Andric 
14004eeddc0SDimitry Andric   const SmallVector<DuplexCandidate, 8> possibleDuplexes =
14106c3fb27SDimitry Andric       (STI.hasFeature(Hexagon::FeatureDuplex))
14204eeddc0SDimitry Andric           ? HexagonMCInstrInfo::getDuplexPossibilties(MCII, STI, MCB)
14304eeddc0SDimitry Andric           : SmallVector<DuplexCandidate, 8>();
14404eeddc0SDimitry Andric 
1450b57cec5SDimitry Andric   // Examine the packet and convert pairs of instructions to duplex
1460b57cec5SDimitry Andric   // instructions when possible.
1470b57cec5SDimitry Andric   HexagonMCShuffle(Context, MCII, STI, MCB, possibleDuplexes);
14804eeddc0SDimitry Andric 
1490b57cec5SDimitry Andric   // Examines packet and pad the packet, if needed, when an
1500b57cec5SDimitry Andric   // end-loop is in the bundle.
1510b57cec5SDimitry Andric   HexagonMCInstrInfo::padEndloop(MCB, Context);
15204eeddc0SDimitry Andric 
1530b57cec5SDimitry Andric   // If compounding and duplexing didn't reduce the size below
1540b57cec5SDimitry Andric   // 4 or less we have a packet that is too big.
1555ffd83dbSDimitry Andric   if (HexagonMCInstrInfo::bundleSize(MCB) > HEXAGON_PACKET_SIZE) {
1565ffd83dbSDimitry Andric     if (Check)
1575ffd83dbSDimitry Andric       Check->reportError("invalid instruction packet: out of slots");
1580b57cec5SDimitry Andric     return false;
1595ffd83dbSDimitry Andric   }
1600b57cec5SDimitry Andric   // Check the bundle for errors.
1610b57cec5SDimitry Andric   CheckOk = Check ? Check->check(true) : true;
1620b57cec5SDimitry Andric   if (!CheckOk)
1630b57cec5SDimitry Andric     return false;
16404eeddc0SDimitry Andric 
1650b57cec5SDimitry Andric   HexagonMCShuffle(Context, true, MCII, STI, MCB);
16604eeddc0SDimitry Andric 
1670b57cec5SDimitry Andric   return true;
1680b57cec5SDimitry Andric }
1695ffd83dbSDimitry Andric } // namespace
1705ffd83dbSDimitry Andric 
canonicalizePacket(MCInstrInfo const & MCII,MCSubtargetInfo const & STI,MCContext & Context,MCInst & MCB,HexagonMCChecker * Check,bool AttemptCompatibility)1715ffd83dbSDimitry Andric bool HexagonMCInstrInfo::canonicalizePacket(MCInstrInfo const &MCII,
1725ffd83dbSDimitry Andric                                             MCSubtargetInfo const &STI,
1735ffd83dbSDimitry Andric                                             MCContext &Context, MCInst &MCB,
1745ffd83dbSDimitry Andric                                             HexagonMCChecker *Check,
1755ffd83dbSDimitry Andric                                             bool AttemptCompatibility) {
1765ffd83dbSDimitry Andric   auto ArchSTI = Hexagon_MC::getArchSubtarget(&STI);
1775ffd83dbSDimitry Andric   if (!AttemptCompatibility || ArchSTI == nullptr)
1785ffd83dbSDimitry Andric     return canonicalizePacketImpl(MCII, STI, Context, MCB, Check);
1795ffd83dbSDimitry Andric 
1805ffd83dbSDimitry Andric   const MCRegisterInfo *RI = Context.getRegisterInfo();
1815ffd83dbSDimitry Andric   HexagonMCChecker DefaultCheck(Context, MCII, STI, MCB, *RI, false);
1825ffd83dbSDimitry Andric   HexagonMCChecker *BaseCheck = (Check == nullptr) ? &DefaultCheck : Check;
1835ffd83dbSDimitry Andric   HexagonMCChecker PerfCheck(*BaseCheck, STI, false);
1845ffd83dbSDimitry Andric   if (canonicalizePacketImpl(MCII, STI, Context, MCB, &PerfCheck))
1855ffd83dbSDimitry Andric     return true;
1865ffd83dbSDimitry Andric 
1875ffd83dbSDimitry Andric   HexagonMCChecker ArchCheck(*BaseCheck, *ArchSTI, true);
1885ffd83dbSDimitry Andric   return canonicalizePacketImpl(MCII, *ArchSTI, Context, MCB, &ArchCheck);
1895ffd83dbSDimitry Andric }
1900b57cec5SDimitry Andric 
deriveExtender(MCInstrInfo const & MCII,MCInst const & Inst,MCOperand const & MO)1910b57cec5SDimitry Andric MCInst HexagonMCInstrInfo::deriveExtender(MCInstrInfo const &MCII,
1920b57cec5SDimitry Andric                                           MCInst const &Inst,
1930b57cec5SDimitry Andric                                           MCOperand const &MO) {
1940b57cec5SDimitry Andric   assert(HexagonMCInstrInfo::isExtendable(MCII, Inst) ||
1950b57cec5SDimitry Andric          HexagonMCInstrInfo::isExtended(MCII, Inst));
1960b57cec5SDimitry Andric 
1970b57cec5SDimitry Andric   MCInst XMI;
1980b57cec5SDimitry Andric   XMI.setOpcode(Hexagon::A4_ext);
1990b57cec5SDimitry Andric   if (MO.isImm())
2000b57cec5SDimitry Andric     XMI.addOperand(MCOperand::createImm(MO.getImm() & (~0x3f)));
2010b57cec5SDimitry Andric   else if (MO.isExpr())
2020b57cec5SDimitry Andric     XMI.addOperand(MCOperand::createExpr(MO.getExpr()));
2030b57cec5SDimitry Andric   else
2040b57cec5SDimitry Andric     llvm_unreachable("invalid extendable operand");
2050b57cec5SDimitry Andric   return XMI;
2060b57cec5SDimitry Andric }
2070b57cec5SDimitry Andric 
deriveDuplex(MCContext & Context,unsigned iClass,MCInst const & inst0,MCInst const & inst1)2080b57cec5SDimitry Andric MCInst *HexagonMCInstrInfo::deriveDuplex(MCContext &Context, unsigned iClass,
2090b57cec5SDimitry Andric                                          MCInst const &inst0,
2100b57cec5SDimitry Andric                                          MCInst const &inst1) {
2110b57cec5SDimitry Andric   assert((iClass <= 0xf) && "iClass must have range of 0 to 0xf");
2120b57cec5SDimitry Andric   MCInst *duplexInst = new (Context) MCInst;
2130b57cec5SDimitry Andric   duplexInst->setOpcode(Hexagon::DuplexIClass0 + iClass);
2140b57cec5SDimitry Andric 
2150b57cec5SDimitry Andric   MCInst *SubInst0 = new (Context) MCInst(deriveSubInst(inst0));
2160b57cec5SDimitry Andric   MCInst *SubInst1 = new (Context) MCInst(deriveSubInst(inst1));
2170b57cec5SDimitry Andric   duplexInst->addOperand(MCOperand::createInst(SubInst0));
2180b57cec5SDimitry Andric   duplexInst->addOperand(MCOperand::createInst(SubInst1));
2190b57cec5SDimitry Andric   return duplexInst;
2200b57cec5SDimitry Andric }
2210b57cec5SDimitry Andric 
extenderForIndex(MCInst const & MCB,size_t Index)2220b57cec5SDimitry Andric MCInst const *HexagonMCInstrInfo::extenderForIndex(MCInst const &MCB,
2230b57cec5SDimitry Andric                                                    size_t Index) {
2240b57cec5SDimitry Andric   assert(Index <= bundleSize(MCB));
2250b57cec5SDimitry Andric   if (Index == 0)
2260b57cec5SDimitry Andric     return nullptr;
2270b57cec5SDimitry Andric   MCInst const *Inst =
2280b57cec5SDimitry Andric       MCB.getOperand(Index + bundleInstructionsOffset - 1).getInst();
2290b57cec5SDimitry Andric   if (isImmext(*Inst))
2300b57cec5SDimitry Andric     return Inst;
2310b57cec5SDimitry Andric   return nullptr;
2320b57cec5SDimitry Andric }
2330b57cec5SDimitry Andric 
extendIfNeeded(MCContext & Context,MCInstrInfo const & MCII,MCInst & MCB,MCInst const & MCI)2340b57cec5SDimitry Andric void HexagonMCInstrInfo::extendIfNeeded(MCContext &Context,
2350b57cec5SDimitry Andric                                         MCInstrInfo const &MCII, MCInst &MCB,
2360b57cec5SDimitry Andric                                         MCInst const &MCI) {
2370b57cec5SDimitry Andric   if (isConstExtended(MCII, MCI))
2380b57cec5SDimitry Andric     addConstExtender(Context, MCII, MCB, MCI);
2390b57cec5SDimitry Andric }
2400b57cec5SDimitry Andric 
getMemAccessSize(MCInstrInfo const & MCII,MCInst const & MCI)2410b57cec5SDimitry Andric unsigned HexagonMCInstrInfo::getMemAccessSize(MCInstrInfo const &MCII,
2420b57cec5SDimitry Andric       MCInst const &MCI) {
2430b57cec5SDimitry Andric   uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
2440b57cec5SDimitry Andric   unsigned S = (F >> HexagonII::MemAccessSizePos) & HexagonII::MemAccesSizeMask;
2450b57cec5SDimitry Andric   return HexagonII::getMemAccessSizeInBytes(HexagonII::MemAccessSize(S));
2460b57cec5SDimitry Andric }
2470b57cec5SDimitry Andric 
getAddrMode(MCInstrInfo const & MCII,MCInst const & MCI)2480b57cec5SDimitry Andric unsigned HexagonMCInstrInfo::getAddrMode(MCInstrInfo const &MCII,
2490b57cec5SDimitry Andric                                          MCInst const &MCI) {
2500b57cec5SDimitry Andric   const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
2510b57cec5SDimitry Andric   return static_cast<unsigned>((F >> HexagonII::AddrModePos) &
2520b57cec5SDimitry Andric                                HexagonII::AddrModeMask);
2530b57cec5SDimitry Andric }
2540b57cec5SDimitry Andric 
getDesc(MCInstrInfo const & MCII,MCInst const & MCI)2550b57cec5SDimitry Andric MCInstrDesc const &HexagonMCInstrInfo::getDesc(MCInstrInfo const &MCII,
2560b57cec5SDimitry Andric                                                MCInst const &MCI) {
2570b57cec5SDimitry Andric   return MCII.get(MCI.getOpcode());
2580b57cec5SDimitry Andric }
2590b57cec5SDimitry Andric 
getDuplexRegisterNumbering(unsigned Reg)2600b57cec5SDimitry Andric unsigned HexagonMCInstrInfo::getDuplexRegisterNumbering(unsigned Reg) {
2610b57cec5SDimitry Andric   using namespace Hexagon;
2620b57cec5SDimitry Andric 
2630b57cec5SDimitry Andric   switch (Reg) {
2640b57cec5SDimitry Andric   default:
2650b57cec5SDimitry Andric     llvm_unreachable("unknown duplex register");
2660b57cec5SDimitry Andric   // Rs       Rss
2670b57cec5SDimitry Andric   case R0:
2680b57cec5SDimitry Andric   case D0:
2690b57cec5SDimitry Andric     return 0;
2700b57cec5SDimitry Andric   case R1:
2710b57cec5SDimitry Andric   case D1:
2720b57cec5SDimitry Andric     return 1;
2730b57cec5SDimitry Andric   case R2:
2740b57cec5SDimitry Andric   case D2:
2750b57cec5SDimitry Andric     return 2;
2760b57cec5SDimitry Andric   case R3:
2770b57cec5SDimitry Andric   case D3:
2780b57cec5SDimitry Andric     return 3;
2790b57cec5SDimitry Andric   case R4:
2800b57cec5SDimitry Andric   case D8:
2810b57cec5SDimitry Andric     return 4;
2820b57cec5SDimitry Andric   case R5:
2830b57cec5SDimitry Andric   case D9:
2840b57cec5SDimitry Andric     return 5;
2850b57cec5SDimitry Andric   case R6:
2860b57cec5SDimitry Andric   case D10:
2870b57cec5SDimitry Andric     return 6;
2880b57cec5SDimitry Andric   case R7:
2890b57cec5SDimitry Andric   case D11:
2900b57cec5SDimitry Andric     return 7;
2910b57cec5SDimitry Andric   case R16:
2920b57cec5SDimitry Andric     return 8;
2930b57cec5SDimitry Andric   case R17:
2940b57cec5SDimitry Andric     return 9;
2950b57cec5SDimitry Andric   case R18:
2960b57cec5SDimitry Andric     return 10;
2970b57cec5SDimitry Andric   case R19:
2980b57cec5SDimitry Andric     return 11;
2990b57cec5SDimitry Andric   case R20:
3000b57cec5SDimitry Andric     return 12;
3010b57cec5SDimitry Andric   case R21:
3020b57cec5SDimitry Andric     return 13;
3030b57cec5SDimitry Andric   case R22:
3040b57cec5SDimitry Andric     return 14;
3050b57cec5SDimitry Andric   case R23:
3060b57cec5SDimitry Andric     return 15;
3070b57cec5SDimitry Andric   }
3080b57cec5SDimitry Andric }
3090b57cec5SDimitry Andric 
getExpr(MCExpr const & Expr)3100b57cec5SDimitry Andric MCExpr const &HexagonMCInstrInfo::getExpr(MCExpr const &Expr) {
3110b57cec5SDimitry Andric   const auto &HExpr = cast<HexagonMCExpr>(Expr);
3120b57cec5SDimitry Andric   assert(HExpr.getExpr());
3130b57cec5SDimitry Andric   return *HExpr.getExpr();
3140b57cec5SDimitry Andric }
3150b57cec5SDimitry Andric 
getExtendableOp(MCInstrInfo const & MCII,MCInst const & MCI)3160b57cec5SDimitry Andric unsigned short HexagonMCInstrInfo::getExtendableOp(MCInstrInfo const &MCII,
3170b57cec5SDimitry Andric                                                    MCInst const &MCI) {
3180b57cec5SDimitry Andric   const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
3190b57cec5SDimitry Andric   return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask);
3200b57cec5SDimitry Andric }
3210b57cec5SDimitry Andric 
3220b57cec5SDimitry Andric MCOperand const &
getExtendableOperand(MCInstrInfo const & MCII,MCInst const & MCI)3230b57cec5SDimitry Andric HexagonMCInstrInfo::getExtendableOperand(MCInstrInfo const &MCII,
3240b57cec5SDimitry Andric                                          MCInst const &MCI) {
3250b57cec5SDimitry Andric   unsigned O = HexagonMCInstrInfo::getExtendableOp(MCII, MCI);
3260b57cec5SDimitry Andric   MCOperand const &MO = MCI.getOperand(O);
3270b57cec5SDimitry Andric 
3280b57cec5SDimitry Andric   assert((HexagonMCInstrInfo::isExtendable(MCII, MCI) ||
3290b57cec5SDimitry Andric           HexagonMCInstrInfo::isExtended(MCII, MCI)) &&
3300b57cec5SDimitry Andric          (MO.isImm() || MO.isExpr()));
3310b57cec5SDimitry Andric   return (MO);
3320b57cec5SDimitry Andric }
3330b57cec5SDimitry Andric 
getExtentAlignment(MCInstrInfo const & MCII,MCInst const & MCI)3340b57cec5SDimitry Andric unsigned HexagonMCInstrInfo::getExtentAlignment(MCInstrInfo const &MCII,
3350b57cec5SDimitry Andric                                                 MCInst const &MCI) {
3360b57cec5SDimitry Andric   const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
3370b57cec5SDimitry Andric   return ((F >> HexagonII::ExtentAlignPos) & HexagonII::ExtentAlignMask);
3380b57cec5SDimitry Andric }
3390b57cec5SDimitry Andric 
getExtentBits(MCInstrInfo const & MCII,MCInst const & MCI)3400b57cec5SDimitry Andric unsigned HexagonMCInstrInfo::getExtentBits(MCInstrInfo const &MCII,
3410b57cec5SDimitry Andric                                            MCInst const &MCI) {
3420b57cec5SDimitry Andric   const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
3430b57cec5SDimitry Andric   return ((F >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask);
3440b57cec5SDimitry Andric }
3450b57cec5SDimitry Andric 
isExtentSigned(MCInstrInfo const & MCII,MCInst const & MCI)3460b57cec5SDimitry Andric bool HexagonMCInstrInfo::isExtentSigned(MCInstrInfo const &MCII,
3470b57cec5SDimitry Andric                                         MCInst const &MCI) {
3480b57cec5SDimitry Andric   const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
3490b57cec5SDimitry Andric   return (F >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask;
3500b57cec5SDimitry Andric }
3510b57cec5SDimitry Andric 
3520b57cec5SDimitry Andric /// Return the maximum value of an extendable operand.
getMaxValue(MCInstrInfo const & MCII,MCInst const & MCI)3530b57cec5SDimitry Andric int HexagonMCInstrInfo::getMaxValue(MCInstrInfo const &MCII,
3540b57cec5SDimitry Andric                                     MCInst const &MCI) {
3550b57cec5SDimitry Andric   assert(HexagonMCInstrInfo::isExtendable(MCII, MCI) ||
3560b57cec5SDimitry Andric          HexagonMCInstrInfo::isExtended(MCII, MCI));
3570b57cec5SDimitry Andric 
3580b57cec5SDimitry Andric   if (HexagonMCInstrInfo::isExtentSigned(MCII, MCI)) // if value is signed
3590b57cec5SDimitry Andric     return (1 << (HexagonMCInstrInfo::getExtentBits(MCII, MCI) - 1)) - 1;
3600b57cec5SDimitry Andric   return (1 << HexagonMCInstrInfo::getExtentBits(MCII, MCI)) - 1;
3610b57cec5SDimitry Andric }
3620b57cec5SDimitry Andric 
3630b57cec5SDimitry Andric /// Return the minimum value of an extendable operand.
getMinValue(MCInstrInfo const & MCII,MCInst const & MCI)3640b57cec5SDimitry Andric int HexagonMCInstrInfo::getMinValue(MCInstrInfo const &MCII,
3650b57cec5SDimitry Andric                                     MCInst const &MCI) {
3660b57cec5SDimitry Andric   assert(HexagonMCInstrInfo::isExtendable(MCII, MCI) ||
3670b57cec5SDimitry Andric          HexagonMCInstrInfo::isExtended(MCII, MCI));
3680b57cec5SDimitry Andric 
3690b57cec5SDimitry Andric   if (HexagonMCInstrInfo::isExtentSigned(MCII, MCI)) // if value is signed
3700b57cec5SDimitry Andric     return -(1 << (HexagonMCInstrInfo::getExtentBits(MCII, MCI) - 1));
3710b57cec5SDimitry Andric   return 0;
3720b57cec5SDimitry Andric }
3730b57cec5SDimitry Andric 
getName(MCInstrInfo const & MCII,MCInst const & MCI)3740b57cec5SDimitry Andric StringRef HexagonMCInstrInfo::getName(MCInstrInfo const &MCII,
3750b57cec5SDimitry Andric                                       MCInst const &MCI) {
3760b57cec5SDimitry Andric   return MCII.getName(MCI.getOpcode());
3770b57cec5SDimitry Andric }
3780b57cec5SDimitry Andric 
getNewValueOp(MCInstrInfo const & MCII,MCInst const & MCI)3790b57cec5SDimitry Andric unsigned short HexagonMCInstrInfo::getNewValueOp(MCInstrInfo const &MCII,
3800b57cec5SDimitry Andric                                                  MCInst const &MCI) {
3810b57cec5SDimitry Andric   const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
3820b57cec5SDimitry Andric   return ((F >> HexagonII::NewValueOpPos) & HexagonII::NewValueOpMask);
3830b57cec5SDimitry Andric }
3840b57cec5SDimitry Andric 
getNewValueOperand(MCInstrInfo const & MCII,MCInst const & MCI)3850b57cec5SDimitry Andric MCOperand const &HexagonMCInstrInfo::getNewValueOperand(MCInstrInfo const &MCII,
3860b57cec5SDimitry Andric                                                         MCInst const &MCI) {
3870b57cec5SDimitry Andric   if (HexagonMCInstrInfo::hasTmpDst(MCII, MCI)) {
3880b57cec5SDimitry Andric     // VTMP doesn't actually exist in the encodings for these 184
3890b57cec5SDimitry Andric     // 3 instructions so go ahead and create it here.
3900b57cec5SDimitry Andric     static MCOperand MCO = MCOperand::createReg(Hexagon::VTMP);
3910b57cec5SDimitry Andric     return (MCO);
3920b57cec5SDimitry Andric   } else {
3930b57cec5SDimitry Andric     unsigned O = HexagonMCInstrInfo::getNewValueOp(MCII, MCI);
3940b57cec5SDimitry Andric     MCOperand const &MCO = MCI.getOperand(O);
3950b57cec5SDimitry Andric 
3960b57cec5SDimitry Andric     assert((HexagonMCInstrInfo::isNewValue(MCII, MCI) ||
3970b57cec5SDimitry Andric             HexagonMCInstrInfo::hasNewValue(MCII, MCI)) &&
3980b57cec5SDimitry Andric            MCO.isReg());
3990b57cec5SDimitry Andric     return (MCO);
4000b57cec5SDimitry Andric   }
4010b57cec5SDimitry Andric }
4020b57cec5SDimitry Andric 
4030b57cec5SDimitry Andric /// Return the new value or the newly produced value.
getNewValueOp2(MCInstrInfo const & MCII,MCInst const & MCI)4040b57cec5SDimitry Andric unsigned short HexagonMCInstrInfo::getNewValueOp2(MCInstrInfo const &MCII,
4050b57cec5SDimitry Andric                                                   MCInst const &MCI) {
4060b57cec5SDimitry Andric   const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
4070b57cec5SDimitry Andric   return ((F >> HexagonII::NewValueOpPos2) & HexagonII::NewValueOpMask2);
4080b57cec5SDimitry Andric }
4090b57cec5SDimitry Andric 
4100b57cec5SDimitry Andric MCOperand const &
getNewValueOperand2(MCInstrInfo const & MCII,MCInst const & MCI)4110b57cec5SDimitry Andric HexagonMCInstrInfo::getNewValueOperand2(MCInstrInfo const &MCII,
4120b57cec5SDimitry Andric                                         MCInst const &MCI) {
4130b57cec5SDimitry Andric   unsigned O = HexagonMCInstrInfo::getNewValueOp2(MCII, MCI);
4140b57cec5SDimitry Andric   MCOperand const &MCO = MCI.getOperand(O);
4150b57cec5SDimitry Andric 
4160b57cec5SDimitry Andric   assert((HexagonMCInstrInfo::isNewValue(MCII, MCI) ||
4170b57cec5SDimitry Andric           HexagonMCInstrInfo::hasNewValue2(MCII, MCI)) &&
4180b57cec5SDimitry Andric          MCO.isReg());
4190b57cec5SDimitry Andric   return (MCO);
4200b57cec5SDimitry Andric }
4210b57cec5SDimitry Andric 
4220b57cec5SDimitry Andric /// Return the Hexagon ISA class for the insn.
getType(MCInstrInfo const & MCII,MCInst const & MCI)4230b57cec5SDimitry Andric unsigned HexagonMCInstrInfo::getType(MCInstrInfo const &MCII,
4240b57cec5SDimitry Andric                                      MCInst const &MCI) {
4250b57cec5SDimitry Andric   const uint64_t F = MCII.get(MCI.getOpcode()).TSFlags;
4260b57cec5SDimitry Andric   return ((F >> HexagonII::TypePos) & HexagonII::TypeMask);
4270b57cec5SDimitry Andric }
4280b57cec5SDimitry Andric 
4295ffd83dbSDimitry Andric /// Return the resources used by this instruction
getCVIResources(MCInstrInfo const & MCII,MCSubtargetInfo const & STI,MCInst const & MCI)4305ffd83dbSDimitry Andric unsigned HexagonMCInstrInfo::getCVIResources(MCInstrInfo const &MCII,
4315ffd83dbSDimitry Andric                                       MCSubtargetInfo const &STI,
4325ffd83dbSDimitry Andric                                       MCInst const &MCI) {
4335ffd83dbSDimitry Andric 
4345ffd83dbSDimitry Andric   const InstrItinerary *II = STI.getSchedModel().InstrItineraries;
4355ffd83dbSDimitry Andric   int SchedClass = HexagonMCInstrInfo::getDesc(MCII, MCI).getSchedClass();
4365ffd83dbSDimitry Andric   int Size = II[SchedClass].LastStage - II[SchedClass].FirstStage;
4375ffd83dbSDimitry Andric 
4385ffd83dbSDimitry Andric   // HVX resources used are currenty located at the second to last stage.
4395ffd83dbSDimitry Andric   // This could also be done with a linear search of the stages looking for:
4405ffd83dbSDimitry Andric   // CVI_ALL, CVI_MPY01, CVI_XLSHF, CVI_MPY0, CVI_MPY1, CVI_SHIFT, CVI_XLANE,
4415ffd83dbSDimitry Andric   // CVI_ZW
4425ffd83dbSDimitry Andric   unsigned Stage = II[SchedClass].LastStage - 1;
4435ffd83dbSDimitry Andric 
4445ffd83dbSDimitry Andric   if (Size < 2)
4455ffd83dbSDimitry Andric     return 0;
4465ffd83dbSDimitry Andric   return ((Stage + HexagonStages)->getUnits());
4475ffd83dbSDimitry Andric }
4485ffd83dbSDimitry Andric 
4490b57cec5SDimitry Andric /// Return the slots this instruction can execute out of
getUnits(MCInstrInfo const & MCII,MCSubtargetInfo const & STI,MCInst const & MCI)4500b57cec5SDimitry Andric unsigned HexagonMCInstrInfo::getUnits(MCInstrInfo const &MCII,
4510b57cec5SDimitry Andric                                       MCSubtargetInfo const &STI,
4520b57cec5SDimitry Andric                                       MCInst const &MCI) {
4530b57cec5SDimitry Andric   const InstrItinerary *II = STI.getSchedModel().InstrItineraries;
4540b57cec5SDimitry Andric   int SchedClass = HexagonMCInstrInfo::getDesc(MCII, MCI).getSchedClass();
4550b57cec5SDimitry Andric   return ((II[SchedClass].FirstStage + HexagonStages)->getUnits());
4560b57cec5SDimitry Andric }
4570b57cec5SDimitry Andric 
4580b57cec5SDimitry Andric /// Return the slots this instruction consumes in addition to
4590b57cec5SDimitry Andric /// the slot(s) it can execute out of
4600b57cec5SDimitry Andric 
getOtherReservedSlots(MCInstrInfo const & MCII,MCSubtargetInfo const & STI,MCInst const & MCI)4610b57cec5SDimitry Andric unsigned HexagonMCInstrInfo::getOtherReservedSlots(MCInstrInfo const &MCII,
4620b57cec5SDimitry Andric                                                    MCSubtargetInfo const &STI,
4630b57cec5SDimitry Andric                                                    MCInst const &MCI) {
4640b57cec5SDimitry Andric   const InstrItinerary *II = STI.getSchedModel().InstrItineraries;
4650b57cec5SDimitry Andric   int SchedClass = HexagonMCInstrInfo::getDesc(MCII, MCI).getSchedClass();
4660b57cec5SDimitry Andric   unsigned Slots = 0;
4670b57cec5SDimitry Andric 
4680b57cec5SDimitry Andric   // FirstStage are slots that this instruction can execute in.
4690b57cec5SDimitry Andric   // FirstStage+1 are slots that are also consumed by this instruction.
4700b57cec5SDimitry Andric   // For example: vmemu can only execute in slot 0 but also consumes slot 1.
4710b57cec5SDimitry Andric   for (unsigned Stage = II[SchedClass].FirstStage + 1;
4720b57cec5SDimitry Andric        Stage < II[SchedClass].LastStage; ++Stage) {
4730b57cec5SDimitry Andric     unsigned Units = (Stage + HexagonStages)->getUnits();
4740b57cec5SDimitry Andric     if (Units > HexagonGetLastSlot())
4750b57cec5SDimitry Andric       break;
4760b57cec5SDimitry Andric     // fyi: getUnits() will return 0x1, 0x2, 0x4 or 0x8
4770b57cec5SDimitry Andric     Slots |= Units;
4780b57cec5SDimitry Andric   }
4790b57cec5SDimitry Andric 
4800b57cec5SDimitry Andric   // if 0 is returned, then no additional slots are consumed by this inst.
4810b57cec5SDimitry Andric   return Slots;
4820b57cec5SDimitry Andric }
4830b57cec5SDimitry Andric 
hasDuplex(MCInstrInfo const & MCII,MCInst const & MCI)4840b57cec5SDimitry Andric bool HexagonMCInstrInfo::hasDuplex(MCInstrInfo const &MCII, MCInst const &MCI) {
4850b57cec5SDimitry Andric   if (!HexagonMCInstrInfo::isBundle(MCI))
4860b57cec5SDimitry Andric     return false;
4870b57cec5SDimitry Andric 
4880b57cec5SDimitry Andric   for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCI)) {
4890b57cec5SDimitry Andric     if (HexagonMCInstrInfo::isDuplex(MCII, *I.getInst()))
4900b57cec5SDimitry Andric       return true;
4910b57cec5SDimitry Andric   }
4920b57cec5SDimitry Andric 
4930b57cec5SDimitry Andric   return false;
4940b57cec5SDimitry Andric }
4950b57cec5SDimitry Andric 
hasExtenderForIndex(MCInst const & MCB,size_t Index)4960b57cec5SDimitry Andric bool HexagonMCInstrInfo::hasExtenderForIndex(MCInst const &MCB, size_t Index) {
4970b57cec5SDimitry Andric   return extenderForIndex(MCB, Index) != nullptr;
4980b57cec5SDimitry Andric }
4990b57cec5SDimitry Andric 
hasImmExt(MCInst const & MCI)5000b57cec5SDimitry Andric bool HexagonMCInstrInfo::hasImmExt(MCInst const &MCI) {
5010b57cec5SDimitry Andric   if (!HexagonMCInstrInfo::isBundle(MCI))
5020b57cec5SDimitry Andric     return false;
5030b57cec5SDimitry Andric 
5040b57cec5SDimitry Andric   for (const auto &I : HexagonMCInstrInfo::bundleInstructions(MCI)) {
5050b57cec5SDimitry Andric     if (isImmext(*I.getInst()))
5060b57cec5SDimitry Andric       return true;
5070b57cec5SDimitry Andric   }
5080b57cec5SDimitry Andric 
5090b57cec5SDimitry Andric   return false;
5100b57cec5SDimitry Andric }
5110b57cec5SDimitry Andric 
5120b57cec5SDimitry Andric /// Return whether the insn produces a value.
hasNewValue(MCInstrInfo const & MCII,MCInst const & MCI)5130b57cec5SDimitry Andric bool HexagonMCInstrInfo::hasNewValue(MCInstrInfo const &MCII,
5140b57cec5SDimitry Andric                                      MCInst const &MCI) {
5150b57cec5SDimitry Andric   const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
5160b57cec5SDimitry Andric   return ((F >> HexagonII::hasNewValuePos) & HexagonII::hasNewValueMask);
5170b57cec5SDimitry Andric }
5180b57cec5SDimitry Andric 
5190b57cec5SDimitry Andric /// Return whether the insn produces a second value.
hasNewValue2(MCInstrInfo const & MCII,MCInst const & MCI)5200b57cec5SDimitry Andric bool HexagonMCInstrInfo::hasNewValue2(MCInstrInfo const &MCII,
5210b57cec5SDimitry Andric                                       MCInst const &MCI) {
5220b57cec5SDimitry Andric   const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
5230b57cec5SDimitry Andric   return ((F >> HexagonII::hasNewValuePos2) & HexagonII::hasNewValueMask2);
5240b57cec5SDimitry Andric }
5250b57cec5SDimitry Andric 
instruction(MCInst const & MCB,size_t Index)5260b57cec5SDimitry Andric MCInst const &HexagonMCInstrInfo::instruction(MCInst const &MCB, size_t Index) {
5270b57cec5SDimitry Andric   assert(isBundle(MCB));
5285ffd83dbSDimitry Andric   assert(Index < HEXAGON_PRESHUFFLE_PACKET_SIZE);
5290b57cec5SDimitry Andric   return *MCB.getOperand(bundleInstructionsOffset + Index).getInst();
5300b57cec5SDimitry Andric }
5310b57cec5SDimitry Andric 
5320b57cec5SDimitry Andric /// Return where the instruction is an accumulator.
isAccumulator(MCInstrInfo const & MCII,MCInst const & MCI)5330b57cec5SDimitry Andric bool HexagonMCInstrInfo::isAccumulator(MCInstrInfo const &MCII,
5340b57cec5SDimitry Andric                                        MCInst const &MCI) {
5350b57cec5SDimitry Andric   const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
5360b57cec5SDimitry Andric   return ((F >> HexagonII::AccumulatorPos) & HexagonII::AccumulatorMask);
5370b57cec5SDimitry Andric }
5380b57cec5SDimitry Andric 
isBundle(MCInst const & MCI)5390b57cec5SDimitry Andric bool HexagonMCInstrInfo::isBundle(MCInst const &MCI) {
5400b57cec5SDimitry Andric   auto Result = Hexagon::BUNDLE == MCI.getOpcode();
5410b57cec5SDimitry Andric   assert(!Result || (MCI.size() > 0 && MCI.getOperand(0).isImm()));
5420b57cec5SDimitry Andric   return Result;
5430b57cec5SDimitry Andric }
5440b57cec5SDimitry Andric 
isConstExtended(MCInstrInfo const & MCII,MCInst const & MCI)5450b57cec5SDimitry Andric bool HexagonMCInstrInfo::isConstExtended(MCInstrInfo const &MCII,
5460b57cec5SDimitry Andric                                          MCInst const &MCI) {
5470b57cec5SDimitry Andric   if (HexagonMCInstrInfo::isExtended(MCII, MCI))
5480b57cec5SDimitry Andric     return true;
5490b57cec5SDimitry Andric   if (!HexagonMCInstrInfo::isExtendable(MCII, MCI))
5500b57cec5SDimitry Andric     return false;
5510b57cec5SDimitry Andric   MCOperand const &MO = HexagonMCInstrInfo::getExtendableOperand(MCII, MCI);
5520b57cec5SDimitry Andric   if (isa<HexagonMCExpr>(MO.getExpr()) &&
5530b57cec5SDimitry Andric       HexagonMCInstrInfo::mustExtend(*MO.getExpr()))
5540b57cec5SDimitry Andric     return true;
5550b57cec5SDimitry Andric   // Branch insns are handled as necessary by relaxation.
5560b57cec5SDimitry Andric   if ((HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeJ) ||
5570b57cec5SDimitry Andric       (HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeCJ &&
5580b57cec5SDimitry Andric        HexagonMCInstrInfo::getDesc(MCII, MCI).isBranch()) ||
5590b57cec5SDimitry Andric       (HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeNCJ &&
5600b57cec5SDimitry Andric        HexagonMCInstrInfo::getDesc(MCII, MCI).isBranch()))
5610b57cec5SDimitry Andric     return false;
5620b57cec5SDimitry Andric   // Otherwise loop instructions and other CR insts are handled by relaxation
5630b57cec5SDimitry Andric   else if ((HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeCR) &&
5640b57cec5SDimitry Andric            (MCI.getOpcode() != Hexagon::C4_addipc))
5650b57cec5SDimitry Andric     return false;
5660b57cec5SDimitry Andric 
5670b57cec5SDimitry Andric   assert(!MO.isImm());
5680b57cec5SDimitry Andric   if (isa<HexagonMCExpr>(MO.getExpr()) &&
5690b57cec5SDimitry Andric       HexagonMCInstrInfo::mustNotExtend(*MO.getExpr()))
5700b57cec5SDimitry Andric     return false;
57106c3fb27SDimitry Andric 
5720b57cec5SDimitry Andric   int64_t Value;
5730b57cec5SDimitry Andric   if (!MO.getExpr()->evaluateAsAbsolute(Value))
5740b57cec5SDimitry Andric     return true;
57506c3fb27SDimitry Andric   if (HexagonMCInstrInfo::isExtentSigned(MCII, MCI)) {
57606c3fb27SDimitry Andric     int32_t SValue = Value;
57706c3fb27SDimitry Andric     int32_t MinValue = HexagonMCInstrInfo::getMinValue(MCII, MCI);
57806c3fb27SDimitry Andric     int32_t MaxValue = HexagonMCInstrInfo::getMaxValue(MCII, MCI);
57906c3fb27SDimitry Andric     return SValue < MinValue || SValue > MaxValue;
58006c3fb27SDimitry Andric   }
58106c3fb27SDimitry Andric   uint32_t UValue = Value;
58206c3fb27SDimitry Andric   uint32_t MinValue = HexagonMCInstrInfo::getMinValue(MCII, MCI);
58306c3fb27SDimitry Andric   uint32_t MaxValue = HexagonMCInstrInfo::getMaxValue(MCII, MCI);
58406c3fb27SDimitry Andric   return UValue < MinValue || UValue > MaxValue;
5850b57cec5SDimitry Andric }
5860b57cec5SDimitry Andric 
isCanon(MCInstrInfo const & MCII,MCInst const & MCI)5870b57cec5SDimitry Andric bool HexagonMCInstrInfo::isCanon(MCInstrInfo const &MCII, MCInst const &MCI) {
5880b57cec5SDimitry Andric   return !HexagonMCInstrInfo::getDesc(MCII, MCI).isPseudo() &&
5890b57cec5SDimitry Andric          !HexagonMCInstrInfo::isPrefix(MCII, MCI);
5900b57cec5SDimitry Andric }
5910b57cec5SDimitry Andric 
isCofMax1(MCInstrInfo const & MCII,MCInst const & MCI)5920b57cec5SDimitry Andric bool HexagonMCInstrInfo::isCofMax1(MCInstrInfo const &MCII, MCInst const &MCI) {
5930b57cec5SDimitry Andric   const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
5940b57cec5SDimitry Andric   return ((F >> HexagonII::CofMax1Pos) & HexagonII::CofMax1Mask);
5950b57cec5SDimitry Andric }
5960b57cec5SDimitry Andric 
isCofRelax1(MCInstrInfo const & MCII,MCInst const & MCI)5970b57cec5SDimitry Andric bool HexagonMCInstrInfo::isCofRelax1(MCInstrInfo const &MCII,
5980b57cec5SDimitry Andric                                      MCInst const &MCI) {
5990b57cec5SDimitry Andric   const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
6000b57cec5SDimitry Andric   return ((F >> HexagonII::CofRelax1Pos) & HexagonII::CofRelax1Mask);
6010b57cec5SDimitry Andric }
6020b57cec5SDimitry Andric 
isCofRelax2(MCInstrInfo const & MCII,MCInst const & MCI)6030b57cec5SDimitry Andric bool HexagonMCInstrInfo::isCofRelax2(MCInstrInfo const &MCII,
6040b57cec5SDimitry Andric                                      MCInst const &MCI) {
6050b57cec5SDimitry Andric   const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
6060b57cec5SDimitry Andric   return ((F >> HexagonII::CofRelax2Pos) & HexagonII::CofRelax2Mask);
6070b57cec5SDimitry Andric }
6080b57cec5SDimitry Andric 
isCompound(MCInstrInfo const & MCII,MCInst const & MCI)6090b57cec5SDimitry Andric bool HexagonMCInstrInfo::isCompound(MCInstrInfo const &MCII,
6100b57cec5SDimitry Andric                                     MCInst const &MCI) {
6110b57cec5SDimitry Andric   return (getType(MCII, MCI) == HexagonII::TypeCJ);
6120b57cec5SDimitry Andric }
6130b57cec5SDimitry Andric 
isCVINew(MCInstrInfo const & MCII,MCInst const & MCI)6140b57cec5SDimitry Andric bool HexagonMCInstrInfo::isCVINew(MCInstrInfo const &MCII, MCInst const &MCI) {
6150b57cec5SDimitry Andric   const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
6160b57cec5SDimitry Andric   return ((F >> HexagonII::CVINewPos) & HexagonII::CVINewMask);
6170b57cec5SDimitry Andric }
6180b57cec5SDimitry Andric 
isDblRegForSubInst(unsigned Reg)6190b57cec5SDimitry Andric bool HexagonMCInstrInfo::isDblRegForSubInst(unsigned Reg) {
6200b57cec5SDimitry Andric   return ((Reg >= Hexagon::D0 && Reg <= Hexagon::D3) ||
6210b57cec5SDimitry Andric           (Reg >= Hexagon::D8 && Reg <= Hexagon::D11));
6220b57cec5SDimitry Andric }
6230b57cec5SDimitry Andric 
isDuplex(MCInstrInfo const & MCII,MCInst const & MCI)6240b57cec5SDimitry Andric bool HexagonMCInstrInfo::isDuplex(MCInstrInfo const &MCII, MCInst const &MCI) {
6250b57cec5SDimitry Andric   return HexagonII::TypeDUPLEX == HexagonMCInstrInfo::getType(MCII, MCI);
6260b57cec5SDimitry Andric }
6270b57cec5SDimitry Andric 
isExtendable(MCInstrInfo const & MCII,MCInst const & MCI)6280b57cec5SDimitry Andric bool HexagonMCInstrInfo::isExtendable(MCInstrInfo const &MCII,
6290b57cec5SDimitry Andric                                       MCInst const &MCI) {
6300b57cec5SDimitry Andric   uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
6310b57cec5SDimitry Andric   return (F >> HexagonII::ExtendablePos) & HexagonII::ExtendableMask;
6320b57cec5SDimitry Andric }
6330b57cec5SDimitry Andric 
isExtended(MCInstrInfo const & MCII,MCInst const & MCI)6340b57cec5SDimitry Andric bool HexagonMCInstrInfo::isExtended(MCInstrInfo const &MCII,
6350b57cec5SDimitry Andric                                     MCInst const &MCI) {
6360b57cec5SDimitry Andric   uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
6370b57cec5SDimitry Andric   return (F >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask;
6380b57cec5SDimitry Andric }
6390b57cec5SDimitry Andric 
isFloat(MCInstrInfo const & MCII,MCInst const & MCI)6400b57cec5SDimitry Andric bool HexagonMCInstrInfo::isFloat(MCInstrInfo const &MCII, MCInst const &MCI) {
6410b57cec5SDimitry Andric   const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
6420b57cec5SDimitry Andric   return ((F >> HexagonII::FPPos) & HexagonII::FPMask);
6430b57cec5SDimitry Andric }
6440b57cec5SDimitry Andric 
isHVX(MCInstrInfo const & MCII,MCInst const & MCI)6450b57cec5SDimitry Andric bool HexagonMCInstrInfo::isHVX(MCInstrInfo const &MCII, MCInst const &MCI) {
6460b57cec5SDimitry Andric   const uint64_t V = getType(MCII, MCI);
6470b57cec5SDimitry Andric   return HexagonII::TypeCVI_FIRST <= V && V <= HexagonII::TypeCVI_LAST;
6480b57cec5SDimitry Andric }
6490b57cec5SDimitry Andric 
isImmext(MCInst const & MCI)6500b57cec5SDimitry Andric bool HexagonMCInstrInfo::isImmext(MCInst const &MCI) {
6510b57cec5SDimitry Andric   return MCI.getOpcode() == Hexagon::A4_ext;
6520b57cec5SDimitry Andric }
6530b57cec5SDimitry Andric 
isInnerLoop(MCInst const & MCI)6540b57cec5SDimitry Andric bool HexagonMCInstrInfo::isInnerLoop(MCInst const &MCI) {
6550b57cec5SDimitry Andric   assert(isBundle(MCI));
6560b57cec5SDimitry Andric   int64_t Flags = MCI.getOperand(0).getImm();
6570b57cec5SDimitry Andric   return (Flags & innerLoopMask) != 0;
6580b57cec5SDimitry Andric }
6590b57cec5SDimitry Andric 
isIntReg(unsigned Reg)6600b57cec5SDimitry Andric bool HexagonMCInstrInfo::isIntReg(unsigned Reg) {
6610b57cec5SDimitry Andric   return (Reg >= Hexagon::R0 && Reg <= Hexagon::R31);
6620b57cec5SDimitry Andric }
6630b57cec5SDimitry Andric 
isIntRegForSubInst(unsigned Reg)6640b57cec5SDimitry Andric bool HexagonMCInstrInfo::isIntRegForSubInst(unsigned Reg) {
6650b57cec5SDimitry Andric   return ((Reg >= Hexagon::R0 && Reg <= Hexagon::R7) ||
6660b57cec5SDimitry Andric           (Reg >= Hexagon::R16 && Reg <= Hexagon::R23));
6670b57cec5SDimitry Andric }
6680b57cec5SDimitry Andric 
6690b57cec5SDimitry Andric /// Return whether the insn expects newly produced value.
isNewValue(MCInstrInfo const & MCII,MCInst const & MCI)6700b57cec5SDimitry Andric bool HexagonMCInstrInfo::isNewValue(MCInstrInfo const &MCII,
6710b57cec5SDimitry Andric                                     MCInst const &MCI) {
6720b57cec5SDimitry Andric   const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
6730b57cec5SDimitry Andric   return ((F >> HexagonII::NewValuePos) & HexagonII::NewValueMask);
6740b57cec5SDimitry Andric }
6750b57cec5SDimitry Andric 
isNewValueStore(MCInstrInfo const & MCII,MCInst const & MCI)6765ffd83dbSDimitry Andric bool HexagonMCInstrInfo::isNewValueStore(MCInstrInfo const &MCII,
6775ffd83dbSDimitry Andric                                          MCInst const &MCI) {
6785ffd83dbSDimitry Andric   const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
6795ffd83dbSDimitry Andric   return (F >> HexagonII::NVStorePos) & HexagonII::NVStoreMask;
6805ffd83dbSDimitry Andric }
6815ffd83dbSDimitry Andric 
6820b57cec5SDimitry Andric /// Return whether the operand is extendable.
isOpExtendable(MCInstrInfo const & MCII,MCInst const & MCI,unsigned short O)6830b57cec5SDimitry Andric bool HexagonMCInstrInfo::isOpExtendable(MCInstrInfo const &MCII,
6840b57cec5SDimitry Andric                                         MCInst const &MCI, unsigned short O) {
6850b57cec5SDimitry Andric   return (O == HexagonMCInstrInfo::getExtendableOp(MCII, MCI));
6860b57cec5SDimitry Andric }
6870b57cec5SDimitry Andric 
isOuterLoop(MCInst const & MCI)6880b57cec5SDimitry Andric bool HexagonMCInstrInfo::isOuterLoop(MCInst const &MCI) {
6890b57cec5SDimitry Andric   assert(isBundle(MCI));
6900b57cec5SDimitry Andric   int64_t Flags = MCI.getOperand(0).getImm();
6910b57cec5SDimitry Andric   return (Flags & outerLoopMask) != 0;
6920b57cec5SDimitry Andric }
6930b57cec5SDimitry Andric 
IsVecRegPair(unsigned VecReg)6945ffd83dbSDimitry Andric bool HexagonMCInstrInfo::IsVecRegPair(unsigned VecReg) {
6955ffd83dbSDimitry Andric   return (VecReg >= Hexagon::W0 && VecReg <= Hexagon::W15) ||
6965ffd83dbSDimitry Andric          (VecReg >= Hexagon::WR0 && VecReg <= Hexagon::WR15);
6975ffd83dbSDimitry Andric }
6985ffd83dbSDimitry Andric 
IsReverseVecRegPair(unsigned VecReg)6995ffd83dbSDimitry Andric bool HexagonMCInstrInfo::IsReverseVecRegPair(unsigned VecReg) {
7005ffd83dbSDimitry Andric   return (VecReg >= Hexagon::WR0 && VecReg <= Hexagon::WR15);
7015ffd83dbSDimitry Andric }
7025ffd83dbSDimitry Andric 
IsVecRegSingle(unsigned VecReg)7035ffd83dbSDimitry Andric bool HexagonMCInstrInfo::IsVecRegSingle(unsigned VecReg) {
7045ffd83dbSDimitry Andric   return (VecReg >= Hexagon::V0 && VecReg <= Hexagon::V31);
7055ffd83dbSDimitry Andric }
7065ffd83dbSDimitry Andric 
7075ffd83dbSDimitry Andric std::pair<unsigned, unsigned>
GetVecRegPairIndices(unsigned VecRegPair)7085ffd83dbSDimitry Andric HexagonMCInstrInfo::GetVecRegPairIndices(unsigned VecRegPair) {
7095ffd83dbSDimitry Andric   assert(IsVecRegPair(VecRegPair) &&
7105ffd83dbSDimitry Andric          "VecRegPair must be a vector register pair");
7115ffd83dbSDimitry Andric 
7125ffd83dbSDimitry Andric   const bool IsRev = IsReverseVecRegPair(VecRegPair);
7135ffd83dbSDimitry Andric   const unsigned PairIndex =
7145ffd83dbSDimitry Andric       2 * (IsRev ? VecRegPair - Hexagon::WR0 : VecRegPair - Hexagon::W0);
7155ffd83dbSDimitry Andric 
7165ffd83dbSDimitry Andric   return IsRev ? std::make_pair(PairIndex, PairIndex + 1)
7175ffd83dbSDimitry Andric                : std::make_pair(PairIndex + 1, PairIndex);
7185ffd83dbSDimitry Andric }
7195ffd83dbSDimitry Andric 
IsSingleConsumerRefPairProducer(unsigned Producer,unsigned Consumer)7205ffd83dbSDimitry Andric bool HexagonMCInstrInfo::IsSingleConsumerRefPairProducer(unsigned Producer,
7215ffd83dbSDimitry Andric                                                          unsigned Consumer) {
7225ffd83dbSDimitry Andric   if (IsVecRegPair(Producer) && IsVecRegSingle(Consumer)) {
7235ffd83dbSDimitry Andric     const unsigned ProdPairIndex = IsReverseVecRegPair(Producer)
7245ffd83dbSDimitry Andric                                        ? Producer - Hexagon::WR0
7255ffd83dbSDimitry Andric                                        : Producer - Hexagon::W0;
7265ffd83dbSDimitry Andric     const unsigned ConsumerSingleIndex = (Consumer - Hexagon::V0) >> 1;
7275ffd83dbSDimitry Andric 
7285ffd83dbSDimitry Andric     return ConsumerSingleIndex == ProdPairIndex;
7295ffd83dbSDimitry Andric   }
7305ffd83dbSDimitry Andric   return false;
7315ffd83dbSDimitry Andric }
7325ffd83dbSDimitry Andric 
isPredicated(MCInstrInfo const & MCII,MCInst const & MCI)7330b57cec5SDimitry Andric bool HexagonMCInstrInfo::isPredicated(MCInstrInfo const &MCII,
7340b57cec5SDimitry Andric                                       MCInst const &MCI) {
7350b57cec5SDimitry Andric   const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
7360b57cec5SDimitry Andric   return ((F >> HexagonII::PredicatedPos) & HexagonII::PredicatedMask);
7370b57cec5SDimitry Andric }
7380b57cec5SDimitry Andric 
isPrefix(MCInstrInfo const & MCII,MCInst const & MCI)7390b57cec5SDimitry Andric bool HexagonMCInstrInfo::isPrefix(MCInstrInfo const &MCII, MCInst const &MCI) {
7400b57cec5SDimitry Andric   return HexagonII::TypeEXTENDER == HexagonMCInstrInfo::getType(MCII, MCI);
7410b57cec5SDimitry Andric }
7420b57cec5SDimitry Andric 
isPredicateLate(MCInstrInfo const & MCII,MCInst const & MCI)7430b57cec5SDimitry Andric bool HexagonMCInstrInfo::isPredicateLate(MCInstrInfo const &MCII,
7440b57cec5SDimitry Andric                                          MCInst const &MCI) {
7450b57cec5SDimitry Andric   const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
7460b57cec5SDimitry Andric   return (F >> HexagonII::PredicateLatePos & HexagonII::PredicateLateMask);
7470b57cec5SDimitry Andric }
7480b57cec5SDimitry Andric 
7490b57cec5SDimitry Andric /// Return whether the insn is newly predicated.
isPredicatedNew(MCInstrInfo const & MCII,MCInst const & MCI)7500b57cec5SDimitry Andric bool HexagonMCInstrInfo::isPredicatedNew(MCInstrInfo const &MCII,
7510b57cec5SDimitry Andric                                          MCInst const &MCI) {
7520b57cec5SDimitry Andric   const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
7530b57cec5SDimitry Andric   return ((F >> HexagonII::PredicatedNewPos) & HexagonII::PredicatedNewMask);
7540b57cec5SDimitry Andric }
7550b57cec5SDimitry Andric 
isPredicatedTrue(MCInstrInfo const & MCII,MCInst const & MCI)7560b57cec5SDimitry Andric bool HexagonMCInstrInfo::isPredicatedTrue(MCInstrInfo const &MCII,
7570b57cec5SDimitry Andric                                           MCInst const &MCI) {
7580b57cec5SDimitry Andric   const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
7590b57cec5SDimitry Andric   return (
7600b57cec5SDimitry Andric       !((F >> HexagonII::PredicatedFalsePos) & HexagonII::PredicatedFalseMask));
7610b57cec5SDimitry Andric }
7620b57cec5SDimitry Andric 
isPredReg(MCRegisterInfo const & MRI,unsigned Reg)7635ffd83dbSDimitry Andric bool HexagonMCInstrInfo::isPredReg(MCRegisterInfo const &MRI, unsigned Reg) {
7645ffd83dbSDimitry Andric   auto &PredRegClass = MRI.getRegClass(Hexagon::PredRegsRegClassID);
7655ffd83dbSDimitry Andric   return PredRegClass.contains(Reg);
7665ffd83dbSDimitry Andric }
7675ffd83dbSDimitry Andric 
isPredRegister(MCInstrInfo const & MCII,MCInst const & Inst,unsigned I)7685ffd83dbSDimitry Andric bool HexagonMCInstrInfo::isPredRegister(MCInstrInfo const &MCII,
7695ffd83dbSDimitry Andric                                         MCInst const &Inst, unsigned I) {
7705ffd83dbSDimitry Andric   MCInstrDesc const &Desc = HexagonMCInstrInfo::getDesc(MCII, Inst);
7715ffd83dbSDimitry Andric 
7725ffd83dbSDimitry Andric   return Inst.getOperand(I).isReg() &&
773bdd1243dSDimitry Andric          Desc.operands()[I].RegClass == Hexagon::PredRegsRegClassID;
7740b57cec5SDimitry Andric }
7750b57cec5SDimitry Andric 
7760b57cec5SDimitry Andric /// Return whether the insn can be packaged only with A and X-type insns.
isSoloAX(MCInstrInfo const & MCII,MCInst const & MCI)7770b57cec5SDimitry Andric bool HexagonMCInstrInfo::isSoloAX(MCInstrInfo const &MCII, MCInst const &MCI) {
7780b57cec5SDimitry Andric   const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
7790b57cec5SDimitry Andric   return ((F >> HexagonII::SoloAXPos) & HexagonII::SoloAXMask);
7800b57cec5SDimitry Andric }
7810b57cec5SDimitry Andric 
7820b57cec5SDimitry Andric /// Return whether the insn can be packaged only with an A-type insn in slot #1.
isRestrictSlot1AOK(MCInstrInfo const & MCII,MCInst const & MCI)7830b57cec5SDimitry Andric bool HexagonMCInstrInfo::isRestrictSlot1AOK(MCInstrInfo const &MCII,
7840b57cec5SDimitry Andric                                             MCInst const &MCI) {
7850b57cec5SDimitry Andric   const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
7860b57cec5SDimitry Andric   return ((F >> HexagonII::RestrictSlot1AOKPos) &
7870b57cec5SDimitry Andric           HexagonII::RestrictSlot1AOKMask);
7880b57cec5SDimitry Andric }
7890b57cec5SDimitry Andric 
isRestrictNoSlot1Store(MCInstrInfo const & MCII,MCInst const & MCI)7900b57cec5SDimitry Andric bool HexagonMCInstrInfo::isRestrictNoSlot1Store(MCInstrInfo const &MCII,
7910b57cec5SDimitry Andric                                                 MCInst const &MCI) {
7920b57cec5SDimitry Andric   const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
7930b57cec5SDimitry Andric   return ((F >> HexagonII::RestrictNoSlot1StorePos) &
7940b57cec5SDimitry Andric           HexagonII::RestrictNoSlot1StoreMask);
7950b57cec5SDimitry Andric }
7960b57cec5SDimitry Andric 
7970b57cec5SDimitry Andric /// Return whether the insn is solo, i.e., cannot be in a packet.
isSolo(MCInstrInfo const & MCII,MCInst const & MCI)7980b57cec5SDimitry Andric bool HexagonMCInstrInfo::isSolo(MCInstrInfo const &MCII, MCInst const &MCI) {
7990b57cec5SDimitry Andric   const uint64_t F = MCII.get(MCI.getOpcode()).TSFlags;
8000b57cec5SDimitry Andric   return ((F >> HexagonII::SoloPos) & HexagonII::SoloMask);
8010b57cec5SDimitry Andric }
8020b57cec5SDimitry Andric 
isMemReorderDisabled(MCInst const & MCI)8030b57cec5SDimitry Andric bool HexagonMCInstrInfo::isMemReorderDisabled(MCInst const &MCI) {
8040b57cec5SDimitry Andric   assert(isBundle(MCI));
8050b57cec5SDimitry Andric   auto Flags = MCI.getOperand(0).getImm();
8060b57cec5SDimitry Andric   return (Flags & memReorderDisabledMask) != 0;
8070b57cec5SDimitry Andric }
8080b57cec5SDimitry Andric 
isSubInstruction(MCInst const & MCI)8090b57cec5SDimitry Andric bool HexagonMCInstrInfo::isSubInstruction(MCInst const &MCI) {
8100b57cec5SDimitry Andric   switch (MCI.getOpcode()) {
8110b57cec5SDimitry Andric   default:
8120b57cec5SDimitry Andric     return false;
8130b57cec5SDimitry Andric   case Hexagon::SA1_addi:
8140b57cec5SDimitry Andric   case Hexagon::SA1_addrx:
8150b57cec5SDimitry Andric   case Hexagon::SA1_addsp:
8160b57cec5SDimitry Andric   case Hexagon::SA1_and1:
8170b57cec5SDimitry Andric   case Hexagon::SA1_clrf:
8180b57cec5SDimitry Andric   case Hexagon::SA1_clrfnew:
8190b57cec5SDimitry Andric   case Hexagon::SA1_clrt:
8200b57cec5SDimitry Andric   case Hexagon::SA1_clrtnew:
8210b57cec5SDimitry Andric   case Hexagon::SA1_cmpeqi:
8220b57cec5SDimitry Andric   case Hexagon::SA1_combine0i:
8230b57cec5SDimitry Andric   case Hexagon::SA1_combine1i:
8240b57cec5SDimitry Andric   case Hexagon::SA1_combine2i:
8250b57cec5SDimitry Andric   case Hexagon::SA1_combine3i:
8260b57cec5SDimitry Andric   case Hexagon::SA1_combinerz:
8270b57cec5SDimitry Andric   case Hexagon::SA1_combinezr:
8280b57cec5SDimitry Andric   case Hexagon::SA1_dec:
8290b57cec5SDimitry Andric   case Hexagon::SA1_inc:
8300b57cec5SDimitry Andric   case Hexagon::SA1_seti:
8310b57cec5SDimitry Andric   case Hexagon::SA1_setin1:
8320b57cec5SDimitry Andric   case Hexagon::SA1_sxtb:
8330b57cec5SDimitry Andric   case Hexagon::SA1_sxth:
8340b57cec5SDimitry Andric   case Hexagon::SA1_tfr:
8350b57cec5SDimitry Andric   case Hexagon::SA1_zxtb:
8360b57cec5SDimitry Andric   case Hexagon::SA1_zxth:
8370b57cec5SDimitry Andric   case Hexagon::SL1_loadri_io:
8380b57cec5SDimitry Andric   case Hexagon::SL1_loadrub_io:
8390b57cec5SDimitry Andric   case Hexagon::SL2_deallocframe:
8400b57cec5SDimitry Andric   case Hexagon::SL2_jumpr31:
8410b57cec5SDimitry Andric   case Hexagon::SL2_jumpr31_f:
8420b57cec5SDimitry Andric   case Hexagon::SL2_jumpr31_fnew:
8430b57cec5SDimitry Andric   case Hexagon::SL2_jumpr31_t:
8440b57cec5SDimitry Andric   case Hexagon::SL2_jumpr31_tnew:
8450b57cec5SDimitry Andric   case Hexagon::SL2_loadrb_io:
8460b57cec5SDimitry Andric   case Hexagon::SL2_loadrd_sp:
8470b57cec5SDimitry Andric   case Hexagon::SL2_loadrh_io:
8480b57cec5SDimitry Andric   case Hexagon::SL2_loadri_sp:
8490b57cec5SDimitry Andric   case Hexagon::SL2_loadruh_io:
8500b57cec5SDimitry Andric   case Hexagon::SL2_return:
8510b57cec5SDimitry Andric   case Hexagon::SL2_return_f:
8520b57cec5SDimitry Andric   case Hexagon::SL2_return_fnew:
8530b57cec5SDimitry Andric   case Hexagon::SL2_return_t:
8540b57cec5SDimitry Andric   case Hexagon::SL2_return_tnew:
8550b57cec5SDimitry Andric   case Hexagon::SS1_storeb_io:
8560b57cec5SDimitry Andric   case Hexagon::SS1_storew_io:
8570b57cec5SDimitry Andric   case Hexagon::SS2_allocframe:
8580b57cec5SDimitry Andric   case Hexagon::SS2_storebi0:
8590b57cec5SDimitry Andric   case Hexagon::SS2_storebi1:
8600b57cec5SDimitry Andric   case Hexagon::SS2_stored_sp:
8610b57cec5SDimitry Andric   case Hexagon::SS2_storeh_io:
8620b57cec5SDimitry Andric   case Hexagon::SS2_storew_sp:
8630b57cec5SDimitry Andric   case Hexagon::SS2_storewi0:
8640b57cec5SDimitry Andric   case Hexagon::SS2_storewi1:
8650b57cec5SDimitry Andric     return true;
8660b57cec5SDimitry Andric   }
8670b57cec5SDimitry Andric }
8680b57cec5SDimitry Andric 
isVector(MCInstrInfo const & MCII,MCInst const & MCI)8690b57cec5SDimitry Andric bool HexagonMCInstrInfo::isVector(MCInstrInfo const &MCII, MCInst const &MCI) {
8705ffd83dbSDimitry Andric   const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
8715ffd83dbSDimitry Andric   return (F >> HexagonII::isCVIPos) & HexagonII::isCVIMask;
8720b57cec5SDimitry Andric }
8730b57cec5SDimitry Andric 
minConstant(MCInst const & MCI,size_t Index)8740b57cec5SDimitry Andric int64_t HexagonMCInstrInfo::minConstant(MCInst const &MCI, size_t Index) {
87504eeddc0SDimitry Andric   auto Sentinel = static_cast<int64_t>(std::numeric_limits<uint32_t>::max())
8760b57cec5SDimitry Andric                   << 8;
8770b57cec5SDimitry Andric   if (MCI.size() <= Index)
87804eeddc0SDimitry Andric     return Sentinel;
8790b57cec5SDimitry Andric   MCOperand const &MCO = MCI.getOperand(Index);
8800b57cec5SDimitry Andric   if (!MCO.isExpr())
88104eeddc0SDimitry Andric     return Sentinel;
8820b57cec5SDimitry Andric   int64_t Value;
8830b57cec5SDimitry Andric   if (!MCO.getExpr()->evaluateAsAbsolute(Value))
88404eeddc0SDimitry Andric     return Sentinel;
8850b57cec5SDimitry Andric   return Value;
8860b57cec5SDimitry Andric }
8870b57cec5SDimitry Andric 
setMustExtend(MCExpr const & Expr,bool Val)8880b57cec5SDimitry Andric void HexagonMCInstrInfo::setMustExtend(MCExpr const &Expr, bool Val) {
8890b57cec5SDimitry Andric   HexagonMCExpr &HExpr = const_cast<HexagonMCExpr &>(cast<HexagonMCExpr>(Expr));
8900b57cec5SDimitry Andric   HExpr.setMustExtend(Val);
8910b57cec5SDimitry Andric }
8920b57cec5SDimitry Andric 
mustExtend(MCExpr const & Expr)8930b57cec5SDimitry Andric bool HexagonMCInstrInfo::mustExtend(MCExpr const &Expr) {
8940b57cec5SDimitry Andric   HexagonMCExpr const &HExpr = cast<HexagonMCExpr>(Expr);
8950b57cec5SDimitry Andric   return HExpr.mustExtend();
8960b57cec5SDimitry Andric }
setMustNotExtend(MCExpr const & Expr,bool Val)8970b57cec5SDimitry Andric void HexagonMCInstrInfo::setMustNotExtend(MCExpr const &Expr, bool Val) {
8980b57cec5SDimitry Andric   HexagonMCExpr &HExpr = const_cast<HexagonMCExpr &>(cast<HexagonMCExpr>(Expr));
8990b57cec5SDimitry Andric   HExpr.setMustNotExtend(Val);
9000b57cec5SDimitry Andric }
mustNotExtend(MCExpr const & Expr)9010b57cec5SDimitry Andric bool HexagonMCInstrInfo::mustNotExtend(MCExpr const &Expr) {
9020b57cec5SDimitry Andric   HexagonMCExpr const &HExpr = cast<HexagonMCExpr>(Expr);
9030b57cec5SDimitry Andric   return HExpr.mustNotExtend();
9040b57cec5SDimitry Andric }
setS27_2_reloc(MCExpr const & Expr,bool Val)9050b57cec5SDimitry Andric void HexagonMCInstrInfo::setS27_2_reloc(MCExpr const &Expr, bool Val) {
9060b57cec5SDimitry Andric   HexagonMCExpr &HExpr =
9070b57cec5SDimitry Andric       const_cast<HexagonMCExpr &>(*cast<HexagonMCExpr>(&Expr));
9080b57cec5SDimitry Andric   HExpr.setS27_2_reloc(Val);
9090b57cec5SDimitry Andric }
s27_2_reloc(MCExpr const & Expr)9100b57cec5SDimitry Andric bool HexagonMCInstrInfo::s27_2_reloc(MCExpr const &Expr) {
9110b57cec5SDimitry Andric   HexagonMCExpr const *HExpr = dyn_cast<HexagonMCExpr>(&Expr);
9120b57cec5SDimitry Andric   if (!HExpr)
9130b57cec5SDimitry Andric     return false;
9140b57cec5SDimitry Andric   return HExpr->s27_2_reloc();
9150b57cec5SDimitry Andric }
9160b57cec5SDimitry Andric 
packetSizeSlots(MCSubtargetInfo const & STI)9175ffd83dbSDimitry Andric unsigned HexagonMCInstrInfo::packetSizeSlots(MCSubtargetInfo const &STI) {
91806c3fb27SDimitry Andric   const bool IsTiny = STI.hasFeature(Hexagon::ProcTinyCore);
9195ffd83dbSDimitry Andric 
9205ffd83dbSDimitry Andric   return IsTiny ? (HEXAGON_PACKET_SIZE - 1) : HEXAGON_PACKET_SIZE;
9215ffd83dbSDimitry Andric }
9225ffd83dbSDimitry Andric 
packetSize(StringRef CPU)9235ffd83dbSDimitry Andric unsigned HexagonMCInstrInfo::packetSize(StringRef CPU) {
9245ffd83dbSDimitry Andric   return llvm::StringSwitch<unsigned>(CPU)
9255ffd83dbSDimitry Andric       .Case("hexagonv67t", 3)
9265ffd83dbSDimitry Andric       .Default(4);
9275ffd83dbSDimitry Andric }
9285ffd83dbSDimitry Andric 
padEndloop(MCInst & MCB,MCContext & Context)9290b57cec5SDimitry Andric void HexagonMCInstrInfo::padEndloop(MCInst &MCB, MCContext &Context) {
9300b57cec5SDimitry Andric   MCInst Nop;
9310b57cec5SDimitry Andric   Nop.setOpcode(Hexagon::A2_nop);
9320b57cec5SDimitry Andric   assert(isBundle(MCB));
93304eeddc0SDimitry Andric   while (LoopNeedsPadding(MCB))
9340b57cec5SDimitry Andric     MCB.addOperand(MCOperand::createInst(new (Context) MCInst(Nop)));
9350b57cec5SDimitry Andric }
9360b57cec5SDimitry Andric 
9370b57cec5SDimitry Andric HexagonMCInstrInfo::PredicateInfo
predicateInfo(MCInstrInfo const & MCII,MCInst const & MCI)9380b57cec5SDimitry Andric HexagonMCInstrInfo::predicateInfo(MCInstrInfo const &MCII, MCInst const &MCI) {
9390b57cec5SDimitry Andric   if (!isPredicated(MCII, MCI))
9400b57cec5SDimitry Andric     return {0, 0, false};
9410b57cec5SDimitry Andric   MCInstrDesc const &Desc = getDesc(MCII, MCI);
9420b57cec5SDimitry Andric   for (auto I = Desc.getNumDefs(), N = Desc.getNumOperands(); I != N; ++I)
943bdd1243dSDimitry Andric     if (Desc.operands()[I].RegClass == Hexagon::PredRegsRegClassID)
9440b57cec5SDimitry Andric       return {MCI.getOperand(I).getReg(), I, isPredicatedTrue(MCII, MCI)};
9450b57cec5SDimitry Andric   return {0, 0, false};
9460b57cec5SDimitry Andric }
9470b57cec5SDimitry Andric 
prefersSlot3(MCInstrInfo const & MCII,MCInst const & MCI)9480b57cec5SDimitry Andric bool HexagonMCInstrInfo::prefersSlot3(MCInstrInfo const &MCII,
9490b57cec5SDimitry Andric                                       MCInst const &MCI) {
9500b57cec5SDimitry Andric   const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
9510b57cec5SDimitry Andric   return (F >> HexagonII::PrefersSlot3Pos) & HexagonII::PrefersSlot3Mask;
9520b57cec5SDimitry Andric }
9530b57cec5SDimitry Andric 
hasTmpDst(MCInstrInfo const & MCII,MCInst const & MCI)9540b57cec5SDimitry Andric bool HexagonMCInstrInfo::hasTmpDst(MCInstrInfo const &MCII, MCInst const &MCI) {
9550eae32dcSDimitry Andric   switch (MCI.getOpcode()) {
9560eae32dcSDimitry Andric   default:
9570eae32dcSDimitry Andric     return false;
9580eae32dcSDimitry Andric   case Hexagon::V6_vgathermh:
9590eae32dcSDimitry Andric   case Hexagon::V6_vgathermhq:
9600eae32dcSDimitry Andric   case Hexagon::V6_vgathermhw:
9610eae32dcSDimitry Andric   case Hexagon::V6_vgathermhwq:
9620eae32dcSDimitry Andric   case Hexagon::V6_vgathermw:
9630eae32dcSDimitry Andric   case Hexagon::V6_vgathermwq:
9640eae32dcSDimitry Andric     return true;
9650eae32dcSDimitry Andric   }
9660eae32dcSDimitry Andric   return false;
9670eae32dcSDimitry Andric }
9680eae32dcSDimitry Andric 
hasHvxTmp(MCInstrInfo const & MCII,MCInst const & MCI)9690eae32dcSDimitry Andric bool HexagonMCInstrInfo::hasHvxTmp(MCInstrInfo const &MCII, MCInst const &MCI) {
9700b57cec5SDimitry Andric   const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
9710eae32dcSDimitry Andric   return (F >> HexagonII::HasHvxTmpPos) & HexagonII::HasHvxTmpMask;
9720b57cec5SDimitry Andric }
9730b57cec5SDimitry Andric 
requiresSlot(MCSubtargetInfo const & STI,MCInst const & MCI)9745ffd83dbSDimitry Andric bool HexagonMCInstrInfo::requiresSlot(MCSubtargetInfo const &STI,
9755ffd83dbSDimitry Andric                                       MCInst const &MCI) {
9765ffd83dbSDimitry Andric   const unsigned OpCode = MCI.getOpcode();
9775ffd83dbSDimitry Andric   const bool IsTiny = STI.getFeatureBits() [Hexagon::ProcTinyCore];
9785ffd83dbSDimitry Andric   const bool NoSlotReqd = Hexagon::A4_ext == OpCode ||
9795ffd83dbSDimitry Andric                           (IsTiny && Hexagon::A2_nop == OpCode) ||
9805ffd83dbSDimitry Andric                           (IsTiny && Hexagon::J4_hintjumpr == OpCode);
9815ffd83dbSDimitry Andric 
9825ffd83dbSDimitry Andric   return !NoSlotReqd;
9835ffd83dbSDimitry Andric }
9845ffd83dbSDimitry Andric 
slotsConsumed(MCInstrInfo const & MCII,MCSubtargetInfo const & STI,MCInst const & MCI)9855ffd83dbSDimitry Andric unsigned HexagonMCInstrInfo::slotsConsumed(MCInstrInfo const &MCII,
9865ffd83dbSDimitry Andric                                            MCSubtargetInfo const &STI,
9875ffd83dbSDimitry Andric                                            MCInst const &MCI) {
9885ffd83dbSDimitry Andric   unsigned slotsUsed = 0;
9895ffd83dbSDimitry Andric   for (auto HMI : bundleInstructions(MCI)) {
9905ffd83dbSDimitry Andric     MCInst const &MCI = *HMI.getInst();
9915ffd83dbSDimitry Andric     if (!requiresSlot(STI, MCI))
9925ffd83dbSDimitry Andric       continue;
9935ffd83dbSDimitry Andric     if (isDuplex(MCII, MCI))
9945ffd83dbSDimitry Andric       slotsUsed += 2;
9955ffd83dbSDimitry Andric     else
9965ffd83dbSDimitry Andric       ++slotsUsed;
9975ffd83dbSDimitry Andric   }
9985ffd83dbSDimitry Andric   return slotsUsed;
9995ffd83dbSDimitry Andric }
10005ffd83dbSDimitry Andric 
replaceDuplex(MCContext & Context,MCInst & MCB,DuplexCandidate Candidate)10010b57cec5SDimitry Andric void HexagonMCInstrInfo::replaceDuplex(MCContext &Context, MCInst &MCB,
10020b57cec5SDimitry Andric                                        DuplexCandidate Candidate) {
10030b57cec5SDimitry Andric   assert(Candidate.packetIndexI < MCB.size());
10040b57cec5SDimitry Andric   assert(Candidate.packetIndexJ < MCB.size());
10050b57cec5SDimitry Andric   assert(isBundle(MCB));
10060b57cec5SDimitry Andric   MCInst *Duplex =
10070b57cec5SDimitry Andric       deriveDuplex(Context, Candidate.iClass,
10080b57cec5SDimitry Andric                    *MCB.getOperand(Candidate.packetIndexJ).getInst(),
10090b57cec5SDimitry Andric                    *MCB.getOperand(Candidate.packetIndexI).getInst());
10100b57cec5SDimitry Andric   assert(Duplex != nullptr);
10110b57cec5SDimitry Andric   MCB.getOperand(Candidate.packetIndexI).setInst(Duplex);
10120b57cec5SDimitry Andric   MCB.erase(MCB.begin() + Candidate.packetIndexJ);
10130b57cec5SDimitry Andric }
10140b57cec5SDimitry Andric 
setInnerLoop(MCInst & MCI)10150b57cec5SDimitry Andric void HexagonMCInstrInfo::setInnerLoop(MCInst &MCI) {
10160b57cec5SDimitry Andric   assert(isBundle(MCI));
10170b57cec5SDimitry Andric   MCOperand &Operand = MCI.getOperand(0);
10180b57cec5SDimitry Andric   Operand.setImm(Operand.getImm() | innerLoopMask);
10190b57cec5SDimitry Andric }
10200b57cec5SDimitry Andric 
setMemReorderDisabled(MCInst & MCI)10210b57cec5SDimitry Andric void HexagonMCInstrInfo::setMemReorderDisabled(MCInst &MCI) {
10220b57cec5SDimitry Andric   assert(isBundle(MCI));
10230b57cec5SDimitry Andric   MCOperand &Operand = MCI.getOperand(0);
10240b57cec5SDimitry Andric   Operand.setImm(Operand.getImm() | memReorderDisabledMask);
10250b57cec5SDimitry Andric   assert(isMemReorderDisabled(MCI));
10260b57cec5SDimitry Andric }
10270b57cec5SDimitry Andric 
setOuterLoop(MCInst & MCI)10280b57cec5SDimitry Andric void HexagonMCInstrInfo::setOuterLoop(MCInst &MCI) {
10290b57cec5SDimitry Andric   assert(isBundle(MCI));
10300b57cec5SDimitry Andric   MCOperand &Operand = MCI.getOperand(0);
10310b57cec5SDimitry Andric   Operand.setImm(Operand.getImm() | outerLoopMask);
10320b57cec5SDimitry Andric }
10330b57cec5SDimitry Andric 
SubregisterBit(unsigned Consumer,unsigned Producer,unsigned Producer2)10340b57cec5SDimitry Andric unsigned HexagonMCInstrInfo::SubregisterBit(unsigned Consumer,
10350b57cec5SDimitry Andric                                             unsigned Producer,
10360b57cec5SDimitry Andric                                             unsigned Producer2) {
10370b57cec5SDimitry Andric   // If we're a single vector consumer of a double producer, set subreg bit
10380b57cec5SDimitry Andric   // based on if we're accessing the lower or upper register component
1039*7a6dacacSDimitry Andric   if (IsVecRegPair(Producer) && IsVecRegSingle(Consumer)) {
1040*7a6dacacSDimitry Andric     unsigned Rev = IsReverseVecRegPair(Producer);
1041*7a6dacacSDimitry Andric     return ((Consumer - Hexagon::V0) & 0x1) ^ Rev;
1042*7a6dacacSDimitry Andric   }
10430b57cec5SDimitry Andric   if (Producer2 != Hexagon::NoRegister)
10440b57cec5SDimitry Andric     return Consumer == Producer;
10450b57cec5SDimitry Andric   return 0;
10460b57cec5SDimitry Andric }
104704eeddc0SDimitry Andric 
LoopNeedsPadding(MCInst const & MCB)104804eeddc0SDimitry Andric bool HexagonMCInstrInfo::LoopNeedsPadding(MCInst const &MCB) {
104904eeddc0SDimitry Andric   return (
105004eeddc0SDimitry Andric       (HexagonMCInstrInfo::isInnerLoop(MCB) &&
105104eeddc0SDimitry Andric        (HexagonMCInstrInfo::bundleSize(MCB) < HEXAGON_PACKET_INNER_SIZE)) ||
105204eeddc0SDimitry Andric       ((HexagonMCInstrInfo::isOuterLoop(MCB) &&
105304eeddc0SDimitry Andric         (HexagonMCInstrInfo::bundleSize(MCB) < HEXAGON_PACKET_OUTER_SIZE))));
105404eeddc0SDimitry Andric }
105504eeddc0SDimitry Andric 
IsABranchingInst(MCInstrInfo const & MCII,MCSubtargetInfo const & STI,MCInst const & I)105604eeddc0SDimitry Andric bool HexagonMCInstrInfo::IsABranchingInst(MCInstrInfo const &MCII,
105704eeddc0SDimitry Andric                                           MCSubtargetInfo const &STI,
105804eeddc0SDimitry Andric                                           MCInst const &I) {
105904eeddc0SDimitry Andric   assert(!HexagonMCInstrInfo::isBundle(I));
106004eeddc0SDimitry Andric   MCInstrDesc const &Desc = HexagonMCInstrInfo::getDesc(MCII, I);
106104eeddc0SDimitry Andric   return (Desc.isBranch() || Desc.isCall() || Desc.isReturn());
106204eeddc0SDimitry Andric }
1063