Add narrowing multiply functions [committed]

Message ID alpine.DEB.2.20.1805160006030.6025@digraph.polyomino.org.uk
State New
Headers show
Series
  • Add narrowing multiply functions [committed]
Related show

Commit Message

Joseph Myers May 16, 2018, 12:06 a.m.
This patch adds the narrowing multiply functions from TS 18661-1 to
glibc's libm: fmul, fmull, dmull, f32mulf64, f32mulf32x, f32xmulf64
for all configurations; f32mulf64x, f32mulf128, f64mulf64x,
f64mulf128, f32xmulf64x, f32xmulf128, f64xmulf128 for configurations
with _Float64x and _Float128; __nldbl_dmull for ldbl-opt.

The changes are mostly essentially the same as for the narrowing add
functions, so the description of those generally applies to this patch
as well.  f32xmulf64 for i386 cannot use precision control as used for
add and subtract, because that would result in double rounding for
subnormal results, so that uses round-to-odd with long double
intermediate result instead.  The soft-fp support involves adding a
new FP_TRUNC_COOKED since soft-fp multiplication uses cooked inputs
and outputs.

Tested for x86_64, x86, mips64 (all three ABIs, both hard and soft
float) and powerpc, and with build-many-glibcs.py.

(auto-libm-test-out-narrow-mul diffs omitted below.)

2018-05-16  Joseph Myers  <joseph@codesourcery.com>

	* math/Makefile (libm-narrow-fns): Add mul.
	(libm-test-funcs-narrow): Likewise.
	* math/Versions (GLIBC_2.28): Add narrowing multiply functions.
	* math/bits/mathcalls-narrow.h (mul): Use __MATHCALL_NARROW.
	* math/gen-auto-libm-tests.c (test_functions): Add mul.
	* math/math-narrow.h (CHECK_NARROW_MUL): New macro.
	(NARROW_MUL_ROUND_TO_ODD): Likewise.
	(NARROW_MUL_TRIVIAL): Likewise.
	* soft-fp/op-common.h (FP_TRUNC_COOKED): Likewise.
	* sysdeps/ieee754/float128/float128_private.h (__fmull): New
	macro.
	(__dmull): Likewise.
	* sysdeps/ieee754/ldbl-opt/Makefile (libnldbl-calls): Add fmul and
	dmul.
	(CFLAGS-nldbl-dmul.c): New variable.
	(CFLAGS-nldbl-fmul.c): Likewise.
	* sysdeps/ieee754/ldbl-opt/Versions (GLIBC_2.28): Add
	__nldbl_dmull.
	* sysdeps/ieee754/ldbl-opt/nldbl-compat.h (__nldbl_dmull): New
	prototype.
	* manual/arith.texi (Misc FP Arithmetic): Document fmul, fmull,
	dmull, fMmulfN, fMmulfNx, fMxmulfN and fMxmulfNx.
	* math/auto-libm-test-in: Add tests of mul.
	* math/auto-libm-test-out-narrow-mul: New generated file.
	* math/libm-test-narrow-mul.inc: New file.
	* sysdeps/i386/fpu/s_f32xmulf64.c: Likewise.
	* sysdeps/ieee754/dbl-64/s_f32xmulf64.c: Likewise.
	* sysdeps/ieee754/dbl-64/s_fmul.c: Likewise.
	* sysdeps/ieee754/float128/s_f32mulf128.c: Likewise.
	* sysdeps/ieee754/float128/s_f64mulf128.c: Likewise.
	* sysdeps/ieee754/float128/s_f64xmulf128.c: Likewise.
	* sysdeps/ieee754/ldbl-128/s_dmull.c: Likewise.
	* sysdeps/ieee754/ldbl-128/s_f64xmulf128.c: Likewise.
	* sysdeps/ieee754/ldbl-128/s_fmull.c: Likewise.
	* sysdeps/ieee754/ldbl-128ibm/s_dmull.c: Likewise.
	* sysdeps/ieee754/ldbl-128ibm/s_fmull.c: Likewise.
	* sysdeps/ieee754/ldbl-96/s_dmull.c: Likewise.
	* sysdeps/ieee754/ldbl-96/s_fmull.c: Likewise.
	* sysdeps/ieee754/ldbl-opt/nldbl-dmul.c: Likewise.
	* sysdeps/ieee754/ldbl-opt/nldbl-fmul.c: Likewise.
	* sysdeps/ieee754/soft-fp/s_dmull.c: Likewise.
	* sysdeps/ieee754/soft-fp/s_fmul.c: Likewise.
	* sysdeps/ieee754/soft-fp/s_fmull.c: Likewise.
	* sysdeps/powerpc/fpu/libm-test-ulps: Update.
	* sysdeps/mach/hurd/i386/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/aarch64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/alpha/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/arm/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/hppa/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/i386/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/ia64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/m68k/m680x0/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/microblaze/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/mips/mips32/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/mips/mips64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/nios2/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/libm-le.abilist: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/riscv/rv64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/sh/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/x86_64/64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist: Likewise.

Patch

diff --git a/NEWS b/NEWS
index 5155c86..e9ce936 100644
--- a/NEWS
+++ b/NEWS
@@ -18,6 +18,9 @@  Major new features:
   - fsub, fsubl, dsubl and corresponding fMsubfN, fMsubfNx, fMxsubfN and
     fMxsubfNx functions.
 
+  - fmul, fmull, dmull and corresponding fMmulfN, fMmulfNx, fMxmulfN and
+    fMxmulfNx functions.
+
 * Nominative and genitive month names are now supported for the Catalan and
   Czech languages.  The Catalan and Greek languages now support abbreviated
   alternative month names.
diff --git a/manual/arith.texi b/manual/arith.texi
index 116788b..3c5b69b 100644
--- a/manual/arith.texi
+++ b/manual/arith.texi
@@ -2229,6 +2229,25 @@  function without any intermediate rounding to the type of the
 arguments.
 @end deftypefun
 
+@deftypefun float fmul (double @var{x}, double @var{y})
+@deftypefunx float fmull (long double @var{x}, long double @var{y})
+@deftypefunx double dmull (long double @var{x}, long double @var{y})
+@deftypefunx _FloatM fMmulfN (_Float@var{N} @var{x}, _Float@var{N} @var{y})
+@deftypefunx _FloatM fMmulfNx (_Float@var{N}x @var{x}, _Float@var{N}x @var{y})
+@deftypefunx _FloatMx fMxmulfN (_Float@var{N} @var{x}, _Float@var{N} @var{y})
+@deftypefunx _FloatMx fMxmulfNx (_Float@var{N}x @var{x}, _Float@var{N}x @var{y})
+@standards{TS 18661-1:2014, math.h}
+@standardsx{fMmulfN, TS 18661-3:2015, math.h}
+@standardsx{fMmulfNx, TS 18661-3:2015, math.h}
+@standardsx{fMxmulfN, TS 18661-3:2015, math.h}
+@standardsx{fMxmulfNx, TS 18661-3:2015, math.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+These functions, from TS 18661-1:2014 and TS 18661-3:2015, return
+@math{@var{x} * @var{y}}, rounded once to the return type of the
+function without any intermediate rounding to the type of the
+arguments.
+@end deftypefun
+
 @node Complex Numbers
 @section Complex Numbers
 @pindex complex.h
diff --git a/math/Makefile b/math/Makefile
index 7cc0d16..892008f 100644
--- a/math/Makefile
+++ b/math/Makefile
@@ -89,7 +89,7 @@  libm-compat-calls =							\
 	w_lgammaF_r_compat w_lgammaF_compat2 w_expF_compat		\
 	w_lgamma_compatF k_standardF
 
-libm-narrow-fns = add sub
+libm-narrow-fns = add mul sub
 libm-narrow-types-basic = s_fF s_f32xFf64
 libm-narrow-types-ldouble-yes = s_fFl s_dFl
 libm-narrow-types-float128-yes = s_f32Ff128 s_f64Ff128 s_f64xFf128
@@ -284,7 +284,7 @@  libm-test-funcs-noauto = canonicalize ceil cimag conj copysign cproj creal \
 			 scalbln scalbn setpayload setpayloadsig signbit \
 			 significand totalorder totalordermag trunc ufromfp \
 			 ufromfpx
-libm-test-funcs-narrow = add sub
+libm-test-funcs-narrow = add mul sub
 libm-test-funcs-all = $(libm-test-funcs-auto) $(libm-test-funcs-noauto)
 libm-test-c-auto = $(foreach f,$(libm-test-funcs-auto),libm-test-$(f).c)
 libm-test-c-noauto = $(foreach f,$(libm-test-funcs-noauto),libm-test-$(f).c)
diff --git a/math/Versions b/math/Versions
index 87c7ff6..edf0daa 100644
--- a/math/Versions
+++ b/math/Versions
@@ -555,12 +555,17 @@  libm {
     # Functions not involving _Float64x or _Float128, for all configurations.
     fadd; faddl; daddl;
     f32addf32x; f32addf64; f32xaddf64;
+    fmul; fmull; dmull;
+    f32mulf32x; f32mulf64; f32xmulf64;
     fsub; fsubl; dsubl;
     f32subf32x; f32subf64; f32xsubf64;
     # Functions involving _Float64x or _Float128, for some configurations.
     f32addf64x; f32addf128;
     f32xaddf64x; f32xaddf128; f64addf64x; f64addf128;
     f64xaddf128;
+    f32mulf64x; f32mulf128;
+    f32xmulf64x; f32xmulf128; f64mulf64x; f64mulf128;
+    f64xmulf128;
     f32subf64x; f32subf128;
     f32xsubf64x; f32xsubf128; f64subf64x; f64subf128;
     f64xsubf128;
diff --git a/math/auto-libm-test-in b/math/auto-libm-test-in
index bb3c325..d102b99 100644
--- a/math/auto-libm-test-in
+++ b/math/auto-libm-test-in
@@ -6445,6 +6445,54 @@  log2 min
 log2 min_subnorm
 log2 max
 
+mul 0 0
+mul 0 -0
+mul -0 0
+mul -0 -0
+mul max max
+mul max -max
+mul -max max
+mul -max -max
+mul min min
+mul min -min
+mul -min min
+mul -min -min
+mul min_subnorm min_subnorm
+mul min_subnorm -min_subnorm
+mul -min_subnorm min_subnorm
+mul -min_subnorm -min_subnorm
+mul 1 2
+mul 1 -2
+mul -1 2
+mul -1 -2
+mul 100.5 0.75
+mul 100.5 -0.75
+mul -100.5 0.75
+mul -100.5 -0.75
+# Cases where the product of two values in a wider format is very
+# close to half way between two representable values in a narrower
+# format, so that double rounding would sometimes yield the wrong
+# result.  These examples have products of the form
+# (2^a + 1)(2^b + 1)/2^(a+b), where a is the width of the narrower
+# format, b is greater than the width of the wider format and factors
+# have been rearranged between the terms so that both terms do fit
+# within the wider format.
+# a = 24, b = 54
+mul 0x5000005p-24 0xccccccccccccdp-54
+# a = 24, b = 65
+mul 0x3000003p-24 0xaaaaaaaaaaaaaaabp-65
+# a = 24, b = 114
+mul 0x5000005p-24 0xcccccccccccccccccccccccccccdp-114
+# a = 53, b = 65
+mul 0x60000000000003p-53 0xaaaaaaaaaaaaaaabp-65
+# a = 53, b = 114
+mul 0xa0000000000005p-53 0xcccccccccccccccccccccccccccdp-114
+# a = 64, b = 114
+mul 0x50000000000000005p-64 0xcccccccccccccccccccccccccccdp-114
+# Similar, for double rounding to 64 bit of a product of 53-bit values.
+# This product equals 2^64 + 2^11 + 1.
+mul 97689974585 188829449
+
 pow 0 0
 pow 0 -0
 pow -0 0
diff --git a/math/bits/mathcalls-narrow.h b/math/bits/mathcalls-narrow.h
index 1082843..daaae12 100644
--- a/math/bits/mathcalls-narrow.h
+++ b/math/bits/mathcalls-narrow.h
@@ -23,5 +23,8 @@ 
 /* Add.  */
 __MATHCALL_NARROW (__MATHCALL_NAME (add), __MATHCALL_REDIR_NAME (add), 2);
 
+/* Multiply.  */
+__MATHCALL_NARROW (__MATHCALL_NAME (mul), __MATHCALL_REDIR_NAME (mul), 2);
+
 /* Subtract.  */
 __MATHCALL_NARROW (__MATHCALL_NAME (sub), __MATHCALL_REDIR_NAME (sub), 2);
diff --git a/math/gen-auto-libm-tests.c b/math/gen-auto-libm-tests.c
index cf157f5..80845a1 100644
--- a/math/gen-auto-libm-tests.c
+++ b/math/gen-auto-libm-tests.c
@@ -579,6 +579,7 @@  static test_function test_functions[] =
     FUNC_mpfr_f_f ("log10", mpfr_log10, false),
     FUNC_mpfr_f_f ("log1p", mpfr_log1p, false),
     FUNC_mpfr_f_f ("log2", mpfr_log2, false),
+    FUNC_mpfr_ff_f ("mul", mpfr_mul, true),
     FUNC_mpfr_ff_f ("pow", mpfr_pow, false),
     FUNC_mpfr_f_f ("sin", mpfr_sin, false),
     FUNC ("sincos", ARGS1 (type_fp), RET2 (type_fp, type_fp), false, false,
diff --git a/math/libm-test-narrow-mul.inc b/math/libm-test-narrow-mul.inc
new file mode 100644
index 0000000..4774fa2
--- /dev/null
+++ b/math/libm-test-narrow-mul.inc
@@ -0,0 +1,179 @@ 
+/* Test narrowing multiply.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "libm-test-driver.c"
+
+static const struct test_aa_f_data mul_test_data[] =
+  {
+    TEST_aa_f (mul, arg_qnan_value, arg_qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_qnan_value, -arg_qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, -arg_qnan_value, arg_qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, -arg_qnan_value, -arg_qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_qnan_value, arg_snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, arg_qnan_value, -arg_snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, -arg_qnan_value, arg_snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, -arg_qnan_value, -arg_snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, arg_snan_value, arg_qnan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, arg_snan_value, -arg_qnan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, -arg_snan_value, arg_qnan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, -arg_snan_value, -arg_qnan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, arg_snan_value, arg_snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, arg_snan_value, -arg_snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, -arg_snan_value, arg_snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, -arg_snan_value, -arg_snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+
+    TEST_aa_f (mul, arg_qnan_value, arg_plus_zero, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_qnan_value, arg_minus_zero, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_qnan_value, arg_plus_infty, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_qnan_value, arg_minus_infty, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_qnan_value, arg_min_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_qnan_value, -arg_min_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_qnan_value, arg_min_subnorm_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_qnan_value, -arg_min_subnorm_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_qnan_value, arg_max_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_qnan_value, -arg_max_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_plus_zero, arg_qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_minus_zero, arg_qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_plus_infty, arg_qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_minus_infty, arg_qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_min_value, arg_qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, -arg_min_value, arg_qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_min_subnorm_value, arg_qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, -arg_min_subnorm_value, arg_qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_max_value, arg_qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, -arg_max_value, arg_qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, -arg_qnan_value, arg_plus_zero, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, -arg_qnan_value, arg_minus_zero, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, -arg_qnan_value, arg_plus_infty, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, -arg_qnan_value, arg_minus_infty, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, -arg_qnan_value, arg_min_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, -arg_qnan_value, -arg_min_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, -arg_qnan_value, arg_min_subnorm_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, -arg_qnan_value, -arg_min_subnorm_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, -arg_qnan_value, arg_max_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, -arg_qnan_value, -arg_max_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_plus_zero, -arg_qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_minus_zero, -arg_qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_plus_infty, -arg_qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_minus_infty, -arg_qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_min_value, -arg_qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, -arg_min_value, -arg_qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_min_subnorm_value, -arg_qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, -arg_min_subnorm_value, -arg_qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_max_value, -arg_qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, -arg_max_value, -arg_qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+
+    TEST_aa_f (mul, arg_snan_value, arg_plus_zero, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, arg_snan_value, arg_minus_zero, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, arg_snan_value, arg_plus_infty, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, arg_snan_value, arg_minus_infty, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, arg_snan_value, arg_min_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, arg_snan_value, -arg_min_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, arg_snan_value, arg_min_subnorm_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, arg_snan_value, -arg_min_subnorm_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, arg_snan_value, arg_max_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, arg_snan_value, -arg_max_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, arg_plus_zero, arg_snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, arg_minus_zero, arg_snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, arg_plus_infty, arg_snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, arg_minus_infty, arg_snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, arg_min_value, arg_snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, -arg_min_value, arg_snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, arg_min_subnorm_value, arg_snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, -arg_min_subnorm_value, arg_snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, arg_max_value, arg_snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, -arg_max_value, arg_snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, -arg_snan_value, arg_plus_zero, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, -arg_snan_value, arg_minus_zero, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, -arg_snan_value, arg_plus_infty, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, -arg_snan_value, arg_minus_infty, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, -arg_snan_value, arg_min_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, -arg_snan_value, -arg_min_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, -arg_snan_value, arg_min_subnorm_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, -arg_snan_value, -arg_min_subnorm_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, -arg_snan_value, arg_max_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, -arg_snan_value, -arg_max_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, arg_plus_zero, -arg_snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, arg_minus_zero, -arg_snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, arg_plus_infty, -arg_snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, arg_minus_infty, -arg_snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, arg_min_value, -arg_snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, -arg_min_value, -arg_snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, arg_min_subnorm_value, -arg_snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, -arg_min_subnorm_value, -arg_snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, arg_max_value, -arg_snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_aa_f (mul, -arg_max_value, -arg_snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+
+    TEST_aa_f (mul, arg_plus_infty, arg_plus_infty, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_plus_infty, arg_minus_infty, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_minus_infty, arg_plus_infty, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_minus_infty, arg_minus_infty, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+
+    TEST_aa_f (mul, arg_plus_infty, arg_plus_zero, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_aa_f (mul, arg_plus_infty, arg_minus_zero, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_aa_f (mul, arg_plus_infty, arg_min_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_plus_infty, -arg_min_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_plus_infty, arg_min_subnorm_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_plus_infty, -arg_min_subnorm_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_plus_infty, arg_max_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_plus_infty, -arg_max_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_plus_zero, arg_plus_infty, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_aa_f (mul, arg_minus_zero, arg_plus_infty, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_aa_f (mul, arg_min_value, arg_plus_infty, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, -arg_min_value, arg_plus_infty, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_min_subnorm_value, arg_plus_infty, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, -arg_min_subnorm_value, arg_plus_infty, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_max_value, arg_plus_infty, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, -arg_max_value, arg_plus_infty, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_minus_infty, arg_plus_zero, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_aa_f (mul, arg_minus_infty, arg_minus_zero, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_aa_f (mul, arg_minus_infty, arg_min_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_minus_infty, -arg_min_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_minus_infty, arg_min_subnorm_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_minus_infty, -arg_min_subnorm_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_minus_infty, arg_max_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_minus_infty, -arg_max_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_plus_zero, arg_minus_infty, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_aa_f (mul, arg_minus_zero, arg_minus_infty, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_aa_f (mul, arg_min_value, arg_minus_infty, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, -arg_min_value, arg_minus_infty, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_min_subnorm_value, arg_minus_infty, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, -arg_min_subnorm_value, arg_minus_infty, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, arg_max_value, arg_minus_infty, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_aa_f (mul, -arg_max_value, arg_minus_infty, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+
+    AUTO_TESTS_aa_f (mul),
+  };
+
+static void
+mul_test (void)
+{
+  ALL_RM_TEST (mul, 1, mul_test_data, RUN_TEST_LOOP_aa_f, END);
+}
+
+static void
+do_test (void)
+{
+  mul_test ();
+}
+
+/*
+ * Local Variables:
+ * mode:c
+ * End:
+ */
diff --git a/math/math-narrow.h b/math/math-narrow.h
index b6982f2..f769830 100644
--- a/math/math-narrow.h
+++ b/math/math-narrow.h
@@ -166,6 +166,59 @@ 
     }						\
   while (0)
 
+/* Check for error conditions from a narrowing multiply function
+   returning RET with arguments X and Y and set errno as needed.
+   Overflow and underflow can occur for finite arguments and a domain
+   error for Inf * 0.  */
+#define CHECK_NARROW_MUL(RET, X, Y)			\
+  do							\
+    {							\
+      if (!isfinite (RET))				\
+	{						\
+	  if (isnan (RET))				\
+	    {						\
+	      if (!isnan (X) && !isnan (Y))		\
+		__set_errno (EDOM);			\
+	    }						\
+	  else if (isfinite (X) && isfinite (Y))	\
+	    __set_errno (ERANGE);			\
+	}						\
+      else if ((RET) == 0 && (X) != 0 && (Y) != 0)	\
+	__set_errno (ERANGE);				\
+    }							\
+  while (0)
+
+/* Implement narrowing multiply using round-to-odd.  The arguments are
+   X and Y, the return type is TYPE and UNION, MANTISSA and SUFFIX are
+   as for ROUND_TO_ODD.  */
+#define NARROW_MUL_ROUND_TO_ODD(X, Y, TYPE, UNION, SUFFIX, MANTISSA)	\
+  do									\
+    {									\
+      TYPE ret;								\
+									\
+      ret = (TYPE) ROUND_TO_ODD (math_opt_barrier (X) * (Y),		\
+				 UNION, SUFFIX, MANTISSA);		\
+									\
+      CHECK_NARROW_MUL (ret, (X), (Y));					\
+      return ret;							\
+    }									\
+  while (0)
+
+/* Implement a narrowing multiply function that is not actually
+   narrowing or where no attempt is made to be correctly rounding (the
+   latter only applies to IBM long double).  The arguments are X and Y
+   and the return type is TYPE.  */
+#define NARROW_MUL_TRIVIAL(X, Y, TYPE)		\
+  do						\
+    {						\
+      TYPE ret;					\
+						\
+      ret = (TYPE) ((X) * (Y));			\
+      CHECK_NARROW_MUL (ret, (X), (Y));		\
+      return ret;				\
+    }						\
+  while (0)
+
 /* The following macros declare aliases for a narrowing function.  The
    sole argument is the base name of a family of functions, such as
    "add".  If any platform changes long double format after the
diff --git a/soft-fp/op-common.h b/soft-fp/op-common.h
index 4526afd..d6f32ae 100644
--- a/soft-fp/op-common.h
+++ b/soft-fp/op-common.h
@@ -2041,6 +2041,27 @@ 
     }									\
   while (0)
 
+/* Truncate from a wider floating-point format to a narrower one.
+   Input and output are cooked.  */
+#define FP_TRUNC_COOKED(dfs, sfs, dwc, swc, D, S)			\
+  do									\
+    {									\
+      _FP_STATIC_ASSERT (_FP_FRACBITS_##sfs >= _FP_FRACBITS_##dfs,	\
+			 "destination mantissa wider than source");	\
+      if (S##_c == FP_CLS_NAN)						\
+	_FP_FRAC_SRL_##swc (S, (_FP_WFRACBITS_##sfs			\
+				- _FP_WFRACBITS_##dfs));		\
+      else								\
+	_FP_FRAC_SRS_##swc (S, (_FP_WFRACBITS_##sfs			\
+				- _FP_WFRACBITS_##dfs),			\
+			    _FP_WFRACBITS_##sfs);			\
+      _FP_FRAC_COPY_##dwc##_##swc (D, S);				\
+      D##_e = S##_e;							\
+      D##_c = S##_c;							\
+      D##_s = S##_s;							\
+    }									\
+  while (0)
+
 /* Helper primitives.  */
 
 /* Count leading zeros in a word.  */
diff --git a/sysdeps/i386/fpu/s_f32xmulf64.c b/sysdeps/i386/fpu/s_f32xmulf64.c
new file mode 100644
index 0000000..7710fa4
--- /dev/null
+++ b/sysdeps/i386/fpu/s_f32xmulf64.c
@@ -0,0 +1,29 @@ 
+/* Multiply _Float64 values, converting the result to _Float32x.  i386 version.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math-narrow.h>
+
+_Float32x
+__f32xmulf64 (_Float64 x, _Float64 y)
+{
+  /* To avoid double rounding, use round-to-odd on long double.  */
+  NARROW_MUL_ROUND_TO_ODD ((long double) x, (long double) y, double,
+			   union ieee854_long_double, l, mantissa1);
+}
+libm_alias_float32x_float64 (mul)
diff --git a/sysdeps/ieee754/dbl-64/s_f32xmulf64.c b/sysdeps/ieee754/dbl-64/s_f32xmulf64.c
new file mode 100644
index 0000000..f899c84
--- /dev/null
+++ b/sysdeps/ieee754/dbl-64/s_f32xmulf64.c
@@ -0,0 +1,30 @@ 
+/* Multiply _Float64 values, converting the result to _Float32x.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define dmull __hide_dmull
+#include <math.h>
+#undef dmull
+
+#include <math-narrow.h>
+
+_Float32x
+__f32xmulf64 (_Float64 x, _Float64 y)
+{
+  NARROW_MUL_TRIVIAL (x, y, _Float32x);
+}
+libm_alias_float32x_float64 (mul)
diff --git a/sysdeps/ieee754/dbl-64/s_fmul.c b/sysdeps/ieee754/dbl-64/s_fmul.c
new file mode 100644
index 0000000..ad9ab7e
--- /dev/null
+++ b/sysdeps/ieee754/dbl-64/s_fmul.c
@@ -0,0 +1,34 @@ 
+/* Multiply double values, narrowing the result to float.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define f32mulf64 __hide_f32mulf64
+#define f32mulf32x __hide_f32mulf32x
+#define fmull __hide_fmull
+#include <math.h>
+#undef f32mulf64
+#undef f32mulf32x
+#undef fmull
+
+#include <math-narrow.h>
+
+float
+__fmul (double x, double y)
+{
+  NARROW_MUL_ROUND_TO_ODD (x, y, float, union ieee754_double, , mantissa1);
+}
+libm_alias_float_double (mul)
diff --git a/sysdeps/ieee754/float128/float128_private.h b/sysdeps/ieee754/float128/float128_private.h
index 7606026..9136e53 100644
--- a/sysdeps/ieee754/float128/float128_private.h
+++ b/sysdeps/ieee754/float128/float128_private.h
@@ -258,6 +258,8 @@ 
 
 #define __faddl __f32addf128
 #define __daddl __f64addf128
+#define __fmull __f32mulf128
+#define __dmull __f64mulf128
 #define __fsubl __f32subf128
 #define __dsubl __f64subf128
 
diff --git a/sysdeps/ieee754/float128/s_f32mulf128.c b/sysdeps/ieee754/float128/s_f32mulf128.c
new file mode 100644
index 0000000..45fdc66
--- /dev/null
+++ b/sysdeps/ieee754/float128/s_f32mulf128.c
@@ -0,0 +1,6 @@ 
+#define f32mulf64x __hide_f32mulf64x
+#define f32mulf128 __hide_f32mulf128
+#include <float128_private.h>
+#undef f32mulf64x
+#undef f32mulf128
+#include "../ldbl-128/s_fmull.c"
diff --git a/sysdeps/ieee754/float128/s_f64mulf128.c b/sysdeps/ieee754/float128/s_f64mulf128.c
new file mode 100644
index 0000000..47a645a
--- /dev/null
+++ b/sysdeps/ieee754/float128/s_f64mulf128.c
@@ -0,0 +1,10 @@ 
+#define f32xmulf64x __hide_f32xmulf64x
+#define f32xmulf128 __hide_f32xmulf128
+#define f64mulf64x __hide_f64mulf64x
+#define f64mulf128 __hide_f64mulf128
+#include <float128_private.h>
+#undef f32xmulf64x
+#undef f32xmulf128
+#undef f64mulf64x
+#undef f64mulf128
+#include "../ldbl-128/s_dmull.c"
diff --git a/sysdeps/ieee754/float128/s_f64xmulf128.c b/sysdeps/ieee754/float128/s_f64xmulf128.c
new file mode 100644
index 0000000..085bf9f
--- /dev/null
+++ b/sysdeps/ieee754/float128/s_f64xmulf128.c
@@ -0,0 +1,2 @@ 
+#include <float128_private.h>
+#include "../ldbl-128/s_f64xmulf128.c"
diff --git a/sysdeps/ieee754/ldbl-128/s_dmull.c b/sysdeps/ieee754/ldbl-128/s_dmull.c
new file mode 100644
index 0000000..d32c428
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128/s_dmull.c
@@ -0,0 +1,37 @@ 
+/* Multiply long double (ldbl-128) values, narrowing the result to double.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define f32xmulf64x __hide_f32xmulf64x
+#define f32xmulf128 __hide_f32xmulf128
+#define f64mulf64x __hide_f64mulf64x
+#define f64mulf128 __hide_f64mulf128
+#include <math.h>
+#undef f32xmulf64x
+#undef f32xmulf128
+#undef f64mulf64x
+#undef f64mulf128
+
+#include <math-narrow.h>
+
+double
+__dmull (_Float128 x, _Float128 y)
+{
+  NARROW_MUL_ROUND_TO_ODD (x, y, double, union ieee854_long_double, l,
+			   mantissa3);
+}
+libm_alias_double_ldouble (mul)
diff --git a/sysdeps/ieee754/ldbl-128/s_f64xmulf128.c b/sysdeps/ieee754/ldbl-128/s_f64xmulf128.c
new file mode 100644
index 0000000..ed88eab
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128/s_f64xmulf128.c
@@ -0,0 +1,38 @@ 
+/* Multiply _Float128 values, converting the result to _Float64x.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math-narrow.h>
+
+/* math_ldbl.h defines _Float128 to long double for this directory,
+   but when they are different, this function must be defined with
+   _Float128 arguments to avoid defining an alias with an incompatible
+   type.  */
+#undef _Float128
+
+_Float64x
+__f64xmulf128 (_Float128 x, _Float128 y)
+{
+#if __HAVE_FLOAT64X_LONG_DOUBLE && __HAVE_DISTINCT_FLOAT128
+  NARROW_MUL_ROUND_TO_ODD (x, y, _Float64x, union ieee854_long_double, l,
+			   mantissa3);
+#else
+  NARROW_MUL_TRIVIAL (x, y, _Float64x);
+#endif
+}
+libm_alias_float64x_float128 (mul)
diff --git a/sysdeps/ieee754/ldbl-128/s_fmull.c b/sysdeps/ieee754/ldbl-128/s_fmull.c
new file mode 100644
index 0000000..dd399f9
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128/s_fmull.c
@@ -0,0 +1,33 @@ 
+/* Multiply long double (ldbl-128) values, narrowing the result to float.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define f32mulf64x __hide_f32mulf64x
+#define f32mulf128 __hide_f32mulf128
+#include <math.h>
+#undef f32mulf64x
+#undef f32mulf128
+
+#include <math-narrow.h>
+
+float
+__fmull (_Float128 x, _Float128 y)
+{
+  NARROW_MUL_ROUND_TO_ODD (x, y, float, union ieee854_long_double, l,
+			   mantissa3);
+}
+libm_alias_float_ldouble (mul)
diff --git a/sysdeps/ieee754/ldbl-128ibm/s_dmull.c b/sysdeps/ieee754/ldbl-128ibm/s_dmull.c
new file mode 100644
index 0000000..7b75b2b
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm/s_dmull.c
@@ -0,0 +1,27 @@ 
+/* Multiply long double (ldbl-128ibm) values, narrowing the result to double.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math-narrow.h>
+
+double
+__dmull (long double x, long double y)
+{
+  NARROW_MUL_TRIVIAL (x, y, double);
+}
+libm_alias_double_ldouble (mul)
diff --git a/sysdeps/ieee754/ldbl-128ibm/s_fmull.c b/sysdeps/ieee754/ldbl-128ibm/s_fmull.c
new file mode 100644
index 0000000..d1988f1
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm/s_fmull.c
@@ -0,0 +1,27 @@ 
+/* Multiply long double (ldbl-128ibm) values, narrowing the result to float.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math-narrow.h>
+
+float
+__fmull (long double x, long double y)
+{
+  NARROW_MUL_TRIVIAL (x, y, float);
+}
+libm_alias_float_ldouble (mul)
diff --git a/sysdeps/ieee754/ldbl-96/s_dmull.c b/sysdeps/ieee754/ldbl-96/s_dmull.c
new file mode 100644
index 0000000..a717b0a
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-96/s_dmull.c
@@ -0,0 +1,33 @@ 
+/* Multiply long double (ldbl-96) values, narrowing the result to double.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define f32xmulf64x __hide_f32xmulf64x
+#define f64mulf64x __hide_f64mulf64x
+#include <math.h>
+#undef f32xmulf64x
+#undef f64mulf64x
+
+#include <math-narrow.h>
+
+double
+__dmull (long double x, long double y)
+{
+  NARROW_MUL_ROUND_TO_ODD (x, y, double, union ieee854_long_double, l,
+			   mantissa1);
+}
+libm_alias_double_ldouble (mul)
diff --git a/sysdeps/ieee754/ldbl-96/s_fmull.c b/sysdeps/ieee754/ldbl-96/s_fmull.c
new file mode 100644
index 0000000..b758252
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-96/s_fmull.c
@@ -0,0 +1,31 @@ 
+/* Multiply long double (ldbl-96) values, narrowing the result to float.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define f32mulf64x __hide_f32mulf64x
+#include <math.h>
+#undef f32mulf64x
+
+#include <math-narrow.h>
+
+float
+__fmull (long double x, long double y)
+{
+  NARROW_MUL_ROUND_TO_ODD (x, y, float, union ieee854_long_double, l,
+			   mantissa1);
+}
+libm_alias_float_ldouble (mul)
diff --git a/sysdeps/ieee754/ldbl-opt/Makefile b/sysdeps/ieee754/ldbl-opt/Makefile
index 7cdeaad..90b2c92 100644
--- a/sysdeps/ieee754/ldbl-opt/Makefile
+++ b/sysdeps/ieee754/ldbl-opt/Makefile
@@ -45,7 +45,7 @@  libnldbl-calls = asprintf dprintf fprintf fscanf fwprintf fwscanf iovfscanf \
 		 nextup nextdown totalorder totalordermag getpayload \
 		 canonicalize setpayload setpayloadsig llogb fmaxmag fminmag \
 		 roundeven fromfp ufromfp fromfpx ufromfpx fadd dadd \
-		 fsub dsub
+		 fmul dmul fsub dsub
 libnldbl-routines = $(libnldbl-calls:%=nldbl-%)
 libnldbl-inhibit-o = $(object-suffixes)
 libnldbl-static-only-routines = $(libnldbl-routines)
@@ -88,6 +88,7 @@  CFLAGS-nldbl-csqrt.c = -fno-builtin-csqrtl
 CFLAGS-nldbl-ctan.c = -fno-builtin-ctanl
 CFLAGS-nldbl-ctanh.c = -fno-builtin-ctanhl
 CFLAGS-nldbl-dadd.c = -fno-builtin-daddl
+CFLAGS-nldbl-dmul.c = -fno-builtin-dmull
 CFLAGS-nldbl-dsub.c = -fno-builtin-dsubl
 CFLAGS-nldbl-erf.c = -fno-builtin-erfl
 CFLAGS-nldbl-erfc.c = -fno-builtin-erfcl
@@ -106,6 +107,7 @@  CFLAGS-nldbl-fmaxmag.c = -fno-builtin-fmaxmagl
 CFLAGS-nldbl-fmin.c = -fno-builtin-fminl
 CFLAGS-nldbl-fminmag.c = -fno-builtin-fminmagl
 CFLAGS-nldbl-fmod.c = -fno-builtin-fmodl
+CFLAGS-nldbl-fmul.c = -fno-builtin-fmull
 CFLAGS-nldbl-frexp.c = -fno-builtin-frexpl
 CFLAGS-nldbl-fromfp.c = -fno-builtin-fromfpl
 CFLAGS-nldbl-fromfpx.c = -fno-builtin-fromfpxl
diff --git a/sysdeps/ieee754/ldbl-opt/Versions b/sysdeps/ieee754/ldbl-opt/Versions
index c33dc42..17aa035 100644
--- a/sysdeps/ieee754/ldbl-opt/Versions
+++ b/sysdeps/ieee754/ldbl-opt/Versions
@@ -101,6 +101,6 @@  libm {
     # Functions taking long double = double argument and rounding
     # result to double (same as f32x*f64 functions, but those names
     # are not reserved in TS 18661-1).
-    __nldbl_daddl; __nldbl_dsubl;
+    __nldbl_daddl; __nldbl_dmull; __nldbl_dsubl;
   }
 }
diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-compat.h b/sysdeps/ieee754/ldbl-opt/nldbl-compat.h
index 4f5ae2d..e0d1254 100644
--- a/sysdeps/ieee754/ldbl-opt/nldbl-compat.h
+++ b/sysdeps/ieee754/ldbl-opt/nldbl-compat.h
@@ -104,6 +104,7 @@  extern void __nldbl___vsyslog_chk (int, int, const char *, va_list);
 /* The original declarations of these were hidden by the including
    file.  */
 extern double __nldbl_daddl (double, double) __THROW;
+extern double __nldbl_dmull (double, double) __THROW;
 extern double __nldbl_dsubl (double, double) __THROW;
 
 #endif /* __NLDBL_COMPAT_H */
diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-dmul.c b/sysdeps/ieee754/ldbl-opt/nldbl-dmul.c
new file mode 100644
index 0000000..9c9b94e
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-opt/nldbl-dmul.c
@@ -0,0 +1,28 @@ 
+/* Compatibility routine for IEEE double as long double for dmul.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define dmull __hide_dmull
+#include "nldbl-compat.h"
+#undef dmull
+
+double
+attribute_hidden
+dmull (double x, double y)
+{
+  return __nldbl_dmull (x, y);
+}
diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-fmul.c b/sysdeps/ieee754/ldbl-opt/nldbl-fmul.c
new file mode 100644
index 0000000..2520d1b
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-opt/nldbl-fmul.c
@@ -0,0 +1,28 @@ 
+/* Compatibility routine for IEEE double as long double for fmul.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define fmull __hide_fmull
+#include "nldbl-compat.h"
+#undef fmull
+
+float
+attribute_hidden
+fmull (double x, double y)
+{
+  return fmul (x, y);
+}
diff --git a/sysdeps/ieee754/soft-fp/s_dmull.c b/sysdeps/ieee754/soft-fp/s_dmull.c
new file mode 100644
index 0000000..4ebf311
--- /dev/null
+++ b/sysdeps/ieee754/soft-fp/s_dmull.c
@@ -0,0 +1,59 @@ 
+/* Multiply long double (ldbl-128) values, narrowing the result to
+   double, using soft-fp.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define f32xmulf64x __hide_f32xmulf64x
+#define f32xmulf128 __hide_f32xmulf128
+#define f64mulf64x __hide_f64mulf64x
+#define f64mulf128 __hide_f64mulf128
+#include <math.h>
+#undef f32xmulf64x
+#undef f32xmulf128
+#undef f64mulf64x
+#undef f64mulf128
+
+#include <math-narrow.h>
+#include <soft-fp.h>
+#include <double.h>
+#include <quad.h>
+
+double
+__dmull (_Float128 x, _Float128 y)
+{
+  FP_DECL_EX;
+  FP_DECL_Q (X);
+  FP_DECL_Q (Y);
+  FP_DECL_Q (R);
+  FP_DECL_D (RN);
+  double ret;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_Q (X, x);
+  FP_UNPACK_Q (Y, y);
+  FP_MUL_Q (R, X, Y);
+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
+  FP_TRUNC_COOKED (D, Q, 2, 4, RN, R);
+#else
+  FP_TRUNC_COOKED (D, Q, 1, 2, RN, R);
+#endif
+  FP_PACK_D (ret, RN);
+  FP_HANDLE_EXCEPTIONS;
+  CHECK_NARROW_MUL (ret, x, y);
+  return ret;
+}
+libm_alias_double_ldouble (mul)
diff --git a/sysdeps/ieee754/soft-fp/s_fmul.c b/sysdeps/ieee754/soft-fp/s_fmul.c
new file mode 100644
index 0000000..5f679b1
--- /dev/null
+++ b/sysdeps/ieee754/soft-fp/s_fmul.c
@@ -0,0 +1,56 @@ 
+/* Multiply double values, narrowing the result to float, using soft-fp.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define f32mulf64 __hide_f32mulf64
+#define f32mulf32x __hide_f32mulf32x
+#define fmull __hide_fmull
+#include <math.h>
+#undef f32mulf64
+#undef f32mulf32x
+#undef fmull
+
+#include <math-narrow.h>
+#include <soft-fp.h>
+#include <single.h>
+#include <double.h>
+
+float
+__fmul (double x, double y)
+{
+  FP_DECL_EX;
+  FP_DECL_D (X);
+  FP_DECL_D (Y);
+  FP_DECL_D (R);
+  FP_DECL_S (RN);
+  float ret;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_D (X, x);
+  FP_UNPACK_D (Y, y);
+  FP_MUL_D (R, X, Y);
+#if _FP_W_TYPE_SIZE < _FP_FRACBITS_D
+  FP_TRUNC_COOKED (S, D, 1, 2, RN, R);
+#else
+  FP_TRUNC_COOKED (S, D, 1, 1, RN, R);
+#endif
+  FP_PACK_S (ret, RN);
+  FP_HANDLE_EXCEPTIONS;
+  CHECK_NARROW_MUL (ret, x, y);
+  return ret;
+}
+libm_alias_float_double (mul)
diff --git a/sysdeps/ieee754/soft-fp/s_fmull.c b/sysdeps/ieee754/soft-fp/s_fmull.c
new file mode 100644
index 0000000..da4a12c
--- /dev/null
+++ b/sysdeps/ieee754/soft-fp/s_fmull.c
@@ -0,0 +1,55 @@ 
+/* Multiply long double (ldbl-128) values, narrowing the result to
+   float, using soft-fp.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define f32mulf64x __hide_f32mulf64x
+#define f32mulf128 __hide_f32mulf128
+#include <math.h>
+#undef f32mulf64x
+#undef f32mulf128
+
+#include <math-narrow.h>
+#include <soft-fp.h>
+#include <single.h>
+#include <quad.h>
+
+float
+__fmull (_Float128 x, _Float128 y)
+{
+  FP_DECL_EX;
+  FP_DECL_Q (X);
+  FP_DECL_Q (Y);
+  FP_DECL_Q (R);
+  FP_DECL_S (RN);
+  float ret;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_Q (X, x);
+  FP_UNPACK_Q (Y, y);
+  FP_MUL_Q (R, X, Y);
+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
+  FP_TRUNC_COOKED (S, Q, 1, 4, RN, R);
+#else
+  FP_TRUNC_COOKED (S, Q, 1, 2, RN, R);
+#endif
+  FP_PACK_S (ret, RN);
+  FP_HANDLE_EXCEPTIONS;
+  CHECK_NARROW_MUL (ret, x, y);
+  return ret;
+}
+libm_alias_float_ldouble (mul)
diff --git a/sysdeps/mach/hurd/i386/libm.abilist b/sysdeps/mach/hurd/i386/libm.abilist
index 11b8fd1..8aef1bd 100644
--- a/sysdeps/mach/hurd/i386/libm.abilist
+++ b/sysdeps/mach/hurd/i386/libm.abilist
@@ -1017,11 +1017,16 @@  GLIBC_2.27 ynf32x F
 GLIBC_2.27 ynf64 F
 GLIBC_2.27 ynf64x F
 GLIBC_2.28 daddl F
+GLIBC_2.28 dmull F
 GLIBC_2.28 dsubl F
 GLIBC_2.28 f32addf128 F
 GLIBC_2.28 f32addf32x F
 GLIBC_2.28 f32addf64 F
 GLIBC_2.28 f32addf64x F
+GLIBC_2.28 f32mulf128 F
+GLIBC_2.28 f32mulf32x F
+GLIBC_2.28 f32mulf64 F
+GLIBC_2.28 f32mulf64x F
 GLIBC_2.28 f32subf128 F
 GLIBC_2.28 f32subf32x F
 GLIBC_2.28 f32subf64 F
@@ -1029,16 +1034,24 @@  GLIBC_2.28 f32subf64x F
 GLIBC_2.28 f32xaddf128 F
 GLIBC_2.28 f32xaddf64 F
 GLIBC_2.28 f32xaddf64x F
+GLIBC_2.28 f32xmulf128 F
+GLIBC_2.28 f32xmulf64 F
+GLIBC_2.28 f32xmulf64x F
 GLIBC_2.28 f32xsubf128 F
 GLIBC_2.28 f32xsubf64 F
 GLIBC_2.28 f32xsubf64x F
 GLIBC_2.28 f64addf128 F
 GLIBC_2.28 f64addf64x F
+GLIBC_2.28 f64mulf128 F
+GLIBC_2.28 f64mulf64x F
 GLIBC_2.28 f64subf128 F
 GLIBC_2.28 f64subf64x F
 GLIBC_2.28 f64xaddf128 F
+GLIBC_2.28 f64xmulf128 F
 GLIBC_2.28 f64xsubf128 F
 GLIBC_2.28 fadd F
 GLIBC_2.28 faddl F
+GLIBC_2.28 fmul F
+GLIBC_2.28 fmull F
 GLIBC_2.28 fsub F
 GLIBC_2.28 fsubl F
diff --git a/sysdeps/powerpc/fpu/libm-test-ulps b/sysdeps/powerpc/fpu/libm-test-ulps
index ea5df2d..e5098d6 100644
--- a/sysdeps/powerpc/fpu/libm-test-ulps
+++ b/sysdeps/powerpc/fpu/libm-test-ulps
@@ -2457,6 +2457,22 @@  ifloat128: 1
 ildouble: 1
 ldouble: 1
 
+Function: "mul_downward_ldouble":
+double: 1
+float: 1
+
+Function: "mul_ldouble":
+double: 1
+float: 1
+
+Function: "mul_towardzero_ldouble":
+double: 1
+float: 1
+
+Function: "mul_upward_ldouble":
+double: 1
+float: 1
+
 Function: "nextafter_downward":
 ildouble: 1
 ldouble: 1
diff --git a/sysdeps/unix/sysv/linux/aarch64/libm.abilist b/sysdeps/unix/sysv/linux/aarch64/libm.abilist
index e22190e..c31b114 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libm.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libm.abilist
@@ -981,11 +981,16 @@  GLIBC_2.27 ynf32x F
 GLIBC_2.27 ynf64 F
 GLIBC_2.27 ynf64x F
 GLIBC_2.28 daddl F
+GLIBC_2.28 dmull F
 GLIBC_2.28 dsubl F
 GLIBC_2.28 f32addf128 F
 GLIBC_2.28 f32addf32x F
 GLIBC_2.28 f32addf64 F
 GLIBC_2.28 f32addf64x F
+GLIBC_2.28 f32mulf128 F
+GLIBC_2.28 f32mulf32x F
+GLIBC_2.28 f32mulf64 F
+GLIBC_2.28 f32mulf64x F
 GLIBC_2.28 f32subf128 F
 GLIBC_2.28 f32subf32x F
 GLIBC_2.28 f32subf64 F
@@ -993,16 +998,24 @@  GLIBC_2.28 f32subf64x F
 GLIBC_2.28 f32xaddf128 F
 GLIBC_2.28 f32xaddf64 F
 GLIBC_2.28 f32xaddf64x F
+GLIBC_2.28 f32xmulf128 F
+GLIBC_2.28 f32xmulf64 F
+GLIBC_2.28 f32xmulf64x F
 GLIBC_2.28 f32xsubf128 F
 GLIBC_2.28 f32xsubf64 F
 GLIBC_2.28 f32xsubf64x F
 GLIBC_2.28 f64addf128 F
 GLIBC_2.28 f64addf64x F
+GLIBC_2.28 f64mulf128 F
+GLIBC_2.28 f64mulf64x F
 GLIBC_2.28 f64subf128 F
 GLIBC_2.28 f64subf64x F
 GLIBC_2.28 f64xaddf128 F
+GLIBC_2.28 f64xmulf128 F
 GLIBC_2.28 f64xsubf128 F
 GLIBC_2.28 fadd F
 GLIBC_2.28 faddl F
+GLIBC_2.28 fmul F
+GLIBC_2.28 fmull F
 GLIBC_2.28 fsub F
 GLIBC_2.28 fsubl F
diff --git a/sysdeps/unix/sysv/linux/alpha/libm.abilist b/sysdeps/unix/sysv/linux/alpha/libm.abilist
index 0da51ce..eed5f20 100644
--- a/sysdeps/unix/sysv/linux/alpha/libm.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libm.abilist
@@ -988,13 +988,19 @@  GLIBC_2.27 ynf32x F
 GLIBC_2.27 ynf64 F
 GLIBC_2.27 ynf64x F
 GLIBC_2.28 __nldbl_daddl F
+GLIBC_2.28 __nldbl_dmull F
 GLIBC_2.28 __nldbl_dsubl F
 GLIBC_2.28 daddl F
+GLIBC_2.28 dmull F
 GLIBC_2.28 dsubl F
 GLIBC_2.28 f32addf128 F
 GLIBC_2.28 f32addf32x F
 GLIBC_2.28 f32addf64 F
 GLIBC_2.28 f32addf64x F
+GLIBC_2.28 f32mulf128 F
+GLIBC_2.28 f32mulf32x F
+GLIBC_2.28 f32mulf64 F
+GLIBC_2.28 f32mulf64x F
 GLIBC_2.28 f32subf128 F
 GLIBC_2.28 f32subf32x F
 GLIBC_2.28 f32subf64 F
@@ -1002,17 +1008,25 @@  GLIBC_2.28 f32subf64x F
 GLIBC_2.28 f32xaddf128 F
 GLIBC_2.28 f32xaddf64 F
 GLIBC_2.28 f32xaddf64x F
+GLIBC_2.28 f32xmulf128 F
+GLIBC_2.28 f32xmulf64 F
+GLIBC_2.28 f32xmulf64x F
 GLIBC_2.28 f32xsubf128 F
 GLIBC_2.28 f32xsubf64 F
 GLIBC_2.28 f32xsubf64x F
 GLIBC_2.28 f64addf128 F
 GLIBC_2.28 f64addf64x F
+GLIBC_2.28 f64mulf128 F
+GLIBC_2.28 f64mulf64x F
 GLIBC_2.28 f64subf128 F
 GLIBC_2.28 f64subf64x F
 GLIBC_2.28 f64xaddf128 F
+GLIBC_2.28 f64xmulf128 F
 GLIBC_2.28 f64xsubf128 F
 GLIBC_2.28 fadd F
 GLIBC_2.28 faddl F
+GLIBC_2.28 fmul F
+GLIBC_2.28 fmull F
 GLIBC_2.28 fsub F
 GLIBC_2.28 fsubl F
 GLIBC_2.3.4 __c1_cabsf F
diff --git a/sysdeps/unix/sysv/linux/arm/libm.abilist b/sysdeps/unix/sysv/linux/arm/libm.abilist
index a355af5..8226f61 100644
--- a/sysdeps/unix/sysv/linux/arm/libm.abilist
+++ b/sysdeps/unix/sysv/linux/arm/libm.abilist
@@ -430,15 +430,21 @@  GLIBC_2.27 ynf32 F
 GLIBC_2.27 ynf32x F
 GLIBC_2.27 ynf64 F
 GLIBC_2.28 daddl F
+GLIBC_2.28 dmull F
 GLIBC_2.28 dsubl F
 GLIBC_2.28 f32addf32x F
 GLIBC_2.28 f32addf64 F
+GLIBC_2.28 f32mulf32x F
+GLIBC_2.28 f32mulf64 F
 GLIBC_2.28 f32subf32x F
 GLIBC_2.28 f32subf64 F
 GLIBC_2.28 f32xaddf64 F
+GLIBC_2.28 f32xmulf64 F
 GLIBC_2.28 f32xsubf64 F
 GLIBC_2.28 fadd F
 GLIBC_2.28 faddl F
+GLIBC_2.28 fmul F
+GLIBC_2.28 fmull F
 GLIBC_2.28 fsub F
 GLIBC_2.28 fsubl F
 GLIBC_2.4 _LIB_VERSION D 0x4
diff --git a/sysdeps/unix/sysv/linux/hppa/libm.abilist b/sysdeps/unix/sysv/linux/hppa/libm.abilist
index 2f923c0..81a9b8b 100644
--- a/sysdeps/unix/sysv/linux/hppa/libm.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libm.abilist
@@ -741,15 +741,21 @@  GLIBC_2.27 ynf32 F
 GLIBC_2.27 ynf32x F
 GLIBC_2.27 ynf64 F
 GLIBC_2.28 daddl F
+GLIBC_2.28 dmull F
 GLIBC_2.28 dsubl F
 GLIBC_2.28 f32addf32x F
 GLIBC_2.28 f32addf64 F
+GLIBC_2.28 f32mulf32x F
+GLIBC_2.28 f32mulf64 F
 GLIBC_2.28 f32subf32x F
 GLIBC_2.28 f32subf64 F
 GLIBC_2.28 f32xaddf64 F
+GLIBC_2.28 f32xmulf64 F
 GLIBC_2.28 f32xsubf64 F
 GLIBC_2.28 fadd F
 GLIBC_2.28 faddl F
+GLIBC_2.28 fmul F
+GLIBC_2.28 fmull F
 GLIBC_2.28 fsub F
 GLIBC_2.28 fsubl F
 GLIBC_2.4 exp2l F
diff --git a/sysdeps/unix/sysv/linux/i386/libm.abilist b/sysdeps/unix/sysv/linux/i386/libm.abilist
index d65f237..106a2bd 100644
--- a/sysdeps/unix/sysv/linux/i386/libm.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libm.abilist
@@ -1024,11 +1024,16 @@  GLIBC_2.27 ynf32x F
 GLIBC_2.27 ynf64 F
 GLIBC_2.27 ynf64x F
 GLIBC_2.28 daddl F
+GLIBC_2.28 dmull F
 GLIBC_2.28 dsubl F
 GLIBC_2.28 f32addf128 F
 GLIBC_2.28 f32addf32x F
 GLIBC_2.28 f32addf64 F
 GLIBC_2.28 f32addf64x F
+GLIBC_2.28 f32mulf128 F
+GLIBC_2.28 f32mulf32x F
+GLIBC_2.28 f32mulf64 F
+GLIBC_2.28 f32mulf64x F
 GLIBC_2.28 f32subf128 F
 GLIBC_2.28 f32subf32x F
 GLIBC_2.28 f32subf64 F
@@ -1036,16 +1041,24 @@  GLIBC_2.28 f32subf64x F
 GLIBC_2.28 f32xaddf128 F
 GLIBC_2.28 f32xaddf64 F
 GLIBC_2.28 f32xaddf64x F
+GLIBC_2.28 f32xmulf128 F
+GLIBC_2.28 f32xmulf64 F
+GLIBC_2.28 f32xmulf64x F
 GLIBC_2.28 f32xsubf128 F
 GLIBC_2.28 f32xsubf64 F
 GLIBC_2.28 f32xsubf64x F
 GLIBC_2.28 f64addf128 F
 GLIBC_2.28 f64addf64x F
+GLIBC_2.28 f64mulf128 F
+GLIBC_2.28 f64mulf64x F
 GLIBC_2.28 f64subf128 F
 GLIBC_2.28 f64subf64x F
 GLIBC_2.28 f64xaddf128 F
+GLIBC_2.28 f64xmulf128 F
 GLIBC_2.28 f64xsubf128 F
 GLIBC_2.28 fadd F
 GLIBC_2.28 faddl F
+GLIBC_2.28 fmul F
+GLIBC_2.28 fmull F
 GLIBC_2.28 fsub F
 GLIBC_2.28 fsubl F
diff --git a/sysdeps/unix/sysv/linux/ia64/libm.abilist b/sysdeps/unix/sysv/linux/ia64/libm.abilist
index 2dd457b..bfef4e1 100644
--- a/sysdeps/unix/sysv/linux/ia64/libm.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libm.abilist
@@ -954,11 +954,16 @@  GLIBC_2.27 ynf32x F
 GLIBC_2.27 ynf64 F
 GLIBC_2.27 ynf64x F
 GLIBC_2.28 daddl F
+GLIBC_2.28 dmull F
 GLIBC_2.28 dsubl F
 GLIBC_2.28 f32addf128 F
 GLIBC_2.28 f32addf32x F
 GLIBC_2.28 f32addf64 F
 GLIBC_2.28 f32addf64x F
+GLIBC_2.28 f32mulf128 F
+GLIBC_2.28 f32mulf32x F
+GLIBC_2.28 f32mulf64 F
+GLIBC_2.28 f32mulf64x F
 GLIBC_2.28 f32subf128 F
 GLIBC_2.28 f32subf32x F
 GLIBC_2.28 f32subf64 F
@@ -966,16 +971,24 @@  GLIBC_2.28 f32subf64x F
 GLIBC_2.28 f32xaddf128 F
 GLIBC_2.28 f32xaddf64 F
 GLIBC_2.28 f32xaddf64x F
+GLIBC_2.28 f32xmulf128 F
+GLIBC_2.28 f32xmulf64 F
+GLIBC_2.28 f32xmulf64x F
 GLIBC_2.28 f32xsubf128 F
 GLIBC_2.28 f32xsubf64 F
 GLIBC_2.28 f32xsubf64x F
 GLIBC_2.28 f64addf128 F
 GLIBC_2.28 f64addf64x F
+GLIBC_2.28 f64mulf128 F
+GLIBC_2.28 f64mulf64x F
 GLIBC_2.28 f64subf128 F
 GLIBC_2.28 f64subf64x F
 GLIBC_2.28 f64xaddf128 F
+GLIBC_2.28 f64xmulf128 F
 GLIBC_2.28 f64xsubf128 F
 GLIBC_2.28 fadd F
 GLIBC_2.28 faddl F
+GLIBC_2.28 fmul F
+GLIBC_2.28 fmull F
 GLIBC_2.28 fsub F
 GLIBC_2.28 fsubl F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist
index a355af5..8226f61 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist
@@ -430,15 +430,21 @@  GLIBC_2.27 ynf32 F
 GLIBC_2.27 ynf32x F
 GLIBC_2.27 ynf64 F
 GLIBC_2.28 daddl F
+GLIBC_2.28 dmull F
 GLIBC_2.28 dsubl F
 GLIBC_2.28 f32addf32x F
 GLIBC_2.28 f32addf64 F
+GLIBC_2.28 f32mulf32x F
+GLIBC_2.28 f32mulf64 F
 GLIBC_2.28 f32subf32x F
 GLIBC_2.28 f32subf64 F
 GLIBC_2.28 f32xaddf64 F
+GLIBC_2.28 f32xmulf64 F
 GLIBC_2.28 f32xsubf64 F
 GLIBC_2.28 fadd F
 GLIBC_2.28 faddl F
+GLIBC_2.28 fmul F
+GLIBC_2.28 fmull F
 GLIBC_2.28 fsub F
 GLIBC_2.28 fsubl F
 GLIBC_2.4 _LIB_VERSION D 0x4
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libm.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libm.abilist
index 1e32185..2c86d3b 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libm.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libm.abilist
@@ -781,14 +781,20 @@  GLIBC_2.27 ynf32 F
 GLIBC_2.27 ynf32x F
 GLIBC_2.27 ynf64 F
 GLIBC_2.28 daddl F
+GLIBC_2.28 dmull F
 GLIBC_2.28 dsubl F
 GLIBC_2.28 f32addf32x F
 GLIBC_2.28 f32addf64 F
+GLIBC_2.28 f32mulf32x F
+GLIBC_2.28 f32mulf64 F
 GLIBC_2.28 f32subf32x F
 GLIBC_2.28 f32subf64 F
 GLIBC_2.28 f32xaddf64 F
+GLIBC_2.28 f32xmulf64 F
 GLIBC_2.28 f32xsubf64 F
 GLIBC_2.28 fadd F
 GLIBC_2.28 faddl F
+GLIBC_2.28 fmul F
+GLIBC_2.28 fmull F
 GLIBC_2.28 fsub F
 GLIBC_2.28 fsubl F
diff --git a/sysdeps/unix/sysv/linux/microblaze/libm.abilist b/sysdeps/unix/sysv/linux/microblaze/libm.abilist
index dab26bc..b410ba2 100644
--- a/sysdeps/unix/sysv/linux/microblaze/libm.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/libm.abilist
@@ -742,14 +742,20 @@  GLIBC_2.27 ynf32 F
 GLIBC_2.27 ynf32x F
 GLIBC_2.27 ynf64 F
 GLIBC_2.28 daddl F
+GLIBC_2.28 dmull F
 GLIBC_2.28 dsubl F
 GLIBC_2.28 f32addf32x F
 GLIBC_2.28 f32addf64 F
+GLIBC_2.28 f32mulf32x F
+GLIBC_2.28 f32mulf64 F
 GLIBC_2.28 f32subf32x F
 GLIBC_2.28 f32subf64 F
 GLIBC_2.28 f32xaddf64 F
+GLIBC_2.28 f32xmulf64 F
 GLIBC_2.28 f32xsubf64 F
 GLIBC_2.28 fadd F
 GLIBC_2.28 faddl F
+GLIBC_2.28 fmul F
+GLIBC_2.28 fmull F
 GLIBC_2.28 fsub F
 GLIBC_2.28 fsubl F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/libm.abilist b/sysdeps/unix/sysv/linux/mips/mips32/libm.abilist
index 4400071..39438e6 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/libm.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/libm.abilist
@@ -741,15 +741,21 @@  GLIBC_2.27 ynf32 F
 GLIBC_2.27 ynf32x F
 GLIBC_2.27 ynf64 F
 GLIBC_2.28 daddl F
+GLIBC_2.28 dmull F
 GLIBC_2.28 dsubl F
 GLIBC_2.28 f32addf32x F
 GLIBC_2.28 f32addf64 F
+GLIBC_2.28 f32mulf32x F
+GLIBC_2.28 f32mulf64 F
 GLIBC_2.28 f32subf32x F
 GLIBC_2.28 f32subf64 F
 GLIBC_2.28 f32xaddf64 F
+GLIBC_2.28 f32xmulf64 F
 GLIBC_2.28 f32xsubf64 F
 GLIBC_2.28 fadd F
 GLIBC_2.28 faddl F
+GLIBC_2.28 fmul F
+GLIBC_2.28 fmull F
 GLIBC_2.28 fsub F
 GLIBC_2.28 fsubl F
 GLIBC_2.4 exp2l F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/libm.abilist b/sysdeps/unix/sysv/linux/mips/mips64/libm.abilist
index bfc16d5..4280f2c 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/libm.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/libm.abilist
@@ -981,11 +981,16 @@  GLIBC_2.27 ynf32x F
 GLIBC_2.27 ynf64 F
 GLIBC_2.27 ynf64x F
 GLIBC_2.28 daddl F
+GLIBC_2.28 dmull F
 GLIBC_2.28 dsubl F
 GLIBC_2.28 f32addf128 F
 GLIBC_2.28 f32addf32x F
 GLIBC_2.28 f32addf64 F
 GLIBC_2.28 f32addf64x F
+GLIBC_2.28 f32mulf128 F
+GLIBC_2.28 f32mulf32x F
+GLIBC_2.28 f32mulf64 F
+GLIBC_2.28 f32mulf64x F
 GLIBC_2.28 f32subf128 F
 GLIBC_2.28 f32subf32x F
 GLIBC_2.28 f32subf64 F
@@ -993,16 +998,24 @@  GLIBC_2.28 f32subf64x F
 GLIBC_2.28 f32xaddf128 F
 GLIBC_2.28 f32xaddf64 F
 GLIBC_2.28 f32xaddf64x F
+GLIBC_2.28 f32xmulf128 F
+GLIBC_2.28 f32xmulf64 F
+GLIBC_2.28 f32xmulf64x F
 GLIBC_2.28 f32xsubf128 F
 GLIBC_2.28 f32xsubf64 F
 GLIBC_2.28 f32xsubf64x F
 GLIBC_2.28 f64addf128 F
 GLIBC_2.28 f64addf64x F
+GLIBC_2.28 f64mulf128 F
+GLIBC_2.28 f64mulf64x F
 GLIBC_2.28 f64subf128 F
 GLIBC_2.28 f64subf64x F
 GLIBC_2.28 f64xaddf128 F
+GLIBC_2.28 f64xmulf128 F
 GLIBC_2.28 f64xsubf128 F
 GLIBC_2.28 fadd F
 GLIBC_2.28 faddl F
+GLIBC_2.28 fmul F
+GLIBC_2.28 fmull F
 GLIBC_2.28 fsub F
 GLIBC_2.28 fsubl F
diff --git a/sysdeps/unix/sysv/linux/nios2/libm.abilist b/sysdeps/unix/sysv/linux/nios2/libm.abilist
index 6b2d3b2..1005468 100644
--- a/sysdeps/unix/sysv/linux/nios2/libm.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libm.abilist
@@ -742,14 +742,20 @@  GLIBC_2.27 ynf32 F
 GLIBC_2.27 ynf32x F
 GLIBC_2.27 ynf64 F
 GLIBC_2.28 daddl F
+GLIBC_2.28 dmull F
 GLIBC_2.28 dsubl F
 GLIBC_2.28 f32addf32x F
 GLIBC_2.28 f32addf64 F
+GLIBC_2.28 f32mulf32x F
+GLIBC_2.28 f32mulf64 F
 GLIBC_2.28 f32subf32x F
 GLIBC_2.28 f32subf64 F
 GLIBC_2.28 f32xaddf64 F
+GLIBC_2.28 f32xmulf64 F
 GLIBC_2.28 f32xsubf64 F
 GLIBC_2.28 fadd F
 GLIBC_2.28 faddl F
+GLIBC_2.28 fmul F
+GLIBC_2.28 fmull F
 GLIBC_2.28 fsub F
 GLIBC_2.28 fsubl F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist
index fc09e32..3110eea 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist
@@ -783,17 +783,24 @@  GLIBC_2.27 ynf32 F
 GLIBC_2.27 ynf32x F
 GLIBC_2.27 ynf64 F
 GLIBC_2.28 __nldbl_daddl F
+GLIBC_2.28 __nldbl_dmull F
 GLIBC_2.28 __nldbl_dsubl F
 GLIBC_2.28 daddl F
+GLIBC_2.28 dmull F
 GLIBC_2.28 dsubl F
 GLIBC_2.28 f32addf32x F
 GLIBC_2.28 f32addf64 F
+GLIBC_2.28 f32mulf32x F
+GLIBC_2.28 f32mulf64 F
 GLIBC_2.28 f32subf32x F
 GLIBC_2.28 f32subf64 F
 GLIBC_2.28 f32xaddf64 F
+GLIBC_2.28 f32xmulf64 F
 GLIBC_2.28 f32xsubf64 F
 GLIBC_2.28 fadd F
 GLIBC_2.28 faddl F
+GLIBC_2.28 fmul F
+GLIBC_2.28 fmull F
 GLIBC_2.28 fsub F
 GLIBC_2.28 fsubl F
 GLIBC_2.4 __clog10l F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist
index 4056219..c3c3879 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist
@@ -782,17 +782,24 @@  GLIBC_2.27 ynf32 F
 GLIBC_2.27 ynf32x F
 GLIBC_2.27 ynf64 F
 GLIBC_2.28 __nldbl_daddl F
+GLIBC_2.28 __nldbl_dmull F
 GLIBC_2.28 __nldbl_dsubl F
 GLIBC_2.28 daddl F
+GLIBC_2.28 dmull F
 GLIBC_2.28 dsubl F
 GLIBC_2.28 f32addf32x F
 GLIBC_2.28 f32addf64 F
+GLIBC_2.28 f32mulf32x F
+GLIBC_2.28 f32mulf64 F
 GLIBC_2.28 f32subf32x F
 GLIBC_2.28 f32subf64 F
 GLIBC_2.28 f32xaddf64 F
+GLIBC_2.28 f32xmulf64 F
 GLIBC_2.28 f32xsubf64 F
 GLIBC_2.28 fadd F
 GLIBC_2.28 faddl F
+GLIBC_2.28 fmul F
+GLIBC_2.28 fmull F
 GLIBC_2.28 fsub F
 GLIBC_2.28 fsubl F
 GLIBC_2.4 __clog10l F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libm-le.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libm-le.abilist
index 511b839..19956e0 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libm-le.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libm-le.abilist
@@ -1021,13 +1021,19 @@  GLIBC_2.27 ynf32x F
 GLIBC_2.27 ynf64 F
 GLIBC_2.27 ynf64x F
 GLIBC_2.28 __nldbl_daddl F
+GLIBC_2.28 __nldbl_dmull F
 GLIBC_2.28 __nldbl_dsubl F
 GLIBC_2.28 daddl F
+GLIBC_2.28 dmull F
 GLIBC_2.28 dsubl F
 GLIBC_2.28 f32addf128 F
 GLIBC_2.28 f32addf32x F
 GLIBC_2.28 f32addf64 F
 GLIBC_2.28 f32addf64x F
+GLIBC_2.28 f32mulf128 F
+GLIBC_2.28 f32mulf32x F
+GLIBC_2.28 f32mulf64 F
+GLIBC_2.28 f32mulf64x F
 GLIBC_2.28 f32subf128 F
 GLIBC_2.28 f32subf32x F
 GLIBC_2.28 f32subf64 F
@@ -1035,16 +1041,24 @@  GLIBC_2.28 f32subf64x F
 GLIBC_2.28 f32xaddf128 F
 GLIBC_2.28 f32xaddf64 F
 GLIBC_2.28 f32xaddf64x F
+GLIBC_2.28 f32xmulf128 F
+GLIBC_2.28 f32xmulf64 F
+GLIBC_2.28 f32xmulf64x F
 GLIBC_2.28 f32xsubf128 F
 GLIBC_2.28 f32xsubf64 F
 GLIBC_2.28 f32xsubf64x F
 GLIBC_2.28 f64addf128 F
 GLIBC_2.28 f64addf64x F
+GLIBC_2.28 f64mulf128 F
+GLIBC_2.28 f64mulf64x F
 GLIBC_2.28 f64subf128 F
 GLIBC_2.28 f64subf64x F
 GLIBC_2.28 f64xaddf128 F
+GLIBC_2.28 f64xmulf128 F
 GLIBC_2.28 f64xsubf128 F
 GLIBC_2.28 fadd F
 GLIBC_2.28 faddl F
+GLIBC_2.28 fmul F
+GLIBC_2.28 fmull F
 GLIBC_2.28 fsub F
 GLIBC_2.28 fsubl F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libm.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libm.abilist
index e14fc55..dc97d82 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libm.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libm.abilist
@@ -461,17 +461,24 @@  GLIBC_2.27 ynf32 F
 GLIBC_2.27 ynf32x F
 GLIBC_2.27 ynf64 F
 GLIBC_2.28 __nldbl_daddl F
+GLIBC_2.28 __nldbl_dmull F
 GLIBC_2.28 __nldbl_dsubl F
 GLIBC_2.28 daddl F
+GLIBC_2.28 dmull F
 GLIBC_2.28 dsubl F
 GLIBC_2.28 f32addf32x F
 GLIBC_2.28 f32addf64 F
+GLIBC_2.28 f32mulf32x F
+GLIBC_2.28 f32mulf64 F
 GLIBC_2.28 f32subf32x F
 GLIBC_2.28 f32subf64 F
 GLIBC_2.28 f32xaddf64 F
+GLIBC_2.28 f32xmulf64 F
 GLIBC_2.28 f32xsubf64 F
 GLIBC_2.28 fadd F
 GLIBC_2.28 faddl F
+GLIBC_2.28 fmul F
+GLIBC_2.28 fmull F
 GLIBC_2.28 fsub F
 GLIBC_2.28 fsubl F
 GLIBC_2.3 _LIB_VERSION D 0x4
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libm.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libm.abilist
index fa672de..e9e623e 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libm.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libm.abilist
@@ -968,11 +968,16 @@  GLIBC_2.27 ynf64 F
 GLIBC_2.27 ynf64x F
 GLIBC_2.27 ynl F
 GLIBC_2.28 daddl F
+GLIBC_2.28 dmull F
 GLIBC_2.28 dsubl F
 GLIBC_2.28 f32addf128 F
 GLIBC_2.28 f32addf32x F
 GLIBC_2.28 f32addf64 F
 GLIBC_2.28 f32addf64x F
+GLIBC_2.28 f32mulf128 F
+GLIBC_2.28 f32mulf32x F
+GLIBC_2.28 f32mulf64 F
+GLIBC_2.28 f32mulf64x F
 GLIBC_2.28 f32subf128 F
 GLIBC_2.28 f32subf32x F
 GLIBC_2.28 f32subf64 F
@@ -980,16 +985,24 @@  GLIBC_2.28 f32subf64x F
 GLIBC_2.28 f32xaddf128 F
 GLIBC_2.28 f32xaddf64 F
 GLIBC_2.28 f32xaddf64x F
+GLIBC_2.28 f32xmulf128 F
+GLIBC_2.28 f32xmulf64 F
+GLIBC_2.28 f32xmulf64x F
 GLIBC_2.28 f32xsubf128 F
 GLIBC_2.28 f32xsubf64 F
 GLIBC_2.28 f32xsubf64x F
 GLIBC_2.28 f64addf128 F
 GLIBC_2.28 f64addf64x F
+GLIBC_2.28 f64mulf128 F
+GLIBC_2.28 f64mulf64x F
 GLIBC_2.28 f64subf128 F
 GLIBC_2.28 f64subf64x F
 GLIBC_2.28 f64xaddf128 F
+GLIBC_2.28 f64xmulf128 F
 GLIBC_2.28 f64xsubf128 F
 GLIBC_2.28 fadd F
 GLIBC_2.28 faddl F
+GLIBC_2.28 fmul F
+GLIBC_2.28 fmull F
 GLIBC_2.28 fsub F
 GLIBC_2.28 fsubl F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist
index f8c32bd..06345a6 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist
@@ -978,13 +978,19 @@  GLIBC_2.27 ynf32x F
 GLIBC_2.27 ynf64 F
 GLIBC_2.27 ynf64x F
 GLIBC_2.28 __nldbl_daddl F
+GLIBC_2.28 __nldbl_dmull F
 GLIBC_2.28 __nldbl_dsubl F
 GLIBC_2.28 daddl F
+GLIBC_2.28 dmull F
 GLIBC_2.28 dsubl F
 GLIBC_2.28 f32addf128 F
 GLIBC_2.28 f32addf32x F
 GLIBC_2.28 f32addf64 F
 GLIBC_2.28 f32addf64x F
+GLIBC_2.28 f32mulf128 F
+GLIBC_2.28 f32mulf32x F
+GLIBC_2.28 f32mulf64 F
+GLIBC_2.28 f32mulf64x F
 GLIBC_2.28 f32subf128 F
 GLIBC_2.28 f32subf32x F
 GLIBC_2.28 f32subf64 F
@@ -992,17 +998,25 @@  GLIBC_2.28 f32subf64x F
 GLIBC_2.28 f32xaddf128 F
 GLIBC_2.28 f32xaddf64 F
 GLIBC_2.28 f32xaddf64x F
+GLIBC_2.28 f32xmulf128 F
+GLIBC_2.28 f32xmulf64 F
+GLIBC_2.28 f32xmulf64x F
 GLIBC_2.28 f32xsubf128 F
 GLIBC_2.28 f32xsubf64 F
 GLIBC_2.28 f32xsubf64x F
 GLIBC_2.28 f64addf128 F
 GLIBC_2.28 f64addf64x F
+GLIBC_2.28 f64mulf128 F
+GLIBC_2.28 f64mulf64x F
 GLIBC_2.28 f64subf128 F
 GLIBC_2.28 f64subf64x F
 GLIBC_2.28 f64xaddf128 F
+GLIBC_2.28 f64xmulf128 F
 GLIBC_2.28 f64xsubf128 F
 GLIBC_2.28 fadd F
 GLIBC_2.28 faddl F
+GLIBC_2.28 fmul F
+GLIBC_2.28 fmull F
 GLIBC_2.28 fsub F
 GLIBC_2.28 fsubl F
 GLIBC_2.4 __clog10l F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist
index 0b88ee7..bc40b6c 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist
@@ -978,13 +978,19 @@  GLIBC_2.27 ynf32x F
 GLIBC_2.27 ynf64 F
 GLIBC_2.27 ynf64x F
 GLIBC_2.28 __nldbl_daddl F
+GLIBC_2.28 __nldbl_dmull F
 GLIBC_2.28 __nldbl_dsubl F
 GLIBC_2.28 daddl F
+GLIBC_2.28 dmull F
 GLIBC_2.28 dsubl F
 GLIBC_2.28 f32addf128 F
 GLIBC_2.28 f32addf32x F
 GLIBC_2.28 f32addf64 F
 GLIBC_2.28 f32addf64x F
+GLIBC_2.28 f32mulf128 F
+GLIBC_2.28 f32mulf32x F
+GLIBC_2.28 f32mulf64 F
+GLIBC_2.28 f32mulf64x F
 GLIBC_2.28 f32subf128 F
 GLIBC_2.28 f32subf32x F
 GLIBC_2.28 f32subf64 F
@@ -992,17 +998,25 @@  GLIBC_2.28 f32subf64x F
 GLIBC_2.28 f32xaddf128 F
 GLIBC_2.28 f32xaddf64 F
 GLIBC_2.28 f32xaddf64x F
+GLIBC_2.28 f32xmulf128 F
+GLIBC_2.28 f32xmulf64 F
+GLIBC_2.28 f32xmulf64x F
 GLIBC_2.28 f32xsubf128 F
 GLIBC_2.28 f32xsubf64 F
 GLIBC_2.28 f32xsubf64x F
 GLIBC_2.28 f64addf128 F
 GLIBC_2.28 f64addf64x F
+GLIBC_2.28 f64mulf128 F
+GLIBC_2.28 f64mulf64x F
 GLIBC_2.28 f64subf128 F
 GLIBC_2.28 f64subf64x F
 GLIBC_2.28 f64xaddf128 F
+GLIBC_2.28 f64xmulf128 F
 GLIBC_2.28 f64xsubf128 F
 GLIBC_2.28 fadd F
 GLIBC_2.28 faddl F
+GLIBC_2.28 fmul F
+GLIBC_2.28 fmull F
 GLIBC_2.28 fsub F
 GLIBC_2.28 fsubl F
 GLIBC_2.4 __clog10l F
diff --git a/sysdeps/unix/sysv/linux/sh/libm.abilist b/sysdeps/unix/sysv/linux/sh/libm.abilist
index 5f2f34b..20a4974 100644
--- a/sysdeps/unix/sysv/linux/sh/libm.abilist
+++ b/sysdeps/unix/sysv/linux/sh/libm.abilist
@@ -741,15 +741,21 @@  GLIBC_2.27 ynf32 F
 GLIBC_2.27 ynf32x F
 GLIBC_2.27 ynf64 F
 GLIBC_2.28 daddl F
+GLIBC_2.28 dmull F
 GLIBC_2.28 dsubl F
 GLIBC_2.28 f32addf32x F
 GLIBC_2.28 f32addf64 F
+GLIBC_2.28 f32mulf32x F
+GLIBC_2.28 f32mulf64 F
 GLIBC_2.28 f32subf32x F
 GLIBC_2.28 f32subf64 F
 GLIBC_2.28 f32xaddf64 F
+GLIBC_2.28 f32xmulf64 F
 GLIBC_2.28 f32xsubf64 F
 GLIBC_2.28 fadd F
 GLIBC_2.28 faddl F
+GLIBC_2.28 fmul F
+GLIBC_2.28 fmull F
 GLIBC_2.28 fsub F
 GLIBC_2.28 fsubl F
 GLIBC_2.4 exp2l F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist
index f31e748..b1364ba 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist
@@ -985,13 +985,19 @@  GLIBC_2.27 ynf32x F
 GLIBC_2.27 ynf64 F
 GLIBC_2.27 ynf64x F
 GLIBC_2.28 __nldbl_daddl F
+GLIBC_2.28 __nldbl_dmull F
 GLIBC_2.28 __nldbl_dsubl F
 GLIBC_2.28 daddl F
+GLIBC_2.28 dmull F
 GLIBC_2.28 dsubl F
 GLIBC_2.28 f32addf128 F
 GLIBC_2.28 f32addf32x F
 GLIBC_2.28 f32addf64 F
 GLIBC_2.28 f32addf64x F
+GLIBC_2.28 f32mulf128 F
+GLIBC_2.28 f32mulf32x F
+GLIBC_2.28 f32mulf64 F
+GLIBC_2.28 f32mulf64x F
 GLIBC_2.28 f32subf128 F
 GLIBC_2.28 f32subf32x F
 GLIBC_2.28 f32subf64 F
@@ -999,17 +1005,25 @@  GLIBC_2.28 f32subf64x F
 GLIBC_2.28 f32xaddf128 F
 GLIBC_2.28 f32xaddf64 F
 GLIBC_2.28 f32xaddf64x F
+GLIBC_2.28 f32xmulf128 F
+GLIBC_2.28 f32xmulf64 F
+GLIBC_2.28 f32xmulf64x F
 GLIBC_2.28 f32xsubf128 F
 GLIBC_2.28 f32xsubf64 F
 GLIBC_2.28 f32xsubf64x F
 GLIBC_2.28 f64addf128 F
 GLIBC_2.28 f64addf64x F
+GLIBC_2.28 f64mulf128 F
+GLIBC_2.28 f64mulf64x F
 GLIBC_2.28 f64subf128 F
 GLIBC_2.28 f64subf64x F
 GLIBC_2.28 f64xaddf128 F
+GLIBC_2.28 f64xmulf128 F
 GLIBC_2.28 f64xsubf128 F
 GLIBC_2.28 fadd F
 GLIBC_2.28 faddl F
+GLIBC_2.28 fmul F
+GLIBC_2.28 fmull F
 GLIBC_2.28 fsub F
 GLIBC_2.28 fsubl F
 GLIBC_2.4 __clog10l F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist
index a3585ce..133d2d3 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist
@@ -981,11 +981,16 @@  GLIBC_2.27 ynf32x F
 GLIBC_2.27 ynf64 F
 GLIBC_2.27 ynf64x F
 GLIBC_2.28 daddl F
+GLIBC_2.28 dmull F
 GLIBC_2.28 dsubl F
 GLIBC_2.28 f32addf128 F
 GLIBC_2.28 f32addf32x F
 GLIBC_2.28 f32addf64 F
 GLIBC_2.28 f32addf64x F
+GLIBC_2.28 f32mulf128 F
+GLIBC_2.28 f32mulf32x F
+GLIBC_2.28 f32mulf64 F
+GLIBC_2.28 f32mulf64x F
 GLIBC_2.28 f32subf128 F
 GLIBC_2.28 f32subf32x F
 GLIBC_2.28 f32subf64 F
@@ -993,16 +998,24 @@  GLIBC_2.28 f32subf64x F
 GLIBC_2.28 f32xaddf128 F
 GLIBC_2.28 f32xaddf64 F
 GLIBC_2.28 f32xaddf64x F
+GLIBC_2.28 f32xmulf128 F
+GLIBC_2.28 f32xmulf64 F
+GLIBC_2.28 f32xmulf64x F
 GLIBC_2.28 f32xsubf128 F
 GLIBC_2.28 f32xsubf64 F
 GLIBC_2.28 f32xsubf64x F
 GLIBC_2.28 f64addf128 F
 GLIBC_2.28 f64addf64x F
+GLIBC_2.28 f64mulf128 F
+GLIBC_2.28 f64mulf64x F
 GLIBC_2.28 f64subf128 F
 GLIBC_2.28 f64subf64x F
 GLIBC_2.28 f64xaddf128 F
+GLIBC_2.28 f64xmulf128 F
 GLIBC_2.28 f64xsubf128 F
 GLIBC_2.28 fadd F
 GLIBC_2.28 faddl F
+GLIBC_2.28 fmul F
+GLIBC_2.28 fmull F
 GLIBC_2.28 fsub F
 GLIBC_2.28 fsubl F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libm.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libm.abilist
index 4f4cc3c..66ab054 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libm.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libm.abilist
@@ -1015,11 +1015,16 @@  GLIBC_2.27 ynf32x F
 GLIBC_2.27 ynf64 F
 GLIBC_2.27 ynf64x F
 GLIBC_2.28 daddl F
+GLIBC_2.28 dmull F
 GLIBC_2.28 dsubl F
 GLIBC_2.28 f32addf128 F
 GLIBC_2.28 f32addf32x F
 GLIBC_2.28 f32addf64 F
 GLIBC_2.28 f32addf64x F
+GLIBC_2.28 f32mulf128 F
+GLIBC_2.28 f32mulf32x F
+GLIBC_2.28 f32mulf64 F
+GLIBC_2.28 f32mulf64x F
 GLIBC_2.28 f32subf128 F
 GLIBC_2.28 f32subf32x F
 GLIBC_2.28 f32subf64 F
@@ -1027,16 +1032,24 @@  GLIBC_2.28 f32subf64x F
 GLIBC_2.28 f32xaddf128 F
 GLIBC_2.28 f32xaddf64 F
 GLIBC_2.28 f32xaddf64x F
+GLIBC_2.28 f32xmulf128 F
+GLIBC_2.28 f32xmulf64 F
+GLIBC_2.28 f32xmulf64x F
 GLIBC_2.28 f32xsubf128 F
 GLIBC_2.28 f32xsubf64 F
 GLIBC_2.28 f32xsubf64x F
 GLIBC_2.28 f64addf128 F
 GLIBC_2.28 f64addf64x F
+GLIBC_2.28 f64mulf128 F
+GLIBC_2.28 f64mulf64x F
 GLIBC_2.28 f64subf128 F
 GLIBC_2.28 f64subf64x F
 GLIBC_2.28 f64xaddf128 F
+GLIBC_2.28 f64xmulf128 F
 GLIBC_2.28 f64xsubf128 F
 GLIBC_2.28 fadd F
 GLIBC_2.28 faddl F
+GLIBC_2.28 fmul F
+GLIBC_2.28 fmull F
 GLIBC_2.28 fsub F
 GLIBC_2.28 fsubl F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist
index 36e8130..9442ef1 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist
@@ -1015,11 +1015,16 @@  GLIBC_2.27 ynf32x F
 GLIBC_2.27 ynf64 F
 GLIBC_2.27 ynf64x F
 GLIBC_2.28 daddl F
+GLIBC_2.28 dmull F
 GLIBC_2.28 dsubl F
 GLIBC_2.28 f32addf128 F
 GLIBC_2.28 f32addf32x F
 GLIBC_2.28 f32addf64 F
 GLIBC_2.28 f32addf64x F
+GLIBC_2.28 f32mulf128 F
+GLIBC_2.28 f32mulf32x F
+GLIBC_2.28 f32mulf64 F
+GLIBC_2.28 f32mulf64x F
 GLIBC_2.28 f32subf128 F
 GLIBC_2.28 f32subf32x F
 GLIBC_2.28 f32subf64 F
@@ -1027,16 +1032,24 @@  GLIBC_2.28 f32subf64x F
 GLIBC_2.28 f32xaddf128 F
 GLIBC_2.28 f32xaddf64 F
 GLIBC_2.28 f32xaddf64x F
+GLIBC_2.28 f32xmulf128 F
+GLIBC_2.28 f32xmulf64 F
+GLIBC_2.28 f32xmulf64x F
 GLIBC_2.28 f32xsubf128 F
 GLIBC_2.28 f32xsubf64 F
 GLIBC_2.28 f32xsubf64x F
 GLIBC_2.28 f64addf128 F
 GLIBC_2.28 f64addf64x F
+GLIBC_2.28 f64mulf128 F
+GLIBC_2.28 f64mulf64x F
 GLIBC_2.28 f64subf128 F
 GLIBC_2.28 f64subf64x F
 GLIBC_2.28 f64xaddf128 F
+GLIBC_2.28 f64xmulf128 F
 GLIBC_2.28 f64xsubf128 F
 GLIBC_2.28 fadd F
 GLIBC_2.28 faddl F
+GLIBC_2.28 fmul F
+GLIBC_2.28 fmull F
 GLIBC_2.28 fsub F
 GLIBC_2.28 fsubl F