brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.6 KiB · 52963e0 Raw
167 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8///9/// \file10/// This file implements the DXContainer-specific dumper for llvm-objdump.11///12//===----------------------------------------------------------------------===//13 14#include "llvm-objdump.h"15#include "llvm/BinaryFormat/DXContainer.h"16#include "llvm/Object/DXContainer.h"17#include "llvm/Support/ScopedPrinter.h"18 19using namespace llvm;20using namespace llvm::object;21 22static llvm::SmallString<4> maskToString(uint8_t Mask,23                                         bool StripTrailing = false) {24  llvm::SmallString<4> Result("    ");25  if (Mask & 1)26    Result[0] = 'x';27  if (Mask & 2)28    Result[1] = 'y';29  if (Mask & 4)30    Result[2] = 'z';31  if (Mask & 8)32    Result[3] = 'w';33  if (!StripTrailing)34    return Result;35  int Size = 8 - countl_zero(Mask);36  return Result.slice(0, Size);37}38 39static void printColumnHeader(raw_ostream &OS, size_t Length) {40  for (size_t I = 0; I < Length; ++I)41    OS << "-";42}43 44static void printColumnHeaders(raw_ostream &OS, ArrayRef<size_t> Lengths) {45  // Generate the header in a temporary to avoid trailing whitespace.46  SmallString<256> Str;47  raw_svector_ostream Tmp(Str);48  for (auto L : Lengths) {49    printColumnHeader(Tmp, L);50    Tmp << " ";51  }52  Str.back() = '\n';53  OS << Str;54}55 56static size_t digitsForNumber(size_t N) {57  if (N == 0)58    return 1;59  return static_cast<size_t>(log10(static_cast<double>(N))) + 1;60}61 62namespace {63class DXContainerDumper : public objdump::Dumper {64  const DXContainerObjectFile &Obj;65 66public:67  DXContainerDumper(const DXContainerObjectFile &O)68      : objdump::Dumper(O), Obj(O) {}69 70  void printPrivateHeaders() override;71  void printSignature(const DirectX::Signature &S);72};73 74void DXContainerDumper::printSignature(const DirectX::Signature &S) {75  // DXC prints a table like this as part of the shader disassembly:76  //; Name                 Index   Mask Register SysValue  Format   Used77  //; -------------------- ----- ------ -------- -------- ------- ------78  //; NORMAL                   0   xyz         0     NONE   float   xyz79  //; TEXCOORD                 0   xy          1     NONE   float   xy80 81  // DXC's implementation doesn't scale columns entirely completely for the82  // provided input, so this implementation is a bit more complicated in83  // formatting logic to scale with the size of the printed text.84 85  // DXC gives names 21 characters for some unknown reason, I arbitrarily chose86  // to start at 24 so that we're not going shorter but are using a round87  // number.88  size_t LongestName = 24;89  size_t LongestSV = 10;90  size_t LongestIndex = strlen("Index");91  size_t LongestRegister = strlen("Register");92  size_t LongestFormat = strlen("Format");93  const size_t MaskWidth = 5;94  // Compute the column widths. Skip calculating the "Mask" and "Used" columns95  // since they both have widths of 4.96  for (auto El : S) {97    LongestName = std::max(LongestName, S.getName(El.NameOffset).size());98    LongestSV = std::max(99        LongestSV,100        enumToStringRef(El.SystemValue, dxbc::getD3DSystemValues()).size());101    LongestIndex = std::max(LongestIndex, digitsForNumber(El.Index));102    LongestRegister = std::max(LongestRegister, digitsForNumber(El.Register));103    LongestFormat = std::max(104        LongestFormat,105        enumToStringRef(El.CompType, dxbc::getSigComponentTypes()).size());106  }107 108  // Print Column headers.109  OS << "; ";110  OS << left_justify("Name", LongestName) << " ";111  OS << right_justify("Index", LongestIndex) << " ";112  OS << right_justify("Mask", MaskWidth) << " ";113  OS << right_justify("Register", LongestRegister) << " ";114  OS << right_justify("SysValue", LongestSV) << " ";115  OS << right_justify("Format", LongestFormat) << " ";116  OS << right_justify("Used", MaskWidth) << "\n";117  OS << "; ";118  printColumnHeaders(OS, {LongestName, LongestIndex, MaskWidth, LongestRegister,119                          LongestSV, LongestFormat, MaskWidth});120 121  for (auto El : S) {122    OS << "; " << left_justify(S.getName(El.NameOffset), LongestName) << " ";123    OS << right_justify(std::to_string(El.Index), LongestIndex) << " ";124    OS << right_justify(maskToString(El.Mask), MaskWidth) << " ";125    OS << right_justify(std::to_string(El.Register), LongestRegister) << " ";126    OS << right_justify(127              enumToStringRef(El.SystemValue, dxbc::getD3DSystemValues()),128              LongestSV)129       << " ";130    OS << right_justify(131        enumToStringRef(El.CompType, dxbc::getSigComponentTypes()),132        LongestFormat);133    if (El.ExclusiveMask)134      OS << "  " << maskToString(El.ExclusiveMask, true);135    OS << "\n";136  }137}138 139void DXContainerDumper::printPrivateHeaders() {140  const DXContainer &C =141      cast<object::DXContainerObjectFile>(Obj).getDXContainer();142 143  if (!C.getInputSignature().isEmpty()) {144    OS << "; Input signature:\n;\n";145    printSignature(C.getInputSignature());146    OS << ";\n";147  }148 149  if (!C.getOutputSignature().isEmpty()) {150    OS << "; Output signature:\n;\n";151    printSignature(C.getOutputSignature());152    OS << ";\n";153  }154 155  if (!C.getPatchConstantSignature().isEmpty()) {156    OS << "; Patch Constant signature:\n;\n";157    printSignature(C.getPatchConstantSignature());158    OS << ";\n";159  }160}161} // namespace162 163std::unique_ptr<objdump::Dumper> llvm::objdump::createDXContainerDumper(164    const object::DXContainerObjectFile &Obj) {165  return std::make_unique<DXContainerDumper>(Obj);166}167