This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] sim: bfin: handle odd shift values with shift insns


From: Robin Getz <robin.getz@analog.com>

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.

Committed.

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

2011-03-21  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
	small enough, otherwise call lshift.
---
 sim/bfin/bfin-sim.c |   36 +++++++++++++++++++++++++++++-------
 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));
-- 
1.7.5.3


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]