Jit64: Check downcount at block exit, not block entry
This commit is contained in:
parent
490dffc791
commit
5236dc31a6
|
@ -442,21 +442,36 @@ void Jit64::JustWriteExit(u32 destination, bool bl, u32 after)
|
||||||
JitBlock::LinkData linkData;
|
JitBlock::LinkData linkData;
|
||||||
linkData.exitAddress = destination;
|
linkData.exitAddress = destination;
|
||||||
linkData.linkStatus = false;
|
linkData.linkStatus = false;
|
||||||
|
linkData.call = bl;
|
||||||
|
|
||||||
MOV(32, PPCSTATE(pc), Imm32(destination));
|
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)
|
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);
|
POP(RSCRATCH);
|
||||||
JustWriteExit(after, false, 0);
|
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)
|
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
|
// TODO: Test if this or AlignCode16 make a difference from GetCodePtr
|
||||||
u8* const start = AlignCode4();
|
u8* const start = AlignCode4();
|
||||||
b->checkedEntry = start;
|
b->checkedEntry = start;
|
||||||
|
b->normalEntry = 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;
|
|
||||||
|
|
||||||
// Used to get a trace of the last few blocks before a crash, sometimes VERY useful
|
// Used to get a trace of the last few blocks before a crash, sometimes VERY useful
|
||||||
if (ImHereDebug)
|
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);
|
LogGeneratedX86(code_block.m_num_instructions, m_code_buffer, start, b);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return normal_entry;
|
return start;
|
||||||
}
|
}
|
||||||
|
|
||||||
BitSet8 Jit64::ComputeStaticGQRs(const PPCAnalyst::CodeBlock& cb) const
|
BitSet8 Jit64::ComputeStaticGQRs(const PPCAnalyst::CodeBlock& cb) const
|
||||||
|
|
|
@ -15,9 +15,9 @@ JitBlockCache::JitBlockCache(JitBase& jit) : JitBaseBlockCache{jit}
|
||||||
void JitBlockCache::WriteLinkBlock(const JitBlock::LinkData& source, const JitBlock* dest)
|
void JitBlockCache::WriteLinkBlock(const JitBlock::LinkData& source, const JitBlock* dest)
|
||||||
{
|
{
|
||||||
u8* location = source.exitPtrs;
|
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);
|
Gen::XEmitter emit(location);
|
||||||
if (*location == 0xE8)
|
if (source.call)
|
||||||
{
|
{
|
||||||
emit.CALL(address);
|
emit.CALL(address);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue