mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-23 11:13:19 +01:00
Optimize SPU interpreter
Made SPU decoder similar to PPU decoder
This commit is contained in:
parent
53f8b03acc
commit
445b7c0758
@ -117,7 +117,7 @@ u32 cellSpursModulePollStatus(SPUThread& spu, u32* status)
|
||||
void cellSpursModuleExit(SPUThread& spu)
|
||||
{
|
||||
auto ctxt = vm::_ptr<SpursKernelContext>(spu.offset + 0x100);
|
||||
spu.pc = ctxt->exitToKernelAddr - 4;
|
||||
spu.pc = ctxt->exitToKernelAddr;
|
||||
throw SpursModuleExit();
|
||||
}
|
||||
|
||||
@ -659,7 +659,7 @@ void spursKernelDispatchWorkload(SPUThread& spu, u64 widAndPollStatus)
|
||||
spu.gpr[3]._u32[3] = 0x100;
|
||||
spu.gpr[4]._u64[1] = wklInfo->arg;
|
||||
spu.gpr[5]._u32[3] = pollStatus;
|
||||
spu.pc = 0xA00 - 4;
|
||||
spu.pc = 0xA00;
|
||||
}
|
||||
|
||||
// SPURS kernel workload exit
|
||||
@ -1404,7 +1404,7 @@ void spursTasksetResumeTask(SPUThread& spu)
|
||||
spu.gpr[80 + i] = ctxt->savedContextR80ToR127[i];
|
||||
}
|
||||
|
||||
spu.pc = spu.gpr[0]._u32[3] - 4;
|
||||
spu.pc = spu.gpr[0]._u32[3];
|
||||
}
|
||||
|
||||
// Start a task
|
||||
@ -1422,7 +1422,7 @@ void spursTasksetStartTask(SPUThread& spu, CellSpursTaskArgument& taskArgs)
|
||||
spu.gpr[i].clear();
|
||||
}
|
||||
|
||||
spu.pc = ctxt->savedContextLr.value()._u32[3] - 4;
|
||||
spu.pc = ctxt->savedContextLr.value()._u32[3];
|
||||
}
|
||||
|
||||
// Process a request and update the state of the taskset
|
||||
|
@ -340,18 +340,13 @@ void spu_recompiler::InterpreterCall(spu_opcode_t op)
|
||||
{
|
||||
// TODO: check correctness
|
||||
|
||||
const u32 old_pc = _spu->pc;
|
||||
|
||||
if (test(_spu->state) && _spu->check_state())
|
||||
{
|
||||
return 0x2000000 | _spu->pc;
|
||||
}
|
||||
|
||||
_func(*_spu, { opcode });
|
||||
|
||||
if (old_pc != _spu->pc)
|
||||
if (UNLIKELY(!_func(*_spu, {opcode})))
|
||||
{
|
||||
_spu->pc += 4;
|
||||
return 0x2000000 | _spu->pc;
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -4,258 +4,258 @@
|
||||
|
||||
class SPUThread;
|
||||
|
||||
using spu_inter_func_t = void(*)(SPUThread& spu, spu_opcode_t op);
|
||||
using spu_inter_func_t = bool(*)(SPUThread& spu, spu_opcode_t op);
|
||||
|
||||
struct spu_interpreter
|
||||
{
|
||||
static void UNK(SPUThread&, spu_opcode_t);
|
||||
static bool UNK(SPUThread&, spu_opcode_t);
|
||||
static void set_interrupt_status(SPUThread&, spu_opcode_t);
|
||||
|
||||
static void STOP(SPUThread&, spu_opcode_t);
|
||||
static void LNOP(SPUThread&, spu_opcode_t);
|
||||
static void SYNC(SPUThread&, spu_opcode_t);
|
||||
static void DSYNC(SPUThread&, spu_opcode_t);
|
||||
static void MFSPR(SPUThread&, spu_opcode_t);
|
||||
static void RDCH(SPUThread&, spu_opcode_t);
|
||||
static void RCHCNT(SPUThread&, spu_opcode_t);
|
||||
static void SF(SPUThread&, spu_opcode_t);
|
||||
static void OR(SPUThread&, spu_opcode_t);
|
||||
static void BG(SPUThread&, spu_opcode_t);
|
||||
static void SFH(SPUThread&, spu_opcode_t);
|
||||
static void NOR(SPUThread&, spu_opcode_t);
|
||||
static void ABSDB(SPUThread&, spu_opcode_t);
|
||||
static void ROT(SPUThread&, spu_opcode_t);
|
||||
static void ROTM(SPUThread&, spu_opcode_t);
|
||||
static void ROTMA(SPUThread&, spu_opcode_t);
|
||||
static void SHL(SPUThread&, spu_opcode_t);
|
||||
static void ROTH(SPUThread&, spu_opcode_t);
|
||||
static void ROTHM(SPUThread&, spu_opcode_t);
|
||||
static void ROTMAH(SPUThread&, spu_opcode_t);
|
||||
static void SHLH(SPUThread&, spu_opcode_t);
|
||||
static void ROTI(SPUThread&, spu_opcode_t);
|
||||
static void ROTMI(SPUThread&, spu_opcode_t);
|
||||
static void ROTMAI(SPUThread&, spu_opcode_t);
|
||||
static void SHLI(SPUThread&, spu_opcode_t);
|
||||
static void ROTHI(SPUThread&, spu_opcode_t);
|
||||
static void ROTHMI(SPUThread&, spu_opcode_t);
|
||||
static void ROTMAHI(SPUThread&, spu_opcode_t);
|
||||
static void SHLHI(SPUThread&, spu_opcode_t);
|
||||
static void A(SPUThread&, spu_opcode_t);
|
||||
static void AND(SPUThread&, spu_opcode_t);
|
||||
static void CG(SPUThread&, spu_opcode_t);
|
||||
static void AH(SPUThread&, spu_opcode_t);
|
||||
static void NAND(SPUThread&, spu_opcode_t);
|
||||
static void AVGB(SPUThread&, spu_opcode_t);
|
||||
static void MTSPR(SPUThread&, spu_opcode_t);
|
||||
static void WRCH(SPUThread&, spu_opcode_t);
|
||||
static void BIZ(SPUThread&, spu_opcode_t);
|
||||
static void BINZ(SPUThread&, spu_opcode_t);
|
||||
static void BIHZ(SPUThread&, spu_opcode_t);
|
||||
static void BIHNZ(SPUThread&, spu_opcode_t);
|
||||
static void STOPD(SPUThread&, spu_opcode_t);
|
||||
static void STQX(SPUThread&, spu_opcode_t);
|
||||
static void BI(SPUThread&, spu_opcode_t);
|
||||
static void BISL(SPUThread&, spu_opcode_t);
|
||||
static void IRET(SPUThread&, spu_opcode_t);
|
||||
static void BISLED(SPUThread&, spu_opcode_t);
|
||||
static void HBR(SPUThread&, spu_opcode_t);
|
||||
static void GB(SPUThread&, spu_opcode_t);
|
||||
static void GBH(SPUThread&, spu_opcode_t);
|
||||
static void GBB(SPUThread&, spu_opcode_t);
|
||||
static void FSM(SPUThread&, spu_opcode_t);
|
||||
static void FSMH(SPUThread&, spu_opcode_t);
|
||||
static void FSMB(SPUThread&, spu_opcode_t);
|
||||
static void LQX(SPUThread&, spu_opcode_t);
|
||||
static void CBX(SPUThread&, spu_opcode_t);
|
||||
static void CHX(SPUThread&, spu_opcode_t);
|
||||
static void CWX(SPUThread&, spu_opcode_t);
|
||||
static void CDX(SPUThread&, spu_opcode_t);
|
||||
static void ROTQBI(SPUThread&, spu_opcode_t);
|
||||
static void ROTQMBI(SPUThread&, spu_opcode_t);
|
||||
static void SHLQBI(SPUThread&, spu_opcode_t);
|
||||
static void ORX(SPUThread&, spu_opcode_t);
|
||||
static void CBD(SPUThread&, spu_opcode_t);
|
||||
static void CHD(SPUThread&, spu_opcode_t);
|
||||
static void CWD(SPUThread&, spu_opcode_t);
|
||||
static void CDD(SPUThread&, spu_opcode_t);
|
||||
static void ROTQBII(SPUThread&, spu_opcode_t);
|
||||
static void ROTQMBII(SPUThread&, spu_opcode_t);
|
||||
static void SHLQBII(SPUThread&, spu_opcode_t);
|
||||
static void NOP(SPUThread&, spu_opcode_t);
|
||||
static void CGT(SPUThread&, spu_opcode_t);
|
||||
static void XOR(SPUThread&, spu_opcode_t);
|
||||
static void CGTH(SPUThread&, spu_opcode_t);
|
||||
static void EQV(SPUThread&, spu_opcode_t);
|
||||
static void CGTB(SPUThread&, spu_opcode_t);
|
||||
static void SUMB(SPUThread&, spu_opcode_t);
|
||||
static void HGT(SPUThread&, spu_opcode_t);
|
||||
static void CLZ(SPUThread&, spu_opcode_t);
|
||||
static void XSWD(SPUThread&, spu_opcode_t);
|
||||
static void XSHW(SPUThread&, spu_opcode_t);
|
||||
static void CNTB(SPUThread&, spu_opcode_t);
|
||||
static void XSBH(SPUThread&, spu_opcode_t);
|
||||
static void CLGT(SPUThread&, spu_opcode_t);
|
||||
static void ANDC(SPUThread&, spu_opcode_t);
|
||||
static void CLGTH(SPUThread&, spu_opcode_t);
|
||||
static void ORC(SPUThread&, spu_opcode_t);
|
||||
static void CLGTB(SPUThread&, spu_opcode_t);
|
||||
static void HLGT(SPUThread&, spu_opcode_t);
|
||||
static void CEQ(SPUThread&, spu_opcode_t);
|
||||
static void MPYHHU(SPUThread&, spu_opcode_t);
|
||||
static void ADDX(SPUThread&, spu_opcode_t);
|
||||
static void SFX(SPUThread&, spu_opcode_t);
|
||||
static void CGX(SPUThread&, spu_opcode_t);
|
||||
static void BGX(SPUThread&, spu_opcode_t);
|
||||
static void MPYHHA(SPUThread&, spu_opcode_t);
|
||||
static void MPYHHAU(SPUThread&, spu_opcode_t);
|
||||
static void MPY(SPUThread&, spu_opcode_t);
|
||||
static void MPYH(SPUThread&, spu_opcode_t);
|
||||
static void MPYHH(SPUThread&, spu_opcode_t);
|
||||
static void MPYS(SPUThread&, spu_opcode_t);
|
||||
static void CEQH(SPUThread&, spu_opcode_t);
|
||||
static void MPYU(SPUThread&, spu_opcode_t);
|
||||
static void CEQB(SPUThread&, spu_opcode_t);
|
||||
static void HEQ(SPUThread&, spu_opcode_t);
|
||||
static void BRZ(SPUThread&, spu_opcode_t);
|
||||
static void STQA(SPUThread&, spu_opcode_t);
|
||||
static void BRNZ(SPUThread&, spu_opcode_t);
|
||||
static void BRHZ(SPUThread&, spu_opcode_t);
|
||||
static void BRHNZ(SPUThread&, spu_opcode_t);
|
||||
static void STQR(SPUThread&, spu_opcode_t);
|
||||
static void BRA(SPUThread&, spu_opcode_t);
|
||||
static void LQA(SPUThread&, spu_opcode_t);
|
||||
static void BRASL(SPUThread&, spu_opcode_t);
|
||||
static void BR(SPUThread&, spu_opcode_t);
|
||||
static void FSMBI(SPUThread&, spu_opcode_t);
|
||||
static void BRSL(SPUThread&, spu_opcode_t);
|
||||
static void LQR(SPUThread&, spu_opcode_t);
|
||||
static void IL(SPUThread&, spu_opcode_t);
|
||||
static void ILHU(SPUThread&, spu_opcode_t);
|
||||
static void ILH(SPUThread&, spu_opcode_t);
|
||||
static void IOHL(SPUThread&, spu_opcode_t);
|
||||
static void ORI(SPUThread&, spu_opcode_t);
|
||||
static void ORHI(SPUThread&, spu_opcode_t);
|
||||
static void ORBI(SPUThread&, spu_opcode_t);
|
||||
static void SFI(SPUThread&, spu_opcode_t);
|
||||
static void SFHI(SPUThread&, spu_opcode_t);
|
||||
static void ANDI(SPUThread&, spu_opcode_t);
|
||||
static void ANDHI(SPUThread&, spu_opcode_t);
|
||||
static void ANDBI(SPUThread&, spu_opcode_t);
|
||||
static void AI(SPUThread&, spu_opcode_t);
|
||||
static void AHI(SPUThread&, spu_opcode_t);
|
||||
static void STQD(SPUThread&, spu_opcode_t);
|
||||
static void LQD(SPUThread&, spu_opcode_t);
|
||||
static void XORI(SPUThread&, spu_opcode_t);
|
||||
static void XORHI(SPUThread&, spu_opcode_t);
|
||||
static void XORBI(SPUThread&, spu_opcode_t);
|
||||
static void CGTI(SPUThread&, spu_opcode_t);
|
||||
static void CGTHI(SPUThread&, spu_opcode_t);
|
||||
static void CGTBI(SPUThread&, spu_opcode_t);
|
||||
static void HGTI(SPUThread&, spu_opcode_t);
|
||||
static void CLGTI(SPUThread&, spu_opcode_t);
|
||||
static void CLGTHI(SPUThread&, spu_opcode_t);
|
||||
static void CLGTBI(SPUThread&, spu_opcode_t);
|
||||
static void HLGTI(SPUThread&, spu_opcode_t);
|
||||
static void MPYI(SPUThread&, spu_opcode_t);
|
||||
static void MPYUI(SPUThread&, spu_opcode_t);
|
||||
static void CEQI(SPUThread&, spu_opcode_t);
|
||||
static void CEQHI(SPUThread&, spu_opcode_t);
|
||||
static void CEQBI(SPUThread&, spu_opcode_t);
|
||||
static void HEQI(SPUThread&, spu_opcode_t);
|
||||
static void HBRA(SPUThread&, spu_opcode_t);
|
||||
static void HBRR(SPUThread&, spu_opcode_t);
|
||||
static void ILA(SPUThread&, spu_opcode_t);
|
||||
static void SELB(SPUThread&, spu_opcode_t);
|
||||
static void MPYA(SPUThread&, spu_opcode_t);
|
||||
static void DFCGT(SPUThread&, spu_opcode_t);
|
||||
static void DFCMGT(SPUThread&, spu_opcode_t);
|
||||
static void DFTSV(SPUThread&, spu_opcode_t);
|
||||
static void DFCEQ(SPUThread&, spu_opcode_t);
|
||||
static void DFCMEQ(SPUThread&, spu_opcode_t);
|
||||
static bool STOP(SPUThread&, spu_opcode_t);
|
||||
static bool LNOP(SPUThread&, spu_opcode_t);
|
||||
static bool SYNC(SPUThread&, spu_opcode_t);
|
||||
static bool DSYNC(SPUThread&, spu_opcode_t);
|
||||
static bool MFSPR(SPUThread&, spu_opcode_t);
|
||||
static bool RDCH(SPUThread&, spu_opcode_t);
|
||||
static bool RCHCNT(SPUThread&, spu_opcode_t);
|
||||
static bool SF(SPUThread&, spu_opcode_t);
|
||||
static bool OR(SPUThread&, spu_opcode_t);
|
||||
static bool BG(SPUThread&, spu_opcode_t);
|
||||
static bool SFH(SPUThread&, spu_opcode_t);
|
||||
static bool NOR(SPUThread&, spu_opcode_t);
|
||||
static bool ABSDB(SPUThread&, spu_opcode_t);
|
||||
static bool ROT(SPUThread&, spu_opcode_t);
|
||||
static bool ROTM(SPUThread&, spu_opcode_t);
|
||||
static bool ROTMA(SPUThread&, spu_opcode_t);
|
||||
static bool SHL(SPUThread&, spu_opcode_t);
|
||||
static bool ROTH(SPUThread&, spu_opcode_t);
|
||||
static bool ROTHM(SPUThread&, spu_opcode_t);
|
||||
static bool ROTMAH(SPUThread&, spu_opcode_t);
|
||||
static bool SHLH(SPUThread&, spu_opcode_t);
|
||||
static bool ROTI(SPUThread&, spu_opcode_t);
|
||||
static bool ROTMI(SPUThread&, spu_opcode_t);
|
||||
static bool ROTMAI(SPUThread&, spu_opcode_t);
|
||||
static bool SHLI(SPUThread&, spu_opcode_t);
|
||||
static bool ROTHI(SPUThread&, spu_opcode_t);
|
||||
static bool ROTHMI(SPUThread&, spu_opcode_t);
|
||||
static bool ROTMAHI(SPUThread&, spu_opcode_t);
|
||||
static bool SHLHI(SPUThread&, spu_opcode_t);
|
||||
static bool A(SPUThread&, spu_opcode_t);
|
||||
static bool AND(SPUThread&, spu_opcode_t);
|
||||
static bool CG(SPUThread&, spu_opcode_t);
|
||||
static bool AH(SPUThread&, spu_opcode_t);
|
||||
static bool NAND(SPUThread&, spu_opcode_t);
|
||||
static bool AVGB(SPUThread&, spu_opcode_t);
|
||||
static bool MTSPR(SPUThread&, spu_opcode_t);
|
||||
static bool WRCH(SPUThread&, spu_opcode_t);
|
||||
static bool BIZ(SPUThread&, spu_opcode_t);
|
||||
static bool BINZ(SPUThread&, spu_opcode_t);
|
||||
static bool BIHZ(SPUThread&, spu_opcode_t);
|
||||
static bool BIHNZ(SPUThread&, spu_opcode_t);
|
||||
static bool STOPD(SPUThread&, spu_opcode_t);
|
||||
static bool STQX(SPUThread&, spu_opcode_t);
|
||||
static bool BI(SPUThread&, spu_opcode_t);
|
||||
static bool BISL(SPUThread&, spu_opcode_t);
|
||||
static bool IRET(SPUThread&, spu_opcode_t);
|
||||
static bool BISLED(SPUThread&, spu_opcode_t);
|
||||
static bool HBR(SPUThread&, spu_opcode_t);
|
||||
static bool GB(SPUThread&, spu_opcode_t);
|
||||
static bool GBH(SPUThread&, spu_opcode_t);
|
||||
static bool GBB(SPUThread&, spu_opcode_t);
|
||||
static bool FSM(SPUThread&, spu_opcode_t);
|
||||
static bool FSMH(SPUThread&, spu_opcode_t);
|
||||
static bool FSMB(SPUThread&, spu_opcode_t);
|
||||
static bool LQX(SPUThread&, spu_opcode_t);
|
||||
static bool CBX(SPUThread&, spu_opcode_t);
|
||||
static bool CHX(SPUThread&, spu_opcode_t);
|
||||
static bool CWX(SPUThread&, spu_opcode_t);
|
||||
static bool CDX(SPUThread&, spu_opcode_t);
|
||||
static bool ROTQBI(SPUThread&, spu_opcode_t);
|
||||
static bool ROTQMBI(SPUThread&, spu_opcode_t);
|
||||
static bool SHLQBI(SPUThread&, spu_opcode_t);
|
||||
static bool ORX(SPUThread&, spu_opcode_t);
|
||||
static bool CBD(SPUThread&, spu_opcode_t);
|
||||
static bool CHD(SPUThread&, spu_opcode_t);
|
||||
static bool CWD(SPUThread&, spu_opcode_t);
|
||||
static bool CDD(SPUThread&, spu_opcode_t);
|
||||
static bool ROTQBII(SPUThread&, spu_opcode_t);
|
||||
static bool ROTQMBII(SPUThread&, spu_opcode_t);
|
||||
static bool SHLQBII(SPUThread&, spu_opcode_t);
|
||||
static bool NOP(SPUThread&, spu_opcode_t);
|
||||
static bool CGT(SPUThread&, spu_opcode_t);
|
||||
static bool XOR(SPUThread&, spu_opcode_t);
|
||||
static bool CGTH(SPUThread&, spu_opcode_t);
|
||||
static bool EQV(SPUThread&, spu_opcode_t);
|
||||
static bool CGTB(SPUThread&, spu_opcode_t);
|
||||
static bool SUMB(SPUThread&, spu_opcode_t);
|
||||
static bool HGT(SPUThread&, spu_opcode_t);
|
||||
static bool CLZ(SPUThread&, spu_opcode_t);
|
||||
static bool XSWD(SPUThread&, spu_opcode_t);
|
||||
static bool XSHW(SPUThread&, spu_opcode_t);
|
||||
static bool CNTB(SPUThread&, spu_opcode_t);
|
||||
static bool XSBH(SPUThread&, spu_opcode_t);
|
||||
static bool CLGT(SPUThread&, spu_opcode_t);
|
||||
static bool ANDC(SPUThread&, spu_opcode_t);
|
||||
static bool CLGTH(SPUThread&, spu_opcode_t);
|
||||
static bool ORC(SPUThread&, spu_opcode_t);
|
||||
static bool CLGTB(SPUThread&, spu_opcode_t);
|
||||
static bool HLGT(SPUThread&, spu_opcode_t);
|
||||
static bool CEQ(SPUThread&, spu_opcode_t);
|
||||
static bool MPYHHU(SPUThread&, spu_opcode_t);
|
||||
static bool ADDX(SPUThread&, spu_opcode_t);
|
||||
static bool SFX(SPUThread&, spu_opcode_t);
|
||||
static bool CGX(SPUThread&, spu_opcode_t);
|
||||
static bool BGX(SPUThread&, spu_opcode_t);
|
||||
static bool MPYHHA(SPUThread&, spu_opcode_t);
|
||||
static bool MPYHHAU(SPUThread&, spu_opcode_t);
|
||||
static bool MPY(SPUThread&, spu_opcode_t);
|
||||
static bool MPYH(SPUThread&, spu_opcode_t);
|
||||
static bool MPYHH(SPUThread&, spu_opcode_t);
|
||||
static bool MPYS(SPUThread&, spu_opcode_t);
|
||||
static bool CEQH(SPUThread&, spu_opcode_t);
|
||||
static bool MPYU(SPUThread&, spu_opcode_t);
|
||||
static bool CEQB(SPUThread&, spu_opcode_t);
|
||||
static bool HEQ(SPUThread&, spu_opcode_t);
|
||||
static bool BRZ(SPUThread&, spu_opcode_t);
|
||||
static bool STQA(SPUThread&, spu_opcode_t);
|
||||
static bool BRNZ(SPUThread&, spu_opcode_t);
|
||||
static bool BRHZ(SPUThread&, spu_opcode_t);
|
||||
static bool BRHNZ(SPUThread&, spu_opcode_t);
|
||||
static bool STQR(SPUThread&, spu_opcode_t);
|
||||
static bool BRA(SPUThread&, spu_opcode_t);
|
||||
static bool LQA(SPUThread&, spu_opcode_t);
|
||||
static bool BRASL(SPUThread&, spu_opcode_t);
|
||||
static bool BR(SPUThread&, spu_opcode_t);
|
||||
static bool FSMBI(SPUThread&, spu_opcode_t);
|
||||
static bool BRSL(SPUThread&, spu_opcode_t);
|
||||
static bool LQR(SPUThread&, spu_opcode_t);
|
||||
static bool IL(SPUThread&, spu_opcode_t);
|
||||
static bool ILHU(SPUThread&, spu_opcode_t);
|
||||
static bool ILH(SPUThread&, spu_opcode_t);
|
||||
static bool IOHL(SPUThread&, spu_opcode_t);
|
||||
static bool ORI(SPUThread&, spu_opcode_t);
|
||||
static bool ORHI(SPUThread&, spu_opcode_t);
|
||||
static bool ORBI(SPUThread&, spu_opcode_t);
|
||||
static bool SFI(SPUThread&, spu_opcode_t);
|
||||
static bool SFHI(SPUThread&, spu_opcode_t);
|
||||
static bool ANDI(SPUThread&, spu_opcode_t);
|
||||
static bool ANDHI(SPUThread&, spu_opcode_t);
|
||||
static bool ANDBI(SPUThread&, spu_opcode_t);
|
||||
static bool AI(SPUThread&, spu_opcode_t);
|
||||
static bool AHI(SPUThread&, spu_opcode_t);
|
||||
static bool STQD(SPUThread&, spu_opcode_t);
|
||||
static bool LQD(SPUThread&, spu_opcode_t);
|
||||
static bool XORI(SPUThread&, spu_opcode_t);
|
||||
static bool XORHI(SPUThread&, spu_opcode_t);
|
||||
static bool XORBI(SPUThread&, spu_opcode_t);
|
||||
static bool CGTI(SPUThread&, spu_opcode_t);
|
||||
static bool CGTHI(SPUThread&, spu_opcode_t);
|
||||
static bool CGTBI(SPUThread&, spu_opcode_t);
|
||||
static bool HGTI(SPUThread&, spu_opcode_t);
|
||||
static bool CLGTI(SPUThread&, spu_opcode_t);
|
||||
static bool CLGTHI(SPUThread&, spu_opcode_t);
|
||||
static bool CLGTBI(SPUThread&, spu_opcode_t);
|
||||
static bool HLGTI(SPUThread&, spu_opcode_t);
|
||||
static bool MPYI(SPUThread&, spu_opcode_t);
|
||||
static bool MPYUI(SPUThread&, spu_opcode_t);
|
||||
static bool CEQI(SPUThread&, spu_opcode_t);
|
||||
static bool CEQHI(SPUThread&, spu_opcode_t);
|
||||
static bool CEQBI(SPUThread&, spu_opcode_t);
|
||||
static bool HEQI(SPUThread&, spu_opcode_t);
|
||||
static bool HBRA(SPUThread&, spu_opcode_t);
|
||||
static bool HBRR(SPUThread&, spu_opcode_t);
|
||||
static bool ILA(SPUThread&, spu_opcode_t);
|
||||
static bool SELB(SPUThread&, spu_opcode_t);
|
||||
static bool MPYA(SPUThread&, spu_opcode_t);
|
||||
static bool DFCGT(SPUThread&, spu_opcode_t);
|
||||
static bool DFCMGT(SPUThread&, spu_opcode_t);
|
||||
static bool DFTSV(SPUThread&, spu_opcode_t);
|
||||
static bool DFCEQ(SPUThread&, spu_opcode_t);
|
||||
static bool DFCMEQ(SPUThread&, spu_opcode_t);
|
||||
};
|
||||
|
||||
struct spu_interpreter_fast final : spu_interpreter
|
||||
{
|
||||
static void ROTQBYBI(SPUThread&, spu_opcode_t);
|
||||
static void ROTQMBYBI(SPUThread&, spu_opcode_t);
|
||||
static void SHLQBYBI(SPUThread&, spu_opcode_t);
|
||||
static void ROTQBY(SPUThread&, spu_opcode_t);
|
||||
static void ROTQMBY(SPUThread&, spu_opcode_t);
|
||||
static void SHLQBY(SPUThread&, spu_opcode_t);
|
||||
static void ROTQBYI(SPUThread&, spu_opcode_t);
|
||||
static void ROTQMBYI(SPUThread&, spu_opcode_t);
|
||||
static void SHLQBYI(SPUThread&, spu_opcode_t);
|
||||
static void SHUFB(SPUThread&, spu_opcode_t);
|
||||
static bool ROTQBYBI(SPUThread&, spu_opcode_t);
|
||||
static bool ROTQMBYBI(SPUThread&, spu_opcode_t);
|
||||
static bool SHLQBYBI(SPUThread&, spu_opcode_t);
|
||||
static bool ROTQBY(SPUThread&, spu_opcode_t);
|
||||
static bool ROTQMBY(SPUThread&, spu_opcode_t);
|
||||
static bool SHLQBY(SPUThread&, spu_opcode_t);
|
||||
static bool ROTQBYI(SPUThread&, spu_opcode_t);
|
||||
static bool ROTQMBYI(SPUThread&, spu_opcode_t);
|
||||
static bool SHLQBYI(SPUThread&, spu_opcode_t);
|
||||
static bool SHUFB(SPUThread&, spu_opcode_t);
|
||||
|
||||
static void FREST(SPUThread&, spu_opcode_t);
|
||||
static void FRSQEST(SPUThread&, spu_opcode_t);
|
||||
static void FCGT(SPUThread&, spu_opcode_t);
|
||||
static void FA(SPUThread&, spu_opcode_t);
|
||||
static void FS(SPUThread&, spu_opcode_t);
|
||||
static void FM(SPUThread&, spu_opcode_t);
|
||||
static void FCMGT(SPUThread&, spu_opcode_t);
|
||||
static void DFA(SPUThread&, spu_opcode_t);
|
||||
static void DFS(SPUThread&, spu_opcode_t);
|
||||
static void DFM(SPUThread&, spu_opcode_t);
|
||||
static void DFMA(SPUThread&, spu_opcode_t);
|
||||
static void DFMS(SPUThread&, spu_opcode_t);
|
||||
static void DFNMS(SPUThread&, spu_opcode_t);
|
||||
static void DFNMA(SPUThread&, spu_opcode_t);
|
||||
static void FSCRRD(SPUThread&, spu_opcode_t);
|
||||
static void FESD(SPUThread&, spu_opcode_t);
|
||||
static void FRDS(SPUThread&, spu_opcode_t);
|
||||
static void FSCRWR(SPUThread&, spu_opcode_t);
|
||||
static void FCEQ(SPUThread&, spu_opcode_t);
|
||||
static void FCMEQ(SPUThread&, spu_opcode_t);
|
||||
static void FI(SPUThread&, spu_opcode_t);
|
||||
static void CFLTS(SPUThread&, spu_opcode_t);
|
||||
static void CFLTU(SPUThread&, spu_opcode_t);
|
||||
static void CSFLT(SPUThread&, spu_opcode_t);
|
||||
static void CUFLT(SPUThread&, spu_opcode_t);
|
||||
static void FNMS(SPUThread&, spu_opcode_t);
|
||||
static void FMA(SPUThread&, spu_opcode_t);
|
||||
static void FMS(SPUThread&, spu_opcode_t);
|
||||
static bool FREST(SPUThread&, spu_opcode_t);
|
||||
static bool FRSQEST(SPUThread&, spu_opcode_t);
|
||||
static bool FCGT(SPUThread&, spu_opcode_t);
|
||||
static bool FA(SPUThread&, spu_opcode_t);
|
||||
static bool FS(SPUThread&, spu_opcode_t);
|
||||
static bool FM(SPUThread&, spu_opcode_t);
|
||||
static bool FCMGT(SPUThread&, spu_opcode_t);
|
||||
static bool DFA(SPUThread&, spu_opcode_t);
|
||||
static bool DFS(SPUThread&, spu_opcode_t);
|
||||
static bool DFM(SPUThread&, spu_opcode_t);
|
||||
static bool DFMA(SPUThread&, spu_opcode_t);
|
||||
static bool DFMS(SPUThread&, spu_opcode_t);
|
||||
static bool DFNMS(SPUThread&, spu_opcode_t);
|
||||
static bool DFNMA(SPUThread&, spu_opcode_t);
|
||||
static bool FSCRRD(SPUThread&, spu_opcode_t);
|
||||
static bool FESD(SPUThread&, spu_opcode_t);
|
||||
static bool FRDS(SPUThread&, spu_opcode_t);
|
||||
static bool FSCRWR(SPUThread&, spu_opcode_t);
|
||||
static bool FCEQ(SPUThread&, spu_opcode_t);
|
||||
static bool FCMEQ(SPUThread&, spu_opcode_t);
|
||||
static bool FI(SPUThread&, spu_opcode_t);
|
||||
static bool CFLTS(SPUThread&, spu_opcode_t);
|
||||
static bool CFLTU(SPUThread&, spu_opcode_t);
|
||||
static bool CSFLT(SPUThread&, spu_opcode_t);
|
||||
static bool CUFLT(SPUThread&, spu_opcode_t);
|
||||
static bool FNMS(SPUThread&, spu_opcode_t);
|
||||
static bool FMA(SPUThread&, spu_opcode_t);
|
||||
static bool FMS(SPUThread&, spu_opcode_t);
|
||||
};
|
||||
|
||||
struct spu_interpreter_precise final : spu_interpreter
|
||||
{
|
||||
static void ROTQBYBI(SPUThread&, spu_opcode_t);
|
||||
static void ROTQMBYBI(SPUThread&, spu_opcode_t);
|
||||
static void SHLQBYBI(SPUThread&, spu_opcode_t);
|
||||
static void ROTQBY(SPUThread&, spu_opcode_t);
|
||||
static void ROTQMBY(SPUThread&, spu_opcode_t);
|
||||
static void SHLQBY(SPUThread&, spu_opcode_t);
|
||||
static void ROTQBYI(SPUThread&, spu_opcode_t);
|
||||
static void ROTQMBYI(SPUThread&, spu_opcode_t);
|
||||
static void SHLQBYI(SPUThread&, spu_opcode_t);
|
||||
static void SHUFB(SPUThread&, spu_opcode_t);
|
||||
static bool ROTQBYBI(SPUThread&, spu_opcode_t);
|
||||
static bool ROTQMBYBI(SPUThread&, spu_opcode_t);
|
||||
static bool SHLQBYBI(SPUThread&, spu_opcode_t);
|
||||
static bool ROTQBY(SPUThread&, spu_opcode_t);
|
||||
static bool ROTQMBY(SPUThread&, spu_opcode_t);
|
||||
static bool SHLQBY(SPUThread&, spu_opcode_t);
|
||||
static bool ROTQBYI(SPUThread&, spu_opcode_t);
|
||||
static bool ROTQMBYI(SPUThread&, spu_opcode_t);
|
||||
static bool SHLQBYI(SPUThread&, spu_opcode_t);
|
||||
static bool SHUFB(SPUThread&, spu_opcode_t);
|
||||
|
||||
static void FREST(SPUThread&, spu_opcode_t);
|
||||
static void FRSQEST(SPUThread&, spu_opcode_t);
|
||||
static void FCGT(SPUThread&, spu_opcode_t);
|
||||
static void FA(SPUThread&, spu_opcode_t);
|
||||
static void FS(SPUThread&, spu_opcode_t);
|
||||
static void FM(SPUThread&, spu_opcode_t);
|
||||
static void FCMGT(SPUThread&, spu_opcode_t);
|
||||
static void DFA(SPUThread&, spu_opcode_t);
|
||||
static void DFS(SPUThread&, spu_opcode_t);
|
||||
static void DFM(SPUThread&, spu_opcode_t);
|
||||
static void DFMA(SPUThread&, spu_opcode_t);
|
||||
static void DFMS(SPUThread&, spu_opcode_t);
|
||||
static void DFNMS(SPUThread&, spu_opcode_t);
|
||||
static void DFNMA(SPUThread&, spu_opcode_t);
|
||||
static void FSCRRD(SPUThread&, spu_opcode_t);
|
||||
static void FESD(SPUThread&, spu_opcode_t);
|
||||
static void FRDS(SPUThread&, spu_opcode_t);
|
||||
static void FSCRWR(SPUThread&, spu_opcode_t);
|
||||
static void FCEQ(SPUThread&, spu_opcode_t);
|
||||
static void FCMEQ(SPUThread&, spu_opcode_t);
|
||||
static void FI(SPUThread&, spu_opcode_t);
|
||||
static void CFLTS(SPUThread&, spu_opcode_t);
|
||||
static void CFLTU(SPUThread&, spu_opcode_t);
|
||||
static void CSFLT(SPUThread&, spu_opcode_t);
|
||||
static void CUFLT(SPUThread&, spu_opcode_t);
|
||||
static void FNMS(SPUThread&, spu_opcode_t);
|
||||
static void FMA(SPUThread&, spu_opcode_t);
|
||||
static void FMS(SPUThread&, spu_opcode_t);
|
||||
static bool FREST(SPUThread&, spu_opcode_t);
|
||||
static bool FRSQEST(SPUThread&, spu_opcode_t);
|
||||
static bool FCGT(SPUThread&, spu_opcode_t);
|
||||
static bool FA(SPUThread&, spu_opcode_t);
|
||||
static bool FS(SPUThread&, spu_opcode_t);
|
||||
static bool FM(SPUThread&, spu_opcode_t);
|
||||
static bool FCMGT(SPUThread&, spu_opcode_t);
|
||||
static bool DFA(SPUThread&, spu_opcode_t);
|
||||
static bool DFS(SPUThread&, spu_opcode_t);
|
||||
static bool DFM(SPUThread&, spu_opcode_t);
|
||||
static bool DFMA(SPUThread&, spu_opcode_t);
|
||||
static bool DFMS(SPUThread&, spu_opcode_t);
|
||||
static bool DFNMS(SPUThread&, spu_opcode_t);
|
||||
static bool DFNMA(SPUThread&, spu_opcode_t);
|
||||
static bool FSCRRD(SPUThread&, spu_opcode_t);
|
||||
static bool FESD(SPUThread&, spu_opcode_t);
|
||||
static bool FRDS(SPUThread&, spu_opcode_t);
|
||||
static bool FSCRWR(SPUThread&, spu_opcode_t);
|
||||
static bool FCEQ(SPUThread&, spu_opcode_t);
|
||||
static bool FCMEQ(SPUThread&, spu_opcode_t);
|
||||
static bool FI(SPUThread&, spu_opcode_t);
|
||||
static bool CFLTS(SPUThread&, spu_opcode_t);
|
||||
static bool CFLTU(SPUThread&, spu_opcode_t);
|
||||
static bool CSFLT(SPUThread&, spu_opcode_t);
|
||||
static bool CUFLT(SPUThread&, spu_opcode_t);
|
||||
static bool FNMS(SPUThread&, spu_opcode_t);
|
||||
static bool FMA(SPUThread&, spu_opcode_t);
|
||||
static bool FMS(SPUThread&, spu_opcode_t);
|
||||
};
|
||||
|
@ -32,6 +32,7 @@ const bool s_use_ssse3 =
|
||||
true;
|
||||
#else
|
||||
false;
|
||||
#define _mm_shuffle_epi8
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
@ -388,25 +389,75 @@ void SPUThread::cpu_task()
|
||||
g_cfg.core.spu_decoder == spu_decoder_type::fast ? &g_spu_interpreter_fast.get_table() :
|
||||
(fmt::throw_exception<std::logic_error>("Invalid SPU decoder"), nullptr));
|
||||
|
||||
// LS base address
|
||||
const auto base = vm::_ptr<const u32>(offset);
|
||||
// LS pointer
|
||||
const auto base = vm::_ptr<const u8>(offset);
|
||||
const auto bswap4 = _mm_set_epi8(12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3);
|
||||
|
||||
v128 _op;
|
||||
using func_t = decltype(&spu_interpreter::UNK);
|
||||
func_t func0, func1, func2, func3, func4, func5;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (!test(state) || !check_state())
|
||||
if (UNLIKELY(test(state)))
|
||||
{
|
||||
// Read opcode
|
||||
const u32 op = base[pc / 4];
|
||||
|
||||
// Call interpreter function
|
||||
table[spu_decode(op)](*this, { op });
|
||||
|
||||
// Next instruction
|
||||
pc += 4;
|
||||
if (check_state()) return;
|
||||
|
||||
// Decode single instruction (may be step)
|
||||
const u32 op = *reinterpret_cast<const be_t<u32>*>(base + pc);
|
||||
if (table[spu_decode(op)](*this, {op})) { pc += 4; }
|
||||
continue;
|
||||
}
|
||||
return;
|
||||
|
||||
if (pc % 16 || !s_use_ssse3)
|
||||
{
|
||||
// Unaligned
|
||||
const u32 op = *reinterpret_cast<const be_t<u32>*>(base + pc);
|
||||
if (table[spu_decode(op)](*this, {op})) { pc += 4; }
|
||||
continue;
|
||||
}
|
||||
|
||||
// Reinitialize
|
||||
_op.vi = _mm_shuffle_epi8(_mm_load_si128(reinterpret_cast<const __m128i*>(base + pc)), bswap4);
|
||||
func0 = table[spu_decode(_op._u32[0])];
|
||||
func1 = table[spu_decode(_op._u32[1])];
|
||||
func2 = table[spu_decode(_op._u32[2])];
|
||||
func3 = table[spu_decode(_op._u32[3])];
|
||||
|
||||
while (LIKELY(func0(*this, {_op._u32[0]})))
|
||||
{
|
||||
pc += 4;
|
||||
if (LIKELY(func1(*this, {_op._u32[1]})))
|
||||
{
|
||||
pc += 4;
|
||||
u32 op2 = _op._u32[2];
|
||||
u32 op3 = _op._u32[3];
|
||||
_op.vi = _mm_shuffle_epi8(_mm_load_si128(reinterpret_cast<const __m128i*>(base + pc + 8)), bswap4);
|
||||
func0 = table[spu_decode(_op._u32[0])];
|
||||
func1 = table[spu_decode(_op._u32[1])];
|
||||
func4 = table[spu_decode(_op._u32[2])];
|
||||
func5 = table[spu_decode(_op._u32[3])];
|
||||
if (LIKELY(func2(*this, {op2})))
|
||||
{
|
||||
pc += 4;
|
||||
if (LIKELY(func3(*this, {op3})))
|
||||
{
|
||||
pc += 4;
|
||||
func2 = func4;
|
||||
func3 = func5;
|
||||
|
||||
if (UNLIKELY(test(state)))
|
||||
{
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user