mip3: Proper DMULT(U) implementation from git issue #3718 [bryanperris] (#3746)

* mip3: Proper DMULT(U) implementation from git issue #3718 [bryanperris]

* mips3: Updated dmult(u) implementation.
This commit is contained in:
tedgreen99 2018-08-31 15:31:13 -06:00 committed by GitHub
parent 3196d06264
commit a47cc64fd0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -3501,33 +3501,43 @@ void mips3_device::handle_special(uint32_t op)
break;
case 0x1c: /* DMULT */
{
int64_t rshi = (int32_t)(RSVAL64 >> 32);
int64_t rthi = (int32_t)(RTVAL64 >> 32);
int64_t rslo = (uint32_t)RSVAL64;
int64_t rtlo = (uint32_t)RTVAL64;
int64_t mid_prods = (rshi * rtlo) + (rslo * rthi);
uint64_t lo_prod = (rslo * rtlo);
int64_t hi_prod = (rshi * rthi);
mid_prods += lo_prod >> 32;
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;
HIVAL64 = hi_prod + (mid_prods >> 32);
LOVAL64 = (uint32_t)lo_prod + (mid_prods << 32);
m_core->icount -= 7;
break;
}
case 0x1d: /* DMULTU */
{
uint64_t rshi = (int32_t)(RSVAL64 >> 32);
uint64_t rthi = (int32_t)(RTVAL64 >> 32);
uint64_t rslo = (uint32_t)RSVAL64;
uint64_t rtlo = (uint32_t)RTVAL64;
uint64_t mid_prods = (rshi * rtlo) + (rslo * rthi);
uint64_t lo_prod = (rslo * rtlo);
uint64_t hi_prod = (rshi * rthi);
mid_prods += lo_prod >> 32;
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;
HIVAL64 = hi_prod + (mid_prods >> 32);
LOVAL64 = (uint32_t)lo_prod + (mid_prods << 32);
m_core->icount -= 7;
break;
}