diff --git a/Source/Core/Core/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/PowerPC/Jit64/Jit.cpp index 2cdad6e54d..b2e893e2c0 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit.cpp @@ -442,21 +442,36 @@ void Jit64::JustWriteExit(u32 destination, bool bl, u32 after) JitBlock::LinkData linkData; linkData.exitAddress = destination; linkData.linkStatus = false; + linkData.call = bl; MOV(32, PPCSTATE(pc), Imm32(destination)); - linkData.exitPtrs = GetWritableCodePtr(); - if (bl) - CALL(asm_routines.dispatcher); - else - JMP(asm_routines.dispatcher, true); - - b->linkData.push_back(linkData); + // Perform downcount flag check, followed by the requested exit if (bl) { + FixupBranch do_timing = J_CC(CC_LE, true); + SwitchToFarCode(); + SetJumpTarget(do_timing); + CALL(asm_routines.do_timing); + FixupBranch after_fixup = J(true); + SwitchToNearCode(); + + linkData.exitPtrs = GetWritableCodePtr(); + CALL(asm_routines.dispatcher_no_check); + + SetJumpTarget(after_fixup); POP(RSCRATCH); JustWriteExit(after, false, 0); } + else + { + J_CC(CC_LE, asm_routines.do_timing); + + linkData.exitPtrs = GetWritableCodePtr(); + JMP(asm_routines.dispatcher_no_check, true); + } + + b->linkData.push_back(linkData); } void Jit64::WriteExitDestInRSCRATCH(bool bl, u32 after) @@ -660,16 +675,7 @@ u8* Jit64::DoJit(u32 em_address, JitBlock* b, u32 nextPC) // TODO: Test if this or AlignCode16 make a difference from GetCodePtr u8* const start = AlignCode4(); b->checkedEntry = start; - - // Downcount flag check. The last block decremented downcounter, and the flag should still be - // available. - FixupBranch skip = J_CC(CC_G); - MOV(32, PPCSTATE(pc), Imm32(js.blockStart)); - JMP(asm_routines.do_timing, true); // downcount hit zero - go do_timing. - SetJumpTarget(skip); - - u8* const normal_entry = GetWritableCodePtr(); - b->normalEntry = normal_entry; + b->normalEntry = start; // Used to get a trace of the last few blocks before a crash, sometimes VERY useful if (ImHereDebug) @@ -955,7 +961,7 @@ u8* Jit64::DoJit(u32 em_address, JitBlock* b, u32 nextPC) LogGeneratedX86(code_block.m_num_instructions, m_code_buffer, start, b); #endif - return normal_entry; + return start; } BitSet8 Jit64::ComputeStaticGQRs(const PPCAnalyst::CodeBlock& cb) const diff --git a/Source/Core/Core/PowerPC/Jit64Common/BlockCache.cpp b/Source/Core/Core/PowerPC/Jit64Common/BlockCache.cpp index 096a46f57d..e857226265 100644 --- a/Source/Core/Core/PowerPC/Jit64Common/BlockCache.cpp +++ b/Source/Core/Core/PowerPC/Jit64Common/BlockCache.cpp @@ -15,9 +15,9 @@ JitBlockCache::JitBlockCache(JitBase& jit) : JitBaseBlockCache{jit} void JitBlockCache::WriteLinkBlock(const JitBlock::LinkData& source, const JitBlock* dest) { u8* location = source.exitPtrs; - const u8* address = dest ? dest->checkedEntry : m_jit.GetAsmRoutines()->dispatcher; + const u8* address = dest ? dest->checkedEntry : m_jit.GetAsmRoutines()->dispatcher_no_check; Gen::XEmitter emit(location); - if (*location == 0xE8) + if (source.call) { emit.CALL(address); }