diff --git a/common/include/Pcsx2Config.h b/common/include/Pcsx2Config.h index ce8b9b2c12..b1d69d4e4e 100644 --- a/common/include/Pcsx2Config.h +++ b/common/include/Pcsx2Config.h @@ -61,7 +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_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/x86/microVU_Alloc.inl b/pcsx2/x86/microVU_Alloc.inl index bc4eb4f84f..dd40b4b6f3 100644 --- a/pcsx2/x86/microVU_Alloc.inl +++ b/pcsx2/x86/microVU_Alloc.inl @@ -77,13 +77,37 @@ microVUt(void) mVUallocSFLAGc(int reg, int regT, int fInstance) { 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) { MOVZX32M16toR(reg, (uptr)&mVU->macFlag[fInstance]); } microVUt(void) mVUallocMFLAGb(mV, int reg, int fInstance) { //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) { diff --git a/pcsx2/x86/microVU_Branch.inl b/pcsx2/x86/microVU_Branch.inl index 054446c567..7fe9c8c723 100644 --- a/pcsx2/x86/microVU_Branch.inl +++ b/pcsx2/x86/microVU_Branch.inl @@ -59,8 +59,13 @@ microVUt(void) mVUendProgram(mV, microFlagCycles* mFC, int isEbit) { } // Save Flag Instances +#ifdef CHECK_MACROVU0 + getFlagReg(fStatus, fStatus); + MOV32RtoM((uptr)&mVU->regs->VI[REG_STATUS_FLAG].UL, fStatus); +#else mVUallocSFLAGc(gprT1, gprT2, fStatus); MOV32RtoM((uptr)&mVU->regs->VI[REG_STATUS_FLAG].UL, gprT1); +#endif mVUallocMFLAGa(mVU, gprT1, fMac); mVUallocCFLAGa(mVU, gprT2, fClip); MOV32RtoM((uptr)&mVU->regs->VI[REG_MAC_FLAG].UL, gprT1); diff --git a/pcsx2/x86/microVU_Execute.inl b/pcsx2/x86/microVU_Execute.inl index 1e4c105820..ca29e10469 100644 --- a/pcsx2/x86/microVU_Execute.inl +++ b/pcsx2/x86/microVU_Execute.inl @@ -40,24 +40,15 @@ void mVUdispatcherA(mV) { SSE_LDMXCSR((uptr)&g_sseVUMXCSR); // Load Regs +#ifdef CHECK_MACROVU0 MOV32MtoR(gprF0, (uptr)&mVU->regs->VI[REG_STATUS_FLAG].UL); 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); - - MOV32RtoR(gprF0, gprF1); - MOV32RtoR(gprF2, gprF1); - MOV32RtoR(gprF3, gprF1); - + MOV32RtoR(gprF3, gprF0); +#else + mVUallocSFLAGd((uptr)&mVU->regs->VI[REG_STATUS_FLAG].UL, 1); +#endif + SSE_MOVAPS_M128_to_XMM(xmmT1, (uptr)&mVU->regs->VI[REG_MAC_FLAG].UL); SSE_SHUFPS_XMM_to_XMM (xmmT1, xmmT1, 0); SSE_MOVAPS_XMM_to_M128((uptr)mVU->macFlag, xmmT1); diff --git a/pcsx2/x86/microVU_Macro.inl b/pcsx2/x86/microVU_Macro.inl index 0e9bee6a4b..f1073a902c 100644 --- a/pcsx2/x86/microVU_Macro.inl +++ b/pcsx2/x86/microVU_Macro.inl @@ -41,19 +41,31 @@ void setupMacroOp(int mode, const char* opName) { memset(µVU0.prog.IRinfo.info[0], 0, sizeof(microVU0.prog.IRinfo.info[0])); iFlushCall(FLUSH_EVERYTHING); 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)µVU0.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.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)µVU0.regs->VI[REG_STATUS_FLAG].UL); + } } 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)µVU0.regs->VI[REG_Q].UL, xmmPQ); } + if (mode & 0x10) { // Status/Mac Flags were Updated + MOV32RtoM((uptr)µVU0.regs->VI[REG_STATUS_FLAG].UL, gprF0); + } microVU0.regAlloc->flushAll(); } @@ -261,10 +273,16 @@ static void recCFC2() { if (!_Rt_) return; iFlushCall(FLUSH_EVERYTHING); - MOV32MtoR(EAX, (uptr)µVU0.regs->VI[_Rd_].UL); + if (_Rd_ == REG_STATUS_FLAG) { // Normalize Status Flag + MOV32MtoR(gprF0, (uptr)µVU0.regs->VI[REG_STATUS_FLAG].UL); + mVUallocSFLAGc(EAX, gprF0, 0); + } + else MOV32MtoR(EAX, (uptr)µVU0.regs->VI[_Rd_].UL); + + // FixMe: Should R-Reg have upper 9 bits 0? MOV32RtoM((uptr)&cpuRegs.GPR.r[_Rt_].UL[0], EAX); - if( _Rd_ >= 16 ) { + if (_Rd_ >= 16) { CDQ(); // Sign Extend MOV32RtoM ((uptr)&cpuRegs.GPR.r[_Rt_].UL[1], EDX); } @@ -289,7 +307,14 @@ static void recCTC2() { OR32ItoR (EAX, 0x3f800000); MOV32RtoM((uptr)µVU0.regs->VI[REG_R].UL, EAX); 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)µVU0.regs->VI[_Rd_].UL, gprF1); + } + else MOV32ItoM((uptr)µVU0.regs->VI[_Rd_].UL, 0); + break; + case REG_CMSAR1: if (_Rt_) { MOV32MtoR(EAX, (uptr)&cpuRegs.GPR.r[_Rt_].UL[0]); PUSH32R(EAX);