From e127ca0cd1c8e6f1640eb3fc90b2e0dfb564afb9 Mon Sep 17 00:00:00 2001 From: refractionpcsx2 Date: Tue, 21 Sep 2021 10:40:41 +0100 Subject: [PATCH] COP2: Set correct number of XMM's per COP2 OP + Fix some hidden bugs Corrects XMM count for COP2 ops (some might be wrong, keep an eye out in the logs) Fixes a hidden microVU bug with a SUB shortcut + some reg allocation bugs in QMFC/QMTC hidden by flushes. --- pcsx2/x86/iCore.cpp | 13 +- pcsx2/x86/iR5900.h | 2 +- pcsx2/x86/ix86-32/iR5900Templates.cpp | 4 +- pcsx2/x86/microVU_Macro.inl | 197 +++++++++++++------------- pcsx2/x86/microVU_Misc.h | 9 ++ pcsx2/x86/microVU_Upper.inl | 2 +- 6 files changed, 121 insertions(+), 106 deletions(-) diff --git a/pcsx2/x86/iCore.cpp b/pcsx2/x86/iCore.cpp index 1ca14019eb..5592dd38f1 100644 --- a/pcsx2/x86/iCore.cpp +++ b/pcsx2/x86/iCore.cpp @@ -801,20 +801,23 @@ u16 _freeXMMregsCOP2(int requiredcount) // Finally Get rid of registers which are gonna be needed, they'll need to be reloaded int maxcount = 9999; // The lower this value the more towards the end of the block it'll need flushing int regtoclear = -1; + while (count > 0) { for (int i = 0; i < iREGCNT_XMM - 1; i++) { if (xmmregs[i].inuse && xmmregs[i].counter < maxcount) { - int regtoclear = i; + regtoclear = i; maxcount = xmmregs[i].counter; } } - - _freeXMMreg(regtoclear); - count--; - regs |= (1 << regtoclear); + if (regtoclear != -1) + { + _freeXMMreg(regtoclear); + count--; + regs |= (1 << regtoclear); + } } pxAssert(count <= 0); diff --git a/pcsx2/x86/iR5900.h b/pcsx2/x86/iR5900.h index 0c7d9a614e..65eb1df0ee 100644 --- a/pcsx2/x86/iR5900.h +++ b/pcsx2/x86/iR5900.h @@ -127,7 +127,7 @@ void _eeOnWriteReg(int reg, int signext); // if 0, only flushes if not an xmm reg (used when overwriting lower 64bits of reg) void _deleteEEreg(int reg, int flush); -void _flushEEreg(int reg); +void _flushEEreg(int reg, bool clear = false); // allocates memory on the instruction size and returns the pointer u32* recGetImm64(u32 hi, u32 lo); diff --git a/pcsx2/x86/ix86-32/iR5900Templates.cpp b/pcsx2/x86/ix86-32/iR5900Templates.cpp index d9c9c82ea1..129aa068f0 100644 --- a/pcsx2/x86/ix86-32/iR5900Templates.cpp +++ b/pcsx2/x86/ix86-32/iR5900Templates.cpp @@ -50,7 +50,7 @@ void _deleteEEreg(int reg, int flush) _deleteGPRtoXMMreg(reg, flush ? 0 : 2); } -void _flushEEreg(int reg) +void _flushEEreg(int reg, bool clear) { if (!reg) return; @@ -59,7 +59,7 @@ void _flushEEreg(int reg) _flushConstReg(reg); return; } - _deleteGPRtoXMMreg(reg, 1); + _deleteGPRtoXMMreg(reg, clear ? 2 : 1); } int eeProcessHILO(int reg, int mode, int mmx) diff --git a/pcsx2/x86/microVU_Macro.inl b/pcsx2/x86/microVU_Macro.inl index 0d564a9650..a4ac444d90 100644 --- a/pcsx2/x86/microVU_Macro.inl +++ b/pcsx2/x86/microVU_Macro.inl @@ -74,9 +74,10 @@ void setupMacroOp(int mode, const char* opName) microVU0.prog.IRinfo.info[0].sFlag.lastWrite = 0; microVU0.prog.IRinfo.info[0].mFlag.doFlag = true; microVU0.prog.IRinfo.info[0].mFlag.write = 0xff; + _freeX86reg(ebx); //Denormalize mVUallocSFLAGd(&vu0Regs.VI[REG_STATUS_FLAG].UL); - + xMOV(gprF0, eax); } } @@ -93,19 +94,21 @@ void endMacroOp(int mode) mVUallocSFLAGc(eax, gprF0, 0); xMOV(ptr32[&vu0Regs.VI[REG_STATUS_FLAG].UL], eax); } + microVU0.regAlloc->flushAll(); if (mode & 0x10) // Update VU0 Status/Mac instances after flush to avoid corrupting anything { - _freeXMMreg(xmmT1.Id); + int t0reg = _allocTempXMMreg(XMMT_INT, -1); mVUallocSFLAGd(&vu0Regs.VI[REG_STATUS_FLAG].UL); - xMOVDZX(xmmT1, eax); - xSHUF.PS(xmmT1, xmmT1, 0); - xMOVAPS(ptr128[µVU0.regs().micro_statusflags], xmmT1); + xMOVDZX(xRegisterSSE(t0reg), eax); + xSHUF.PS(xRegisterSSE(t0reg), xRegisterSSE(t0reg), 0); + xMOVAPS(ptr128[µVU0.regs().micro_statusflags], xRegisterSSE(t0reg)); - xMOVDZX(xmmT1, ptr32[&vu0Regs.VI[REG_MAC_FLAG].UL]); - xSHUF.PS(xmmT1, xmmT1, 0); - xMOVAPS(ptr128[µVU0.regs().micro_macflags], xmmT1); + xMOVDZX(xRegisterSSE(t0reg), ptr32[&vu0Regs.VI[REG_MAC_FLAG].UL]); + xSHUF.PS(xRegisterSSE(t0reg), xRegisterSSE(t0reg), 0); + xMOVAPS(ptr128[µVU0.regs().micro_macflags], xRegisterSSE(t0reg)); + _freeXMMreg(t0reg); } microVU0.cop2 = 0; } @@ -167,90 +170,90 @@ REC_COP2_mVU0(FTOI0, "FTOI0", 0x3000); REC_COP2_mVU0(FTOI4, "FTOI4", 0x3000); REC_COP2_mVU0(FTOI12, "FTOI12", 0x3000); REC_COP2_mVU0(FTOI15, "FTOI15", 0x3000); -REC_COP2_mVU0(ADD, "ADD", 0x4110); -REC_COP2_mVU0(ADDi, "ADDi", 0x4110); -REC_COP2_mVU0(ADDq, "ADDq", 0x4111); -REC_COP2_mVU0(ADDx, "ADDx", 0x4110); -REC_COP2_mVU0(ADDy, "ADDy", 0x4110); -REC_COP2_mVU0(ADDz, "ADDz", 0x4110); -REC_COP2_mVU0(ADDw, "ADDw", 0x4110); -REC_COP2_mVU0(ADDA, "ADDA", 0x4110); -REC_COP2_mVU0(ADDAi, "ADDAi", 0x4110); -REC_COP2_mVU0(ADDAq, "ADDAq", 0x4111); +REC_COP2_mVU0(ADD, "ADD", ((_cXYZW_SS2 || clampE) ? 0x2110 : 0x3110) + (!_cXYZW_SS ? 0x1000 : 0)); +REC_COP2_mVU0(ADDi, "ADDi", 0x2110 + (!_cXYZW_SS ? 0x1000 : 0)); +REC_COP2_mVU0(ADDq, "ADDq", 0x2111 + (!_cXYZW_SS ? 0x1000 : 0)); +REC_COP2_mVU0(ADDx, "ADDx", 0x3110 + (!_cXYZW_SS ? 0x1000 : 0)); +REC_COP2_mVU0(ADDy, "ADDy", 0x3110 + (!_cXYZW_SS ? 0x1000 : 0)); +REC_COP2_mVU0(ADDz, "ADDz", 0x3110 + (!_cXYZW_SS ? 0x1000 : 0)); +REC_COP2_mVU0(ADDw, "ADDw", 0x3110 + (!_cXYZW_SS ? 0x1000 : 0)); +REC_COP2_mVU0(ADDA, "ADDA", ((!(_cXYZW_SS2 || clampE) && !_cXYZW_SS) ? 0x4110 : 0x3110)); +REC_COP2_mVU0(ADDAi, "ADDAi", 0x3110); +REC_COP2_mVU0(ADDAq, "ADDAq", 0x2111 + ((clampE || !_cXYZW_SS) ? 0x1000 : 0)); REC_COP2_mVU0(ADDAx, "ADDAx", 0x4110); REC_COP2_mVU0(ADDAy, "ADDAy", 0x4110); REC_COP2_mVU0(ADDAz, "ADDAz", 0x4110); REC_COP2_mVU0(ADDAw, "ADDAw", 0x4110); -REC_COP2_mVU0(SUB, "SUB", 0x4110); -REC_COP2_mVU0(SUBi, "SUBi", 0x4110); -REC_COP2_mVU0(SUBq, "SUBq", 0x4111); -REC_COP2_mVU0(SUBx, "SUBx", 0x4110); -REC_COP2_mVU0(SUBy, "SUBy", 0x4110); -REC_COP2_mVU0(SUBz, "SUBz", 0x4110); -REC_COP2_mVU0(SUBw, "SUBw", 0x4110); -REC_COP2_mVU0(SUBA, "SUBA", 0x4110); -REC_COP2_mVU0(SUBAi, "SUBAi", 0x4110); -REC_COP2_mVU0(SUBAq, "SUBAq", 0x4111); +REC_COP2_mVU0(SUB, "SUB", (_Rt_ == _Rd_) ? (!(_cXYZW_SS) ? 0x3110 : 0x2110) : ((_cXYZW_SS2 || clampE) ? 0x2110 : 0x3110) + (!_cXYZW_SS ? 0x1000 : 0)); +REC_COP2_mVU0(SUBi, "SUBi", 0x2110 + (!_cXYZW_SS ? 0x1000 : 0)); +REC_COP2_mVU0(SUBq, "SUBq", 0x2111 + (!_cXYZW_SS ? 0x1000 : 0)); +REC_COP2_mVU0(SUBx, "SUBx", 0x3110 + (!_cXYZW_SS ? 0x1000 : 0)); +REC_COP2_mVU0(SUBy, "SUBy", 0x3110 + (!_cXYZW_SS ? 0x1000 : 0)); +REC_COP2_mVU0(SUBz, "SUBz", 0x3110 + (!_cXYZW_SS ? 0x1000 : 0)); +REC_COP2_mVU0(SUBw, "SUBw", 0x3110 + (!_cXYZW_SS ? 0x1000 : 0)); +REC_COP2_mVU0(SUBA, "SUBA", (_Rt_ == _Rd_) ? (!(_cXYZW_SS) ? 0x3110 : 0x2110) : ((!clampE && !_cXYZW_SS) ? 0x4110 : 0x3110)); +REC_COP2_mVU0(SUBAi, "SUBAi", 0x3110); +REC_COP2_mVU0(SUBAq, "SUBAq", 0x2111 + ((clampE || !_cXYZW_SS) ? 0x1000 : 0)); REC_COP2_mVU0(SUBAx, "SUBAx", 0x4110); REC_COP2_mVU0(SUBAy, "SUBAy", 0x4110); REC_COP2_mVU0(SUBAz, "SUBAz", 0x4110); REC_COP2_mVU0(SUBAw, "SUBAw", 0x4110); -REC_COP2_mVU0(MUL, "MUL", 0x4110); -REC_COP2_mVU0(MULi, "MULi", 0x4110); -REC_COP2_mVU0(MULq, "MULq", 0x4111); -REC_COP2_mVU0(MULx, "MULx", 0x4110); -REC_COP2_mVU0(MULy, "MULy", 0x4110); -REC_COP2_mVU0(MULz, "MULz", 0x4110); -REC_COP2_mVU0(MULw, "MULw", 0x4110); -REC_COP2_mVU0(MULA, "MULA", 0x4110); -REC_COP2_mVU0(MULAi, "MULAi", 0x4110); -REC_COP2_mVU0(MULAq, "MULAq", 0x4111); +REC_COP2_mVU0(MUL, "MUL", ((_cXYZW_SS2 || clampE) ? 0x2110 : 0x3110) + (!_cXYZW_SS ? 0x1000 : 0)); +REC_COP2_mVU0(MULi, "MULi", 0x2110 + (!_cXYZW_SS ? 0x1000 : 0)); +REC_COP2_mVU0(MULq, "MULq", 0x2111 + (!_cXYZW_SS ? 0x1000 : 0)); +REC_COP2_mVU0(MULx, "MULx", 0x3110 + (!_cXYZW_SS ? 0x1000 : 0)); +REC_COP2_mVU0(MULy, "MULy", 0x3110 + (!_cXYZW_SS ? 0x1000 : 0)); +REC_COP2_mVU0(MULz, "MULz", 0x3110 + (!_cXYZW_SS ? 0x1000 : 0)); +REC_COP2_mVU0(MULw, "MULw", 0x3110 + (!_cXYZW_SS ? 0x1000 : 0)); +REC_COP2_mVU0(MULA, "MULA", 0x3110 + ((!_cXYZW_SS2 && !clampE && !_cXYZW_SS) ? 0x1000 : 0)); // Done +REC_COP2_mVU0(MULAi, "MULAi", 0x3110); +REC_COP2_mVU0(MULAq, "MULAq", 0x2111 + ((clampE || !_cXYZW_SS) ? 0x1000 : 0)); REC_COP2_mVU0(MULAx, "MULAx", 0x4110); REC_COP2_mVU0(MULAy, "MULAy", 0x4110); REC_COP2_mVU0(MULAz, "MULAz", 0x4110); REC_COP2_mVU0(MULAw, "MULAw", 0x4110); -REC_COP2_mVU0(MAX, "MAX", 0x4000); -REC_COP2_mVU0(MAXi, "MAXi", 0x4000); -REC_COP2_mVU0(MAXx, "MAXx", 0x4000); -REC_COP2_mVU0(MAXy, "MAXy", 0x4000); -REC_COP2_mVU0(MAXz, "MAXz", 0x4000); -REC_COP2_mVU0(MAXw, "MAXw", 0x4000); -REC_COP2_mVU0(MINI, "MINI", 0x4000); -REC_COP2_mVU0(MINIi, "MINIi", 0x4000); -REC_COP2_mVU0(MINIx, "MINIx", 0x4000); -REC_COP2_mVU0(MINIy, "MINIy", 0x4000); -REC_COP2_mVU0(MINIz, "MINIz", 0x4000); -REC_COP2_mVU0(MINIw, "MINIw", 0x4000); -REC_COP2_mVU0(MADD, "MADD", 0x4110); -REC_COP2_mVU0(MADDi, "MADDi", 0x4110); -REC_COP2_mVU0(MADDq, "MADDq", 0x4111); -REC_COP2_mVU0(MADDx, "MADDx", 0x4110); -REC_COP2_mVU0(MADDy, "MADDy", 0x4110); -REC_COP2_mVU0(MADDz, "MADDz", 0x4110); -REC_COP2_mVU0(MADDw, "MADDw", 0x4110); -REC_COP2_mVU0(MADDA, "MADDA", 0x4110); -REC_COP2_mVU0(MADDAi, "MADDAi", 0x4110); -REC_COP2_mVU0(MADDAq, "MADDAq", 0x4111); -REC_COP2_mVU0(MADDAx, "MADDAx", 0x4110); -REC_COP2_mVU0(MADDAy, "MADDAy", 0x4110); -REC_COP2_mVU0(MADDAz, "MADDAz", 0x4110); -REC_COP2_mVU0(MADDAw, "MADDAw", 0x4110); -REC_COP2_mVU0(MSUB, "MSUB", 0x4110); -REC_COP2_mVU0(MSUBi, "MSUBi", 0x4110); -REC_COP2_mVU0(MSUBq, "MSUBq", 0x4111); +REC_COP2_mVU0(MAX, "MAX", 0x3000 + (!_cXYZW_SS ? 0x1000 : 0)); +REC_COP2_mVU0(MAXi, "MAXi", 0x3000 + (!_cXYZW_SS ? 0x1000 : 0)); +REC_COP2_mVU0(MAXx, "MAXx", 0x4000 + (!_cXYZW_SS ? 0x1000 : 0)); +REC_COP2_mVU0(MAXy, "MAXy", 0x4000 + (!_cXYZW_SS ? 0x1000 : 0)); +REC_COP2_mVU0(MAXz, "MAXz", 0x4000 + (!_cXYZW_SS ? 0x1000 : 0)); +REC_COP2_mVU0(MAXw, "MAXw", 0x4000 + (!_cXYZW_SS ? 0x1000 : 0)); +REC_COP2_mVU0(MINI, "MINI", 0x3000 + (!_cXYZW_SS ? 0x1000 : 0)); +REC_COP2_mVU0(MINIi, "MINIi", 0x3000 + (!_cXYZW_SS ? 0x1000 : 0)); +REC_COP2_mVU0(MINIx, "MINIx", 0x4000 + (!_cXYZW_SS ? 0x1000 : 0)); +REC_COP2_mVU0(MINIy, "MINIy", 0x4000 + (!_cXYZW_SS ? 0x1000 : 0)); +REC_COP2_mVU0(MINIz, "MINIz", 0x4000 + (!_cXYZW_SS ? 0x1000 : 0)); +REC_COP2_mVU0(MINIw, "MINIw", 0x4000 + (!_cXYZW_SS ? 0x1000 : 0)); +REC_COP2_mVU0(MADD, "MADD", ((_cXYZW_SS2 || clampE) ? 0x3110 : 0x4110) + (!_cXYZW_SS ? 0x1000 : 0)); +REC_COP2_mVU0(MADDi, "MADDi", 0x3110 + (!_cXYZW_SS ? 0x1000 : 0)); +REC_COP2_mVU0(MADDq, "MADDq", 0x3111 + (!_cXYZW_SS ? 0x1000 : 0)); +REC_COP2_mVU0(MADDx, "MADDx", 0x4110 + (!_cXYZW_SS ? 0x1000 : 0)); +REC_COP2_mVU0(MADDy, "MADDy", 0x4110 + (!_cXYZW_SS ? 0x1000 : 0)); +REC_COP2_mVU0(MADDz, "MADDz", 0x4110 + (!_cXYZW_SS ? 0x1000 : 0)); +REC_COP2_mVU0(MADDw, "MADDw", 0x4110 + (!_cXYZW_SS ? 0x1000 : 0)); +REC_COP2_mVU0(MADDA, "MADDA", ((_cXYZW_SS || _cX_Y_Z_W == 0xf) ? 0x3110 : 0x4110) + ((!_cXYZW_SS2 && !clampE && !_cXYZW_SS) ? 0x1000 : 0)); +REC_COP2_mVU0(MADDAi, "MADDAi", 0x3110); +REC_COP2_mVU0(MADDAq, "MADDAq", 0x2111 + ((clampE || !_cXYZW_SS) ? 0x1000 : 0) + (!(_cXYZW_SS || _cX_Y_Z_W == 0xf) ? 0x1000 : 0)); +REC_COP2_mVU0(MADDAx, "MADDAx", (_cXYZW_SS || _cX_Y_Z_W == 0xf) ? 0x4110 : 0x5110); +REC_COP2_mVU0(MADDAy, "MADDAy", (_cXYZW_SS || _cX_Y_Z_W == 0xf) ? 0x4110 : 0x5110); +REC_COP2_mVU0(MADDAz, "MADDAz", (_cXYZW_SS || _cX_Y_Z_W == 0xf) ? 0x4110 : 0x5110); +REC_COP2_mVU0(MADDAw, "MADDAw", (_cXYZW_SS || _cX_Y_Z_W == 0xf) ? 0x4110 : 0x5110); +REC_COP2_mVU0(MSUB, "MSUB", 0x3110 + ((!_cXYZW_SS && !clampE) ? 0x1000 : 0)); +REC_COP2_mVU0(MSUBi, "MSUBi", 0x3110); +REC_COP2_mVU0(MSUBq, "MSUBq", 0x2111 + (!(_cXYZW_SS && !clampE) ? 0x1000 : 0)); REC_COP2_mVU0(MSUBx, "MSUBx", 0x4110); REC_COP2_mVU0(MSUBy, "MSUBy", 0x4110); REC_COP2_mVU0(MSUBz, "MSUBz", 0x4110); REC_COP2_mVU0(MSUBw, "MSUBw", 0x4110); -REC_COP2_mVU0(MSUBA, "MSUBA", 0x4110); -REC_COP2_mVU0(MSUBAi, "MSUBAi", 0x4110); -REC_COP2_mVU0(MSUBAq, "MSUBAq", 0x4111); -REC_COP2_mVU0(MSUBAx, "MSUBAx", 0x4110); -REC_COP2_mVU0(MSUBAy, "MSUBAy", 0x4110); -REC_COP2_mVU0(MSUBAz, "MSUBAz", 0x4110); -REC_COP2_mVU0(MSUBAw, "MSUBAw", 0x4110); -REC_COP2_mVU0(OPMULA, "OPMULA", 0x3110); -REC_COP2_mVU0(OPMSUB, "OPMSUB", 0x3110); +REC_COP2_mVU0(MSUBA, "MSUBA", ((!(_cXYZW_SS2 || clampE) && !_cXYZW_SS) ? 0x4110 : 0x3110) + ((!_cXYZW_SS && _cX_Y_Z_W != 0xf) ? 0x1000 : 0)); +REC_COP2_mVU0(MSUBAi, "MSUBAi", (!(_cXYZW_SS || _cX_Y_Z_W == 0xf) ? 0x4110 : 0x3110)); +REC_COP2_mVU0(MSUBAq, "MSUBAq", 0x2111 + ((clampE || !_cXYZW_SS) ? 0x1000 : 0) + (!(_cXYZW_SS || _cX_Y_Z_W == 0xf) ? 0x1000 : 0)); +REC_COP2_mVU0(MSUBAx, "MSUBAx", (_cXYZW_SS || _cX_Y_Z_W == 0xf) ? 0x4110 : 0x5110); +REC_COP2_mVU0(MSUBAy, "MSUBAy", (_cXYZW_SS || _cX_Y_Z_W == 0xf) ? 0x4110 : 0x5110); +REC_COP2_mVU0(MSUBAz, "MSUBAz", (_cXYZW_SS || _cX_Y_Z_W == 0xf) ? 0x4110 : 0x5110); +REC_COP2_mVU0(MSUBAw, "MSUBAw", (_cXYZW_SS || _cX_Y_Z_W == 0xf) ? 0x4110 : 0x5110); +REC_COP2_mVU0(OPMULA, "OPMULA", 0x4110); +REC_COP2_mVU0(OPMSUB, "OPMSUB", 0x5110); REC_COP2_mVU0(CLIP, "CLIP", 0x3108); //------------------------------------------------------------------ @@ -267,18 +270,18 @@ REC_COP2_mVU0(IOR, "IOR", 0x104); REC_COP2_mVU0(ISUB, "ISUB", 0x104); REC_COP2_mVU0(ILWR, "ILWR", 0x104); REC_COP2_mVU0(ISWR, "ISWR", 0x100); -REC_COP2_mVU0(LQI, "LQI", 0x1104); -REC_COP2_mVU0(LQD, "LQD", 0x1104); +REC_COP2_mVU0(LQI, "LQI", 0x0104 + ((_Rt_) ? 0x1100 : 0)); +REC_COP2_mVU0(LQD, "LQD", 0x0104 + ((_Rt_) ? 0x1100 : 0)); REC_COP2_mVU0(SQI, "SQI", 0x1100); REC_COP2_mVU0(SQD, "SQD", 0x1100); -REC_COP2_mVU0(MFIR, "MFIR", 0x1104); -REC_COP2_mVU0(MTIR, "MTIR", 0x1104); +REC_COP2_mVU0(MFIR, "MFIR", 0x0104 + ((_Rt_) ? 0x1000 : 0)); +REC_COP2_mVU0(MTIR, "MTIR", 0x0104 + (((cpuRegs.code >> 16) & 0xF) ? 0x1000 : 0)); // It REC_COP2_mVU0(MOVE, "MOVE", 0x1000); REC_COP2_mVU0(MR32, "MR32", 0x2000); -REC_COP2_mVU0(RINIT, "RINIT", 0x1100); -REC_COP2_mVU0(RGET, "RGET", 0x1104); -REC_COP2_mVU0(RNEXT, "RNEXT", 0x1104); -REC_COP2_mVU0(RXOR, "RXOR", 0x1100); +REC_COP2_mVU0(RINIT, "RINIT", 0x0100 + ((_Rd_ || (((cpuRegs.code >> 21) & 0x03) == 3)) ? 0x1000 : 0)); //Fsf +REC_COP2_mVU0(RGET, "RGET", 0x0104 + (_Rt_ != 0 ? 0x1000 : 0)); +REC_COP2_mVU0(RNEXT, "RNEXT", 0x0104 + (_Rt_ != 0 ? 0x1000 : 0)); +REC_COP2_mVU0(RXOR, "RXOR", 0x0100 + ((_Rd_ || (((cpuRegs.code >> 21) & 0x03) == 3)) ? 0x1000 : 0)); //Fsf //------------------------------------------------------------------ // Macro VU - Misc... @@ -382,7 +385,7 @@ static void recCFC2() skipvuidle.SetTarget(); } - _flushEEreg(_Rt_); + _flushEEreg(_Rt_, true); if (_Rd_ == REG_STATUS_FLAG) // Normalize Status Flag xMOV(eax, ptr32[&vu0Regs.VI[REG_STATUS_FLAG].UL]); @@ -517,7 +520,7 @@ static void recQMFC2() if (!_Rt_) return; - + if (!(cpuRegs.code & 1)) { _freeX86reg(eax); @@ -539,26 +542,25 @@ static void recQMFC2() skipvuidle.SetTarget(); } - _flushEEreg(_Rt_); - _freeXMMreg(xmmT1.Id); + int rtreg = _allocGPRtoXMMreg(-1, _Rt_, MODE_WRITE); + int t0reg = _allocTempXMMreg(XMMT_INT, -1); // Update Refraction 20/09/2021: This is needed because Const Prop is broken // the Flushed flag isn't being cleared when it's not flushed. TODO I guess _eeOnWriteReg(_Rt_, 0); // This is needed because Const Prop is broken - xMOVAPS(xmmT1, ptr128[&vu0Regs.VF[_Rd_]]); - xMOVAPS(ptr128[&cpuRegs.GPR.r[_Rt_]], xmmT1); + xMOVAPS(xRegisterSSE(t0reg), ptr128[&vu0Regs.VF[_Rd_]]); + xMOVAPS(xRegisterSSE(rtreg), xRegisterSSE(t0reg)); + _freeXMMreg(t0reg); } static void recQMTC2() { - printCOP2("QMTC2"); - COP2_Interlock(true); if (!_Rd_) return; - + if (!(cpuRegs.code & 1)) { _freeX86reg(eax); @@ -580,11 +582,12 @@ static void recQMTC2() skipvuidle.SetTarget(); } - _flushEEreg(_Rt_); - _freeXMMreg(xmmT1.Id); + int rtreg = _allocGPRtoXMMreg(-1, _Rt_, MODE_READ); + int t0reg = _allocTempXMMreg(XMMT_INT, -1); - xMOVAPS(xmmT1, ptr128[&cpuRegs.GPR.r[_Rt_]]); - xMOVAPS(ptr128[&vu0Regs.VF[_Rd_]], xmmT1); + xMOVAPS(xRegisterSSE(t0reg), xRegisterSSE(rtreg)); + xMOVAPS(ptr128[&vu0Regs.VF[_Rd_]], xRegisterSSE(t0reg)); + _freeXMMreg(t0reg); } //------------------------------------------------------------------ diff --git a/pcsx2/x86/microVU_Misc.h b/pcsx2/x86/microVU_Misc.h index 3ff25f4c78..ae812c372e 100644 --- a/pcsx2/x86/microVU_Misc.h +++ b/pcsx2/x86/microVU_Misc.h @@ -105,7 +105,16 @@ static const char branchSTR[16][8] = { #define _Z ((mVU.code >> 22) & 0x1) #define _W ((mVU.code >> 21) & 0x1) +#define _cX ((cpuRegs.code >> 24) & 0x1) +#define _cY ((cpuRegs.code >> 23) & 0x1) +#define _cZ ((cpuRegs.code >> 22) & 0x1) +#define _cW ((cpuRegs.code >> 21) & 0x1) + #define _X_Y_Z_W (((mVU.code >> 21) & 0xF)) +#define _cX_Y_Z_W (((cpuRegs.code >> 21) & 0xF)) +#define _cXYZW_SS (_cX + _cY + _cZ + _cW == 1) +#define _cXYZW_SS2 (_cXYZW_SS && (_cX_Y_Z_W != 8)) + #define _XYZW_SS (_X + _Y + _Z + _W == 1) #define _XYZW_SS2 (_XYZW_SS && (_X_Y_Z_W != 8)) #define _XYZW_PS (_X_Y_Z_W == 0xf) diff --git a/pcsx2/x86/microVU_Upper.inl b/pcsx2/x86/microVU_Upper.inl index 6bf496fad4..f55897581b 100644 --- a/pcsx2/x86/microVU_Upper.inl +++ b/pcsx2/x86/microVU_Upper.inl @@ -179,7 +179,7 @@ static bool doSafeSub(microVU& mVU, int opCase, int opType, bool isACC) { opCase1 { - if ((opType == 1) && (_Ft_ == _Fs_)) + if ((opType == 1) && (_Ft_ == _Fs_) && (opCase == 1)) // Don't do this with BC's! { const xmm& Fs = mVU.regAlloc->allocReg(-1, isACC ? 32 : _Fd_, _X_Y_Z_W); xPXOR(Fs, Fs); // Set to Positive 0