mirror of
				https://github.com/hedge-dev/XenonRecomp.git
				synced 2025-11-04 06:47:09 +00:00 
			
		
		
		
	Implement switch case generation.
This commit is contained in:
		@@ -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))
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user