From a3f0ba5315b747d660642900742e22883f6dc71f Mon Sep 17 00:00:00 2001 From: cottonvibes Date: Mon, 24 Aug 2009 02:48:50 +0000 Subject: [PATCH] microVU: - Started implementing VU macro mode (code off by default) - Disabled Constant Propagation for Jump Addresses (this rarely was a speedup, and it slowed down recompilation time a lot in some games causing bad slowdowns (GoW)) git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1675 96395faa-99c1-11dd-bbfe-3dabce05a288 --- common/include/Pcsx2Config.h | 1 + pcsx2/windows/VCprojects/pcsx2_2008.vcproj | 4 + pcsx2/x86/iCOP2.cpp | 131 ++-- pcsx2/x86/microVU.h | 1 + pcsx2/x86/microVU_Macro.inl | 671 +++++++++++++++++++++ pcsx2/x86/microVU_Misc.h | 2 +- 6 files changed, 719 insertions(+), 91 deletions(-) create mode 100644 pcsx2/x86/microVU_Macro.inl diff --git a/common/include/Pcsx2Config.h b/common/include/Pcsx2Config.h index 01be808273..ce8b9b2c12 100644 --- a/common/include/Pcsx2Config.h +++ b/common/include/Pcsx2Config.h @@ -61,6 +61,7 @@ extern SessionOverrideFlags g_Session; #define CHECK_MULTIGS (Config.Options&PCSX2_GSMULTITHREAD) #define CHECK_MICROVU0 (Config.Options&PCSX2_MICROVU0) #define CHECK_MICROVU1 (Config.Options&PCSX2_MICROVU1) +//#define CHECK_MACROVU0 // ifndef = Use sVU for VU macro, ifdef = Use mVU for VU macro #define CHECK_EEREC (!g_Session.ForceDisableEErec && Config.Options&PCSX2_EEREC) #define CHECK_VU0REC (!g_Session.ForceDisableVU0rec && Config.Options&PCSX2_VU0REC) #define CHECK_VU1REC (!g_Session.ForceDisableVU1rec && (Config.Options&PCSX2_VU1REC)) diff --git a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj index d81c52aefe..38689a0bb0 100644 --- a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj +++ b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj @@ -2104,6 +2104,10 @@ RelativePath="..\..\x86\microVU_Lower.inl" > + + diff --git a/pcsx2/x86/iCOP2.cpp b/pcsx2/x86/iCOP2.cpp index dabe4440f6..654f315c15 100644 --- a/pcsx2/x86/iCOP2.cpp +++ b/pcsx2/x86/iCOP2.cpp @@ -31,6 +31,8 @@ extern void _vu0WaitMicro(); +#ifndef CHECK_MACROVU0 + #define _Ft_ _Rt_ #define _Fs_ _Rd_ #define _Fd_ _Sa_ @@ -39,60 +41,36 @@ extern void _vu0WaitMicro(); #define _Ftf_ ((cpuRegs.code >> 23) & 0x03) #define _Cc_ (cpuRegs.code & 0x03) -void recCop2BranchCall( void (*func)() ) -{ - SetFPUstate(); - recBranchCall( func ); - _freeX86regs(); -} - -#define REC_COP2_FUNC( f ) \ - void rec##f(s32 info) \ - { \ - Console::Notice("Warning > cop2 "#f" called"); \ - recCop2BranchCall( f ); \ +#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(); \ -} - -#define REC_COP2_VU0(f) \ -void recV##f( s32 info ) { \ - recVUMI_##f( &VU0, info ); \ -} - -#define REC_COP2_VU0_Q(f) \ -void recV##f( s32 info ) { \ - recVUMI_##f( &VU0, info ); \ -} - -void rec_C2UNK( s32 info ) -{ - Console::Error("Cop2 bad opcode: %x", params cpuRegs.code); -} - -void _vuRegs_C2UNK(VURegs * VU, _VURegsNum *VUregsn) -{ - Console::Error("Cop2 bad _vuRegs code:%x", params cpuRegs.code); +#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", params cpuRegs.code); +} +void _vuRegs_C2UNK(VURegs * VU, _VURegsNum *VUregsn) { + Console::Error("Cop2 bad _vuRegs code:%x", params cpuRegs.code); +} + static void recCFC2(s32 info) { int mmreg; - if (cpuRegs.code & 1) - { + if (cpuRegs.code & 1) { iFlushCall(FLUSH_NOCONST); CALLFunc((uptr)_vu0WaitMicro); } @@ -102,48 +80,30 @@ static void recCFC2(s32 info) _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 - { + 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 - { + else { MOV32MtoR(EAX, (uptr)&VU0.VI[ _Fs_ ].UL); MOV32RtoM((uptr)&cpuRegs.GPR.r[_Rt_].UL[0],EAX); - if(EEINST_ISLIVE1(_Rt_)) - { - if( _Fs_ < 16 ) - { + if(EEINST_ISLIVE1(_Rt_)) { + if( _Fs_ < 16 ) { // no sign extending MOV32ItoM((uptr)&cpuRegs.GPR.r[_Rt_].UL[1],0); } - else - { + else { CDQ(); MOV32RtoM((uptr)&cpuRegs.GPR.r[_Rt_].UL[1], EDX); } } - else - { - EEINST_RESETHASLIVE1(_Rt_); - } + else { EEINST_RESETHASLIVE1(_Rt_); } } _eeOnWriteReg(_Rt_, 1); @@ -253,8 +213,7 @@ static void recQMFC2(s32 info) { int t0reg, fsreg; - if (cpuRegs.code & 1) - { + if (cpuRegs.code & 1) { iFlushCall(FLUSH_NOCONST); CALLFunc((uptr)_vu0WaitMicro); } @@ -269,8 +228,7 @@ static void recQMFC2(s32 info) fsreg = _checkXMMreg(XMMTYPE_VFREG, _Fs_, MODE_READ); if( fsreg >= 0 ) { - if( xmmregs[fsreg].mode & MODE_WRITE ) - { + if ( xmmregs[fsreg].mode & MODE_WRITE ) { _xmmregs temp; t0reg = _allocGPRtoXMMreg(-1, _Rt_, MODE_WRITE); @@ -281,8 +239,7 @@ static void recQMFC2(s32 info) xmmregs[t0reg] = xmmregs[fsreg]; xmmregs[fsreg] = temp; } - else - { + else { // swap regs t0reg = _allocGPRtoXMMreg(-1, _Rt_, MODE_WRITE); @@ -293,10 +250,8 @@ static void recQMFC2(s32 info) 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]); + 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(); @@ -378,10 +333,6 @@ static void recQMTC2(s32 info) ////////////////////////////////////////////////////////////////////////// // BC2: Instructions ////////////////////////////////////////////////////////////////////////// -//REC_COP2_FUNC(BC2F); -//REC_COP2_FUNC(BC2T); -//REC_COP2_FUNC(BC2FL); -//REC_COP2_FUNC(BC2TL); using namespace R5900::Dynarec; @@ -393,8 +344,7 @@ static void _setupBranchTest() // ((VU0.VI[REG_VPU_STAT].US[0] >> 8) & 1) // BC2F checks if the statement is false, BC2T checks if the statement is true. - MOV32MtoR( EAX, (uptr)&VU0.VI[REG_VPU_STAT].UL ); - TEST32ItoR( EAX, 0x100 ); + TEST32ItoM((uptr)&VU0.VI[REG_VPU_STAT].UL, 0x100); } void recBC2F( s32 info ) @@ -421,10 +371,10 @@ void recBC2TL( s32 info ) recDoBranchImm_Likely(JZ32(0)); } - ////////////////////////////////////////////////////////////////////////// // Special1 instructions ////////////////////////////////////////////////////////////////////////// + //TODO: redirect all the opcodes to the ivu0micro same functions REC_COP2_VU0(IADD); REC_COP2_VU0(IADDI); @@ -551,9 +501,9 @@ REC_COP2_VU0(MULAz); REC_COP2_VU0(MULAw); REC_COP2_VU0(OPMULA); REC_COP2_VU0(MOVE); -REC_COP2_VU0_Q(DIV); -REC_COP2_VU0_Q(SQRT); -REC_COP2_VU0_Q(RSQRT); +REC_COP2_VU0(DIV); +REC_COP2_VU0(SQRT); +REC_COP2_VU0(RSQRT); REC_COP2_VU0(MR32); REC_COP2_VU0(ABS); @@ -718,3 +668,4 @@ void recCOP2_SPECIAL2(s32 info) recCOP2SPECIAL2t[opc](info); } +#endif // CHECK_MACROVU0 \ No newline at end of file diff --git a/pcsx2/x86/microVU.h b/pcsx2/x86/microVU.h index b3231bafbd..f0ee81f400 100644 --- a/pcsx2/x86/microVU.h +++ b/pcsx2/x86/microVU.h @@ -222,3 +222,4 @@ typedef void (__fastcall *mVUrecCall)(u32, u32); #include "microVU_Branch.inl" #include "microVU_Compile.inl" #include "microVU_Execute.inl" +#include "microVU_Macro.inl" diff --git a/pcsx2/x86/microVU_Macro.inl b/pcsx2/x86/microVU_Macro.inl new file mode 100644 index 0000000000..962507f95a --- /dev/null +++ b/pcsx2/x86/microVU_Macro.inl @@ -0,0 +1,671 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifdef CHECK_MACROVU0 + +#pragma once +#include "iR5900.h" +#include "R5900OpcodeTables.h" + +extern void _vu0WaitMicro(); + +//------------------------------------------------------------------ +// Macro VU - Helper Macros +//------------------------------------------------------------------ + +#undef _Ft_ +#undef _Fs_ +#undef _Fd_ +#undef _Fsf_ +#undef _Ftf_ +#undef _Cc_ + +#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", params cpuRegs.code); +} +void _vuRegs_C2UNK(VURegs * VU, _VURegsNum *VUregsn) { + Console::Error("Cop2 bad _vuRegs code:%x", params 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);// since CALLFunc + assert( _checkX86reg(X86TYPE_VI, REG_VPU_STAT, 0) < 0 && + _checkX86reg(X86TYPE_VI, REG_TPC, 0) < 0 ); + // Execute VU1 Micro SubRoutine + _callFunctionArg1((uptr)vu1ExecMicro, MEM_CONSTTAG, g_cpuConstRegs[_Rt_].UL[0]&0xffff); + break; + default: + { + if( _Fs_ < 16 ) + assert( (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]); + //PUSH32I( -1 ); + iFlushCall(FLUSH_NOCONST); + CALLFunc((uptr)CpuVU0.ExecuteBlock); + //CALLFunc((uptr)vu0ExecMicro); + //ADD32ItoR( ESP, 4 ); + 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); + assert( _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 + iFlushCall(FLUSH_NOCONST); + _eeMoveGPRtoR(EAX, _Rt_); + _callFunctionArg1((uptr)vu1ExecMicro, MEM_X86TAG|EAX, 0); // Execute VU1 Micro SubRoutine + 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_ ) ) { + assert( _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(); +} + + +//------------------------------------------------------------------ +// Macro VU - Instructions +//------------------------------------------------------------------ + +using namespace R5900::Dynarec; + +void printCOP2(const char* text) { + Console::Status(text); +} + +//------------------------------------------------------------------ +// Macro VU - Branches +//------------------------------------------------------------------ + +static void _setupBranchTest() { + _eeFlushAllUnused(); + TEST32ItoM((uptr)&VU0.VI[REG_VPU_STAT].UL, 0x100); + printCOP2("_setupBranchTest()"); +} + +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)); +} + +#define REC_COP2_mVU0(f, opName) \ +void recV##f(s32 info) { \ + microVU0.prog.IRinfo.curPC = 0; \ + microVU0.code = cpuRegs.code; \ + memset(µVU0.prog.IRinfo.info[0], 0, sizeof(microVU0.prog.IRinfo.info[0])); \ + iFlushCall(FLUSH_EVERYTHING); \ + microVU0.regAlloc->reset(); \ + /*mVU_##f(µVU0, 0);*/ \ + mVU_##f(µVU0, 1); \ + microVU0.regAlloc->flushAll(); \ + printCOP2(opName); \ +} + +//------------------------------------------------------------------ +// Macro VU - Redirect Upper Instructions +//------------------------------------------------------------------ + +REC_COP2_mVU0(ABS, "ABS"); +REC_COP2_mVU0(ITOF0, "ITOF0"); +REC_COP2_mVU0(ITOF4, "ITOF4"); +REC_COP2_mVU0(ITOF12, "ITOF12"); +REC_COP2_mVU0(ITOF15, "ITOF15"); +REC_COP2_mVU0(FTOI0, "FTOI0"); +REC_COP2_mVU0(FTOI4, "FTOI4"); +REC_COP2_mVU0(FTOI12, "FTOI12"); +REC_COP2_mVU0(FTOI15, "FTOI15"); +REC_COP2_mVU0(ADD, "ADD"); +REC_COP2_mVU0(ADDi, "ADDi"); +REC_COP2_VU0 (ADDq); +REC_COP2_mVU0(ADDx, "ADDx"); +REC_COP2_mVU0(ADDy, "ADDy"); +REC_COP2_mVU0(ADDz, "ADDz"); +REC_COP2_mVU0(ADDw, "ADDw"); +REC_COP2_mVU0(ADDA, "ADDA"); +REC_COP2_mVU0(ADDAi, "ADDAi"); +REC_COP2_VU0 (ADDAq); +REC_COP2_mVU0(ADDAx, "ADDAx"); +REC_COP2_mVU0(ADDAy, "ADDAy"); +REC_COP2_mVU0(ADDAz, "ADDAz"); +REC_COP2_mVU0(ADDAw, "ADDAw"); +REC_COP2_mVU0(SUB, "SUB"); +REC_COP2_mVU0(SUBi, "SUBi"); +REC_COP2_VU0 (SUBq); +REC_COP2_mVU0(SUBx, "SUBx"); +REC_COP2_mVU0(SUBy, "SUBy"); +REC_COP2_mVU0(SUBz, "SUBz"); +REC_COP2_mVU0(SUBw, "SUBw"); +REC_COP2_mVU0(SUBA, "SUBA"); +REC_COP2_mVU0(SUBAi, "SUBAi"); +REC_COP2_VU0 (SUBAq); +REC_COP2_mVU0(SUBAx, "SUBAx"); +REC_COP2_mVU0(SUBAy, "SUBAy"); +REC_COP2_mVU0(SUBAz, "SUBAz"); +REC_COP2_mVU0(SUBAw, "SUBAw"); +REC_COP2_mVU0(MUL, "MUL"); +REC_COP2_mVU0(MULi, "MULi"); +REC_COP2_VU0 (MULq); +REC_COP2_mVU0(MULx, "MULx"); +REC_COP2_mVU0(MULy, "MULy"); +REC_COP2_mVU0(MULz, "MULz"); +REC_COP2_mVU0(MULw, "MULw"); +REC_COP2_mVU0(MULA, "MULA"); +REC_COP2_mVU0(MULAi, "MULAi"); +REC_COP2_VU0 (MULAq); +REC_COP2_mVU0(MULAx, "MULAx"); +REC_COP2_mVU0(MULAy, "MULAy"); +REC_COP2_mVU0(MULAz, "MULAz"); +REC_COP2_mVU0(MULAw, "MULAw"); +REC_COP2_mVU0(MAX, "MAX"); +REC_COP2_mVU0(MAXi, "MAXi"); +REC_COP2_mVU0(MAXx, "MAXx"); +REC_COP2_mVU0(MAXy, "MAXy"); +REC_COP2_mVU0(MAXz, "MAXz"); +REC_COP2_mVU0(MAXw, "MAXw"); +REC_COP2_mVU0(MINI, "MINI"); +REC_COP2_mVU0(MINIi, "MINIi"); +REC_COP2_mVU0(MINIx, "MINIx"); +REC_COP2_mVU0(MINIy, "MINIy"); +REC_COP2_mVU0(MINIz, "MINIz"); +REC_COP2_mVU0(MINIw, "MINIw"); +REC_COP2_mVU0(MADD, "MADD"); +REC_COP2_mVU0(MADDi, "MADDi"); +REC_COP2_VU0 (MADDq); +REC_COP2_mVU0(MADDx, "MADDx"); +REC_COP2_mVU0(MADDy, "MADDy"); +REC_COP2_mVU0(MADDz, "MADDz"); +REC_COP2_mVU0(MADDw, "MADDw"); +REC_COP2_mVU0(MADDA, "MADDA"); +REC_COP2_mVU0(MADDAi, "MADDAi"); +REC_COP2_VU0 (MADDAq); +REC_COP2_mVU0(MADDAx, "MADDAx"); +REC_COP2_mVU0(MADDAy, "MADDAy"); +REC_COP2_mVU0(MADDAz, "MADDAz"); +REC_COP2_mVU0(MADDAw, "MADDAw"); +REC_COP2_mVU0(MSUB, "MSUB"); +REC_COP2_mVU0(MSUBi, "MSUBi"); +REC_COP2_VU0 (MSUBq); +REC_COP2_mVU0(MSUBx, "MSUBx"); +REC_COP2_mVU0(MSUBy, "MSUBy"); +REC_COP2_mVU0(MSUBz, "MSUBz"); +REC_COP2_mVU0(MSUBw, "MSUBw"); +REC_COP2_mVU0(MSUBA, "MSUBA"); +REC_COP2_mVU0(MSUBAi, "MSUBAi"); +REC_COP2_VU0 (MSUBAq); +REC_COP2_mVU0(MSUBAx, "MSUBAx"); +REC_COP2_mVU0(MSUBAy, "MSUBAy"); +REC_COP2_mVU0(MSUBAz, "MSUBAz"); +REC_COP2_mVU0(MSUBAw, "MSUBAw"); +REC_COP2_mVU0(OPMULA, "OPMULA"); +REC_COP2_mVU0(OPMSUB, "OPMSUB"); +REC_COP2_VU0 (CLIP); + +//------------------------------------------------------------------ +// Macro VU - Redirect Lower Instructions +//------------------------------------------------------------------ + +REC_COP2_VU0(DIV); +REC_COP2_VU0(SQRT); +REC_COP2_VU0(RSQRT); +REC_COP2_VU0(IADD); +REC_COP2_VU0(IADDI); +REC_COP2_VU0(IAND); +REC_COP2_VU0(IOR); +REC_COP2_VU0(ISUB); +REC_COP2_VU0(ILWR); +REC_COP2_VU0(ISWR); +REC_COP2_VU0(LQI); +REC_COP2_VU0(LQD); +REC_COP2_VU0(SQI); +REC_COP2_VU0(SQD); +REC_COP2_VU0(MOVE); +REC_COP2_VU0(MFIR); +REC_COP2_VU0(MTIR); +REC_COP2_VU0(MR32); +REC_COP2_VU0(RINIT); +REC_COP2_VU0(RGET); +REC_COP2_VU0(RNEXT); +REC_COP2_VU0(RXOR); +/* +REC_COP2_mVU0(IADD, "IADD"); +REC_COP2_mVU0(IADDI, "IADDI"); +REC_COP2_mVU0(IAND, "IAND"); +REC_COP2_mVU0(IOR, "IOR"); +REC_COP2_mVU0(ISUB, "ISUB"); +REC_COP2_mVU0(ILWR, "ILWR"); +REC_COP2_mVU0(ISWR, "ISWR"); +REC_COP2_mVU0(LQI, "LQI"); +REC_COP2_mVU0(LQD, "LQD"); +REC_COP2_mVU0(SQI, "SQI"); +REC_COP2_mVU0(SQD, "SQD"); +REC_COP2_mVU0(MOVE, "MOVE"); +REC_COP2_mVU0(MFIR, "MFIR"); +REC_COP2_mVU0(MTIR, "MTIR"); +REC_COP2_mVU0(MR32, "MR32"); +REC_COP2_mVU0(RINIT, "RINIT"); +REC_COP2_mVU0(RGET, "RGET"); +REC_COP2_mVU0(RNEXT, "RNEXT"); +REC_COP2_mVU0(RXOR, "RXOR"); +*/ + +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, +}; + +#define cParams VURegs* VU, _VURegsNum* VUregsn +void _vuRegsCOP22(cParams) { _vuRegsCOP2t[_Rs_](VU, VUregsn); } +void _vuRegsCOP2_SPECIAL (cParams) { _vuRegsCOP2SPECIAL1t[_Funct_](VU, VUregsn); } +void _vuRegsCOP2_SPECIAL2(cParams) { _vuRegsCOP2SPECIAL2t[(cpuRegs.code&3)|((cpuRegs.code>>4)&0x7c)](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_BC2(s32 info) { recCOP2_BC2t[_Rt_](info); } +void recCOP2_SPECIAL(s32 info) { recCOP2SPECIAL1t[_Funct_]( info ); } +void recCOP2_SPECIAL2(s32 info) { recCOP2SPECIAL2t[(cpuRegs.code&3)|((cpuRegs.code>>4)&0x7c)](info); } + +#endif // CHECK_MACROVU0 diff --git a/pcsx2/x86/microVU_Misc.h b/pcsx2/x86/microVU_Misc.h index 943954a4ed..1c203e10dc 100644 --- a/pcsx2/x86/microVU_Misc.h +++ b/pcsx2/x86/microVU_Misc.h @@ -263,7 +263,7 @@ typedef u32 (__fastcall *mVUCall)(void*, void*); #define doRegAlloc 1 // Set to 0 to flush every 64bit Instruction (Turns off regAlloc) // Speed Hacks -#define CHECK_VU_CONSTHACK 0 // Only use for GoW (will be slower on other games) +#define CHECK_VU_CONSTHACK 1 // Disables Constant Propagation for Jumps #define CHECK_VU_FLAGHACK (u32)Config.Hacks.vuFlagHack // (Can cause Infinite loops, SPS, etc...) #define CHECK_VU_MINMAXHACK (u32)Config.Hacks.vuMinMax // (Can cause SPS, Black Screens, etc...)