summaryrefslogtreecommitdiff
path: root/sim/bfin
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2012-04-09 05:56:32 +0000
committerMike Frysinger <vapier@gentoo.org>2012-04-09 05:56:32 +0000
commitc0c463826f679c70950874dd07ecc3947ccff320 (patch)
tree5b85755c18cf32193ab04316cc1ffe002987ca5a /sim/bfin
parentef0b041e050c0a7f489a1a68ca284db910742cbc (diff)
downloadbinutils-c0c463826f679c70950874dd07ecc3947ccff320.tar.gz
binutils-c0c463826f679c70950874dd07ecc3947ccff320.tar.bz2
binutils-c0c463826f679c70950874dd07ecc3947ccff320.zip
sim: bfin: fix ASTAT issues in immediate shifts
More ASTAT directed fixes, but this time at the dsp32shift insns. Signed-off-by: Robin Getz <robin.getz@analog.com> Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'sim/bfin')
-rw-r--r--sim/bfin/ChangeLog6
-rw-r--r--sim/bfin/bfin-sim.c75
2 files changed, 64 insertions, 17 deletions
diff --git a/sim/bfin/ChangeLog b/sim/bfin/ChangeLog
index 14cb28d26d0..8134269e06c 100644
--- a/sim/bfin/ChangeLog
+++ b/sim/bfin/ChangeLog
@@ -1,5 +1,11 @@
2012-04-09 Robin Getz <robin.getz@analog.com>
+ * bfin-sim.c (decode_dsp32shift_0): Extract the sign for ASHIFT
+ and LSHIFT, and set ASTAT based on the before/after values.
+ Rename "val" to "acc" to be consistent with other code branches.
+
+2012-04-09 Robin Getz <robin.getz@analog.com>
+
* bfin-sim.c (sgn_extend): New helper.
(decode_dsp32shiftimm_0): Call lshift when newimmag is more
than 16, otherwise call ashiftrt. Set ASTAT fields as needed.
diff --git a/sim/bfin/bfin-sim.c b/sim/bfin/bfin-sim.c
index e3201ef2b66..169079bdb6b 100644
--- a/sim/bfin/bfin-sim.c
+++ b/sim/bfin/bfin-sim.c
@@ -5206,7 +5206,16 @@ decode_dsp32shift_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
if (shft <= 0)
val = ashiftrt (cpu, val, -shft, 16);
else
- val = lshift (cpu, val, shft, 16, sop == 1, 1);
+ {
+ int sgn = (val >> 15) & 0x1;
+
+ val = lshift (cpu, val, shft, 16, sop == 1, 1);
+ if (((val >> 15) & 0x1) != sgn)
+ {
+ SET_ASTATREG (v, 1);
+ SET_ASTATREG (vs, 1);
+ }
+ }
if ((HLs & 2) == 0)
STORE (DREG (dst0), REG_H_L (DREG (dst0), val));
@@ -5258,42 +5267,40 @@ decode_dsp32shift_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
else if (sop == 0 && sopcde == 3 && (HLs == 0 || HLs == 1))
{
bs32 shft = (bs8)(DREG (src0) << 2) >> 2;
- bu64 val = get_extended_acc (cpu, HLs);
+ bu64 acc = get_extended_acc (cpu, HLs);
+ bu64 val;
HLs = !!HLs;
TRACE_INSN (cpu, "A%i = ASHIFT A%i BY R%i.L;", HLs, HLs, src0);
- TRACE_DECODE (cpu, "A%i:%#"PRIx64" shift:%i", HLs, val, shft);
+ TRACE_DECODE (cpu, "A%i:%#"PRIx64" shift:%i", HLs, acc, shft);
if (shft <= 0)
- val = ashiftrt (cpu, val, -shft, 40);
+ val = ashiftrt (cpu, acc, -shft, 40);
else
- val = lshift (cpu, val, shft, 40, 0, 0);
+ val = lshift (cpu, acc, shft, 40, 0, 0);
STORE (AXREG (HLs), (val >> 32) & 0xff);
STORE (AWREG (HLs), (val & 0xffffffff));
- STORE (ASTATREG (av[HLs]), val == 0);
- if (val == 0)
- STORE (ASTATREG (avs[HLs]), 1);
+ STORE (ASTATREG (av[HLs]), 0);
}
else if (sop == 1 && sopcde == 3 && (HLs == 0 || HLs == 1))
{
bs32 shft = (bs8)(DREG (src0) << 2) >> 2;
+ bu64 acc = get_unextended_acc (cpu, HLs);
bu64 val;
HLs = !!HLs;
TRACE_INSN (cpu, "A%i = LSHIFT A%i BY R%i.L;", HLs, HLs, src0);
- val = get_unextended_acc (cpu, HLs);
+ TRACE_DECODE (cpu, "A%i:%#"PRIx64" shift:%i", HLs, acc, shft);
if (shft <= 0)
- val = lshiftrt (cpu, val, -shft, 40);
+ val = lshiftrt (cpu, acc, -shft, 40);
else
- val = lshift (cpu, val, shft, 40, 0, 0);
+ val = lshift (cpu, acc, shft, 40, 0, 0);
STORE (AXREG (HLs), (val >> 32) & 0xff);
STORE (AWREG (HLs), (val & 0xffffffff));
- STORE (ASTATREG (av[HLs]), val == 0);
- if (val == 0)
- STORE (ASTATREG (avs[HLs]), 1);
+ STORE (ASTATREG (av[HLs]), 0);
}
else if ((sop == 0 || sop == 1) && sopcde == 1)
{
@@ -5315,9 +5322,18 @@ decode_dsp32shift_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
}
else
{
+ int sgn0 = (val0 >> 15) & 0x1;
+ int sgn1 = (val1 >> 15) & 0x1;
+
val0 = lshift (cpu, val0, shft, 16, sop == 1, 1);
astat = ASTAT;
val1 = lshift (cpu, val1, shft, 16, sop == 1, 1);
+
+ if ((sgn0 != ((val0 >> 15) & 0x1)) || (sgn1 != ((val1 >> 15) & 0x1)))
+ {
+ SET_ASTATREG (v, 1);
+ SET_ASTATREG (vs, 1);
+ }
}
SET_ASTAT (ASTAT | astat);
STORE (DREG (dst0), (val1 << 16) | val0);
@@ -5342,7 +5358,16 @@ decode_dsp32shift_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
STORE (DREG (dst0), ashiftrt (cpu, v, -shft, 32));
}
else
- STORE (DREG (dst0), lshift (cpu, v, shft, 32, sop == 1, 1));
+ {
+ bu32 val = lshift (cpu, v, shft, 32, sop == 1, 1);
+
+ STORE (DREG (dst0), val);
+ if (((v >> 31) & 0x1) != ((val >> 31) & 0x1))
+ {
+ SET_ASTATREG (v, 1);
+ SET_ASTATREG (vs, 1);
+ }
+ }
}
else if (sop == 3 && sopcde == 2)
{
@@ -5770,7 +5795,14 @@ decode_dsp32shiftimm_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
dst0, (HLs & 2) ? 'H' : 'L',
src1, (HLs & 1) ? 'H' : 'L', newimmag);
if (newimmag > 16)
- result = lshift (cpu, in, 16 - (newimmag & 0xF), 16, 0, 1);
+ {
+ result = lshift (cpu, in, 16 - (newimmag & 0xF), 16, 0, 1);
+ if (((result >> 15) & 0x1) != ((in >> 15) & 0x1))
+ {
+ SET_ASTATREG (v, 1);
+ SET_ASTATREG (vs, 1);
+ }
+ }
else
result = ashiftrt (cpu, in, newimmag, 16);
}
@@ -5972,11 +6004,20 @@ decode_dsp32shiftimm_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
TRACE_INSN (cpu, "R%i = R%i >>> %i %s;", dst0, src1, count,
sop == 0 ? "(V)" : "(V,S)");
- if (count & 0x10)
+ if (count > 16)
{
+ int sgn0 = (val0 >> 15) & 0x1;
+ int sgn1 = (val1 >> 15) & 0x1;
+
val0 = lshift (cpu, val0, 16 - (count & 0xF), 16, 0, 1);
astat = ASTAT;
val1 = lshift (cpu, val1, 16 - (count & 0xF), 16, 0, 1);
+
+ if ((sgn0 != ((val0 >> 15) & 0x1)) || (sgn1 != ((val1 >> 15) & 0x1)))
+ {
+ SET_ASTATREG (v, 1);
+ SET_ASTATREG (vs, 1);
+ }
}
else
{