[Hexagon] Disassembling, printing, and emitting instructions a whole-bundle at a...
[oota-llvm.git] / tools / llvm-objdump / llvm-objdump.cpp
index 080a059d576b8db24f93e6491ef5def854b9b8d8..7598df5f701ec41b77e7d199080bafd96cb9551e 100644 (file)
@@ -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 ObjectFile *Obj, bool InlineRelocs) {
         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();