Disassembler tool indents to 15 by default

The assigned-to result Id appears to the left of the 15th column.

Add --no-indent option.

The API form of the disassembler does not indent by default.
This commit is contained in:
David Neto 2015-11-12 13:53:27 -05:00
parent 9a5ac08bcf
commit e7c426ac8d
5 changed files with 68 additions and 5 deletions

View File

@ -243,6 +243,7 @@ typedef enum spv_binary_to_text_options_t {
SPV_BINARY_TO_TEXT_OPTION_NONE = SPV_BIT(0),
SPV_BINARY_TO_TEXT_OPTION_PRINT = SPV_BIT(1),
SPV_BINARY_TO_TEXT_OPTION_COLOR = SPV_BIT(2),
SPV_BINARY_TO_TEXT_OPTION_INDENT = SPV_BIT(3),
SPV_FORCE_32_BIT_ENUM(spv_binary_to_text_options_t)
} spv_binary_to_text_options_t;

View File

@ -46,6 +46,8 @@ namespace {
// A Disassembler instance converts a SPIR-V binary to its assembly
// representation.
class Disassembler {
enum { kStandardIndent = 15 };
public:
Disassembler(const libspirv::AssemblyGrammar& grammar, uint32_t const* words,
size_t num_words, uint32_t options)
@ -55,6 +57,9 @@ class Disassembler {
print_(spvIsInBitfield(SPV_BINARY_TO_TEXT_OPTION_PRINT, options)),
color_(print_ &&
spvIsInBitfield(SPV_BINARY_TO_TEXT_OPTION_COLOR, options)),
indent_(spvIsInBitfield(SPV_BINARY_TO_TEXT_OPTION_INDENT, options)
? kStandardIndent
: 0),
text_(),
out_(print_ ? out_stream() : out_stream(text_)),
stream_(out_.get()) {}
@ -113,6 +118,7 @@ class Disassembler {
const libspirv::AssemblyGrammar& grammar_;
const bool print_; // Should we also print to the standard output stream?
const bool color_; // Should we print in colour?
const int indent_; // How much to indent. 0 means don't indent
spv_endianness_t endian_; // The detected endianness of the binary.
std::stringstream text_; // Captures the text, if not printing.
out_stream out_; // The Output stream. Either to text_ or standard output.
@ -135,12 +141,31 @@ spv_result_t Disassembler::HandleHeader(spv_endianness_t endian,
return SPV_SUCCESS;
}
// Returns the number of digits in n.
int NumDigits(uint32_t n) {
if (n < 10) return 0;
if (n < 100) return 1;
if (n < 1000) return 2;
if (n < 10000) return 3;
if (n < 100000) return 4;
if (n < 1000000) return 5;
if (n < 10000000) return 6;
if (n < 100000000) return 7;
if (n < 1000000000) return 8;
return 9;
}
spv_result_t Disassembler::HandleInstruction(
const spv_parsed_instruction_t& inst) {
if (inst.result_id) {
SetBlue();
stream_ << "%" << inst.result_id << " = ";
// Indent if needed, but account for the 4 characters in "%" and " = "
if (indent_) stream_ << std::setw(indent_ - 4 - NumDigits(inst.result_id));
stream_ << "%" << inst.result_id;
ResetColor();
stream_ << " = ";
} else {
stream_ << std::string(indent_, ' ');
}
stream_ << "Op" << spvOpcodeString(inst.opcode);

View File

@ -364,4 +364,28 @@ TEST_F(OperandTypeTest, OptionalTypedLiteralNumber) {
EXPECT_EQ(input, EncodeAndDecodeSuccessfully(input));
}
using IndentTest = spvtest::TextToBinaryTest;
TEST_F(IndentTest, Sample) {
const std::string input = R"(
OpCapability Shader
OpMemoryModel Logical GLSL450
%1 = OpTypeInt 32 0
%2 = OpTypeStruct %1 %3 %4 %5 %6 %7 %8 %9 %10 ; force IDs into double digits
%11 = OpConstant %1 42
OpStore %2 %3 Aligned|Volatile 4 ; bogus, but not indented
)";
const std::string expected =
R"( OpCapability Shader
OpMemoryModel Logical GLSL450
%1 = OpTypeInt 32 0
%2 = OpTypeStruct %1 %3 %4 %5 %6 %7 %8 %9 %10
%11 = OpConstant %1 42
OpStore %2 %3 Volatile|Aligned 4
)";
EXPECT_THAT(
EncodeAndDecodeSuccessfully(input, SPV_BINARY_TO_TEXT_OPTION_INDENT),
expected);
}
} // anonymous namespace

View File

@ -84,9 +84,16 @@ class TextToBinaryTestBase : public T {
return diagnostic->error;
}
// Encodes SPIR-V text into binary and then decodes the binary. Returns the
// decoded text.
// Encodes SPIR-V text into binary and then decodes the binary using
// default options. Returns the decoded text.
std::string EncodeAndDecodeSuccessfully(const std::string& text) {
return EncodeAndDecodeSuccessfully(text, SPV_BINARY_TO_TEXT_OPTION_NONE);
}
// Encodes SPIR-V text into binary and then decodes the binary using
// given options. Returns the decoded text.
std::string EncodeAndDecodeSuccessfully(const std::string& text,
uint32_t disassemble_options) {
DestroyBinary();
spv_result_t error =
spvTextToBinary(text.c_str(), text.size(), &binary, &diagnostic);
@ -99,8 +106,7 @@ class TextToBinaryTestBase : public T {
spv_text decoded_text;
error = spvBinaryToText(binary->code, binary->wordCount,
SPV_BINARY_TO_TEXT_OPTION_NONE, &decoded_text,
&diagnostic);
disassemble_options, &decoded_text, &diagnostic);
if (error) {
spvDiagnosticPrint(diagnostic);
spvDiagnosticDestroy(diagnostic);

View File

@ -46,6 +46,8 @@ Options:
--no-color Don't print in color.
The default when output goes to a file.
--no-indent Don't indent instructions.
)",
argv0, argv0);
}
@ -63,6 +65,7 @@ int main(int argc, char** argv) {
#ifdef SPIRV_COLOR_TERMINAL
allow_color = true;
#endif
bool allow_indent = true;
for (int argi = 1; argi < argc; ++argi) {
if ('-' == argv[argi][0]) {
@ -81,6 +84,7 @@ int main(int argc, char** argv) {
case '-': {
// Long options
if (0 == strcmp(argv[argi], "--no-color")) allow_color = false;
if (0 == strcmp(argv[argi], "--no-indent")) allow_indent = false;
if (0 == strcmp(argv[argi], "--help")) {
print_usage(argv[0]);
return 0;
@ -102,6 +106,9 @@ int main(int argc, char** argv) {
uint32_t options = SPV_BINARY_TO_TEXT_OPTION_NONE;
if (allow_indent)
options |= SPV_BINARY_TO_TEXT_OPTION_INDENT;
if (!outFile) {
// Print to standard output.
options |= SPV_BINARY_TO_TEXT_OPTION_PRINT;