From 4ada281e4c75650b656ee24738c4f27de5f7b498 Mon Sep 17 00:00:00 2001 From: Patrick Mackinlay Date: Mon, 18 Feb 2019 17:09:01 +0700 Subject: mips3: trivial changes (nw) * use the new 64x64 multiply helpers * make sure unordered exceptions are generated by abs.fmt * correct an unimportant drc flag --- src/devices/cpu/mips/mips3.cpp | 38 ++---------------------------- src/devices/cpu/mips/mips3fe.cpp | 4 ++-- src/devices/cpu/mips/r4000.cpp | 51 +++++++--------------------------------- 3 files changed, 13 insertions(+), 80 deletions(-) diff --git a/src/devices/cpu/mips/mips3.cpp b/src/devices/cpu/mips/mips3.cpp index df9ff7f96ba..178d81fadbd 100644 --- a/src/devices/cpu/mips/mips3.cpp +++ b/src/devices/cpu/mips/mips3.cpp @@ -3530,47 +3530,13 @@ void mips3_device::handle_special(uint32_t op) m_core->icount -= 35; break; case 0x1c: /* DMULT */ - { - uint64_t a_hi = (uint32_t)(RSVAL64 >> 32); - uint64_t b_hi = (uint32_t)(RTVAL64 >> 32); - uint64_t a_lo = (uint32_t)RSVAL64; - uint64_t b_lo = (uint32_t)RTVAL64; - uint64_t p1 = a_lo * b_lo; - uint64_t p2 = a_hi * b_lo; - uint64_t p3 = a_lo * b_hi; - uint64_t p4 = a_hi * b_hi; - uint64_t carry = (uint32_t)(((p1 >> 32) + (uint32_t)p2 + (uint32_t)p3) >> 32); - - LOVAL64 = p1 + (p2 << 32) + (p3 << 32); - HIVAL64 = p4 + (p2 >> 32) + (p3 >> 32) + carry; - - // Adjust for sign - if (RSVAL64 < 0) - HIVAL64 -= RTVAL64; - if (RTVAL64 < 0) - HIVAL64 -= RSVAL64; - + LOVAL64 = mul_64x64(RSVAL64, RTVAL64, reinterpret_cast(&HIVAL64)); m_core->icount -= 7; break; - } case 0x1d: /* DMULTU */ - { - uint64_t a_hi = (uint32_t)(RSVAL64 >> 32); - uint64_t b_hi = (uint32_t)(RTVAL64 >> 32); - uint64_t a_lo = (uint32_t)RSVAL64; - uint64_t b_lo = (uint32_t)RTVAL64; - uint64_t p1 = a_lo * b_lo; - uint64_t p2 = a_hi * b_lo; - uint64_t p3 = a_lo * b_hi; - uint64_t p4 = a_hi * b_hi; - uint64_t carry = (uint32_t)(((p1 >> 32) + (uint32_t)p2 + (uint32_t)p3) >> 32); - - LOVAL64 = p1 + (p2 << 32) + (p3 << 32); - HIVAL64 = p4 + (p2 >> 32) + (p3 >> 32) + carry; - + LOVAL64 = mulu_64x64(RSVAL64, RTVAL64, &HIVAL64); m_core->icount -= 7; break; - } case 0x1e: /* DDIV */ if (RTVAL64) { diff --git a/src/devices/cpu/mips/mips3fe.cpp b/src/devices/cpu/mips/mips3fe.cpp index ff0c59797d9..77b72c9b48b 100644 --- a/src/devices/cpu/mips/mips3fe.cpp +++ b/src/devices/cpu/mips/mips3fe.cpp @@ -316,13 +316,13 @@ bool mips3_frontend::describe_special(uint32_t op, opcode_desc &desc) return true; case 0x10: // MFHI - desc.regin[0] |= REGFLAG_HI; + desc.regin[2] |= REGFLAG_HI; desc.regout[0] |= REGFLAG_R(RDREG); return true; case 0x11: // MTHI desc.regin[0] |= REGFLAG_R(RSREG); - desc.regout[0] |= REGFLAG_HI; + desc.regout[2] |= REGFLAG_HI; return true; case 0x12: // MFLO diff --git a/src/devices/cpu/mips/r4000.cpp b/src/devices/cpu/mips/r4000.cpp index 7aedc9054e1..ca95b107c65 100644 --- a/src/devices/cpu/mips/r4000.cpp +++ b/src/devices/cpu/mips/r4000.cpp @@ -486,48 +486,12 @@ void r4000_base_device::cpu_execute(u32 const op) m_icount -= 35; break; case 0x1c: // DMULT - { - u64 const a_hi = u32(m_r[RSREG] >> 32); - u64 const b_hi = u32(m_r[RTREG] >> 32); - u64 const a_lo = u32(m_r[RSREG]); - u64 const b_lo = u32(m_r[RTREG]); - - u64 const p1 = a_lo * b_lo; - u64 const p2 = a_hi * b_lo; - u64 const p3 = a_lo * b_hi; - u64 const p4 = a_hi * b_hi; - u64 const carry = u32(((p1 >> 32) + u32(p2) + u32(p3)) >> 32); - - m_lo = p1 + (p2 << 32) + (p3 << 32); - m_hi = p4 + (p2 >> 32) + (p3 >> 32) + carry; - - // adjust for sign - if (s64(m_r[RSREG]) < 0) - m_hi -= m_r[RTREG]; - if (s64(m_r[RTREG]) < 0) - m_hi -= m_r[RSREG]; - - m_icount -= 7; - } + m_lo = mul_64x64(m_r[RSREG], m_r[RTREG], reinterpret_cast(&m_hi)); + m_icount -= 7; break; case 0x1d: // DMULTU - { - u64 const a_hi = u32(m_r[RSREG] >> 32); - u64 const b_hi = u32(m_r[RTREG] >> 32); - u64 const a_lo = u32(m_r[RSREG]); - u64 const b_lo = u32(m_r[RTREG]); - - u64 const p1 = a_lo * b_lo; - u64 const p2 = a_hi * b_lo; - u64 const p3 = a_lo * b_hi; - u64 const p4 = a_hi * b_hi; - u64 const carry = u32(((p1 >> 32) + u32(p2) + u32(p3)) >> 32); - - m_lo = p1 + (p2 << 32) + (p3 << 32); - m_hi = p4 + (p2 >> 32) + (p3 >> 32) + carry; - - m_icount -= 7; - } + m_lo = mulu_64x64(m_r[RSREG], m_r[RTREG], &m_hi); + m_icount -= 7; break; case 0x1e: // DDIV if (m_r[RTREG]) @@ -1797,7 +1761,7 @@ void r4000_base_device::cp1_execute(u32 const op) if (f32_lt(float32_t{ u32(m_f[FSREG]) }, float32_t{ 0 })) cp1_set(FDREG, f32_mul(float32_t{ u32(m_f[FSREG]) }, i32_to_f32(-1)).v); else - m_f[FDREG] = m_f[FSREG]; + cp1_set(FDREG, m_f[FSREG]); } break; case 0x06: // MOV.S @@ -2085,7 +2049,7 @@ void r4000_base_device::cp1_execute(u32 const op) if (f64_lt(float64_t{ m_f[FSREG] }, float64_t{ 0 })) cp1_set(FDREG, f64_mul(float64_t{ m_f[FSREG] }, i32_to_f64(-1)).v); else - m_f[FDREG] = m_f[FSREG]; + cp1_set(FDREG, m_f[FSREG]); } break; case 0x06: // MOV.D @@ -2808,6 +2772,9 @@ void r4000_base_device::address_error(int intention, u64 const address) m_cp0[CP0_BadVAddr] = address; cpu_exception((intention & TRANSLATE_WRITE) ? EXCEPTION_ADES : EXCEPTION_ADEL); + + // address errors shouldn't typically occur, so a breakpoint is handy + machine().debug_break(); } } -- cgit v1.2.3