mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-22 02:50:08 +08:00
sim: bfin: handle V/VS saturation in dsp mac insns
Some saturation cases with dsp mac insns were not setting the V flag. So implement that part and split up the logic between the dual macs. Signed-off-by: Robin Getz <robin.getz@analog.com> Signed-off-by: Mike Frysinger <vapier@gentoo.org>
This commit is contained in:
@ -1,3 +1,13 @@
|
|||||||
|
2011-06-18 Robin Getz <robin.getz@analog.com>
|
||||||
|
|
||||||
|
* bfin-sim.c (decode_macfunc): Add nosat_acc to track acc value
|
||||||
|
before saturation, set sat when more cases saturate, and set the
|
||||||
|
overflow bit based on these results. For M_TFU, M_IU, M_FU, and
|
||||||
|
M_W32, change the max values compared against.
|
||||||
|
(decode_dsp32mac_0): Delete v_i and add v_0 and v_1. Pass v_1
|
||||||
|
when processing MAC1 and pass v_0 when processing MAC0. Combine
|
||||||
|
the results into the V/VS ASTAT bits.
|
||||||
|
|
||||||
2011-06-18 Robin Getz <robin.getz@analog.com>
|
2011-06-18 Robin Getz <robin.getz@analog.com>
|
||||||
|
|
||||||
* bfin-sim.c (extract_mult): Call saturate_s32 when MM is set
|
* bfin-sim.c (extract_mult): Call saturate_s32 when MM is set
|
||||||
|
@ -1591,6 +1591,9 @@ decode_macfunc (SIM_CPU *cpu, int which, int op, int h0, int h1, int src0,
|
|||||||
if (op != 3)
|
if (op != 3)
|
||||||
{
|
{
|
||||||
bu8 sgn0 = (acc >> 31) & 1;
|
bu8 sgn0 = (acc >> 31) & 1;
|
||||||
|
bu8 sgn40 = (acc >> 39) & 1;
|
||||||
|
bu40 nosat_acc;
|
||||||
|
|
||||||
/* This can't saturate, so we don't keep track of the sat flag. */
|
/* This can't saturate, so we don't keep track of the sat flag. */
|
||||||
bu64 res = decode_multfunc (cpu, h0, h1, src0, src1, mmod,
|
bu64 res = decode_multfunc (cpu, h0, h1, src0, src1, mmod,
|
||||||
MM, &tsat);
|
MM, &tsat);
|
||||||
@ -1610,6 +1613,7 @@ decode_macfunc (SIM_CPU *cpu, int which, int op, int h0, int h1, int src0,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nosat_acc = acc;
|
||||||
/* Saturate. */
|
/* Saturate. */
|
||||||
switch (mmod)
|
switch (mmod)
|
||||||
{
|
{
|
||||||
@ -1624,20 +1628,20 @@ decode_macfunc (SIM_CPU *cpu, int which, int op, int h0, int h1, int src0,
|
|||||||
acc = 0x7fffffffffull, sat = 1;
|
acc = 0x7fffffffffull, sat = 1;
|
||||||
break;
|
break;
|
||||||
case M_TFU:
|
case M_TFU:
|
||||||
if (!MM && acc > 0xFFFFFFFFFFull)
|
if (!MM && (bs64)acc < 0)
|
||||||
acc = 0x0, sat = 1;
|
acc = 0, sat = 1;
|
||||||
if (MM && acc > 0xFFFFFFFF)
|
if (!MM && (bs64)acc > 0xFFFFFFFFFFull)
|
||||||
acc &= 0xFFFFFFFF;
|
acc = 0xFFFFFFFFFFull, sat = 1;
|
||||||
break;
|
break;
|
||||||
case M_IU:
|
case M_IU:
|
||||||
if (acc & 0x8000000000000000ull)
|
if (!MM && acc & 0x8000000000000000ull)
|
||||||
acc = 0x0, sat = 1;
|
acc = 0x0, sat = 1;
|
||||||
if (acc > 0xFFFFFFFFFFull)
|
if (!MM && acc > 0xFFFFFFFFFFull)
|
||||||
acc &= 0xFFFFFFFFFFull, sat = 1;
|
acc = 0xFFFFFFFFFFull, sat = 1;
|
||||||
if (MM && acc > 0xFFFFFFFF)
|
if (MM && acc > 0xFFFFFFFFFFull)
|
||||||
acc &= 0xFFFFFFFF;
|
acc &= 0xFFFFFFFFFFull;
|
||||||
if (acc & 0x80000000)
|
if (acc & 0x8000000000ull)
|
||||||
acc |= 0xffffffff00000000ull;
|
acc |= 0xffffff0000000000ull;
|
||||||
break;
|
break;
|
||||||
case M_FU:
|
case M_FU:
|
||||||
if (!MM && (bs64)acc < 0)
|
if (!MM && (bs64)acc < 0)
|
||||||
@ -1648,8 +1652,8 @@ decode_macfunc (SIM_CPU *cpu, int which, int op, int h0, int h1, int src0,
|
|||||||
acc = 0xFFFFFFFFFFull, sat = 1;
|
acc = 0xFFFFFFFFFFull, sat = 1;
|
||||||
if (MM && acc > 0xFFFFFFFFFFull)
|
if (MM && acc > 0xFFFFFFFFFFull)
|
||||||
acc &= 0xFFFFFFFFFFull;
|
acc &= 0xFFFFFFFFFFull;
|
||||||
if (MM && acc & 0x80000000)
|
if (MM && acc & 0x8000000000ull)
|
||||||
acc |= 0xffffffff00000000ull;
|
acc |= 0xffffff0000000000ull;
|
||||||
break;
|
break;
|
||||||
case M_IH:
|
case M_IH:
|
||||||
if ((bs64)acc < -0x80000000ll)
|
if ((bs64)acc < -0x80000000ll)
|
||||||
@ -1658,12 +1662,18 @@ decode_macfunc (SIM_CPU *cpu, int which, int op, int h0, int h1, int src0,
|
|||||||
acc = 0x7fffffffull, sat = 1;
|
acc = 0x7fffffffull, sat = 1;
|
||||||
break;
|
break;
|
||||||
case M_W32:
|
case M_W32:
|
||||||
if (sgn0 && (sgn0 != ((acc >> 31) & 1))
|
/* check max negative value */
|
||||||
&& (((acc >> 32) & 0xFF) == 0xff))
|
if (sgn40 && ((acc >> 31) != 0x1ffffffff)
|
||||||
acc = 0x80000000;
|
&& ((acc >> 31) != 0x0))
|
||||||
|
acc = 0x80000000, sat = 1;
|
||||||
|
if (!sat && !sgn40 && ((acc >> 31) != 0x0)
|
||||||
|
&& ((acc >> 31) != 0x1ffffffff))
|
||||||
|
acc = 0x7FFFFFFF, sat = 1;
|
||||||
acc &= 0xffffffff;
|
acc &= 0xffffffff;
|
||||||
if (acc & 0x80000000)
|
if (acc & 0x80000000)
|
||||||
acc |= 0xffffffff00000000ull;
|
acc |= 0xffffffff00000000ull;
|
||||||
|
if (tsat)
|
||||||
|
sat = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
illegal_instruction (cpu);
|
illegal_instruction (cpu);
|
||||||
@ -1677,6 +1687,15 @@ decode_macfunc (SIM_CPU *cpu, int which, int op, int h0, int h1, int src0,
|
|||||||
STORE (ASTATREG (av[which]), sat);
|
STORE (ASTATREG (av[which]), sat);
|
||||||
if (sat)
|
if (sat)
|
||||||
STORE (ASTATREG (avs[which]), sat);
|
STORE (ASTATREG (avs[which]), sat);
|
||||||
|
|
||||||
|
/* Figure out the overflow bit. */
|
||||||
|
if (sat)
|
||||||
|
{
|
||||||
|
if (fullword)
|
||||||
|
*overflow = 1;
|
||||||
|
else
|
||||||
|
ret = extract_mult (cpu, nosat_acc, mmod, MM, fullword, overflow);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = extract_mult (cpu, acc, mmod, MM, fullword, overflow);
|
ret = extract_mult (cpu, acc, mmod, MM, fullword, overflow);
|
||||||
@ -3727,7 +3746,7 @@ decode_dsp32mac_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
|
|||||||
int h01 = ((iw1 >> DSP32Mac_h01_bits) & DSP32Mac_h01_mask);
|
int h01 = ((iw1 >> DSP32Mac_h01_bits) & DSP32Mac_h01_mask);
|
||||||
|
|
||||||
bu32 res = DREG (dst);
|
bu32 res = DREG (dst);
|
||||||
bu32 v_i = 0, zero = 0, n_1 = 0, n_0 = 0;
|
bu32 v_0 = 0, v_1 = 0, zero = 0, n_1 = 0, n_0 = 0;
|
||||||
|
|
||||||
static const char * const ops[] = { "=", "+=", "-=" };
|
static const char * const ops[] = { "=", "+=", "-=" };
|
||||||
char _buf[128], *buf = _buf;
|
char _buf[128], *buf = _buf;
|
||||||
@ -3752,7 +3771,7 @@ decode_dsp32mac_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
|
|||||||
if (w1 == 1 || op1 != 3)
|
if (w1 == 1 || op1 != 3)
|
||||||
{
|
{
|
||||||
bu32 res1 = decode_macfunc (cpu, 1, op1, h01, h11, src0,
|
bu32 res1 = decode_macfunc (cpu, 1, op1, h01, h11, src0,
|
||||||
src1, mmod, MM, P, &v_i, &n_1);
|
src1, mmod, MM, P, &v_1, &n_1);
|
||||||
|
|
||||||
if (w1)
|
if (w1)
|
||||||
buf += sprintf (buf, P ? "R%i" : "R%i.H", dst + P);
|
buf += sprintf (buf, P ? "R%i" : "R%i.H", dst + P);
|
||||||
@ -3784,6 +3803,8 @@ decode_dsp32mac_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
|
|||||||
res = REG_H_L (res1 << 16, res);
|
res = REG_H_L (res1 << 16, res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
v_1 = 0;
|
||||||
|
|
||||||
if (w0 == 1 || op0 != 3)
|
if (w0 == 1 || op0 != 3)
|
||||||
{
|
{
|
||||||
@ -3798,7 +3819,7 @@ decode_dsp32mac_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
|
|||||||
if (w0 == 1 || op0 != 3)
|
if (w0 == 1 || op0 != 3)
|
||||||
{
|
{
|
||||||
bu32 res0 = decode_macfunc (cpu, 0, op0, h00, h10, src0,
|
bu32 res0 = decode_macfunc (cpu, 0, op0, h00, h10, src0,
|
||||||
src1, mmod, 0, P, &v_i, &n_0);
|
src1, mmod, 0, P, &v_0, &n_0);
|
||||||
|
|
||||||
if (w0)
|
if (w0)
|
||||||
buf += sprintf (buf, P ? "R%i" : "R%i.L", dst);
|
buf += sprintf (buf, P ? "R%i" : "R%i.L", dst);
|
||||||
@ -3830,6 +3851,8 @@ decode_dsp32mac_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
|
|||||||
res = REG_H_L (res, res0);
|
res = REG_H_L (res, res0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
v_0 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE_INSN (cpu, "%s%s;", _buf, mac_optmode (mmod, _MM));
|
TRACE_INSN (cpu, "%s%s;", _buf, mac_optmode (mmod, _MM));
|
||||||
@ -3837,15 +3860,15 @@ decode_dsp32mac_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
|
|||||||
if (!P && (w0 || w1))
|
if (!P && (w0 || w1))
|
||||||
{
|
{
|
||||||
STORE (DREG (dst), res);
|
STORE (DREG (dst), res);
|
||||||
SET_ASTATREG (v, v_i);
|
SET_ASTATREG (v, v_0 | v_1);
|
||||||
if (v_i)
|
if (v_0 || v_1)
|
||||||
SET_ASTATREG (vs, v_i);
|
SET_ASTATREG (vs, 1);
|
||||||
}
|
}
|
||||||
else if (P)
|
else if (P)
|
||||||
{
|
{
|
||||||
SET_ASTATREG (v, v_i);
|
SET_ASTATREG (v, v_0 | v_1);
|
||||||
if (v_i)
|
if (v_0 || v_1)
|
||||||
SET_ASTATREG (vs, v_i);
|
SET_ASTATREG (vs, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((w0 == 1 && op0 == 3) || (w1 == 1 && op1 == 3))
|
if ((w0 == 1 && op0 == 3) || (w1 == 1 && op1 == 3))
|
||||||
|
Reference in New Issue
Block a user