Add floating ppoint hint
This commit is contained in:
@@ -158,6 +158,15 @@ struct spu_itype
|
|||||||
CUFLT,
|
CUFLT,
|
||||||
FRDS, // xfloat_tag last
|
FRDS, // xfloat_tag last
|
||||||
|
|
||||||
|
CFLTS,
|
||||||
|
CFLTU,
|
||||||
|
FCEQ,
|
||||||
|
FCMEQ,
|
||||||
|
FCGT,
|
||||||
|
FCMGT, // floating_tag last
|
||||||
|
FSCRWR,
|
||||||
|
FSCRRD,
|
||||||
|
|
||||||
DFA,
|
DFA,
|
||||||
DFS,
|
DFS,
|
||||||
DFM,
|
DFM,
|
||||||
@@ -167,20 +176,11 @@ struct spu_itype
|
|||||||
DFNMA,
|
DFNMA,
|
||||||
FESD,
|
FESD,
|
||||||
|
|
||||||
CFLTS,
|
|
||||||
CFLTU,
|
|
||||||
FCEQ,
|
|
||||||
FCMEQ,
|
|
||||||
FCGT,
|
|
||||||
FCMGT,
|
|
||||||
FSCRWR,
|
|
||||||
FSCRRD,
|
|
||||||
|
|
||||||
DFCEQ,
|
DFCEQ,
|
||||||
DFCMEQ,
|
DFCMEQ,
|
||||||
DFCGT,
|
DFCGT,
|
||||||
DFCMGT,
|
DFCMGT,
|
||||||
DFTSV, // floating_tag last
|
DFTSV,
|
||||||
|
|
||||||
SHLH, // shiftrot_tag first
|
SHLH, // shiftrot_tag first
|
||||||
SHLHI,
|
SHLHI,
|
||||||
@@ -248,10 +248,10 @@ struct spu_itype
|
|||||||
return value >= BR && value <= BISL;
|
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)
|
friend constexpr bool operator &(type value, floating_tag)
|
||||||
{
|
{
|
||||||
return value >= FMA && value <= DFTSV;
|
return value >= FMA && value <= FCMGT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test for 4-op instruction
|
// Test for 4-op instruction
|
||||||
|
|||||||
@@ -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);
|
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])
|
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
|
// Register reg use only if it happens before reg mod
|
||||||
if (!block.reg_mod[reg])
|
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])
|
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})
|
for (u8 reg : {s_reg_mfc_lsa, s_reg_mfc_tag, s_reg_mfc_size})
|
||||||
{
|
{
|
||||||
if (!block.reg_mod[reg])
|
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 (i == s_reg_lr || (i >= 2 && i < s_reg_80) || i > s_reg_127)
|
||||||
{
|
{
|
||||||
if (!block.reg_mod[i])
|
if (!block.reg_mod[i])
|
||||||
block.reg_use.set(i);
|
block.reg_use[i]++;
|
||||||
|
|
||||||
if (!is_tail)
|
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 (!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->is_constant_expression = false;
|
||||||
reduced_loop->loop_writes.set(i);
|
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 (!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->is_constant_expression = false;
|
||||||
reduced_loop->loop_writes.set(i);
|
reduced_loop->loop_writes.set(i);
|
||||||
|
|||||||
@@ -739,8 +739,11 @@ protected:
|
|||||||
// Set if the initial register value in this block may be xfloat
|
// Set if the initial register value in this block may be xfloat
|
||||||
std::bitset<s_reg_max> reg_maybe_xf{};
|
std::bitset<s_reg_max> reg_maybe_xf{};
|
||||||
|
|
||||||
// Bit mask of the registers used (before modified)
|
// Set if register is used in floating pont instruction
|
||||||
std::bitset<s_reg_max> reg_use{};
|
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
|
// Bit mask of the trivial (u32 x 4) constant value resulting in this block
|
||||||
std::bitset<s_reg_max> reg_const{};
|
std::bitset<s_reg_max> reg_const{};
|
||||||
|
|||||||
Reference in New Issue
Block a user