fpu: Return struct from parts{64,128}_mul

At the same time, export.

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson
2026-04-26 13:04:15 +10:00
parent b8b683af59
commit e007622768
3 changed files with 38 additions and 36 deletions

View File

@@ -613,55 +613,52 @@ static FloatPartsN *partsN(addsub)(FloatPartsN *a, FloatPartsN *b,
* `b'. The operation is performed according to the IEC/IEEE Standard
* for Binary Floating-Point Arithmetic.
*/
static FloatPartsN *partsN(mul)(FloatPartsN *a, FloatPartsN *b,
float_status *s)
FloatPartsN partsN(mul)(const FloatPartsN *a, const FloatPartsN *b,
float_status *s)
{
int ab_mask = float_cmask(a->cls) | float_cmask(b->cls);
bool sign = a->sign ^ b->sign;
if (likely(cmask_is_only_normals(ab_mask))) {
FloatPartsW tmp;
FloatPartsN r = {
.cls = float_class_normal,
.sign = sign,
.exp = a->exp + b->exp + 1,
};
record_denormals_used(ab_mask, s);
fracN(mulw)(&tmp, a, b);
fracN(truncjam)(a, &tmp);
fracN(truncjam)(&r, &tmp);
a->exp += b->exp + 1;
if (!(a->frac_hi & DECOMPOSED_IMPLICIT_BIT)) {
fracN(add)(a, a, a);
a->exp -= 1;
if (!(r.frac_hi & DECOMPOSED_IMPLICIT_BIT)) {
fracN(add)(&r, &r, &r);
r.exp -= 1;
}
a->sign = sign;
return a;
return r;
}
/* Inf * Zero == NaN */
if (unlikely(ab_mask == float_cmask_infzero)) {
float_raise(float_flag_invalid | float_flag_invalid_imz, s);
*a = partsN(default_nan)(s);
return a;
return partsN(default_nan)(s);
}
if (unlikely(ab_mask & float_cmask_anynan)) {
*a = partsN(pick_nan)(a, b, s);
return a;
return partsN(pick_nan)(a, b, s);
}
/* Multiply by 0 or Inf */
record_denormals_used(ab_mask, s);
if (ab_mask & float_cmask_inf) {
a->cls = float_class_inf;
a->sign = sign;
return a;
return (FloatPartsN){ .cls = float_class_inf, .sign = sign };
}
g_assert(ab_mask & float_cmask_zero);
a->cls = float_class_zero;
a->sign = sign;
return a;
return (FloatPartsN){ .cls = float_class_zero, .sign = sign };
}
/*

View File

@@ -1804,9 +1804,9 @@ float16 QEMU_FLATTEN float16_mul(float16 a, float16 b, float_status *status)
{
FloatParts64 pa = float16_unpack_canonical(a, status);
FloatParts64 pb = float16_unpack_canonical(b, status);
FloatParts64 *pr = parts64_mul(&pa, &pb, status);
FloatParts64 pr = parts64_mul(&pa, &pb, status);
return float16_round_pack_canonical(pr, status);
return float16_round_pack_canonical(&pr, status);
}
static float32 QEMU_SOFTFLOAT_ATTR
@@ -1814,9 +1814,9 @@ soft_f32_mul(float32 a, float32 b, float_status *status)
{
FloatParts64 pa = float32_unpack_canonical(a, status);
FloatParts64 pb = float32_unpack_canonical(b, status);
FloatParts64 *pr = parts64_mul(&pa, &pb, status);
FloatParts64 pr = parts64_mul(&pa, &pb, status);
return float32_round_pack_canonical(pr, status);
return float32_round_pack_canonical(&pr, status);
}
static float64 QEMU_SOFTFLOAT_ATTR
@@ -1824,9 +1824,9 @@ soft_f64_mul(float64 a, float64 b, float_status *status)
{
FloatParts64 pa = float64_unpack_canonical(a, status);
FloatParts64 pb = float64_unpack_canonical(b, status);
FloatParts64 *pr = parts64_mul(&pa, &pb, status);
FloatParts64 pr = parts64_mul(&pa, &pb, status);
return float64_round_pack_canonical(pr, status);
return float64_round_pack_canonical(&pr, status);
}
static float hard_f32_mul(float a, float b)
@@ -1857,9 +1857,9 @@ float64 float64r32_mul(float64 a, float64 b, float_status *status)
{
FloatParts64 pa = float64_unpack_canonical(a, status);
FloatParts64 pb = float64_unpack_canonical(b, status);
FloatParts64 *pr = parts64_mul(&pa, &pb, status);
FloatParts64 pr = parts64_mul(&pa, &pb, status);
return float64r32_round_pack_canonical(pr, status);
return float64r32_round_pack_canonical(&pr, status);
}
bfloat16 QEMU_FLATTEN
@@ -1867,9 +1867,9 @@ bfloat16_mul(bfloat16 a, bfloat16 b, float_status *status)
{
FloatParts64 pa = bfloat16_unpack_canonical(a, status);
FloatParts64 pb = bfloat16_unpack_canonical(b, status);
FloatParts64 *pr = parts64_mul(&pa, &pb, status);
FloatParts64 pr = parts64_mul(&pa, &pb, status);
return bfloat16_round_pack_canonical(pr, status);
return bfloat16_round_pack_canonical(&pr, status);
}
float128 QEMU_FLATTEN
@@ -1877,23 +1877,23 @@ float128_mul(float128 a, float128 b, float_status *status)
{
FloatParts128 pa = float128_unpack_canonical(a, status);
FloatParts128 pb = float128_unpack_canonical(b, status);
FloatParts128 *pr = parts128_mul(&pa, &pb, status);
FloatParts128 pr = parts128_mul(&pa, &pb, status);
return float128_round_pack_canonical(pr, status);
return float128_round_pack_canonical(&pr, status);
}
floatx80 QEMU_FLATTEN
floatx80_mul(floatx80 a, floatx80 b, float_status *status)
{
FloatParts128 pa, pb, *pr;
FloatParts128 pa, pb;
if (!floatx80_unpack_canonical(&pa, a, status) ||
!floatx80_unpack_canonical(&pb, b, status)) {
return floatx80_default_nan(status);
}
pr = parts128_mul(&pa, &pb, status);
return floatx80_round_pack_canonical(pr, status);
pa = parts128_mul(&pa, &pb, status);
return floatx80_round_pack_canonical(&pa, status);
}
/*
@@ -5121,14 +5121,14 @@ float32 float32_exp2(float32 a, float_status *status)
float_raise(float_flag_inexact, status);
tp = float64_unpack_canonical(float64_ln2, status);
xp = *parts64_mul(&xp, &tp, status);
xp = parts64_mul(&xp, &tp, status);
xnp = xp;
rp = float64_unpack_canonical(float64_one, status);
for (int i = 0; i < 15; i++) {
tp = float64_unpack_canonical(float32_exp2_coefficients[i], status);
rp = *parts64_muladd(&tp, &xnp, &rp, 0, status);
xnp = *parts64_mul(&xnp, &xp, status);
xnp = parts64_mul(&xnp, &xp, status);
}
return float32_round_pack_canonical(&rp, status);

View File

@@ -192,6 +192,11 @@ FloatParts64 parts64_div(const FloatParts64 *a, const FloatParts64 *b,
FloatParts128 parts128_div(const FloatParts128 *a, const FloatParts128 *b,
float_status *s);
FloatParts64 parts64_mul(const FloatParts64 *a, const FloatParts64 *b,
float_status *s);
FloatParts128 parts128_mul(const FloatParts128 *a, const FloatParts128 *b,
float_status *s);
FloatParts64 parts64_round_to_int(const FloatParts64 *a,
FloatRoundMode rmode,
int scale, float_status *s,