aboutsummaryrefslogtreecommitdiff
path: root/sim/aarch64
diff options
context:
space:
mode:
authorJim Wilson <jim.wilson@linaro.org>2017-03-03 13:10:45 -0800
committerJim Wilson <jim.wilson@linaro.org>2017-03-03 13:10:45 -0800
commit8ecbe595e69a84a0e3053884832d63af37113680 (patch)
treece6ff5924c03fd1d2287b713bb8150aaeccc4def /sim/aarch64
parentdf97be551faa262732128493c8ac159ae4b7f6d3 (diff)
downloadgdb-8ecbe595e69a84a0e3053884832d63af37113680.zip
gdb-8ecbe595e69a84a0e3053884832d63af37113680.tar.gz
gdb-8ecbe595e69a84a0e3053884832d63af37113680.tar.bz2
Fix umulh and smulh bugs. Fix bugs in last week's sumov.s testsuite.
sim/aarch64/ * simulator.c (mul64hi): Shift carry left by 32. (smulh): Change signum to negate. If negate, invert result, and add carry bit if low part of multiply result is zero. sim/testsuite/sim/aarch64/ * sumov.s: Correct compare test values. * sumulh.s: New.
Diffstat (limited to 'sim/aarch64')
-rw-r--r--sim/aarch64/ChangeLog6
-rw-r--r--sim/aarch64/simulator.c19
2 files changed, 21 insertions, 4 deletions
diff --git a/sim/aarch64/ChangeLog b/sim/aarch64/ChangeLog
index b6c0256..0bf305a 100644
--- a/sim/aarch64/ChangeLog
+++ b/sim/aarch64/ChangeLog
@@ -1,3 +1,9 @@
+2017-03-03 Jim Wilson <jim.wilson@linaro.org>
+
+ * simulator.c (mul64hi): Shift carry left by 32.
+ (smulh): Change signum to negate. If negate, invert result, and add
+ carry bit if low part of multiply result is zero.
+
2017-02-25 Jim Wilson <jim.wilson@linaro.org>
* simulator.c (do_vec_SMOV_into_scalar): New.
diff --git a/sim/aarch64/simulator.c b/sim/aarch64/simulator.c
index 1756ba1..8a8df7a 100644
--- a/sim/aarch64/simulator.c
+++ b/sim/aarch64/simulator.c
@@ -13020,6 +13020,8 @@ mul64hi (uint64_t value1, uint64_t value2)
/* Drop lowest 32 bits of middle cross-product. */
result = resultmid1 >> 32;
+ /* Move carry bit to just above middle cross-product highest bit. */
+ carry = carry << 32;
/* Add top cross-product plus and any carry. */
result += xproducthi + carry;
@@ -13042,7 +13044,7 @@ smulh (sim_cpu *cpu)
int64_t value2 = aarch64_get_reg_u64 (cpu, rm, NO_SP);
uint64_t uvalue1;
uint64_t uvalue2;
- int64_t signum = 1;
+ int negate = 0;
if (ra != R31)
HALT_UNALLOC;
@@ -13051,7 +13053,7 @@ smulh (sim_cpu *cpu)
the fix the sign up afterwards. */
if (value1 < 0)
{
- signum *= -1L;
+ negate = !negate;
uvalue1 = -value1;
}
else
@@ -13061,7 +13063,7 @@ smulh (sim_cpu *cpu)
if (value2 < 0)
{
- signum *= -1L;
+ negate = !negate;
uvalue2 = -value2;
}
else
@@ -13070,9 +13072,18 @@ smulh (sim_cpu *cpu)
}
TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
+
uresult = mul64hi (uvalue1, uvalue2);
result = uresult;
- result *= signum;
+
+ if (negate)
+ {
+ /* Multiply 128-bit result by -1, which means highpart gets inverted,
+ and has carry in added only if low part is 0. */
+ result = ~result;
+ if ((uvalue1 * uvalue2) == 0)
+ result += 1;
+ }
aarch64_set_reg_s64 (cpu, rd, NO_SP, result);
}