aboutsummaryrefslogtreecommitdiff
path: root/sim
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2011-03-15 20:09:39 +0000
committerMike Frysinger <vapier@gentoo.org>2011-03-15 20:09:39 +0000
commit86d3d8de687fda121bd8d12a9d0e9f00e7284bf1 (patch)
treef3d7d49f05cc0c98bfab9e63ce1902213d31623a /sim
parent9b7509d90051f21ad1af0f86c079ab3a35ae0c1e (diff)
downloadfsf-binutils-gdb-86d3d8de687fda121bd8d12a9d0e9f00e7284bf1.zip
fsf-binutils-gdb-86d3d8de687fda121bd8d12a9d0e9f00e7284bf1.tar.gz
fsf-binutils-gdb-86d3d8de687fda121bd8d12a9d0e9f00e7284bf1.tar.bz2
sim: bfin: handle AN (negative overflows) in dsp mult insns
The current dsp mult handler does not take care of overflows which turn values negative (and thus set AN in ASTAT). So implement it. Signed-off-by: Robin Getz <robin.getz@analog.com> Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'sim')
-rw-r--r--sim/bfin/ChangeLog7
-rw-r--r--sim/bfin/bfin-sim.c41
2 files changed, 40 insertions, 8 deletions
diff --git a/sim/bfin/ChangeLog b/sim/bfin/ChangeLog
index d8cbc40..45bf0a8 100644
--- a/sim/bfin/ChangeLog
+++ b/sim/bfin/ChangeLog
@@ -1,5 +1,12 @@
2011-03-15 Robin Getz <robin.getz@analog.com>
+ * bfin-sim.c (decode_macfunc): New neg parameter. Set when the
+ high bit is set after extract_mult.
+ (decode_dsp32mac_0): Declare n_1 and n_0. Pass to the decode_macfunc
+ functions. Use these to update the AN bit.
+
+2011-03-15 Robin Getz <robin.getz@analog.com>
+
* bfin-sim.c (decode_dsp32mult_0): Declare v_i0 and v_i1. Pass to
the extract_mult functions. Include these when updating the V, VS,
and V_COPY bits.
diff --git a/sim/bfin/bfin-sim.c b/sim/bfin/bfin-sim.c
index 5df7340..ba0e0c2 100644
--- a/sim/bfin/bfin-sim.c
+++ b/sim/bfin/bfin-sim.c
@@ -1562,10 +1562,11 @@ extract_mult (SIM_CPU *cpu, bu64 res, int mmod, int MM,
static bu32
decode_macfunc (SIM_CPU *cpu, int which, int op, int h0, int h1, int src0,
- int src1, int mmod, int MM, int fullword, bu32 *overflow)
+ int src1, int mmod, int MM, int fullword, bu32 *overflow,
+ bu32 *neg)
{
bu64 acc;
- bu32 sat = 0, tsat;
+ bu32 sat = 0, tsat, ret;
/* Sign extend accumulator if necessary, otherwise unsigned. */
if (mmod == 0 || mmod == M_T || mmod == M_IS || mmod == M_ISS2
@@ -1658,6 +1659,9 @@ decode_macfunc (SIM_CPU *cpu, int which, int op, int h0, int h1, int src0,
default:
illegal_instruction (cpu);
}
+
+ if (acc & 0x8000000000ull)
+ *neg = 1;
}
STORE (AXREG (which), (acc >> 32) & 0xff);
@@ -1666,7 +1670,20 @@ decode_macfunc (SIM_CPU *cpu, int which, int op, int h0, int h1, int src0,
if (sat)
STORE (ASTATREG (avs[which]), sat);
- return extract_mult (cpu, acc, mmod, MM, fullword, overflow);
+ ret = extract_mult (cpu, acc, mmod, MM, fullword, overflow);
+
+ if (!fullword)
+ {
+ if (ret & 0x8000)
+ *neg = 1;
+ }
+ else
+ {
+ if (ret & 0x80000000)
+ *neg = 1;
+ }
+
+ return ret;
}
bu32
@@ -3702,7 +3719,7 @@ decode_dsp32mac_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
int h01 = ((iw1 >> DSP32Mac_h01_bits) & DSP32Mac_h01_mask);
bu32 res = DREG (dst);
- bu32 v_i = 0, zero = 0;
+ bu32 v_i = 0, zero = 0, n_1 = 0, n_0 = 0;
static const char * const ops[] = { "=", "+=", "-=" };
char _buf[128], *buf = _buf;
@@ -3727,7 +3744,7 @@ decode_dsp32mac_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
if (w1 == 1 || op1 != 3)
{
bu32 res1 = decode_macfunc (cpu, 1, op1, h01, h11, src0,
- src1, mmod, MM, P, &v_i);
+ src1, mmod, MM, P, &v_i, &n_1);
if (w1)
buf += sprintf (buf, P ? "R%i" : "R%i.H", dst + P);
@@ -3773,7 +3790,7 @@ decode_dsp32mac_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
if (w0 == 1 || op0 != 3)
{
bu32 res0 = decode_macfunc (cpu, 0, op0, h00, h10, src0,
- src1, mmod, 0, P, &v_i);
+ src1, mmod, 0, P, &v_i, &n_0);
if (w0)
buf += sprintf (buf, P ? "R%i" : "R%i.L", dst);
@@ -3822,8 +3839,16 @@ decode_dsp32mac_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
if (v_i)
SET_ASTATREG (vs, v_i);
}
- if (op0 == 3 || op1 == 3)
- SET_ASTATREG (az, zero);
+
+ if ((w0 == 1 && op0 == 3) || (w1 == 1 && op1 == 3))
+ {
+ SET_ASTATREG (az, zero);
+ if (!(w0 == 1 && op0 == 3))
+ n_0 = 0;
+ if (!(w1 == 1 && op1 == 3))
+ n_1 = 0;
+ SET_ASTATREG (an, n_1 | n_0);
+ }
}
static void