Merge pull request #1174 from FioraAeterna/fifowriteaddrfix
JIT: properly remove FIFO write addresses when code is invalidated
This commit is contained in:
commit
7bce3fcdf9
|
@ -66,7 +66,7 @@ void BreakPoints::Add(const TBreakPoint& bp)
|
||||||
{
|
{
|
||||||
m_BreakPoints.push_back(bp);
|
m_BreakPoints.push_back(bp);
|
||||||
if (jit)
|
if (jit)
|
||||||
jit->GetBlockCache()->InvalidateICache(bp.iAddress, 4);
|
jit->GetBlockCache()->InvalidateICache(bp.iAddress, 4, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ void BreakPoints::Add(u32 em_address, bool temp)
|
||||||
m_BreakPoints.push_back(pt);
|
m_BreakPoints.push_back(pt);
|
||||||
|
|
||||||
if (jit)
|
if (jit)
|
||||||
jit->GetBlockCache()->InvalidateICache(em_address, 4);
|
jit->GetBlockCache()->InvalidateICache(em_address, 4, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ void BreakPoints::Remove(u32 em_address)
|
||||||
{
|
{
|
||||||
m_BreakPoints.erase(i);
|
m_BreakPoints.erase(i);
|
||||||
if (jit)
|
if (jit)
|
||||||
jit->GetBlockCache()->InvalidateICache(em_address, 4);
|
jit->GetBlockCache()->InvalidateICache(em_address, 4, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ void BreakPoints::Clear()
|
||||||
{
|
{
|
||||||
for (const TBreakPoint& bp : m_BreakPoints)
|
for (const TBreakPoint& bp : m_BreakPoints)
|
||||||
{
|
{
|
||||||
jit->GetBlockCache()->InvalidateICache(bp.iAddress, 4);
|
jit->GetBlockCache()->InvalidateICache(bp.iAddress, 4, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -327,7 +327,7 @@ void Interpreter::dcbf(UGeckoInstruction _inst)
|
||||||
NPC = PC + 12;
|
NPC = PC + 12;
|
||||||
}*/
|
}*/
|
||||||
u32 address = Helper_Get_EA_X(_inst);
|
u32 address = Helper_Get_EA_X(_inst);
|
||||||
JitInterface::InvalidateICache(address & ~0x1f, 32);
|
JitInterface::InvalidateICache(address & ~0x1f, 32, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::dcbi(UGeckoInstruction _inst)
|
void Interpreter::dcbi(UGeckoInstruction _inst)
|
||||||
|
@ -335,7 +335,7 @@ void Interpreter::dcbi(UGeckoInstruction _inst)
|
||||||
// Removes a block from data cache. Since we don't emulate the data cache, we don't need to do anything to the data cache
|
// Removes a block from data cache. Since we don't emulate the data cache, we don't need to do anything to the data cache
|
||||||
// However, we invalidate the jit block cache on dcbi
|
// However, we invalidate the jit block cache on dcbi
|
||||||
u32 address = Helper_Get_EA_X(_inst);
|
u32 address = Helper_Get_EA_X(_inst);
|
||||||
JitInterface::InvalidateICache(address & ~0x1f, 32);
|
JitInterface::InvalidateICache(address & ~0x1f, 32, false);
|
||||||
|
|
||||||
// The following detects a situation where the game is writing to the dcache at the address being DMA'd. As we do not
|
// The following detects a situation where the game is writing to the dcache at the address being DMA'd. As we do not
|
||||||
// have dcache emulation, invalid data is being DMA'd causing audio glitches. The following code detects this and
|
// have dcache emulation, invalid data is being DMA'd causing audio glitches. The following code detects this and
|
||||||
|
@ -359,7 +359,7 @@ void Interpreter::dcbst(UGeckoInstruction _inst)
|
||||||
// Cache line flush. Since we don't emulate the data cache, we don't need to do anything.
|
// Cache line flush. Since we don't emulate the data cache, we don't need to do anything.
|
||||||
// Invalidate the jit block cache on dcbst in case new code has been loaded via the data cache
|
// Invalidate the jit block cache on dcbst in case new code has been loaded via the data cache
|
||||||
u32 address = Helper_Get_EA_X(_inst);
|
u32 address = Helper_Get_EA_X(_inst);
|
||||||
JitInterface::InvalidateICache(address & ~0x1f, 32);
|
JitInterface::InvalidateICache(address & ~0x1f, 32, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::dcbt(UGeckoInstruction _inst)
|
void Interpreter::dcbt(UGeckoInstruction _inst)
|
||||||
|
|
|
@ -159,7 +159,7 @@ bool Jit64::HandleFault(uintptr_t access_address, SContext* ctx)
|
||||||
// CALLs, but we can't yet. Fake the downcount so we're forced to the
|
// CALLs, but we can't yet. Fake the downcount so we're forced to the
|
||||||
// dispatcher (no block linking), and clear the cache so we're sent to
|
// dispatcher (no block linking), and clear the cache so we're sent to
|
||||||
// Jit. Yeah, it's kind of gross.
|
// Jit. Yeah, it's kind of gross.
|
||||||
GetBlockCache()->InvalidateICache(0, 0xffffffff);
|
GetBlockCache()->InvalidateICache(0, 0xffffffff, true);
|
||||||
CoreTiming::ForceExceptionCheck(0);
|
CoreTiming::ForceExceptionCheck(0);
|
||||||
m_clear_cache_asap = true;
|
m_clear_cache_asap = true;
|
||||||
|
|
||||||
|
|
|
@ -327,7 +327,7 @@ using namespace Gen;
|
||||||
WriteDestroyBlock(b.checkedEntry, b.originalAddress);
|
WriteDestroyBlock(b.checkedEntry, b.originalAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitBaseBlockCache::InvalidateICache(u32 address, const u32 length)
|
void JitBaseBlockCache::InvalidateICache(u32 address, const u32 length, bool forced)
|
||||||
{
|
{
|
||||||
// Convert the logical address to a physical address for the block map
|
// Convert the logical address to a physical address for the block map
|
||||||
u32 pAddr = address & 0x1FFFFFFF;
|
u32 pAddr = address & 0x1FFFFFFF;
|
||||||
|
@ -358,6 +358,16 @@ using namespace Gen;
|
||||||
{
|
{
|
||||||
block_map.erase(it1, it2);
|
block_map.erase(it1, it2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the code was actually modified, we need to clear the relevant entries from the
|
||||||
|
// FIFO write address cache, so we don't end up with FIFO checks in places they shouldn't
|
||||||
|
// be (this can clobber flags, and thus break any optimization that relies on flags
|
||||||
|
// being in the right place between instructions).
|
||||||
|
if (!forced)
|
||||||
|
{
|
||||||
|
for (u32 i = address; i < address + length; i += 4)
|
||||||
|
jit->js.fifoWriteAddresses.erase(i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -161,7 +161,7 @@ public:
|
||||||
CompiledCode GetCompiledCodeFromBlock(int block_num);
|
CompiledCode GetCompiledCodeFromBlock(int block_num);
|
||||||
|
|
||||||
// DOES NOT WORK CORRECTLY WITH INLINING
|
// DOES NOT WORK CORRECTLY WITH INLINING
|
||||||
void InvalidateICache(u32 address, const u32 length);
|
void InvalidateICache(u32 address, const u32 length, bool forced);
|
||||||
void DestroyBlock(int block_num, bool invalidate);
|
void DestroyBlock(int block_num, bool invalidate);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -210,10 +210,10 @@ namespace JitInterface
|
||||||
jit->GetBlockCache()->Clear();
|
jit->GetBlockCache()->Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void InvalidateICache(u32 address, u32 size)
|
void InvalidateICache(u32 address, u32 size, bool forced)
|
||||||
{
|
{
|
||||||
if (jit)
|
if (jit)
|
||||||
jit->GetBlockCache()->InvalidateICache(address, size);
|
jit->GetBlockCache()->InvalidateICache(address, size, forced);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 ReadOpcodeJIT(u32 _Address)
|
u32 ReadOpcodeJIT(u32 _Address)
|
||||||
|
@ -263,7 +263,7 @@ namespace JitInterface
|
||||||
exception_addresses->insert(PC);
|
exception_addresses->insert(PC);
|
||||||
|
|
||||||
// Invalidate the JIT block so that it gets recompiled with the external exception check included.
|
// Invalidate the JIT block so that it gets recompiled with the external exception check included.
|
||||||
jit->GetBlockCache()->InvalidateICache(PC, 4);
|
jit->GetBlockCache()->InvalidateICache(PC, 4, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,8 @@ namespace JitInterface
|
||||||
|
|
||||||
void ClearSafe();
|
void ClearSafe();
|
||||||
|
|
||||||
void InvalidateICache(u32 address, u32 size);
|
// If "forced" is true, a recompile is being requested on code that hasn't been modified.
|
||||||
|
void InvalidateICache(u32 address, u32 size, bool forced);
|
||||||
|
|
||||||
void CompileExceptionCheck(int type);
|
void CompileExceptionCheck(int type);
|
||||||
|
|
||||||
|
|
|
@ -95,7 +95,7 @@ namespace PowerPC
|
||||||
lookup_table[((tags[set][i] << 7) | set) & 0xfffff] = 0xff;
|
lookup_table[((tags[set][i] << 7) | set) & 0xfffff] = 0xff;
|
||||||
}
|
}
|
||||||
valid[set] = 0;
|
valid[set] = 0;
|
||||||
JitInterface::InvalidateICache(addr & ~0x1f, 32);
|
JitInterface::InvalidateICache(addr & ~0x1f, 32, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 InstructionCache::ReadInstruction(u32 addr)
|
u32 InstructionCache::ReadInstruction(u32 addr)
|
||||||
|
|
|
@ -288,7 +288,7 @@ void CCodeWindow::SingleStep()
|
||||||
{
|
{
|
||||||
if (CCPU::IsStepping())
|
if (CCPU::IsStepping())
|
||||||
{
|
{
|
||||||
JitInterface::InvalidateICache(PC, 4);
|
JitInterface::InvalidateICache(PC, 4, true);
|
||||||
CCPU::StepOpcode(&sync_event);
|
CCPU::StepOpcode(&sync_event);
|
||||||
wxThread::Sleep(20);
|
wxThread::Sleep(20);
|
||||||
// need a short wait here
|
// need a short wait here
|
||||||
|
|
Loading…
Reference in New Issue