@samitouri / QOSamiQemu / commits / e007622768

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>

Richard Henderson committed Apr 26, 2026 at 13:04 UTC e0076227680a9764e6d92835f20c1798f644200e
3 files changed +38 -36
fpu/softfloat-parts.c.inc
+16 -19
@@ -613,55 +613,52 @@ static FloatPartsN *partsN(addsub)(FloatPartsN *a, FloatPartsN *b,
613 * `b'. The operation is performed according to the IEC/IEEE Standard
614 * for Binary Floating-Point Arithmetic.
615 */
616 -static FloatPartsN *partsN(mul)(FloatPartsN *a, FloatPartsN *b,
617 - float_status *s)
616 +FloatPartsN partsN(mul)(const FloatPartsN *a, const FloatPartsN *b,
617 + float_status *s)
618 {
619 int ab_mask = float_cmask(a->cls) | float_cmask(b->cls);
620 bool sign = a->sign ^ b->sign;
621
622 if (likely(cmask_is_only_normals(ab_mask))) {
623 FloatPartsW tmp;
624 + FloatPartsN r = {
625 + .cls = float_class_normal,
626 + .sign = sign,
627 + .exp = a->exp + b->exp + 1,
628 + };
629
630 record_denormals_used(ab_mask, s);
631
632 fracN(mulw)(&tmp, a, b);
628 - fracN(truncjam)(a, &tmp);
633 + fracN(truncjam)(&r, &tmp);
634
630 - a->exp += b->exp + 1;
631 - if (!(a->frac_hi & DECOMPOSED_IMPLICIT_BIT)) {
632 - fracN(add)(a, a, a);
633 - a->exp -= 1;
635 + if (!(r.frac_hi & DECOMPOSED_IMPLICIT_BIT)) {
636 + fracN(add)(&r, &r, &r);
637 + r.exp -= 1;
638 }
639
636 - a->sign = sign;
637 - return a;
640 + return r;
641 }
642
643 /* Inf * Zero == NaN */
644 if (unlikely(ab_mask == float_cmask_infzero)) {
645 float_raise(float_flag_invalid | float_flag_invalid_imz, s);
643 - *a = partsN(default_nan)(s);
644 - return a;
646 + return partsN(default_nan)(s);
647 }
648
649 if (unlikely(ab_mask & float_cmask_anynan)) {
648 - *a = partsN(pick_nan)(a, b, s);
649 - return a;
650 + return partsN(pick_nan)(a, b, s);
651 }
652
653 /* Multiply by 0 or Inf */
654 record_denormals_used(ab_mask, s);
655
656 if (ab_mask & float_cmask_inf) {
656 - a->cls = float_class_inf;
657 - a->sign = sign;
658 - return a;
657 + return (FloatPartsN){ .cls = float_class_inf, .sign = sign };
658 }
659
660 g_assert(ab_mask & float_cmask_zero);
662 - a->cls = float_class_zero;
663 - a->sign = sign;
664 - return a;
661 + return (FloatPartsN){ .cls = float_class_zero, .sign = sign };
662 }
663
664 /*
fpu/softfloat.c
+17 -17
@@ -1804,9 +1804,9 @@ float16 QEMU_FLATTEN float16_mul(float16 a, float16 b, float_status *status)
1804 {
1805 FloatParts64 pa = float16_unpack_canonical(a, status);
1806 FloatParts64 pb = float16_unpack_canonical(b, status);
1807 - FloatParts64 *pr = parts64_mul(&pa, &pb, status);
1807 + FloatParts64 pr = parts64_mul(&pa, &pb, status);
1808
1809 - return float16_round_pack_canonical(pr, status);
1809 + return float16_round_pack_canonical(&pr, status);
1810 }
1811
1812 static float32 QEMU_SOFTFLOAT_ATTR
@@ -1814,9 +1814,9 @@ soft_f32_mul(float32 a, float32 b, float_status *status)
1814 {
1815 FloatParts64 pa = float32_unpack_canonical(a, status);
1816 FloatParts64 pb = float32_unpack_canonical(b, status);
1817 - FloatParts64 *pr = parts64_mul(&pa, &pb, status);
1817 + FloatParts64 pr = parts64_mul(&pa, &pb, status);
1818
1819 - return float32_round_pack_canonical(pr, status);
1819 + return float32_round_pack_canonical(&pr, status);
1820 }
1821
1822 static float64 QEMU_SOFTFLOAT_ATTR
@@ -1824,9 +1824,9 @@ soft_f64_mul(float64 a, float64 b, float_status *status)
1824 {
1825 FloatParts64 pa = float64_unpack_canonical(a, status);
1826 FloatParts64 pb = float64_unpack_canonical(b, status);
1827 - FloatParts64 *pr = parts64_mul(&pa, &pb, status);
1827 + FloatParts64 pr = parts64_mul(&pa, &pb, status);
1828
1829 - return float64_round_pack_canonical(pr, status);
1829 + return float64_round_pack_canonical(&pr, status);
1830 }
1831
1832 static float hard_f32_mul(float a, float b)
@@ -1857,9 +1857,9 @@ float64 float64r32_mul(float64 a, float64 b, float_status *status)
1857 {
1858 FloatParts64 pa = float64_unpack_canonical(a, status);
1859 FloatParts64 pb = float64_unpack_canonical(b, status);
1860 - FloatParts64 *pr = parts64_mul(&pa, &pb, status);
1860 + FloatParts64 pr = parts64_mul(&pa, &pb, status);
1861
1862 - return float64r32_round_pack_canonical(pr, status);
1862 + return float64r32_round_pack_canonical(&pr, status);
1863 }
1864
1865 bfloat16 QEMU_FLATTEN
@@ -1867,9 +1867,9 @@ bfloat16_mul(bfloat16 a, bfloat16 b, float_status *status)
1867 {
1868 FloatParts64 pa = bfloat16_unpack_canonical(a, status);
1869 FloatParts64 pb = bfloat16_unpack_canonical(b, status);
1870 - FloatParts64 *pr = parts64_mul(&pa, &pb, status);
1870 + FloatParts64 pr = parts64_mul(&pa, &pb, status);
1871
1872 - return bfloat16_round_pack_canonical(pr, status);
1872 + return bfloat16_round_pack_canonical(&pr, status);
1873 }
1874
1875 float128 QEMU_FLATTEN
@@ -1877,23 +1877,23 @@ float128_mul(float128 a, float128 b, float_status *status)
1877 {
1878 FloatParts128 pa = float128_unpack_canonical(a, status);
1879 FloatParts128 pb = float128_unpack_canonical(b, status);
1880 - FloatParts128 *pr = parts128_mul(&pa, &pb, status);
1880 + FloatParts128 pr = parts128_mul(&pa, &pb, status);
1881
1882 - return float128_round_pack_canonical(pr, status);
1882 + return float128_round_pack_canonical(&pr, status);
1883 }
1884
1885 floatx80 QEMU_FLATTEN
1886 floatx80_mul(floatx80 a, floatx80 b, float_status *status)
1887 {
1888 - FloatParts128 pa, pb, *pr;
1888 + FloatParts128 pa, pb;
1889
1890 if (!floatx80_unpack_canonical(&pa, a, status) ||
1891 !floatx80_unpack_canonical(&pb, b, status)) {
1892 return floatx80_default_nan(status);
1893 }
1894
1895 - pr = parts128_mul(&pa, &pb, status);
1896 - return floatx80_round_pack_canonical(pr, status);
1895 + pa = parts128_mul(&pa, &pb, status);
1896 + return floatx80_round_pack_canonical(&pa, status);
1897 }
1898
1899 /*
@@ -5121,14 +5121,14 @@ float32 float32_exp2(float32 a, float_status *status)
5121 float_raise(float_flag_inexact, status);
5122
5123 tp = float64_unpack_canonical(float64_ln2, status);
5124 - xp = *parts64_mul(&xp, &tp, status);
5124 + xp = parts64_mul(&xp, &tp, status);
5125 xnp = xp;
5126
5127 rp = float64_unpack_canonical(float64_one, status);
5128 for (int i = 0; i < 15; i++) {
5129 tp = float64_unpack_canonical(float32_exp2_coefficients[i], status);
5130 rp = *parts64_muladd(&tp, &xnp, &rp, 0, status);
5131 - xnp = *parts64_mul(&xnp, &xp, status);
5131 + xnp = parts64_mul(&xnp, &xp, status);
5132 }
5133
5134 return float32_round_pack_canonical(&rp, status);
include/fpu/softfloat-parts.h
+5
@@ -192,6 +192,11 @@ FloatParts64 parts64_div(const FloatParts64 *a, const FloatParts64 *b,
192 FloatParts128 parts128_div(const FloatParts128 *a, const FloatParts128 *b,
193 float_status *s);
194
195 +FloatParts64 parts64_mul(const FloatParts64 *a, const FloatParts64 *b,
196 + float_status *s);
197 +FloatParts128 parts128_mul(const FloatParts128 *a, const FloatParts128 *b,
198 + float_status *s);
199 +
200 FloatParts64 parts64_round_to_int(const FloatParts64 *a,
201 FloatRoundMode rmode,
202 int scale, float_status *s,