aboutsummaryrefslogtreecommitdiff
path: root/target-arm
diff options
context:
space:
mode:
authorRichard Henderson <rth@twiddle.net>2013-02-19 23:52:05 -0800
committerBlue Swirl <blauwirbel@gmail.com>2013-02-23 17:25:29 +0000
commit831d7fe800774db0d7142fdf2a8f8758c8bf9c92 (patch)
tree7eefe470335a31d5eddb5cfbfa1ac89183d2c242 /target-arm
parentdc46d1c68aa107b8e3c95f66e87cd9d02e6452a9 (diff)
target-arm: Use mul[us]2 in gen_mul[us]_i64_i32
Cc: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <rth@twiddle.net> Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Diffstat (limited to 'target-arm')
-rw-r--r--target-arm/translate.c38
1 files changed, 22 insertions, 16 deletions
diff --git a/target-arm/translate.c b/target-arm/translate.c
index a8893f767f..129f6744cb 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -305,35 +305,41 @@ static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv b)
return a;
}
-/* FIXME: Most targets have native widening multiplication.
- It would be good to use that instead of a full wide multiply. */
/* 32x32->64 multiply. Marks inputs as dead. */
static TCGv_i64 gen_mulu_i64_i32(TCGv a, TCGv b)
{
- TCGv_i64 tmp1 = tcg_temp_new_i64();
- TCGv_i64 tmp2 = tcg_temp_new_i64();
+ TCGv lo = tcg_temp_new_i32();
+ TCGv hi = tcg_temp_new_i32();
+ TCGv_i64 ret;
- tcg_gen_extu_i32_i64(tmp1, a);
+ tcg_gen_mulu2_i32(lo, hi, a, b);
tcg_temp_free_i32(a);
- tcg_gen_extu_i32_i64(tmp2, b);
tcg_temp_free_i32(b);
- tcg_gen_mul_i64(tmp1, tmp1, tmp2);
- tcg_temp_free_i64(tmp2);
- return tmp1;
+
+ ret = tcg_temp_new_i64();
+ tcg_gen_concat_i32_i64(ret, lo, hi);
+ tcg_temp_free(lo);
+ tcg_temp_free(hi);
+
+ return ret;
}
static TCGv_i64 gen_muls_i64_i32(TCGv a, TCGv b)
{
- TCGv_i64 tmp1 = tcg_temp_new_i64();
- TCGv_i64 tmp2 = tcg_temp_new_i64();
+ TCGv lo = tcg_temp_new_i32();
+ TCGv hi = tcg_temp_new_i32();
+ TCGv_i64 ret;
- tcg_gen_ext_i32_i64(tmp1, a);
+ tcg_gen_muls2_i32(lo, hi, a, b);
tcg_temp_free_i32(a);
- tcg_gen_ext_i32_i64(tmp2, b);
tcg_temp_free_i32(b);
- tcg_gen_mul_i64(tmp1, tmp1, tmp2);
- tcg_temp_free_i64(tmp2);
- return tmp1;
+
+ ret = tcg_temp_new_i64();
+ tcg_gen_concat_i32_i64(ret, lo, hi);
+ tcg_temp_free(lo);
+ tcg_temp_free(hi);
+
+ return ret;
}
/* Swap low and high halfwords. */