From 36dd50005ad38de13a692ac9b26e09b7a3313147 Mon Sep 17 00:00:00 2001 From: Pseudonym Date: Thu, 23 Jun 2016 20:57:43 +0100 Subject: [PATCH] Changed the M[FT]P[CS] instruction decoding logic to match results from this test: https://github.com/unknownbrackets/ps2autotests/blob/master/tests/cpu/ee_cop0/performance.cpp --- pcsx2/COP0.cpp | 64 +++++++++++++------------- pcsx2/x86/iCOP0.cpp | 106 ++++++++++++++++++++++---------------------- 2 files changed, 84 insertions(+), 86 deletions(-) diff --git a/pcsx2/COP0.cpp b/pcsx2/COP0.cpp index fa52d5aef4..28330ce351 100644 --- a/pcsx2/COP0.cpp +++ b/pcsx2/COP0.cpp @@ -422,22 +422,20 @@ void MFC0() break; case 25: - switch(_Imm_ & 0x3F) - { - case 0: // MFPS [LSB is clear] - cpuRegs.GPR.r[_Rt_].SD[0] = (s32)cpuRegs.PERF.n.pccr.val; - break; - - case 1: // MFPC [LSB is set] - read PCR0 - COP0_UpdatePCCR(); - cpuRegs.GPR.r[_Rt_].SD[0] = (s32)cpuRegs.PERF.n.pcr0; - break; - - case 3: // MFPC [LSB is set] - read PCR1 - COP0_UpdatePCCR(); - cpuRegs.GPR.r[_Rt_].SD[0] = (s32)cpuRegs.PERF.n.pcr1; - break; - } + if (0 == (_Imm_ & 1)) // MFPS, register value ignored + { + cpuRegs.GPR.r[_Rt_].SD[0] = (s32)cpuRegs.PERF.n.pccr.val; + } + else if (0 == (_Imm_ & 2)) // MFPC 0, only LSB of register matters + { + COP0_UpdatePCCR(); + cpuRegs.GPR.r[_Rt_].SD[0] = (s32)cpuRegs.PERF.n.pcr0; + } + else // MFPC 1 + { + COP0_UpdatePCCR(); + cpuRegs.GPR.r[_Rt_].SD[0] = (s32)cpuRegs.PERF.n.pcr1; + } /*Console.WriteLn("MFC0 PCCR = %x PCR0 = %x PCR1 = %x IMM= %x", params cpuRegs.PERF.n.pccr, cpuRegs.PERF.n.pcr0, cpuRegs.PERF.n.pcr1, _Imm_ & 0x3F);*/ break; @@ -481,24 +479,24 @@ void MTC0() case 25: /*if(bExecBIOS == FALSE && _Rd_ == 25) Console.WriteLn("MTC0 PCCR = %x PCR0 = %x PCR1 = %x IMM= %x", params cpuRegs.PERF.n.pccr, cpuRegs.PERF.n.pcr0, cpuRegs.PERF.n.pcr1, _Imm_ & 0x3F);*/ - switch(_Imm_ & 0x3F) + if (0 == (_Imm_ & 1)) // MTPS { - case 0: // MTPS [LSB is clear] - // Updates PCRs and sets the PCCR. - COP0_UpdatePCCR(); - cpuRegs.PERF.n.pccr.val = cpuRegs.GPR.r[_Rt_].UL[0]; - COP0_DiagnosticPCCR(); - break; - - case 1: // MTPC [LSB is set] - set PCR0 - cpuRegs.PERF.n.pcr0 = cpuRegs.GPR.r[_Rt_].UL[0]; - s_iLastPERFCycle[0] = cpuRegs.cycle; - break; - - case 3: // MTPC [LSB is set] - set PCR0 - cpuRegs.PERF.n.pcr1 = cpuRegs.GPR.r[_Rt_].UL[0]; - s_iLastPERFCycle[1] = cpuRegs.cycle; - break; + if (0 != (_Imm_ & 0x3E)) // only effective when the register is 0 + break; + // Updates PCRs and sets the PCCR. + COP0_UpdatePCCR(); + cpuRegs.PERF.n.pccr.val = cpuRegs.GPR.r[_Rt_].UL[0]; + COP0_DiagnosticPCCR(); + } + else if (0 == (_Imm_ & 2)) // MTPC 0, only LSB of register matters + { + cpuRegs.PERF.n.pcr0 = cpuRegs.GPR.r[_Rt_].UL[0]; + s_iLastPERFCycle[0] = cpuRegs.cycle; + } + else // MTPC 1 + { + cpuRegs.PERF.n.pcr1 = cpuRegs.GPR.r[_Rt_].UL[0]; + s_iLastPERFCycle[1] = cpuRegs.cycle; } break; diff --git a/pcsx2/x86/iCOP0.cpp b/pcsx2/x86/iCOP0.cpp index a4b672edb5..84513b90f0 100644 --- a/pcsx2/x86/iCOP0.cpp +++ b/pcsx2/x86/iCOP0.cpp @@ -162,22 +162,21 @@ void recMFC0() if( _Rd_ == 25 ) { - switch(_Imm_ & 0x3F) + if (0 == (_Imm_ & 1)) // MFPS, register value ignored { - case 0: - xMOV(eax, ptr[&cpuRegs.PERF.n.pccr]); - break; - - case 1: - iFlushCall(FLUSH_INTERPRETER); - xFastCall(COP0_UpdatePCCR ); - xMOV(eax, ptr[&cpuRegs.PERF.n.pcr0]); - break; - case 3: - iFlushCall(FLUSH_INTERPRETER); - xFastCall(COP0_UpdatePCCR ); - xMOV(eax, ptr[&cpuRegs.PERF.n.pcr1]); - break; + xMOV(eax, ptr[&cpuRegs.PERF.n.pccr]); + } + else if (0 == (_Imm_ & 2)) // MFPC 0, only LSB of register matters + { + iFlushCall(FLUSH_INTERPRETER); + xFastCall(COP0_UpdatePCCR); + xMOV(eax, ptr[&cpuRegs.PERF.n.pcr0]); + } + else // MFPC 1 + { + iFlushCall(FLUSH_INTERPRETER); + xFastCall(COP0_UpdatePCCR); + xMOV(eax, ptr[&cpuRegs.PERF.n.pcr1]); } _deleteEEreg(_Rt_, 0); xMOV(ptr[&cpuRegs.GPR.r[_Rt_].UL[0]], eax); @@ -217,26 +216,27 @@ void recMTC0() break; case 25: - switch(_Imm_ & 0x3F) + if (0 == (_Imm_ & 1)) // MTPS { - case 0: - iFlushCall(FLUSH_INTERPRETER); - xFastCall(COP0_UpdatePCCR ); - xMOV( ptr32[&cpuRegs.PERF.n.pccr], g_cpuConstRegs[_Rt_].UL[0] ); - xFastCall(COP0_DiagnosticPCCR ); - break; - - case 1: - xMOV(eax, ptr[&cpuRegs.cycle]); - xMOV(ptr32[&cpuRegs.PERF.n.pcr0], g_cpuConstRegs[_Rt_].UL[0]); - xMOV(ptr[&s_iLastPERFCycle[0]], eax); - break; - - case 3: - xMOV(eax, ptr[&cpuRegs.cycle]); - xMOV(ptr32[&cpuRegs.PERF.n.pcr1], g_cpuConstRegs[_Rt_].UL[0]); - xMOV(ptr[&s_iLastPERFCycle[1]], eax); - break; + if (0 != (_Imm_ & 0x3E)) // only effective when the register is 0 + break; + // Updates PCRs and sets the PCCR. + iFlushCall(FLUSH_INTERPRETER); + xFastCall(COP0_UpdatePCCR); + xMOV(ptr32[&cpuRegs.PERF.n.pccr], g_cpuConstRegs[_Rt_].UL[0]); + xFastCall(COP0_DiagnosticPCCR); + } + else if (0 == (_Imm_ & 2)) // MTPC 0, only LSB of register matters + { + xMOV(eax, ptr[&cpuRegs.cycle]); + xMOV(ptr32[&cpuRegs.PERF.n.pcr0], g_cpuConstRegs[_Rt_].UL[0]); + xMOV(ptr[&s_iLastPERFCycle[0]], eax); + } + else // MTPC 1 + { + xMOV(eax, ptr[&cpuRegs.cycle]); + xMOV(ptr32[&cpuRegs.PERF.n.pcr1], g_cpuConstRegs[_Rt_].UL[0]); + xMOV(ptr[&s_iLastPERFCycle[1]], eax); } break; @@ -266,26 +266,26 @@ void recMTC0() break; case 25: - switch(_Imm_ & 0x3F) + if (0 == (_Imm_ & 1)) // MTPS { - case 0: - iFlushCall(FLUSH_INTERPRETER); - xFastCall(COP0_UpdatePCCR ); - _eeMoveGPRtoM((uptr)&cpuRegs.PERF.n.pccr, _Rt_); - xFastCall(COP0_DiagnosticPCCR ); - break; - - case 1: - xMOV(ecx, ptr[&cpuRegs.cycle]); - _eeMoveGPRtoM((uptr)&cpuRegs.PERF.n.pcr0, _Rt_); - xMOV(ptr[&s_iLastPERFCycle[0]], ecx); - break; - - case 3: - xMOV(ecx, ptr[&cpuRegs.cycle]); - _eeMoveGPRtoM((uptr)&cpuRegs.PERF.n.pcr1, _Rt_); - xMOV(ptr[&s_iLastPERFCycle[1]], ecx); - break; + if (0 != (_Imm_ & 0x3E)) // only effective when the register is 0 + break; + iFlushCall(FLUSH_INTERPRETER); + xFastCall(COP0_UpdatePCCR); + _eeMoveGPRtoM((uptr)&cpuRegs.PERF.n.pccr, _Rt_); + xFastCall(COP0_DiagnosticPCCR); + } + else if (0 == (_Imm_ & 2)) // MTPC 0, only LSB of register matters + { + xMOV(ecx, ptr[&cpuRegs.cycle]); + _eeMoveGPRtoM((uptr)&cpuRegs.PERF.n.pcr0, _Rt_); + xMOV(ptr[&s_iLastPERFCycle[0]], ecx); + } + else // MTPC 1 + { + xMOV(ecx, ptr[&cpuRegs.cycle]); + _eeMoveGPRtoM((uptr)&cpuRegs.PERF.n.pcr1, _Rt_); + xMOV(ptr[&s_iLastPERFCycle[1]], ecx); } break;