mirror of
https://github.com/N64Recomp/N64Recomp.git
synced 2026-05-01 22:41:59 +00:00
Move recompiler core logic into a core library and make the existing CLI consume the core library
This commit is contained in:
parent
bce3baa99a
commit
ddb8a08482
5 changed files with 45 additions and 26 deletions
|
|
@ -62,24 +62,38 @@ add_subdirectory(lib/fmt)
|
||||||
set(TOML_ENABLE_FORMATTERS OFF)
|
set(TOML_ENABLE_FORMATTERS OFF)
|
||||||
add_subdirectory(lib/tomlplusplus)
|
add_subdirectory(lib/tomlplusplus)
|
||||||
|
|
||||||
# N64 recompiler
|
# N64 recompiler core library
|
||||||
project(N64Recomp)
|
project(N64Recomp)
|
||||||
add_executable(N64Recomp)
|
add_library(N64Recomp)
|
||||||
|
|
||||||
target_sources(N64Recomp PRIVATE
|
target_sources(N64Recomp PRIVATE
|
||||||
${CMAKE_SOURCE_DIR}/src/analysis.cpp
|
${CMAKE_SOURCE_DIR}/src/analysis.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/config.cpp
|
|
||||||
${CMAKE_SOURCE_DIR}/src/main.cpp
|
|
||||||
${CMAKE_SOURCE_DIR}/src/operations.cpp
|
${CMAKE_SOURCE_DIR}/src/operations.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/cgenerator.cpp
|
${CMAKE_SOURCE_DIR}/src/cgenerator.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/recompilation.cpp)
|
${CMAKE_SOURCE_DIR}/src/recompilation.cpp
|
||||||
|
)
|
||||||
|
|
||||||
target_include_directories(N64Recomp PRIVATE
|
target_include_directories(N64Recomp PRIVATE
|
||||||
"${CMAKE_SOURCE_DIR}/lib/ELFIO"
|
|
||||||
"${CMAKE_SOURCE_DIR}/include")
|
"${CMAKE_SOURCE_DIR}/include")
|
||||||
|
|
||||||
target_link_libraries(N64Recomp fmt rabbitizer tomlplusplus::tomlplusplus)
|
target_link_libraries(N64Recomp fmt rabbitizer tomlplusplus::tomlplusplus)
|
||||||
|
|
||||||
|
# N64 recompiler executable
|
||||||
|
project(N64RecompCLI)
|
||||||
|
add_executable(N64RecompCLI)
|
||||||
|
|
||||||
|
target_sources(N64RecompCLI PRIVATE
|
||||||
|
${CMAKE_SOURCE_DIR}/src/config.cpp
|
||||||
|
${CMAKE_SOURCE_DIR}/src/main.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(N64RecompCLI PRIVATE
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/ELFIO"
|
||||||
|
"${CMAKE_SOURCE_DIR}/include")
|
||||||
|
|
||||||
|
target_link_libraries(N64RecompCLI fmt rabbitizer tomlplusplus::tomlplusplus N64Recomp)
|
||||||
|
set_target_properties(N64RecompCLI PROPERTIES OUTPUT_NAME N64Recomp)
|
||||||
|
|
||||||
# RSP recompiler
|
# RSP recompiler
|
||||||
project(RSPRecomp)
|
project(RSPRecomp)
|
||||||
add_executable(RSPRecomp)
|
add_executable(RSPRecomp)
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include "rabbitizer.hpp"
|
#include "rabbitizer.hpp"
|
||||||
#include "elfio/elfio.hpp"
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
inline uint32_t byteswap(uint32_t val) {
|
inline uint32_t byteswap(uint32_t val) {
|
||||||
|
|
@ -119,13 +118,13 @@ namespace RecompPort {
|
||||||
uint32_t rom;
|
uint32_t rom;
|
||||||
std::vector<uint32_t> words;
|
std::vector<uint32_t> words;
|
||||||
std::string name;
|
std::string name;
|
||||||
ELFIO::Elf_Half section_index;
|
uint16_t section_index;
|
||||||
bool ignored;
|
bool ignored;
|
||||||
bool reimplemented;
|
bool reimplemented;
|
||||||
bool stubbed;
|
bool stubbed;
|
||||||
std::unordered_map<int32_t, std::string> function_hooks;
|
std::unordered_map<int32_t, std::string> function_hooks;
|
||||||
|
|
||||||
Function(uint32_t vram, uint32_t rom, std::vector<uint32_t> words, std::string name, ELFIO::Elf_Half section_index, bool ignored = false, bool reimplemented = false, bool stubbed = false)
|
Function(uint32_t vram, uint32_t rom, std::vector<uint32_t> words, std::string name, uint16_t section_index, bool ignored = false, bool reimplemented = false, bool stubbed = false)
|
||||||
: vram(vram), rom(rom), words(std::move(words)), name(std::move(name)), section_index(section_index), ignored(ignored), reimplemented(reimplemented), stubbed(stubbed) {}
|
: vram(vram), rom(rom), words(std::move(words)), name(std::move(name)), section_index(section_index), ignored(ignored), reimplemented(reimplemented), stubbed(stubbed) {}
|
||||||
Function() = default;
|
Function() = default;
|
||||||
};
|
};
|
||||||
|
|
@ -153,13 +152,13 @@ namespace RecompPort {
|
||||||
constexpr uint16_t SectionSelf = (uint16_t)-1;
|
constexpr uint16_t SectionSelf = (uint16_t)-1;
|
||||||
constexpr uint16_t SectionAbsolute = (uint16_t)-2;
|
constexpr uint16_t SectionAbsolute = (uint16_t)-2;
|
||||||
struct Section {
|
struct Section {
|
||||||
ELFIO::Elf_Xword rom_addr = 0;
|
uint32_t rom_addr = 0;
|
||||||
ELFIO::Elf64_Addr ram_addr = 0;
|
uint32_t ram_addr = 0;
|
||||||
ELFIO::Elf_Xword size = 0;
|
uint32_t size = 0;
|
||||||
std::vector<uint32_t> function_addrs;
|
std::vector<uint32_t> function_addrs;
|
||||||
std::vector<Reloc> relocs;
|
std::vector<Reloc> relocs;
|
||||||
std::string name;
|
std::string name;
|
||||||
ELFIO::Elf_Half bss_section_index = (ELFIO::Elf_Half)-1;
|
uint16_t bss_section_index = (uint16_t)-1;
|
||||||
bool executable = false;
|
bool executable = false;
|
||||||
bool relocatable = false;
|
bool relocatable = false;
|
||||||
bool has_mips32_relocs = false;
|
bool has_mips32_relocs = false;
|
||||||
|
|
@ -209,16 +208,6 @@ namespace RecompPort {
|
||||||
std::unordered_map<std::string, size_t> reference_symbols_by_name;
|
std::unordered_map<std::string, size_t> reference_symbols_by_name;
|
||||||
int executable_section_count;
|
int executable_section_count;
|
||||||
|
|
||||||
Context(const ELFIO::elfio& elf_file) {
|
|
||||||
sections.resize(elf_file.sections.size());
|
|
||||||
section_functions.resize(elf_file.sections.size());
|
|
||||||
functions.reserve(1024);
|
|
||||||
functions_by_vram.reserve(functions.capacity());
|
|
||||||
functions_by_name.reserve(functions.capacity());
|
|
||||||
rom.reserve(8 * 1024 * 1024);
|
|
||||||
executable_section_count = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Imports sections and function symbols from a provided context into this context's reference sections and reference functions.
|
// Imports sections and function symbols from a provided context into this context's reference sections and reference functions.
|
||||||
void import_reference_context(const Context& reference_context);
|
void import_reference_context(const Context& reference_context);
|
||||||
// Reads a data symbol file and adds its contents into this context's reference data symbols.
|
// Reads a data symbol file and adds its contents into this context's reference data symbols.
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#include <source_location>
|
#include <iostream>
|
||||||
|
|
||||||
#include <toml++/toml.hpp>
|
#include <toml++/toml.hpp>
|
||||||
#include "fmt/format.h"
|
#include "fmt/format.h"
|
||||||
|
|
|
||||||
14
src/main.cpp
14
src/main.cpp
|
|
@ -1053,7 +1053,7 @@ ELFIO::section* read_sections(RecompPort::Context& context, const RecompPort::Co
|
||||||
std::copy(section->get_data(), section->get_data() + section->get_size(), &context.rom[section_out.rom_addr]);
|
std::copy(section->get_data(), section->get_data() + section->get_size(), &context.rom[section_out.rom_addr]);
|
||||||
} else {
|
} else {
|
||||||
// Otherwise mark this section as having an invalid rom address
|
// Otherwise mark this section as having an invalid rom address
|
||||||
section_out.rom_addr = (ELFIO::Elf_Xword)-1;
|
section_out.rom_addr = (uint32_t)-1;
|
||||||
}
|
}
|
||||||
// Check if this section is marked as executable, which means it has code in it
|
// Check if this section is marked as executable, which means it has code in it
|
||||||
if (section->get_flags() & ELFIO::SHF_EXECINSTR) {
|
if (section->get_flags() & ELFIO::SHF_EXECINSTR) {
|
||||||
|
|
@ -1482,6 +1482,16 @@ static std::vector<uint8_t> read_file(const std::filesystem::path& path) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void setup_context_for_elf(RecompPort::Context& context, const ELFIO::elfio& elf_file) {
|
||||||
|
context.sections.resize(elf_file.sections.size());
|
||||||
|
context.section_functions.resize(elf_file.sections.size());
|
||||||
|
context.functions.reserve(1024);
|
||||||
|
context.functions_by_vram.reserve(context.functions.capacity());
|
||||||
|
context.functions_by_name.reserve(context.functions.capacity());
|
||||||
|
context.rom.reserve(8 * 1024 * 1024);
|
||||||
|
context.executable_section_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
auto exit_failure = [] (const std::string& error_str) {
|
auto exit_failure = [] (const std::string& error_str) {
|
||||||
fmt::vprint(stderr, error_str, fmt::make_format_args());
|
fmt::vprint(stderr, error_str, fmt::make_format_args());
|
||||||
|
|
@ -1542,7 +1552,7 @@ int main(int argc, char** argv) {
|
||||||
exit_failure("Incorrect endianness\n");
|
exit_failure("Incorrect endianness\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
context = { elf_file };
|
setup_context_for_elf(context, elf_file);
|
||||||
context.relocatable_sections = std::move(relocatable_sections);
|
context.relocatable_sections = std::move(relocatable_sections);
|
||||||
|
|
||||||
// Import symbols from any reference symbols files that were provided.
|
// Import symbols from any reference symbols files that were provided.
|
||||||
|
|
|
||||||
|
|
@ -596,6 +596,9 @@ bool process_instruction(const RecompPort::Context& context, const RecompPort::C
|
||||||
case Operand::FtU64:
|
case Operand::FtU64:
|
||||||
generator.emit_check_fr(output_file, ctx.ft);
|
generator.emit_check_fr(output_file, ctx.ft);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
// No MIPS3 float check needed for non-float operands.
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -619,6 +622,9 @@ bool process_instruction(const RecompPort::Context& context, const RecompPort::C
|
||||||
case Operand::FtDouble:
|
case Operand::FtDouble:
|
||||||
generator.emit_check_nan(output_file, ctx.ft, true);
|
generator.emit_check_nan(output_file, ctx.ft, true);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
// No NaN checks needed for non-float operands.
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue