Finished mVU macro, and set it on by default.

Basically this means whenever COP2 recs are used, its calling mVU instructions instead of sVU instructions.

Note: Theres a very-minor incompatibility problem when using interpreters/sVU for VU0 with mVU Macro. But I'll fix it later (and it probably doesn't effect much).


git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1710 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
cottonvibes 2009-08-29 23:07:03 +00:00
parent e879890d2a
commit 7c7dfa2f58
5 changed files with 68 additions and 23 deletions

View File

@ -61,7 +61,7 @@ extern SessionOverrideFlags g_Session;
#define CHECK_MULTIGS (Config.Options&PCSX2_GSMULTITHREAD) #define CHECK_MULTIGS (Config.Options&PCSX2_GSMULTITHREAD)
#define CHECK_MICROVU0 (Config.Options&PCSX2_MICROVU0) #define CHECK_MICROVU0 (Config.Options&PCSX2_MICROVU0)
#define CHECK_MICROVU1 (Config.Options&PCSX2_MICROVU1) #define CHECK_MICROVU1 (Config.Options&PCSX2_MICROVU1)
//#define CHECK_MACROVU0 // ifndef = Use sVU for VU macro, ifdef = Use mVU for VU macro #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_EEREC (!g_Session.ForceDisableEErec && Config.Options&PCSX2_EEREC)
#define CHECK_VU0REC (!g_Session.ForceDisableVU0rec && Config.Options&PCSX2_VU0REC) #define CHECK_VU0REC (!g_Session.ForceDisableVU0rec && Config.Options&PCSX2_VU0REC)
#define CHECK_VU1REC (!g_Session.ForceDisableVU1rec && (Config.Options&PCSX2_VU1REC)) #define CHECK_VU1REC (!g_Session.ForceDisableVU1rec && (Config.Options&PCSX2_VU1REC))

View File

@ -77,13 +77,37 @@ microVUt(void) mVUallocSFLAGc(int reg, int regT, int fInstance) {
OR32RtoR(reg, regT); OR32RtoR(reg, regT);
} }
// Denormalizes Status Flag
microVUt(void) mVUallocSFLAGd(uptr memAddr, bool setAllflags) {
MOV32MtoR(gprF0, memAddr);
MOV32RtoR(gprF1, gprF0);
SHR32ItoR(gprF1, 3);
AND32ItoR(gprF1, 0x18);
MOV32RtoR(gprF2, gprF0);
SHL32ItoR(gprF2, 11);
AND32ItoR(gprF2, 0x1800);
OR32RtoR (gprF1, gprF2);
SHL32ItoR(gprF0, 14);
AND32ItoR(gprF0, 0x3cf0000);
OR32RtoR (gprF1, gprF0);
if (setAllflags) {
MOV32RtoR(gprF0, gprF1);
MOV32RtoR(gprF2, gprF1);
MOV32RtoR(gprF3, gprF1);
}
}
microVUt(void) mVUallocMFLAGa(mV, int reg, int fInstance) { microVUt(void) mVUallocMFLAGa(mV, int reg, int fInstance) {
MOVZX32M16toR(reg, (uptr)&mVU->macFlag[fInstance]); MOVZX32M16toR(reg, (uptr)&mVU->macFlag[fInstance]);
} }
microVUt(void) mVUallocMFLAGb(mV, int reg, int fInstance) { microVUt(void) mVUallocMFLAGb(mV, int reg, int fInstance) {
//AND32ItoR(reg, 0xffff); //AND32ItoR(reg, 0xffff);
MOV32RtoM((uptr)&mVU->macFlag[fInstance], reg); if (fInstance < 4) MOV32RtoM((uptr)&mVU->macFlag[fInstance], reg); // microVU
else MOV32RtoM((uptr)&mVU->regs->VI[REG_MAC_FLAG].UL, reg); // macroVU
} }
microVUt(void) mVUallocCFLAGa(mV, int reg, int fInstance) { microVUt(void) mVUallocCFLAGa(mV, int reg, int fInstance) {

View File

@ -59,8 +59,13 @@ microVUt(void) mVUendProgram(mV, microFlagCycles* mFC, int isEbit) {
} }
// Save Flag Instances // Save Flag Instances
#ifdef CHECK_MACROVU0
getFlagReg(fStatus, fStatus);
MOV32RtoM((uptr)&mVU->regs->VI[REG_STATUS_FLAG].UL, fStatus);
#else
mVUallocSFLAGc(gprT1, gprT2, fStatus); mVUallocSFLAGc(gprT1, gprT2, fStatus);
MOV32RtoM((uptr)&mVU->regs->VI[REG_STATUS_FLAG].UL, gprT1); MOV32RtoM((uptr)&mVU->regs->VI[REG_STATUS_FLAG].UL, gprT1);
#endif
mVUallocMFLAGa(mVU, gprT1, fMac); mVUallocMFLAGa(mVU, gprT1, fMac);
mVUallocCFLAGa(mVU, gprT2, fClip); mVUallocCFLAGa(mVU, gprT2, fClip);
MOV32RtoM((uptr)&mVU->regs->VI[REG_MAC_FLAG].UL, gprT1); MOV32RtoM((uptr)&mVU->regs->VI[REG_MAC_FLAG].UL, gprT1);

View File

@ -40,23 +40,14 @@ void mVUdispatcherA(mV) {
SSE_LDMXCSR((uptr)&g_sseVUMXCSR); SSE_LDMXCSR((uptr)&g_sseVUMXCSR);
// Load Regs // Load Regs
#ifdef CHECK_MACROVU0
MOV32MtoR(gprF0, (uptr)&mVU->regs->VI[REG_STATUS_FLAG].UL); MOV32MtoR(gprF0, (uptr)&mVU->regs->VI[REG_STATUS_FLAG].UL);
MOV32RtoR(gprF1, gprF0); MOV32RtoR(gprF1, gprF0);
SHR32ItoR(gprF1, 3);
AND32ItoR(gprF1, 0x18);
MOV32RtoR(gprF2, gprF0); MOV32RtoR(gprF2, gprF0);
SHL32ItoR(gprF2, 11); MOV32RtoR(gprF3, gprF0);
AND32ItoR(gprF2, 0x1800); #else
OR32RtoR (gprF1, gprF2); mVUallocSFLAGd((uptr)&mVU->regs->VI[REG_STATUS_FLAG].UL, 1);
#endif
SHL32ItoR(gprF0, 14);
AND32ItoR(gprF0, 0x3cf0000);
OR32RtoR (gprF1, gprF0);
MOV32RtoR(gprF0, gprF1);
MOV32RtoR(gprF2, gprF1);
MOV32RtoR(gprF3, gprF1);
SSE_MOVAPS_M128_to_XMM(xmmT1, (uptr)&mVU->regs->VI[REG_MAC_FLAG].UL); SSE_MOVAPS_M128_to_XMM(xmmT1, (uptr)&mVU->regs->VI[REG_MAC_FLAG].UL);
SSE_SHUFPS_XMM_to_XMM (xmmT1, xmmT1, 0); SSE_SHUFPS_XMM_to_XMM (xmmT1, xmmT1, 0);

View File

@ -41,19 +41,31 @@ void setupMacroOp(int mode, const char* opName) {
memset(&microVU0.prog.IRinfo.info[0], 0, sizeof(microVU0.prog.IRinfo.info[0])); memset(&microVU0.prog.IRinfo.info[0], 0, sizeof(microVU0.prog.IRinfo.info[0]));
iFlushCall(FLUSH_EVERYTHING); iFlushCall(FLUSH_EVERYTHING);
microVU0.regAlloc->reset(); microVU0.regAlloc->reset();
if (mode & 1) { // Q-Reg will be Read if (mode & 0x01) { // Q-Reg will be Read
SSE_MOVSS_M32_to_XMM(xmmPQ, (uptr)&microVU0.regs->VI[REG_Q].UL); SSE_MOVSS_M32_to_XMM(xmmPQ, (uptr)&microVU0.regs->VI[REG_Q].UL);
} }
if (mode & 8) { // Clip Instruction if (mode & 0x08) { // Clip Instruction
microVU0.prog.IRinfo.info[0].cFlag.write = 0xff; microVU0.prog.IRinfo.info[0].cFlag.write = 0xff;
microVU0.prog.IRinfo.info[0].cFlag.lastWrite = 0xff; microVU0.prog.IRinfo.info[0].cFlag.lastWrite = 0xff;
} }
if (mode & 0x10) { // Update Status/Mac Flags
microVU0.prog.IRinfo.info[0].sFlag.doFlag = 1;
microVU0.prog.IRinfo.info[0].sFlag.doNonSticky = 1;
microVU0.prog.IRinfo.info[0].sFlag.write = 0;
microVU0.prog.IRinfo.info[0].sFlag.lastWrite = 0;
microVU0.prog.IRinfo.info[0].mFlag.doFlag = 1;
microVU0.prog.IRinfo.info[0].mFlag.write = 0xff;
MOV32MtoR(gprF0, (uptr)&microVU0.regs->VI[REG_STATUS_FLAG].UL);
}
} }
void endMacroOp(int mode) { void endMacroOp(int mode) {
if (mode & 2) { // Q-Reg was Written To if (mode & 0x02) { // Q-Reg was Written To
SSE_MOVSS_XMM_to_M32((uptr)&microVU0.regs->VI[REG_Q].UL, xmmPQ); SSE_MOVSS_XMM_to_M32((uptr)&microVU0.regs->VI[REG_Q].UL, xmmPQ);
} }
if (mode & 0x10) { // Status/Mac Flags were Updated
MOV32RtoM((uptr)&microVU0.regs->VI[REG_STATUS_FLAG].UL, gprF0);
}
microVU0.regAlloc->flushAll(); microVU0.regAlloc->flushAll();
} }
@ -261,10 +273,16 @@ static void recCFC2() {
if (!_Rt_) return; if (!_Rt_) return;
iFlushCall(FLUSH_EVERYTHING); iFlushCall(FLUSH_EVERYTHING);
MOV32MtoR(EAX, (uptr)&microVU0.regs->VI[_Rd_].UL); if (_Rd_ == REG_STATUS_FLAG) { // Normalize Status Flag
MOV32MtoR(gprF0, (uptr)&microVU0.regs->VI[REG_STATUS_FLAG].UL);
mVUallocSFLAGc(EAX, gprF0, 0);
}
else MOV32MtoR(EAX, (uptr)&microVU0.regs->VI[_Rd_].UL);
// FixMe: Should R-Reg have upper 9 bits 0?
MOV32RtoM((uptr)&cpuRegs.GPR.r[_Rt_].UL[0], EAX); MOV32RtoM((uptr)&cpuRegs.GPR.r[_Rt_].UL[0], EAX);
if( _Rd_ >= 16 ) { if (_Rd_ >= 16) {
CDQ(); // Sign Extend CDQ(); // Sign Extend
MOV32RtoM ((uptr)&cpuRegs.GPR.r[_Rt_].UL[1], EDX); MOV32RtoM ((uptr)&cpuRegs.GPR.r[_Rt_].UL[1], EDX);
} }
@ -289,7 +307,14 @@ static void recCTC2() {
OR32ItoR (EAX, 0x3f800000); OR32ItoR (EAX, 0x3f800000);
MOV32RtoM((uptr)&microVU0.regs->VI[REG_R].UL, EAX); MOV32RtoM((uptr)&microVU0.regs->VI[REG_R].UL, EAX);
break; break;
case REG_CMSAR1: // REG_CMSAR1 case REG_STATUS_FLAG:
if (_Rt_) { // Denormalizes flag into gprF1
mVUallocSFLAGd((uptr)&cpuRegs.GPR.r[_Rt_].UL[0], 0);
MOV32RtoM((uptr)&microVU0.regs->VI[_Rd_].UL, gprF1);
}
else MOV32ItoM((uptr)&microVU0.regs->VI[_Rd_].UL, 0);
break;
case REG_CMSAR1:
if (_Rt_) { if (_Rt_) {
MOV32MtoR(EAX, (uptr)&cpuRegs.GPR.r[_Rt_].UL[0]); MOV32MtoR(EAX, (uptr)&cpuRegs.GPR.r[_Rt_].UL[0]);
PUSH32R(EAX); PUSH32R(EAX);