From 9a7caef9af6cd2e00aa10fa9bf1267227b5ec9ab Mon Sep 17 00:00:00 2001 From: Skyth <19259897+blueskythlikesclouds@users.noreply.github.com> Date: Tue, 24 Sep 2024 10:48:35 +0300 Subject: [PATCH] Make a few failed Xenia PPC tests pass. --- PowerRecomp/recompiler.cpp | 32 +++++++++++++++++++++++++------- PowerSample/CMakeLists.txt | 3 ++- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/PowerRecomp/recompiler.cpp b/PowerRecomp/recompiler.cpp index 41764e3..6323579 100644 --- a/PowerRecomp/recompiler.cpp +++ b/PowerRecomp/recompiler.cpp @@ -80,8 +80,9 @@ bool Recompiler::Recompile(const Function& fn, uint32_t base, const ppc_insn& in break; case PPC_INST_ADDE: - // TODO: set carry flag + println("\ttemp.u8 = (ctx.r{}.u32 + ctx.r{}.u32 < ctx.r{}.u32) | (ctx.r{}.u32 + ctx.r{}.u32 + ctx.xer.ca < ctx.xer.ca);", insn.operands[1], insn.operands[2], insn.operands[1], insn.operands[1], insn.operands[2]); println("\tctx.r{}.u64 = ctx.r{}.u64 + ctx.r{}.u64 + ctx.xer.ca;", insn.operands[0], insn.operands[1], insn.operands[2]); + println("\tctx.xer.ca = temp.u8;"); if (strchr(insn.opcode->name, '.')) println("\tctx.cr0.compare(ctx.r{}.s32, 0, ctx.xer);", insn.operands[0]); break; @@ -929,7 +930,7 @@ bool Recompiler::Recompile(const Function& fn, uint32_t base, const ppc_insn& in } case PPC_INST_RLWINM: - println("\tctx.r{}.u64 = _rotl(ctx.r{}.u32, {}) & 0x{:X};", insn.operands[0], insn.operands[1], insn.operands[2], ComputeMask(insn.operands[3] + 32, insn.operands[4] + 32)); + println("\tctx.r{}.u64 = _rotl64(ctx.r{}.u32 | (ctx.r{}.u64 << 32), {}) & 0x{:X};", insn.operands[0], insn.operands[1], insn.operands[1], insn.operands[2], ComputeMask(insn.operands[3] + 32, insn.operands[4] + 32)); if (strchr(insn.opcode->name, '.')) println("\tctx.cr0.compare(ctx.r{}.s32, 0, ctx.xer);", insn.operands[0]); break; @@ -966,8 +967,16 @@ bool Recompiler::Recompile(const Function& fn, uint32_t base, const ppc_insn& in break; case PPC_INST_SRADI: - println("\tctx.xer.ca = (ctx.r{}.s64 < 0) & ((ctx.r{}.u64 & 0x{:X}) != 0);", insn.operands[1], insn.operands[1], ComputeMask(64 - insn.operands[2], 63)); - println("\tctx.r{}.s64 = ctx.r{}.s64 >> {};", insn.operands[0], insn.operands[1], insn.operands[2]); + if (insn.operands[2] != 0) + { + println("\tctx.xer.ca = (ctx.r{}.s64 < 0) & ((ctx.r{}.u64 & 0x{:X}) != 0);", insn.operands[1], insn.operands[1], ComputeMask(64 - insn.operands[2], 63)); + println("\tctx.r{}.s64 = ctx.r{}.s64 >> {};", insn.operands[0], insn.operands[1], insn.operands[2]); + } + else + { + println("\tctx.xer.ca = 0;"); + println("\tctx.r{}.s64 = ctx.r{}.s64;", insn.operands[0], insn.operands[1]); + } break; case PPC_INST_SRAW: @@ -980,8 +989,16 @@ bool Recompiler::Recompile(const Function& fn, uint32_t base, const ppc_insn& in break; case PPC_INST_SRAWI: - println("\tctx.xer.ca = (ctx.r{}.s32 < 0) & ((ctx.r{}.u32 & 0x{:X}) != 0);", insn.operands[1], insn.operands[1], ComputeMask(64 - insn.operands[2], 63)); - println("\tctx.r{}.s64 = ctx.r{}.s32 >> {};", insn.operands[0], insn.operands[1], insn.operands[2]); + if (insn.operands[2] != 0) + { + println("\tctx.xer.ca = (ctx.r{}.s32 < 0) & ((ctx.r{}.u32 & 0x{:X}) != 0);", insn.operands[1], insn.operands[1], ComputeMask(64 - insn.operands[2], 63)); + println("\tctx.r{}.s64 = ctx.r{}.s32 >> {};", insn.operands[0], insn.operands[1], insn.operands[2]); + } + else + { + println("\tctx.xer.ca = 0;"); + println("\tctx.r{}.s64 = ctx.r{}.s32;", insn.operands[0], insn.operands[1]); + } if (strchr(insn.opcode->name, '.')) println("\tctx.cr0.compare(ctx.r{}.s32, 0, ctx.xer);", insn.operands[0]); break; @@ -1223,8 +1240,9 @@ bool Recompiler::Recompile(const Function& fn, uint32_t base, const ppc_insn& in break; case PPC_INST_SUBFE: - // TODO: do we need to set the carry flag here? + println("\ttemp.u8 = (~ctx.r{}.u32 + ctx.r{}.u32 < ~ctx.r{}.u32) | (~ctx.r{}.u32 + ctx.r{}.u32 + ctx.xer.ca < ctx.xer.ca);", insn.operands[1], insn.operands[2], insn.operands[1], insn.operands[1], insn.operands[2]); println("\tctx.r{}.u64 = ~ctx.r{}.u64 + ctx.r{}.u64 + ctx.xer.ca;", insn.operands[0], insn.operands[1], insn.operands[2]); + println("\tctx.xer.ca = temp.u8;"); if (strchr(insn.opcode->name, '.')) println("\tctx.cr0.compare(ctx.r{}.s32, 0, ctx.xer);", insn.operands[0]); break; diff --git a/PowerSample/CMakeLists.txt b/PowerSample/CMakeLists.txt index b2bbbd9..a25b2b4 100644 --- a/PowerSample/CMakeLists.txt +++ b/PowerSample/CMakeLists.txt @@ -1,8 +1,9 @@ project("PowerSample") add_compile_options( - "/arch:AVX" "/fp:strict" + "-march=x86-64-v3" + "-fno-strict-aliasing" "-Wno-unused-label" "-Wno-unused-variable")