[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 55/72] softfloat: Add float{16,32,64}_muladd_scalbn
From: |
Richard Henderson |
Subject: |
[PULL 55/72] softfloat: Add float{16,32,64}_muladd_scalbn |
Date: |
Tue, 24 Dec 2024 12:05:04 -0800 |
We currently have a flag, float_muladd_halve_result, to scale
the result by 2**-1. Extend this to handle arbitrary scaling.
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
include/fpu/softfloat.h | 6 ++++
fpu/softfloat.c | 58 ++++++++++++++++++++++-----------------
fpu/softfloat-parts.c.inc | 7 +++--
3 files changed, 44 insertions(+), 27 deletions(-)
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index eb64075b9c..c34ce0477d 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -238,6 +238,8 @@ float16 float16_add(float16, float16, float_status *status);
float16 float16_sub(float16, float16, float_status *status);
float16 float16_mul(float16, float16, float_status *status);
float16 float16_muladd(float16, float16, float16, int, float_status *status);
+float16 float16_muladd_scalbn(float16, float16, float16,
+ int, int, float_status *status);
float16 float16_div(float16, float16, float_status *status);
float16 float16_scalbn(float16, int, float_status *status);
float16 float16_min(float16, float16, float_status *status);
@@ -597,6 +599,8 @@ float32 float32_mul(float32, float32, float_status *status);
float32 float32_div(float32, float32, float_status *status);
float32 float32_rem(float32, float32, float_status *status);
float32 float32_muladd(float32, float32, float32, int, float_status *status);
+float32 float32_muladd_scalbn(float32, float32, float32,
+ int, int, float_status *status);
float32 float32_sqrt(float32, float_status *status);
float32 float32_exp2(float32, float_status *status);
float32 float32_log2(float32, float_status *status);
@@ -792,6 +796,8 @@ float64 float64_mul(float64, float64, float_status *status);
float64 float64_div(float64, float64, float_status *status);
float64 float64_rem(float64, float64, float_status *status);
float64 float64_muladd(float64, float64, float64, int, float_status *status);
+float64 float64_muladd_scalbn(float64, float64, float64,
+ int, int, float_status *status);
float64 float64_sqrt(float64, float_status *status);
float64 float64_log2(float64, float_status *status);
FloatRelation float64_compare(float64, float64, float_status *status);
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 8de8d5f342..b5936cc0f8 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -789,15 +789,15 @@ static FloatParts128 *parts128_mul(FloatParts128 *a,
FloatParts128 *b,
#define parts_mul(A, B, S) \
PARTS_GENERIC_64_128(mul, A)(A, B, S)
-static FloatParts64 *parts64_muladd(FloatParts64 *a, FloatParts64 *b,
- FloatParts64 *c, int flags,
- float_status *s);
-static FloatParts128 *parts128_muladd(FloatParts128 *a, FloatParts128 *b,
- FloatParts128 *c, int flags,
- float_status *s);
+static FloatParts64 *parts64_muladd_scalbn(FloatParts64 *a, FloatParts64 *b,
+ FloatParts64 *c, int scale,
+ int flags, float_status *s);
+static FloatParts128 *parts128_muladd_scalbn(FloatParts128 *a, FloatParts128
*b,
+ FloatParts128 *c, int scale,
+ int flags, float_status *s);
-#define parts_muladd(A, B, C, Z, S) \
- PARTS_GENERIC_64_128(muladd, A)(A, B, C, Z, S)
+#define parts_muladd_scalbn(A, B, C, Z, Y, S) \
+ PARTS_GENERIC_64_128(muladd_scalbn, A)(A, B, C, Z, Y, S)
static FloatParts64 *parts64_div(FloatParts64 *a, FloatParts64 *b,
float_status *s);
@@ -2212,43 +2212,50 @@ floatx80_mul(floatx80 a, floatx80 b, float_status
*status)
* Fused multiply-add
*/
-float16 QEMU_FLATTEN float16_muladd(float16 a, float16 b, float16 c,
- int flags, float_status *status)
+float16 QEMU_FLATTEN
+float16_muladd_scalbn(float16 a, float16 b, float16 c,
+ int scale, int flags, float_status *status)
{
FloatParts64 pa, pb, pc, *pr;
float16_unpack_canonical(&pa, a, status);
float16_unpack_canonical(&pb, b, status);
float16_unpack_canonical(&pc, c, status);
- pr = parts_muladd(&pa, &pb, &pc, flags, status);
+ pr = parts_muladd_scalbn(&pa, &pb, &pc, scale, flags, status);
return float16_round_pack_canonical(pr, status);
}
-static float32 QEMU_SOFTFLOAT_ATTR
-soft_f32_muladd(float32 a, float32 b, float32 c, int flags,
- float_status *status)
+float16 float16_muladd(float16 a, float16 b, float16 c,
+ int flags, float_status *status)
+{
+ return float16_muladd_scalbn(a, b, c, 0, flags, status);
+}
+
+float32 QEMU_SOFTFLOAT_ATTR
+float32_muladd_scalbn(float32 a, float32 b, float32 c,
+ int scale, int flags, float_status *status)
{
FloatParts64 pa, pb, pc, *pr;
float32_unpack_canonical(&pa, a, status);
float32_unpack_canonical(&pb, b, status);
float32_unpack_canonical(&pc, c, status);
- pr = parts_muladd(&pa, &pb, &pc, flags, status);
+ pr = parts_muladd_scalbn(&pa, &pb, &pc, scale, flags, status);
return float32_round_pack_canonical(pr, status);
}
-static float64 QEMU_SOFTFLOAT_ATTR
-soft_f64_muladd(float64 a, float64 b, float64 c, int flags,
- float_status *status)
+float64 QEMU_SOFTFLOAT_ATTR
+float64_muladd_scalbn(float64 a, float64 b, float64 c,
+ int scale, int flags, float_status *status)
{
FloatParts64 pa, pb, pc, *pr;
float64_unpack_canonical(&pa, a, status);
float64_unpack_canonical(&pb, b, status);
float64_unpack_canonical(&pc, c, status);
- pr = parts_muladd(&pa, &pb, &pc, flags, status);
+ pr = parts_muladd_scalbn(&pa, &pb, &pc, scale, flags, status);
return float64_round_pack_canonical(pr, status);
}
@@ -2323,7 +2330,7 @@ float32_muladd(float32 xa, float32 xb, float32 xc, int
flags, float_status *s)
return ur.s;
soft:
- return soft_f32_muladd(ua.s, ub.s, uc.s, flags, s);
+ return float32_muladd_scalbn(ua.s, ub.s, uc.s, 0, flags, s);
}
float64 QEMU_FLATTEN
@@ -2394,7 +2401,7 @@ float64_muladd(float64 xa, float64 xb, float64 xc, int
flags, float_status *s)
return ur.s;
soft:
- return soft_f64_muladd(ua.s, ub.s, uc.s, flags, s);
+ return float64_muladd_scalbn(ua.s, ub.s, uc.s, 0, flags, s);
}
float64 float64r32_muladd(float64 a, float64 b, float64 c,
@@ -2405,7 +2412,7 @@ float64 float64r32_muladd(float64 a, float64 b, float64 c,
float64_unpack_canonical(&pa, a, status);
float64_unpack_canonical(&pb, b, status);
float64_unpack_canonical(&pc, c, status);
- pr = parts_muladd(&pa, &pb, &pc, flags, status);
+ pr = parts_muladd_scalbn(&pa, &pb, &pc, 0, flags, status);
return float64r32_round_pack_canonical(pr, status);
}
@@ -2418,7 +2425,7 @@ bfloat16 QEMU_FLATTEN bfloat16_muladd(bfloat16 a,
bfloat16 b, bfloat16 c,
bfloat16_unpack_canonical(&pa, a, status);
bfloat16_unpack_canonical(&pb, b, status);
bfloat16_unpack_canonical(&pc, c, status);
- pr = parts_muladd(&pa, &pb, &pc, flags, status);
+ pr = parts_muladd_scalbn(&pa, &pb, &pc, 0, flags, status);
return bfloat16_round_pack_canonical(pr, status);
}
@@ -2431,7 +2438,7 @@ float128 QEMU_FLATTEN float128_muladd(float128 a,
float128 b, float128 c,
float128_unpack_canonical(&pa, a, status);
float128_unpack_canonical(&pb, b, status);
float128_unpack_canonical(&pc, c, status);
- pr = parts_muladd(&pa, &pb, &pc, flags, status);
+ pr = parts_muladd_scalbn(&pa, &pb, &pc, 0, flags, status);
return float128_round_pack_canonical(pr, status);
}
@@ -5249,8 +5256,9 @@ float32 float32_exp2(float32 a, float_status *status)
float64_unpack_canonical(&rp, float64_one, status);
for (i = 0 ; i < 15 ; i++) {
+
float64_unpack_canonical(&tp, float32_exp2_coefficients[i], status);
- rp = *parts_muladd(&tp, &xnp, &rp, 0, status);
+ rp = *parts_muladd_scalbn(&tp, &xnp, &rp, 0, 0, status);
xnp = *parts_mul(&xnp, &xp, status);
}
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
index ba8de7be76..4a62d6ca24 100644
--- a/fpu/softfloat-parts.c.inc
+++ b/fpu/softfloat-parts.c.inc
@@ -562,8 +562,9 @@ static FloatPartsN *partsN(mul)(FloatPartsN *a, FloatPartsN
*b,
* Requires A and C extracted into a double-sized structure to provide the
* extra space for the widening multiply.
*/
-static FloatPartsN *partsN(muladd)(FloatPartsN *a, FloatPartsN *b,
- FloatPartsN *c, int flags, float_status *s)
+static FloatPartsN *partsN(muladd_scalbn)(FloatPartsN *a, FloatPartsN *b,
+ FloatPartsN *c, int scale,
+ int flags, float_status *s)
{
int ab_mask, abc_mask;
FloatPartsW p_widen, c_widen;
@@ -652,9 +653,11 @@ static FloatPartsN *partsN(muladd)(FloatPartsN *a,
FloatPartsN *b,
a->exp = p_widen.exp;
return_normal:
+ /* TODO: Replace all use of float_muladd_halve_result with scale. */
if (flags & float_muladd_halve_result) {
a->exp -= 1;
}
+ a->exp += scale;
finish_sign:
if (flags & float_muladd_negate_result) {
a->sign ^= 1;
--
2.43.0
- [PULL 22/72] tcg/optimize: Use finish_folding in fold_extract2, (continued)
- [PULL 22/72] tcg/optimize: Use finish_folding in fold_extract2, Richard Henderson, 2024/12/24
- [PULL 28/72] tcg/optimize: Use fold_masks_z in fold_neg_no_const, Richard Henderson, 2024/12/24
- [PULL 27/72] tcg/optimize: Use fold_masks_s in fold_nand, Richard Henderson, 2024/12/24
- [PULL 36/72] tcg/optimize: Distinguish simplification in fold_setcond_zmask, Richard Henderson, 2024/12/24
- [PULL 37/72] tcg/optimize: Use fold_masks_z in fold_setcond, Richard Henderson, 2024/12/24
- [PULL 40/72] tcg/optimize: Use finish_folding in fold_cmp_vec, Richard Henderson, 2024/12/24
- [PULL 41/72] tcg/optimize: Use finish_folding in fold_cmpsel_vec, Richard Henderson, 2024/12/24
- [PULL 45/72] tcg/optimize: Use finish_folding in fold_sub, fold_sub_vec, Richard Henderson, 2024/12/24
- [PULL 43/72] tcg/optimize: Use fold_masks_zs, fold_masks_s in fold_shift, Richard Henderson, 2024/12/24
- [PULL 54/72] tcg/optimize: Move fold_cmp_vec, fold_cmpsel_vec into alphabetic sort, Richard Henderson, 2024/12/24
- [PULL 55/72] softfloat: Add float{16,32,64}_muladd_scalbn,
Richard Henderson <=
- [PULL 57/72] target/sparc: Use float*_muladd_scalbn, Richard Henderson, 2024/12/24
- [PULL 59/72] softfloat: Add float_round_nearest_even_max, Richard Henderson, 2024/12/24
- [PULL 48/72] tcg/optimize: Use fold_masks_zs in fold_xor, Richard Henderson, 2024/12/24
- [PULL 50/72] tcg/optimize: Use finish_folding as default in tcg_optimize, Richard Henderson, 2024/12/24
- [PULL 42/72] tcg/optimize: Use fold_masks_zs in fold_sextract, Richard Henderson, 2024/12/24
- [PULL 46/72] tcg/optimize: Use fold_masks_zs in fold_tcg_ld, Richard Henderson, 2024/12/24
- [PULL 47/72] tcg/optimize: Use finish_folding in fold_tcg_ld_memcopy, Richard Henderson, 2024/12/24
- [PULL 49/72] tcg/optimize: Use finish_folding in fold_bitsel_vec, Richard Henderson, 2024/12/24
- [PULL 53/72] tcg/optimize: Move fold_bitsel_vec into alphabetic sort, Richard Henderson, 2024/12/24
- [PULL 58/72] softfloat: Remove float_muladd_halve_result, Richard Henderson, 2024/12/24