diff --git a/include/spirv-tools/libspirv.h b/include/spirv-tools/libspirv.h index 16cdd1b1..16ea7ffa 100644 --- a/include/spirv-tools/libspirv.h +++ b/include/spirv-tools/libspirv.h @@ -325,6 +325,8 @@ typedef enum spv_binary_to_text_options_t { // time, but will use common names for scalar types, and debug names from // OpName instructions. SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES = SPV_BIT(6), + // Add some comments to the generated assembly + SPV_BINARY_TO_TEXT_OPTION_COMMENT = SPV_BIT(7), SPV_FORCE_32_BIT_ENUM(spv_binary_to_text_options_t) } spv_binary_to_text_options_t; diff --git a/source/disassemble.cpp b/source/disassemble.cpp index af30ce0b..e7632512 100644 --- a/source/disassemble.cpp +++ b/source/disassemble.cpp @@ -54,6 +54,7 @@ class Disassembler { indent_(spvIsInBitfield(SPV_BINARY_TO_TEXT_OPTION_INDENT, options) ? kStandardIndent : 0), + comment_(spvIsInBitfield(SPV_BINARY_TO_TEXT_OPTION_COMMENT, options)), text_(), out_(print_ ? out_stream() : out_stream(text_)), stream_(out_.get()), @@ -118,6 +119,7 @@ class Disassembler { 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 + const int comment_; // Should we comment the source 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. @@ -126,6 +128,9 @@ class Disassembler { const bool show_byte_offset_; // Should we print byte offset, in hex? size_t byte_offset_; // The number of bytes processed so far. spvtools::NameMapper name_mapper_; + bool inserted_decoration_space_ = false; + bool inserted_debug_space_ = false; + bool inserted_type_space_ = false; }; spv_result_t Disassembler::HandleHeader(spv_endianness_t endian, @@ -134,7 +139,6 @@ spv_result_t Disassembler::HandleHeader(spv_endianness_t endian, endian_ = endian; if (header_) { - SetGrey(); const char* generator_tool = spvGeneratorStr(SPV_GENERATOR_TOOL_PART(generator)); stream_ << "; SPIR-V\n" @@ -150,7 +154,6 @@ spv_result_t Disassembler::HandleHeader(spv_endianness_t endian, stream_ << "; " << SPV_GENERATOR_MISC_PART(generator) << "\n" << "; Bound: " << id_bound << "\n" << "; Schema: " << schema << "\n"; - ResetColor(); } byte_offset_ = SPV_INDEX_INSTRUCTION * sizeof(uint32_t); @@ -160,6 +163,32 @@ spv_result_t Disassembler::HandleHeader(spv_endianness_t endian, spv_result_t Disassembler::HandleInstruction( const spv_parsed_instruction_t& inst) { + auto opcode = static_cast(inst.opcode); + if (comment_ && opcode == SpvOpFunction) { + stream_ << std::endl; + stream_ << std::string(indent_, ' '); + stream_ << "; Function " << name_mapper_(inst.result_id) << std::endl; + } + if (comment_ && !inserted_decoration_space_ && + spvOpcodeIsDecoration(opcode)) { + inserted_decoration_space_ = true; + stream_ << std::endl; + stream_ << std::string(indent_, ' '); + stream_ << "; Annotations" << std::endl; + } + if (comment_ && !inserted_debug_space_ && spvOpcodeIsDebug(opcode)) { + inserted_debug_space_ = true; + stream_ << std::endl; + stream_ << std::string(indent_, ' '); + stream_ << "; Debug Information" << std::endl; + } + if (comment_ && !inserted_type_space_ && spvOpcodeGeneratesType(opcode)) { + inserted_type_space_ = true; + stream_ << std::endl; + stream_ << std::string(indent_, ' '); + stream_ << "; Types, variables and constants" << std::endl; + } + if (inst.result_id) { SetBlue(); const std::string id_name = name_mapper_(inst.result_id); @@ -172,7 +201,7 @@ spv_result_t Disassembler::HandleInstruction( stream_ << std::string(indent_, ' '); } - stream_ << "Op" << spvOpcodeString(static_cast(inst.opcode)); + stream_ << "Op" << spvOpcodeString(opcode); for (uint16_t i = 0; i < inst.num_operands; i++) { const spv_operand_type_t type = inst.operands[i].type; @@ -182,6 +211,12 @@ spv_result_t Disassembler::HandleInstruction( EmitOperand(inst, i); } + if (comment_ && opcode == SpvOpName) { + const spv_parsed_operand_t& operand = inst.operands[0]; + const uint32_t word = inst.words[operand.offset]; + stream_ << " ; id %" << word; + } + if (show_byte_offset_) { SetGrey(); auto saved_flags = stream_.flags(); diff --git a/tools/dis/dis.cpp b/tools/dis/dis.cpp index c0ce267d..bdeeef11 100644 --- a/tools/dis/dis.cpp +++ b/tools/dis/dis.cpp @@ -56,6 +56,8 @@ Options: --raw-id Show raw Id values instead of friendly names. --offsets Show byte offsets for each instruction. + + --comment Add comments to make reading easier )", argv0, argv0); } @@ -79,6 +81,7 @@ int main(int argc, char** argv) { bool show_byte_offsets = false; bool no_header = false; bool friendly_names = true; + bool comments = false; for (int argi = 1; argi < argc; ++argi) { if ('-' == argv[argi][0]) { @@ -102,6 +105,8 @@ int main(int argc, char** argv) { } else if (0 == strcmp(argv[argi], "--color")) { force_no_color = false; force_color = true; + } else if (0 == strcmp(argv[argi], "--comment")) { + comments = true; } else if (0 == strcmp(argv[argi], "--no-indent")) { allow_indent = false; } else if (0 == strcmp(argv[argi], "--offsets")) { @@ -156,6 +161,8 @@ int main(int argc, char** argv) { if (friendly_names) options |= SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES; + if (comments) options |= SPV_BINARY_TO_TEXT_OPTION_COMMENT; + if (!outFile || (0 == strcmp("-", outFile))) { // Print to standard output. options |= SPV_BINARY_TO_TEXT_OPTION_PRINT;