sim: bfin: handle negative left saturated shifts as ashifts [BZ #18407]
authorMike Frysinger <vapier@gentoo.org>
Sun, 11 Oct 2015 07:32:11 +0000 (03:32 -0400)
committerMike Frysinger <vapier@gentoo.org>
Sun, 11 Oct 2015 07:42:09 +0000 (03:42 -0400)
When handling left saturated ashifts with negative immediates, they
should be treated as right ashifts.  This matches hardware behavior.

Reported-by: Igor Rayak <igorr@gitatechnologies.com>
sim/bfin/ChangeLog
sim/bfin/bfin-sim.c
sim/testsuite/sim/bfin/ChangeLog
sim/testsuite/sim/bfin/ashift_left.s [new file with mode: 0644]

index d0e91b3b5a517199e006ba79a9ef34baa33da986..2e62a74de34abab98e402c8eb970c7d6b7850950 100644 (file)
@@ -1,3 +1,9 @@
+2015-10-11  Mike Frysinger  <vapier@gentoo.org>
+
+       PR sim/18407
+       * bfin-sim.c (decode_dsp32shiftimm_0): Call ashiftrt when count
+       is less than 0.
+
 2015-06-24  Mike Frysinger  <vapier@gentoo.org>
 
        * interp.c (trace_register): Delete.
index 8b19eadd25dbd6bc0d0ec96c3b49cb6032b96d6b..b6acb4e6a50b42ae84d983ae4961fe7637d43ff8 100644 (file)
@@ -6083,7 +6083,11 @@ decode_dsp32shiftimm_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
       int count = imm6 (immag);
 
       TRACE_INSN (cpu, "R%i = R%i << %i (S);", dst0, src1, count);
-      STORE (DREG (dst0), lshift (cpu, DREG (src1), count, 32, 1, 1));
+
+      if (count < 0)
+       STORE (DREG (dst0), ashiftrt (cpu, DREG (src1), -count, 32));
+      else
+       STORE (DREG (dst0), lshift (cpu, DREG (src1), count, 32, 1, 1));
     }
   else if (sop == 2 && sopcde == 2)
     {
index 89d2833637008a3294888d046ff2bb10c9ed1f30..4fc604f9af655902567404ce80625864db056fdd 100644 (file)
@@ -1,3 +1,8 @@
+2015-10-11  Mike Frysinger  <vapier@gentoo.org>
+
+       PR sim/18407
+       * ashift_left.s: New test.
+
 2013-12-07  Mike Frysinger  <vapier@gentoo.org>
 
        * run-tests.sh: Add +x file mode.
diff --git a/sim/testsuite/sim/bfin/ashift_left.s b/sim/testsuite/sim/bfin/ashift_left.s
new file mode 100644 (file)
index 0000000..04cfa40
--- /dev/null
@@ -0,0 +1,17 @@
+# Blackfin testcase for left ashift
+# Dreg = Dreg << imm (S);
+# mach: bfin
+
+       .include "testutils.inc"
+
+       .macro test in:req, shift:req, out:req, opt
+       imm32 r0, \in;
+       r1 = r0 >>> \shift \opt;
+       CHECKREG r1, \out;
+       .endm
+
+       start
+
+test 2, 1, 1, (S);
+
+       pass