mirror of
https://github.com/WinampDesktop/winamp.git
synced 2025-06-18 19:35:46 -04:00
CPU: Implement instruction cache simulation
Implemented for all execution modes. Disabled by default in the cached interpreter and recompiler, always enabled in the pure interpreter.
This commit is contained in:
@ -139,8 +139,7 @@ static void ExecuteImpl()
|
||||
{
|
||||
if (HasPendingInterrupt())
|
||||
{
|
||||
// TODO: Fill in m_next_instruction...
|
||||
SafeReadMemoryWord(g_state.regs.pc, &g_state.next_instruction.bits);
|
||||
SafeReadInstruction(g_state.regs.pc, &g_state.next_instruction.bits);
|
||||
DispatchInterrupt();
|
||||
next_block_key = GetNextBlockKey();
|
||||
}
|
||||
@ -165,6 +164,9 @@ static void ExecuteImpl()
|
||||
LogCurrentState();
|
||||
#endif
|
||||
|
||||
if (g_settings.cpu_recompiler_icache)
|
||||
CheckAndUpdateICacheTags(block->icache_line_count, block->uncached_fetch_ticks);
|
||||
|
||||
InterpretCachedBlock<pgxp_mode>(*block);
|
||||
|
||||
if (g_state.pending_ticks >= g_state.downcount)
|
||||
@ -247,7 +249,7 @@ void ExecuteRecompiler()
|
||||
{
|
||||
if (HasPendingInterrupt())
|
||||
{
|
||||
SafeReadMemoryWord(g_state.regs.pc, &g_state.next_instruction.bits);
|
||||
SafeReadInstruction(g_state.regs.pc, &g_state.next_instruction.bits);
|
||||
DispatchInterrupt();
|
||||
}
|
||||
|
||||
@ -351,7 +353,8 @@ bool RevalidateBlock(CodeBlock* block)
|
||||
{
|
||||
for (const CodeBlockInstruction& cbi : block->instructions)
|
||||
{
|
||||
u32 new_code = Bus::ReadCacheableAddress(cbi.pc & PHYSICAL_MEMORY_ADDRESS_MASK);
|
||||
u32 new_code = 0;
|
||||
SafeReadInstruction(cbi.pc, &new_code);
|
||||
if (cbi.instruction.bits != new_code)
|
||||
{
|
||||
Log_DebugPrintf("Block 0x%08X changed at PC 0x%08X - %08X to %08X - recompiling.", block->GetPC(), cbi.pc,
|
||||
@ -395,16 +398,12 @@ bool CompileBlock(CodeBlock* block)
|
||||
__debugbreak();
|
||||
#endif
|
||||
|
||||
u32 last_cache_line = ICACHE_LINES;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
CodeBlockInstruction cbi = {};
|
||||
|
||||
const PhysicalMemoryAddress phys_addr = pc & PHYSICAL_MEMORY_ADDRESS_MASK;
|
||||
if (!Bus::IsCacheableAddress(phys_addr))
|
||||
break;
|
||||
|
||||
cbi.instruction.bits = Bus::ReadCacheableAddress(phys_addr);
|
||||
if (!IsInvalidInstruction(cbi.instruction))
|
||||
if (!SafeReadInstruction(pc, &cbi.instruction.bits) || !IsInvalidInstruction(cbi.instruction))
|
||||
break;
|
||||
|
||||
cbi.pc = pc;
|
||||
@ -416,6 +415,18 @@ bool CompileBlock(CodeBlock* block)
|
||||
cbi.has_load_delay = InstructionHasLoadDelay(cbi.instruction);
|
||||
cbi.can_trap = CanInstructionTrap(cbi.instruction, InUserMode());
|
||||
|
||||
if (g_settings.cpu_recompiler_icache)
|
||||
{
|
||||
const u32 icache_line = GetICacheLine(pc);
|
||||
if (icache_line != last_cache_line)
|
||||
{
|
||||
block->icache_line_count++;
|
||||
block->icache_line_count = GetICacheFillTicks(pc);
|
||||
last_cache_line = icache_line;
|
||||
}
|
||||
block->uncached_fetch_ticks += GetInstructionReadTicks(pc);
|
||||
}
|
||||
|
||||
// instruction is decoded now
|
||||
block->instructions.push_back(cbi);
|
||||
pc += sizeof(cbi.instruction.bits);
|
||||
|
Reference in New Issue
Block a user