diff --git a/Core/MIPS/JitCommon/JitState.h b/Core/MIPS/JitCommon/JitState.h index c77481499d..0bb7007a6e 100644 --- a/Core/MIPS/JitCommon/JitState.h +++ b/Core/MIPS/JitCommon/JitState.h @@ -64,6 +64,8 @@ namespace MIPSComp { u32 compilerPC; u32 blockStart; + u32 lastContinuedPC; + u32 initialBlockSize; int nextExit; bool cancel; bool inDelaySlot; diff --git a/Core/MIPS/x86/CompBranch.cpp b/Core/MIPS/x86/CompBranch.cpp index 0f391805db..ec8979122c 100644 --- a/Core/MIPS/x86/CompBranch.cpp +++ b/Core/MIPS/x86/CompBranch.cpp @@ -215,6 +215,7 @@ void Jit::CompBranchExits(CCFlags cc, u32 targetAddr, u32 notTakenAddr, bool del if (likely) CompileDelaySlot(DELAYSLOT_NICE); + AddContinuedBlock(targetAddr); // Account for the increment in the loop. js.compilerPC = targetAddr - 4; // In case the delay slot was a break or something. @@ -328,6 +329,7 @@ void Jit::BranchRSRTComp(MIPSOpcode op, Gen::CCFlags cc, bool likely) // Branch taken. Always compile the delay slot, and then go to dest. CompileDelaySlot(DELAYSLOT_NICE); + AddContinuedBlock(targetAddr); // Account for the increment in the loop. js.compilerPC = targetAddr - 4; // In case the delay slot was a break or something. @@ -406,6 +408,7 @@ void Jit::BranchRSZeroComp(MIPSOpcode op, Gen::CCFlags cc, bool andLink, bool li if (andLink) gpr.SetImm(MIPS_REG_RA, js.compilerPC + 8); + AddContinuedBlock(targetAddr); // Account for the increment in the loop. js.compilerPC = targetAddr - 4; // In case the delay slot was a break or something. @@ -585,6 +588,7 @@ void Jit::Comp_Jump(MIPSOpcode op) { CompileDelaySlot(DELAYSLOT_NICE); if (jo.continueJumps && js.numInstructions < jo.continueMaxInstructions) { + AddContinuedBlock(targetAddr); // Account for the increment in the loop. js.compilerPC = targetAddr - 4; // In case the delay slot was a break or something. @@ -609,6 +613,7 @@ void Jit::Comp_Jump(MIPSOpcode op) { CompileDelaySlot(DELAYSLOT_NICE); if (jo.continueJumps && js.numInstructions < jo.continueMaxInstructions) { + AddContinuedBlock(targetAddr); // Account for the increment in the loop. js.compilerPC = targetAddr - 4; // In case the delay slot was a break or something. @@ -679,6 +684,7 @@ void Jit::Comp_JumpReg(MIPSOpcode op) if (jo.continueJumps && gpr.IsImm(rs) && js.numInstructions < jo.continueMaxInstructions) { + AddContinuedBlock(gpr.GetImm(rs)); // Account for the increment in the loop. js.compilerPC = gpr.GetImm(rs) - 4; // In case the delay slot was a break or something. diff --git a/Core/MIPS/x86/Jit.cpp b/Core/MIPS/x86/Jit.cpp index acdf203074..6d3cf01e75 100644 --- a/Core/MIPS/x86/Jit.cpp +++ b/Core/MIPS/x86/Jit.cpp @@ -116,8 +116,6 @@ static void JitLogMiss(MIPSOpcode op) JitOptions::JitOptions() { enableBlocklink = true; - // WARNING: These options don't work properly with cache clearing. - // Need to find a smart way to handle before enabling. immBranches = false; continueBranches = false; continueJumps = false; @@ -396,6 +394,8 @@ const u8 *Jit::DoJit(u32 em_address, JitBlock *b) { js.cancel = false; js.blockStart = js.compilerPC = mips_->pc; + js.lastContinuedPC = 0; + js.initialBlockSize = 0; js.nextExit = 0; js.downcountAmount = 0; js.curBlock = b; @@ -466,10 +466,27 @@ const u8 *Jit::DoJit(u32 em_address, JitBlock *b) b->codeSize = (u32)(GetCodePtr() - b->normalEntry); NOP(); AlignCode4(); - b->originalSize = js.numInstructions; + if (js.lastContinuedPC == 0) + b->originalSize = js.numInstructions; + else + { + // We continued at least once. Add the last proxy and set the originalSize correctly. + blocks.ProxyBlock(js.blockStart, js.lastContinuedPC, (js.compilerPC - js.lastContinuedPC) / sizeof(u32), GetCodePtr()); + b->originalSize = js.initialBlockSize; + } return b->normalEntry; } +void Jit::AddContinuedBlock(u32 dest) +{ + // The first block is the root block. When we continue, we create proxy blocks after that. + if (js.lastContinuedPC == 0) + js.initialBlockSize = js.numInstructions; + else + blocks.ProxyBlock(js.blockStart, js.lastContinuedPC, (js.compilerPC - js.lastContinuedPC) / sizeof(u32), GetCodePtr()); + js.lastContinuedPC = dest; +} + bool Jit::DescribeCodePtr(const u8 *ptr, std::string &name) { u32 jitAddr = blocks.GetAddressFromBlockPtr(ptr); diff --git a/Core/MIPS/x86/Jit.h b/Core/MIPS/x86/Jit.h index bc3e7f0f0b..a273e23ba3 100644 --- a/Core/MIPS/x86/Jit.h +++ b/Core/MIPS/x86/Jit.h @@ -193,6 +193,7 @@ private: CompileDelaySlot(flags, &state); } void EatInstruction(MIPSOpcode op); + void AddContinuedBlock(u32 dest); void WriteExit(u32 destination, int exit_num); void WriteExitDestInReg(X64Reg reg);