CPU: Use partial icache fills for non-line-aligned addresses

This commit is contained in:
Connor McLaughlin
2020-10-29 23:04:36 +10:00
parent 3b3ad0c1cb
commit be63d893cd
4 changed files with 46 additions and 34 deletions

View File

@ -1,6 +1,6 @@
#pragma once
#include "cpu_core.h"
#include "bus.h"
#include "cpu_core.h"
namespace CPU {
@ -11,7 +11,7 @@ void RaiseException(u32 CAUSE_bits, u32 EPC);
ALWAYS_INLINE bool HasPendingInterrupt()
{
return g_state.cop0_regs.sr.IEc &&
(((g_state.cop0_regs.cause.bits & g_state.cop0_regs.sr.bits) & (UINT32_C(0xFF) << 8)) != 0);
(((g_state.cop0_regs.cause.bits & g_state.cop0_regs.sr.bits) & (UINT32_C(0xFF) << 8)) != 0);
}
ALWAYS_INLINE void CheckForPendingInterrupt()
@ -40,10 +40,23 @@ ALWAYS_INLINE u32 GetICacheTagForAddress(VirtualMemoryAddress address)
{
return (address & ICACHE_TAG_ADDRESS_MASK);
}
ALWAYS_INLINE u32 GetICacheFillTagForAddress(VirtualMemoryAddress address)
{
static const u32 invalid_bits[4] = {0, 1, 3, 7};
return GetICacheTagForAddress(address) | invalid_bits[(address >> 2) & 0x03u];
}
ALWAYS_INLINE u32 GetICacheTagMaskForAddress(VirtualMemoryAddress address)
{
const u32 offset = (address >> 2) & 0x03u;
static const u32 mask[4] = {ICACHE_TAG_ADDRESS_MASK | 1, ICACHE_TAG_ADDRESS_MASK | 2, ICACHE_TAG_ADDRESS_MASK | 4,
ICACHE_TAG_ADDRESS_MASK | 8};
return mask[(address >> 2) & 0x03u];
}
ALWAYS_INLINE bool CompareICacheTag(VirtualMemoryAddress address)
{
const u32 line = GetICacheLine(address);
return (g_state.icache_tags[line] == GetICacheTagForAddress(address));
return ((g_state.icache_tags[line] & GetICacheTagMaskForAddress(address)) == GetICacheTagForAddress(address));
}
TickCount GetInstructionReadTicks(VirtualMemoryAddress address);