sim: bfin: handle large shift values with accumulator shift insns
authorMike Frysinger <vapier@gentoo.org>
Sat, 18 Jun 2011 20:59:54 +0000 (20:59 +0000)
committerMike Frysinger <vapier@gentoo.org>
Sat, 18 Jun 2011 20:59:54 +0000 (20:59 +0000)
When the shift magnitude exceeds 32 bits, the values rotate around (since
the hardware is actually a barrel shifter).  So handle this edge case,
update the corresponding AV bit in ASTAT which was missing previously,
and tweak the AZ setting based on how the hardware behaves.

Signed-off-by: Robin Getz <robin.getz@analog.com>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
sim/bfin/ChangeLog
sim/bfin/bfin-sim.c

index c702981..31efa11 100644 (file)
@@ -1,5 +1,11 @@
 2011-06-18  Robin Getz  <robin.getz@analog.com>
 
+       * bfin-sim.c (decode_dsp32shiftimm_0): When shift is greater than
+       32, perform a left shift.  Update the corresponding AV bit.  Set
+       AZ when the low 32bits are also zero.
+
+2011-06-18  Robin Getz  <robin.getz@analog.com>
+
        * bfin-sim.c (decode_dsp32shiftimm_0): With left shift vector insns,
        call lshift only when count is positive.  Otherwise, call ashiftrt.
        With arithmetic right shift insns, call ashiftrt when the value is
index 11eea3a..b982aaf 100644 (file)
@@ -5775,11 +5775,17 @@ decode_dsp32shiftimm_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
       if (sop == 0)
        acc <<= shiftup;
       else
-       acc >>= shiftdn;
+       {
+         if (shiftdn <= 32)
+           acc >>= shiftdn;
+         else
+           acc <<= 32 - (shiftdn & 0x1f);
+       }
 
       SET_AREG (HLs, acc);
+      SET_ASTATREG (av[HLs], 0);
       SET_ASTATREG (an, !!(acc & 0x8000000000ull));
-      SET_ASTATREG (az, acc == 0);
+      SET_ASTATREG (az, (acc & 0xFFFFFFFFFF) == 0);
     }
   else if (sop == 1 && sopcde == 1 && bit8 == 0)
     {