mirror of https://github.com/PCSX2/pcsx2.git
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
This commit is contained in:
parent
3734a30c55
commit
a3f0ba5315
|
@ -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))
|
||||
|
|
|
@ -2104,6 +2104,10 @@
|
|||
RelativePath="..\..\x86\microVU_Lower.inl"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\x86\microVU_Macro.inl"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\x86\microVU_Misc.h"
|
||||
>
|
||||
|
|
|
@ -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
|
|
@ -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"
|
||||
|
|
|
@ -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
|
|
@ -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...)
|
||||
|
||||
|
|
Loading…
Reference in New Issue