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>
This commit is contained in:
parent
4bd2c0c31c
commit
99dcc4dc65
2 changed files with 36 additions and 7 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
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
|
||||||
|
small enough, otherwise call lshift.
|
||||||
|
|
||||||
2011-06-18 Robin Getz <robin.getz@analog.com>
|
2011-06-18 Robin Getz <robin.getz@analog.com>
|
||||||
|
|
||||||
* bfin-sim.c (extract_mult): Call saturate_s16 directly when
|
* bfin-sim.c (extract_mult): Call saturate_s16 directly when
|
||||||
|
|
|
@ -5678,7 +5678,10 @@ decode_dsp32shiftimm_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
|
||||||
TRACE_INSN (cpu, "R%i.%c = R%i.%c >>> %i;",
|
TRACE_INSN (cpu, "R%i.%c = R%i.%c >>> %i;",
|
||||||
dst0, (HLs & 2) ? 'H' : 'L',
|
dst0, (HLs & 2) ? 'H' : 'L',
|
||||||
src1, (HLs & 1) ? 'H' : 'L', newimmag);
|
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)
|
else if (sop == 1 && bit8 == 0)
|
||||||
{
|
{
|
||||||
|
@ -5786,9 +5789,18 @@ decode_dsp32shiftimm_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
|
||||||
bu32 astat;
|
bu32 astat;
|
||||||
|
|
||||||
TRACE_INSN (cpu, "R%i = R%i << %i (V,S);", dst0, src1, count);
|
TRACE_INSN (cpu, "R%i = R%i << %i (V,S);", dst0, src1, count);
|
||||||
val0 = lshift (cpu, val0, count, 16, 1);
|
if (count >= 0)
|
||||||
astat = ASTAT;
|
{
|
||||||
val1 = lshift (cpu, val1, count, 16, 1);
|
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);
|
SET_ASTAT (ASTAT | astat);
|
||||||
|
|
||||||
STORE (DREG (dst0), (val0 << 16) | val1);
|
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,
|
TRACE_INSN (cpu, "R%i = R%i >>> %i %s;", dst0, src1, count,
|
||||||
sop == 0 ? "(V)" : "(V,S)");
|
sop == 0 ? "(V)" : "(V,S)");
|
||||||
|
|
||||||
val0 = ashiftrt (cpu, val0, count, 16);
|
if (count & 0x10)
|
||||||
astat = ASTAT;
|
{
|
||||||
val1 = ashiftrt (cpu, val1, count, 16);
|
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);
|
SET_ASTAT (ASTAT | astat);
|
||||||
|
|
||||||
STORE (DREG (dst0), REG_H_L (val1 << 16, val0));
|
STORE (DREG (dst0), REG_H_L (val1 << 16, val0));
|
||||||
|
|
Loading…
Reference in a new issue