summaryrefslogtreecommitdiff
path: root/sim
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2013-06-24 02:03:03 +0000
committerMike Frysinger <vapier@gentoo.org>2013-06-24 02:03:03 +0000
commitbc30f4ee106d73efe2f50645a906967106b63071 (patch)
tree61077f3c3be2e5d5092045d51c02303a2aa8852d /sim
parent273839b58a3773e6e6e9fc704201d32232f88050 (diff)
downloadgdb-bc30f4ee106d73efe2f50645a906967106b63071.tar.gz
sim: bfin: handle invalid HLs encoding in dsp shift insns
For many of the 32bit dsp shift related insns, we were just ignoring the HLs field. The hardware does not though and will reject the insn if it's set incorrectly. Update the sim to match.
Diffstat (limited to 'sim')
-rw-r--r--sim/bfin/ChangeLog7
-rw-r--r--sim/bfin/bfin-sim.c14
2 files changed, 16 insertions, 5 deletions
diff --git a/sim/bfin/ChangeLog b/sim/bfin/ChangeLog
index 59c4ce279a3..17a75f138ce 100644
--- a/sim/bfin/ChangeLog
+++ b/sim/bfin/ChangeLog
@@ -1,3 +1,10 @@
+2013-06-23 Mike Frysinger <vapier@gentoo.org>
+
+ * bfin-sim.c (decode_dsp32shift_0): Make sure HLs is 0 after last
+ insn that uses it.
+ (decode_dsp32shiftimm_0): Likewise.
+ Require HLs be less than 2 for accumulator shift insns.
+
2013-06-18 Mike Frysinger <vapier@gentoo.org>
* bfin-sim.c (decode_dsp32alu_0): Check more opcode fields before
diff --git a/sim/bfin/bfin-sim.c b/sim/bfin/bfin-sim.c
index 2d6be16e6e5..90e09106c5b 100644
--- a/sim/bfin/bfin-sim.c
+++ b/sim/bfin/bfin-sim.c
@@ -5333,6 +5333,9 @@ decode_dsp32shift_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
STORE (AWREG (HLs), (val & 0xffffffff));
STORE (ASTATREG (av[HLs]), 0);
}
+ else if (HLs != 0)
+ /* All the insns after this point don't use HLs. */
+ illegal_instruction (cpu);
else if ((sop == 0 || sop == 1) && sopcde == 1 && HLs == 0)
{
bs32 shft = (bs8)(DREG (src0) << 2) >> 2;
@@ -5917,12 +5920,11 @@ decode_dsp32shiftimm_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
if (shift)
SET_CCREG (cc);
}
- else if (sop == 0 && sopcde == 3 && bit8 == 1)
+ else if (sop == 0 && sopcde == 3 && bit8 == 1 && HLs < 2)
{
/* Arithmetic shift, so shift in sign bit copies. */
bu64 acc, val;
int shift = uimm5 (newimmag);
- HLs = !!HLs;
TRACE_INSN (cpu, "A%i = A%i >>> %i;", HLs, HLs, shift);
@@ -5938,13 +5940,12 @@ decode_dsp32shiftimm_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
STORE (ASTATREG (az), !val);
STORE (ASTATREG (av[HLs]), 0);
}
- else if ((sop == 0 && sopcde == 3 && bit8 == 0)
- || (sop == 1 && sopcde == 3))
+ else if (((sop == 0 && sopcde == 3 && bit8 == 0)
+ || (sop == 1 && sopcde == 3)) && HLs < 2)
{
bu64 acc;
int shiftup = uimm5 (immag);
int shiftdn = uimm5 (newimmag);
- HLs = !!HLs;
TRACE_INSN (cpu, "A%i = A%i %s %i;", HLs, HLs,
sop == 0 ? "<<" : ">>",
@@ -5971,6 +5972,9 @@ decode_dsp32shiftimm_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
SET_ASTATREG (an, !!(acc & 0x8000000000ull));
SET_ASTATREG (az, (acc & 0xFFFFFFFFFF) == 0);
}
+ else if (HLs != 0)
+ /* All the insns after this point don't use HLs. */
+ illegal_instruction (cpu);
else if (sop == 1 && sopcde == 1 && bit8 == 0)
{
int count = imm5 (immag);