[llvm] r238556 - [Hexagon] Disassembling, printing, and emitting instructions a whole-bundle at a time which is the semantic unit for Hexagon. Fixing tests to use the new format. Disabling tests in the direct object emission path for a followup patch.

Colin LeMahieu colinl at codeaurora.org
Fri May 29 07:44:14 PDT 2015


Author: colinl
Date: Fri May 29 09:44:13 2015
New Revision: 238556

URL: http://llvm.org/viewvc/llvm-project?rev=238556&view=rev
Log:
[Hexagon] Disassembling, printing, and emitting instructions a whole-bundle at a time which is the semantic unit for Hexagon.  Fixing tests to use the new format.  Disabling tests in the direct object emission path for a followup patch.

Modified:
    llvm/trunk/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp
    llvm/trunk/lib/Target/Hexagon/Hexagon.h
    llvm/trunk/lib/Target/Hexagon/HexagonAsmPrinter.cpp
    llvm/trunk/lib/Target/Hexagon/HexagonInstrFormats.td
    llvm/trunk/lib/Target/Hexagon/HexagonMCInstLower.cpp
    llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h
    llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.cpp
    llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.h
    llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp
    llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.h
    llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp
    llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h
    llvm/trunk/test/CodeGen/Hexagon/cext-valid-packet1.ll
    llvm/trunk/test/CodeGen/Hexagon/cext-valid-packet2.ll
    llvm/trunk/test/MC/Hexagon/inst_cmp_eq.ll
    llvm/trunk/test/MC/Hexagon/inst_cmp_eqi.ll
    llvm/trunk/test/MC/Hexagon/inst_cmp_gt.ll
    llvm/trunk/test/MC/Hexagon/inst_cmp_gti.ll
    llvm/trunk/test/MC/Hexagon/inst_cmp_lt.ll
    llvm/trunk/test/MC/Hexagon/inst_cmp_ugt.ll
    llvm/trunk/test/MC/Hexagon/inst_cmp_ugti.ll
    llvm/trunk/test/MC/Hexagon/inst_cmp_ult.ll
    llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp

Modified: llvm/trunk/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp?rev=238556&r1=238555&r2=238556&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp Fri May 29 09:44:13 2015
@@ -7,9 +7,11 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "Hexagon.h"
 #include "MCTargetDesc/HexagonBaseInfo.h"
 #include "MCTargetDesc/HexagonMCInstrInfo.h"
 #include "MCTargetDesc/HexagonMCTargetDesc.h"
+
 #include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCDisassembler.h"
 #include "llvm/MC/MCExpr.h"
@@ -27,6 +29,7 @@
 #include <vector>
 
 using namespace llvm;
+using namespace Hexagon;
 
 #define DEBUG_TYPE "hexagon-disassembler"
 
@@ -37,9 +40,14 @@ namespace {
 /// \brief Hexagon disassembler for all Hexagon platforms.
 class HexagonDisassembler : public MCDisassembler {
 public:
+  std::unique_ptr<MCInst *> CurrentBundle;
   HexagonDisassembler(MCSubtargetInfo const &STI, MCContext &Ctx)
-      : MCDisassembler(STI, Ctx) {}
+      : MCDisassembler(STI, Ctx), CurrentBundle(new MCInst *) {}
 
+  DecodeStatus getSingleInstruction(MCInst &Instr, MCInst &MCB,
+                                    ArrayRef<uint8_t> Bytes, uint64_t Address,
+                                    raw_ostream &VStream, raw_ostream &CStream,
+                                    bool &Complete) const;
   DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
                               ArrayRef<uint8_t> Bytes, uint64_t Address,
                               raw_ostream &VStream,
@@ -191,17 +199,53 @@ DecodeStatus HexagonDisassembler::getIns
                                                  uint64_t Address,
                                                  raw_ostream &os,
                                                  raw_ostream &cs) const {
-  Size = 4;
-  if (Bytes.size() < 4)
-    return MCDisassembler::Fail;
+  DecodeStatus Result = DecodeStatus::Success;
+  bool Complete = false;
+  Size = 0;
+
+  *CurrentBundle = &MI;
+  MI.setOpcode(Hexagon::BUNDLE);
+  MI.addOperand(MCOperand::createImm(0));
+  while (Result == Success && Complete == false)
+  {
+    if (Bytes.size() < HEXAGON_INSTR_SIZE)
+      return MCDisassembler::Fail;
+    MCInst * Inst = new (getContext()) MCInst;
+    Result = getSingleInstruction(*Inst, MI, Bytes, Address, os, cs, Complete);
+    MI.addOperand(MCOperand::createInst(Inst));
+    Size += HEXAGON_INSTR_SIZE;
+    Bytes = Bytes.slice(HEXAGON_INSTR_SIZE);
+  }
+  return Result;
+}
 
-  uint32_t insn =
+DecodeStatus HexagonDisassembler::getSingleInstruction(
+    MCInst &MI, MCInst &MCB, ArrayRef<uint8_t> Bytes, uint64_t Address,
+    raw_ostream &os, raw_ostream &cs, bool &Complete) const {
+  assert(Bytes.size() >= HEXAGON_INSTR_SIZE);
+
+  uint32_t Instruction =
       llvm::support::endian::read<uint32_t, llvm::support::little,
                                   llvm::support::unaligned>(Bytes.data());
 
-  // Remove parse bits.
-  insn &= ~static_cast<uint32_t>(HexagonII::InstParseBits::INST_PARSE_MASK);
-  DecodeStatus Result = decodeInstruction(DecoderTable32, MI, insn, Address, this, STI);
-  HexagonMCInstrInfo::AppendImplicitOperands(MI);
+  auto BundleSize = HexagonMCInstrInfo::bundleSize(MCB);
+  if ((Instruction & HexagonII::INST_PARSE_MASK) ==
+      HexagonII::INST_PARSE_LOOP_END) {
+    if (BundleSize == 0)
+      HexagonMCInstrInfo::setInnerLoop(MCB);
+    else if (BundleSize == 1)
+      HexagonMCInstrInfo::setOuterLoop(MCB);
+    else
+      return DecodeStatus::Fail;
+  }
+
+  DecodeStatus Result = DecodeStatus::Success;
+  if ((Instruction & HexagonII::INST_PARSE_MASK) ==
+      HexagonII::INST_PARSE_PACKET_END)
+    Complete = true;
+  // Calling the auto-generated decoder function.
+  Result =
+      decodeInstruction(DecoderTable32, MI, Instruction, Address, this, STI);
+
   return Result;
 }

Modified: llvm/trunk/lib/Target/Hexagon/Hexagon.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/Hexagon.h?rev=238556&r1=238555&r2=238556&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/Hexagon.h (original)
+++ llvm/trunk/lib/Target/Hexagon/Hexagon.h Fri May 29 09:44:13 2015
@@ -76,4 +76,8 @@ namespace llvm {
 // Maximum number of words and instructions in a packet.
 #define HEXAGON_PACKET_SIZE 4
 
+// Minimum number of instructions in an end-loop packet.
+#define HEXAGON_PACKET_INNER_SIZE 2
+#define HEXAGON_PACKET_OUTER_SIZE 3
+
 #endif

Modified: llvm/trunk/lib/Target/Hexagon/HexagonAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonAsmPrinter.cpp?rev=238556&r1=238555&r2=238556&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonAsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonAsmPrinter.cpp Fri May 29 09:44:13 2015
@@ -177,47 +177,29 @@ bool HexagonAsmPrinter::PrintAsmMemoryOp
 /// the current output stream.
 ///
 void HexagonAsmPrinter::EmitInstruction(const MachineInstr *MI) {
-  if (MI->isBundle()) {
-    std::vector<MachineInstr const *> BundleMIs;
+  MCInst MCB;
+  MCB.setOpcode(Hexagon::BUNDLE);
+  MCB.addOperand(MCOperand::createImm(0));
 
-    const MachineBasicBlock *MBB = MI->getParent();
+  if (MI->isBundle()) {
+    const MachineBasicBlock* MBB = MI->getParent();
     MachineBasicBlock::const_instr_iterator MII = MI;
-    ++MII;
-    unsigned int IgnoreCount = 0;
-    while (MII != MBB->end() && MII->isInsideBundle()) {
-      const MachineInstr *MInst = MII;
-      if (MInst->getOpcode() == TargetOpcode::DBG_VALUE ||
-        MInst->getOpcode() == TargetOpcode::IMPLICIT_DEF) {
-        IgnoreCount++;
-        ++MII;
-        continue;
-      }
-      // BundleMIs.push_back(&*MII);
-      BundleMIs.push_back(MInst);
-      ++MII;
-    }
-    unsigned Size = BundleMIs.size();
-    assert((Size + IgnoreCount) == MI->getBundleSize() && "Corrupt Bundle!");
-    for (unsigned Index = 0; Index < Size; Index++) {
-      MCInst MCI;
+    unsigned IgnoreCount = 0;
 
-      HexagonLowerToMC(BundleMIs[Index], MCI, *this);
-      HexagonMCInstrInfo::AppendImplicitOperands(MCI);
-      HexagonMCInstrInfo::setPacketBegin(MCI, Index == 0);
-      HexagonMCInstrInfo::setPacketEnd(MCI, Index == (Size - 1));
-      EmitToStreamer(*OutStreamer, MCI);
+    for (++MII; MII != MBB->end() && MII->isInsideBundle(); ++MII) {
+      if (MII->getOpcode() == TargetOpcode::DBG_VALUE ||
+          MII->getOpcode() == TargetOpcode::IMPLICIT_DEF)
+        ++IgnoreCount;
+      else {
+        HexagonLowerToMC(MII, MCB, *this);
+      }
     }
   }
   else {
-    MCInst MCI;
-    HexagonLowerToMC(MI, MCI, *this);
-    HexagonMCInstrInfo::AppendImplicitOperands(MCI);
-    if (MI->getOpcode() == Hexagon::ENDLOOP0) {
-      HexagonMCInstrInfo::setPacketBegin(MCI, true);
-      HexagonMCInstrInfo::setPacketEnd(MCI, true);
-    }
-    EmitToStreamer(*OutStreamer, MCI);
+    HexagonLowerToMC(MI, MCB, *this);
+    HexagonMCInstrInfo::padEndloop(MCB);
   }
+  EmitToStreamer(*OutStreamer, MCB);
 
   return;
 }

Modified: llvm/trunk/lib/Target/Hexagon/HexagonInstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonInstrFormats.td?rev=238556&r1=238555&r2=238556&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonInstrFormats.td (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonInstrFormats.td Fri May 29 09:44:13 2015
@@ -66,10 +66,8 @@ def DoubleWordAccess : MemAccessSize<4>;
 class OpcodeHexagon {
   field bits<32> Inst = ?; // Default to an invalid insn.
   bits<4> IClass = 0; // ICLASS
-  bits<2> IParse = 0; // Parse bits.
 
   let Inst{31-28} = IClass;
-  let Inst{15-14} = IParse;
 
   bits<1> zero = 0;
 }

Modified: llvm/trunk/lib/Target/Hexagon/HexagonMCInstLower.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonMCInstLower.cpp?rev=238556&r1=238555&r2=238556&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonMCInstLower.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonMCInstLower.cpp Fri May 29 09:44:13 2015
@@ -15,9 +15,12 @@
 #include "Hexagon.h"
 #include "HexagonAsmPrinter.h"
 #include "HexagonMachineFunctionInfo.h"
+#include "MCTargetDesc/HexagonMCInstrInfo.h"
+
 #include "llvm/CodeGen/MachineBasicBlock.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/Mangler.h"
+#include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCExpr.h"
 #include "llvm/MC/MCInst.h"
 
@@ -38,9 +41,20 @@ static MCOperand GetSymbolRef(const Mach
 }
 
 // Create an MCInst from a MachineInstr
-void llvm::HexagonLowerToMC(MachineInstr const* MI, MCInst& MCI,
+void llvm::HexagonLowerToMC(MachineInstr const* MI, MCInst& MCB,
                             HexagonAsmPrinter& AP) {
-  MCI.setOpcode(MI->getOpcode());
+  if(MI->getOpcode() == Hexagon::ENDLOOP0){
+    HexagonMCInstrInfo::setInnerLoop(MCB);
+    return;
+  }
+  if(MI->getOpcode() == Hexagon::ENDLOOP1){
+    HexagonMCInstrInfo::setOuterLoop(MCB);
+    return;
+  }
+  MCInst* MCI = new (AP.OutContext) MCInst;
+  MCI->setOpcode(MI->getOpcode());
+  assert(MCI->getOpcode() == static_cast<unsigned>(MI->getOpcode()) &&
+         "MCI opcode should have been set on construction");
 
   for (unsigned i = 0, e = MI->getNumOperands(); i < e; i++) {
     const MachineOperand &MO = MI->getOperand(i);
@@ -88,6 +102,7 @@ void llvm::HexagonLowerToMC(MachineInstr
       break;
     }
 
-    MCI.addOperand(MCO);
+    MCI->addOperand(MCO);
   }
+  MCB.addOperand(MCOperand::createInst(MCI));
 }

Modified: llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h?rev=238556&r1=238555&r2=238556&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h (original)
+++ llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h Fri May 29 09:44:13 2015
@@ -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,

Modified: llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.cpp?rev=238556&r1=238555&r2=238556&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.cpp Fri May 29 09:44:13 2015
@@ -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(ra
   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,

Modified: llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.h?rev=238556&r1=238555&r2=238556&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.h (original)
+++ llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.h Fri May 29 09:44:13 2015
@@ -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

Modified: llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp?rev=238556&r1=238555&r2=238556&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp Fri May 29 09:44:13 2015
@@ -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, r
 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;
 }

Modified: llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.h?rev=238556&r1=238555&r2=238556&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.h (original)
+++ llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.h Fri May 29 09:44:13 2015
@@ -30,6 +30,7 @@ class HexagonMCCodeEmitter : public MCCo
   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 MCCo
 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,

Modified: llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp?rev=238556&r1=238555&r2=238556&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp Fri May 29 09:44:13 2015
@@ -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::getExtentBi
   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(
   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(MCI
   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(MCIn
   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::isOperandExtend
          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(MCInstrI
   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::setPacketBegin(MCInst &MCI, bool f) {
-  std::bitset<16> Bits(GetImplicitBits(MCI));
-  Bits.set(packetBeginIndex, f);
-  SetImplicitBits(MCI, Bits);
-}
-
-void HexagonMCInstrInfo::setPacketEnd(MCInst &MCI, bool f) {
-  std::bitset<16> Bits(GetImplicitBits(MCI));
-  Bits.set(packetEndIndex, f);
-  SetImplicitBits(MCI, Bits);
+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::setInnerLoop(MCInst &MCI) {
+  assert(isBundle(MCI));
+  MCOperand &Operand = MCI.getOperand(0);
+  Operand.setImm(Operand.getImm() | innerLoopMask);
+}
+
+void HexagonMCInstrInfo::setOuterLoop(MCInst &MCI) {
+  assert(isBundle(MCI));
+  MCOperand &Operand = MCI.getOperand(0);
+  Operand.setImm(Operand.getImm() | outerLoopMask);
 }
 }

Modified: llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h?rev=238556&r1=238555&r2=238556&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h (original)
+++ llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h Fri May 29 09:44:13 2015
@@ -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
 // 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,
 // 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
 // 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 &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,
 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, M
 // 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);
 }
 }
 

Modified: llvm/trunk/test/CodeGen/Hexagon/cext-valid-packet1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Hexagon/cext-valid-packet1.ll?rev=238556&r1=238555&r2=238556&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Hexagon/cext-valid-packet1.ll (original)
+++ llvm/trunk/test/CodeGen/Hexagon/cext-valid-packet1.ll Fri May 29 09:44:13 2015
@@ -1,4 +1,5 @@
 ; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s | FileCheck %s
+; XFAIL:
 
 ; Check that the packetizer generates valid packets with constant
 ; extended instructions.

Modified: llvm/trunk/test/CodeGen/Hexagon/cext-valid-packet2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Hexagon/cext-valid-packet2.ll?rev=238556&r1=238555&r2=238556&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Hexagon/cext-valid-packet2.ll (original)
+++ llvm/trunk/test/CodeGen/Hexagon/cext-valid-packet2.ll Fri May 29 09:44:13 2015
@@ -1,4 +1,5 @@
 ; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s | FileCheck %s
+; XFAIL:
 ; Check that the packetizer generates valid packets with constant
 ; extended add and base+offset store instructions.
 

Modified: llvm/trunk/test/MC/Hexagon/inst_cmp_eq.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Hexagon/inst_cmp_eq.ll?rev=238556&r1=238555&r2=238556&view=diff
==============================================================================
--- llvm/trunk/test/MC/Hexagon/inst_cmp_eq.ll (original)
+++ llvm/trunk/test/MC/Hexagon/inst_cmp_eq.ll Fri May 29 09:44:13 2015
@@ -1,5 +1,5 @@
 ;; RUN: llc -mtriple=hexagon-unknown-elf -filetype=obj %s -o - \
-;; RUN: | llvm-objdump -s - | FileCheck %s
+;; RUN: | llvm-objdump -d - | FileCheck %s
 
 define i1 @foo (i32 %a, i32 %b)
 {
@@ -7,4 +7,6 @@ define i1 @foo (i32 %a, i32 %b)
   ret i1 %1
 }
 
-; CHECK:  0000 004100f2 00404089 00c09f52
+; CHECK: p0 = cmp.eq(r0, r1)
+; CHECK: r0 = p0
+; CHECK: jumpr r31

Modified: llvm/trunk/test/MC/Hexagon/inst_cmp_eqi.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Hexagon/inst_cmp_eqi.ll?rev=238556&r1=238555&r2=238556&view=diff
==============================================================================
--- llvm/trunk/test/MC/Hexagon/inst_cmp_eqi.ll (original)
+++ llvm/trunk/test/MC/Hexagon/inst_cmp_eqi.ll Fri May 29 09:44:13 2015
@@ -1,5 +1,5 @@
 ;; RUN: llc -mtriple=hexagon-unknown-elf -filetype=obj %s -o - \
-;; RUN: | llvm-objdump -s - | FileCheck %s
+;; RUN: | llvm-objdump -d - | FileCheck %s
 
 define i1 @foo (i32 %a)
 {
@@ -7,4 +7,6 @@ define i1 @foo (i32 %a)
   ret i1 %1
 }
 
-; CHECK:  0000 40450075 00404089 00c09f52
+; CHECK: p0 = cmp.eq(r0, #42)
+; CHECK: r0 = p0
+; CHECK: jumpr r31

Modified: llvm/trunk/test/MC/Hexagon/inst_cmp_gt.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Hexagon/inst_cmp_gt.ll?rev=238556&r1=238555&r2=238556&view=diff
==============================================================================
--- llvm/trunk/test/MC/Hexagon/inst_cmp_gt.ll (original)
+++ llvm/trunk/test/MC/Hexagon/inst_cmp_gt.ll Fri May 29 09:44:13 2015
@@ -1,5 +1,5 @@
 ;; RUN: llc -mtriple=hexagon-unknown-elf -filetype=obj %s -o - \
-;; RUN: | llvm-objdump -s - | FileCheck %s
+;; RUN: | llvm-objdump -d - | FileCheck %s
 
 define i1 @foo (i32 %a, i32 %b)
 {
@@ -7,4 +7,6 @@ define i1 @foo (i32 %a, i32 %b)
   ret i1 %1
 }
 
-; CHECK:  0000 004140f2 00404089 00c09f52
+; CHECK: p0 = cmp.gt(r0, r1)
+; CHECK: r0 = p0
+; CHECK: jumpr r31 }
\ No newline at end of file

Modified: llvm/trunk/test/MC/Hexagon/inst_cmp_gti.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Hexagon/inst_cmp_gti.ll?rev=238556&r1=238555&r2=238556&view=diff
==============================================================================
--- llvm/trunk/test/MC/Hexagon/inst_cmp_gti.ll (original)
+++ llvm/trunk/test/MC/Hexagon/inst_cmp_gti.ll Fri May 29 09:44:13 2015
@@ -1,5 +1,5 @@
 ;; RUN: llc -mtriple=hexagon-unknown-elf -filetype=obj %s -o - \
-;; RUN: | llvm-objdump -s - | FileCheck %s
+;; RUN: | llvm-objdump -d - | FileCheck %s
 
 define i1 @foo (i32 %a)
 {
@@ -7,4 +7,6 @@ define i1 @foo (i32 %a)
   ret i1 %1
 }
 
-; CHECK:  0000 40454075 00404089 00c09f52
+; CHECK: p0 = cmp.gt(r0, #42)
+; CHECK: r0 = p0
+; CHECK: jumpr r31

Modified: llvm/trunk/test/MC/Hexagon/inst_cmp_lt.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Hexagon/inst_cmp_lt.ll?rev=238556&r1=238555&r2=238556&view=diff
==============================================================================
--- llvm/trunk/test/MC/Hexagon/inst_cmp_lt.ll (original)
+++ llvm/trunk/test/MC/Hexagon/inst_cmp_lt.ll Fri May 29 09:44:13 2015
@@ -1,5 +1,5 @@
 ;; RUN: llc -mtriple=hexagon-unknown-elf -filetype=obj %s -o - \
-;; RUN: | llvm-objdump -s - | FileCheck %s
+;; RUN: | llvm-objdump -d - | FileCheck %s
 
 define i1 @foo (i32 %a, i32 %b)
 {
@@ -7,4 +7,6 @@ define i1 @foo (i32 %a, i32 %b)
   ret i1 %1
 }
 
-; CHECK:  0000 004041f2 00404089 00c09f52
+; CHECK: p0 = cmp.gt(r1, r0)
+; CHECK: r0 = p0
+; CHECK: jumpr r31

Modified: llvm/trunk/test/MC/Hexagon/inst_cmp_ugt.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Hexagon/inst_cmp_ugt.ll?rev=238556&r1=238555&r2=238556&view=diff
==============================================================================
--- llvm/trunk/test/MC/Hexagon/inst_cmp_ugt.ll (original)
+++ llvm/trunk/test/MC/Hexagon/inst_cmp_ugt.ll Fri May 29 09:44:13 2015
@@ -1,5 +1,5 @@
 ;; RUN: llc -mtriple=hexagon-unknown-elf -filetype=obj %s -o - \
-;; RUN: | llvm-objdump -s - | FileCheck %s
+;; RUN: | llvm-objdump -d - | FileCheck %s
 
 define i1 @foo (i32 %a, i32 %b)
 {
@@ -7,4 +7,6 @@ define i1 @foo (i32 %a, i32 %b)
   ret i1 %1
 }
 
-; CHECK:  0000 004160f2 00404089 00c09f52
+; CHECK: p0 = cmp.gtu(r0, r1)
+; CHECK: r0 = p0
+; CHECK: jumpr r31

Modified: llvm/trunk/test/MC/Hexagon/inst_cmp_ugti.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Hexagon/inst_cmp_ugti.ll?rev=238556&r1=238555&r2=238556&view=diff
==============================================================================
--- llvm/trunk/test/MC/Hexagon/inst_cmp_ugti.ll (original)
+++ llvm/trunk/test/MC/Hexagon/inst_cmp_ugti.ll Fri May 29 09:44:13 2015
@@ -1,5 +1,5 @@
 ;; RUN: llc -mtriple=hexagon-unknown-elf -filetype=obj %s -o - \
-;; RUN: | llvm-objdump -s - | FileCheck %s
+;; RUN: | llvm-objdump -d - | FileCheck %s
 
 define i1 @foo (i32 %a)
 {
@@ -7,4 +7,6 @@ define i1 @foo (i32 %a)
   ret i1 %1
 }
 
-; CHECK:  0000 40458075 00404089 00c09f52
+; CHECK: p0 = cmp.gtu(r0, #42)
+; CHECK: r0 = p0
+; CHECK: jumpr r31

Modified: llvm/trunk/test/MC/Hexagon/inst_cmp_ult.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Hexagon/inst_cmp_ult.ll?rev=238556&r1=238555&r2=238556&view=diff
==============================================================================
--- llvm/trunk/test/MC/Hexagon/inst_cmp_ult.ll (original)
+++ llvm/trunk/test/MC/Hexagon/inst_cmp_ult.ll Fri May 29 09:44:13 2015
@@ -1,5 +1,5 @@
 ;; RUN: llc -mtriple=hexagon-unknown-elf -filetype=obj %s -o - \
-;; RUN: | llvm-objdump -s - | FileCheck %s
+;; RUN: | llvm-objdump -d - | FileCheck %s
 
 define i1 @foo (i32 %a, i32 %b)
 {
@@ -7,4 +7,6 @@ define i1 @foo (i32 %a, i32 %b)
   ret i1 %1
 }
 
-; CHECK:  0000 004061f2 00404089 00c09f52
+; CHECK: p0 = cmp.gtu(r1, r0)
+; CHECK: r0 = p0
+; CHECK: jumpr r31
\ No newline at end of file

Modified: llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp?rev=238556&r1=238555&r2=238556&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp (original)
+++ llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp Fri May 29 09:44:13 2015
@@ -205,7 +205,7 @@ namespace {
 class PrettyPrinter {
 public:
   virtual ~PrettyPrinter(){}
-  virtual void printInst(MCInstPrinter &IP, const MCInst *MI, bool ShowRawInsn,
+  virtual void printInst(MCInstPrinter &IP, const MCInst *MI,
                          ArrayRef<uint8_t> Bytes, uint64_t Address,
                          raw_ostream &OS, StringRef Annot,
                          MCSubtargetInfo const &STI) {
@@ -218,8 +218,66 @@ public:
   }
 };
 PrettyPrinter PrettyPrinterInst;
+class HexagonPrettyPrinter : public PrettyPrinter {
+public:
+  void printLead(ArrayRef<uint8_t> Bytes, uint64_t Address,
+                 raw_ostream &OS) {
+    uint32_t opcode =
+      (Bytes[3] << 24) | (Bytes[2] << 16) | (Bytes[1] << 8) | Bytes[0];
+    OS << format("%8" PRIx64 ":", Address);
+    if (!NoShowRawInsn) {
+      OS << "\t";
+      dumpBytes(Bytes.slice(0, 4), OS);
+      OS << format("%08" PRIx32, opcode);
+    }
+  }
+  void printInst(MCInstPrinter &IP, const MCInst *MI,
+                 ArrayRef<uint8_t> Bytes, uint64_t Address,
+                 raw_ostream &OS, StringRef Annot,
+                 MCSubtargetInfo const &STI) override {
+    std::string Buffer;
+    {
+      raw_string_ostream TempStream(Buffer);
+      IP.printInst(MI, TempStream, "", STI);
+    }
+    StringRef Contents(Buffer);
+    // Split off bundle attributes
+    auto PacketBundle = Contents.rsplit('\n');
+    // Split off first instruction from the rest
+    auto HeadTail = PacketBundle.first.split('\n');
+    auto Preamble = " { ";
+    auto Separator = "";
+    while(!HeadTail.first.empty()) {
+      OS << Separator;
+      Separator = "\n";
+      printLead(Bytes, Address, OS);
+      OS << Preamble;
+      Preamble = "   ";
+      StringRef Inst;
+      auto Duplex = HeadTail.first.split('\v');
+      if(!Duplex.second.empty()){
+        OS << Duplex.first;
+        OS << "; ";
+        Inst = Duplex.second;
+      }
+      else
+        Inst = HeadTail.first;
+      OS << Inst;
+      Bytes = Bytes.slice(4);
+      Address += 4;
+      HeadTail = HeadTail.second.split('\n');
+    }
+    OS << " } " << PacketBundle.second;
+  }
+};
+HexagonPrettyPrinter HexagonPrettyPrinterInst;
 PrettyPrinter &selectPrettyPrinter(Triple const &Triple, MCInstPrinter &IP) {
-  return PrettyPrinterInst;
+  switch(Triple.getArch()) {
+  default:
+    return PrettyPrinterInst;
+  case Triple::hexagon:
+    return HexagonPrettyPrinterInst;
+  }
 }
 }
 
@@ -406,7 +464,7 @@ static void DisassembleObject(const Obje
         if (DisAsm->getInstruction(Inst, Size, Bytes.slice(Index),
                                    SectionAddr + Index, DebugOut,
                                    CommentStream)) {
-          PIP.printInst(*IP, &Inst, !NoShowRawInsn,
+          PIP.printInst(*IP, &Inst,
                         Bytes.slice(Index, Size),
                         SectionAddr + Index, outs(), "", *STI);
           outs() << CommentStream.str();





More information about the llvm-commits mailing list