diff --git a/CMakeLists.txt b/CMakeLists.txt index 8594d15..07f7d0f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,14 @@ FetchContent_Declare( GIT_REPOSITORY https://github.com/marzer/tomlplusplus.git GIT_TAG v3.4.0 ) +FetchContent_Declare( + xxHash + GIT_REPOSITORY https://github.com/Cyan4973/xxHash.git + GIT_TAG v0.8.2 + SOURCE_SUBDIR "cmake_unofficial" +) FetchContent_MakeAvailable(tomlplusplus) +FetchContent_MakeAvailable(xxHash) add_subdirectory(${THIRDPARTY_ROOT}/disasm) diff --git a/PowerRecomp/CMakeLists.txt b/PowerRecomp/CMakeLists.txt index 638e0d1..ab4909d 100644 --- a/PowerRecomp/CMakeLists.txt +++ b/PowerRecomp/CMakeLists.txt @@ -3,4 +3,4 @@ cmake_minimum_required (VERSION 3.8) project("PowerRecomp") add_executable(PowerRecomp "main.cpp") -target_link_libraries(PowerRecomp PRIVATE LibPowerAnalyse tomlplusplus::tomlplusplus) +target_link_libraries(PowerRecomp PRIVATE LibPowerAnalyse tomlplusplus::tomlplusplus xxHash::xxhash) diff --git a/PowerRecomp/main.cpp b/PowerRecomp/main.cpp index 1912e9c..9433c01 100644 --- a/PowerRecomp/main.cpp +++ b/PowerRecomp/main.cpp @@ -9,6 +9,7 @@ #include #include #include +#include static uint64_t computeMask(uint32_t mstart, uint32_t mstop) { @@ -119,7 +120,7 @@ int main(int argc, char* argv[]) } std::string out; - out.reserve(512 * 1024 * 1024); + out.reserve(10 * 1024 * 1024); auto print = [&](std::format_string fmt, Args&&... args) { @@ -134,6 +135,7 @@ int main(int argc, char* argv[]) std::filesystem::create_directory("out"); + std::vector tempData; size_t cppFileIndex = 0; auto saveFile = [&](std::string name = "") @@ -146,9 +148,31 @@ int main(int argc, char* argv[]) ++cppFileIndex; } - FILE* f = fopen(name.c_str(), "wb"); - fwrite(out.data(), 1, out.size(), f); - fclose(f); + bool shouldWrite = true; + + // Check if an identical file already exists first to not trigger recompilation + FILE* f = fopen(name.c_str(), "rb"); + if (f) + { + fseek(f, 0, SEEK_END); + long fileSize = ftell(f); + if (fileSize == out.size()) + { + fseek(f, 0, SEEK_SET); + tempData.resize(fileSize); + fread(tempData.data(), 1, fileSize, f); + + shouldWrite = XXH3_64bits(tempData.data(), tempData.size()) != XXH3_64bits(out.data(), out.size()); + } + fclose(f); + } + + if (shouldWrite) + { + f = fopen(name.c_str(), "wb"); + fwrite(out.data(), 1, out.size(), f); + fclose(f); + } out.clear(); } @@ -167,7 +191,7 @@ int main(int argc, char* argv[]) { println("#include \"ppc_recomp_shared.h\"\n"); - println("extern \"C\" __declspec(dllexport) PPCFuncMapping PPCFuncMapping[] = {{"); + println("const struct PPCFuncMapping PPCFuncMapping[] = {{"); for (auto& symbol : image.symbols) println("\t{{ 0x{:X}, {} }},", symbol.address, symbol.name); @@ -181,12 +205,13 @@ int main(int argc, char* argv[]) { if ((funcIdx % 100) == 0) { - std::println("Recompiling functions... {}%", static_cast(funcIdx) / functions.size() * 100.0f); - saveFile(); println("#include \"ppc_recomp_shared.h\"\n"); } + if ((funcIdx % 2000) == 0 || (funcIdx == (functions.size() - 1))) + std::println("Recompiling functions... {}%", static_cast(funcIdx + 1) / functions.size() * 100.0f); + auto& fn = functions[funcIdx]; auto base = fn.base; auto end = base + fn.size; diff --git a/PowerUtils/ppc_context.h b/PowerUtils/ppc_context.h index e69feb2..924ac10 100644 --- a/PowerUtils/ppc_context.h +++ b/PowerUtils/ppc_context.h @@ -38,6 +38,8 @@ struct PPCFuncMapping PPCFunc* host; }; +extern const struct PPCFuncMapping PPCFuncMapping[]; + struct PPCRegister { union