mirror of
https://github.com/holub/mame
synced 2025-04-22 16:31:49 +03:00
mips1: improved cache logic for partial word store
This commit is contained in:
parent
f3845348ba
commit
ab3ad7671d
@ -215,7 +215,7 @@ DEFINE_DEVICE_TYPE(SONYPS2_IOP, iop_device, "sonyiop", "Sony Playstation 2
|
||||
|
||||
ALLOW_SAVE_TYPE(mips1core_device_base::branch_state);
|
||||
|
||||
mips1core_device_base::mips1core_device_base(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock, u32 cpurev, size_t icache_size, size_t dcache_size)
|
||||
mips1core_device_base::mips1core_device_base(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock, u32 cpurev, size_t icache_size, size_t dcache_size, bool cache_pws)
|
||||
: cpu_device(mconfig, type, tag, owner, clock)
|
||||
, m_program_config_be("program", ENDIANNESS_BIG, 32, 32)
|
||||
, m_program_config_le("program", ENDIANNESS_LITTLE, 32, 32)
|
||||
@ -225,69 +225,70 @@ mips1core_device_base::mips1core_device_base(machine_config const &mconfig, devi
|
||||
, m_icache(icache_size)
|
||||
, m_dcache(dcache_size)
|
||||
, m_cache((icache_size && dcache_size) ? CACHED : UNCACHED)
|
||||
, m_cache_pws(cache_pws)
|
||||
, m_in_brcond(*this, 0)
|
||||
{
|
||||
}
|
||||
|
||||
mips1_device_base::mips1_device_base(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock, u32 cpurev, size_t icache_size, size_t dcache_size)
|
||||
: mips1core_device_base(mconfig, type, tag, owner, clock, cpurev, icache_size, dcache_size)
|
||||
mips1_device_base::mips1_device_base(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock, u32 cpurev, size_t icache_size, size_t dcache_size, bool cache_pws)
|
||||
: mips1core_device_base(mconfig, type, tag, owner, clock, cpurev, icache_size, dcache_size, cache_pws)
|
||||
, m_fcr0(0)
|
||||
{
|
||||
}
|
||||
|
||||
r2000_device::r2000_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock, size_t icache_size, size_t dcache_size)
|
||||
: mips1_device_base(mconfig, R2000, tag, owner, clock, 0x0100, icache_size, dcache_size)
|
||||
: mips1_device_base(mconfig, R2000, tag, owner, clock, 0x0100, icache_size, dcache_size, false)
|
||||
{
|
||||
}
|
||||
|
||||
r2000a_device::r2000a_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock, size_t icache_size, size_t dcache_size)
|
||||
: mips1_device_base(mconfig, R2000A, tag, owner, clock, 0x0210, icache_size, dcache_size)
|
||||
: mips1_device_base(mconfig, R2000A, tag, owner, clock, 0x0210, icache_size, dcache_size, false)
|
||||
{
|
||||
}
|
||||
|
||||
r3000_device::r3000_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock, size_t icache_size, size_t dcache_size)
|
||||
: mips1_device_base(mconfig, R3000, tag, owner, clock, 0x0220, icache_size, dcache_size)
|
||||
: mips1_device_base(mconfig, R3000, tag, owner, clock, 0x0220, icache_size, dcache_size, false)
|
||||
{
|
||||
}
|
||||
|
||||
r3000a_device::r3000a_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock, size_t icache_size, size_t dcache_size)
|
||||
: mips1_device_base(mconfig, R3000A, tag, owner, clock, 0x0230, icache_size, dcache_size)
|
||||
: mips1_device_base(mconfig, R3000A, tag, owner, clock, 0x0230, icache_size, dcache_size, false)
|
||||
{
|
||||
}
|
||||
|
||||
r3041_device::r3041_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
|
||||
: mips1core_device_base(mconfig, R3041, tag, owner, clock, 0x0700, 2048, 512)
|
||||
: mips1core_device_base(mconfig, R3041, tag, owner, clock, 0x0700, 2048, 512, true)
|
||||
{
|
||||
}
|
||||
|
||||
r3051_device::r3051_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
|
||||
: mips1core_device_base(mconfig, R3051, tag, owner, clock, 0x0200, 4096, 2048)
|
||||
: mips1core_device_base(mconfig, R3051, tag, owner, clock, 0x0200, 4096, 2048, true)
|
||||
{
|
||||
}
|
||||
|
||||
r3052_device::r3052_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
|
||||
: mips1core_device_base(mconfig, R3052, tag, owner, clock, 0x0200, 8192, 2048)
|
||||
: mips1core_device_base(mconfig, R3052, tag, owner, clock, 0x0200, 8192, 2048, true)
|
||||
{
|
||||
}
|
||||
|
||||
r3052e_device::r3052e_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
|
||||
: mips1_device_base(mconfig, R3052E, tag, owner, clock, 0x0200, 8192, 2048)
|
||||
: mips1_device_base(mconfig, R3052E, tag, owner, clock, 0x0200, 8192, 2048, true)
|
||||
{
|
||||
}
|
||||
|
||||
r3071_device::r3071_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock, size_t icache_size, size_t dcache_size)
|
||||
: mips1_device_base(mconfig, R3071, tag, owner, clock, 0x0200, icache_size, dcache_size)
|
||||
: mips1_device_base(mconfig, R3071, tag, owner, clock, 0x0200, icache_size, dcache_size, true)
|
||||
{
|
||||
}
|
||||
|
||||
r3081_device::r3081_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock, size_t icache_size, size_t dcache_size)
|
||||
: mips1_device_base(mconfig, R3081, tag, owner, clock, 0x0200, icache_size, dcache_size)
|
||||
: mips1_device_base(mconfig, R3081, tag, owner, clock, 0x0200, icache_size, dcache_size, true)
|
||||
{
|
||||
set_fpu(0x0300);
|
||||
}
|
||||
|
||||
iop_device::iop_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
|
||||
: mips1core_device_base(mconfig, SONYPS2_IOP, tag, owner, clock, 0x001f, 4096, 1024)
|
||||
: mips1core_device_base(mconfig, SONYPS2_IOP, tag, owner, clock, 0x001f, 4096, 1024, false)
|
||||
{
|
||||
m_endianness = ENDIANNESS_LITTLE;
|
||||
}
|
||||
@ -1390,15 +1391,30 @@ template <typename T, bool Aligned> void mips1core_device_base::store(u32 addres
|
||||
{
|
||||
auto [l, miss] = cache_lookup(address, sizeof(T) == 4);
|
||||
|
||||
if (!miss)
|
||||
// cached full word stores always update the cache
|
||||
if constexpr (Aligned && sizeof(T) == 4)
|
||||
l.update(data);
|
||||
else if (!miss)
|
||||
{
|
||||
unsigned const shift = shift_factor<T>(address);
|
||||
if (!m_cache_pws)
|
||||
{
|
||||
// reload the cache line from memory
|
||||
u32 const data = space(AS_PROGRAM).read_dword(address);
|
||||
if (m_bus_error)
|
||||
{
|
||||
m_bus_error = false;
|
||||
generate_exception(EXCEPTION_BUSDATA);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
l.update(data);
|
||||
}
|
||||
|
||||
// merge data into the cache
|
||||
unsigned const shift = shift_factor<T>(address);
|
||||
l.update(u32(data) << shift, u32(mem_mask) << shift);
|
||||
}
|
||||
else if constexpr (Aligned && sizeof(T) == 4)
|
||||
// only full word stores update the cache after a miss
|
||||
l.update(data, mem_mask);
|
||||
}
|
||||
|
||||
// uncached or write-through store
|
||||
|
@ -17,7 +17,7 @@ public:
|
||||
void berr_w(int state) { m_bus_error = bool(state); }
|
||||
|
||||
protected:
|
||||
mips1core_device_base(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock, u32 cpurev, size_t icache_size, size_t dcache_size);
|
||||
mips1core_device_base(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock, u32 cpurev, size_t icache_size, size_t dcache_size, bool cache_pws);
|
||||
|
||||
// device_t implementation
|
||||
virtual void device_start() override;
|
||||
@ -136,6 +136,7 @@ protected:
|
||||
struct cache m_icache;
|
||||
struct cache m_dcache;
|
||||
translate_result const m_cache;
|
||||
bool const m_cache_pws; // cache supports partial-word store
|
||||
|
||||
// I/O
|
||||
devcb_read_line::array<4> m_in_brcond;
|
||||
@ -160,7 +161,7 @@ public:
|
||||
void set_fpu(u32 revision, unsigned interrupt = 3) { m_fcr0 = revision; m_fpu_irq = interrupt; }
|
||||
|
||||
protected:
|
||||
mips1_device_base(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock, u32 cpurev, size_t icache_size, size_t dcache_size);
|
||||
mips1_device_base(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock, u32 cpurev, size_t icache_size, size_t dcache_size, bool cache_pws);
|
||||
|
||||
// device_t implementation
|
||||
virtual void device_start() override;
|
||||
|
Loading…
Reference in New Issue
Block a user