mirror of
https://github.com/holub/mame
synced 2025-06-17 09:49:31 +03:00
tms32082: more opcodes (nw)
This commit is contained in:
parent
bd9ceb779e
commit
86d7993148
@ -38,7 +38,7 @@ static const char *FLOATOP_PRECISION[4] =
|
|||||||
|
|
||||||
static const char *ACC_SEL[4] =
|
static const char *ACC_SEL[4] =
|
||||||
{
|
{
|
||||||
"a0", "a1", "a2", "a3"
|
"A0", "A1", "A2", "A3"
|
||||||
};
|
};
|
||||||
|
|
||||||
static char *output;
|
static char *output;
|
||||||
@ -94,7 +94,7 @@ static char* get_creg_name(UINT32 reg)
|
|||||||
case 0x4000: sprintf(buffer, "IN0P"); break;
|
case 0x4000: sprintf(buffer, "IN0P"); break;
|
||||||
case 0x4001: sprintf(buffer, "IN1P"); break;
|
case 0x4001: sprintf(buffer, "IN1P"); break;
|
||||||
case 0x4002: sprintf(buffer, "OUTP"); break;
|
case 0x4002: sprintf(buffer, "OUTP"); break;
|
||||||
default: sprintf(buffer, "CR %04X\n", reg);
|
default: sprintf(buffer, "CR %04X", reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
@ -171,9 +171,9 @@ static char* format_vector_op(UINT32 op, UINT32 imm32)
|
|||||||
|
|
||||||
// align the line end
|
// align the line end
|
||||||
int len = strlen(buffer);
|
int len = strlen(buffer);
|
||||||
if (len < 27)
|
if (len < 29)
|
||||||
{
|
{
|
||||||
for (int i=0; i < (27-len); i++)
|
for (int i=0; i < (29-len); i++)
|
||||||
{
|
{
|
||||||
b += sprintf(b, " ");
|
b += sprintf(b, " ");
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#define OP_PD() ((m_ir >> 9) & 0x3)
|
#define OP_PD() ((m_ir >> 9) & 0x3)
|
||||||
#define OP_P1() ((m_ir >> 5) & 0x3)
|
#define OP_P1() ((m_ir >> 5) & 0x3)
|
||||||
#define OP_P2() ((m_ir >> 7) & 0x3)
|
#define OP_P2() ((m_ir >> 7) & 0x3)
|
||||||
|
#define OP_ACC() ((m_ir >> 15) & 0x2) | ((m_ir >> 11) & 1)
|
||||||
|
|
||||||
#define ROTATE_L(x, r) ((x << r) | (x >> (32-r)))
|
#define ROTATE_L(x, r) ((x << r) | (x >> (32-r)))
|
||||||
#define ROTATE_R(x, r) ((x >> r) | (x << (32-r)))
|
#define ROTATE_R(x, r) ((x >> r) | (x << (32-r)))
|
||||||
@ -130,6 +131,57 @@ UINT32 tms32082_mp_device::calculate_cmp(UINT32 src1, UINT32 src2)
|
|||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tms32082_mp_device::vector_loadstore()
|
||||||
|
{
|
||||||
|
int rd = OP_RD();
|
||||||
|
int vector_ls_bits = (((m_ir >> 9) & 0x3) << 1) | ((m_ir >> 6) & 1);
|
||||||
|
|
||||||
|
switch (vector_ls_bits)
|
||||||
|
{
|
||||||
|
case 0x01: // vst.s
|
||||||
|
{
|
||||||
|
m_program->write_dword(m_outp, m_reg[rd]);
|
||||||
|
m_outp += 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x03: // vst.d
|
||||||
|
{
|
||||||
|
UINT64 data = m_fpair[rd >> 1];
|
||||||
|
m_program->write_qword(m_outp, data);
|
||||||
|
m_outp += 8;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x04: // vld0.s
|
||||||
|
{
|
||||||
|
m_reg[rd] = m_program->read_dword(m_in0p);
|
||||||
|
m_in0p += 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x05: // vld1.s
|
||||||
|
{
|
||||||
|
m_reg[rd] = m_program->read_dword(m_in1p);
|
||||||
|
m_in1p += 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x06: // vld0.d
|
||||||
|
{
|
||||||
|
m_fpair[rd >> 1] = m_program->read_qword(m_in0p);
|
||||||
|
m_in0p += 8;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x07: // vld1.d
|
||||||
|
{
|
||||||
|
m_fpair[rd >> 1] = m_program->read_qword(m_in1p);
|
||||||
|
m_in1p += 8;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
fatalerror("vector_loadstore(): ls bits = %02X\n", vector_ls_bits);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void tms32082_mp_device::execute_short_imm()
|
void tms32082_mp_device::execute_short_imm()
|
||||||
{
|
{
|
||||||
switch ((m_ir >> 15) & 0x7f)
|
switch ((m_ir >> 15) & 0x7f)
|
||||||
@ -137,7 +189,7 @@ void tms32082_mp_device::execute_short_imm()
|
|||||||
case 0x04: // rdcr
|
case 0x04: // rdcr
|
||||||
{
|
{
|
||||||
int rd = OP_RD();
|
int rd = OP_RD();
|
||||||
INT32 imm = OP_SIMM15();
|
UINT32 imm = OP_UIMM15();
|
||||||
|
|
||||||
UINT32 r = read_creg(imm);
|
UINT32 r = read_creg(imm);
|
||||||
|
|
||||||
@ -150,7 +202,7 @@ void tms32082_mp_device::execute_short_imm()
|
|||||||
{
|
{
|
||||||
int rd = OP_RD();
|
int rd = OP_RD();
|
||||||
int rs = OP_RS();
|
int rs = OP_RS();
|
||||||
INT32 imm = OP_SIMM15();
|
UINT32 imm = OP_UIMM15();
|
||||||
|
|
||||||
UINT32 r = read_creg(imm);
|
UINT32 r = read_creg(imm);
|
||||||
if (rd)
|
if (rd)
|
||||||
@ -998,7 +1050,188 @@ void tms32082_mp_device::execute_reg_long_imm()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xe4: // fmpy
|
case 0xc4:
|
||||||
|
case 0xd4:
|
||||||
|
case 0xc5:
|
||||||
|
case 0xd5: // vmpy
|
||||||
|
{
|
||||||
|
int p1 = m_ir & (1 << 5);
|
||||||
|
int pd = m_ir & (1 << 7);
|
||||||
|
int ls_bit1 = m_ir & (1 << 10);
|
||||||
|
int ls_bit2 = m_ir & (1 << 6);
|
||||||
|
int rd = OP_RS();
|
||||||
|
int src1 OP_SRC1();
|
||||||
|
|
||||||
|
double source = has_imm ? (double)u2f(imm32) : (p1 ? u2d(m_fpair[src1 >> 1]) : (double)u2f(m_reg[src1]));
|
||||||
|
|
||||||
|
if (rd)
|
||||||
|
{
|
||||||
|
if (pd)
|
||||||
|
{
|
||||||
|
double res = source * u2d(m_fpair[rd >> 1]);
|
||||||
|
m_fpair[rd >> 1] = d2u(res);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float res = (float)(source) * u2f(m_reg[rd]);
|
||||||
|
m_reg[rd] = f2u(res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// parallel load/store op
|
||||||
|
if (!(ls_bit1 == 0 && ls_bit2 == 0))
|
||||||
|
{
|
||||||
|
vector_loadstore();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 0xcc:
|
||||||
|
case 0xdc:
|
||||||
|
case 0xcd:
|
||||||
|
case 0xdd: // vmac
|
||||||
|
{
|
||||||
|
int acc = OP_ACC();
|
||||||
|
int z = m_ir & (1 << 8);
|
||||||
|
int pd = m_ir & (1 << 9);
|
||||||
|
int ls_bit1 = m_ir & (1 << 10);
|
||||||
|
int ls_bit2 = m_ir & (1 << 6);
|
||||||
|
int rd = OP_RD();
|
||||||
|
|
||||||
|
float src1 = u2f(m_reg[OP_SRC1()]);
|
||||||
|
float src2 = u2f(m_reg[OP_RS()]);
|
||||||
|
|
||||||
|
float res = (src1 * src2) + (z ? 0.0f : m_acc[acc]);
|
||||||
|
|
||||||
|
// parallel load/store op
|
||||||
|
if (!(ls_bit1 == 0 && ls_bit2 == 0))
|
||||||
|
{
|
||||||
|
vector_loadstore();
|
||||||
|
|
||||||
|
// if the opcode has load/store, dest is always accumulator
|
||||||
|
m_facc[acc] = (double)res;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (rd)
|
||||||
|
{
|
||||||
|
if (pd)
|
||||||
|
m_fpair[rd >> 1] = d2u(res);
|
||||||
|
else
|
||||||
|
m_reg[rd] = f2u((float)res);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// write to accumulator
|
||||||
|
m_facc[acc] = (double)res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 0xce:
|
||||||
|
case 0xde:
|
||||||
|
case 0xcf:
|
||||||
|
case 0xdf: // vmsc
|
||||||
|
{
|
||||||
|
int acc = OP_ACC();
|
||||||
|
int z = m_ir & (1 << 8);
|
||||||
|
int pd = m_ir & (1 << 9);
|
||||||
|
int ls_bit1 = m_ir & (1 << 10);
|
||||||
|
int ls_bit2 = m_ir & (1 << 6);
|
||||||
|
int rd = OP_RD();
|
||||||
|
|
||||||
|
float src1 = u2f(m_reg[OP_SRC1()]);
|
||||||
|
float src2 = u2f(m_reg[OP_RS()]);
|
||||||
|
|
||||||
|
float res = (z ? 0.0f : m_acc[acc]) - (src1 * src2);
|
||||||
|
|
||||||
|
// parallel load/store op
|
||||||
|
if (!(ls_bit1 == 0 && ls_bit2 == 0))
|
||||||
|
{
|
||||||
|
vector_loadstore();
|
||||||
|
|
||||||
|
// if the opcode has load/store, dest is always accumulator
|
||||||
|
m_facc[acc] = (double)res;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (rd)
|
||||||
|
{
|
||||||
|
if (pd)
|
||||||
|
m_fpair[rd >> 1] = d2u(res);
|
||||||
|
else
|
||||||
|
m_reg[rd] = f2u((float)res);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// write to accumulator
|
||||||
|
m_facc[acc] = (double)res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 0xe2:
|
||||||
|
case 0xe3: // fsub
|
||||||
|
{
|
||||||
|
int rd = OP_RD();
|
||||||
|
int rs = OP_RS();
|
||||||
|
int src1 = OP_SRC1();
|
||||||
|
int precision = (m_ir >> 5) & 0x3f;
|
||||||
|
|
||||||
|
if (rd) // only calculate if destination register is valid
|
||||||
|
{
|
||||||
|
switch (precision)
|
||||||
|
{
|
||||||
|
case 0x00: // SP - SP -> SP
|
||||||
|
{
|
||||||
|
float s1 = u2f(has_imm ? imm32 : m_reg[src1]);
|
||||||
|
float s2 = u2f(m_reg[rs]);
|
||||||
|
m_reg[rd] = f2u(s1 - s2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x10: // SP - SP -> DP
|
||||||
|
{
|
||||||
|
float s1 = u2f(has_imm ? imm32 : m_reg[src1]);
|
||||||
|
float s2 = u2f(m_reg[rs]);
|
||||||
|
UINT64 res = d2u((double)(s1 - s2));
|
||||||
|
m_fpair[rd >> 1] = res;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x14: // SP - DP -> DP
|
||||||
|
{
|
||||||
|
float s1 = u2f(has_imm ? imm32 : m_reg[src1]);
|
||||||
|
double s2 = u2d(m_fpair[rs >> 1]);
|
||||||
|
UINT64 res = d2u((double)(s1 - s2));
|
||||||
|
m_fpair[rd >> 1] = res;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x11: // DP - SP -> DP
|
||||||
|
{
|
||||||
|
double s1 = u2d(m_fpair[src1 >> 1]);
|
||||||
|
float s2 = u2f(m_reg[rs]);
|
||||||
|
UINT64 res = d2u((double)(s1 - s2));
|
||||||
|
m_fpair[rd >> 1] = res;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x15: // DP - DP -> DP
|
||||||
|
{
|
||||||
|
double s1 = u2d(m_fpair[src1 >> 1]);
|
||||||
|
double s2 = u2d(m_fpair[rs >> 1]);
|
||||||
|
UINT64 res = d2u((double)(s1 - s2));
|
||||||
|
m_fpair[rd >> 1] = res;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
fatalerror("fsub: invalid precision combination %02X\n", precision);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 0xe4:
|
||||||
|
case 0xe5: // fmpy
|
||||||
{
|
{
|
||||||
int rd = OP_RD();
|
int rd = OP_RD();
|
||||||
int rs = OP_RS();
|
int rs = OP_RS();
|
||||||
@ -1065,6 +1298,27 @@ void tms32082_mp_device::execute_reg_long_imm()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 0xee:
|
||||||
|
case 0xef: // fsqrt
|
||||||
|
{
|
||||||
|
int rd = OP_RD();
|
||||||
|
int src1 = OP_SRC1();
|
||||||
|
int p1 = m_ir & (1 << 5);
|
||||||
|
int pd = m_ir & (1 << 9);
|
||||||
|
double source = has_imm ? (double)u2f(imm32) : (p1 ? u2d(m_fpair[src1 >> 1]) : (double)u2f(m_reg[src1]));
|
||||||
|
|
||||||
|
if (rd)
|
||||||
|
{
|
||||||
|
double res = sqrt(source);
|
||||||
|
|
||||||
|
if (pd)
|
||||||
|
m_fpair[rd >> 1] = d2u(res);
|
||||||
|
else
|
||||||
|
m_reg[rd] = f2u((float)res);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 0xf2: // rmo
|
case 0xf2: // rmo
|
||||||
{
|
{
|
||||||
UINT32 source = m_reg[OP_RS()];
|
UINT32 source = m_reg[OP_RS()];
|
||||||
|
@ -173,6 +173,10 @@ void tms32082_mp_device::device_start()
|
|||||||
state_add(MP_ACC2, "acc2", m_acc[2]).formatstr("%016X");
|
state_add(MP_ACC2, "acc2", m_acc[2]).formatstr("%016X");
|
||||||
state_add(MP_ACC3, "acc3", m_acc[3]).formatstr("%016X");
|
state_add(MP_ACC3, "acc3", m_acc[3]).formatstr("%016X");
|
||||||
|
|
||||||
|
state_add(MP_IN0P, "in0p", m_in0p).formatstr("%08X");
|
||||||
|
state_add(MP_IN1P, "in1p", m_in1p).formatstr("%08X");
|
||||||
|
state_add(MP_OUTP, "outp", m_outp).formatstr("%08X");
|
||||||
|
|
||||||
state_add(STATE_GENPC, "curpc", m_pc).noshow();
|
state_add(STATE_GENPC, "curpc", m_pc).noshow();
|
||||||
|
|
||||||
m_param_ram = auto_alloc_array(machine(), UINT32, 0x800);
|
m_param_ram = auto_alloc_array(machine(), UINT32, 0x800);
|
||||||
@ -216,6 +220,15 @@ UINT32 tms32082_mp_device::read_creg(int reg)
|
|||||||
case 0xa: // PPERROR
|
case 0xa: // PPERROR
|
||||||
return 0xe0000;
|
return 0xe0000;
|
||||||
|
|
||||||
|
case 0x4000: // IN0P
|
||||||
|
return m_in0p;
|
||||||
|
|
||||||
|
case 0x4001: // IN1P
|
||||||
|
return m_in1p;
|
||||||
|
|
||||||
|
case 0x4002: // OUTP
|
||||||
|
return m_outp;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
printf("read_creg(): %08X\n", reg);
|
printf("read_creg(): %08X\n", reg);
|
||||||
break;
|
break;
|
||||||
@ -225,7 +238,24 @@ UINT32 tms32082_mp_device::read_creg(int reg)
|
|||||||
|
|
||||||
void tms32082_mp_device::write_creg(int reg, UINT32 data)
|
void tms32082_mp_device::write_creg(int reg, UINT32 data)
|
||||||
{
|
{
|
||||||
|
switch (reg)
|
||||||
|
{
|
||||||
|
case 0x4000: // IN0P
|
||||||
|
m_in0p = data;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x4001: // IN1P
|
||||||
|
m_in1p = data;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x4002: // OUTP
|
||||||
|
m_outp = data;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
printf("write_creg(): %08X, %08X\n", reg, data);
|
printf("write_creg(): %08X, %08X\n", reg, data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT32 tms32082_mp_device::fetch()
|
UINT32 tms32082_mp_device::fetch()
|
||||||
|
@ -48,6 +48,9 @@ public:
|
|||||||
MP_ACC1,
|
MP_ACC1,
|
||||||
MP_ACC2,
|
MP_ACC2,
|
||||||
MP_ACC3,
|
MP_ACC3,
|
||||||
|
MP_IN0P,
|
||||||
|
MP_IN1P,
|
||||||
|
MP_OUTP
|
||||||
};
|
};
|
||||||
|
|
||||||
DECLARE_READ32_MEMBER(mp_param_r);
|
DECLARE_READ32_MEMBER(mp_param_r);
|
||||||
@ -90,15 +93,22 @@ protected:
|
|||||||
|
|
||||||
UINT32 m_pc;
|
UINT32 m_pc;
|
||||||
UINT32 m_fetchpc;
|
UINT32 m_fetchpc;
|
||||||
//UINT32 m_reg[32];
|
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
UINT32 m_reg[32];
|
UINT32 m_reg[32];
|
||||||
UINT64 m_fpair[16];
|
UINT64 m_fpair[16];
|
||||||
};
|
};
|
||||||
|
union
|
||||||
|
{
|
||||||
UINT64 m_acc[4];
|
UINT64 m_acc[4];
|
||||||
|
double m_facc[4];
|
||||||
|
};
|
||||||
UINT32 m_ir;
|
UINT32 m_ir;
|
||||||
|
|
||||||
|
UINT32 m_in0p;
|
||||||
|
UINT32 m_in1p;
|
||||||
|
UINT32 m_outp;
|
||||||
|
|
||||||
UINT32 *m_param_ram;
|
UINT32 *m_param_ram;
|
||||||
|
|
||||||
int m_icount;
|
int m_icount;
|
||||||
@ -115,6 +125,7 @@ protected:
|
|||||||
void write_creg(int reg, UINT32 data);
|
void write_creg(int reg, UINT32 data);
|
||||||
bool test_condition(int condition, UINT32 value);
|
bool test_condition(int condition, UINT32 value);
|
||||||
UINT32 calculate_cmp(UINT32 src1, UINT32 src2);
|
UINT32 calculate_cmp(UINT32 src1, UINT32 src2);
|
||||||
|
void vector_loadstore();
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const device_type TMS32082_MP;
|
extern const device_type TMS32082_MP;
|
||||||
|
Loading…
Reference in New Issue
Block a user