aboutsummaryrefslogtreecommitdiff
path: root/sim/bfin/bfin-sim.c
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2011-06-18 20:59:24 +0000
committerMike Frysinger <vapier@gentoo.org>2011-06-18 20:59:24 +0000
commit99dcc4dc6501c726df79173fa254faebc68a486d (patch)
tree7b6f02f91d68dbd0e7627569a616a75bd72a5ae4 /sim/bfin/bfin-sim.c
parent4bd2c0c31ccea3032031648e7497bb7d1c04cc39 (diff)
downloadfsf-binutils-gdb-99dcc4dc6501c726df79173fa254faebc68a486d.zip
fsf-binutils-gdb-99dcc4dc6501c726df79173fa254faebc68a486d.tar.gz
fsf-binutils-gdb-99dcc4dc6501c726df79173fa254faebc68a486d.tar.bz2
sim: bfin: handle odd shift values with shift insns
The shift magnitude is a 5-bit signed value. When it is between 0 and 15, then we do the requested shift, but when it is outside of that, we have to do the opposite. That means we flip between lshift and ashiftrt to match the hardware. Signed-off-by: Robin Getz <robin.getz@analog.com> Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'sim/bfin/bfin-sim.c')
-rw-r--r--sim/bfin/bfin-sim.c36
1 files changed, 29 insertions, 7 deletions
diff --git a/sim/bfin/bfin-sim.c b/sim/bfin/bfin-sim.c
index 38e5fe1..11eea3a 100644
--- a/sim/bfin/bfin-sim.c
+++ b/sim/bfin/bfin-sim.c
@@ -5678,7 +5678,10 @@ decode_dsp32shiftimm_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
TRACE_INSN (cpu, "R%i.%c = R%i.%c >>> %i;",
dst0, (HLs & 2) ? 'H' : 'L',
src1, (HLs & 1) ? 'H' : 'L', newimmag);
- result = ashiftrt (cpu, in, newimmag, 16);
+ if (newimmag > 16)
+ result = lshift (cpu, in, 16 - (newimmag & 0xF), 16, 0);
+ else
+ result = ashiftrt (cpu, in, newimmag, 16);
}
else if (sop == 1 && bit8 == 0)
{
@@ -5786,9 +5789,18 @@ decode_dsp32shiftimm_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
bu32 astat;
TRACE_INSN (cpu, "R%i = R%i << %i (V,S);", dst0, src1, count);
- val0 = lshift (cpu, val0, count, 16, 1);
- astat = ASTAT;
- val1 = lshift (cpu, val1, count, 16, 1);
+ if (count >= 0)
+ {
+ val0 = lshift (cpu, val0, count, 16, 1);
+ astat = ASTAT;
+ val1 = lshift (cpu, val1, count, 16, 1);
+ }
+ else
+ {
+ val0 = ashiftrt (cpu, val0, -count, 16);
+ astat = ASTAT;
+ val1 = ashiftrt (cpu, val1, -count, 16);
+ }
SET_ASTAT (ASTAT | astat);
STORE (DREG (dst0), (val0 << 16) | val1);
@@ -5833,9 +5845,19 @@ 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)");
- val0 = ashiftrt (cpu, val0, count, 16);
- astat = ASTAT;
- val1 = ashiftrt (cpu, val1, count, 16);
+ if (count & 0x10)
+ {
+ val0 = lshift (cpu, val0, 16 - (count & 0xF), 16, 0);
+ astat = ASTAT;
+ val1 = lshift (cpu, val1, 16 - (count & 0xF), 16, 0);
+ }
+ else
+ {
+ val0 = ashiftrt (cpu, val0, count, 16);
+ astat = ASTAT;
+ val1 = ashiftrt (cpu, val1, count, 16);
+ }
+
SET_ASTAT (ASTAT | astat);
STORE (DREG (dst0), REG_H_L (val1 << 16, val0));