| 2796 | } |
| 2797 | |
| 2798 | spv_result_t Differ::Output() { |
| 2799 | id_map_.MapUnmatchedIds( |
| 2800 | [this](uint32_t src_id) { return src_id_to_.IsDefined(src_id); }, |
| 2801 | [this](uint32_t dst_id) { return dst_id_to_.IsDefined(dst_id); }); |
| 2802 | src_id_to_.inst_map_.resize(id_map_.SrcToDstMap().IdBound(), nullptr); |
| 2803 | dst_id_to_.inst_map_.resize(id_map_.DstToSrcMap().IdBound(), nullptr); |
| 2804 | |
| 2805 | spv_context_t context{SPV_ENV_UNIVERSAL_1_6, nullptr}; |
| 2806 | |
| 2807 | uint32_t disassembly_options = SPV_BINARY_TO_TEXT_OPTION_PRINT; |
| 2808 | if (options_.indent) { |
| 2809 | disassembly_options |= SPV_BINARY_TO_TEXT_OPTION_INDENT; |
| 2810 | } |
| 2811 | |
| 2812 | NameMapper name_mapper = GetTrivialNameMapper(); |
| 2813 | disassemble::InstructionDisassembler dis(out_, disassembly_options, |
| 2814 | name_mapper); |
| 2815 | |
| 2816 | if (!options_.no_header) { |
| 2817 | // Output the header |
| 2818 | // TODO: when using diff with text, the assembler overrides the version and |
| 2819 | // generator, so these aren't reflected correctly in the output. Could |
| 2820 | // potentially extract this info from the header comment. |
| 2821 | OutputLine([]() { return true; }, [&dis]() { dis.EmitHeaderSpirv(); }, |
| 2822 | []() { assert(false && "Unreachable"); }); |
| 2823 | OutputLine([this]() { return src_->version() == dst_->version(); }, |
| 2824 | [this, &dis]() { dis.EmitHeaderVersion(src_->version()); }, |
| 2825 | [this, &dis]() { dis.EmitHeaderVersion(dst_->version()); }); |
| 2826 | OutputLine([this]() { return src_->generator() == dst_->generator(); }, |
| 2827 | [this, &dis]() { dis.EmitHeaderGenerator(src_->generator()); }, |
| 2828 | [this, &dis]() { dis.EmitHeaderGenerator(dst_->generator()); }); |
| 2829 | OutputLine( |
| 2830 | [this]() { return src_->IdBound() == id_map_.SrcToDstMap().IdBound(); }, |
| 2831 | [this, &dis]() { dis.EmitHeaderIdBound(src_->IdBound()); }, |
| 2832 | [this, &dis]() { |
| 2833 | dis.EmitHeaderIdBound(id_map_.SrcToDstMap().IdBound()); |
| 2834 | }); |
| 2835 | OutputLine([this]() { return src_->schema() == dst_->schema(); }, |
| 2836 | [this, &dis]() { dis.EmitHeaderSchema(src_->schema()); }, |
| 2837 | [this, &dis]() { dis.EmitHeaderSchema(dst_->schema()); }); |
| 2838 | } |
| 2839 | |
| 2840 | // For each section, iterate both modules and output the disassembly. |
| 2841 | auto write_inst = [this, &dis](const opt::Instruction& inst, |
| 2842 | const IdInstructions& id_to, |
| 2843 | const opt::Instruction& original_inst) { |
| 2844 | spv_parsed_instruction_t parsed_inst; |
| 2845 | std::vector<spv_parsed_operand_t> parsed_operands; |
| 2846 | std::vector<uint32_t> inst_binary; |
| 2847 | |
| 2848 | ToParsedInstruction(inst, id_to, original_inst, &parsed_inst, |
| 2849 | parsed_operands, inst_binary); |
| 2850 | |
| 2851 | dis.EmitInstruction(parsed_inst, 0); |
| 2852 | }; |
| 2853 | |
| 2854 | OutputSection(src_->capabilities(), dst_->capabilities(), write_inst); |
| 2855 | OutputSection(src_->extensions(), dst_->extensions(), write_inst); |
no test coverage detected