diff --git a/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp b/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp index 116af6b02c..578f15d0c9 100644 --- a/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp +++ b/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp @@ -5620,32 +5620,37 @@ public: const auto [a, b] = get_vrs(op.ra, op.rb); - auto full_fm_accurate = [&](const auto& a, const auto& div) + // This causes issues in LBP 1(first platform on first temple level doesn't come down when grabbed) + // Presumably 1/x might result in Zero/NaN when a/x doesn't + if (g_cfg.core.spu_xfloat_accuracy == xfloat_accuracy::relaxed) { - const auto div_result = a / div; - 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)); + auto full_fm_accurate = [&](const auto& a, const auto& div) + { + const auto div_result = a / div; + 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 = bitcast(result_cmp_nan) & splat(0xFFFFFFFFu); - const auto or_mask = bitcast(result_cmp_inf) & splat(0xFFFFFFFu); - set_vr(op.rt, bitcast((bitcast(div_result) & and_mask) | or_mask)); - }; + const auto and_mask = bitcast(result_cmp_nan) & splat(0xFFFFFFFFu); + const auto or_mask = bitcast(result_cmp_inf) & splat(0xFFFFFFFu); + set_vr(op.rt, bitcast((bitcast(div_result) & and_mask) | or_mask)); + }; - // FM(a, re_accurate(div)) - if (const auto [ok_re_acc, div, one] = match_expr(b, re_accurate(match(), match())); ok_re_acc) - { - full_fm_accurate(a, div); - erase_stores(one, b); - return; - } + // FM(a, re_accurate(div)) + if (const auto [ok_re_acc, div, one] = match_expr(b, re_accurate(match(), match())); ok_re_acc) + { + full_fm_accurate(a, div); + erase_stores(one, b); + return; + } - // FM(re_accurate(div), b) - if (const auto [ok_re_acc, div, one] = match_expr(a, re_accurate(match(), match())); ok_re_acc) - { - full_fm_accurate(b, div); - erase_stores(one, a); - return; + // FM(re_accurate(div), b) + if (const auto [ok_re_acc, div, one] = match_expr(a, re_accurate(match(), match())); ok_re_acc) + { + full_fm_accurate(b, div); + erase_stores(one, a); + return; + } } set_vr(op.rt, fm(a, b));