aboutsummaryrefslogtreecommitdiff
path: root/sim
diff options
context:
space:
mode:
authorJeff Law <jeffreyalaw@gmail.com>2022-04-06 11:10:40 -0400
committerJeff Law <jeffreyalaw@gmail.com>2022-04-06 11:10:40 -0400
commit477904ca751c50d243ee3cba3f12cf75e8ba12b3 (patch)
treec8cc726797b77cc277f6ef04f51aa5deda085dfd /sim
parent49fffa58f7e6da777d10fe77663bc7c8f531fe7f (diff)
downloadgdb-477904ca751c50d243ee3cba3f12cf75e8ba12b3.zip
gdb-477904ca751c50d243ee3cba3f12cf75e8ba12b3.tar.gz
gdb-477904ca751c50d243ee3cba3f12cf75e8ba12b3.tar.bz2
Fix for v850e divq instruction
This is the last of the correctness fixes I've been carrying around for the v850. Like the other recent fixes, this is another case where we haven't been as careful as we should WRT host vs target types. For the divq instruction both operands are 32 bit types. Yet in the simulator code we convert them from unsigned int to signed long by assignment. So 0xfffffffb (aka -5) turns into 4294967291 and naturally that changes the result of our division. The fix is simple, insert a cast to int32_t to force interpretation as a signed value. Testcase for the simulator is included. It has a trivial dependency on the bins patch.
Diffstat (limited to 'sim')
-rw-r--r--sim/testsuite/v850/divq.cgs11
-rw-r--r--sim/v850/simops.c4
2 files changed, 13 insertions, 2 deletions
diff --git a/sim/testsuite/v850/divq.cgs b/sim/testsuite/v850/divq.cgs
new file mode 100644
index 0000000..8461f86
--- /dev/null
+++ b/sim/testsuite/v850/divq.cgs
@@ -0,0 +1,11 @@
+# v850 bins
+# mach: v850e3v5
+# as: -mv850e3v5
+
+ .include "testutils.inc"
+ seti 0xfffffffb r11
+ seti 0x32 r10
+ divq r11, r10, r11
+ reg r10, 0xfffffff6
+ reg r11, 0x0
+ pass
diff --git a/sim/v850/simops.c b/sim/v850/simops.c
index e9a5d48..f90a0f7 100644
--- a/sim/v850/simops.c
+++ b/sim/v850/simops.c
@@ -3135,8 +3135,8 @@ v850_div (SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p, u
bfd_boolean overflow = FALSE;
/* Compute the result. */
- divide_by = op0;
- divide_this = op1;
+ divide_by = (int32_t)op0;
+ divide_this = (int32_t)op1;
if (divide_by == 0 || (divide_by == -1 && divide_this == (1 << 31)))
{