mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-12 01:38:37 +12: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
|
@ -288,6 +288,31 @@ inline asmjit::X86Mem spu_recompiler::XmmConst(__m128i data)
|
|||
return XmmConst(v128::fromV(data));
|
||||
}
|
||||
|
||||
void spu_recompiler::CheckInterruptStatus(spu_opcode_t op)
|
||||
{
|
||||
if (op.d)
|
||||
c->lock().btr(SPU_OFF_8(interrupts_enabled), 0);
|
||||
else if (op.e) {
|
||||
c->lock().bts(SPU_OFF_8(interrupts_enabled), 0);
|
||||
c->mov(*qw0, SPU_OFF_32(ch_event_stat));
|
||||
c->and_(*qw0, SPU_OFF_32(ch_event_mask));
|
||||
c->and_(*qw0, SPU_EVENT_INTR_TEST);
|
||||
c->cmp(*qw0, 0);
|
||||
|
||||
asmjit::Label noInterrupt = c->newLabel();
|
||||
c->je(noInterrupt);
|
||||
c->lock().btr(SPU_OFF_8(interrupts_enabled), 0);
|
||||
c->mov(SPU_OFF_32(srr0), *addr);
|
||||
c->mov(SPU_OFF_32(pc), 0);
|
||||
|
||||
FunctionCall();
|
||||
|
||||
c->mov(*addr, SPU_OFF_32(srr0));
|
||||
c->bind(noInterrupt);
|
||||
c->unuse(*qw0);
|
||||
}
|
||||
}
|
||||
|
||||
void spu_recompiler::InterpreterCall(spu_opcode_t op)
|
||||
{
|
||||
auto gate = [](SPUThread* _spu, u32 opcode, spu_inter_func_t _func) noexcept -> u32
|
||||
|
@ -1013,7 +1038,7 @@ void spu_recompiler::BI(spu_opcode_t op)
|
|||
{
|
||||
c->mov(*addr, SPU_OFF_32(gpr, op.ra, &v128::_u32, 3));
|
||||
c->and_(*addr, 0x3fffc);
|
||||
if (op.d || op.e) c->or_(*addr, op.e << 26 | op.d << 27); // interrupt flags neutralize jump table
|
||||
CheckInterruptStatus(op);
|
||||
c->jmp(*jt);
|
||||
}
|
||||
|
||||
|
@ -1037,7 +1062,7 @@ void spu_recompiler::IRET(spu_opcode_t op)
|
|||
{
|
||||
c->mov(*addr, SPU_OFF_32(srr0));
|
||||
c->and_(*addr, 0x3fffc);
|
||||
if (op.d || op.e) c->or_(*addr, op.e << 26 | op.d << 27); // interrupt flags neutralize jump table
|
||||
CheckInterruptStatus(op);
|
||||
c->jmp(*jt);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue