Message ID | 20200320205228.18373-1-rzinsly@linux.ibm.com |
---|---|
State | New |
Headers | show |
Series | powerpc: Add support for fmaf128() in hardware | expand |
On 20/03/2020 17:52, Raphael Moreira Zinsly via Libc-alpha wrote: > Adds a POWER9 version of fmaf128 that uses the xsmaddqp > instruction. > > Co-authored-by: Tulio Magno Quites Machado Filho <tuliom@linux.vnet.ibm.com> LGTM, thanks. Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org> > --- > .../powerpc64/le/fpu/multiarch/Makefile | 4 +- > .../le/fpu/multiarch/s_fmaf128-power9.c | 26 +++++++++++++ > .../le/fpu/multiarch/s_fmaf128-ppc64.c | 24 ++++++++++++ > .../powerpc64/le/fpu/multiarch/s_fmaf128.c | 36 ++++++++++++++++++ > .../powerpc64/le/power9/fpu/s_fmaf128.c | 37 +++++++++++++++++++ > 5 files changed, 126 insertions(+), 1 deletion(-) > create mode 100644 sysdeps/powerpc/powerpc64/le/fpu/multiarch/s_fmaf128-power9.c > create mode 100644 sysdeps/powerpc/powerpc64/le/fpu/multiarch/s_fmaf128-ppc64.c > create mode 100644 sysdeps/powerpc/powerpc64/le/fpu/multiarch/s_fmaf128.c > create mode 100644 sysdeps/powerpc/powerpc64/le/power9/fpu/s_fmaf128.c > > diff --git a/sysdeps/powerpc/powerpc64/le/fpu/multiarch/Makefile b/sysdeps/powerpc/powerpc64/le/fpu/multiarch/Makefile > index a32f3d8b81..8db708205e 100644 > --- a/sysdeps/powerpc/powerpc64/le/fpu/multiarch/Makefile > +++ b/sysdeps/powerpc/powerpc64/le/fpu/multiarch/Makefile > @@ -1,6 +1,8 @@ > ifeq ($(subdir),math) > -libm-sysdep_routines += w_sqrtf128-power9 w_sqrtf128-ppc64le > +libm-sysdep_routines += w_sqrtf128-power9 w_sqrtf128-ppc64le s_fmaf128-ppc64 s_fmaf128-power9 > > CFLAGS-w_sqrtf128-ppc64le.c += -mfloat128 > CFLAGS-w_sqrtf128-power9.c += -mfloat128 -mcpu=power9 > +CFLAGS-s_fmaf128-ppc64.c += -mfloat128 > +CFLAGS-s_fmaf128-power9.c += -mfloat128 -mcpu=power9 > endif Ok. > diff --git a/sysdeps/powerpc/powerpc64/le/fpu/multiarch/s_fmaf128-power9.c b/sysdeps/powerpc/powerpc64/le/fpu/multiarch/s_fmaf128-power9.c > new file mode 100644 > index 0000000000..8df77ceade > --- /dev/null > +++ b/sysdeps/powerpc/powerpc64/le/fpu/multiarch/s_fmaf128-power9.c > @@ -0,0 +1,26 @@ > +/* __fmaf128() PowerPC64LE POWER9 version. > + Copyright (C) 2020 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-alias-float128.h> > + > +#undef libm_alias_float128 > +#define libm_alias_float128(a, b) > + > +#define __fmaf128 __fmaf128_power9 > + > +#include <sysdeps/powerpc/powerpc64/le/power9/fpu/s_fmaf128.c> Ok. > diff --git a/sysdeps/powerpc/powerpc64/le/fpu/multiarch/s_fmaf128-ppc64.c b/sysdeps/powerpc/powerpc64/le/fpu/multiarch/s_fmaf128-ppc64.c > new file mode 100644 > index 0000000000..7374a799af > --- /dev/null > +++ b/sysdeps/powerpc/powerpc64/le/fpu/multiarch/s_fmaf128-ppc64.c > @@ -0,0 +1,24 @@ > +/* __fmaf128() PowerPC64LE version. > + Copyright (C) 2020 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/>. */ > + > +#undef weak_alias > +#define weak_alias(a, b) > + > +#define __fmaf128 __fmaf128_ppc64 > + > +#include <sysdeps/ieee754/float128/s_fmaf128.c> Ok. > diff --git a/sysdeps/powerpc/powerpc64/le/fpu/multiarch/s_fmaf128.c b/sysdeps/powerpc/powerpc64/le/fpu/multiarch/s_fmaf128.c > new file mode 100644 > index 0000000000..3a370950f9 > --- /dev/null > +++ b/sysdeps/powerpc/powerpc64/le/fpu/multiarch/s_fmaf128.c > @@ -0,0 +1,36 @@ > +/* Multiple versions of fmaf128. > + Copyright (C) 2020 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-alias-float128.h> > + > +#define fmaf128 __redirect_fmaf128 > +#include <math.h> > +#undef fmaf128 > + > +#include <math_ldbl_opt.h> > +#include "init-arch.h" > + > +extern __typeof (__redirect_fmaf128) __fmaf128_ppc64 attribute_hidden; > +extern __typeof (__redirect_fmaf128) __fmaf128_power9 attribute_hidden; > + > +libc_ifunc_redirected (__redirect_fmaf128, __fmaf128, > + (hwcap2 & PPC_FEATURE2_HAS_IEEE128) > + ? __fmaf128_power9 > + : __fmaf128_ppc64); > + > +libm_alias_float128 (__fma, fma) Ok. > diff --git a/sysdeps/powerpc/powerpc64/le/power9/fpu/s_fmaf128.c b/sysdeps/powerpc/powerpc64/le/power9/fpu/s_fmaf128.c > new file mode 100644 > index 0000000000..ecd30f1cef > --- /dev/null > +++ b/sysdeps/powerpc/powerpc64/le/power9/fpu/s_fmaf128.c > @@ -0,0 +1,37 @@ > +/* Compute x * y + z as a ternary operation for _Float128. POWER9 version. > + Copyright (C) 2020 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. > + > + In addition to the permissions in the GNU Lesser General Public > + License, the Free Software Foundation gives you unlimited > + permission to link the compiled version of this file into > + combinations with other programs, and to distribute those > + combinations without any restriction coming from the use of this > + file. (The Lesser General Public License restrictions do apply in > + other respects; for example, they cover modification of the file, > + and distribution when not linked into a combine executable.) > + > + 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-alias-float128.h> > + > +__float128 > +__fmaf128 (__float128 x, __float128 y, __float128 z) > +{ > + asm ("xsmaddqp\t%0, %1, %2" : "+v" (z) : "v" (x), "v" (y)); > + return z; > +} > + > +libm_alias_float128 (__fma, fma) > I think you can 'x * y + z' here, at least GCC 6 optimizes it correctly [1]. [1] https://godbolt.org/z/pHSdDN
Adhemerval Zanella via Libc-alpha <libc-alpha@sourceware.org> writes: > On 20/03/2020 17:52, Raphael Moreira Zinsly via Libc-alpha wrote: >> +__float128 >> +__fmaf128 (__float128 x, __float128 y, __float128 z) >> +{ >> + asm ("xsmaddqp\t%0, %1, %2" : "+v" (z) : "v" (x), "v" (y)); >> + return z; >> +} >> + >> +libm_alias_float128 (__fma, fma) >> > I think you can 'x * y + z' here, at least GCC 6 optimizes it correctly [1]. Changed. Pushed as 66807aebadc4a8cf62a9593ab3f714f971366907. Thanks!
diff --git a/sysdeps/powerpc/powerpc64/le/fpu/multiarch/Makefile b/sysdeps/powerpc/powerpc64/le/fpu/multiarch/Makefile index a32f3d8b81..8db708205e 100644 --- a/sysdeps/powerpc/powerpc64/le/fpu/multiarch/Makefile +++ b/sysdeps/powerpc/powerpc64/le/fpu/multiarch/Makefile @@ -1,6 +1,8 @@ ifeq ($(subdir),math) -libm-sysdep_routines += w_sqrtf128-power9 w_sqrtf128-ppc64le +libm-sysdep_routines += w_sqrtf128-power9 w_sqrtf128-ppc64le s_fmaf128-ppc64 s_fmaf128-power9 CFLAGS-w_sqrtf128-ppc64le.c += -mfloat128 CFLAGS-w_sqrtf128-power9.c += -mfloat128 -mcpu=power9 +CFLAGS-s_fmaf128-ppc64.c += -mfloat128 +CFLAGS-s_fmaf128-power9.c += -mfloat128 -mcpu=power9 endif diff --git a/sysdeps/powerpc/powerpc64/le/fpu/multiarch/s_fmaf128-power9.c b/sysdeps/powerpc/powerpc64/le/fpu/multiarch/s_fmaf128-power9.c new file mode 100644 index 0000000000..8df77ceade --- /dev/null +++ b/sysdeps/powerpc/powerpc64/le/fpu/multiarch/s_fmaf128-power9.c @@ -0,0 +1,26 @@ +/* __fmaf128() PowerPC64LE POWER9 version. + Copyright (C) 2020 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-alias-float128.h> + +#undef libm_alias_float128 +#define libm_alias_float128(a, b) + +#define __fmaf128 __fmaf128_power9 + +#include <sysdeps/powerpc/powerpc64/le/power9/fpu/s_fmaf128.c> diff --git a/sysdeps/powerpc/powerpc64/le/fpu/multiarch/s_fmaf128-ppc64.c b/sysdeps/powerpc/powerpc64/le/fpu/multiarch/s_fmaf128-ppc64.c new file mode 100644 index 0000000000..7374a799af --- /dev/null +++ b/sysdeps/powerpc/powerpc64/le/fpu/multiarch/s_fmaf128-ppc64.c @@ -0,0 +1,24 @@ +/* __fmaf128() PowerPC64LE version. + Copyright (C) 2020 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/>. */ + +#undef weak_alias +#define weak_alias(a, b) + +#define __fmaf128 __fmaf128_ppc64 + +#include <sysdeps/ieee754/float128/s_fmaf128.c> diff --git a/sysdeps/powerpc/powerpc64/le/fpu/multiarch/s_fmaf128.c b/sysdeps/powerpc/powerpc64/le/fpu/multiarch/s_fmaf128.c new file mode 100644 index 0000000000..3a370950f9 --- /dev/null +++ b/sysdeps/powerpc/powerpc64/le/fpu/multiarch/s_fmaf128.c @@ -0,0 +1,36 @@ +/* Multiple versions of fmaf128. + Copyright (C) 2020 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-alias-float128.h> + +#define fmaf128 __redirect_fmaf128 +#include <math.h> +#undef fmaf128 + +#include <math_ldbl_opt.h> +#include "init-arch.h" + +extern __typeof (__redirect_fmaf128) __fmaf128_ppc64 attribute_hidden; +extern __typeof (__redirect_fmaf128) __fmaf128_power9 attribute_hidden; + +libc_ifunc_redirected (__redirect_fmaf128, __fmaf128, + (hwcap2 & PPC_FEATURE2_HAS_IEEE128) + ? __fmaf128_power9 + : __fmaf128_ppc64); + +libm_alias_float128 (__fma, fma) diff --git a/sysdeps/powerpc/powerpc64/le/power9/fpu/s_fmaf128.c b/sysdeps/powerpc/powerpc64/le/power9/fpu/s_fmaf128.c new file mode 100644 index 0000000000..ecd30f1cef --- /dev/null +++ b/sysdeps/powerpc/powerpc64/le/power9/fpu/s_fmaf128.c @@ -0,0 +1,37 @@ +/* Compute x * y + z as a ternary operation for _Float128. POWER9 version. + Copyright (C) 2020 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. + + In addition to the permissions in the GNU Lesser General Public + License, the Free Software Foundation gives you unlimited + permission to link the compiled version of this file into + combinations with other programs, and to distribute those + combinations without any restriction coming from the use of this + file. (The Lesser General Public License restrictions do apply in + other respects; for example, they cover modification of the file, + and distribution when not linked into a combine executable.) + + 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-alias-float128.h> + +__float128 +__fmaf128 (__float128 x, __float128 y, __float128 z) +{ + asm ("xsmaddqp\t%0, %1, %2" : "+v" (z) : "v" (x), "v" (y)); + return z; +} + +libm_alias_float128 (__fma, fma)