mirror of
https://github.com/hedge-dev/XenonRecomp.git
synced 2025-06-23 16:05:30 +00:00
Add several config options for more efficient code generation.
This commit is contained in:
parent
746947455d
commit
70497754d9
@ -11,6 +11,14 @@ int main(int argc, char* argv[])
|
|||||||
if (strstr(argv[1], ".xex") != nullptr)
|
if (strstr(argv[1], ".xex") != nullptr)
|
||||||
{
|
{
|
||||||
SWARecompiler recompiler;
|
SWARecompiler recompiler;
|
||||||
|
recompiler.config.skipLr = true;
|
||||||
|
recompiler.config.ctrAsLocalVariable = true;
|
||||||
|
recompiler.config.xerAsLocalVariable = true;
|
||||||
|
recompiler.config.reservedRegisterAsLocalVariable = true;
|
||||||
|
recompiler.config.skipMsr = true;
|
||||||
|
recompiler.config.crRegistersAsLocalVariables = true;
|
||||||
|
recompiler.config.nonArgumentRegistersAsLocalVariables = true;
|
||||||
|
recompiler.config.nonVolatileRegistersAsLocalVariables = true;
|
||||||
|
|
||||||
std::println("Loading executable...");
|
std::println("Loading executable...");
|
||||||
recompiler.LoadExecutable(argv[1]);
|
recompiler.LoadExecutable(argv[1]);
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -7,6 +7,33 @@ struct SwitchTable
|
|||||||
std::vector<size_t> labels;
|
std::vector<size_t> labels;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct RecompilerLocalVariables
|
||||||
|
{
|
||||||
|
bool ctr{};
|
||||||
|
bool xer{};
|
||||||
|
bool reserved{};
|
||||||
|
bool cr[8]{};
|
||||||
|
bool r[32]{};
|
||||||
|
bool f[32]{};
|
||||||
|
bool v[128]{};
|
||||||
|
bool env{};
|
||||||
|
bool temp{};
|
||||||
|
bool vTemp{};
|
||||||
|
bool ea{};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RecompilerConfig
|
||||||
|
{
|
||||||
|
bool skipLr = false;
|
||||||
|
bool ctrAsLocalVariable = false;
|
||||||
|
bool xerAsLocalVariable = false;
|
||||||
|
bool reservedRegisterAsLocalVariable = false;
|
||||||
|
bool skipMsr = false;
|
||||||
|
bool crRegistersAsLocalVariables = false;
|
||||||
|
bool nonArgumentRegistersAsLocalVariables = false;
|
||||||
|
bool nonVolatileRegistersAsLocalVariables = false;
|
||||||
|
};
|
||||||
|
|
||||||
struct Recompiler
|
struct Recompiler
|
||||||
{
|
{
|
||||||
Image image;
|
Image image;
|
||||||
@ -15,8 +42,10 @@ struct Recompiler
|
|||||||
std::string out;
|
std::string out;
|
||||||
size_t cppFileIndex = 0;
|
size_t cppFileIndex = 0;
|
||||||
std::vector<uint8_t> temp;
|
std::vector<uint8_t> temp;
|
||||||
|
std::string tempString;
|
||||||
uint32_t setJmpAddress = 0;
|
uint32_t setJmpAddress = 0;
|
||||||
uint32_t longJmpAddress = 0;
|
uint32_t longJmpAddress = 0;
|
||||||
|
RecompilerConfig config;
|
||||||
|
|
||||||
void LoadSwitchTables(const char* filePath);
|
void LoadSwitchTables(const char* filePath);
|
||||||
void LoadExecutable(const char* filePath);
|
void LoadExecutable(const char* filePath);
|
||||||
@ -34,7 +63,12 @@ struct Recompiler
|
|||||||
out += '\n';
|
out += '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Recompile(const Function& fn, uint32_t base, const ppc_insn& insn, std::unordered_map<size_t, SwitchTable>::iterator& switchTable);
|
bool Recompile(
|
||||||
|
const Function& fn,
|
||||||
|
uint32_t base,
|
||||||
|
const ppc_insn& insn,
|
||||||
|
std::unordered_map<size_t, SwitchTable>::iterator& switchTable,
|
||||||
|
RecompilerLocalVariables& localVariables);
|
||||||
|
|
||||||
bool Recompile(const Function& fn);
|
bool Recompile(const Function& fn);
|
||||||
|
|
||||||
|
@ -45,6 +45,7 @@ void TestRecompiler::RecompileTests(const char* srcDirectoryPath, const char* ds
|
|||||||
auto stem = file.path().stem().string();
|
auto stem = file.path().stem().string();
|
||||||
recompiler.Analyse(stem);
|
recompiler.Analyse(stem);
|
||||||
|
|
||||||
|
recompiler.println("#define PPC_CONFIG_H_INCLUDED");
|
||||||
recompiler.println("#include <ppc_context.h>\n");
|
recompiler.println("#include <ppc_context.h>\n");
|
||||||
recompiler.println("#define __debugbreak()\n");
|
recompiler.println("#define __debugbreak()\n");
|
||||||
|
|
||||||
@ -95,6 +96,7 @@ void TestRecompiler::RecompileTests(const char* srcDirectoryPath, const char* ds
|
|||||||
FILE* file = fopen(std::format("{}/main.cpp", dstDirectoryPath).c_str(), "w");
|
FILE* file = fopen(std::format("{}/main.cpp", dstDirectoryPath).c_str(), "w");
|
||||||
std::string main;
|
std::string main;
|
||||||
|
|
||||||
|
std::println(file, "#define PPC_CONFIG_H_INCLUDED");
|
||||||
std::println(file, "#include <ppc_context.h>");
|
std::println(file, "#include <ppc_context.h>");
|
||||||
std::println(file, "#include <Windows.h>");
|
std::println(file, "#include <Windows.h>");
|
||||||
std::println(file, "#include <print>\n");
|
std::println(file, "#include <print>\n");
|
||||||
|
@ -1,4 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef PPC_CONFIG_H_INCLUDED
|
||||||
|
#error "ppc_config.h must be included before ppc_context.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
@ -7,6 +12,7 @@
|
|||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
#include <x86intrin.h>
|
#include <x86intrin.h>
|
||||||
|
#define PPC_NOINLINE __attribute__((noinline))
|
||||||
#else
|
#else
|
||||||
#include <intrin.h>
|
#include <intrin.h>
|
||||||
#define __restrict__ __restrict
|
#define __restrict__ __restrict
|
||||||
@ -16,16 +22,13 @@
|
|||||||
#define __builtin_isnan isnan
|
#define __builtin_isnan isnan
|
||||||
#define __builtin_assume __assume
|
#define __builtin_assume __assume
|
||||||
#define __builtin_unreachable() __assume(0)
|
#define __builtin_unreachable() __assume(0)
|
||||||
|
#define PPC_NOINLINE __declspec(noinline)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define PPC_FUNC(x) extern "C" void x(PPCContext& __restrict__ ctx, uint8_t* base)
|
#define PPC_FUNC(x) extern "C" PPC_NOINLINE void x(PPCContext& __restrict__ ctx, uint8_t* base)
|
||||||
|
|
||||||
#define PPC_FUNC_PROLOGUE() \
|
#define PPC_FUNC_PROLOGUE() \
|
||||||
__builtin_assume((reinterpret_cast<size_t>(base) & 0xFFFFFFFF) == 0); \
|
__builtin_assume(((size_t)base & 0xFFFFFFFF) == 0); \
|
||||||
PPCContext env; \
|
|
||||||
PPCRegister temp; \
|
|
||||||
PPCVRegister vtemp; \
|
|
||||||
uint32_t ea
|
|
||||||
|
|
||||||
#define PPC_LOAD_U8(x) *(uint8_t*)(base + (x))
|
#define PPC_LOAD_U8(x) *(uint8_t*)(base + (x))
|
||||||
#define PPC_LOAD_U16(x) __builtin_bswap16(*(uint16_t*)(base + (x)))
|
#define PPC_LOAD_U16(x) __builtin_bswap16(*(uint16_t*)(base + (x)))
|
||||||
@ -37,6 +40,9 @@
|
|||||||
#define PPC_STORE_U32(x, y) *(uint32_t*)(base + (x)) = __builtin_bswap32(y)
|
#define PPC_STORE_U32(x, y) *(uint32_t*)(base + (x)) = __builtin_bswap32(y)
|
||||||
#define PPC_STORE_U64(x, y) *(uint64_t*)(base + (x)) = __builtin_bswap64(y)
|
#define PPC_STORE_U64(x, y) *(uint64_t*)(base + (x)) = __builtin_bswap64(y)
|
||||||
|
|
||||||
|
#define PPC_CALL_FUNC(x) x(ctx, base)
|
||||||
|
#define PPC_CALL_INDIRECT_FUNC(x) (*(PPCFunc**)(ctx.fn + uint64_t(x) * 2))(ctx, base)
|
||||||
|
|
||||||
typedef void PPCFunc(struct PPCContext& __restrict__ ctx, uint8_t* base);
|
typedef void PPCFunc(struct PPCContext& __restrict__ ctx, uint8_t* base);
|
||||||
|
|
||||||
struct PPCFuncMapping
|
struct PPCFuncMapping
|
||||||
@ -83,7 +89,7 @@ struct PPCCRRegister
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void compare(T left, T right, const PPCXERRegister& xer)
|
inline void compare(T left, T right, const PPCXERRegister& xer) noexcept
|
||||||
{
|
{
|
||||||
lt = left < right;
|
lt = left < right;
|
||||||
gt = left > right;
|
gt = left > right;
|
||||||
@ -91,7 +97,7 @@ struct PPCCRRegister
|
|||||||
so = xer.so;
|
so = xer.so;
|
||||||
}
|
}
|
||||||
|
|
||||||
void compare(double left, double right)
|
inline void compare(double left, double right) noexcept
|
||||||
{
|
{
|
||||||
un = __builtin_isnan(left) || __builtin_isnan(right);
|
un = __builtin_isnan(left) || __builtin_isnan(right);
|
||||||
lt = !un && (left < right);
|
lt = !un && (left < right);
|
||||||
@ -99,7 +105,7 @@ struct PPCCRRegister
|
|||||||
eq = !un && (left == right);
|
eq = !un && (left == right);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setFromMask(__m128 mask, int imm)
|
inline void setFromMask(__m128 mask, int imm) noexcept
|
||||||
{
|
{
|
||||||
int m = _mm_movemask_ps(mask);
|
int m = _mm_movemask_ps(mask);
|
||||||
lt = m == imm; // all equal
|
lt = m == imm; // all equal
|
||||||
@ -108,7 +114,7 @@ struct PPCCRRegister
|
|||||||
so = 0;
|
so = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setFromMask(__m128i mask, int imm)
|
inline void setFromMask(__m128i mask, int imm) noexcept
|
||||||
{
|
{
|
||||||
int m = _mm_movemask_epi8(mask);
|
int m = _mm_movemask_epi8(mask);
|
||||||
lt = m == imm; // all equal
|
lt = m == imm; // all equal
|
||||||
@ -139,20 +145,20 @@ struct PPCFPSCRRegister
|
|||||||
{
|
{
|
||||||
uint32_t csr;
|
uint32_t csr;
|
||||||
|
|
||||||
uint32_t loadFromHost()
|
inline uint32_t loadFromHost() noexcept
|
||||||
{
|
{
|
||||||
csr = _mm_getcsr();
|
csr = _mm_getcsr();
|
||||||
return (0x6C >> ((csr & _MM_ROUND_MASK) >> 12)) & 3;
|
return (0x6C >> ((csr & _MM_ROUND_MASK) >> 12)) & 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
void storeFromGuest(uint32_t value)
|
inline void storeFromGuest(uint32_t value) noexcept
|
||||||
{
|
{
|
||||||
csr &= ~_MM_ROUND_MASK;
|
csr &= ~_MM_ROUND_MASK;
|
||||||
csr |= ((0x6C >> (2 * (value & 3))) & 3) << 13;
|
csr |= ((0x6C >> (2 * (value & 3))) & 3) << 13;
|
||||||
_mm_setcsr(csr);
|
_mm_setcsr(csr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setFlushMode(bool enable)
|
inline void setFlushMode(bool enable) noexcept
|
||||||
{
|
{
|
||||||
constexpr uint32_t mask = _MM_FLUSH_ZERO_MASK | _MM_DENORMALS_ZERO_MASK;
|
constexpr uint32_t mask = _MM_FLUSH_ZERO_MASK | _MM_DENORMALS_ZERO_MASK;
|
||||||
uint32_t value = enable ? (csr | mask) : (csr & ~mask);
|
uint32_t value = enable ? (csr | mask) : (csr & ~mask);
|
||||||
@ -167,13 +173,25 @@ struct PPCFPSCRRegister
|
|||||||
|
|
||||||
struct PPCContext
|
struct PPCContext
|
||||||
{
|
{
|
||||||
PPCFunc** fn;
|
uint8_t* fn;
|
||||||
uint64_t lr;
|
|
||||||
PPCRegister ctr;
|
|
||||||
PPCXERRegister xer;
|
|
||||||
PPCRegister reserved;
|
|
||||||
uint32_t msr = 0x200A000;
|
|
||||||
|
|
||||||
|
#ifndef PPC_CONFIG_SKIP_LR
|
||||||
|
uint64_t lr;
|
||||||
|
#endif
|
||||||
|
#ifndef PPC_CONFIG_CTR_AS_LOCAL
|
||||||
|
PPCRegister ctr;
|
||||||
|
#endif
|
||||||
|
#ifndef PPC_CONFIG_XER_AS_LOCAL
|
||||||
|
PPCXERRegister xer;
|
||||||
|
#endif
|
||||||
|
#ifndef PPC_CONFIG_RESERVED_AS_LOCAL
|
||||||
|
PPCRegister reserved;
|
||||||
|
#endif
|
||||||
|
#ifndef PPC_CONFIG_SKIP_MSR
|
||||||
|
uint32_t msr = 0x200A000;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef PPC_CONFIG_CR_AS_LOCAL
|
||||||
PPCCRRegister cr0;
|
PPCCRRegister cr0;
|
||||||
PPCCRRegister cr1;
|
PPCCRRegister cr1;
|
||||||
PPCCRRegister cr2;
|
PPCCRRegister cr2;
|
||||||
@ -182,10 +200,15 @@ struct PPCContext
|
|||||||
PPCCRRegister cr5;
|
PPCCRRegister cr5;
|
||||||
PPCCRRegister cr6;
|
PPCCRRegister cr6;
|
||||||
PPCCRRegister cr7;
|
PPCCRRegister cr7;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef PPC_CONFIG_NON_ARGUMENT_AS_LOCAL
|
||||||
PPCRegister r0;
|
PPCRegister r0;
|
||||||
|
#endif
|
||||||
PPCRegister r1;
|
PPCRegister r1;
|
||||||
|
#ifndef PPC_CONFIG_NON_ARGUMENT_AS_LOCAL
|
||||||
PPCRegister r2;
|
PPCRegister r2;
|
||||||
|
#endif
|
||||||
PPCRegister r3;
|
PPCRegister r3;
|
||||||
PPCRegister r4;
|
PPCRegister r4;
|
||||||
PPCRegister r5;
|
PPCRegister r5;
|
||||||
@ -194,9 +217,12 @@ struct PPCContext
|
|||||||
PPCRegister r8;
|
PPCRegister r8;
|
||||||
PPCRegister r9;
|
PPCRegister r9;
|
||||||
PPCRegister r10;
|
PPCRegister r10;
|
||||||
|
#ifndef PPC_CONFIG_NON_ARGUMENT_AS_LOCAL
|
||||||
PPCRegister r11;
|
PPCRegister r11;
|
||||||
PPCRegister r12;
|
PPCRegister r12;
|
||||||
|
#endif
|
||||||
PPCRegister r13;
|
PPCRegister r13;
|
||||||
|
#ifndef PPC_CONFIG_NON_VOLATILE_AS_LOCAL
|
||||||
PPCRegister r14;
|
PPCRegister r14;
|
||||||
PPCRegister r15;
|
PPCRegister r15;
|
||||||
PPCRegister r16;
|
PPCRegister r16;
|
||||||
@ -215,10 +241,13 @@ struct PPCContext
|
|||||||
PPCRegister r29;
|
PPCRegister r29;
|
||||||
PPCRegister r30;
|
PPCRegister r30;
|
||||||
PPCRegister r31;
|
PPCRegister r31;
|
||||||
|
#endif
|
||||||
|
|
||||||
PPCFPSCRRegister fpscr;
|
PPCFPSCRRegister fpscr;
|
||||||
|
|
||||||
|
#ifndef PPC_CONFIG_NON_ARGUMENT_AS_LOCAL
|
||||||
PPCRegister f0;
|
PPCRegister f0;
|
||||||
|
#endif
|
||||||
PPCRegister f1;
|
PPCRegister f1;
|
||||||
PPCRegister f2;
|
PPCRegister f2;
|
||||||
PPCRegister f3;
|
PPCRegister f3;
|
||||||
@ -232,6 +261,7 @@ struct PPCContext
|
|||||||
PPCRegister f11;
|
PPCRegister f11;
|
||||||
PPCRegister f12;
|
PPCRegister f12;
|
||||||
PPCRegister f13;
|
PPCRegister f13;
|
||||||
|
#ifndef PPC_CONFIG_NON_VOLATILE_AS_LOCAL
|
||||||
PPCRegister f14;
|
PPCRegister f14;
|
||||||
PPCRegister f15;
|
PPCRegister f15;
|
||||||
PPCRegister f16;
|
PPCRegister f16;
|
||||||
@ -250,7 +280,8 @@ struct PPCContext
|
|||||||
PPCRegister f29;
|
PPCRegister f29;
|
||||||
PPCRegister f30;
|
PPCRegister f30;
|
||||||
PPCRegister f31;
|
PPCRegister f31;
|
||||||
|
#endif
|
||||||
|
|
||||||
PPCVRegister v0;
|
PPCVRegister v0;
|
||||||
PPCVRegister v1;
|
PPCVRegister v1;
|
||||||
PPCVRegister v2;
|
PPCVRegister v2;
|
||||||
@ -265,6 +296,7 @@ struct PPCContext
|
|||||||
PPCVRegister v11;
|
PPCVRegister v11;
|
||||||
PPCVRegister v12;
|
PPCVRegister v12;
|
||||||
PPCVRegister v13;
|
PPCVRegister v13;
|
||||||
|
#ifndef PPC_CONFIG_NON_VOLATILE_AS_LOCAL
|
||||||
PPCVRegister v14;
|
PPCVRegister v14;
|
||||||
PPCVRegister v15;
|
PPCVRegister v15;
|
||||||
PPCVRegister v16;
|
PPCVRegister v16;
|
||||||
@ -283,6 +315,8 @@ struct PPCContext
|
|||||||
PPCVRegister v29;
|
PPCVRegister v29;
|
||||||
PPCVRegister v30;
|
PPCVRegister v30;
|
||||||
PPCVRegister v31;
|
PPCVRegister v31;
|
||||||
|
#endif
|
||||||
|
#ifndef PPC_CONFIG_NON_ARGUMENT_AS_LOCAL
|
||||||
PPCVRegister v32;
|
PPCVRegister v32;
|
||||||
PPCVRegister v33;
|
PPCVRegister v33;
|
||||||
PPCVRegister v34;
|
PPCVRegister v34;
|
||||||
@ -315,6 +349,8 @@ struct PPCContext
|
|||||||
PPCVRegister v61;
|
PPCVRegister v61;
|
||||||
PPCVRegister v62;
|
PPCVRegister v62;
|
||||||
PPCVRegister v63;
|
PPCVRegister v63;
|
||||||
|
#endif
|
||||||
|
#ifndef PPC_CONFIG_NON_VOLATILE_AS_LOCAL
|
||||||
PPCVRegister v64;
|
PPCVRegister v64;
|
||||||
PPCVRegister v65;
|
PPCVRegister v65;
|
||||||
PPCVRegister v66;
|
PPCVRegister v66;
|
||||||
@ -379,6 +415,7 @@ struct PPCContext
|
|||||||
PPCVRegister v125;
|
PPCVRegister v125;
|
||||||
PPCVRegister v126;
|
PPCVRegister v126;
|
||||||
PPCVRegister v127;
|
PPCVRegister v127;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
inline uint8_t VectorMaskL[] =
|
inline uint8_t VectorMaskL[] =
|
||||||
|
Loading…
x
Reference in New Issue
Block a user