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) {