summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/tms32031/32031ops.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/tms32031/32031ops.hxx')
-rw-r--r--src/devices/cpu/tms32031/32031ops.hxx112
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;
}