mirror of
https://github.com/hedge-dev/XenonRecomp.git
synced 2025-05-23 10:22:06 +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>")
|
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)
|
add_subdirectory(${THIRDPARTY_ROOT}/disasm)
|
||||||
|
|
||||||
project ("PowerRecomp-ALL")
|
project ("PowerRecomp-ALL")
|
||||||
|
@ -3,4 +3,4 @@ cmake_minimum_required (VERSION 3.8)
|
|||||||
project("PowerRecomp")
|
project("PowerRecomp")
|
||||||
|
|
||||||
add_executable(PowerRecomp "main.cpp")
|
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 <filesystem>
|
||||||
#include <xbox.h>
|
#include <xbox.h>
|
||||||
#include <cassert>
|
#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)
|
static uint64_t computeMask(uint32_t mstart, uint32_t mstop)
|
||||||
{
|
{
|
||||||
@ -23,6 +25,29 @@ int main()
|
|||||||
const auto file = LoadFile(TEST_FILE).value();
|
const auto file = LoadFile(TEST_FILE).value();
|
||||||
auto image = Image::ParseImage(file.data(), file.size()).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...");
|
std::println("Analysing functions...");
|
||||||
|
|
||||||
uint32_t cxxFrameHandler = std::byteswap(0x831B1C90);
|
uint32_t cxxFrameHandler = std::byteswap(0x831B1C90);
|
||||||
@ -142,11 +167,16 @@ int main()
|
|||||||
println("\tPPCRegister temp;");
|
println("\tPPCRegister temp;");
|
||||||
println("\tuint32_t ea;\n");
|
println("\tuint32_t ea;\n");
|
||||||
|
|
||||||
|
auto switchTable = switchTables.end();
|
||||||
|
|
||||||
ppc_insn insn;
|
ppc_insn insn;
|
||||||
while (base < end)
|
while (base < end)
|
||||||
{
|
{
|
||||||
println("loc_{:X}:", base);
|
println("loc_{:X}:", base);
|
||||||
|
|
||||||
|
if (switchTable == switchTables.end())
|
||||||
|
switchTable = switchTables.find(base);
|
||||||
|
|
||||||
ppc::Disassemble(data, 4, base, insn);
|
ppc::Disassemble(data, 4, base, insn);
|
||||||
|
|
||||||
base += 4;
|
base += 4;
|
||||||
@ -264,8 +294,23 @@ int main()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PPC_INST_BCTR:
|
case PPC_INST_BCTR:
|
||||||
println("\tctx.fn[ctx.ctr / 4](ctx, base);");
|
if (switchTable != switchTables.end())
|
||||||
println("\treturn;");
|
{
|
||||||
|
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;
|
break;
|
||||||
|
|
||||||
case PPC_INST_BCTRL:
|
case PPC_INST_BCTRL:
|
||||||
|
@ -12,10 +12,12 @@
|
|||||||
#define _byteswap_uint64 __builtin_bswap64
|
#define _byteswap_uint64 __builtin_bswap64
|
||||||
#define isnan __builtin_isnan
|
#define isnan __builtin_isnan
|
||||||
#define __assume __builtin_assume
|
#define __assume __builtin_assume
|
||||||
|
#define __unreachable() __builtin_unreachable()
|
||||||
#define PPC_FUNC __attribute__((weak,noinline))
|
#define PPC_FUNC __attribute__((weak,noinline))
|
||||||
#else
|
#else
|
||||||
#include <intrin.h>
|
#include <intrin.h>
|
||||||
#define PPC_FUNC __declspec(noinline)
|
#define PPC_FUNC __declspec(noinline)
|
||||||
|
#define __unreachable() __assume(0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define PPC_LOAD_U8(x) *(uint8_t*)(base + (x))
|
#define PPC_LOAD_U8(x) *(uint8_t*)(base + (x))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user