diff options
author | Richard Henderson | 2019-08-29 03:32:58 +0200 |
---|---|---|
committer | Peter Maydell | 2019-09-03 17:20:34 +0200 |
commit | e0a0c8322b8ebcdad674f443a3e86db8708d6738 (patch) | |
tree | 5c5a2d7661ed25b49d5aa1c12bff3b2936217e08 | |
parent | hw/arm/smmuv3: Remove spurious error messages on IOVA invalidations (diff) | |
download | qemu-e0a0c8322b8ebcdad674f443a3e86db8708d6738.tar.gz qemu-e0a0c8322b8ebcdad674f443a3e86db8708d6738.tar.xz qemu-e0a0c8322b8ebcdad674f443a3e86db8708d6738.zip |
target/arm: Fix SMMLS argument order
The previous simplification got the order of operands to the
subtraction wrong. Since the 64-bit product is the subtrahend,
we must use a 64-bit subtract to properly compute the borrow
from the low-part of the product.
Fixes: 5f8cd06ebcf5 ("target/arm: Simplify SMMLA, SMMLAR, SMMLS, SMMLSR")
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
Message-id: 20190829013258.16102-1-richard.henderson@linaro.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | target/arm/translate.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/target/arm/translate.c b/target/arm/translate.c index 78d93f63ca..cfebd35d26 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -8831,7 +8831,16 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) if (rd != 15) { tmp3 = load_reg(s, rd); if (insn & (1 << 6)) { - tcg_gen_sub_i32(tmp, tmp, tmp3); + /* + * For SMMLS, we need a 64-bit subtract. + * Borrow caused by a non-zero multiplicand + * lowpart, and the correct result lowpart + * for rounding. + */ + TCGv_i32 zero = tcg_const_i32(0); + tcg_gen_sub2_i32(tmp2, tmp, zero, tmp3, + tmp2, tmp); + tcg_temp_free_i32(zero); } else { tcg_gen_add_i32(tmp, tmp, tmp3); } @@ -10075,7 +10084,14 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn) if (insn & (1 << 20)) { tcg_gen_add_i32(tmp, tmp, tmp3); } else { - tcg_gen_sub_i32(tmp, tmp, tmp3); + /* + * For SMMLS, we need a 64-bit subtract. + * Borrow caused by a non-zero multiplicand lowpart, + * and the correct result lowpart for rounding. + */ + TCGv_i32 zero = tcg_const_i32(0); + tcg_gen_sub2_i32(tmp2, tmp, zero, tmp3, tmp2, tmp); + tcg_temp_free_i32(zero); } tcg_temp_free_i32(tmp3); } |