diff options
Diffstat (limited to 'src/devices/cpu/tms32031/32031ops.hxx')
-rw-r--r-- | src/devices/cpu/tms32031/32031ops.hxx | 112 |
1 files changed, 57 insertions, 55 deletions
diff --git a/src/devices/cpu/tms32031/32031ops.hxx b/src/devices/cpu/tms32031/32031ops.hxx index c97512b52b3..b9ae91e762c 100644 --- a/src/devices/cpu/tms32031/32031ops.hxx +++ b/src/devices/cpu/tms32031/32031ops.hxx @@ -2,9 +2,9 @@ // copyright-holders:Aaron Giles /*************************************************************************** - 32031ops.cpp + 32031ops.hxx - TMS32031/2 emulator + TMS320C3x family 32-bit floating point DSP emulator ***************************************************************************/ @@ -88,7 +88,7 @@ void tms3203x_device::unimplemented(uint32_t op) inline void tms3203x_device::execute_one() { uint32_t op = ROPCODE(m_pc); - m_icount -= 2; // 2 clocks per cycle + burn_cycle(1); m_pc++; #if (TMS_3203X_LOG_OPCODE_USAGE) m_hits[op >> 21]++; @@ -118,6 +118,11 @@ void tms3203x_device::update_special(int dreg) } +void tms3203x_device::burn_cycle(int cycle) +{ + m_icount -= cycle * (m_is_lopower ? 16 : 1); +} + //************************************************************************** // CONDITION CODES @@ -393,7 +398,7 @@ void tms3203x_device::int2float(tmsreg &srcdst) // positive values; count leading zeros and shift else if ((int32_t)man > 0) { - cnt = count_leading_zeros(man); + cnt = count_leading_zeros_32(man); man <<= cnt; exp = 31 - cnt; } @@ -401,7 +406,7 @@ void tms3203x_device::int2float(tmsreg &srcdst) // negative values; count leading ones and shift else { - cnt = count_leading_ones(man); + cnt = count_leading_ones_32(man); man <<= cnt; exp = 31 - cnt; } @@ -585,13 +590,13 @@ void tms3203x_device::addf(tmsreg &dst, tmsreg &src1, tmsreg &src2) { if (man > 0) { - cnt = count_leading_zeros((uint32_t)man); + cnt = count_leading_zeros_32((uint32_t)man); man <<= cnt; exp -= cnt; } else { - cnt = count_leading_ones((uint32_t)man); + cnt = count_leading_ones_32((uint32_t)man); man <<= cnt; exp -= cnt; } @@ -698,13 +703,13 @@ void tms3203x_device::subf(tmsreg &dst, tmsreg &src1, tmsreg &src2) { if (man > 0) { - cnt = count_leading_zeros((uint32_t)man); + cnt = count_leading_zeros_32((uint32_t)man); man <<= cnt; exp -= cnt; } else { - cnt = count_leading_ones((uint32_t)man); + cnt = count_leading_ones_32((uint32_t)man); man <<= cnt; exp -= cnt; } @@ -847,13 +852,13 @@ void tms3203x_device::norm(tmsreg &dst, tmsreg &src) int cnt; if (man > 0) { - cnt = count_leading_zeros((uint32_t)man); + cnt = count_leading_zeros_32((uint32_t)man); man <<= cnt; exp -= cnt; } else { - cnt = count_leading_ones((uint32_t)man); + cnt = count_leading_ones_32((uint32_t)man); man <<= cnt; exp -= cnt; } @@ -1729,7 +1734,7 @@ void tms3203x_device::andn_imm(uint32_t op) #define ASH(dreg, src, count) \ { \ uint32_t _res; \ - int32_t _count = (int16_t)(count << 9) >> 9; /* 7 LSBs */ \ + int32_t _count = util::sext(count, 7); /* 7 LSBs */ \ if (_count < 0) \ { \ if (_count >= -31) \ @@ -2112,7 +2117,7 @@ void tms3203x_device::ldm_imm(uint32_t op) #define LSH(dreg, src, count) \ { \ uint32_t _res; \ - int32_t _count = (int16_t)(count << 9) >> 9; /* 7 LSBs */ \ + int32_t _count = util::sext(count, 7); /* 7 LSBs */ \ if (_count < 0) \ { \ if (_count >= -31) \ @@ -2214,7 +2219,7 @@ void tms3203x_device::mpyf_imm(uint32_t op) #define MPYI(dreg, src1, src2) \ { \ - int64_t _res = (int64_t)((int32_t)(src1 << 8) >> 8) * (int64_t)((int32_t)(src2 << 8) >> 8);\ + int64_t _res = mul_32x32(util::sext(src1, 24), util::sext(src2, 24));\ if (!OVM() || (_res >= -(int64_t)0x80000000 && _res <= (int64_t)0x7fffffff)) \ IREG(dreg) = _res; \ else \ @@ -2560,7 +2565,12 @@ void tms3203x_device::or_imm(uint32_t op) /*-----------------------------------------------------*/ -void tms3203x_device::maxspeed(uint32_t op) { unimplemented(op); } +void tms3203x_device::maxspeed(uint32_t op) +{ + // 0x10800000 MAXSPEED + // 0x10800001 LOPOWER + m_is_lopower = BIT(op, 0); +} /*-----------------------------------------------------*/ @@ -2695,7 +2705,7 @@ void tms3203x_device::rpts_reg(uint32_t op) IREG(TMR_RS) = m_pc; IREG(TMR_RE) = m_pc; IREG(TMR_ST) |= RMFLAG; - m_icount -= 3*2; + burn_cycle(3); m_delayed = true; } @@ -2705,7 +2715,7 @@ void tms3203x_device::rpts_dir(uint32_t op) IREG(TMR_RS) = m_pc; IREG(TMR_RE) = m_pc; IREG(TMR_ST) |= RMFLAG; - m_icount -= 3*2; + burn_cycle(3); m_delayed = true; } @@ -2715,7 +2725,7 @@ void tms3203x_device::rpts_ind(uint32_t op) IREG(TMR_RS) = m_pc; IREG(TMR_RE) = m_pc; IREG(TMR_ST) |= RMFLAG; - m_icount -= 3*2; + burn_cycle(3); m_delayed = true; } @@ -2725,7 +2735,7 @@ void tms3203x_device::rpts_imm(uint32_t op) IREG(TMR_RS) = m_pc; IREG(TMR_RE) = m_pc; IREG(TMR_ST) |= RMFLAG; - m_icount -= 3*2; + burn_cycle(3); m_delayed = true; } @@ -5514,7 +5524,7 @@ inline void tms3203x_device::execute_delayed(uint32_t newpc) void tms3203x_device::br_imm(uint32_t op) { m_pc = op & 0xffffff; - m_icount -= 3*2; + burn_cycle(3); } void tms3203x_device::brd_imm(uint32_t op) @@ -5528,7 +5538,7 @@ void tms3203x_device::call_imm(uint32_t op) { WMEM(++IREG(TMR_SP), m_pc); m_pc = op & 0xffffff; - m_icount -= 3*2; + burn_cycle(3); } /*-----------------------------------------------------*/ @@ -5538,7 +5548,7 @@ void tms3203x_device::rptb_imm(uint32_t op) IREG(TMR_RS) = m_pc; IREG(TMR_RE) = op & 0xffffff; IREG(TMR_ST) |= RMFLAG; - m_icount -= 3*2; + burn_cycle(3); } /*-----------------------------------------------------*/ @@ -5552,7 +5562,7 @@ void tms3203x_device::brc_reg(uint32_t op) if (condition(op >> 16)) { m_pc = IREG(op & 31); - m_icount -= 3*2; + burn_cycle(3); } } @@ -5569,7 +5579,7 @@ void tms3203x_device::brc_imm(uint32_t op) if (condition(op >> 16)) { m_pc += (int16_t)op; - m_icount -= 3*2; + burn_cycle(3); } } @@ -5591,7 +5601,7 @@ void tms3203x_device::dbc_reg(uint32_t op) if (condition(op >> 16) && !(res & 0x800000)) { m_pc = IREG(op & 31); - m_icount -= 3*2; + burn_cycle(3); } } @@ -5614,7 +5624,7 @@ void tms3203x_device::dbc_imm(uint32_t op) if (condition(op >> 16) && !(res & 0x800000)) { m_pc += (int16_t)op; - m_icount -= 3*2; + burn_cycle(3); } } @@ -5637,7 +5647,7 @@ void tms3203x_device::callc_reg(uint32_t op) { WMEM(++IREG(TMR_SP), m_pc); m_pc = IREG(op & 31); - m_icount -= 3*2; + burn_cycle(3); } } @@ -5647,7 +5657,7 @@ void tms3203x_device::callc_imm(uint32_t op) { WMEM(++IREG(TMR_SP), m_pc); m_pc += (int16_t)op; - m_icount -= 3*2; + burn_cycle(3); } } @@ -5661,7 +5671,7 @@ void tms3203x_device::trap(int trapnum) m_pc = RMEM(((IREG(TMR_IF) >> 16) << 8) + trapnum); else m_pc = RMEM(trapnum); - m_icount -= 4*2; + burn_cycle(4); } void tms3203x_device::trapc(uint32_t op) @@ -5678,7 +5688,7 @@ void tms3203x_device::retic_reg(uint32_t op) { m_pc = RMEM(IREG(TMR_SP)--); IREG(TMR_ST) |= GIEFLAG; - m_icount -= 3*2; + burn_cycle(3); check_irqs(); } } @@ -5688,7 +5698,7 @@ void tms3203x_device::retsc_reg(uint32_t op) if (condition(op >> 16)) { m_pc = RMEM(IREG(TMR_SP)--); - m_icount -= 3*2; + burn_cycle(3); } } @@ -5818,14 +5828,13 @@ void tms3203x_device::mpyaddi_0(uint32_t op) uint32_t src2 = IREG((op >> 16) & 7); uint32_t src3 = RMEM(INDIRECT_1_DEF(op, op >> 8)); uint32_t src4 = RMEM(INDIRECT_1(op, op)); - int64_t mres = (int64_t)((int32_t)(src3 << 8) >> 8) * (int64_t)((int32_t)(src4 << 8) >> 8); + int64_t mres = mul_32x32(util::sext(src3, 24), util::sext(src4, 24)); uint32_t ares = src1 + src2; CLR_NZVUF(); if (OVM()) { - if (mres < -(int64_t)0x80000000 || mres > (int64_t)0x7fffffff) - mres = (mres < 0) ? 0x80000000 : 0x7fffffff; + mres = std::clamp(mres, -(int64_t)0x80000000, (int64_t)0x7fffffff); if (OVERFLOW_ADD(src1,src2,ares)) ares = ((int32_t)src1 < 0) ? 0x80000000 : 0x7fffffff; } @@ -5842,14 +5851,13 @@ void tms3203x_device::mpyaddi_1(uint32_t op) uint32_t src2 = IREG((op >> 16) & 7); uint32_t src3 = RMEM(INDIRECT_1_DEF(op, op >> 8)); uint32_t src4 = RMEM(INDIRECT_1(op, op)); - int64_t mres = (int64_t)((int32_t)(src3 << 8) >> 8) * (int64_t)((int32_t)(src1 << 8) >> 8); + int64_t mres = mul_32x32(util::sext(src3, 24), util::sext(src1, 24)); uint32_t ares = src4 + src2; CLR_NZVUF(); if (OVM()) { - if (mres < -(int64_t)0x80000000 || mres > (int64_t)0x7fffffff) - mres = (mres < 0) ? 0x80000000 : 0x7fffffff; + mres = std::clamp(mres, -(int64_t)0x80000000, (int64_t)0x7fffffff); if (OVERFLOW_ADD(src4,src2,ares)) ares = ((int32_t)src4 < 0) ? 0x80000000 : 0x7fffffff; } @@ -5866,14 +5874,13 @@ void tms3203x_device::mpyaddi_2(uint32_t op) uint32_t src2 = IREG((op >> 16) & 7); uint32_t src3 = RMEM(INDIRECT_1_DEF(op, op >> 8)); uint32_t src4 = RMEM(INDIRECT_1(op, op)); - int64_t mres = (int64_t)((int32_t)(src1 << 8) >> 8) * (int64_t)((int32_t)(src2 << 8) >> 8); + int64_t mres = mul_32x32(util::sext(src1, 24), util::sext(src2, 24)); uint32_t ares = src3 + src4; CLR_NZVUF(); if (OVM()) { - if (mres < -(int64_t)0x80000000 || mres > (int64_t)0x7fffffff) - mres = (mres < 0) ? 0x80000000 : 0x7fffffff; + mres = std::clamp(mres, -(int64_t)0x80000000, (int64_t)0x7fffffff); if (OVERFLOW_ADD(src3,src4,ares)) ares = ((int32_t)src3 < 0) ? 0x80000000 : 0x7fffffff; } @@ -5890,14 +5897,13 @@ void tms3203x_device::mpyaddi_3(uint32_t op) uint32_t src2 = IREG((op >> 16) & 7); uint32_t src3 = RMEM(INDIRECT_1_DEF(op, op >> 8)); uint32_t src4 = RMEM(INDIRECT_1(op, op)); - int64_t mres = (int64_t)((int32_t)(src3 << 8) >> 8) * (int64_t)((int32_t)(src1 << 8) >> 8); + int64_t mres = mul_32x32(util::sext(src3, 24), util::sext(src1, 24)); uint32_t ares = src2 + src4; CLR_NZVUF(); if (OVM()) { - if (mres < -(int64_t)0x80000000 || mres > (int64_t)0x7fffffff) - mres = (mres < 0) ? 0x80000000 : 0x7fffffff; + mres = std::clamp(mres, -(int64_t)0x80000000, (int64_t)0x7fffffff); if (OVERFLOW_ADD(src2,src4,ares)) ares = ((int32_t)src2 < 0) ? 0x80000000 : 0x7fffffff; } @@ -5916,14 +5922,13 @@ void tms3203x_device::mpysubi_0(uint32_t op) uint32_t src2 = IREG((op >> 16) & 7); uint32_t src3 = RMEM(INDIRECT_1_DEF(op, op >> 8)); uint32_t src4 = RMEM(INDIRECT_1(op, op)); - int64_t mres = (int64_t)((int32_t)(src3 << 8) >> 8) * (int64_t)((int32_t)(src4 << 8) >> 8); + int64_t mres = mul_32x32(util::sext(src3, 24), util::sext(src4, 24)); uint32_t ares = src1 - src2; CLR_NZVUF(); if (OVM()) { - if (mres < -(int64_t)0x80000000 || mres > (int64_t)0x7fffffff) - mres = (mres < 0) ? 0x80000000 : 0x7fffffff; + mres = std::clamp(mres, -(int64_t)0x80000000, (int64_t)0x7fffffff); if (OVERFLOW_SUB(src1,src2,ares)) ares = ((int32_t)src1 < 0) ? 0x80000000 : 0x7fffffff; } @@ -5940,14 +5945,13 @@ void tms3203x_device::mpysubi_1(uint32_t op) uint32_t src2 = IREG((op >> 16) & 7); uint32_t src3 = RMEM(INDIRECT_1_DEF(op, op >> 8)); uint32_t src4 = RMEM(INDIRECT_1(op, op)); - int64_t mres = (int64_t)((int32_t)(src3 << 8) >> 8) * (int64_t)((int32_t)(src1 << 8) >> 8); + int64_t mres = mul_32x32(util::sext(src3, 24), util::sext(src1, 24)); uint32_t ares = src4 - src2; CLR_NZVUF(); if (OVM()) { - if (mres < -(int64_t)0x80000000 || mres > (int64_t)0x7fffffff) - mres = (mres < 0) ? 0x80000000 : 0x7fffffff; + mres = std::clamp(mres, -(int64_t)0x80000000, (int64_t)0x7fffffff); if (OVERFLOW_SUB(src4,src2,ares)) ares = ((int32_t)src4 < 0) ? 0x80000000 : 0x7fffffff; } @@ -5964,14 +5968,13 @@ void tms3203x_device::mpysubi_2(uint32_t op) uint32_t src2 = IREG((op >> 16) & 7); uint32_t src3 = RMEM(INDIRECT_1_DEF(op, op >> 8)); uint32_t src4 = RMEM(INDIRECT_1(op, op)); - int64_t mres = (int64_t)((int32_t)(src1 << 8) >> 8) * (int64_t)((int32_t)(src2 << 8) >> 8); + int64_t mres = mul_32x32(util::sext(src1, 24), util::sext(src2, 24)); uint32_t ares = src3 - src4; CLR_NZVUF(); if (OVM()) { - if (mres < -(int64_t)0x80000000 || mres > (int64_t)0x7fffffff) - mres = (mres < 0) ? 0x80000000 : 0x7fffffff; + mres = std::clamp(mres, -(int64_t)0x80000000, (int64_t)0x7fffffff); if (OVERFLOW_SUB(src3,src4,ares)) ares = ((int32_t)src3 < 0) ? 0x80000000 : 0x7fffffff; } @@ -5988,14 +5991,13 @@ void tms3203x_device::mpysubi_3(uint32_t op) uint32_t src2 = IREG((op >> 16) & 7); uint32_t src3 = RMEM(INDIRECT_1_DEF(op, op >> 8)); uint32_t src4 = RMEM(INDIRECT_1(op, op)); - int64_t mres = (int64_t)((int32_t)(src3 << 8) >> 8) * (int64_t)((int32_t)(src1 << 8) >> 8); + int64_t mres = mul_32x32(util::sext(src3, 24), util::sext(src1, 24)); uint32_t ares = src2 - src4; CLR_NZVUF(); if (OVM()) { - if (mres < -(int64_t)0x80000000 || mres > (int64_t)0x7fffffff) - mres = (mres < 0) ? 0x80000000 : 0x7fffffff; + mres = std::clamp(mres, -(int64_t)0x80000000, (int64_t)0x7fffffff); if (OVERFLOW_SUB(src2,src4,ares)) ares = ((int32_t)src2 < 0) ? 0x80000000 : 0x7fffffff; } |