diff --git a/pcsx2/x86/microVU_Analyze.inl b/pcsx2/x86/microVU_Analyze.inl index e903d304d7..de29c74f50 100644 --- a/pcsx2/x86/microVU_Analyze.inl +++ b/pcsx2/x86/microVU_Analyze.inl @@ -619,19 +619,7 @@ __ri int mVUbranchCheck(mV) incPC(2); mVUlow.evilBranch = true; - if (mVUlow.branch == 2 || mVUlow.branch == 10) // Needs linking, we can only guess this if the next is not conditional - { - // First branch is not conditional so we know what the link will be - // So we can let the existing evil block do its thing! We know where to get the addr :) - if (branchType <= 2 || branchType >= 9) - { - mVUregs.blockType = 2; - } // Else it is conditional, so we need to do some nasty processing later in microVU_Branch.inl - } - else - { - mVUregs.blockType = 2; // Second branch doesn't need linking, so can let it run its evil block course (MGS2 for testing) - } + mVUregs.blockType = 2; // Second branch doesn't need linking, so can let it run its evil block course (MGS2 for testing) mVUregs.needExactMatch |= 7; // This might not be necessary, but w/e... mVUregs.flagInfo = 0; @@ -678,7 +666,8 @@ __fi void mVUanalyzeNormBranch(mV, int It, bool isBAL) if (isBAL) { analyzeVIreg2(mVU, It, mVUlow.VI_write, 1); - setConstReg(It, bSaveAddr); + if(!mVUlow.evilBranch) + setConstReg(It, bSaveAddr); } } @@ -695,6 +684,7 @@ __ri void mVUanalyzeJump(mV, int Is, int It, bool isJALR) if (isJALR) { analyzeVIreg2(mVU, It, mVUlow.VI_write, 1); - setConstReg(It, bSaveAddr); + if (!mVUlow.evilBranch) + setConstReg(It, bSaveAddr); } } diff --git a/pcsx2/x86/microVU_Branch.inl b/pcsx2/x86/microVU_Branch.inl index 6027aac471..5030840743 100644 --- a/pcsx2/x86/microVU_Branch.inl +++ b/pcsx2/x86/microVU_Branch.inl @@ -17,7 +17,6 @@ extern void mVUincCycles(microVU& mVU, int x); extern void* mVUcompile(microVU& mVU, u32 startPC, uptr pState); -extern void* mVUcompileSingleInstruction(microVU& mVU, u32 startPC, uptr pState, microFlagCycles& mFC); __fi int getLastFlagInst(microRegInfo& pState, int* xFlag, int flagType, int isEbit) { if (isEbit) @@ -395,65 +394,11 @@ void normBranch(mV, microFlagCycles& mFC) return; } - if (mVUlow.badBranch) - { - u32 badBranchAddr = branchAddr(mVU) + 8; - incPC(3); - if (mVUlow.branch == 2 || mVUlow.branch == 10) //Delay slot branch needs linking - { - DevCon.Warning("Found %s in delay slot, linking - If game broken report to PCSX2 Team", mVUlow.branch == 2 ? "BAL" : "JALR"); - xMOV(gprT3, badBranchAddr); - xSHR(gprT3, 3); - mVUallocVIb(mVU, gprT3, _It_); - } - incPC(-3); - } - // Normal Branch mVUsetupBranch(mVU, mFC); normBranchCompile(mVU, branchAddr(mVU)); } -//Messy handler warning!! -//This handles JALR/BAL in the delay slot of a conditional branch. We do this because the normal handling -//Doesn't seem to work properly, even if the link is made to the correct address, so we do it manually instead. -//Normally EvilBlock handles all this stuff, but something to do with conditionals and links don't quite work right :/ -void condJumpProcessingEvil(mV, microFlagCycles& mFC, int JMPcc) -{ - - u32 bPC = iPC - 1; // mVUcompile can modify iPC, mVUpBlock, and mVUregs so back them up - u32 badBranchAddr; - iPC = bPC - 2; - setCode(); - badBranchAddr = branchAddr(mVU); - - xCMP(ptr16[&mVU.branch], 0); - - xForwardJump32 eJMP(xInvertCond((JccComparisonType)JMPcc)); - - mVUcompileSingleInstruction(mVU, badBranchAddr, (uptr)&mVUregs, mFC); - - xMOV(gprT3, badBranchAddr + 8); - iPC = bPC; - setCode(); - xSHR(gprT3, 3); - mVUallocVIb(mVU, gprT3, _It_); //Link to branch addr + 8 - - normJumpCompile(mVU, mFC, true); //Compile evil branch, just in time! - - eJMP.SetTarget(); - - incPC(2); // Point to delay slot of evil Branch (as the original branch isn't taken) - mVUcompileSingleInstruction(mVU, xPC, (uptr)&mVUregs, mFC); - - xMOV(gprT3, xPC); - iPC = bPC; - setCode(); - xSHR(gprT3, 3); - mVUallocVIb(mVU, gprT3, _It_); - - normJumpCompile(mVU, mFC, true); //Compile evil branch, just in time! -} void condBranch(mV, microFlagCycles& mFC, int JMPcc) { mVUsetupBranch(mVU, mFC); @@ -555,15 +500,6 @@ void condBranch(mV, microFlagCycles& mFC, int JMPcc) xCMP(ptr16[&mVU.branch], 0); incPC(3); - if (mVUlow.evilBranch) // We are dealing with an evil evil block, so we need to process this slightly differently - { - if (mVUlow.branch == 10 || mVUlow.branch == 2) // Evil branch is a jump of some measure - { - //Because of how it is linked, we need to make sure the target is recompiled if taken - condJumpProcessingEvil(mVU, mFC, JMPcc); - return; - } - } microBlock* bBlock; incPC2(1); // Check if Branch Non-Taken Side has already been recompiled blockCreate(iPC / 2); @@ -612,21 +548,6 @@ void normJump(mV, microFlagCycles& mFC) normBranchCompile(mVU, jumpAddr); return; } - if (mVUlow.badBranch) - { - incPC(3); - if (mVUlow.branch == 2 || mVUlow.branch == 10) //Delay slot BAL needs linking, only need to do BAL here, JALR done earlier - { - DevCon.Warning("Found %x in delay slot, linking - If game broken report to PCSX2 Team", mVUlow.branch == 2 ? "BAL" : "JALR"); - incPC(-2); - mVUallocVIa(mVU, gprT1, _Is_); - xADD(gprT1, 8); - xSHR(gprT1, 3); - incPC(2); - mVUallocVIb(mVU, gprT1, _It_); - } - incPC(-3); - } if (mVUup.dBit && doDBitHandling) { xTEST(ptr32[&VU0.VI[REG_FBRST].UL], (isVU1 ? 0x400 : 0x4)); diff --git a/pcsx2/x86/microVU_Compile.inl b/pcsx2/x86/microVU_Compile.inl index 2dc98ed027..a88d6e66a9 100644 --- a/pcsx2/x86/microVU_Compile.inl +++ b/pcsx2/x86/microVU_Compile.inl @@ -295,7 +295,7 @@ __ri void eBitWarning(mV) if (mVUpBlock->pState.blockType == 1) Console.Error("microVU%d Warning: Branch, E-bit, Branch! [%04x]", mVU.index, xPC); if (mVUpBlock->pState.blockType == 2) - Console.Error("microVU%d Warning: Branch, Branch, Branch! [%04x]", mVU.index, xPC); + DevCon.Warning("microVU%d Warning: Branch, Branch, Branch! [%04x]", mVU.index, xPC); incPC(2); if (curI & _Ebit_) { @@ -547,107 +547,6 @@ __fi void mVUinitFirstPass(microVU& mVU, uptr pState, u8* thisPtr) // Recompiler //------------------------------------------------------------------ -//This bastardized function is used when a linked branch is in a conditional delay slot. It's messy, it's horrible, but it works. -//Unfortunately linking the reg manually and using the normal evil block method seems to suck at this :/ -//If this is removed, test Evil Dead: Fistful of Boomstick (hangs going ingame), Mark of Kri (collision detection) -//and Tony Hawks Project 8 (graphics are half missing, requires Negative rounding when working) -void* mVUcompileSingleInstruction(microVU& mVU, u32 startPC, uptr pState, microFlagCycles& mFC) -{ - - u8* thisPtr = x86Ptr; - - // First Pass - iPC = startPC / 4; - - mVUbranch = 0; - incPC(1); - startLoop(mVU); - - mVUincCycles(mVU, 1); - mVUopU(mVU, 0); - mVUcheckBadOp(mVU); - if (curI & _Ebit_) - { - eBitPass1(mVU, g_branch); - DevCon.Warning("E Bit on single instruction"); - } - if (curI & _Dbit_) - { - mVUup.dBit = true; - } - if (curI & _Tbit_) - { - mVUup.tBit = true; - } - if (curI & _Mbit_) - { - mVUup.mBit = true; - DevCon.Warning("M Bit on single instruction"); - } - if (curI & _Ibit_) - { - mVUlow.isNOP = true; - mVUup.iBit = true; - DevCon.Warning("I Bit on single instruction"); - } - else - { - incPC(-1); - mVUopL(mVU, 0); - incPC(1); - } - - if (!mVUlow.isKick) - { - mVUlow.kickcycles = 1 + mVUstall; - mVUregs.xgkickcycles = 0; - } - else - { - mVUregs.xgkickcycles = 0; - mVUlow.kickcycles = 0; - } - - mVUsetCycles(mVU); - mVUinfo.readQ = mVU.q; - mVUinfo.writeQ = !mVU.q; - mVUinfo.readP = mVU.p && isVU1; - mVUinfo.writeP = !mVU.p && isVU1; - mVUcount++; - mVUsetFlagInfo(mVU); - incPC(1); - - - mVUsetFlags(mVU, mFC); // Sets Up Flag instances - mVUoptimizePipeState(mVU); // Optimize the End Pipeline State for nicer Block Linking - mVUdebugPrintBlocks(mVU, false); // Prints Start/End PC of blocks executed, for debugging... - - // Second Pass - iPC = startPC / 4; - setCode(); - - if (mVUup.mBit) - { - xOR(ptr32[&mVU.regs().flags], VUFLAG_MFLAGSET); - } - mVUexecuteInstruction(mVU); - - if (isVU1 && mVUlow.kickcycles && CHECK_XGKICKHACK) - { - mVU_XGKICK_SYNC(mVU, false); - } - - mVUincCycles(mVU, 1); //Just incase the is XGKick - if (mVUinfo.doXGKICK) - { - mVU_XGKICK_DELAY(mVU); - } - - mVUregs.xgkickcycles = 0; - - return thisPtr; -} - void mVUDoDBit(microVU& mVU, microFlagCycles* mFC) { xTEST(ptr32[&VU0.VI[REG_FBRST].UL], (isVU1 ? 0x400 : 0x4)); diff --git a/pcsx2/x86/microVU_Lower.inl b/pcsx2/x86/microVU_Lower.inl index a38c481032..45fd825809 100644 --- a/pcsx2/x86/microVU_Lower.inl +++ b/pcsx2/x86/microVU_Lower.inl @@ -1746,13 +1746,13 @@ void condEvilBranch(mV, int JMPcc) if (mVUlow.badBranch) { xMOV(ptr32[&mVU.branch], gprT1); - xMOV(ptr32[&mVU.badBranch], branchAddrN(mVU)); + xMOV(ptr32[&mVU.badBranch], branchAddr(mVU)); xCMP(gprT1b, 0); xForwardJump8 cJMP((JccComparisonType)JMPcc); - incPC(6); // Branch Not Taken Addr + 8 + incPC(4); // Branch Not Taken Addr xMOV(ptr32[&mVU.badBranch], xPC); - incPC(-6); + incPC(-4); cJMP.SetTarget(); return; } @@ -1772,7 +1772,7 @@ void condEvilBranch(mV, int JMPcc) xCMP(gprT1b, 0); xForwardJump8 cJMP((JccComparisonType)JMPcc); xMOV(gprT1, ptr32[&mVU.badBranch]); // Branch Not Taken - //xADD(gprT1, 8); // We have already executed 1 instruction from the original branch + xADD(gprT1, 8); // We have already executed 1 instruction from the original branch xMOV(ptr32[&mVU.evilBranch], gprT1); cJMP.SetTarget(); incPC(-2); @@ -1809,7 +1809,7 @@ mVUop(mVU_BAL) else { incPC(-2); - DevCon.Warning("Linking BAL from %s branch taken/nottaken target! - If game broken report to PCSX2 Team", branchSTR[mVUlow.branch & 0xf]); + DevCon.Warning("Linking BAL from %s branch taken/not taken target! - If game broken report to PCSX2 Team", branchSTR[mVUlow.branch & 0xf]); incPC(2); if (isEvilBlock) xMOV(gprT1, ptr32[&mVU.evilBranch]); @@ -1982,7 +1982,6 @@ void normJumpPass2(mV) //If delay slot is conditional, it uses badBranch to go to its target if (mVUlow.badBranch) { - xADD(gprT1, 8); xMOV(ptr32[&mVU.badBranch], gprT1); } } @@ -2024,24 +2023,13 @@ mVUop(mVU_JALR) else { incPC(-2); - if (mVUlow.branch >= 9) // Previous branch is a jump of some type so we need to take the branch address from the register it uses. - { - DevCon.Warning("Linking JALR from JALR/JR branch target! - If game broken report to PCSX2 Team"); - mVUallocVIa(mVU, gprT1, _Is_); - xADD(gprT1, 8); - xSHR(gprT1, 3); - incPC(2); - mVUallocVIb(mVU, gprT1, _It_); - } - else // Else we take the branch target of the previous branch - { - DevCon.Warning("Linking JALR from %d branch taken/nottaken target! - If game broken report to PCSX2 Team", branchSTR[mVUlow.branch & 0xf]); - xMOV(gprT1, ptr32[&mVU.badBranch]); - xADD(gprT1, 8); - xSHR(gprT1, 3); - incPC(2); - mVUallocVIb(mVU, gprT1, _It_); - } + DevCon.Warning("Linking JALR from %s branch taken/not taken target! - If game broken report to PCSX2 Team", branchSTR[mVUlow.branch & 0xf]); + incPC(2); + + xMOV(gprT1, ptr32[&mVU.badBranch]); + xADD(gprT1, 8); + xSHR(gprT1, 3); + mVUallocVIb(mVU, gprT1, _It_); } }