diff --git a/pcsx2/Config.h b/pcsx2/Config.h
index f1be1c45a7..39a4c45bd4 100644
--- a/pcsx2/Config.h
+++ b/pcsx2/Config.h
@@ -550,7 +550,6 @@ TraceLogFilters& SetTraceConfig();
// ------------ CPU / Recompiler Options ---------------
-#define CHECK_MACROVU0 // If defined uses mVU for VU Macro (COP2), else uses sVU
#define CHECK_MICROVU0 (EmuConfig.Cpu.Recompiler.UseMicroVU0)
#define CHECK_MICROVU1 (EmuConfig.Cpu.Recompiler.UseMicroVU1)
#define CHECK_EEREC (EmuConfig.Cpu.Recompiler.EnableEE && GetSysCoreAlloc().IsRecAvailable_EE())
diff --git a/pcsx2/R5900.cpp b/pcsx2/R5900.cpp
index 46f5abdb19..ddbff98334 100644
--- a/pcsx2/R5900.cpp
+++ b/pcsx2/R5900.cpp
@@ -422,20 +422,9 @@ __forceinline void _cpuBranchTest_Shared()
}
// ---- VU0 -------------
-
- if (VU0.VI[REG_VPU_STAT].UL & 0x1)
- {
- // We're in a BranchTest. All dynarec registers are flushed
- // so there is no need to freeze registers here.
- CpuVU0->ExecuteBlock(vu0RunCycles);
- DevCon.Warning("VU0 running when in BranchTest");
- // This might be needed to keep the EE and VU0 in sync.
- // A better fix will require hefty changes to the VU recs. -_-
- // Fixme:
- // Check Silver Surfer. Currently has SPS varying with different branch deltas set below.
- if(VU0.VI[REG_VPU_STAT].UL & 0x1)
- cpuSetNextBranchDelta( 768 );
- }
+ // We're in a BranchTest. All dynarec registers are flushed
+ // so there is no need to freeze registers here.
+ CpuVU0->ExecuteBlock();
// Note: We don't update the VU1 here because it runs it's micro-programs in
// one shot always. That is, when a program is executed the VU1 doesn't even
diff --git a/pcsx2/VU0.cpp b/pcsx2/VU0.cpp
index 627573dfcb..96973a77d5 100644
--- a/pcsx2/VU0.cpp
+++ b/pcsx2/VU0.cpp
@@ -65,15 +65,11 @@ __forceinline void _vu0run(bool breakOnMbit, bool addCycles) {
if (!(VU0.VI[REG_VPU_STAT].UL & 1)) return;
int startcycle = VU0.cycle;
- VU0.flags &= ~VUFLAG_MFLAGSET;
-
- do {
- // knockout kings 2002 loops here with sVU
- if (breakOnMbit && (VU0.cycle-startcycle > 0x1000)) {
- Console.Warning("VU0 stuck in infinite loop? Breaking execution!");
- break; // Do games still need this?
- }
- CpuVU0->ExecuteBlock(vu0RunCycles);
+ u32 runCycles = breakOnMbit ? vu0RunCycles : 0x7fffffff;
+ VU0.flags &= ~VUFLAG_MFLAGSET;
+
+ do { // Run VU until it finishes or M-Bit
+ CpuVU0->Execute(runCycles);
} while ((VU0.VI[REG_VPU_STAT].UL & 1) // E-bit Termination
&& (!breakOnMbit || !(VU0.flags & VUFLAG_MFLAGSET))); // M-bit Break
diff --git a/pcsx2/VU0micro.cpp b/pcsx2/VU0micro.cpp
index d7639b2f1b..1cfbf3bcef 100644
--- a/pcsx2/VU0micro.cpp
+++ b/pcsx2/VU0micro.cpp
@@ -56,12 +56,7 @@ void __fastcall vu0ExecMicro(u32 addr) {
if ((s32)addr != -1) VU0.VI[REG_TPC].UL = addr;
_vuExecMicroDebug(VU0);
- CpuVU0->ExecuteBlock(vu0RunCycles);
-
- // If the VU0 program didn't finish then we'll want to finish it up
- // pretty soon. This fixes vmhacks in some games (Naruto Ultimate Ninja 2)
- if(VU0.VI[REG_VPU_STAT].UL & 0x1)
- cpuSetNextBranchDelta( 192 ); // fixme : ideally this should be higher, like 512 or so.
+ CpuVU0->ExecuteBlock(1);
}
void VU0unknown() {
diff --git a/pcsx2/VU0microInterp.cpp b/pcsx2/VU0microInterp.cpp
index b19479d841..de38ecac63 100644
--- a/pcsx2/VU0microInterp.cpp
+++ b/pcsx2/VU0microInterp.cpp
@@ -195,6 +195,7 @@ void vu0Exec(VURegs* VU)
// --------------------------------------------------------------------------------------
InterpVU0::InterpVU0()
{
+ m_Idx = 0;
IsInterpreter = true;
}
@@ -203,7 +204,7 @@ void InterpVU0::Step()
vu0Exec( &VU0 );
}
-void InterpVU0::ExecuteBlock(u32 cycles)
+void InterpVU0::Execute(u32 cycles)
{
for (int i = 128; i--;)
{
diff --git a/pcsx2/VU1micro.cpp b/pcsx2/VU1micro.cpp
index 36688cb04d..e2cf46b51d 100644
--- a/pcsx2/VU1micro.cpp
+++ b/pcsx2/VU1micro.cpp
@@ -46,7 +46,7 @@ void __fastcall vu1ExecMicro(u32 addr)
{
while(VU0.VI[REG_VPU_STAT].UL & 0x100) {
VUM_LOG("vu1ExecMicro > Stalling until current microprogram finishes");
- CpuVU1->ExecuteBlock(vu1RunCycles);
+ CpuVU1->Execute(vu1RunCycles);
}
VUM_LOG("vu1ExecMicro %x", addr);
@@ -59,7 +59,7 @@ void __fastcall vu1ExecMicro(u32 addr)
if ((s32)addr != -1) VU1.VI[REG_TPC].UL = addr;
_vuExecMicroDebug(VU1);
- CpuVU1->ExecuteBlock(vu1RunCycles);
+ CpuVU1->Execute(vu1RunCycles);
}
_vuRegsTables(VU1, VU1regs);
diff --git a/pcsx2/VU1microInterp.cpp b/pcsx2/VU1microInterp.cpp
index 229713baac..44394ebe1c 100644
--- a/pcsx2/VU1microInterp.cpp
+++ b/pcsx2/VU1microInterp.cpp
@@ -178,6 +178,7 @@ void vu1Exec(VURegs* VU)
InterpVU1::InterpVU1()
{
+ m_Idx = 1;
IsInterpreter = true;
}
@@ -186,7 +187,7 @@ void InterpVU1::Step()
vu1Exec( &VU1 );
}
-void InterpVU1::ExecuteBlock(u32 cycles)
+void InterpVU1::Execute(u32 cycles)
{
for (int i = 128; i--;)
{
diff --git a/pcsx2/VUmicro.h b/pcsx2/VUmicro.h
index 2328124542..c0d06e2de9 100644
--- a/pcsx2/VUmicro.h
+++ b/pcsx2/VUmicro.h
@@ -16,6 +16,7 @@
#pragma once
#include "VU.h"
#include "VUops.h"
+#include "R5900.h"
#define vuRunCycles (512*12) // Cycles to run ExecuteBlockJIT() for (called from within recs)
#define vu0RunCycles (512*12) // Cycles to run vu0 for whenever ExecuteBlock() is called
#define vu1RunCycles (3000000) // mVU1 uses this for inf loop detection on dev builds
@@ -47,7 +48,7 @@ public:
public:
BaseCpuProvider()
{
- m_AllocCount = 0;
+ m_AllocCount = 0;
}
virtual ~BaseCpuProvider() throw()
@@ -62,17 +63,18 @@ public:
virtual void Allocate()=0;
virtual void Shutdown()=0;
virtual void Reset()=0;
+ virtual void Execute(u32 cycles)=0;
+ virtual void ExecuteBlock(bool startUp)=0;
virtual void Step()=0;
- virtual void ExecuteBlock(u32 cycles)=0;
virtual void Clear(u32 Addr, u32 Size)=0;
-
+
// C++ Calling Conventions are unstable, and some compilers don't even allow us to take the
// address of C++ methods. We need to use a wrapper function to invoke the ExecuteBlock from
// recompiled code.
- static void __fastcall ExecuteBlockJIT( BaseCpuProvider* cpu )
+ static void __fastcall ExecuteBlockJIT( BaseCpuProvider* cpu )
{
- cpu->ExecuteBlock(vuRunCycles);
+ cpu->Execute(vuRunCycles);
}
};
@@ -82,8 +84,15 @@ public:
// Layer class for possible future implementation (currently is nothing more than a type-safe
// type define).
//
-class BaseVUmicroCPU : public BaseCpuProvider
-{
+class BaseVUmicroCPU : public BaseCpuProvider {
+protected:
+ u32 m_lastEEcycles;
+ int m_Idx;
+ BaseVUmicroCPU() {
+ m_Idx = 0;
+ m_lastEEcycles = 0;
+ }
+ virtual ~BaseVUmicroCPU() throw() {}
public:
// Called by the PS2 VM's event manager for every internal vertical sync (occurs at either
@@ -99,16 +108,63 @@ public:
//
virtual void Vsync() throw() { }
- virtual void Step()
- {
+ virtual void Step() {
// Ideally this would fall back on interpretation for executing single instructions
// for all CPU types, but due to VU complexities and large discrepancies between
// clamping in recs and ints, it's not really worth bothering with yet.
}
-protected:
- BaseVUmicroCPU() {}
- virtual ~BaseVUmicroCPU() throw() {}
+ // Execute VU for the number of VU cycles (recs might go over 0~30 cycles)
+ //virtual void Execute(u32 cycles)=0;
+
+ // Executes a Block based on static preset cycles
+ virtual void ExecuteBlock(bool startUp=0) {
+ const int vuRunning = m_Idx ? 0x100 : 1;
+ if (!(VU0.VI[REG_VPU_STAT].UL & vuRunning)) return;
+ if (startUp) { // Start Executing a microprogram
+ Execute(vu0RunCycles); // Kick start VU
+ // If the VU0 program didn't finish then we'll want to finish it up
+ // pretty soon. This fixes vmhacks in some games (Naruto Ultimate Ninja 2)
+ if(VU0.VI[REG_VPU_STAT].UL & 0x1)
+ cpuSetNextBranchDelta( 192 ); // fixme : ideally this should be higher, like 512 or so.
+ }
+ else {
+ Execute(vu0RunCycles);
+ DevCon.Warning("VU0 running when in BranchTest");
+ // This helps keep the EE and VU0 in sync.
+ // Check Silver Surfer. Currently has SPS varying with different branch deltas set below.
+ if(VU0.VI[REG_VPU_STAT].UL & 0x1)
+ cpuSetNextBranchDelta( 768 );
+ }
+ }
+
+ // Executes a Block based on EE delta time
+ /*virtual void ExecuteBlock(bool startUp=0) {
+ const int vuRunning = m_Idx ? 0x100 : 1;
+ const int c = 1024;
+ if (!(VU0.VI[REG_VPU_STAT].UL & vuRunning)) return;
+ if (startUp) { // Start Executing a microprogram
+ Execute(c); // Kick start VU
+ m_lastEEcycles = cpuRegs.cycle + (c*2);
+ if (VU0.VI[REG_VPU_STAT].UL & vuRunning)
+ cpuSetNextBranchDelta(c*4); // Let VUs run behind EE instead of ahead
+ }
+ else { // Continue Executing (VU roughly half the mhz of EE)
+ s32 delta = (s32)(u32)(cpuRegs.cycle - m_lastEEcycles);
+ if (delta > 0) {
+ delta>>=1;
+ DevCon.WriteLn("Event Test1: Running VU0 for %d cycles", delta);
+ Execute(delta);
+ m_lastEEcycles = cpuRegs.cycle;
+ if (VU0.VI[REG_VPU_STAT].UL & vuRunning)
+ cpuSetNextBranchDelta(c*2); // Let VUs run behind EE instead of in front
+ }
+ else {
+ cpuSetNextBranchDelta(-delta);
+ DevCon.WriteLn("Event Test2: Running VU0 for %d cycles", delta/2);
+ }
+ }
+ }*/
};
@@ -129,7 +185,7 @@ public:
void Reset() { }
void Step();
- void ExecuteBlock(u32 cycles);
+ void Execute(u32 cycles);
void Clear(u32 addr, u32 size) {}
};
@@ -147,7 +203,7 @@ public:
void Reset() { }
void Step();
- void ExecuteBlock(u32 cycles);
+ void Execute(u32 cycles);
void Clear(u32 addr, u32 size) {}
};
@@ -167,7 +223,7 @@ public:
void Shutdown() throw();
void Reset();
- void ExecuteBlock(u32 cycles);
+ void Execute(u32 cycles);
void Clear(u32 addr, u32 size);
void Vsync() throw();
};
@@ -184,11 +240,45 @@ public:
void Allocate();
void Shutdown() throw();
void Reset();
- void ExecuteBlock(u32 cycles);
+ void Execute(u32 cycles);
void Clear(u32 addr, u32 size);
void Vsync() throw();
};
+// --------------------------------------------------------------------------------------
+// recSuperVU0 / recSuperVU1
+// --------------------------------------------------------------------------------------
+
+class recSuperVU0 : public BaseVUmicroCPU
+{
+public:
+ recSuperVU0();
+
+ const char* GetShortName() const { return "sVU0"; }
+ wxString GetLongName() const { return L"SuperVU0 Recompiler"; }
+
+ void Allocate();
+ void Shutdown() throw();
+ void Reset();
+ void Execute(u32 cycles);
+ void Clear(u32 Addr, u32 Size);
+};
+
+class recSuperVU1 : public BaseVUmicroCPU
+{
+public:
+ recSuperVU1();
+
+ const char* GetShortName() const { return "sVU1"; }
+ wxString GetLongName() const { return L"SuperVU1 Recompiler"; }
+
+ void Allocate();
+ void Shutdown() throw();
+ void Reset();
+ void Execute(u32 cycles);
+ void Clear(u32 Addr, u32 Size);
+};
+
extern BaseVUmicroCPU* CpuVU0;
extern BaseVUmicroCPU* CpuVU1;
diff --git a/pcsx2/Vif1_Dma.cpp b/pcsx2/Vif1_Dma.cpp
index ae8b9e6da6..dfc8564dc7 100644
--- a/pcsx2/Vif1_Dma.cpp
+++ b/pcsx2/Vif1_Dma.cpp
@@ -27,7 +27,7 @@ __forceinline void vif1FLUSH()
{
int _cycles = VU1.cycle;
- do { CpuVU1->ExecuteBlock(vu1RunCycles); }
+ do { CpuVU1->Execute(vu1RunCycles); }
while (VU0.VI[REG_VPU_STAT].UL & 0x100);
g_vifCycles += (VU1.cycle - _cycles) * BIAS;
diff --git a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj
index b6ff3a7937..e9337bac3d 100644
--- a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj
+++ b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj
@@ -932,10 +932,6 @@
RelativePath="..\..\x86\iCOP0.h"
>
-
-
diff --git a/pcsx2/x86/iCOP2.cpp b/pcsx2/x86/iCOP2.cpp
deleted file mode 100644
index 99e7543043..0000000000
--- a/pcsx2/x86/iCOP2.cpp
+++ /dev/null
@@ -1,669 +0,0 @@
-/* PCSX2 - PS2 Emulator for PCs
- * Copyright (C) 2002-2009 PCSX2 Dev Team
- *
- * PCSX2 is free software: you can redistribute it and/or modify it under the terms
- * of the GNU Lesser General Public License as published by the Free Software Found-
- * ation, either version 3 of the License, or (at your option) any later version.
- *
- * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with PCSX2.
- * If not, see .
- */
-
-
-#include "PrecompiledHeader.h"
-
-#include "Common.h"
-#include "R5900OpcodeTables.h"
-#include "iR5900.h"
-
-#include "Common.h"
-#include "DebugTools/Debug.h"
-#include "R5900.h"
-#include "R5900OpcodeTables.h"
-#include "VUmicro.h"
-#include "sVU_Micro.h"
-using namespace x86Emitter;
-extern void _vu0WaitMicro();
-
-#ifndef CHECK_MACROVU0
-
-#define _Ft_ _Rt_
-#define _Fs_ _Rd_
-#define _Fd_ _Sa_
-
-#define _Fsf_ ((cpuRegs.code >> 21) & 0x03)
-#define _Ftf_ ((cpuRegs.code >> 23) & 0x03)
-#define _Cc_ (cpuRegs.code & 0x03)
-
-#define REC_COP2_VU0(f) \
- void recV##f( s32 info ) { \
- recVUMI_##f( &VU0, info ); \
- }
-
-#define INTERPRETATE_COP2_FUNC(f) \
-void recV##f(s32 info) { \
- MOV32ItoM((uptr)&cpuRegs.code, cpuRegs.code); \
- MOV32ItoM((uptr)&cpuRegs.pc, pc); \
- iFlushCall(FLUSH_EVERYTHING); \
- CALLFunc((uptr)V##f); \
- _freeX86regs(); \
-}
-
-void recCOP2(s32 info);
-void recCOP2_SPECIAL(s32 info);
-void recCOP2_BC2(s32 info);
-void recCOP2_SPECIAL2(s32 info);
-void rec_C2UNK( s32 info ) {
- Console.Error("Cop2 bad opcode: %x", cpuRegs.code);
-}
-void _vuRegs_C2UNK(VURegs * VU, _VURegsNum *VUregsn) {
- Console.Error("Cop2 bad _vuRegs code:%x", cpuRegs.code);
-}
-
-static void recCFC2(s32 info)
-{
- int mmreg;
-
- if (cpuRegs.code & 1) {
- iFlushCall(FLUSH_NOCONST);
- CALLFunc((uptr)_vu0WaitMicro);
- }
-
- if(!_Rt_) return;
-
- _deleteGPRtoXMMreg(_Rt_, 2);
- mmreg = _checkMMXreg(MMX_GPR+_Rt_, MODE_WRITE);
-
- if (mmreg >= 0) {
- if( _Fs_ >= 16 ) {
- MOVDMtoMMX(mmreg, (uptr)&VU0.VI[ _Fs_ ].UL);
- if (EEINST_ISLIVE1(_Rt_)) { _signExtendGPRtoMMX(mmreg, _Rt_, 0); }
- else { EEINST_RESETHASLIVE1(_Rt_); }
- }
- else MOVDMtoMMX(mmreg, (uptr)&VU0.VI[ _Fs_ ].UL);
- SetMMXstate();
- }
- else {
- MOV32MtoR(EAX, (uptr)&VU0.VI[ _Fs_ ].UL);
- MOV32RtoM((uptr)&cpuRegs.GPR.r[_Rt_].UL[0],EAX);
-
- if(EEINST_ISLIVE1(_Rt_)) {
- if( _Fs_ < 16 ) {
- // no sign extending
- MOV32ItoM((uptr)&cpuRegs.GPR.r[_Rt_].UL[1],0);
- }
- else {
- CDQ();
- MOV32RtoM((uptr)&cpuRegs.GPR.r[_Rt_].UL[1], EDX);
- }
- }
- else { EEINST_RESETHASLIVE1(_Rt_); }
- }
-
- _eeOnWriteReg(_Rt_, 1);
-}
-
-static void recCTC2(s32 info)
-{
- if (cpuRegs.code & 1) {
- iFlushCall(FLUSH_NOCONST);
- CALLFunc((uptr)_vu0WaitMicro);
- }
-
- if(!_Fs_) return;
-
- if( GPR_IS_CONST1(_Rt_) )
- {
- switch(_Fs_) {
- case REG_MAC_FLAG: // read-only
- case REG_TPC: // read-only
- case REG_VPU_STAT: // read-only
- break;
- case REG_FBRST:
- if( g_cpuConstRegs[_Rt_].UL[0] & 0x202 )
- iFlushCall(FLUSH_FREE_TEMPX86);
-
- _deleteX86reg(X86TYPE_VI, REG_FBRST, 2);
-
- if( g_cpuConstRegs[_Rt_].UL[0] & 2 )
- CALLFunc((uptr)vu0ResetRegs);
- if( g_cpuConstRegs[_Rt_].UL[0] & 0x200 )
- CALLFunc((uptr)vu1ResetRegs);
- MOV16ItoM((uptr)&VU0.VI[REG_FBRST].UL,g_cpuConstRegs[_Rt_].UL[0]&0x0c0c);
- break;
- case REG_CMSAR1: // REG_CMSAR1
- iFlushCall(FLUSH_NOCONST);
- pxAssert( _checkX86reg(X86TYPE_VI, REG_VPU_STAT, 0) < 0 &&
- _checkX86reg(X86TYPE_VI, REG_TPC, 0) < 0 );
- // Execute VU1 Micro SubRoutine
-
- xMOV( ecx, g_cpuConstRegs[_Rt_].UL[0]&0xffff );
- xCALL( vu1ExecMicro );
- break;
- default:
- {
- if( _Fs_ < 16 )
- pxAssert( (g_cpuConstRegs[_Rt_].UL[0]&0xffff0000)==0);
-
- // a lot of games have vu0 spinning on some integer
- // then they modify the register and expect vu0 to stop spinning within 10 cycles (donald duck)
-
- // Use vu0ExecMicro instead because it properly stalls for already-running micro
- // instructions, and also sets the nextBranchCycle as needed. (air)
-
- MOV32ItoM((uptr)&VU0.VI[_Fs_].UL,g_cpuConstRegs[_Rt_].UL[0]);
- iFlushCall(FLUSH_NOCONST);
- xMOV(ecx, (uptr)CpuVU0 );
- xCALL(BaseCpuProvider::ExecuteBlockJIT);
- break;
- }
- }
- }
- else
- {
- switch(_Fs_) {
- case REG_MAC_FLAG: // read-only
- case REG_TPC: // read-only
- case REG_VPU_STAT: // read-only
- break;
- case REG_FBRST:
- iFlushCall(FLUSH_FREE_TEMPX86);
- pxAssert( _checkX86reg(X86TYPE_VI, REG_FBRST, 0) < 0 );
-
- _eeMoveGPRtoR(EAX, _Rt_);
-
- TEST32ItoR(EAX,0x2);
- j8Ptr[0] = JZ8(0);
- CALLFunc((uptr)vu0ResetRegs);
- _eeMoveGPRtoR(EAX, _Rt_);
- x86SetJ8(j8Ptr[0]);
-
- TEST32ItoR(EAX,0x200);
- j8Ptr[0] = JZ8(0);
- CALLFunc((uptr)vu1ResetRegs);
- _eeMoveGPRtoR(EAX, _Rt_);
- x86SetJ8(j8Ptr[0]);
-
- AND32ItoR(EAX,0x0C0C);
- MOV16RtoM((uptr)&VU0.VI[REG_FBRST].UL,EAX);
- break;
- case REG_CMSAR1: // REG_CMSAR1 (Execute VU1micro Subroutine)
- iFlushCall(FLUSH_NOCONST);
- _eeMoveGPRtoR(ECX, _Rt_);
- xCALL( vu1ExecMicro );
- break;
- default:
- _eeMoveGPRtoM((uptr)&VU0.VI[_Fs_].UL,_Rt_);
-
- // a lot of games have vu0 spinning on some integer
- // then they modify the register and expect vu0 to stop spinning within 10 cycles (donald duck)
- iFlushCall(FLUSH_NOCONST);
- break;
- }
- }
-}
-
-static void recQMFC2(s32 info)
-{
- int t0reg, fsreg;
-
- if (cpuRegs.code & 1) {
- iFlushCall(FLUSH_NOCONST);
- CALLFunc((uptr)_vu0WaitMicro);
- }
-
- if(!_Rt_) return;
-
- _deleteMMXreg(MMX_GPR+_Rt_, 2);
- _deleteX86reg(X86TYPE_GPR, _Rt_, 2);
- _eeOnWriteReg(_Rt_, 0);
-
- // could 'borrow' the reg
- fsreg = _checkXMMreg(XMMTYPE_VFREG, _Fs_, MODE_READ);
-
- if( fsreg >= 0 ) {
- if ( xmmregs[fsreg].mode & MODE_WRITE ) {
- _xmmregs temp;
-
- t0reg = _allocGPRtoXMMreg(-1, _Rt_, MODE_WRITE);
- SSEX_MOVDQA_XMM_to_XMM(t0reg, fsreg);
-
- // change regs
- temp = xmmregs[t0reg];
- xmmregs[t0reg] = xmmregs[fsreg];
- xmmregs[fsreg] = temp;
- }
- else {
- // swap regs
- t0reg = _allocGPRtoXMMreg(-1, _Rt_, MODE_WRITE);
-
- xmmregs[fsreg] = xmmregs[t0reg];
- xmmregs[t0reg].inuse = 0;
- }
- }
- else {
- t0reg = _allocGPRtoXMMreg(-1, _Rt_, MODE_WRITE);
-
- if (t0reg >= 0) SSE_MOVAPS_M128_to_XMM( t0reg, (uptr)&VU0.VF[_Fs_].UD[0]);
- else _recMove128MtoM((uptr)&cpuRegs.GPR.r[_Rt_].UL[0], (uptr)&VU0.VF[_Fs_].UL[0]);
- }
-
- _clearNeededXMMregs();
-}
-
-static void recQMTC2(s32 info)
-{
- int mmreg;
-
- if (cpuRegs.code & 1) {
- iFlushCall(FLUSH_NOCONST);
- CALLFunc((uptr)_vu0WaitMicro);
- }
-
- if (!_Fs_) return;
-
- mmreg = _checkXMMreg(XMMTYPE_GPRREG, _Rt_, MODE_READ);
-
- if( mmreg >= 0) {
- int fsreg = _checkXMMreg(XMMTYPE_VFREG, _Fs_, MODE_WRITE);
- int flag = ((xmmregs[mmreg].mode&MODE_WRITE) && (g_pCurInstInfo->regs[_Rt_]&(EEINST_LIVE0|EEINST_LIVE1|EEINST_LIVE2)));
-
- if( fsreg >= 0 ) {
-
- if (flag) {
- SSE_MOVAPS_XMM_to_XMM(fsreg, mmreg);
- }
- else {
- // swap regs
- xmmregs[mmreg] = xmmregs[fsreg];
- xmmregs[mmreg].mode = MODE_WRITE;
- xmmregs[fsreg].inuse = 0;
- g_xmmtypes[mmreg] = XMMT_FPS;
- }
- }
- else {
- if (flag) SSE_MOVAPS_XMM_to_M128((uptr)&cpuRegs.GPR.r[_Rt_], mmreg);
-
- // swap regs
- xmmregs[mmreg].type = XMMTYPE_VFREG;
- xmmregs[mmreg].VU = 0;
- xmmregs[mmreg].reg = _Fs_;
- xmmregs[mmreg].mode = MODE_WRITE;
- g_xmmtypes[mmreg] = XMMT_FPS;
- }
- }
- else {
- int fsreg = _allocVFtoXMMreg(&VU0, -1, _Fs_, MODE_WRITE);
-
- if( fsreg >= 0 ) {
- mmreg = _checkMMXreg(MMX_GPR+_Rt_, MODE_READ);
-
- if( mmreg >= 0) {
- SetMMXstate();
- SSE2_MOVQ2DQ_MM_to_XMM(fsreg, mmreg);
- SSE_MOVHPS_M64_to_XMM(fsreg, (uptr)&cpuRegs.GPR.r[_Rt_].UL[2]);
- }
- else {
- if( GPR_IS_CONST1( _Rt_ ) ) {
- pxAssert( _checkXMMreg(XMMTYPE_GPRREG, _Rt_, MODE_READ) == -1 );
- _flushConstReg(_Rt_);
- }
-
- SSE_MOVAPS_M128_to_XMM(fsreg, (uptr)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ]);
- }
- }
- else {
- _deleteEEreg(_Rt_, 0);
- _recMove128MtoM((uptr)&VU0.VF[_Fs_].UL[0], (uptr)&cpuRegs.GPR.r[_Rt_].UL[0]);
- }
- }
-
- _clearNeededXMMregs();
-}
-
-// Removed _cop2AnalyzeOp because it was outdated and unreliable (And currently unused).
-// A new version should be rebuilt using the SuperVU's AnalyzeOp as a reference. (air)
-
-//////////////////////////////////////////////////////////////////////////
-// BC2: Instructions
-//////////////////////////////////////////////////////////////////////////
-
-using namespace R5900::Dynarec;
-
-static void _setupBranchTest()
-{
- _eeFlushAllUnused();
-
- // COP2 branch conditionals are based on the following equation:
- // ((VU0.VI[REG_VPU_STAT].US[0] >> 8) & 1)
- // BC2F checks if the statement is false, BC2T checks if the statement is true.
-
- TEST32ItoM((uptr)&VU0.VI[REG_VPU_STAT].UL, 0x100);
-}
-
-void recBC2F( s32 info )
-{
- _setupBranchTest();
- recDoBranchImm(JNZ32(0));
-}
-
-void recBC2T( s32 info )
-{
- _setupBranchTest();
- recDoBranchImm(JZ32(0));
-}
-
-void recBC2FL( s32 info )
-{
- _setupBranchTest();
- recDoBranchImm_Likely(JNZ32(0));
-}
-
-void recBC2TL( s32 info )
-{
- _setupBranchTest();
- recDoBranchImm_Likely(JZ32(0));
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Special1 instructions
-//////////////////////////////////////////////////////////////////////////
-
-//TODO: redirect all the opcodes to the ivu0micro same functions
-REC_COP2_VU0(IADD);
-REC_COP2_VU0(IADDI);
-REC_COP2_VU0(ISUB);
-REC_COP2_VU0(IOR);
-REC_COP2_VU0(IAND);
-REC_COP2_VU0(OPMSUB);
-REC_COP2_VU0(MADDq);
-REC_COP2_VU0(MADDi);
-REC_COP2_VU0(MSUBq);
-REC_COP2_VU0(MSUBi);
-REC_COP2_VU0(SUBi);
-REC_COP2_VU0(SUBq);
-REC_COP2_VU0(MULi);
-REC_COP2_VU0(MULq);
-REC_COP2_VU0(MAXi);
-REC_COP2_VU0(MINIi);
-REC_COP2_VU0(MUL);
-REC_COP2_VU0(MAX);
-REC_COP2_VU0(MADD);
-REC_COP2_VU0(MSUB);
-
-REC_COP2_VU0(MINIx);
-REC_COP2_VU0(MINIy);
-REC_COP2_VU0(MINIz);
-REC_COP2_VU0(MINIw);
-
-REC_COP2_VU0(MAXx);
-REC_COP2_VU0(MAXy);
-REC_COP2_VU0(MAXz);
-REC_COP2_VU0(MAXw);
-
-REC_COP2_VU0(MULx);
-REC_COP2_VU0(MULy);
-REC_COP2_VU0(MULz);
-REC_COP2_VU0(MULw);
-
-REC_COP2_VU0(ADD);
-REC_COP2_VU0(ADDi);
-REC_COP2_VU0(ADDq);
-REC_COP2_VU0(ADDx);
-REC_COP2_VU0(ADDy);
-REC_COP2_VU0(ADDz);
-REC_COP2_VU0(ADDw);
-
-REC_COP2_VU0(SUBx);
-REC_COP2_VU0(SUBy);
-REC_COP2_VU0(SUBz);
-REC_COP2_VU0(SUBw);
-
-REC_COP2_VU0(MADDx);
-REC_COP2_VU0(MADDy);
-REC_COP2_VU0(MADDz);
-REC_COP2_VU0(MADDw);
-
-REC_COP2_VU0(MSUBx);
-REC_COP2_VU0(MSUBy);
-REC_COP2_VU0(MSUBz);
-REC_COP2_VU0(MSUBw);
-
-REC_COP2_VU0(SUB);
-REC_COP2_VU0(MINI);
-
-//////////////////////////////////////////////////////////////////////////
-// Special2 instructions
-//////////////////////////////////////////////////////////////////////////
-
-REC_COP2_VU0(CLIP);
-REC_COP2_VU0(LQI);
-REC_COP2_VU0(SQI);
-REC_COP2_VU0(LQD);
-REC_COP2_VU0(SQD);
-REC_COP2_VU0(MTIR);
-REC_COP2_VU0(MFIR);
-REC_COP2_VU0(ILWR);
-REC_COP2_VU0(ISWR);
-REC_COP2_VU0(RINIT);
-REC_COP2_VU0(RXOR);
-REC_COP2_VU0(RNEXT);
-REC_COP2_VU0(RGET);
-
-REC_COP2_VU0(ITOF0);
-REC_COP2_VU0(ITOF4);
-REC_COP2_VU0(ITOF12);
-REC_COP2_VU0(ITOF15);
-REC_COP2_VU0(FTOI0);
-REC_COP2_VU0(FTOI4);
-REC_COP2_VU0(FTOI12);
-REC_COP2_VU0(FTOI15);
-REC_COP2_VU0(MADDA);
-REC_COP2_VU0(MSUBA);
-REC_COP2_VU0(MADDAi);
-REC_COP2_VU0(MADDAq);
-REC_COP2_VU0(MADDAx);
-REC_COP2_VU0(MADDAy);
-REC_COP2_VU0(MADDAz);
-REC_COP2_VU0(MADDAw);
-REC_COP2_VU0(MSUBAi);
-REC_COP2_VU0(MSUBAq);
-REC_COP2_VU0(MSUBAx);
-REC_COP2_VU0(MSUBAy);
-REC_COP2_VU0(MSUBAz);
-REC_COP2_VU0(MSUBAw);
-REC_COP2_VU0(ADDAi);
-REC_COP2_VU0(ADDA);
-REC_COP2_VU0(SUBA);
-REC_COP2_VU0(MULA);
-REC_COP2_VU0(ADDAq);
-REC_COP2_VU0(ADDAx);
-REC_COP2_VU0(ADDAy);
-REC_COP2_VU0(ADDAz);
-REC_COP2_VU0(ADDAw);
-REC_COP2_VU0(SUBAi);
-REC_COP2_VU0(SUBAq);
-REC_COP2_VU0(SUBAx);
-REC_COP2_VU0(SUBAy);
-REC_COP2_VU0(SUBAz);
-REC_COP2_VU0(SUBAw);
-REC_COP2_VU0(MULAi);
-REC_COP2_VU0(MULAq);
-REC_COP2_VU0(MULAx);
-REC_COP2_VU0(MULAy);
-REC_COP2_VU0(MULAz);
-REC_COP2_VU0(MULAw);
-REC_COP2_VU0(OPMULA);
-REC_COP2_VU0(MOVE);
-REC_COP2_VU0(DIV);
-REC_COP2_VU0(SQRT);
-REC_COP2_VU0(RSQRT);
-REC_COP2_VU0(MR32);
-REC_COP2_VU0(ABS);
-
-void recVNOP(s32 info){}
-void recVWAITQ(s32 info){}
-INTERPRETATE_COP2_FUNC(CALLMS);
-INTERPRETATE_COP2_FUNC(CALLMSR);
-
-void _vuRegsCOP2_SPECIAL(VURegs * VU, _VURegsNum *VUregsn);
-void _vuRegsCOP2_SPECIAL2(VURegs * VU, _VURegsNum *VUregsn);
-
-// information
-void _vuRegsQMFC2(VURegs * VU, _VURegsNum *VUregsn) {
- VUregsn->VFread0 = _Fs_;
- VUregsn->VFr0xyzw= 0xf;
-}
-
-void _vuRegsCFC2(VURegs * VU, _VURegsNum *VUregsn) {
- VUregsn->VIread = 1<<_Fs_;
-}
-
-void _vuRegsQMTC2(VURegs * VU, _VURegsNum *VUregsn) {
- VUregsn->VFwrite = _Fs_;
- VUregsn->VFwxyzw= 0xf;
-}
-
-void _vuRegsCTC2(VURegs * VU, _VURegsNum *VUregsn) {
- VUregsn->VIwrite = 1<<_Fs_;
-}
-
-void (*_vuRegsCOP2t[32])(VURegs * VU, _VURegsNum *VUregsn) = {
- _vuRegs_C2UNK, _vuRegsQMFC2, _vuRegsCFC2, _vuRegs_C2UNK, _vuRegs_C2UNK, _vuRegsQMTC2, _vuRegsCTC2, _vuRegs_C2UNK,
- _vuRegsNOP, _vuRegs_C2UNK, _vuRegs_C2UNK, _vuRegs_C2UNK, _vuRegs_C2UNK, _vuRegs_C2UNK, _vuRegs_C2UNK, _vuRegs_C2UNK,
- _vuRegsCOP2_SPECIAL,_vuRegsCOP2_SPECIAL,_vuRegsCOP2_SPECIAL,_vuRegsCOP2_SPECIAL,_vuRegsCOP2_SPECIAL,_vuRegsCOP2_SPECIAL,_vuRegsCOP2_SPECIAL,_vuRegsCOP2_SPECIAL,
- _vuRegsCOP2_SPECIAL,_vuRegsCOP2_SPECIAL,_vuRegsCOP2_SPECIAL,_vuRegsCOP2_SPECIAL,_vuRegsCOP2_SPECIAL,_vuRegsCOP2_SPECIAL,_vuRegsCOP2_SPECIAL,_vuRegsCOP2_SPECIAL,
-};
-
-void (*_vuRegsCOP2SPECIAL1t[64])(VURegs * VU, _VURegsNum *VUregsn) = {
- _vuRegsADDx, _vuRegsADDy, _vuRegsADDz, _vuRegsADDw, _vuRegsSUBx, _vuRegsSUBy, _vuRegsSUBz, _vuRegsSUBw,
- _vuRegsMADDx, _vuRegsMADDy, _vuRegsMADDz, _vuRegsMADDw, _vuRegsMSUBx, _vuRegsMSUBy, _vuRegsMSUBz, _vuRegsMSUBw,
- _vuRegsMAXx, _vuRegsMAXy, _vuRegsMAXz, _vuRegsMAXw, _vuRegsMINIx, _vuRegsMINIy, _vuRegsMINIz, _vuRegsMINIw,
- _vuRegsMULx, _vuRegsMULy, _vuRegsMULz, _vuRegsMULw, _vuRegsMULq, _vuRegsMAXi, _vuRegsMULi, _vuRegsMINIi,
- _vuRegsADDq, _vuRegsMADDq, _vuRegsADDi, _vuRegsMADDi, _vuRegsSUBq, _vuRegsMSUBq, _vuRegsSUBi, _vuRegsMSUBi,
- _vuRegsADD, _vuRegsMADD, _vuRegsMUL, _vuRegsMAX, _vuRegsSUB, _vuRegsMSUB, _vuRegsOPMSUB, _vuRegsMINI,
- _vuRegsIADD, _vuRegsISUB, _vuRegsIADDI, _vuRegs_C2UNK, _vuRegsIAND, _vuRegsIOR, _vuRegs_C2UNK, _vuRegs_C2UNK,
- _vuRegsNOP, _vuRegsNOP, _vuRegs_C2UNK, _vuRegs_C2UNK, _vuRegsCOP2_SPECIAL2,_vuRegsCOP2_SPECIAL2,_vuRegsCOP2_SPECIAL2,_vuRegsCOP2_SPECIAL2,
-};
-
-void (*_vuRegsCOP2SPECIAL2t[128])(VURegs * VU, _VURegsNum *VUregsn) = {
- _vuRegsADDAx ,_vuRegsADDAy ,_vuRegsADDAz ,_vuRegsADDAw ,_vuRegsSUBAx ,_vuRegsSUBAy ,_vuRegsSUBAz ,_vuRegsSUBAw,
- _vuRegsMADDAx ,_vuRegsMADDAy ,_vuRegsMADDAz ,_vuRegsMADDAw ,_vuRegsMSUBAx ,_vuRegsMSUBAy ,_vuRegsMSUBAz ,_vuRegsMSUBAw,
- _vuRegsITOF0 ,_vuRegsITOF4 ,_vuRegsITOF12 ,_vuRegsITOF15 ,_vuRegsFTOI0 ,_vuRegsFTOI4 ,_vuRegsFTOI12 ,_vuRegsFTOI15,
- _vuRegsMULAx ,_vuRegsMULAy ,_vuRegsMULAz ,_vuRegsMULAw ,_vuRegsMULAq ,_vuRegsABS ,_vuRegsMULAi ,_vuRegsCLIP,
- _vuRegsADDAq ,_vuRegsMADDAq ,_vuRegsADDAi ,_vuRegsMADDAi ,_vuRegsSUBAq ,_vuRegsMSUBAq ,_vuRegsSUBAi ,_vuRegsMSUBAi,
- _vuRegsADDA ,_vuRegsMADDA ,_vuRegsMULA ,_vuRegs_C2UNK ,_vuRegsSUBA ,_vuRegsMSUBA ,_vuRegsOPMULA ,_vuRegsNOP,
- _vuRegsMOVE ,_vuRegsMR32 ,_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegsLQI ,_vuRegsSQI ,_vuRegsLQD ,_vuRegsSQD,
- _vuRegsDIV ,_vuRegsSQRT ,_vuRegsRSQRT ,_vuRegsWAITQ ,_vuRegsMTIR ,_vuRegsMFIR ,_vuRegsILWR ,_vuRegsISWR,
- _vuRegsRNEXT ,_vuRegsRGET ,_vuRegsRINIT ,_vuRegsRXOR ,_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK,
- _vuRegs_C2UNK ,_vuRegs_C2UNK,_vuRegs_C2UNK,_vuRegs_C2UNK,_vuRegs_C2UNK,_vuRegs_C2UNK,_vuRegs_C2UNK,_vuRegs_C2UNK,
- _vuRegs_C2UNK ,_vuRegs_C2UNK,_vuRegs_C2UNK,_vuRegs_C2UNK,_vuRegs_C2UNK,_vuRegs_C2UNK,_vuRegs_C2UNK,_vuRegs_C2UNK,
- _vuRegs_C2UNK ,_vuRegs_C2UNK,_vuRegs_C2UNK,_vuRegs_C2UNK,_vuRegs_C2UNK,_vuRegs_C2UNK,_vuRegs_C2UNK,_vuRegs_C2UNK,
- _vuRegs_C2UNK ,_vuRegs_C2UNK,_vuRegs_C2UNK,_vuRegs_C2UNK,_vuRegs_C2UNK,_vuRegs_C2UNK,_vuRegs_C2UNK,_vuRegs_C2UNK,
- _vuRegs_C2UNK ,_vuRegs_C2UNK,_vuRegs_C2UNK,_vuRegs_C2UNK,_vuRegs_C2UNK,_vuRegs_C2UNK,_vuRegs_C2UNK,_vuRegs_C2UNK,
- _vuRegs_C2UNK ,_vuRegs_C2UNK,_vuRegs_C2UNK,_vuRegs_C2UNK,_vuRegs_C2UNK,_vuRegs_C2UNK,_vuRegs_C2UNK,_vuRegs_C2UNK,
- _vuRegs_C2UNK ,_vuRegs_C2UNK,_vuRegs_C2UNK,_vuRegs_C2UNK,_vuRegs_C2UNK,_vuRegs_C2UNK,_vuRegs_C2UNK,_vuRegs_C2UNK,
-};
-
-void _vuRegsCOP22(VURegs * VU, _VURegsNum *VUregsn)
-{
- _vuRegsCOP2t[_Rs_](VU, VUregsn);
-}
-
-void _vuRegsCOP2_SPECIAL(VURegs * VU, _VURegsNum *VUregsn)
-{
- _vuRegsCOP2SPECIAL1t[_Funct_](VU, VUregsn);
-}
-
-void _vuRegsCOP2_SPECIAL2(VURegs * VU, _VURegsNum *VUregsn)
-{
- int opc=(cpuRegs.code & 0x3) | ((cpuRegs.code >> 4) & 0x7c);
- _vuRegsCOP2SPECIAL2t[opc](VU, VUregsn);
-}
-
-// recompilation
-void (*recCOP2t[32])(s32 info) = {
- rec_C2UNK, recQMFC2, recCFC2, rec_C2UNK, rec_C2UNK, recQMTC2, recCTC2, rec_C2UNK,
- recCOP2_BC2, rec_C2UNK, rec_C2UNK, rec_C2UNK, rec_C2UNK, rec_C2UNK, rec_C2UNK, rec_C2UNK,
- recCOP2_SPECIAL,recCOP2_SPECIAL,recCOP2_SPECIAL,recCOP2_SPECIAL,recCOP2_SPECIAL,recCOP2_SPECIAL,recCOP2_SPECIAL,recCOP2_SPECIAL,
- recCOP2_SPECIAL,recCOP2_SPECIAL,recCOP2_SPECIAL,recCOP2_SPECIAL,recCOP2_SPECIAL,recCOP2_SPECIAL,recCOP2_SPECIAL,recCOP2_SPECIAL,
-};
-
-void (*recCOP2_BC2t[32])(s32 info) = {
- recBC2F, recBC2T, recBC2FL, recBC2TL, rec_C2UNK, rec_C2UNK, rec_C2UNK, rec_C2UNK,
- rec_C2UNK, rec_C2UNK, rec_C2UNK, rec_C2UNK, rec_C2UNK, rec_C2UNK, rec_C2UNK, rec_C2UNK,
- rec_C2UNK, rec_C2UNK, rec_C2UNK, rec_C2UNK, rec_C2UNK, rec_C2UNK, rec_C2UNK, rec_C2UNK,
- rec_C2UNK, rec_C2UNK, rec_C2UNK, rec_C2UNK, rec_C2UNK, rec_C2UNK, rec_C2UNK, rec_C2UNK,
-};
-
-void (*recCOP2SPECIAL1t[64])(s32 info) = {
- recVADDx, recVADDy, recVADDz, recVADDw, recVSUBx, recVSUBy, recVSUBz, recVSUBw,
- recVMADDx, recVMADDy, recVMADDz, recVMADDw, recVMSUBx, recVMSUBy, recVMSUBz, recVMSUBw,
- recVMAXx, recVMAXy, recVMAXz, recVMAXw, recVMINIx, recVMINIy, recVMINIz, recVMINIw,
- recVMULx, recVMULy, recVMULz, recVMULw, recVMULq, recVMAXi, recVMULi, recVMINIi,
- recVADDq, recVMADDq, recVADDi, recVMADDi, recVSUBq, recVMSUBq, recVSUBi, recVMSUBi,
- recVADD, recVMADD, recVMUL, recVMAX, recVSUB, recVMSUB, recVOPMSUB, recVMINI,
- recVIADD, recVISUB, recVIADDI, rec_C2UNK, recVIAND, recVIOR, rec_C2UNK, rec_C2UNK,
- recVCALLMS, recVCALLMSR, rec_C2UNK, rec_C2UNK, recCOP2_SPECIAL2,recCOP2_SPECIAL2,recCOP2_SPECIAL2,recCOP2_SPECIAL2,
-};
-
-void (*recCOP2SPECIAL2t[128])(s32 info) = {
- recVADDAx ,recVADDAy ,recVADDAz ,recVADDAw ,recVSUBAx ,recVSUBAy ,recVSUBAz ,recVSUBAw,
- recVMADDAx ,recVMADDAy ,recVMADDAz ,recVMADDAw ,recVMSUBAx ,recVMSUBAy ,recVMSUBAz ,recVMSUBAw,
- recVITOF0 ,recVITOF4 ,recVITOF12 ,recVITOF15 ,recVFTOI0 ,recVFTOI4 ,recVFTOI12 ,recVFTOI15,
- recVMULAx ,recVMULAy ,recVMULAz ,recVMULAw ,recVMULAq ,recVABS ,recVMULAi ,recVCLIP,
- recVADDAq ,recVMADDAq ,recVADDAi ,recVMADDAi ,recVSUBAq ,recVMSUBAq ,recVSUBAi ,recVMSUBAi,
- recVADDA ,recVMADDA ,recVMULA ,rec_C2UNK ,recVSUBA ,recVMSUBA ,recVOPMULA ,recVNOP,
- recVMOVE ,recVMR32 ,rec_C2UNK ,rec_C2UNK ,recVLQI ,recVSQI ,recVLQD ,recVSQD,
- recVDIV ,recVSQRT ,recVRSQRT ,recVWAITQ ,recVMTIR ,recVMFIR ,recVILWR ,recVISWR,
- recVRNEXT ,recVRGET ,recVRINIT ,recVRXOR ,rec_C2UNK ,rec_C2UNK ,rec_C2UNK ,rec_C2UNK,
- rec_C2UNK ,rec_C2UNK,rec_C2UNK,rec_C2UNK,rec_C2UNK,rec_C2UNK,rec_C2UNK,rec_C2UNK,
- rec_C2UNK ,rec_C2UNK,rec_C2UNK,rec_C2UNK,rec_C2UNK,rec_C2UNK,rec_C2UNK,rec_C2UNK,
- rec_C2UNK ,rec_C2UNK,rec_C2UNK,rec_C2UNK,rec_C2UNK,rec_C2UNK,rec_C2UNK,rec_C2UNK,
- rec_C2UNK ,rec_C2UNK,rec_C2UNK,rec_C2UNK,rec_C2UNK,rec_C2UNK,rec_C2UNK,rec_C2UNK,
- rec_C2UNK ,rec_C2UNK,rec_C2UNK,rec_C2UNK,rec_C2UNK,rec_C2UNK,rec_C2UNK,rec_C2UNK,
- rec_C2UNK ,rec_C2UNK,rec_C2UNK,rec_C2UNK,rec_C2UNK,rec_C2UNK,rec_C2UNK,rec_C2UNK,
- rec_C2UNK ,rec_C2UNK,rec_C2UNK,rec_C2UNK,rec_C2UNK,rec_C2UNK,rec_C2UNK,rec_C2UNK,
-};
-
-namespace R5900 {
-namespace Dynarec {
-namespace OpcodeImpl
-{
- void recCOP2()
- {
- VU0.code = cpuRegs.code;
-
- g_pCurInstInfo->vuregs.pipe = 0xff; // to notify eeVURecompileCode that COP2
- s32 info = eeVURecompileCode(&VU0, &g_pCurInstInfo->vuregs);
-
- info |= PROCESS_VU_COP2;
- info |= PROCESS_VU_UPDATEFLAGS;
-
- recCOP2t[_Rs_]( info );
-
- _freeX86regs();
- }
-}}}
-
-void recCOP2_SPECIAL(s32 info )
-{
- recCOP2SPECIAL1t[_Funct_]( info );
-}
-
-void recCOP2_BC2(s32 info)
-{
- recCOP2_BC2t[_Rt_](info);
-}
-
-void recCOP2_SPECIAL2(s32 info)
-{
- int opc=(cpuRegs.code & 0x3) | ((cpuRegs.code >> 4) & 0x7c);
- recCOP2SPECIAL2t[opc](info);
-}
-
-#endif // CHECK_MACROVU0
\ No newline at end of file
diff --git a/pcsx2/x86/microVU.cpp b/pcsx2/x86/microVU.cpp
index 281bff65fa..e3a35ddd69 100644
--- a/pcsx2/x86/microVU.cpp
+++ b/pcsx2/x86/microVU.cpp
@@ -331,8 +331,8 @@ _mVUt _f int mVUsearchProg() {
static u32 mvu0_allocated = 0;
static u32 mvu1_allocated = 0;
-recMicroVU0::recMicroVU0() { IsInterpreter = false; }
-recMicroVU1::recMicroVU1() { IsInterpreter = false; }
+recMicroVU0::recMicroVU0() { m_Idx = 0; IsInterpreter = false; }
+recMicroVU1::recMicroVU1() { m_Idx = 1; IsInterpreter = false; }
void recMicroVU0::Vsync() throw() { mVUvsyncUpdate(µVU0); }
void recMicroVU1::Vsync() throw() { mVUvsyncUpdate(µVU1); }
@@ -375,7 +375,7 @@ void recMicroVU1::Reset() {
mVUreset(µVU1);
}
-void recMicroVU0::ExecuteBlock(u32 cycles) {
+void recMicroVU0::Execute(u32 cycles) {
pxAssert(mvu0_allocated); // please allocate me first! :|
if(!(VU0.VI[REG_VPU_STAT].UL & 1)) return;
@@ -387,13 +387,13 @@ void recMicroVU0::ExecuteBlock(u32 cycles) {
((mVUrecCall)microVU0.startFunct)(VU0.VI[REG_TPC].UL, cycles);
XMMRegisters::Thaw();
}
-void recMicroVU1::ExecuteBlock(u32 cycles) {
+void recMicroVU1::Execute(u32 cycles) {
pxAssert(mvu1_allocated); // please allocate me first! :|
if(!(VU0.VI[REG_VPU_STAT].UL & 0x100)) return;
XMMRegisters::Freeze();
- ((mVUrecCall)microVU1.startFunct)(VU1.VI[REG_TPC].UL, cycles);
+ ((mVUrecCall)microVU1.startFunct)(VU1.VI[REG_TPC].UL, vu1RunCycles);
XMMRegisters::Thaw();
}
diff --git a/pcsx2/x86/microVU_Branch.inl b/pcsx2/x86/microVU_Branch.inl
index 5b65e75e81..9f10af1272 100644
--- a/pcsx2/x86/microVU_Branch.inl
+++ b/pcsx2/x86/microVU_Branch.inl
@@ -64,7 +64,7 @@ _f void mVUendProgram(mV, microFlagCycles* mFC, int isEbit) {
}
// Save Flag Instances
-#ifdef CHECK_MACROVU0
+#if 1 // CHECK_MACROVU0 - Always on now
getFlagReg(fStatus, fStatus);
MOV32RtoM((uptr)&mVU->regs->VI[REG_STATUS_FLAG].UL, fStatus);
#else
diff --git a/pcsx2/x86/microVU_Compile.inl b/pcsx2/x86/microVU_Compile.inl
index 975f18d90f..bcdef7e71f 100644
--- a/pcsx2/x86/microVU_Compile.inl
+++ b/pcsx2/x86/microVU_Compile.inl
@@ -298,8 +298,8 @@ _f void mVUtestCycles(microVU* mVU) {
//u32* vu0jmp;
iPC = mVUstartPC;
mVUdebugNOW(0);
- SUB32ItoM((uptr)&mVU->cycles, mVUcycles);
if (doEarlyExit(mVU)) {
+ CMP32ItoM((uptr)&mVU->cycles, 0);
u32* jmp32 = JG32(0);
//if (!isVU1) { TEST32ItoM((uptr)&mVU->regs->flags, VUFLAG_MFLAGSET); vu0jmp = JZ32(0); }
MOV32ItoR(gprT2, (uptr)mVU);
@@ -310,6 +310,7 @@ _f void mVUtestCycles(microVU* mVU) {
//if (!isVU1) x86SetJ32(vu0jmp);
x86SetJ32(jmp32);
}
+ SUB32ItoM((uptr)&mVU->cycles, mVUcycles);
}
// Initialize VI Constants (vi15 propagates through blocks)
diff --git a/pcsx2/x86/microVU_Execute.inl b/pcsx2/x86/microVU_Execute.inl
index 3326ff986b..dfd54bfe45 100644
--- a/pcsx2/x86/microVU_Execute.inl
+++ b/pcsx2/x86/microVU_Execute.inl
@@ -42,7 +42,7 @@ void mVUdispatcherA(mV) {
xLDMXCSR(g_sseVUMXCSR);
// Load Regs
-#ifdef CHECK_MACROVU0
+#if 1 // CHECK_MACROVU0 - Always on now
MOV32MtoR(gprF0, (uptr)&mVU->regs->VI[REG_STATUS_FLAG].UL);
MOV32RtoR(gprF1, gprF0);
MOV32RtoR(gprF2, gprF0);
diff --git a/pcsx2/x86/microVU_Macro.inl b/pcsx2/x86/microVU_Macro.inl
index 2b47fcc479..b9657492bd 100644
--- a/pcsx2/x86/microVU_Macro.inl
+++ b/pcsx2/x86/microVU_Macro.inl
@@ -13,8 +13,6 @@
* If not, see .
*/
-#ifdef CHECK_MACROVU0
-
#pragma once
extern void _vu0WaitMicro();
@@ -432,5 +430,3 @@ namespace OpcodeImpl { void recCOP2() { recCOP2t[_Rs_](); }}}}
void recCOP2_BC2 () { recCOP2_BC2t[_Rt_](); }
void recCOP2_SPEC1() { recCOP2SPECIAL1t[_Funct_](); }
void recCOP2_SPEC2() { recCOP2SPECIAL2t[(cpuRegs.code&3)|((cpuRegs.code>>4)&0x7c)](); }
-
-#endif // CHECK_MACROVU0
diff --git a/pcsx2/x86/sVU_zerorec.cpp b/pcsx2/x86/sVU_zerorec.cpp
index b0c679eff9..d55d276992 100644
--- a/pcsx2/x86/sVU_zerorec.cpp
+++ b/pcsx2/x86/sVU_zerorec.cpp
@@ -4610,6 +4610,7 @@ void recVUunknown(VURegs* VU, s32 info)
// --------------------------------------------------------------------------------------
recSuperVU0::recSuperVU0()
{
+ m_Idx = 0;
IsInterpreter = false;
}
@@ -4628,7 +4629,7 @@ void recSuperVU0::Reset()
SuperVUReset( 0 );
}
-void recSuperVU0::ExecuteBlock(u32 cycles)
+void recSuperVU0::Execute(u32 cycles)
{
if ((VU0.VI[REG_VPU_STAT].UL & 1) == 0) return;
@@ -4648,6 +4649,7 @@ void recSuperVU0::Clear(u32 Addr, u32 Size)
// --------------------------------------------------------------------------------------
recSuperVU1::recSuperVU1()
{
+ m_Idx = 1;
IsInterpreter = false;
}
@@ -4666,7 +4668,7 @@ void recSuperVU1::Reset()
SuperVUReset( 1 );
}
-void recSuperVU1::ExecuteBlock(u32 cycles)
+void recSuperVU1::Execute(u32 cycles)
{
if ((VU0.VI[REG_VPU_STAT].UL & 0x100) == 0) return;
pxAssert( (VU1.VI[REG_TPC].UL&7) == 0 );
diff --git a/pcsx2/x86/sVU_zerorec.h b/pcsx2/x86/sVU_zerorec.h
index 44231a0d4f..13d3c2d937 100644
--- a/pcsx2/x86/sVU_zerorec.h
+++ b/pcsx2/x86/sVU_zerorec.h
@@ -40,34 +40,3 @@ extern u32 SuperVUGetVIAddr(int reg, int read);
// if p == 0, flush q else flush p; if wait is != 0, waits for p/q
extern void SuperVUFlush(int p, int wait);
-
-
-class recSuperVU0 : public BaseVUmicroCPU
-{
-public:
- recSuperVU0();
-
- const char* GetShortName() const { return "sVU0"; }
- wxString GetLongName() const { return L"SuperVU0 Recompiler"; }
-
- void Allocate();
- void Shutdown() throw();
- void Reset();
- void ExecuteBlock(u32 cycles);
- void Clear(u32 Addr, u32 Size);
-};
-
-class recSuperVU1 : public BaseVUmicroCPU
-{
-public:
- recSuperVU1();
-
- const char* GetShortName() const { return "sVU1"; }
- wxString GetLongName() const { return L"SuperVU1 Recompiler"; }
-
- void Allocate();
- void Shutdown() throw();
- void Reset();
- void ExecuteBlock(u32 cycles);
- void Clear(u32 Addr, u32 Size);
-};