mirror of
https://github.com/hedge-dev/XenonRecomp.git
synced 2025-04-19 19:01:17 +00:00
Implement switch case generation.
This commit is contained in:
parent
fc43264f72
commit
e0cb6c7903
@ -10,6 +10,14 @@ endif()
|
||||
|
||||
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
||||
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(
|
||||
tomlplusplus
|
||||
GIT_REPOSITORY https://github.com/marzer/tomlplusplus.git
|
||||
GIT_TAG v3.4.0
|
||||
)
|
||||
FetchContent_MakeAvailable(tomlplusplus)
|
||||
|
||||
add_subdirectory(${THIRDPARTY_ROOT}/disasm)
|
||||
|
||||
project ("PowerRecomp-ALL")
|
||||
|
@ -3,4 +3,4 @@ cmake_minimum_required (VERSION 3.8)
|
||||
project("PowerRecomp")
|
||||
|
||||
add_executable(PowerRecomp "main.cpp")
|
||||
target_link_libraries(PowerRecomp PRIVATE LibPowerAnalyse)
|
||||
target_link_libraries(PowerRecomp PRIVATE LibPowerAnalyse tomlplusplus::tomlplusplus)
|
||||
|
@ -7,8 +7,10 @@
|
||||
#include <filesystem>
|
||||
#include <xbox.h>
|
||||
#include <cassert>
|
||||
#include <toml++/toml.hpp>
|
||||
#include <unordered_map>
|
||||
|
||||
#define TEST_FILE "default.xex"
|
||||
#define TEST_FILE "private/default.xex"
|
||||
|
||||
static uint64_t computeMask(uint32_t mstart, uint32_t mstop)
|
||||
{
|
||||
@ -23,6 +25,29 @@ int main()
|
||||
const auto file = LoadFile(TEST_FILE).value();
|
||||
auto image = Image::ParseImage(file.data(), file.size()).value();
|
||||
|
||||
std::println("Loading switch tables...");
|
||||
|
||||
struct SwitchTable
|
||||
{
|
||||
size_t r;
|
||||
std::vector<size_t> labels;
|
||||
};
|
||||
|
||||
std::unordered_map<size_t, SwitchTable> switchTables;
|
||||
|
||||
toml::table toml = toml::parse_file("out/switches.toml");
|
||||
for (auto& entry : *toml["switch"].as_array())
|
||||
{
|
||||
auto& table = *entry.as_table();
|
||||
|
||||
SwitchTable switchTable;
|
||||
switchTable.r = *table["r"].value<size_t>();
|
||||
for (auto& array : *table["labels"].as_array())
|
||||
switchTable.labels.push_back(*array.value<size_t>());
|
||||
|
||||
switchTables.emplace(*table["base"].value<size_t>(), std::move(switchTable));
|
||||
}
|
||||
|
||||
std::println("Analysing functions...");
|
||||
|
||||
uint32_t cxxFrameHandler = std::byteswap(0x831B1C90);
|
||||
@ -142,11 +167,16 @@ int main()
|
||||
println("\tPPCRegister temp;");
|
||||
println("\tuint32_t ea;\n");
|
||||
|
||||
auto switchTable = switchTables.end();
|
||||
|
||||
ppc_insn insn;
|
||||
while (base < end)
|
||||
{
|
||||
println("loc_{:X}:", base);
|
||||
|
||||
if (switchTable == switchTables.end())
|
||||
switchTable = switchTables.find(base);
|
||||
|
||||
ppc::Disassemble(data, 4, base, insn);
|
||||
|
||||
base += 4;
|
||||
@ -264,8 +294,23 @@ int main()
|
||||
break;
|
||||
|
||||
case PPC_INST_BCTR:
|
||||
println("\tctx.fn[ctx.ctr / 4](ctx, base);");
|
||||
println("\treturn;");
|
||||
if (switchTable != switchTables.end())
|
||||
{
|
||||
println("\tswitch (ctx.r{}.u64) {{", switchTable->second.r);
|
||||
|
||||
for (size_t i = 0; i < switchTable->second.labels.size(); i++)
|
||||
println("\t\tcase {}: goto loc_{:X};", i, switchTable->second.labels[i]);
|
||||
|
||||
println("\t\tdefault: __unreachable();");
|
||||
println("\t}}");
|
||||
|
||||
switchTable = switchTables.end();
|
||||
}
|
||||
else
|
||||
{
|
||||
println("\tctx.fn[ctx.ctr / 4](ctx, base);");
|
||||
println("\treturn;");
|
||||
}
|
||||
break;
|
||||
|
||||
case PPC_INST_BCTRL:
|
||||
|
@ -12,10 +12,12 @@
|
||||
#define _byteswap_uint64 __builtin_bswap64
|
||||
#define isnan __builtin_isnan
|
||||
#define __assume __builtin_assume
|
||||
#define __unreachable() __builtin_unreachable()
|
||||
#define PPC_FUNC __attribute__((weak,noinline))
|
||||
#else
|
||||
#include <intrin.h>
|
||||
#define PPC_FUNC __declspec(noinline)
|
||||
#define __unreachable() __assume(0)
|
||||
#endif
|
||||
|
||||
#define PPC_LOAD_U8(x) *(uint8_t*)(base + (x))
|
||||
|
Loading…
x
Reference in New Issue
Block a user