diff --git a/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp b/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp index 578f15d0c9..e2d2fcd2dd 100644 --- a/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp +++ b/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp @@ -6016,15 +6016,17 @@ public: const auto div_result = the_one / div; - // from ps3 hardware testing: Inf => NaN and NaN => Zero + // 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_cmp_inf = sext(result_and == splat(0x7F800000u)); const auto result_cmp_nan = sext(result_and <= splat(0x7F800000u)); + const auto and_mask_zero = bitcast(sext(result_and != splat(0u))); const auto and_mask = bitcast(result_cmp_nan) & splat(0xFFFFFFFFu); const auto or_mask = bitcast(result_cmp_inf) & splat(0xFFFFFFFu); - return bitcast((bitcast(div_result) & and_mask) | or_mask); + return bitcast(((bitcast(div_result) & and_mask) & and_mask_zero) | or_mask); }); const auto [a, b, c] = get_vrs(op.ra, op.rb, op.rc);