mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-05 06:21:26 +12:00
SPU: Optimize FCGT
- Optimize FCGT to a single signed integer comparison when possible - Add is_spu_float_zero helper
This commit is contained in:
parent
91ee480e56
commit
c47d04fd2f
1 changed files with 66 additions and 1 deletions
|
@ -7281,6 +7281,22 @@ public:
|
||||||
return eval(fmuladd(ca, cb, c));
|
return eval(fmuladd(ca, cb, c));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Checks for postive and negative zero, or Denormal (treated as zero)
|
||||||
|
bool is_spu_float_zero(v128 a)
|
||||||
|
{
|
||||||
|
for (u32 i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
const u32 exponent = a._u32[i] & 0x7f800000u;
|
||||||
|
|
||||||
|
if (exponent)
|
||||||
|
{
|
||||||
|
// Normalized number
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void FREST(spu_opcode_t op)
|
void FREST(spu_opcode_t op)
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
|
@ -7317,6 +7333,55 @@ public:
|
||||||
const auto a = get_vr<f32[4]>(op.ra);
|
const auto a = get_vr<f32[4]>(op.ra);
|
||||||
const auto b = get_vr<f32[4]>(op.rb);
|
const auto b = get_vr<f32[4]>(op.rb);
|
||||||
|
|
||||||
|
if (auto cv = llvm::dyn_cast<llvm::Constant>(b.value))
|
||||||
|
{
|
||||||
|
v128 data = get_const_vector(cv, m_pos, 5000);
|
||||||
|
bool safe_int_compare = true;
|
||||||
|
|
||||||
|
for (u32 i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
const u32 exponent = data._u32[i] & 0x7f800000u;
|
||||||
|
|
||||||
|
if (data._u32[i] > 0x7f7fffffu || !exponent)
|
||||||
|
{
|
||||||
|
// Postive or negative zero, Denormal (treated as zero), Negative constant, or Normalized number with exponent +127
|
||||||
|
// Cannot used signed integer compare safely
|
||||||
|
safe_int_compare = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (safe_int_compare)
|
||||||
|
{
|
||||||
|
set_vr(op.rt, sext<s32[4]>(bitcast<s32[4]>(a) > bitcast<s32[4]>(b)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto cv = llvm::dyn_cast<llvm::Constant>(a.value))
|
||||||
|
{
|
||||||
|
v128 data = get_const_vector(cv, m_pos, 5000);
|
||||||
|
bool safe_int_compare = true;
|
||||||
|
|
||||||
|
for (u32 i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
const u32 exponent = data._u32[i] & 0x7f800000u;
|
||||||
|
|
||||||
|
if (data._u32[i] > 0x7f7fffffu || !exponent)
|
||||||
|
{
|
||||||
|
// See above
|
||||||
|
safe_int_compare = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (safe_int_compare)
|
||||||
|
{
|
||||||
|
set_vr(op.rt, sext<s32[4]>(bitcast<s32[4]>(a) > bitcast<s32[4]>(b)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (g_cfg.core.spu_approx_xfloat)
|
if (g_cfg.core.spu_approx_xfloat)
|
||||||
{
|
{
|
||||||
const auto ca = eval(clamp_positive_smax(a));
|
const auto ca = eval(clamp_positive_smax(a));
|
||||||
|
@ -7460,7 +7525,7 @@ public:
|
||||||
{
|
{
|
||||||
v128 data = get_const_vector(cv, m_pos, 4000);
|
v128 data = get_const_vector(cv, m_pos, 4000);
|
||||||
|
|
||||||
if (data == v128{})
|
if (is_spu_float_zero(data))
|
||||||
{
|
{
|
||||||
r = eval(ca * cb);
|
r = eval(ca * cb);
|
||||||
return r;
|
return r;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue