1 // Copyright (c) 2018 Google Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef SOURCE_DISASSEMBLE_H_ 16 #define SOURCE_DISASSEMBLE_H_ 17 18 #include <iosfwd> 19 #include <sstream> 20 #include <string> 21 22 #include "source/name_mapper.h" 23 #include "spirv-tools/libspirv.h" 24 25 namespace spvtools { 26 27 // Decodes the given SPIR-V instruction binary representation to its assembly 28 // text. The context is inferred from the provided module binary. The options 29 // parameter is a bit field of spv_binary_to_text_options_t (note: the option 30 // SPV_BINARY_TO_TEXT_OPTION_PRINT will be ignored). Decoded text will be 31 // stored into *text. Any error will be written into *diagnostic if diagnostic 32 // is non-null. 33 std::string spvInstructionBinaryToText(const spv_target_env env, 34 const uint32_t* inst_binary, 35 const size_t inst_word_count, 36 const uint32_t* binary, 37 const size_t word_count, 38 const uint32_t options); 39 40 class AssemblyGrammar; 41 namespace disassemble { 42 43 // Shared code with other tools (than the disassembler) that might need to 44 // output disassembly. An InstructionDisassembler instance converts SPIR-V 45 // binary for an instruction to its assembly representation. 46 class InstructionDisassembler { 47 public: 48 InstructionDisassembler(const AssemblyGrammar& grammar, std::ostream& stream, 49 uint32_t options, NameMapper name_mapper); 50 51 // Emits the assembly header for the module. 52 void EmitHeaderSpirv(); 53 void EmitHeaderVersion(uint32_t version); 54 void EmitHeaderGenerator(uint32_t generator); 55 void EmitHeaderIdBound(uint32_t id_bound); 56 void EmitHeaderSchema(uint32_t schema); 57 58 // Emits the assembly text for the given instruction. 59 void EmitInstruction(const spv_parsed_instruction_t& inst, 60 size_t inst_byte_offset); 61 62 // Emits a comment between different sections of the module. 63 void EmitSectionComment(const spv_parsed_instruction_t& inst, 64 bool& inserted_decoration_space, 65 bool& inserted_debug_space, 66 bool& inserted_type_space); 67 68 // Resets the output color, if color is turned on. 69 void ResetColor(); 70 // Set the output color, if color is turned on. 71 void SetGrey(); 72 void SetBlue(); 73 void SetYellow(); 74 void SetRed(); 75 void SetGreen(); 76 77 private: 78 void ResetColor(std::ostream& stream) const; 79 void SetGrey(std::ostream& stream) const; 80 void SetBlue(std::ostream& stream) const; 81 void SetYellow(std::ostream& stream) const; 82 void SetRed(std::ostream& stream) const; 83 void SetGreen(std::ostream& stream) const; 84 85 // Emits an operand for the given instruction, where the instruction 86 // is at offset words from the start of the binary. 87 void EmitOperand(std::ostream& stream, const spv_parsed_instruction_t& inst, 88 const uint16_t operand_index) const; 89 90 // Emits a mask expression for the given mask word of the specified type. 91 void EmitMaskOperand(std::ostream& stream, const spv_operand_type_t type, 92 const uint32_t word) const; 93 94 // Generate part of the instruction as a comment to be added to 95 // |id_comments_|. 96 void GenerateCommentForDecoratedId(const spv_parsed_instruction_t& inst); 97 98 const spvtools::AssemblyGrammar& grammar_; 99 std::ostream& stream_; 100 const bool print_; // Should we also print to the standard output stream? 101 const bool color_; // Should we print in colour? 102 const int indent_; // How much to indent. 0 means don't indent 103 const int comment_; // Should we comment the source 104 const bool show_byte_offset_; // Should we print byte offset, in hex? 105 spvtools::NameMapper name_mapper_; 106 107 // Some comments are generated as instructions (such as OpDecorate) are 108 // visited so that when the instruction with that result id is visited, the 109 // comment can be output. 110 std::unordered_map<uint32_t, std::ostringstream> id_comments_; 111 // Align the comments in consecutive lines for more readability. 112 uint32_t last_instruction_comment_alignment_; 113 }; 114 115 } // namespace disassemble 116 } // namespace spvtools 117 118 #endif // SOURCE_DISASSEMBLE_H_ 119