summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorMerryMage <MerryMage@users.noreply.github.com>2018-12-21 21:21:02 +0000
committerMerryMage <MerryMage@users.noreply.github.com>2018-12-23 18:03:29 +0000
commit5236dc31a6deabc85608b41553e5d5aca61c7a67 (patch)
tree36dfa10e4f4d5893fd42e739bd47fb24d353b4d1 /Source/Core
parent490dffc7915586be9bfdf2f7792f24b040924724 (diff)
Jit64: Check downcount at block exit, not block entry
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/PowerPC/Jit64/Jit.cpp42
-rw-r--r--Source/Core/Core/PowerPC/Jit64Common/BlockCache.cpp4
2 files changed, 26 insertions, 20 deletions
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);
}