mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-04-04 22:19:02 +00:00
spu: Recompiler Interrupt optimizations - Pigeonhole optimize for branching pattern that is used to enable and disable interrupts used in code, this should lower amount of blocks that are compiled and avoid falling out of a block - Recompiled interupt check in some cases to stay in block instead of falling out to dispatcher
This commit is contained in:
parent
ad97780c4f
commit
8b476b5bfa
3 changed files with 54 additions and 4 deletions
|
|
@ -78,6 +78,9 @@ spu_function_t* SPUDatabase::analyse(const be_t<u32>* ls, u32 entry, u32 max_lim
|
|||
// Minimal position of ila $SP,* instruction
|
||||
u32 ila_sp_pos = max_limit;
|
||||
|
||||
// pigeonhole optimization, addr of last ila r2, addr, or 0 if last instruction was not
|
||||
u32 ila_r2_addr = 0;
|
||||
|
||||
// Find preliminary set of possible block entries (first pass), `start` is the current block address
|
||||
for (u32 start = entry, pos = entry; pos < limit; pos += 4)
|
||||
{
|
||||
|
|
@ -173,11 +176,19 @@ spu_function_t* SPUDatabase::analyse(const be_t<u32>* ls, u32 entry, u32 max_lim
|
|||
limit = pos + 4;
|
||||
break;
|
||||
}
|
||||
|
||||
// if upcoming instruction is not BI, reset the pigeonhole optimization
|
||||
// todo: can constant propogation somewhere get rid of this check?
|
||||
if ((type != BI))
|
||||
ila_r2_addr = 0; // reset
|
||||
|
||||
if (type == BI || type == IRET) // Branch Indirect
|
||||
{
|
||||
blocks.emplace(start);
|
||||
start = pos + 4;
|
||||
|
||||
if (op.ra == 2 && ila_r2_addr > entry)
|
||||
blocks.emplace(ila_r2_addr);
|
||||
}
|
||||
else if (type == BR || type == BRA) // Branch Relative/Absolute
|
||||
{
|
||||
|
|
@ -233,6 +244,13 @@ spu_function_t* SPUDatabase::analyse(const be_t<u32>* ls, u32 entry, u32 max_lim
|
|||
blocks.emplace(target);
|
||||
}
|
||||
}
|
||||
else if (type == LNOP || type == NOP) {
|
||||
// theres a chance that theres some random lnops/nops after the end of a function
|
||||
// havent found a definite pattern, but, is an easy optimization to check for, just push start down if lnop is tagged as a start
|
||||
// todo: remove the last added start pos as its probly unnecessary
|
||||
if (pos == start)
|
||||
start = pos + 4;
|
||||
}
|
||||
else // Other instructions (writing rt reg)
|
||||
{
|
||||
const u32 rt = type & spu_itype::_quadrop ? +op.rt4 : +op.rt;
|
||||
|
|
@ -241,9 +259,8 @@ spu_function_t* SPUDatabase::analyse(const be_t<u32>* ls, u32 entry, u32 max_lim
|
|||
if (rt == 0)
|
||||
{
|
||||
}
|
||||
|
||||
// Analyse stack pointer access
|
||||
if (rt == 1)
|
||||
else if (rt == 1)
|
||||
{
|
||||
if (type == ILA && pos < ila_sp_pos)
|
||||
{
|
||||
|
|
@ -251,6 +268,13 @@ spu_function_t* SPUDatabase::analyse(const be_t<u32>* ls, u32 entry, u32 max_lim
|
|||
ila_sp_pos = pos;
|
||||
}
|
||||
}
|
||||
// pigeonhole optimize
|
||||
// ila r2, addr
|
||||
// bi r2
|
||||
else if (rt == 2) {
|
||||
if (type == ILA)
|
||||
ila_r2_addr = spu_branch_target(op.i18);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue