mirror of
https://github.com/hedge-dev/XenonRecomp.git
synced 2025-07-22 21:17:14 +00:00
Fix tests.
This commit is contained in:
@@ -168,7 +168,7 @@ bool Recompiler::Recompile(const Function& fn, uint32_t base, const ppc_insn& in
|
||||
}
|
||||
|
||||
println("\tdefault:");
|
||||
println("\t\t__unreachable();");
|
||||
println("\t\t__builtin_unreachable();");
|
||||
println("\t}}");
|
||||
|
||||
switchTable = switchTables.end();
|
||||
@@ -738,7 +738,7 @@ bool Recompiler::Recompile(const Function& fn, uint32_t base, const ppc_insn& in
|
||||
break;
|
||||
|
||||
case PPC_INST_LWBRX:
|
||||
print("\tctx.r{}.u64 = _byteswap_ulong(PPC_LOAD_U32(", insn.operands[0]);
|
||||
print("\tctx.r{}.u64 = __builtin_bswap32(PPC_LOAD_U32(", insn.operands[0]);
|
||||
if (insn.operands[1] != 0)
|
||||
print("ctx.r{}.u32 + ", insn.operands[1]);
|
||||
println("ctx.r{}.u32));", insn.operands[2]);
|
||||
@@ -1022,7 +1022,7 @@ bool Recompiler::Recompile(const Function& fn, uint32_t base, const ppc_insn& in
|
||||
print("\tctx.cr0.eq = _InterlockedCompareExchange64(reinterpret_cast<__int64*>(base + ");
|
||||
if (insn.operands[1] != 0)
|
||||
print("ctx.r{}.u32 + ", insn.operands[1]);
|
||||
println("ctx.r{}.u32), _byteswap_uint64(ctx.r{}.s64), _byteswap_uint64(ctx.reserved.s64)) == _byteswap_uint64(ctx.reserved.s64);",
|
||||
println("ctx.r{}.u32), __builtin_bswap64(ctx.r{}.s64), __builtin_bswap64(ctx.reserved.s64)) == __builtin_bswap64(ctx.reserved.s64);",
|
||||
insn.operands[2], insn.operands[0]);
|
||||
println("\tctx.cr0.so = ctx.xer.so;");
|
||||
break;
|
||||
@@ -1093,7 +1093,7 @@ bool Recompiler::Recompile(const Function& fn, uint32_t base, const ppc_insn& in
|
||||
print("\tPPC_STORE_U16(");
|
||||
if (insn.operands[1] != 0)
|
||||
print("ctx.r{}.u32 + ", insn.operands[1]);
|
||||
println("ctx.r{}.u32, _byteswap_ushort(ctx.r{}.u16));", insn.operands[2], insn.operands[0]);
|
||||
println("ctx.r{}.u32, __builtin_bswap16(ctx.r{}.u16));", insn.operands[2], insn.operands[0]);
|
||||
break;
|
||||
|
||||
case PPC_INST_STHX:
|
||||
@@ -1169,7 +1169,7 @@ bool Recompiler::Recompile(const Function& fn, uint32_t base, const ppc_insn& in
|
||||
print("\tPPC_STORE_U32(");
|
||||
if (insn.operands[1] != 0)
|
||||
print("ctx.r{}.u32 + ", insn.operands[1]);
|
||||
println("ctx.r{}.u32, _byteswap_ulong(ctx.r{}.u32));", insn.operands[2], insn.operands[0]);
|
||||
println("ctx.r{}.u32, __builtin_bswap32(ctx.r{}.u32));", insn.operands[2], insn.operands[0]);
|
||||
break;
|
||||
|
||||
case PPC_INST_STWCX:
|
||||
@@ -1178,7 +1178,7 @@ bool Recompiler::Recompile(const Function& fn, uint32_t base, const ppc_insn& in
|
||||
print("\tctx.cr0.eq = _InterlockedCompareExchange(reinterpret_cast<long*>(base + ");
|
||||
if (insn.operands[1] != 0)
|
||||
print("ctx.r{}.u32 + ", insn.operands[1]);
|
||||
println("ctx.r{}.u32), _byteswap_ulong(ctx.r{}.s32), _byteswap_ulong(ctx.reserved.s32)) == _byteswap_ulong(ctx.reserved.s32);",
|
||||
println("ctx.r{}.u32), __builtin_bswap32(ctx.r{}.s32), __builtin_bswap32(ctx.reserved.s32)) == __builtin_bswap32(ctx.reserved.s32);",
|
||||
insn.operands[2], insn.operands[0]);
|
||||
println("\tctx.cr0.so = ctx.xer.so;");
|
||||
break;
|
||||
@@ -1228,7 +1228,7 @@ bool Recompiler::Recompile(const Function& fn, uint32_t base, const ppc_insn& in
|
||||
break;
|
||||
|
||||
case PPC_INST_SYNC:
|
||||
println("\t__faststorefence();");
|
||||
// no op
|
||||
break;
|
||||
|
||||
case PPC_INST_TDLGEI:
|
||||
@@ -1328,6 +1328,7 @@ bool Recompiler::Recompile(const Function& fn, uint32_t base, const ppc_insn& in
|
||||
break;
|
||||
}
|
||||
|
||||
case PPC_INST_VCMPBFP:
|
||||
case PPC_INST_VCMPBFP128:
|
||||
println("\t__debugbreak();");
|
||||
break;
|
||||
@@ -1377,6 +1378,7 @@ bool Recompiler::Recompile(const Function& fn, uint32_t base, const ppc_insn& in
|
||||
println("\t_mm_store_si128((__m128i*)ctx.v{}.u8, _mm_cmpgt_epu16(_mm_load_si128((__m128i*)ctx.v{}.u16), _mm_load_si128((__m128i*)ctx.v{}.u16)));", insn.operands[0], insn.operands[1], insn.operands[2]);
|
||||
break;
|
||||
|
||||
case PPC_INST_VEXPTEFP:
|
||||
case PPC_INST_VEXPTEFP128:
|
||||
// TODO: vectorize
|
||||
println("\tctx.fpscr.setFlushMode(true);");
|
||||
@@ -1384,6 +1386,7 @@ bool Recompiler::Recompile(const Function& fn, uint32_t base, const ppc_insn& in
|
||||
println("\tctx.v{}.f32[{}] = exp2f(ctx.v{}.f32[{}]);", insn.operands[0], i, insn.operands[1], i);
|
||||
break;
|
||||
|
||||
case PPC_INST_VLOGEFP:
|
||||
case PPC_INST_VLOGEFP128:
|
||||
// TODO: vectorize
|
||||
println("\tctx.fpscr.setFlushMode(true);");
|
||||
@@ -1509,6 +1512,7 @@ bool Recompiler::Recompile(const Function& fn, uint32_t base, const ppc_insn& in
|
||||
break;
|
||||
|
||||
case PPC_INST_VPKSHUS:
|
||||
case PPC_INST_VPKSHUS128:
|
||||
println("\t_mm_store_si128((__m128i*)ctx.v{}.u8, _mm_packus_epi16(_mm_load_si128((__m128i*)ctx.v{}.s16), _mm_load_si128((__m128i*)ctx.v{}.s16)));", insn.operands[0], insn.operands[2], insn.operands[1]);
|
||||
break;
|
||||
|
||||
@@ -1518,6 +1522,7 @@ bool Recompiler::Recompile(const Function& fn, uint32_t base, const ppc_insn& in
|
||||
println("\t_mm_store_ps(ctx.v{}.f32, _mm_rcp_ps(_mm_load_ps(ctx.v{}.f32)));", insn.operands[0], insn.operands[1]);
|
||||
break;
|
||||
|
||||
case PPC_INST_VRFIM:
|
||||
case PPC_INST_VRFIM128:
|
||||
println("\tctx.fpscr.setFlushMode(true);");
|
||||
println("\t_mm_store_ps(ctx.v{}.f32, _mm_round_ps(_mm_load_ps(ctx.v{}.f32), _MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC));", insn.operands[0], insn.operands[1]);
|
||||
@@ -1529,6 +1534,7 @@ bool Recompiler::Recompile(const Function& fn, uint32_t base, const ppc_insn& in
|
||||
println("\t_mm_store_ps(ctx.v{}.f32, _mm_round_ps(_mm_load_ps(ctx.v{}.f32), _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC));", insn.operands[0], insn.operands[1]);
|
||||
break;
|
||||
|
||||
case PPC_INST_VRFIZ:
|
||||
case PPC_INST_VRFIZ128:
|
||||
println("\tctx.fpscr.setFlushMode(true);");
|
||||
println("\t_mm_store_ps(ctx.v{}.f32, _mm_round_ps(_mm_load_ps(ctx.v{}.f32), _MM_FROUND_TO_ZERO | _MM_FROUND_NO_EXC));", insn.operands[0], insn.operands[1]);
|
||||
@@ -1562,6 +1568,7 @@ bool Recompiler::Recompile(const Function& fn, uint32_t base, const ppc_insn& in
|
||||
println("\t_mm_store_si128((__m128i*)ctx.v{}.u8, _mm_alignr_epi8(_mm_load_si128((__m128i*)ctx.v{}.u8), _mm_load_si128((__m128i*)ctx.v{}.u8), {}));", insn.operands[0], insn.operands[1], insn.operands[2], 16 - insn.operands[3]);
|
||||
break;
|
||||
|
||||
case PPC_INST_VSLW:
|
||||
case PPC_INST_VSLW128:
|
||||
// TODO: vectorize, ensure endianness is correct
|
||||
for (size_t i = 0; i < 4; i++)
|
||||
@@ -1608,6 +1615,7 @@ bool Recompiler::Recompile(const Function& fn, uint32_t base, const ppc_insn& in
|
||||
println("\t_mm_store_si128((__m128i*)ctx.v{}.u8, _mm_vsr(_mm_load_si128((__m128i*)ctx.v{}.u8), _mm_load_si128((__m128i*)ctx.v{}.u8)));", insn.operands[0], insn.operands[1], insn.operands[2]);
|
||||
break;
|
||||
|
||||
case PPC_INST_VSRAW:
|
||||
case PPC_INST_VSRAW128:
|
||||
// TODO: vectorize, ensure endianness is correct
|
||||
for (size_t i = 0; i < 4; i++)
|
||||
@@ -1676,6 +1684,7 @@ bool Recompiler::Recompile(const Function& fn, uint32_t base, const ppc_insn& in
|
||||
}
|
||||
break;
|
||||
|
||||
case PPC_INST_VUPKHSB:
|
||||
case PPC_INST_VUPKHSB128:
|
||||
println("\t_mm_store_si128((__m128i*)ctx.v{}.s16, _mm_cvtepi8_epi16(_mm_unpackhi_epi64(_mm_load_si128((__m128i*)ctx.v{}.s8), _mm_load_si128((__m128i*)ctx.v{}.s8))));", insn.operands[0], insn.operands[1], insn.operands[1]);
|
||||
break;
|
||||
@@ -1685,6 +1694,7 @@ bool Recompiler::Recompile(const Function& fn, uint32_t base, const ppc_insn& in
|
||||
println("\t_mm_store_si128((__m128i*)ctx.v{}.s32, _mm_cvtepi16_epi32(_mm_unpackhi_epi64(_mm_load_si128((__m128i*)ctx.v{}.s16), _mm_load_si128((__m128i*)ctx.v{}.s16))));", insn.operands[0], insn.operands[1], insn.operands[1]);
|
||||
break;
|
||||
|
||||
case PPC_INST_VUPKLSB:
|
||||
case PPC_INST_VUPKLSB128:
|
||||
println("\t_mm_store_si128((__m128i*)ctx.v{}.s32, _mm_cvtepi8_epi16(_mm_load_si128((__m128i*)ctx.v{}.s16)));", insn.operands[0], insn.operands[1]);
|
||||
break;
|
||||
@@ -1780,6 +1790,11 @@ bool Recompiler::Recompile(const Function& fn)
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (insn.opcode == nullptr || (insn.opcode->id != PPC_INST_B && insn.opcode->id != PPC_INST_BCTR && insn.opcode->id != PPC_INST_BLR))
|
||||
std::println("Function at {:X} ends prematurely with instruction {} at {:X}", fn.base, insn.opcode != nullptr ? insn.opcode->name : "INVALID", base - 4);
|
||||
#endif
|
||||
|
||||
println("}}\n");
|
||||
|
||||
return allRecompiled;
|
||||
|
@@ -72,9 +72,10 @@ void SWARecompiler::Analyse()
|
||||
}
|
||||
}
|
||||
|
||||
auto hardcodedFuncCheck = [&](Function& f)
|
||||
auto hardcodedFuncCheck = [&](uint8_t* data, Function& f)
|
||||
{
|
||||
if (f.base == 0x824E7EF0) f.size = 0x98;
|
||||
if (*(uint32_t*)(data + 4) == 0x04000048) f.size = 0x8; // shifted ptr tail call
|
||||
else if (f.base == 0x824E7EF0) f.size = 0x98;
|
||||
else if (f.base == 0x824E7F28) f.size = 0x60;
|
||||
else if (f.base == 0x82C980E8) f.size = 0x110;
|
||||
else if (f.base == 0x82CF7080) f.size = 0x80;
|
||||
@@ -137,8 +138,9 @@ void SWARecompiler::Analyse()
|
||||
|
||||
if (address >= section.base && address < section.base + section.size && image.symbols.find(address) == image.symbols.end())
|
||||
{
|
||||
auto& fn = functions.emplace_back(Function::Analyze(section.data + address - section.base, section.base + section.size - address, address));
|
||||
hardcodedFuncCheck(fn);
|
||||
auto data = section.data + address - section.base;
|
||||
auto& fn = functions.emplace_back(Function::Analyze(data, section.base + section.size - address, address));
|
||||
hardcodedFuncCheck(data, fn);
|
||||
image.symbols.emplace(std::format("sub_{:X}", fn.base), fn.base, fn.size, Symbol_Function);
|
||||
}
|
||||
}
|
||||
@@ -179,7 +181,7 @@ void SWARecompiler::Analyse()
|
||||
else
|
||||
{
|
||||
auto& fn = functions.emplace_back(Function::Analyze(data, dataEnd - data, base));
|
||||
hardcodedFuncCheck(fn);
|
||||
hardcodedFuncCheck(data, fn);
|
||||
image.symbols.emplace(std::format("sub_{:X}", fn.base), fn.base, fn.size, Symbol_Function);
|
||||
|
||||
base += fn.size;
|
||||
|
@@ -98,8 +98,8 @@ void TestRecompiler::RecompileTests(const char* srcDirectoryPath, const char* ds
|
||||
std::println(file, "#include <ppc_context.h>");
|
||||
std::println(file, "#include <Windows.h>");
|
||||
std::println(file, "#include <print>\n");
|
||||
std::println(file, "#define PPC_CHECK_VALUE_U(lhs, rhs) if (lhs != rhs) std::println(__FUNCTION__ \" \" #lhs \" EXPECTED \" #rhs \" ACTUAL {{:X}}\", lhs)\n");
|
||||
std::println(file, "#define PPC_CHECK_VALUE_F(lhs, rhs) if (lhs != rhs) std::println(__FUNCTION__ \" \" #lhs \" EXPECTED \" #rhs \" ACTUAL {{}}\", lhs)\n");
|
||||
std::println(file, "#define PPC_CHECK_VALUE_U(f, lhs, rhs) if (lhs != rhs) std::println(#f \" \" #lhs \" EXPECTED \" #rhs \" ACTUAL {{:X}}\", lhs)\n");
|
||||
std::println(file, "#define PPC_CHECK_VALUE_F(f, lhs, rhs) if (lhs != rhs) std::println(#f \" \" #lhs \" EXPECTED \" #rhs \" ACTUAL {{}}\", lhs)\n");
|
||||
|
||||
for (auto& [fn, addr] : functions)
|
||||
{
|
||||
@@ -212,15 +212,16 @@ void TestRecompiler::RecompileTests(const char* srcDirectoryPath, const char* ds
|
||||
int commaIndex2 = str.find(',', commaIndex1 + 1);
|
||||
int closingBracketIndex = str.find(']', commaIndex2 + 1);
|
||||
|
||||
std::println(file, "\tPPC_CHECK_VALUE_U(ctx.{}.u32[3], 0x{});", reg, str.substr(openingBracketIndex + 1, commaIndex0 - openingBracketIndex - 1));
|
||||
std::println(file, "\tPPC_CHECK_VALUE_U(ctx.{}.u32[2], 0x{});", reg, str.substr(commaIndex0 + 2, commaIndex1 - commaIndex0 - 2));
|
||||
std::println(file, "\tPPC_CHECK_VALUE_U(ctx.{}.u32[1], 0x{});", reg, str.substr(commaIndex1 + 2, commaIndex2 - commaIndex1 - 2));
|
||||
std::println(file, "\tPPC_CHECK_VALUE_U(ctx.{}.u32[0], 0x{});", reg, str.substr(commaIndex2 + 2, closingBracketIndex - commaIndex2 - 2));
|
||||
std::println(file, "\tPPC_CHECK_VALUE_U({}, ctx.{}.u32[3], 0x{});", name, reg, str.substr(openingBracketIndex + 1, commaIndex0 - openingBracketIndex - 1));
|
||||
std::println(file, "\tPPC_CHECK_VALUE_U({}, ctx.{}.u32[2], 0x{});", name, reg, str.substr(commaIndex0 + 2, commaIndex1 - commaIndex0 - 2));
|
||||
std::println(file, "\tPPC_CHECK_VALUE_U({}, ctx.{}.u32[1], 0x{});", name, reg, str.substr(commaIndex1 + 2, commaIndex2 - commaIndex1 - 2));
|
||||
std::println(file, "\tPPC_CHECK_VALUE_U({}, ctx.{}.u32[0], 0x{});", name, reg, str.substr(commaIndex2 + 2, closingBracketIndex - commaIndex2 - 2));
|
||||
}
|
||||
else
|
||||
{
|
||||
std::println(file, "\tPPC_CHECK_VALUE_{}(ctx.{}.{}64, {});",
|
||||
std::println(file, "\tPPC_CHECK_VALUE_{}({}, ctx.{}.{}64, {});",
|
||||
str.find('.', secondSpaceIndex) != std::string::npos ? 'F' : 'U',
|
||||
name,
|
||||
reg,
|
||||
str.find('.', secondSpaceIndex) != std::string::npos ? 'f' : 'u',
|
||||
str.substr(secondSpaceIndex + 1));
|
||||
@@ -238,7 +239,7 @@ void TestRecompiler::RecompileTests(const char* srcDirectoryPath, const char* ds
|
||||
{
|
||||
if (str[i] != ' ')
|
||||
{
|
||||
std::println(file, "\tPPC_CHECK_VALUE_U(base[0x{} + 0x{:X}], 0x{}{});", address, j, str[i], str[i + 1]);
|
||||
std::println(file, "\tPPC_CHECK_VALUE_U({}, base[0x{} + 0x{:X}], 0x{}{});", name, address, j, str[i], str[i + 1]);
|
||||
++i; // the loop adds another
|
||||
++j;
|
||||
}
|
||||
@@ -266,9 +267,10 @@ void TestRecompiler::RecompileTests(const char* srcDirectoryPath, const char* ds
|
||||
}
|
||||
}
|
||||
|
||||
std::println(file, "void main() {{");
|
||||
std::println(file, "int main() {{");
|
||||
std::println(file, "\tuint8_t* base = reinterpret_cast<uint8_t*>(VirtualAlloc(nullptr, 0x100000000, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE));");
|
||||
fwrite(main.data(), 1, main.size(), file);
|
||||
std::println(file, "\treturn 0;");
|
||||
std::println(file, "}}");
|
||||
|
||||
fclose(file);
|
||||
|
Reference in New Issue
Block a user