Add floating ppoint hint

This commit is contained in:
Elad 2026-03-08 14:54:58 +02:00
parent 49abd6d8e5
commit e1eae3ee49
3 changed files with 30 additions and 22 deletions

View File

@ -158,6 +158,15 @@ struct spu_itype
CUFLT,
FRDS, // xfloat_tag last
CFLTS,
CFLTU,
FCEQ,
FCMEQ,
FCGT,
FCMGT, // floating_tag last
FSCRWR,
FSCRRD,
DFA,
DFS,
DFM,
@ -167,20 +176,11 @@ struct spu_itype
DFNMA,
FESD,
CFLTS,
CFLTU,
FCEQ,
FCMEQ,
FCGT,
FCMGT,
FSCRWR,
FSCRRD,
DFCEQ,
DFCMEQ,
DFCGT,
DFCMGT,
DFTSV, // floating_tag last
DFTSV,
SHLH, // shiftrot_tag first
SHLHI,
@ -248,10 +248,10 @@ struct spu_itype
return value >= BR && value <= BISL;
}
// Test for floating point instruction
// Test for floating point instruction (32-bit float)
friend constexpr bool operator &(type value, floating_tag)
{
return value >= FMA && value <= DFTSV;
return value >= FMA && value <= FCMGT;
}
// Test for 4-op instruction

View File

@ -3933,7 +3933,7 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
const auto type = g_spu_itype.decode(op.opcode);
u8 reg_save = 255;
u8 reg_save = s_reg_max;
if (type == spu_itype::STQD && op.ra == s_reg_sp && !block.reg_mod[op.rt] && !block.reg_use[op.rt])
{
@ -3953,7 +3953,12 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
// Register reg use only if it happens before reg mod
if (!block.reg_mod[reg])
{
block.reg_use.set(reg);
if (type & spu_itype::floating)
{
block.reg_maybe_float.set(reg);
}
block.reg_use[reg]++;
if (reg_save != reg && block.reg_save_dom[reg])
{
@ -3970,7 +3975,7 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
for (u8 reg : {s_reg_mfc_lsa, s_reg_mfc_tag, s_reg_mfc_size})
{
if (!block.reg_mod[reg])
block.reg_use.set(reg);
block.reg_use[reg]++;
}
}
@ -4024,7 +4029,7 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
if (i == s_reg_lr || (i >= 2 && i < s_reg_80) || i > s_reg_127)
{
if (!block.reg_mod[i])
block.reg_use.set(i);
block.reg_use[i]++;
if (!is_tail)
{
@ -6353,9 +6358,9 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
if (!reduced_loop->loop_dicts.test(i))
{
if (b.reg_use.test(i) || (!b.reg_mod.test(i) && b2.reg_use.test(i)))
if (b.reg_use[i] || (!b.reg_mod.test(i) && b2.reg_use[i]))
{
if ((b.reg_use.test(i) && b.reg_mod.test(i)) || b2.reg_mod.test(i))
if ((b.reg_use[i] && b.reg_mod.test(i)) || b2.reg_mod.test(i))
{
reduced_loop->is_constant_expression = false;
reduced_loop->loop_writes.set(i);
@ -7032,9 +7037,9 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
if (!reduced_loop->loop_dicts.test(i))
{
if (b.reg_use.test(i) || (!b.reg_mod.test(i) && b2.reg_use.test(i)))
if (b.reg_use[i] || (!b.reg_mod.test(i) && b2.reg_use[i]))
{
if ((b.reg_use.test(i) && b.reg_mod.test(i)) || b2.reg_mod.test(i))
if ((b.reg_use[i] && b.reg_mod.test(i)) || b2.reg_mod.test(i))
{
reduced_loop->is_constant_expression = false;
reduced_loop->loop_writes.set(i);

View File

@ -739,8 +739,11 @@ protected:
// Set if the initial register value in this block may be xfloat
std::bitset<s_reg_max> reg_maybe_xf{};
// Bit mask of the registers used (before modified)
std::bitset<s_reg_max> reg_use{};
// Set if register is used in floating pont instruction
std::bitset<s_reg_max> reg_maybe_float{};
// Number of times registers are used (before modified)
std::array<u32, s_reg_max> reg_use{};
// Bit mask of the trivial (u32 x 4) constant value resulting in this block
std::bitset<s_reg_max> reg_const{};