From 61a0a3c7d8820e7b53f8e2e837d7acd8509f6465 Mon Sep 17 00:00:00 2001 From: Patrick Mackinlay Date: Fri, 22 Sep 2023 15:52:58 +0700 Subject: mips1: cache diagnostic fixes * implement cvt.w.fmt infinity/NaN exception --- src/devices/cpu/mips/mips1.cpp | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/devices/cpu/mips/mips1.cpp b/src/devices/cpu/mips/mips1.cpp index da2b9f666c6..dafef5bea3f 100644 --- a/src/devices/cpu/mips/mips1.cpp +++ b/src/devices/cpu/mips/mips1.cpp @@ -1269,6 +1269,9 @@ std::tuple mips1core_device_b // select line within cache based on low address bits struct cache::line &l = c.line[(address & (c.size - 1)) >> 2]; + // clear cache parity error + SR &= ~SR_PE; + // compare cache line tag against upper address bits and line valid bit bool const miss = (l.tag ^ address) & (-c.size | cache::line::INV); @@ -1355,7 +1358,7 @@ template std::enable_if_t void mips1core_device_base::store(u32 addres { // when isolated, full word stores update the cache, while partial word // stores invalidate the cache line - auto [l, miss] = cache_lookup(address, true); + auto [l, miss] = cache_lookup(address & ~0xe000'0000, true); if constexpr (Aligned && sizeof(T) == 4) l.update(data, mem_mask); @@ -1844,7 +1847,15 @@ void mips1_device_base::handle_cop1(u32 const op) set_cop1_reg(FDREG >> 1, f32_to_f64(float32_t{ u32(m_f[FSREG >> 1]) }).v); break; case 0x24: // CVT.W.S - set_cop1_reg(FDREG >> 1, f32_to_i32(float32_t{ u32(m_f[FSREG >> 1]) }, softfloat_roundingMode, true)); + if (BIT(m_f[FSREG >> 1], 23, 8) == 0xff) + { + // +/- infinity or NaN + m_fcr31 &= ~FCR31_CM; + m_fcr31 |= FCR31_CE; + execute_set_input(m_fpu_irq, ASSERT_LINE); + } + else + set_cop1_reg(FDREG >> 1, f32_to_i32(float32_t{ u32(m_f[FSREG >> 1]) }, softfloat_roundingMode, true)); break; case 0x30: // C.F.S (false) @@ -2028,7 +2039,15 @@ void mips1_device_base::handle_cop1(u32 const op) set_cop1_reg(FDREG >> 1, f64_to_f32(float64_t{ m_f[FSREG >> 1] }).v); break; case 0x24: // CVT.W.D - set_cop1_reg(FDREG >> 1, f64_to_i32(float64_t{ m_f[FSREG >> 1] }, softfloat_roundingMode, true)); + if (BIT(m_f[FSREG >> 1], 52, 11) == 0x7ff) + { + // +/- infinity or NaN + m_fcr31 &= ~FCR31_CM; + m_fcr31 |= FCR31_CE; + execute_set_input(m_fpu_irq, ASSERT_LINE); + } + else + set_cop1_reg(FDREG >> 1, f64_to_i32(float64_t{ m_f[FSREG >> 1] }, softfloat_roundingMode, true)); break; case 0x30: // C.F.D (false) -- cgit v1.2.3