diff options
author | Jim Wilson <jim.wilson@linaro.org> | 2017-03-03 13:10:45 -0800 |
---|---|---|
committer | Jim Wilson <jim.wilson@linaro.org> | 2017-03-03 13:10:45 -0800 |
commit | 8ecbe595e69a84a0e3053884832d63af37113680 (patch) | |
tree | ce6ff5924c03fd1d2287b713bb8150aaeccc4def /sim/aarch64 | |
parent | df97be551faa262732128493c8ac159ae4b7f6d3 (diff) | |
download | gdb-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/ChangeLog | 6 | ||||
-rw-r--r-- | sim/aarch64/simulator.c | 19 |
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); } |