From 1578d938ebefe9bcf63d2f0fc599e35efa12355e Mon Sep 17 00:00:00 2001 From: RipleyTom Date: Thu, 15 Feb 2024 01:12:36 +0100 Subject: [PATCH] Add alternative reciprocal pattern --- rpcs3/Emu/Cell/SPULLVMRecompiler.cpp | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp b/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp index 59198d6017..4c5399ac7d 100644 --- a/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp +++ b/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp @@ -6018,7 +6018,7 @@ public: // From ps3 hardware testing: Inf => NaN and NaN => Zero, Signed Zero => Zero // This results in full accuracy within 1ulp(Currently x86 seems to be rounding up?) - const auto result_and = bitcast(div_result) & 0x7fffffffu; + const auto result_and = bitcast(div_result) & 0x7FFFFFFFu; const auto result_cmp_inf = sext(result_and == splat(0x7F800000u)); const auto result_cmp_nan = sext(result_and <= splat(0x7F800000u)); @@ -6113,6 +6113,27 @@ public: if (check_accurate_reciprocal_pattern_for_float(std::bit_cast(std::bit_cast(1.0f) + 1))) return; + // GOW 3(uses 1.0f * spu_re(div) instead of just spu_re(div) in the pattern) + auto check_alternative_reciprocal_pattern_for_float = [&](f32 float_value) -> bool + { + if (auto [ok_fm, div] = match_expr(c, fm(spu_re(MT), fsplat(1.0f))); ok_fm) + { + if (auto [ok_fnms] = match_expr(a, fnms(c, div, fsplat(1.0f))); ok_fnms) + { + if (auto [ok_spure] = match_expr(b, spu_re(div)); ok_spure) + { + erase_stores(a, b, c); + set_vr(op.rt4, re_accurate(div, fsplat(float_value))); + return true; + } + } + } + return false; + }; + + if (check_alternative_reciprocal_pattern_for_float()) + return; + // NFS Most Wanted doesn't like this if (g_cfg.core.spu_xfloat_accuracy == xfloat_accuracy::relaxed) {