// Copyright © Advanced Micro Devices, Inc., or its affiliates. // SPDX-License-Identifier: MIT #include "include_inliner.hpp" #include "miopen/filesystem.hpp" #include #include #include #include #include #include #include #include #include namespace fs = miopen::fs; void Bin2Hex(std::istream& source, std::ostream& target, const std::string& variable, bool nullTerminate, size_t bufferSize, size_t lineSize) { source.seekg(0, std::ios::end); const std::unique_ptr buffer(new unsigned char[bufferSize]); const std::streamoff sourceSize = source.tellg(); std::streamoff blockStart = 0; if(variable.length() != 0) { target << "extern const size_t " << variable << "_SIZE;" << std::endl; target << "extern const char " << variable << "[];" << std::endl; target << "const size_t " << variable << "_SIZE = " << std::setbase(10) << sourceSize << ";" << std::endl; target << "const char " << variable << "[] = {" << std::endl; } target << std::setbase(16) << std::setfill('0'); source.seekg(0, std::ios::beg); while(blockStart < sourceSize) { source.read(reinterpret_cast(buffer.get()), bufferSize); const std::streamoff pos = source.tellg(); const std::streamoff blockSize = (pos < 0 ? sourceSize : pos) - blockStart; std::streamoff i = 0; while(i < blockSize) { size_t j = i; const size_t end = std::min(i + lineSize, blockSize); for(; j < end; j++) target << "0x" << std::setw(2) << static_cast(buffer[j]) << ","; target << std::endl; i = end; } blockStart += blockSize; } if(nullTerminate) target << "0x00," << std::endl; if(variable.length() != 0) { target << "};" << std::endl; } } void Bin2Asm(std::istream& source, std::ostream& targetHeader, std::ostream& targetAsm, std::ostream& targetBin, const fs::path& targetBinPath, const std::string& variable, bool nullTerminate, size_t bufferSize) { assert(!variable.empty()); source.seekg(0, std::ios::end); const auto sourceSize = source.tellg(); source.seekg(0, std::ios::beg); const auto buffer = std::make_unique(bufferSize); // Write header data targetHeader << "extern \"C\" const size_t " << variable << "_SIZE;" << std::endl; targetHeader << "extern \"C\" const char " << variable << "[" << sourceSize << "];" << std::endl; const auto incbinOffset = targetBin.tellp(); // Write binary data for(std::streamoff blockStart = 0; blockStart < sourceSize; blockStart += bufferSize) { source.read(buffer.get(), bufferSize); const auto pos = source.tellg(); const auto blockSize = (pos < 0 ? sourceSize : pos) - blockStart; targetBin.write(buffer.get(), blockSize); } if(nullTerminate) targetBin.put(0); // Write assembly const auto incbinSize = targetBin.tellp() - incbinOffset; const auto writeSymbol = [&](const std::string& symbol, auto f) { targetAsm << "#if defined(_WIN32) || defined(__CYGWIN__)\n"; targetAsm << " /* PE/COFF format */\n"; targetAsm << " .section .rdata\n"; targetAsm << "#else\n"; targetAsm << " /* ELF format */\n"; targetAsm << " .section .note.GNU-stack,\"\",@progbits\n"; targetAsm << " .type \"" << symbol << "\",@object\n"; targetAsm << " .section .rodata\n"; targetAsm << "#endif\n"; targetAsm << " .globl \"" << symbol << "\"\n"; targetAsm << " .p2align 8\n"; targetAsm << symbol << ":\n"; f(); targetAsm << "#if !(defined(_WIN32) || defined(__CYGWIN__))\n"; targetAsm << " .size " << symbol << ", . - " << symbol << "\n"; targetAsm << "#endif\n"; }; writeSymbol(variable, [&] { targetAsm << " .incbin \"" << targetBinPath.string() << "\", " << incbinOffset << ", " << incbinSize << "\n"; }); writeSymbol(variable + "_SIZE", [&] { targetAsm << " .quad " << incbinSize << "\n"; }); } void PrintHelp() { std::cout << "Usage: addkernels {