fpu: Return struct from parts{64,128}_muladd
At the same time, export. Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Richard Henderson committed
Apr 26, 2026 at 12:18 UTC
21da8ac79d8d4576de6f3422e0b46f399bf694d7
3 files changed
+69
-61
fpu/softfloat-parts.c.inc
+19
-19
@@ -677,9 +677,8 @@ FloatPartsN partsN(mul)(const FloatPartsN *a, const FloatPartsN *b,
677
* Requires A and C extracted into a double-sized structure to provide the
678
* extra space for the widening multiply.
679
*/
680
-static FloatPartsN *partsN(muladd)(FloatPartsN *a, FloatPartsN *b,
681
- FloatPartsN *c,
682
- int flags, float_status *s)
680
+FloatPartsN partsN(muladd)(const FloatPartsN *a, const FloatPartsN *b,
681
+ const FloatPartsN *c, int flags, float_status *s)
682
{
683
int ab_mask = float_cmask(a->cls) | float_cmask(b->cls);
684
int c_mask = float_cmask(c->cls);
@@ -717,10 +716,13 @@ static FloatPartsN *partsN(muladd)(FloatPartsN *a, FloatPartsN *b,
716
}
717
718
/* Narrow with sticky bit, for proper rounding later. */
720
- fracN(truncjam)(a, &p_widen);
721
- a->sign = p_widen.sign;
722
- a->exp = p_widen.exp;
723
- return a;
719
+ FloatPartsN r = {
720
+ .sign = p_widen.sign,
721
+ .exp = p_widen.exp,
722
+ .cls = float_class_normal,
723
+ };
724
+ fracN(truncjam)(&r, &p_widen);
725
+ return r;
726
}
727
728
/*
@@ -730,8 +732,7 @@ static FloatPartsN *partsN(muladd)(FloatPartsN *a, FloatPartsN *b,
732
* off to the target-specific pick-a-NaN routine.
733
*/
734
if (unlikely(abc_mask & float_cmask_anynan)) {
733
- *a = partsN(pick_nan_muladd)(a, b, c, s, ab_mask, abc_mask);
734
- return a;
735
+ return partsN(pick_nan_muladd)(a, b, c, s, ab_mask, abc_mask);
736
}
737
738
if (unlikely(ab_mask == float_cmask_infzero)) {
@@ -748,9 +749,7 @@ static FloatPartsN *partsN(muladd)(FloatPartsN *a, FloatPartsN *b,
749
}
750
/* Inf + C == Inf */
751
record_denormals_used(abc_mask, s);
751
- a->sign = p_sign;
752
- a->cls = float_class_inf;
753
- return a;
752
+ return (FloatPartsN){ .sign = p_sign, .cls = float_class_inf };
753
}
754
record_denormals_used(abc_mask, s);
755
@@ -766,19 +765,20 @@ static FloatPartsN *partsN(muladd)(FloatPartsN *a, FloatPartsN *b,
765
if (!(c_mask & float_cmask_zero)
766
|| p_sign == c_sign
767
|| (flags & float_muladd_suppress_add_product_zero)) {
769
- c->sign = c_sign;
770
- return c;
768
+ FloatPartsN r = *c;
769
+ r.sign = c_sign;
770
+ return r;
771
}
772
773
return_sub_zero:
774
/* 0 - 0 == -0 for round_down, +0 otherwise. */
775
- a->sign = s->float_rounding_mode == float_round_down;
776
- a->cls = float_class_zero;
777
- return a;
775
+ return (FloatPartsN){
776
+ .sign = s->float_rounding_mode == float_round_down,
777
+ .cls = float_class_zero
778
+ };
779
780
d_nan:
780
- *a = partsN(default_nan)(s);
781
- return a;
781
+ return partsN(default_nan)(s);
782
}
783
784
/*
fpu/softfloat.c
+41
-42
@@ -1906,18 +1906,18 @@ float16 float16_muladd_scalbn(float16 a, float16 b, float16 c,
1906
FloatParts64 pa = float16_unpack_canonical(a, status);
1907
FloatParts64 pb = float16_unpack_canonical(b, status);
1908
FloatParts64 pc = float16_unpack_canonical(c, status);
1909
- FloatParts64 *pr = parts64_muladd(&pa, &pb, &pc, flags, status);
1909
+ FloatParts64 pr = parts64_muladd(&pa, &pb, &pc, flags, status);
1910
1911
/* Before rounding, scale. */
1912
if (scale) {
1913
- *pr = parts64_scalbn(pr, scale, status);
1913
+ pr = parts64_scalbn(&pr, scale, status);
1914
}
1915
- parts64_uncanon(pr, status, &float16_params, false);
1915
+ parts64_uncanon(&pr, status, &float16_params, false);
1916
/* After rounding, apply negate result, especially for -0.0. */
1917
- if ((flags & float_muladd_negate_result) && !is_nan(pr->cls)) {
1918
- pr->sign ^= 1;
1917
+ if ((flags & float_muladd_negate_result) && !is_nan(pr.cls)) {
1918
+ pr.sign ^= 1;
1919
}
1920
- return pack_raw64(pr, &float16_params);
1920
+ return pack_raw64(&pr, &float16_params);
1921
}
1922
1923
float16 float16_muladd(float16 a, float16 b, float16 c,
@@ -1933,18 +1933,18 @@ float32_muladd_scalbn(float32 a, float32 b, float32 c,
1933
FloatParts64 pa = float32_unpack_canonical(a, status);
1934
FloatParts64 pb = float32_unpack_canonical(b, status);
1935
FloatParts64 pc = float32_unpack_canonical(c, status);
1936
- FloatParts64 *pr = parts64_muladd(&pa, &pb, &pc, flags, status);
1936
+ FloatParts64 pr = parts64_muladd(&pa, &pb, &pc, flags, status);
1937
1938
/* Before rounding, scale. */
1939
if (scale) {
1940
- *pr = parts64_scalbn(pr, scale, status);
1940
+ pr = parts64_scalbn(&pr, scale, status);
1941
}
1942
- parts64_uncanon(pr, status, &float32_params, false);
1942
+ parts64_uncanon(&pr, status, &float32_params, false);
1943
/* After rounding, apply negate result, especially for -0.0. */
1944
- if ((flags & float_muladd_negate_result) && !is_nan(pr->cls)) {
1945
- pr->sign ^= 1;
1944
+ if ((flags & float_muladd_negate_result) && !is_nan(pr.cls)) {
1945
+ pr.sign ^= 1;
1946
}
1947
- return pack_raw64(pr, &float32_params);
1947
+ return pack_raw64(&pr, &float32_params);
1948
}
1949
1950
float64 QEMU_SOFTFLOAT_ATTR
@@ -1954,18 +1954,18 @@ float64_muladd_scalbn(float64 a, float64 b, float64 c,
1954
FloatParts64 pa = float64_unpack_canonical(a, status);
1955
FloatParts64 pb = float64_unpack_canonical(b, status);
1956
FloatParts64 pc = float64_unpack_canonical(c, status);
1957
- FloatParts64 *pr = parts64_muladd(&pa, &pb, &pc, flags, status);
1957
+ FloatParts64 pr = parts64_muladd(&pa, &pb, &pc, flags, status);
1958
1959
/* Before rounding, scale. */
1960
if (scale) {
1961
- *pr = parts64_scalbn(pr, scale, status);
1961
+ pr = parts64_scalbn(&pr, scale, status);
1962
}
1963
- parts64_uncanon(pr, status, &float64_params, false);
1963
+ parts64_uncanon(&pr, status, &float64_params, false);
1964
/* After rounding, apply negate result, especially for -0.0. */
1965
- if ((flags & float_muladd_negate_result) && !is_nan(pr->cls)) {
1966
- pr->sign ^= 1;
1965
+ if ((flags & float_muladd_negate_result) && !is_nan(pr.cls)) {
1966
+ pr.sign ^= 1;
1967
}
1968
- return pack_raw64(pr, &float64_params);
1968
+ return pack_raw64(&pr, &float64_params);
1969
}
1970
1971
static bool force_soft_fma;
@@ -2115,14 +2115,14 @@ float64 float64r32_muladd(float64 a, float64 b, float64 c,
2115
FloatParts64 pa = float64_unpack_canonical(a, status);
2116
FloatParts64 pb = float64_unpack_canonical(b, status);
2117
FloatParts64 pc = float64_unpack_canonical(c, status);
2118
- FloatParts64 *pr = parts64_muladd(&pa, &pb, &pc, flags, status);
2118
+ FloatParts64 pr = parts64_muladd(&pa, &pb, &pc, flags, status);
2119
2120
/* Round before applying negate result. */
2121
- parts64_uncanon(pr, status, &float32_params, false);
2122
- if ((flags & float_muladd_negate_result) && !is_nan(pr->cls)) {
2123
- pr->sign ^= 1;
2121
+ parts64_uncanon(&pr, status, &float32_params, false);
2122
+ if ((flags & float_muladd_negate_result) && !is_nan(pr.cls)) {
2123
+ pr.sign ^= 1;
2124
}
2125
- return float64r32_pack_raw(pr);
2125
+ return float64r32_pack_raw(&pr);
2126
}
2127
2128
bfloat16 bfloat16_muladd(bfloat16 a, bfloat16 b, bfloat16 c,
@@ -2131,14 +2131,14 @@ bfloat16 bfloat16_muladd(bfloat16 a, bfloat16 b, bfloat16 c,
2131
FloatParts64 pa = bfloat16_unpack_canonical(a, status);
2132
FloatParts64 pb = bfloat16_unpack_canonical(b, status);
2133
FloatParts64 pc = bfloat16_unpack_canonical(c, status);
2134
- FloatParts64 *pr = parts64_muladd(&pa, &pb, &pc, flags, status);
2134
+ FloatParts64 pr = parts64_muladd(&pa, &pb, &pc, flags, status);
2135
2136
/* Round before applying negate result. */
2137
- parts64_uncanon(pr, status, &bfloat16_params, false);
2138
- if ((flags & float_muladd_negate_result) && !is_nan(pr->cls)) {
2139
- pr->sign ^= 1;
2137
+ parts64_uncanon(&pr, status, &bfloat16_params, false);
2138
+ if ((flags & float_muladd_negate_result) && !is_nan(pr.cls)) {
2139
+ pr.sign ^= 1;
2140
}
2141
- return pack_raw64(pr, &bfloat16_params);
2141
+ return pack_raw64(&pr, &bfloat16_params);
2142
}
2143
2144
float128 float128_muladd(float128 a, float128 b, float128 c,
@@ -2147,14 +2147,14 @@ float128 float128_muladd(float128 a, float128 b, float128 c,
2147
FloatParts128 pa = float128_unpack_canonical(a, status);
2148
FloatParts128 pb = float128_unpack_canonical(b, status);
2149
FloatParts128 pc = float128_unpack_canonical(c, status);
2150
- FloatParts128 *pr = parts128_muladd(&pa, &pb, &pc, flags, status);
2150
+ FloatParts128 pr = parts128_muladd(&pa, &pb, &pc, flags, status);
2151
2152
/* Round before applying negate result. */
2153
- parts128_uncanon(pr, status, &float128_params, false);
2154
- if ((flags & float_muladd_negate_result) && !is_nan(pr->cls)) {
2155
- pr->sign ^= 1;
2153
+ parts128_uncanon(&pr, status, &float128_params, false);
2154
+ if ((flags & float_muladd_negate_result) && !is_nan(pr.cls)) {
2155
+ pr.sign ^= 1;
2156
}
2157
- return float128_pack_raw(pr);
2157
+ return float128_pack_raw(&pr);
2158
}
2159
2160
/*
@@ -5126,7 +5126,7 @@ float32 float32_exp2(float32 a, float_status *status)
5126
rp = float64_unpack_canonical(float64_one, status);
5127
for (int i = 0; i < 15; i++) {
5128
tp = float64_unpack_canonical(float32_exp2_coefficients[i], status);
5129
- rp = *parts64_muladd(&tp, &xnp, &rp, 0, status);
5129
+ rp = parts64_muladd(&tp, &xnp, &rp, 0, status);
5130
xnp = parts64_mul(&xnp, &xp, status);
5131
}
5132
@@ -5175,7 +5175,7 @@ static void parts_s390_divide_to_integer(FloatParts64 *a, FloatParts64 *b,
5175
n->sign = a->sign ^ b->sign;
5176
*cc = 0;
5177
} else {
5178
- FloatParts64 *q, q_buf, *r_precise, r_precise_buf;
5178
+ FloatParts64 *q, q_buf, r_precise;
5179
int float_exception_flags = 0;
5180
bool is_q_smallish;
5181
uint32_t r_flags;
@@ -5205,12 +5205,11 @@ static void parts_s390_divide_to_integer(FloatParts64 *a, FloatParts64 *b,
5205
0, fmt->frac_size);
5206
5207
/* Compute precise remainder */
5208
- r_precise_buf = *b;
5209
- r_precise = parts64_muladd(&r_precise_buf, n, a,
5208
+ r_precise = parts64_muladd(b, n, a,
5209
float_muladd_negate_product, status);
5210
5211
/* Round remainder to the target format */
5213
- *r = *r_precise;
5212
+ *r = r_precise;
5213
status->float_exception_flags = 0;
5214
*r = parts64_round_to_fmt(r, status, fmt);
5215
r_flags = status->float_exception_flags;
@@ -5234,17 +5233,17 @@ static void parts_s390_divide_to_integer(FloatParts64 *a, FloatParts64 *b,
5233
* toward zero) or incremented.
5234
*/
5235
saved_r_sign = r->sign;
5237
- saved_r_precise_sign = r_precise->sign;
5236
+ saved_r_precise_sign = r_precise.sign;
5237
r->sign = false;
5239
- r_precise->sign = false;
5240
- if (parts64_compare(r, r_precise, status, true) <
5238
+ r_precise.sign = false;
5239
+ if (parts64_compare(r, &r_precise, status, true) <
5240
float_relation_equal) {
5241
*dxc = 0x8;
5242
} else {
5243
*dxc = 0xc;
5244
}
5245
r->sign = saved_r_sign;
5247
- r_precise->sign = saved_r_precise_sign;
5246
+ r_precise.sign = saved_r_precise_sign;
5247
}
5248
}
5249
}
include/fpu/softfloat-parts.h
+9
@@ -202,6 +202,15 @@ FloatParts64 parts64_mul(const FloatParts64 *a, const FloatParts64 *b,
202
FloatParts128 parts128_mul(const FloatParts128 *a, const FloatParts128 *b,
203
float_status *s);
204
205
+FloatParts64 parts64_muladd(const FloatParts64 *a,
206
+ const FloatParts64 *b,
207
+ const FloatParts64 *c,
208
+ int flags, float_status *s);
209
+FloatParts128 parts128_muladd(const FloatParts128 *a,
210
+ const FloatParts128 *b,
211
+ const FloatParts128 *c,
212
+ int flags, float_status *s);
213
+
214
FloatParts64 parts64_round_to_int(const FloatParts64 *a,
215
FloatRoundMode rmode,
216
int scale, float_status *s,