@samitouri / QOSamiQemu / commits / 21da8ac79d

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,