diff options
Diffstat (limited to 'llvm/lib/Target/Hexagon/MCTargetDesc')
7 files changed, 317 insertions, 112 deletions
diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h index 6a72f205e9d..342a61190e6 100644 --- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h @@ -190,7 +190,7 @@ namespace HexagonII { MO_GPREL }; - enum class InstParseBits : uint32_t { + enum InstParseBits { INST_PARSE_MASK = 0x0000c000, INST_PARSE_PACKET_END = 0x0000c000, INST_PARSE_LOOP_END = 0x00008000, diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.cpp index 15cda717cf1..73f20f52439 100644 --- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.cpp +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.cpp @@ -28,7 +28,47 @@ using namespace llvm; #define GET_INSTRUCTION_NAME #include "HexagonGenAsmWriter.inc" -const char HexagonInstPrinter::PacketPadding = '\t'; +HexagonAsmInstPrinter::HexagonAsmInstPrinter(MCInstPrinter *RawPrinter) + : MCInstPrinter(*RawPrinter), RawPrinter(RawPrinter) {} + +void HexagonAsmInstPrinter::printInst(MCInst const *MI, raw_ostream &O, + StringRef Annot, + MCSubtargetInfo const &STI) { + assert(HexagonMCInstrInfo::isBundle(*MI)); + assert(HexagonMCInstrInfo::bundleSize(*MI) <= HEXAGON_PACKET_SIZE); + std::string Buffer; + { + raw_string_ostream TempStream(Buffer); + RawPrinter->printInst(MI, TempStream, "", STI); + } + StringRef Contents(Buffer); + auto PacketBundle = Contents.rsplit('\n'); + auto HeadTail = PacketBundle.first.split('\n'); + auto Preamble = "\t{\n\t\t"; + auto Separator = ""; + while(!HeadTail.first.empty()) { + O << Separator; + StringRef Inst; + auto Duplex = HeadTail.first.split('\v'); + if(!Duplex.second.empty()){ + O << Duplex.first << "\n"; + Inst = Duplex.second; + } + else + Inst = Duplex.first; + O << Preamble; + O << Inst; + HeadTail = HeadTail.second.split('\n'); + Preamble = ""; + Separator = "\n\t\t"; + } + O << "\n\t}" << PacketBundle.second; +} + +void HexagonAsmInstPrinter::printRegName(raw_ostream &O, unsigned RegNo) const { + RawPrinter->printRegName(O, RegNo); +} + // Return the minimum value that a constant extendable operand can have // without being extended. static int getMinValue(uint64_t TSFlags) { @@ -77,48 +117,38 @@ void HexagonInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const { OS << getRegisterName(RegNo); } -void HexagonInstPrinter::printInst(MCInst const *MI, raw_ostream &O, - StringRef Annot, - const MCSubtargetInfo &STI) { - const char startPacket = '{', - endPacket = '}'; - // TODO: add outer HW loop when it's supported too. - if (MI->getOpcode() == Hexagon::ENDLOOP0) { - // Ending a harware loop is different from ending an regular packet. - assert(HexagonMCInstrInfo::isPacketEnd(*MI) && "Loop-end must also end the packet"); - - if (HexagonMCInstrInfo::isPacketBegin(*MI)) { - // There must be a packet to end a loop. - // FIXME: when shuffling is always run, this shouldn't be needed. - MCInst Nop; - StringRef NoAnnot; - - Nop.setOpcode (Hexagon::A2_nop); - HexagonMCInstrInfo::setPacketBegin (Nop, HexagonMCInstrInfo::isPacketBegin(*MI)); - printInst (&Nop, O, NoAnnot, STI); - } +void HexagonInstPrinter::setExtender(MCInst const &MCI) { + HasExtender = HexagonMCInstrInfo::isImmext(MCI); +} - // Close the packet. - if (HexagonMCInstrInfo::isPacketEnd(*MI)) - O << PacketPadding << endPacket; +void HexagonInstPrinter::printInst(MCInst const *MI, raw_ostream &OS, + StringRef Annot, + MCSubtargetInfo const &STI) { + assert(HexagonMCInstrInfo::isBundle(*MI)); + assert(HexagonMCInstrInfo::bundleSize(*MI) <= HEXAGON_PACKET_SIZE); + HasExtender = false; + for (auto const &I : HexagonMCInstrInfo::bundleInstructions(*MI)) { + MCInst const &MCI = *I.getInst(); + printInstruction(&MCI, OS); + setExtender(MCI); + OS << "\n"; + } - printInstruction(MI, O); + auto Separator = ""; + if (HexagonMCInstrInfo::isInnerLoop(*MI)) { + OS << Separator; + Separator = " "; + MCInst ME; + ME.setOpcode(Hexagon::ENDLOOP0); + printInstruction(&ME, OS); } - else { - // Prefix the insn opening the packet. - if (HexagonMCInstrInfo::isPacketBegin(*MI)) - O << PacketPadding << startPacket << '\n'; - - printInstruction(MI, O); - - // Suffix the insn closing the packet. - if (HexagonMCInstrInfo::isPacketEnd(*MI)) - // Suffix the packet in a new line always, since the GNU assembler has - // issues with a closing brace on the same line as CONST{32,64}. - O << '\n' << PacketPadding << endPacket; + if (HexagonMCInstrInfo::isOuterLoop(*MI)) { + OS << Separator; + Separator = " "; + MCInst ME; + ME.setOpcode(Hexagon::ENDLOOP1); + printInstruction(&ME, OS); } - - printAnnotation(O, Annot); } void HexagonInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.h b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.h index 3fedaed8fbf..534ac237d63 100644 --- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.h +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.h @@ -18,6 +18,21 @@ #include "llvm/MC/MCInstrInfo.h" namespace llvm { +class HexagonAsmInstPrinter : public MCInstPrinter { +public: + HexagonAsmInstPrinter(MCInstPrinter *RawPrinter); + void printInst(MCInst const *MI, raw_ostream &O, StringRef Annot, + MCSubtargetInfo const &STI) override; + void printRegName(raw_ostream &O, unsigned RegNo) const override; + std::unique_ptr<MCInstPrinter> RawPrinter; +}; +/// Prints bundles as a newline separated list of individual instructions +/// Duplexes are separated by a vertical tab \v character +/// A trailing line includes bundle properties such as endloop0/1 +/// +/// r0 = add(r1, r2) +/// r0 = #0 \v jump 0x0 +/// :endloop0 :endloop1 class HexagonInstPrinter : public MCInstPrinter { public: explicit HexagonInstPrinter(MCAsmInfo const &MAI, @@ -74,11 +89,11 @@ namespace llvm { void printSymbol(const MCInst *MI, unsigned OpNo, raw_ostream &O, bool hi) const; - static const char PacketPadding; - private: const MCInstrInfo &MII; + bool HasExtender; + void setExtender(MCInst const &MCI); }; } // end namespace llvm diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp index ae3953abba1..c457fa895bc 100644 --- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp @@ -32,16 +32,6 @@ using namespace Hexagon; STATISTIC(MCNumEmitted, "Number of MC instructions emitted"); namespace { -/// \brief 10.6 Instruction Packets -/// Possible values for instruction packet parse field. -enum class ParseField { duplex = 0x0, last0 = 0x1, last1 = 0x2, end = 0x3 }; -/// \brief Returns the packet bits based on instruction position. -uint32_t getPacketBits(MCInst const &HMI) { - unsigned const ParseFieldOffset = 14; - ParseField Field = HexagonMCInstrInfo::isPacketEnd(HMI) ? ParseField::end - : ParseField::last0; - return static_cast<uint32_t>(Field) << ParseFieldOffset; -} void emitLittleEndian(uint64_t Binary, raw_ostream &OS) { OS << static_cast<uint8_t>((Binary >> 0x00) & 0xff); OS << static_cast<uint8_t>((Binary >> 0x08) & 0xff); @@ -53,15 +43,120 @@ void emitLittleEndian(uint64_t Binary, raw_ostream &OS) { HexagonMCCodeEmitter::HexagonMCCodeEmitter(MCInstrInfo const &aMII, MCContext &aMCT) : MCT(aMCT), MCII(aMII), Addend(new unsigned(0)), - Extended(new bool(false)) {} + Extended(new bool(false)), CurrentBundle(new MCInst const *) {} + +uint32_t HexagonMCCodeEmitter::parseBits(size_t Instruction, size_t Last, + MCInst const &MCB, + MCInst const &MCI) const { + if (Instruction == 0) { + if (HexagonMCInstrInfo::isInnerLoop(MCB)) { + assert(Instruction != Last); + return HexagonII::INST_PARSE_LOOP_END; + } + } + if (Instruction == 1) { + if (HexagonMCInstrInfo::isOuterLoop(MCB)) { + assert(Instruction != Last); + return HexagonII::INST_PARSE_LOOP_END; + } + } + if(Instruction == Last) + return HexagonII::INST_PARSE_PACKET_END; + return HexagonII::INST_PARSE_NOT_END; +} void HexagonMCCodeEmitter::encodeInstruction(MCInst const &MI, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups, MCSubtargetInfo const &STI) const { - uint64_t Binary = getBinaryCodeForInstr(MI, Fixups, STI) | getPacketBits(MI); - assert(HexagonMCInstrInfo::getDesc(MCII, MI).getSize() == 4 && - "All instructions should be 32bit"); - (void)&MCII; + MCInst &HMB = const_cast<MCInst &>(MI); + + assert(HexagonMCInstrInfo::isBundle(HMB)); + DEBUG(dbgs() << "Encoding bundle\n";); + *Addend = 0; + *Extended = false; + *CurrentBundle = &MI; + size_t Instruction = 0; + size_t Last = HexagonMCInstrInfo::bundleSize(HMB) - 1; + for (auto &I : HexagonMCInstrInfo::bundleInstructions(HMB)) { + MCInst &HMI = const_cast<MCInst &>(*I.getInst()); + EncodeSingleInstruction(HMI, OS, Fixups, STI, + parseBits(Instruction, Last, HMB, HMI), + Instruction); + *Extended = HexagonMCInstrInfo::isImmext(HMI); + *Addend += HEXAGON_INSTR_SIZE; + ++Instruction; + } + return; +} + +/// EncodeSingleInstruction - Emit a single +void HexagonMCCodeEmitter::EncodeSingleInstruction( + const MCInst &MI, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI, uint32_t Parse, size_t Index) const { + MCInst HMB = MI; + assert(!HexagonMCInstrInfo::isBundle(HMB)); + uint64_t Binary; + + // Pseudo instructions don't get encoded and shouldn't be here + // in the first place! + assert(!HexagonMCInstrInfo::getDesc(MCII, HMB).isPseudo() && + "pseudo-instruction found"); + DEBUG(dbgs() << "Encoding insn" + " `" << HexagonMCInstrInfo::getName(MCII, HMB) << "'" + "\n"); + + if (HexagonMCInstrInfo::isNewValue(MCII, HMB)) { + // Calculate the new value distance to the associated producer + MCOperand &MCO = + HMB.getOperand(HexagonMCInstrInfo::getNewValueOp(MCII, HMB)); + unsigned SOffset = 0; + unsigned Register = MCO.getReg(); + unsigned Register1; + auto Instructions = HexagonMCInstrInfo::bundleInstructions(**CurrentBundle); + auto i = Instructions.begin() + Index - 1; + for (;; --i) { + assert(i != Instructions.begin() - 1 && "Couldn't find producer"); + MCInst const &Inst = *i->getInst(); + if (HexagonMCInstrInfo::isImmext(Inst)) + continue; + ++SOffset; + Register1 = + HexagonMCInstrInfo::hasNewValue(MCII, Inst) + ? HexagonMCInstrInfo::getNewValueOperand(MCII, Inst).getReg() + : static_cast<unsigned>(Hexagon::NoRegister); + if (Register != Register1) + // This isn't the register we're looking for + continue; + if (!HexagonMCInstrInfo::isPredicated(MCII, Inst)) + // Producer is unpredicated + break; + assert(HexagonMCInstrInfo::isPredicated(MCII, HMB) && + "Unpredicated consumer depending on predicated producer"); + if (HexagonMCInstrInfo::isPredicatedTrue(MCII, Inst) == + HexagonMCInstrInfo::isPredicatedTrue(MCII, HMB)) + // Producer predicate sense matched ours + break; + } + // Hexagon PRM 10.11 Construct Nt from distance + unsigned Offset = SOffset; + Offset <<= 1; + MCO.setReg(Offset + Hexagon::R0); + } + + Binary = getBinaryCodeForInstr(HMB, Fixups, STI); + // Check for unimplemented instructions. Immediate extenders + // are encoded as zero, so they need to be accounted for. + if ((!Binary) && + ((HMB.getOpcode() != DuplexIClass0) && (HMB.getOpcode() != A4_ext) && + (HMB.getOpcode() != A4_ext_b) && (HMB.getOpcode() != A4_ext_c) && + (HMB.getOpcode() != A4_ext_g))) { + // Use a A2_nop for unimplemented instructions. + DEBUG(dbgs() << "Unimplemented inst: " + " `" << HexagonMCInstrInfo::getName(MCII, HMB) << "'" + "\n"); + llvm_unreachable("Unimplemented Instruction"); + } + Binary |= Parse; emitLittleEndian(Binary, OS); ++MCNumEmitted; } diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.h b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.h index 939380af101..9aa258cee4c 100644 --- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.h +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.h @@ -30,6 +30,7 @@ class HexagonMCCodeEmitter : public MCCodeEmitter { MCInstrInfo const &MCII; std::unique_ptr<unsigned> Addend; std::unique_ptr<bool> Extended; + std::unique_ptr<MCInst const *> CurrentBundle; // helper routine for getMachineOpValue() unsigned getExprOpValue(const MCInst &MI, const MCOperand &MO, @@ -39,12 +40,21 @@ class HexagonMCCodeEmitter : public MCCodeEmitter { public: HexagonMCCodeEmitter(MCInstrInfo const &aMII, MCContext &aMCT); + // Return parse bits for instruction `MCI' inside bundle `MCB' + uint32_t parseBits(size_t Instruction, size_t Last, MCInst const &MCB, + MCInst const &MCI) const; + MCSubtargetInfo const &getSubtargetInfo() const; void encodeInstruction(MCInst const &MI, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups, MCSubtargetInfo const &STI) const override; + void EncodeSingleInstruction(const MCInst &MI, raw_ostream &OS, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI, + uint32_t Parse, size_t Index) const; + // \brief TableGen'erated function for getting the // binary encoding for an instruction. uint64_t getBinaryCodeForInstr(MCInst const &MI, diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp index 93c7a0d98bf..88bbe76472b 100644 --- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp @@ -11,13 +11,23 @@ // //===----------------------------------------------------------------------===// -#include "HexagonMCInstrInfo.h" +#include "Hexagon.h" #include "HexagonBaseInfo.h" +#include "HexagonMCInstrInfo.h" namespace llvm { -void HexagonMCInstrInfo::AppendImplicitOperands(MCInst &MCI) { - MCI.addOperand(MCOperand::createImm(0)); - MCI.addOperand(MCOperand::createInst(nullptr)); +iterator_range<MCInst::const_iterator> +HexagonMCInstrInfo::bundleInstructions(MCInst const &MCI) { + assert(isBundle(MCI)); + return iterator_range<MCInst::const_iterator>( + MCI.begin() + bundleInstructionsOffset, MCI.end()); +} + +size_t HexagonMCInstrInfo::bundleSize(MCInst const &MCI) { + if (HexagonMCInstrInfo::isBundle(MCI)) + return (MCI.size() - bundleInstructionsOffset); + else + return (1); } HexagonII::MemAccessSize @@ -58,12 +68,6 @@ unsigned HexagonMCInstrInfo::getExtentBits(MCInstrInfo const &MCII, return ((F >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask); } -std::bitset<16> HexagonMCInstrInfo::GetImplicitBits(MCInst const &MCI) { - SanityCheckImplicitOperands(MCI); - std::bitset<16> Bits(MCI.getOperand(MCI.getNumOperands() - 2).getImm()); - return Bits; -} - // Return the max value that a constant extendable operand can have // without being extended. int HexagonMCInstrInfo::getMaxValue(MCInstrInfo const &MCII, @@ -99,9 +103,14 @@ char const *HexagonMCInstrInfo::getName(MCInstrInfo const &MCII, return MCII.getName(MCI.getOpcode()); } -// Return the operand that consumes or produces a new value. -MCOperand const &HexagonMCInstrInfo::getNewValue(MCInstrInfo const &MCII, +unsigned short HexagonMCInstrInfo::getNewValueOp(MCInstrInfo const &MCII, MCInst const &MCI) { + const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; + return ((F >> HexagonII::NewValueOpPos) & HexagonII::NewValueOpMask); +} + +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; @@ -128,6 +137,12 @@ bool HexagonMCInstrInfo::hasNewValue(MCInstrInfo const &MCII, return ((F >> HexagonII::hasNewValuePos) & HexagonII::hasNewValueMask); } +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() && @@ -187,6 +202,18 @@ bool HexagonMCInstrInfo::isExtended(MCInstrInfo const &MCII, return (F >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask; } +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); +} + +bool HexagonMCInstrInfo::isInnerLoop(MCInst const &MCI) { + assert(isBundle(MCI)); + int64_t Flags = MCI.getOperand(0).getImm(); + return (Flags & innerLoopMask) != 0; +} + // Return whether the insn is a new-value consumer. bool HexagonMCInstrInfo::isNewValue(MCInstrInfo const &MCII, MCInst const &MCI) { @@ -203,14 +230,23 @@ bool HexagonMCInstrInfo::isOperandExtended(MCInstrInfo const &MCII, OperandNum; } -bool HexagonMCInstrInfo::isPacketBegin(MCInst const &MCI) { - std::bitset<16> Bits(GetImplicitBits(MCI)); - return Bits.test(packetBeginIndex); +bool HexagonMCInstrInfo::isOuterLoop(MCInst const &MCI) { + assert(isBundle(MCI)); + int64_t Flags = MCI.getOperand(0).getImm(); + return (Flags & outerLoopMask) != 0; } -bool HexagonMCInstrInfo::isPacketEnd(MCInst const &MCI) { - std::bitset<16> Bits(GetImplicitBits(MCI)); - return Bits.test(packetEndIndex); +bool HexagonMCInstrInfo::isPredicated(MCInstrInfo const &MCII, + MCInst const &MCI) { + const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; + return ((F >> HexagonII::PredicatedPos) & HexagonII::PredicatedMask); +} + +bool HexagonMCInstrInfo::isPredicatedTrue(MCInstrInfo const &MCII, + MCInst const &MCI) { + const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; + return ( + !((F >> HexagonII::PredicatedFalsePos) & HexagonII::PredicatedFalseMask)); } // Return whether the insn is a prefix. @@ -224,25 +260,26 @@ bool HexagonMCInstrInfo::isSolo(MCInstrInfo const &MCII, MCInst const &MCI) { return ((F >> HexagonII::SoloPos) & HexagonII::SoloMask); } -void HexagonMCInstrInfo::resetPacket(MCInst &MCI) { - setPacketBegin(MCI, false); - setPacketEnd(MCI, false); -} - -void HexagonMCInstrInfo::SetImplicitBits(MCInst &MCI, std::bitset<16> Bits) { - SanityCheckImplicitOperands(MCI); - MCI.getOperand(MCI.getNumOperands() - 2).setImm(Bits.to_ulong()); +void HexagonMCInstrInfo::padEndloop(MCInst &MCB) { + MCInst Nop; + Nop.setOpcode(Hexagon::A2_nop); + assert(isBundle(MCB)); + while ((HexagonMCInstrInfo::isInnerLoop(MCB) && + (HexagonMCInstrInfo::bundleSize(MCB) < HEXAGON_PACKET_INNER_SIZE)) || + ((HexagonMCInstrInfo::isOuterLoop(MCB) && + (HexagonMCInstrInfo::bundleSize(MCB) < HEXAGON_PACKET_OUTER_SIZE)))) + MCB.addOperand(MCOperand::createInst(new MCInst(Nop))); } -void HexagonMCInstrInfo::setPacketBegin(MCInst &MCI, bool f) { - std::bitset<16> Bits(GetImplicitBits(MCI)); - Bits.set(packetBeginIndex, f); - SetImplicitBits(MCI, Bits); +void HexagonMCInstrInfo::setInnerLoop(MCInst &MCI) { + assert(isBundle(MCI)); + MCOperand &Operand = MCI.getOperand(0); + Operand.setImm(Operand.getImm() | innerLoopMask); } -void HexagonMCInstrInfo::setPacketEnd(MCInst &MCI, bool f) { - std::bitset<16> Bits(GetImplicitBits(MCI)); - Bits.set(packetEndIndex, f); - SetImplicitBits(MCI, Bits); +void HexagonMCInstrInfo::setOuterLoop(MCInst &MCI) { + assert(isBundle(MCI)); + MCOperand &Operand = MCI.getOperand(0); + Operand.setImm(Operand.getImm() | outerLoopMask); } } diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h index 082c80d5ac0..0301e4814c6 100644 --- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h @@ -28,7 +28,19 @@ namespace HexagonII { enum class MemAccessSize; } namespace HexagonMCInstrInfo { -void AppendImplicitOperands(MCInst &MCI); +size_t const innerLoopOffset = 0; +int64_t const innerLoopMask = 1 << innerLoopOffset; + +size_t const outerLoopOffset = 1; +int64_t const outerLoopMask = 1 << outerLoopOffset; + +size_t const bundleInstructionsOffset = 1; + +// Returns the number of instructions in the bundle +size_t bundleSize(MCInst const &MCI); + +// Returns a iterator range of instructions in this bundle +iterator_range<MCInst::const_iterator> bundleInstructions(MCInst const &MCI); // Return memory access size HexagonII::MemAccessSize getAccessSize(MCInstrInfo const &MCII, @@ -48,8 +60,6 @@ unsigned getExtentAlignment(MCInstrInfo const &MCII, MCInst const &MCI); // Return the number of logical bits of the extendable operand unsigned getExtentBits(MCInstrInfo const &MCII, MCInst const &MCI); -std::bitset<16> GetImplicitBits(MCInst const &MCI); - // Return the max value that a constant extendable operand can have // without being extended. int getMaxValue(MCInstrInfo const &MCII, MCInst const &MCI); @@ -61,8 +71,11 @@ int getMinValue(MCInstrInfo const &MCII, MCInst const &MCI); // Return instruction name char const *getName(MCInstrInfo const &MCII, MCInst const &MCI); +// Return the operand index for the new value. +unsigned short getNewValueOp(MCInstrInfo const &MCII, MCInst const &MCI); + // Return the operand that consumes or produces a new value. -MCOperand const &getNewValue(MCInstrInfo const &MCII, MCInst const &MCI); +MCOperand const &getNewValueOperand(MCInstrInfo const &MCII, MCInst const &MCI); // Return the Hexagon ISA class for the insn. unsigned getType(MCInstrInfo const &MCII, MCInst const &MCI); @@ -70,6 +83,9 @@ unsigned getType(MCInstrInfo const &MCII, MCInst const &MCI); // Return whether the instruction is a legal new-value producer. bool hasNewValue(MCInstrInfo const &MCII, MCInst const &MCI); +// Returns whether this MCInst is a wellformed bundle +bool isBundle(MCInst const &MCI); + // Return whether the insn is an actual insn. bool isCanon(MCInstrInfo const &MCII, MCInst const &MCI); @@ -82,6 +98,12 @@ bool isExtendable(MCInstrInfo const &MCII, MCInst const &MCI); // Return whether the instruction must be always extended. bool isExtended(MCInstrInfo const &MCII, MCInst const &MCI); +// Returns whether this instruction is an immediate extender +bool isImmext(MCInst const &MCI); + +// Returns whether this bundle is an endloop0 +bool isInnerLoop(MCInst const &MCI); + // Return whether the insn is a new-value consumer. bool isNewValue(MCInstrInfo const &MCII, MCInst const &MCI); @@ -89,9 +111,14 @@ bool isNewValue(MCInstrInfo const &MCII, MCInst const &MCI); bool isOperandExtended(MCInstrInfo const &MCII, MCInst const &MCI, unsigned short OperandNum); -bool isPacketBegin(MCInst const &MCI); +// Returns whether this bundle is an endloop1 +bool isOuterLoop(MCInst const &MCI); -bool isPacketEnd(MCInst const &MCI); +// Return whether this instruction is predicated +bool isPredicated(MCInstrInfo const &MCII, MCInst const &MCI); + +// Return whether the predicate sense is true +bool isPredicatedTrue(MCInstrInfo const &MCII, MCInst const &MCI); // Return whether the insn is a prefix. bool isPrefix(MCInstrInfo const &MCII, MCInst const &MCI); @@ -99,23 +126,14 @@ bool isPrefix(MCInstrInfo const &MCII, MCInst const &MCI); // Return whether the insn is solo, i.e., cannot be in a packet. bool isSolo(MCInstrInfo const &MCII, MCInst const &MCI); -static const size_t packetBeginIndex = 0; -static const size_t packetEndIndex = 1; - -void resetPacket(MCInst &MCI); - -inline void SanityCheckImplicitOperands(MCInst const &MCI) { - assert(MCI.getNumOperands() >= 2 && "At least the two implicit operands"); - assert(MCI.getOperand(MCI.getNumOperands() - 1).isInst() && - "Implicit bits and flags"); - assert(MCI.getOperand(MCI.getNumOperands() - 2).isImm() && "Parent pointer"); -} - -void SetImplicitBits(MCInst &MCI, std::bitset<16> Bits); +// Pad the bundle with nops to satisfy endloop requirements +void padEndloop(MCInst &MCI); -void setPacketBegin(MCInst &MCI, bool Y); +// Marks a bundle as endloop0 +void setInnerLoop(MCInst &MCI); -void setPacketEnd(MCInst &MCI, bool Y); +// Marks a bundle as endloop1 +void setOuterLoop(MCInst &MCI); } } |

