mirror of https://github.com/RPCS3/rpcs3.git
SPU LLVM: Upgrade constants propagation
This commit is contained in:
parent
844cc654f2
commit
f6a9ac73b4
|
@ -4277,13 +4277,6 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
|
||||||
{
|
{
|
||||||
const u32 orig = bb.reg_origin_abs[i];
|
const u32 orig = bb.reg_origin_abs[i];
|
||||||
|
|
||||||
if (orig < 0x40000)
|
|
||||||
{
|
|
||||||
auto& src = ::at32(m_bbs, orig);
|
|
||||||
bb.reg_const[i] = src.reg_const[i];
|
|
||||||
bb.reg_val32[i] = src.reg_val32[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!bb.reg_save_dom[i] && bb.reg_use[i] && (orig == 0x40000 || orig + 2 == 0))
|
if (!bb.reg_save_dom[i] && bb.reg_use[i] && (orig == 0x40000 || orig + 2 == 0))
|
||||||
{
|
{
|
||||||
// Destroy offset if external reg value is used
|
// Destroy offset if external reg value is used
|
||||||
|
@ -4317,71 +4310,6 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
|
||||||
// Propagate some constants
|
// Propagate some constants
|
||||||
switch (last_inst)
|
switch (last_inst)
|
||||||
{
|
{
|
||||||
case spu_itype::IL:
|
|
||||||
{
|
|
||||||
bb.reg_const[op.rt] = true;
|
|
||||||
bb.reg_val32[op.rt] = op.si16;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case spu_itype::ILA:
|
|
||||||
{
|
|
||||||
bb.reg_const[op.rt] = true;
|
|
||||||
bb.reg_val32[op.rt] = op.i18;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case spu_itype::ILHU:
|
|
||||||
{
|
|
||||||
bb.reg_const[op.rt] = true;
|
|
||||||
bb.reg_val32[op.rt] = op.i16 << 16;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case spu_itype::ILH:
|
|
||||||
{
|
|
||||||
bb.reg_const[op.rt] = true;
|
|
||||||
bb.reg_val32[op.rt] = op.i16 << 16 | op.i16;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case spu_itype::IOHL:
|
|
||||||
{
|
|
||||||
bb.reg_val32[op.rt] = bb.reg_val32[op.rt] | op.i16;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case spu_itype::ORI:
|
|
||||||
{
|
|
||||||
bb.reg_const[op.rt] = bb.reg_const[op.ra];
|
|
||||||
bb.reg_val32[op.rt] = bb.reg_val32[op.ra] | op.si10;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case spu_itype::OR:
|
|
||||||
{
|
|
||||||
bb.reg_const[op.rt] = bb.reg_const[op.ra] && bb.reg_const[op.rb];
|
|
||||||
bb.reg_val32[op.rt] = bb.reg_val32[op.ra] | bb.reg_val32[op.rb];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case spu_itype::AI:
|
|
||||||
{
|
|
||||||
bb.reg_const[op.rt] = bb.reg_const[op.ra];
|
|
||||||
bb.reg_val32[op.rt] = bb.reg_val32[op.ra] + op.si10;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case spu_itype::A:
|
|
||||||
{
|
|
||||||
bb.reg_const[op.rt] = bb.reg_const[op.ra] && bb.reg_const[op.rb];
|
|
||||||
bb.reg_val32[op.rt] = bb.reg_val32[op.ra] + bb.reg_val32[op.rb];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case spu_itype::SFI:
|
|
||||||
{
|
|
||||||
bb.reg_const[op.rt] = bb.reg_const[op.ra];
|
|
||||||
bb.reg_val32[op.rt] = op.si10 - bb.reg_val32[op.ra];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case spu_itype::SF:
|
|
||||||
{
|
|
||||||
bb.reg_const[op.rt] = bb.reg_const[op.ra] && bb.reg_const[op.rb];
|
|
||||||
bb.reg_val32[op.rt] = bb.reg_val32[op.rb] - bb.reg_val32[op.ra];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case spu_itype::STQD:
|
case spu_itype::STQD:
|
||||||
{
|
{
|
||||||
if (op.ra == s_reg_sp && bb.stack_sub != 0x80000000 && bb.reg_save_dom[op.rt])
|
if (op.ra == s_reg_sp && bb.stack_sub != 0x80000000 && bb.reg_save_dom[op.rt])
|
||||||
|
@ -4410,15 +4338,10 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
|
||||||
bb.reg_load_mod[op.rt] = 0x80000000 + op.si10 * 16 - bb.stack_sub;
|
bb.reg_load_mod[op.rt] = 0x80000000 + op.si10 * 16 - bb.stack_sub;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear const
|
|
||||||
bb.reg_const[op.rt] = false;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
// Clear const if reg is modified here
|
|
||||||
if (u8 reg = m_regmod[ia / 4]; reg < s_reg_max)
|
|
||||||
bb.reg_const[reg] = false;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4426,12 +4349,6 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
|
||||||
// $SP is modified
|
// $SP is modified
|
||||||
if (m_regmod[ia / 4] == s_reg_sp)
|
if (m_regmod[ia / 4] == s_reg_sp)
|
||||||
{
|
{
|
||||||
if (bb.reg_const[s_reg_sp])
|
|
||||||
{
|
|
||||||
// Making $SP a constant is a funny thing too.
|
|
||||||
bb.stack_sub = 0x80000000;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bb.stack_sub != 0x80000000)
|
if (bb.stack_sub != 0x80000000)
|
||||||
{
|
{
|
||||||
switch (last_inst)
|
switch (last_inst)
|
||||||
|
@ -6227,7 +6144,7 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
|
||||||
atomic16.get_rdatomic = true;
|
atomic16.get_rdatomic = true;
|
||||||
|
|
||||||
// Go above and beyond and also set the constant for it
|
// Go above and beyond and also set the constant for it
|
||||||
set_const_value(op.rt, MFC_GETLLAR_SUCCESS);
|
//set_const_value(op.rt, MFC_GETLLAR_SUCCESS);
|
||||||
invalidate = false;
|
invalidate = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7066,6 +6983,22 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
|
||||||
fmt::append(func_hash, "%s", fmt::base57(output));
|
fmt::append(func_hash, "%s", fmt::base57(output));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto& [addr, block] : infos)
|
||||||
|
{
|
||||||
|
auto& bb = ::at32(m_bbs, addr);
|
||||||
|
|
||||||
|
for (u32 i = 0; i < s_reg_max; i++)
|
||||||
|
{
|
||||||
|
const auto& reg = block->start_reg_state[i];
|
||||||
|
|
||||||
|
if (reg.is_const())
|
||||||
|
{
|
||||||
|
bb.reg_const[i] = true;
|
||||||
|
bb.reg_val32[i] = reg.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (const auto& [pc_commited, pattern] : atomic16_all)
|
for (const auto& [pc_commited, pattern] : atomic16_all)
|
||||||
{
|
{
|
||||||
if (!pattern.active)
|
if (!pattern.active)
|
||||||
|
|
Loading…
Reference in New Issue