mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-22 03:40:30 +00:00
Revert FM(a*re_accurate) shortcut to relaxed
This commit is contained in:
parent
50b1402d66
commit
af33c0c69f
@ -5620,32 +5620,37 @@ public:
|
|||||||
|
|
||||||
const auto [a, b] = get_vrs<f32[4]>(op.ra, op.rb);
|
const auto [a, b] = get_vrs<f32[4]>(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;
|
auto full_fm_accurate = [&](const auto& a, const auto& div)
|
||||||
const auto result_and = bitcast<u32[4]>(div_result) & 0x7fffffffu;
|
{
|
||||||
const auto result_cmp_inf = sext<s32[4]>(result_and == splat<u32[4]>(0x7F800000u));
|
const auto div_result = a / div;
|
||||||
const auto result_cmp_nan = sext<s32[4]>(result_and <= splat<u32[4]>(0x7F800000u));
|
const auto result_and = bitcast<u32[4]>(div_result) & 0x7fffffffu;
|
||||||
|
const auto result_cmp_inf = sext<s32[4]>(result_and == splat<u32[4]>(0x7F800000u));
|
||||||
|
const auto result_cmp_nan = sext<s32[4]>(result_and <= splat<u32[4]>(0x7F800000u));
|
||||||
|
|
||||||
const auto and_mask = bitcast<u32[4]>(result_cmp_nan) & splat<u32[4]>(0xFFFFFFFFu);
|
const auto and_mask = bitcast<u32[4]>(result_cmp_nan) & splat<u32[4]>(0xFFFFFFFFu);
|
||||||
const auto or_mask = bitcast<u32[4]>(result_cmp_inf) & splat<u32[4]>(0xFFFFFFFu);
|
const auto or_mask = bitcast<u32[4]>(result_cmp_inf) & splat<u32[4]>(0xFFFFFFFu);
|
||||||
set_vr(op.rt, bitcast<f32[4]>((bitcast<u32[4]>(div_result) & and_mask) | or_mask));
|
set_vr(op.rt, bitcast<f32[4]>((bitcast<u32[4]>(div_result) & and_mask) | or_mask));
|
||||||
};
|
};
|
||||||
|
|
||||||
// FM(a, re_accurate(div))
|
// FM(a, re_accurate(div))
|
||||||
if (const auto [ok_re_acc, div, one] = match_expr(b, re_accurate(match<f32[4]>(), match<f32[4]>())); ok_re_acc)
|
if (const auto [ok_re_acc, div, one] = match_expr(b, re_accurate(match<f32[4]>(), match<f32[4]>())); ok_re_acc)
|
||||||
{
|
{
|
||||||
full_fm_accurate(a, div);
|
full_fm_accurate(a, div);
|
||||||
erase_stores(one, b);
|
erase_stores(one, b);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FM(re_accurate(div), b)
|
// FM(re_accurate(div), b)
|
||||||
if (const auto [ok_re_acc, div, one] = match_expr(a, re_accurate(match<f32[4]>(), match<f32[4]>())); ok_re_acc)
|
if (const auto [ok_re_acc, div, one] = match_expr(a, re_accurate(match<f32[4]>(), match<f32[4]>())); ok_re_acc)
|
||||||
{
|
{
|
||||||
full_fm_accurate(b, div);
|
full_fm_accurate(b, div);
|
||||||
erase_stores(one, a);
|
erase_stores(one, a);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
set_vr(op.rt, fm(a, b));
|
set_vr(op.rt, fm(a, b));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user