diff --git a/bin/resources/GameIndex.yaml b/bin/resources/GameIndex.yaml index 4b26abc5b2307..31cf08a3fcaee 100644 --- a/bin/resources/GameIndex.yaml +++ b/bin/resources/GameIndex.yaml @@ -3573,6 +3573,8 @@ SCED-52759: region: "PAL-M5" clampModes: vuClampMode: 0 # Resolves I Reg Clamping / performance impact and yellow graphics in certain areas. + gameFixes: + - IbitHack # Reduces VU recompilation. gsHWFixes: halfPixelOffset: 2 # Fixes blurriness. SCED-52785: @@ -3598,6 +3600,8 @@ SCED-52846: region: "PAL-E" clampModes: vuClampMode: 0 # Resolves I Reg Clamping / performance impact and yellow graphics in certain areas. + gameFixes: + - IbitHack # Reduces VU recompilation. gsHWFixes: halfPixelOffset: 2 # Fixes blurriness. SCED-52847: @@ -3667,6 +3671,8 @@ SCED-52899: region: "PAL-M5" clampModes: vuClampMode: 0 # Resolves I Reg Clamping / performance impact and yellow graphics in certain areas. + gameFixes: + - IbitHack # Reduces VU recompilation. gsHWFixes: halfPixelOffset: 2 # Fixes blurriness. SCED-52932: @@ -5210,6 +5216,8 @@ SCES-52004: compat: 5 clampModes: vuClampMode: 0 # Resolves I Reg Clamping / performance impact and yellow graphics in certain areas. + gameFixes: + - IbitHack # Reduces VU recompilation. gsHWFixes: halfPixelOffset: 2 # Fixes blurriness. SCES-52033: @@ -5552,6 +5560,8 @@ SCES-52893: region: "PAL-E-GR-R" clampModes: vuClampMode: 0 # Resolves I Reg Clamping / performance impact and yellow graphics in certain areas. + gameFixes: + - IbitHack # Reduces VU recompilation. gsHWFixes: halfPixelOffset: 2 # Fixes blurriness. SCES-52930: @@ -7085,6 +7095,8 @@ SCKA-20048: region: "NTSC-K" clampModes: vuClampMode: 0 # Resolves I Reg Clamping / performance impact and yellow graphics in certain areas. + gameFixes: + - IbitHack # Reduces VU recompilation. gsHWFixes: halfPixelOffset: 2 # Fixes blurriness. SCKA-20049: @@ -7303,6 +7315,8 @@ SCKA-20078: region: "NTSC-K" clampModes: vuClampMode: 0 # Resolves I Reg Clamping / performance impact and yellow graphics in certain areas. + gameFixes: + - IbitHack # Reduces VU recompilation. gsHWFixes: halfPixelOffset: 2 # Fixes blurriness. SCKA-20079: @@ -11342,6 +11356,8 @@ SCUS-97402: compat: 5 clampModes: vuClampMode: 0 # Resolves I Reg Clamping / performance impact and yellow graphics in certain areas. + gameFixes: + - IbitHack # Reduces VU recompilation. gsHWFixes: halfPixelOffset: 2 # Fixes blurriness. SCUS-97403: @@ -11490,6 +11506,8 @@ SCUS-97431: region: "NTSC-U" clampModes: vuClampMode: 0 # Resolves I Reg Clamping / performance impact and yellow graphics in certain areas. + gameFixes: + - IbitHack # Reduces VU recompilation. gsHWFixes: halfPixelOffset: 2 # Fixes blurriness. SCUS-97432: @@ -11497,6 +11515,8 @@ SCUS-97432: region: "NTSC-U" clampModes: vuClampMode: 0 # Resolves I Reg Clamping / performance impact and yellow graphics in certain areas. + gameFixes: + - IbitHack # Reduces VU recompilation. gsHWFixes: halfPixelOffset: 2 # Fixes blurriness. SCUS-97436: @@ -11964,6 +11984,8 @@ SCUS-97517: region: "NTSC-U" clampModes: vuClampMode: 0 # Resolves I Reg Clamping / performance impact and yellow graphics in certain areas. + gameFixes: + - IbitHack # Reduces VU recompilation. gsHWFixes: halfPixelOffset: 2 # Fixes blurriness. SCUS-97518: @@ -13174,6 +13196,8 @@ SLED-52899: region: "PAL-M5" clampModes: vuClampMode: 0 # Resolves I Reg Clamping / performance impact and yellow graphics in certain areas. + gameFixes: + - IbitHack # Reduces VU recompilation. gsHWFixes: halfPixelOffset: 2 # Fixes blurriness. SLED-52929: @@ -18575,6 +18599,8 @@ SLES-51981: region: "PAL-E" clampModes: vuClampMode: 0 # Resolves I Reg Clamping / performance impact and yellow graphics in certain areas. + gameFixes: + - IbitHack # Reduces VU recompilation. gsHWFixes: roundSprite: 1 # Fixes slight blur. SLES-51982: @@ -18582,6 +18608,8 @@ SLES-51982: region: "PAL-M3" clampModes: vuClampMode: 0 # Resolves I Reg Clamping / performance impact and yellow graphics in certain areas. + gameFixes: + - IbitHack # Reduces VU recompilation. gsHWFixes: roundSprite: 1 # Fixes slight blur. SLES-51986: @@ -44237,6 +44265,8 @@ SLPM-66151: region: "NTSC-J" clampModes: vuClampMode: 0 # Resolves I Reg Clamping / performance impact and yellow graphics in certain areas. + gameFixes: + - IbitHack # Reduces VU recompilation. gsHWFixes: halfPixelOffset: 2 # Fixes blurriness. SLPM-66152: @@ -63341,6 +63371,8 @@ SLUS-20828: compat: 5 clampModes: vuClampMode: 0 # Resolves I Reg Clamping / performance impact and yellow graphics in certain areas. + gameFixes: + - IbitHack # Reduces VU recompilation. gsHWFixes: roundSprite: 1 # Fixes slight blur. SLUS-20830: @@ -70946,6 +70978,8 @@ TCES-52004: region: "PAL-E" clampModes: vuClampMode: 0 # Resolves I Reg Clamping / performance impact and yellow graphics in certain areas. + gameFixes: + - IbitHack # Reduces VU recompilation. gsHWFixes: halfPixelOffset: 2 # Fixes blurriness. TCES-52033: diff --git a/pcsx2/x86/microVU_Analyze.inl b/pcsx2/x86/microVU_Analyze.inl index 27b57457d2149..64f866f66d2ab 100644 --- a/pcsx2/x86/microVU_Analyze.inl +++ b/pcsx2/x86/microVU_Analyze.inl @@ -228,7 +228,7 @@ __fi void mVUanalyzeIALU2(mV, int Is, int It) __fi void mVUanalyzeIADDI(mV, int Is, int It, s16 imm) { mVUanalyzeIALU2(mVU, Is, It); - if (!Is) + if (!Is && !EmuConfig.Gamefixes.IbitHack) { setConstReg(It, imm); } diff --git a/pcsx2/x86/microVU_Compile.inl b/pcsx2/x86/microVU_Compile.inl index a345fe5ad4b50..ca418d27cd21a 100644 --- a/pcsx2/x86/microVU_Compile.inl +++ b/pcsx2/x86/microVU_Compile.inl @@ -744,12 +744,27 @@ void* mVUcompile(microVU& mVU, u32 startPC, uptr pState) { mVUsetupRange(mVU, xPC, false); if (branch < 2) - mVUsetupRange(mVU, xPC + 8, true); // Ideally we'd do +4 but the mmx compare only works in 64bits, this should be fine + mVUsetupRange(mVU, xPC + 4, true); } } else { incPC(-1); + if (EmuConfig.Gamefixes.IbitHack) + { + // Ignore IADDI, IADDIU and ISUBU, ILW, ISW, LQ, SQ. + // Be warned, this is a little risky as we could be ignoring subtle differences in the operations. + // 2 is too much, 1 is too little, so it gets 2. It's a hack anyways... + const u32 upper = (mVU.code >> 25); + if (upper == 0x1 || upper == 0x0 || upper == 0x4 || upper == 0x5 || upper == 0x8 || upper == 0x9 || (upper == 0x40 && (mVU.code & 0x3F) == 0x32)) + { + incPC(1); + mVUsetupRange(mVU, xPC, false); + if (branch < 2) + mVUsetupRange(mVU, xPC + 2, true); + incPC(-1); + } + } mVUopL(mVU, 0); incPC(1); } diff --git a/pcsx2/x86/microVU_Lower.inl b/pcsx2/x86/microVU_Lower.inl index da4405e0a0acd..4eee43a1323f4 100644 --- a/pcsx2/x86/microVU_Lower.inl +++ b/pcsx2/x86/microVU_Lower.inl @@ -858,17 +858,37 @@ mVUop(mVU_IADDI) if (_Is_ == 0) { const xRegister32& regT = mVU.regAlloc->allocGPR(-1, _It_, mVUlow.backupVI); - if (_Imm5_ != 0) - xMOV(regT, _Imm5_); + if (!EmuConfig.Gamefixes.IbitHack) + { + if (_Imm5_ != 0) + xMOV(regT, _Imm5_); + else + xXOR(regT, regT); + } else - xXOR(regT, regT); + { + xMOV(regT, ptr32[&curI]); + xSHL(regT, 21); + xSAR(regT, 27); + } mVU.regAlloc->clearNeeded(regT); } else { const xRegister32& regS = mVU.regAlloc->allocGPR(_Is_, _It_, mVUlow.backupVI); - if (_Imm5_ != 0) - xADD(regS, _Imm5_); + if (!EmuConfig.Gamefixes.IbitHack) + { + if (_Imm5_ != 0) + xADD(regS, _Imm5_); + } + else + { + xMOV(gprT1, ptr32[&curI]); + xSHL(gprT1, 21); + xSAR(gprT1, 27); + + xADD(regS, gprT1); + } mVU.regAlloc->clearNeeded(regS); } mVU.profiler.EmitOp(opIADDI); @@ -884,17 +904,43 @@ mVUop(mVU_IADDIU) if (_Is_ == 0) { const xRegister32& regT = mVU.regAlloc->allocGPR(-1, _It_, mVUlow.backupVI); - if (_Imm15_ != 0) - xMOV(regT, _Imm15_); + if (!EmuConfig.Gamefixes.IbitHack) + { + if (_Imm15_ != 0) + xMOV(regT, _Imm15_); + else + xXOR(regT, regT); + } else - xXOR(regT, regT); + { + xMOV(regT, ptr32[&curI]); + xMOV(gprT1, regT); + xSHR(gprT1, 10); + xAND(gprT1, 0x7800); + xAND(regT, 0x7FF); + xOR(regT, gprT1); + } mVU.regAlloc->clearNeeded(regT); } else { const xRegister32& regS = mVU.regAlloc->allocGPR(_Is_, _It_, mVUlow.backupVI); - if (_Imm15_ != 0) - xADD(regS, _Imm15_); + if (!EmuConfig.Gamefixes.IbitHack) + { + if (_Imm15_ != 0) + xADD(regS, _Imm15_); + } + else + { + xMOV(gprT1, ptr32[&curI]); + xMOV(gprT2, gprT1); + xSHR(gprT2, 10); + xAND(gprT2, 0x7800); + xAND(gprT1, 0x7FF); + xOR(gprT1, gprT2); + + xADD(regS, gprT1); + } mVU.regAlloc->clearNeeded(regS); } mVU.profiler.EmitOp(opIADDIU); @@ -964,8 +1010,22 @@ mVUop(mVU_ISUBIU) pass2 { const xRegister32& regS = mVU.regAlloc->allocGPR(_Is_, _It_, mVUlow.backupVI); - if (_Imm15_ != 0) - xSUB(regS, _Imm15_); + if (!EmuConfig.Gamefixes.IbitHack) + { + if (_Imm15_ != 0) + xSUB(regS, _Imm15_); + } + else + { + xMOV(gprT1, ptr32[&curI]); + xMOV(gprT2, gprT1); + xSHR(gprT2, 10); + xAND(gprT2, 0x7800); + xAND(gprT1, 0x7FF); + xOR(gprT1, gprT2); + + xSUB(regS, gprT1); + } mVU.regAlloc->clearNeeded(regS); mVU.profiler.EmitOp(opISUBIU); } @@ -1100,12 +1160,23 @@ mVUop(mVU_ILW) pass2 { void* ptr = mVU.regs().Mem + offsetSS; - std::optional optaddr(mVUoptimizeConstantAddr(mVU, _Is_, _Imm11_, offsetSS)); + std::optional optaddr(EmuConfig.Gamefixes.IbitHack ? std::nullopt : mVUoptimizeConstantAddr(mVU, _Is_, _Imm11_, offsetSS)); if (!optaddr.has_value()) { mVU.regAlloc->moveVIToGPR(gprT1, _Is_); - if (_Imm11_ != 0) - xADD(gprT1, _Imm11_); + if (!EmuConfig.Gamefixes.IbitHack) + { + if (_Imm11_ != 0) + xADD(gprT1, _Imm11_); + } + else + { + xMOV(gprT2, ptr32[&curI]); + xSHL(gprT2, 21); + xSAR(gprT2, 21); + + xADD(gprT1, gprT2); + } mVUaddrFix(mVU, gprT1q); } @@ -1164,12 +1235,23 @@ mVUop(mVU_ISW) } pass2 { - std::optional optaddr(mVUoptimizeConstantAddr(mVU, _Is_, _Imm11_, 0)); + std::optional optaddr(EmuConfig.Gamefixes.IbitHack ? std::nullopt : mVUoptimizeConstantAddr(mVU, _Is_, _Imm11_, 0)); if (!optaddr.has_value()) { mVU.regAlloc->moveVIToGPR(gprT1, _Is_); - if (_Imm11_ != 0) - xADD(gprT1, _Imm11_); + if (!EmuConfig.Gamefixes.IbitHack) + { + if (_Imm11_ != 0) + xADD(gprT1, _Imm11_); + } + else + { + xMOV(gprT2, ptr32[&curI]); + xSHL(gprT2, 21); + xSAR(gprT2, 21); + + xADD(gprT1, gprT2); + } mVUaddrFix(mVU, gprT1q); } @@ -1251,12 +1333,23 @@ mVUop(mVU_LQ) pass1 { mVUanalyzeLQ(mVU, _Ft_, _Is_, false); } pass2 { - const std::optional optaddr(mVUoptimizeConstantAddr(mVU, _Is_, _Imm11_, 0)); + const std::optional optaddr(EmuConfig.Gamefixes.IbitHack ? std::nullopt : mVUoptimizeConstantAddr(mVU, _Is_, _Imm11_, 0)); if (!optaddr.has_value()) { mVU.regAlloc->moveVIToGPR(gprT1, _Is_); - if (_Imm11_ != 0) - xADD(gprT1, _Imm11_); + if (!EmuConfig.Gamefixes.IbitHack) + { + if (_Imm11_ != 0) + xADD(gprT1, _Imm11_); + } + else + { + xMOV(gprT2, ptr32[&curI]); + xSHL(gprT2, 21); + xSAR(gprT2, 21); + + xADD(gprT1, gprT2); + } mVUaddrFix(mVU, gprT1q); } @@ -1345,12 +1438,23 @@ mVUop(mVU_SQ) pass1 { mVUanalyzeSQ(mVU, _Fs_, _It_, false); } pass2 { - const std::optional optptr(mVUoptimizeConstantAddr(mVU, _It_, _Imm11_, 0)); + const std::optional optptr(EmuConfig.Gamefixes.IbitHack ? std::nullopt : mVUoptimizeConstantAddr(mVU, _It_, _Imm11_, 0)); if (!optptr.has_value()) { mVU.regAlloc->moveVIToGPR(gprT1, _It_); - if (_Imm11_ != 0) - xADD(gprT1, _Imm11_); + if (!EmuConfig.Gamefixes.IbitHack) + { + if (_Imm11_ != 0) + xADD(gprT1, _Imm11_); + } + else + { + xMOV(gprT2, ptr32[&curI]); + xSHL(gprT2, 21); + xSAR(gprT2, 21); + + xADD(gprT1, gprT2); + } mVUaddrFix(mVU, gprT1q); }