mirror of https://github.com/PCSX2/pcsx2.git
mVU Macro: Implemented more stuff and did a big cleanup.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1707 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
4d7bfbb86e
commit
2c1397e559
|
@ -87,11 +87,13 @@ microVUt(void) mVUallocMFLAGb(mV, int reg, int fInstance) {
|
||||||
}
|
}
|
||||||
|
|
||||||
microVUt(void) mVUallocCFLAGa(mV, int reg, int fInstance) {
|
microVUt(void) mVUallocCFLAGa(mV, int reg, int fInstance) {
|
||||||
MOV32MtoR(reg, (uptr)&mVU->clipFlag[fInstance]);
|
if (fInstance < 4) MOV32MtoR(reg, (uptr)&mVU->clipFlag[fInstance]); // microVU
|
||||||
|
else MOV32MtoR(reg, (uptr)&mVU->regs->VI[REG_CLIP_FLAG].UL); // macroVU
|
||||||
}
|
}
|
||||||
|
|
||||||
microVUt(void) mVUallocCFLAGb(mV, int reg, int fInstance) {
|
microVUt(void) mVUallocCFLAGb(mV, int reg, int fInstance) {
|
||||||
MOV32RtoM((uptr)&mVU->clipFlag[fInstance], reg);
|
if (fInstance < 4) MOV32RtoM((uptr)&mVU->clipFlag[fInstance], reg); // microVU
|
||||||
|
else MOV32RtoM((uptr)&mVU->regs->VI[REG_CLIP_FLAG].UL, reg); // macroVU
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
|
|
|
@ -25,319 +25,16 @@
|
||||||
extern void _vu0WaitMicro();
|
extern void _vu0WaitMicro();
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
// Macro VU - Helper Macros
|
// Macro VU - Helper Macros / Functions
|
||||||
//------------------------------------------------------------------
|
|
||||||
|
|
||||||
#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;
|
using namespace R5900::Dynarec;
|
||||||
|
|
||||||
|
#define printCOP2 0&&
|
||||||
|
//#define printCOP2 DevCon::Status
|
||||||
|
|
||||||
void setupMacroOp(int mode, const char* opName) {
|
void setupMacroOp(int mode, const char* opName) {
|
||||||
DevCon::Status(opName);
|
printCOP2(opName);
|
||||||
microVU0.prog.IRinfo.curPC = 0;
|
microVU0.prog.IRinfo.curPC = 0;
|
||||||
microVU0.code = cpuRegs.code;
|
microVU0.code = cpuRegs.code;
|
||||||
memset(µVU0.prog.IRinfo.info[0], 0, sizeof(microVU0.prog.IRinfo.info[0]));
|
memset(µVU0.prog.IRinfo.info[0], 0, sizeof(microVU0.prog.IRinfo.info[0]));
|
||||||
|
@ -346,6 +43,10 @@ void setupMacroOp(int mode, const char* opName) {
|
||||||
if (mode & 1) { // Q-Reg will be Read
|
if (mode & 1) { // Q-Reg will be Read
|
||||||
SSE_MOVSS_M32_to_XMM(xmmPQ, (uptr)µVU0.regs->VI[REG_Q].UL);
|
SSE_MOVSS_M32_to_XMM(xmmPQ, (uptr)µVU0.regs->VI[REG_Q].UL);
|
||||||
}
|
}
|
||||||
|
if (mode & 8) { // Clip Instruction
|
||||||
|
microVU0.prog.IRinfo.info[0].cFlag.write = 0xff;
|
||||||
|
microVU0.prog.IRinfo.info[0].cFlag.lastWrite = 0xff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void endMacroOp(int mode) {
|
void endMacroOp(int mode) {
|
||||||
|
@ -356,7 +57,7 @@ void endMacroOp(int mode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#define REC_COP2_mVU0(f, opName, mode) \
|
#define REC_COP2_mVU0(f, opName, mode) \
|
||||||
void recV##f(s32 info) { \
|
void recV##f() { \
|
||||||
setupMacroOp(mode, opName); \
|
setupMacroOp(mode, opName); \
|
||||||
if (mode & 4) { \
|
if (mode & 4) { \
|
||||||
mVU_##f(µVU0, 0); \
|
mVU_##f(µVU0, 0); \
|
||||||
|
@ -368,6 +69,19 @@ void endMacroOp(int mode) {
|
||||||
endMacroOp(mode); \
|
endMacroOp(mode); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define INTERPRETATE_COP2_FUNC(f) \
|
||||||
|
void recV##f() { \
|
||||||
|
MOV32ItoM((uptr)&cpuRegs.code, cpuRegs.code); \
|
||||||
|
MOV32ItoM((uptr)&cpuRegs.pc, pc); \
|
||||||
|
iFlushCall(FLUSH_EVERYTHING); \
|
||||||
|
CALLFunc((uptr)V##f); \
|
||||||
|
_freeX86regs(); \
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
// Macro VU - Instructions
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
// Macro VU - Redirect Upper Instructions
|
// Macro VU - Redirect Upper Instructions
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
|
@ -465,7 +179,7 @@ REC_COP2_mVU0(MSUBAz, "MSUBAz", 0);
|
||||||
REC_COP2_mVU0(MSUBAw, "MSUBAw", 0);
|
REC_COP2_mVU0(MSUBAw, "MSUBAw", 0);
|
||||||
REC_COP2_mVU0(OPMULA, "OPMULA", 0);
|
REC_COP2_mVU0(OPMULA, "OPMULA", 0);
|
||||||
REC_COP2_mVU0(OPMSUB, "OPMSUB", 0);
|
REC_COP2_mVU0(OPMSUB, "OPMSUB", 0);
|
||||||
REC_COP2_VU0 (CLIP);
|
REC_COP2_mVU0(CLIP, "CLIP", 8);
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
// Macro VU - Redirect Lower Instructions
|
// Macro VU - Redirect Lower Instructions
|
||||||
|
@ -498,8 +212,8 @@ REC_COP2_mVU0(RXOR, "RXOR", 0);
|
||||||
// Macro VU - Misc...
|
// Macro VU - Misc...
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
|
|
||||||
void recVNOP (s32 info) {}
|
void recVNOP() {}
|
||||||
void recVWAITQ(s32 info) {}
|
void recVWAITQ(){}
|
||||||
INTERPRETATE_COP2_FUNC(CALLMS);
|
INTERPRETATE_COP2_FUNC(CALLMS);
|
||||||
INTERPRETATE_COP2_FUNC(CALLMSR);
|
INTERPRETATE_COP2_FUNC(CALLMSR);
|
||||||
|
|
||||||
|
@ -507,115 +221,156 @@ INTERPRETATE_COP2_FUNC(CALLMSR);
|
||||||
// Macro VU - Branches
|
// Macro VU - Branches
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
|
|
||||||
static void _setupBranchTest() {
|
void _setupBranchTest(u32*(jmpType)(u32), bool isLikely) {
|
||||||
|
printCOP2("COP2 Branch");
|
||||||
_eeFlushAllUnused();
|
_eeFlushAllUnused();
|
||||||
TEST32ItoM((uptr)&VU0.VI[REG_VPU_STAT].UL, 0x100);
|
TEST32ItoM((uptr)&VU0.VI[REG_VPU_STAT].UL, 0x100);
|
||||||
|
recDoBranchImm(jmpType(0), isLikely);
|
||||||
}
|
}
|
||||||
|
|
||||||
void recBC2F(s32 info) {
|
void recBC2F() { _setupBranchTest(JNZ32, false); }
|
||||||
_setupBranchTest();
|
void recBC2T() { _setupBranchTest(JZ32, false); }
|
||||||
recDoBranchImm(JNZ32(0));
|
void recBC2FL() { _setupBranchTest(JNZ32, true); }
|
||||||
|
void recBC2TL() { _setupBranchTest(JZ32, true); }
|
||||||
|
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
// Macro VU - COP2 Transfer Instructions
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
|
||||||
|
void COP2_Interlock(bool cond) {
|
||||||
|
if (cond) {
|
||||||
|
iFlushCall(FLUSH_NOCONST);
|
||||||
|
CALLFunc((uptr)_vu0WaitMicro);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void recBC2T(s32 info) {
|
void TEST_FBRST_RESET(uptr resetFunct, int vuIndex) {
|
||||||
_setupBranchTest();
|
TEST32ItoR(EAX, (vuIndex) ? 0x200 : 0x002);
|
||||||
recDoBranchImm(JZ32(0));
|
j8Ptr[0] = JZ8(0);
|
||||||
|
CALLFunc(resetFunct);
|
||||||
|
MOV32MtoR(EAX, (uptr)&cpuRegs.GPR.r[_Rt_].UL[0]);
|
||||||
|
x86SetJ8(j8Ptr[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void recBC2FL(s32 info) {
|
static void recCFC2() {
|
||||||
_setupBranchTest();
|
|
||||||
recDoBranchImm_Likely(JNZ32(0));
|
printCOP2("CFC2");
|
||||||
|
COP2_Interlock(cpuRegs.code & 1);
|
||||||
|
if (!_Rt_) return;
|
||||||
|
iFlushCall(FLUSH_EVERYTHING);
|
||||||
|
|
||||||
|
MOV32MtoR(EAX, (uptr)µVU0.regs->VI[_Rd_].UL);
|
||||||
|
MOV32RtoM((uptr)&cpuRegs.GPR.r[_Rt_].UL[0], EAX);
|
||||||
|
|
||||||
|
if( _Rd_ >= 16 ) {
|
||||||
|
CDQ(); // Sign Extend
|
||||||
|
MOV32RtoM ((uptr)&cpuRegs.GPR.r[_Rt_].UL[1], EDX);
|
||||||
|
}
|
||||||
|
else MOV32ItoM((uptr)&cpuRegs.GPR.r[_Rt_].UL[1], 0);
|
||||||
|
|
||||||
|
// FixMe: I think this is needed, but not sure how it works
|
||||||
|
_eeOnWriteReg(_Rt_, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void recBC2TL(s32 info) {
|
static void recCTC2() {
|
||||||
_setupBranchTest();
|
|
||||||
recDoBranchImm_Likely(JZ32(0));
|
printCOP2("CTC2");
|
||||||
|
COP2_Interlock(cpuRegs.code & 1);
|
||||||
|
if (!_Rd_) return;
|
||||||
|
iFlushCall(FLUSH_EVERYTHING);
|
||||||
|
|
||||||
|
switch(_Rd_) {
|
||||||
|
case REG_MAC_FLAG: case REG_TPC:
|
||||||
|
case REG_VPU_STAT: break; // Read Only Regs
|
||||||
|
case REG_R:
|
||||||
|
MOV32MtoR(EAX, (uptr)&cpuRegs.GPR.r[_Rt_].UL[0]);
|
||||||
|
OR32ItoR (EAX, 0x3f800000);
|
||||||
|
MOV32RtoM((uptr)µVU0.regs->VI[REG_R].UL, EAX);
|
||||||
|
break;
|
||||||
|
case REG_CMSAR1: // REG_CMSAR1
|
||||||
|
if (_Rt_) {
|
||||||
|
MOV32MtoR(EAX, (uptr)&cpuRegs.GPR.r[_Rt_].UL[0]);
|
||||||
|
PUSH32R(EAX);
|
||||||
|
}
|
||||||
|
else PUSH32I(0);
|
||||||
|
CALLFunc((uptr)vu1ExecMicro); // Execute VU1 Micro SubRoutine
|
||||||
|
ADD32ItoR(ESP, 4);
|
||||||
|
break;
|
||||||
|
case REG_FBRST:
|
||||||
|
if (!_Rt_) {
|
||||||
|
MOV32ItoM((uptr)µVU0.regs->VI[REG_FBRST].UL, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else MOV32MtoR(EAX, (uptr)&cpuRegs.GPR.r[_Rt_].UL[0]);
|
||||||
|
|
||||||
|
TEST_FBRST_RESET((uptr)vu0ResetRegs, 0);
|
||||||
|
TEST_FBRST_RESET((uptr)vu1ResetRegs, 1);
|
||||||
|
|
||||||
|
AND32ItoR(EAX, 0x0C0C);
|
||||||
|
MOV32RtoM((uptr)µVU0.regs->VI[REG_FBRST].UL, EAX);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_eeMoveGPRtoM((uptr)µVU0.regs->VI[_Rd_].UL, _Rt_);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void recQMFC2() {
|
||||||
|
|
||||||
|
printCOP2("QMFC2");
|
||||||
|
COP2_Interlock(cpuRegs.code & 1);
|
||||||
|
if (!_Rt_) return;
|
||||||
|
iFlushCall(FLUSH_EVERYTHING);
|
||||||
|
|
||||||
|
// FixMe: For some reason this line is needed or else games break:
|
||||||
|
_eeOnWriteReg(_Rt_, 0);
|
||||||
|
|
||||||
|
SSE_MOVAPS_M128_to_XMM(xmmT1, (uptr)µVU0.regs->VF[_Rd_].UL[0]);
|
||||||
|
SSE_MOVAPS_XMM_to_M128((uptr)&cpuRegs.GPR.r[_Rt_].UL[0], xmmT1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void recQMTC2() {
|
||||||
|
|
||||||
|
printCOP2("QMTC2");
|
||||||
|
COP2_Interlock(cpuRegs.code & 1);
|
||||||
|
if (!_Rd_) return;
|
||||||
|
iFlushCall(FLUSH_EVERYTHING);
|
||||||
|
|
||||||
|
SSE_MOVAPS_M128_to_XMM(xmmT1, (uptr)&cpuRegs.GPR.r[_Rt_].UL[0]);
|
||||||
|
SSE_MOVAPS_XMM_to_M128((uptr)µVU0.regs->VF[_Rd_].UL[0], xmmT1);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
// Macro VU - Tables
|
// Macro VU - Tables
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
|
|
||||||
void _vuRegsCOP2_SPECIAL (VURegs * VU, _VURegsNum *VUregsn);
|
void recCOP2();
|
||||||
void _vuRegsCOP2_SPECIAL2(VURegs * VU, _VURegsNum *VUregsn);
|
void recCOP2_BC2();
|
||||||
|
void recCOP2_SPEC1();
|
||||||
// information
|
void recCOP2_SPEC2();
|
||||||
void _vuRegsQMFC2(VURegs * VU, _VURegsNum *VUregsn) {
|
void rec_C2UNK() {
|
||||||
VUregsn->VFread0 = _Fs_;
|
Console::Error("Cop2 bad opcode: %x", params cpuRegs.code);
|
||||||
VUregsn->VFr0xyzw= 0xf;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _vuRegsCFC2(VURegs * VU, _VURegsNum *VUregsn) {
|
// This is called by EE Recs to setup sVU info, this isn't needed for mVU Macro (cottonvibes)
|
||||||
VUregsn->VIread = 1<<_Fs_;
|
void _vuRegsCOP22(VURegs* VU, _VURegsNum* VUregsn) {}
|
||||||
}
|
|
||||||
|
|
||||||
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
|
// Recompilation
|
||||||
void (*recCOP2t[32])(s32 info) = {
|
void (*recCOP2t[32])() = {
|
||||||
rec_C2UNK, recQMFC2, recCFC2, rec_C2UNK, rec_C2UNK, recQMTC2, recCTC2, rec_C2UNK,
|
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_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_SPEC1, recCOP2_SPEC1, recCOP2_SPEC1, recCOP2_SPEC1, recCOP2_SPEC1, recCOP2_SPEC1, recCOP2_SPEC1, recCOP2_SPEC1,
|
||||||
recCOP2_SPECIAL,recCOP2_SPECIAL,recCOP2_SPECIAL,recCOP2_SPECIAL,recCOP2_SPECIAL,recCOP2_SPECIAL,recCOP2_SPECIAL,recCOP2_SPECIAL,
|
recCOP2_SPEC1, recCOP2_SPEC1, recCOP2_SPEC1, recCOP2_SPEC1, recCOP2_SPEC1, recCOP2_SPEC1, recCOP2_SPEC1, recCOP2_SPEC1,
|
||||||
};
|
};
|
||||||
|
|
||||||
void (*recCOP2_BC2t[32])(s32 info) = {
|
void (*recCOP2_BC2t[32])() = {
|
||||||
recBC2F, recBC2T, recBC2FL, recBC2TL, rec_C2UNK, rec_C2UNK, rec_C2UNK, rec_C2UNK,
|
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,
|
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) = {
|
void (*recCOP2SPECIAL1t[64])() = {
|
||||||
recVADDx, recVADDy, recVADDz, recVADDw, recVSUBx, recVSUBy, recVSUBz, recVSUBw,
|
recVADDx, recVADDy, recVADDz, recVADDw, recVSUBx, recVSUBy, recVSUBz, recVSUBw,
|
||||||
recVMADDx, recVMADDy, recVMADDz, recVMADDw, recVMSUBx, recVMSUBy, recVMSUBz, recVMSUBw,
|
recVMADDx, recVMADDy, recVMADDz, recVMADDw, recVMSUBx, recVMSUBy, recVMSUBz, recVMSUBw,
|
||||||
recVMAXx, recVMAXy, recVMAXz, recVMAXw, recVMINIx, recVMINIy, recVMINIz, recVMINIw,
|
recVMAXx, recVMAXy, recVMAXz, recVMAXw, recVMINIx, recVMINIy, recVMINIz, recVMINIw,
|
||||||
|
@ -623,50 +378,33 @@ void (*recCOP2SPECIAL1t[64])(s32 info) = {
|
||||||
recVADDq, recVMADDq, recVADDi, recVMADDi, recVSUBq, recVMSUBq, recVSUBi, recVMSUBi,
|
recVADDq, recVMADDq, recVADDi, recVMADDi, recVSUBq, recVMSUBq, recVSUBi, recVMSUBi,
|
||||||
recVADD, recVMADD, recVMUL, recVMAX, recVSUB, recVMSUB, recVOPMSUB, recVMINI,
|
recVADD, recVMADD, recVMUL, recVMAX, recVSUB, recVMSUB, recVOPMSUB, recVMINI,
|
||||||
recVIADD, recVISUB, recVIADDI, rec_C2UNK, recVIAND, recVIOR, rec_C2UNK, rec_C2UNK,
|
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,
|
recVCALLMS, recVCALLMSR,rec_C2UNK, rec_C2UNK, recCOP2_SPEC2, recCOP2_SPEC2, recCOP2_SPEC2, recCOP2_SPEC2,
|
||||||
};
|
};
|
||||||
|
|
||||||
void (*recCOP2SPECIAL2t[128])(s32 info) = {
|
void (*recCOP2SPECIAL2t[128])() = {
|
||||||
recVADDAx ,recVADDAy ,recVADDAz ,recVADDAw ,recVSUBAx ,recVSUBAy ,recVSUBAz ,recVSUBAw,
|
recVADDAx, recVADDAy, recVADDAz, recVADDAw, recVSUBAx, recVSUBAy, recVSUBAz, recVSUBAw,
|
||||||
recVMADDAx ,recVMADDAy ,recVMADDAz ,recVMADDAw ,recVMSUBAx ,recVMSUBAy ,recVMSUBAz ,recVMSUBAw,
|
recVMADDAx,recVMADDAy, recVMADDAz, recVMADDAw, recVMSUBAx, recVMSUBAy, recVMSUBAz, recVMSUBAw,
|
||||||
recVITOF0 ,recVITOF4 ,recVITOF12 ,recVITOF15 ,recVFTOI0 ,recVFTOI4 ,recVFTOI12 ,recVFTOI15,
|
recVITOF0, recVITOF4, recVITOF12, recVITOF15, recVFTOI0, recVFTOI4, recVFTOI12, recVFTOI15,
|
||||||
recVMULAx ,recVMULAy ,recVMULAz ,recVMULAw ,recVMULAq ,recVABS ,recVMULAi ,recVCLIP,
|
recVMULAx, recVMULAy, recVMULAz, recVMULAw, recVMULAq, recVABS, recVMULAi, recVCLIP,
|
||||||
recVADDAq ,recVMADDAq ,recVADDAi ,recVMADDAi ,recVSUBAq ,recVMSUBAq ,recVSUBAi ,recVMSUBAi,
|
recVADDAq, recVMADDAq, recVADDAi, recVMADDAi, recVSUBAq, recVMSUBAq, recVSUBAi, recVMSUBAi,
|
||||||
recVADDA ,recVMADDA ,recVMULA ,rec_C2UNK ,recVSUBA ,recVMSUBA ,recVOPMULA ,recVNOP,
|
recVADDA, recVMADDA, recVMULA, rec_C2UNK, recVSUBA, recVMSUBA, recVOPMULA, recVNOP,
|
||||||
recVMOVE ,recVMR32 ,rec_C2UNK ,rec_C2UNK ,recVLQI ,recVSQI ,recVLQD ,recVSQD,
|
recVMOVE, recVMR32, rec_C2UNK, rec_C2UNK, recVLQI, recVSQI, recVLQD, recVSQD,
|
||||||
recVDIV ,recVSQRT ,recVRSQRT ,recVWAITQ ,recVMTIR ,recVMFIR ,recVILWR ,recVISWR,
|
recVDIV, recVSQRT, recVRSQRT, recVWAITQ, recVMTIR, recVMFIR, recVILWR, recVISWR,
|
||||||
recVRNEXT ,recVRGET ,recVRINIT ,recVRXOR ,rec_C2UNK ,rec_C2UNK ,rec_C2UNK ,rec_C2UNK,
|
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,
|
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 R5900 {
|
||||||
namespace Dynarec {
|
namespace Dynarec {
|
||||||
namespace OpcodeImpl
|
namespace OpcodeImpl { void recCOP2() { recCOP2t[_Rs_](); }}}}
|
||||||
{
|
void recCOP2_BC2 () { recCOP2_BC2t[_Rt_](); }
|
||||||
void recCOP2()
|
void recCOP2_SPEC1() { recCOP2SPECIAL1t[_Funct_](); }
|
||||||
{
|
void recCOP2_SPEC2() { recCOP2SPECIAL2t[(cpuRegs.code&3)|((cpuRegs.code>>4)&0x7c)](); }
|
||||||
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
|
#endif // CHECK_MACROVU0
|
||||||
|
|
Loading…
Reference in New Issue