From patchwork Mon Feb 18 23:45:13 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: GT X-Patchwork-Id: 31516 Received: (qmail 86246 invoked by alias); 18 Feb 2019 23:45:42 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 85776 invoked by uid 89); 18 Feb 2019 23:45:33 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-27.6 required=5.0 tests=BAYES_00, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_LOW, SPF_HELO_PASS, SPF_PASS autolearn=ham version=3.3.2 spammy=distributed X-HELO: mail-40133.protonmail.ch Date: Mon, 18 Feb 2019 23:45:13 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=default; t=1550533522; bh=JFeje+oQPZ0OvKPKYQaGX6kOwfWX1J/kV2IrQgDfRu4=; h=Date:To:From:Reply-To:Subject:Feedback-ID:From; b=A6HS8o8VhXUHhC8FaMKLimUjKo5fRiN9iGXSns+JlU9S6RCrqbqqbW0VbB0UeeJyL 5dFZHDfR+p/rRgVOL/XdvvRu7gZO3EoIaTQMM2aoUtJU+Kg/910uUVnZrZK6Uy4EYn bV1n9mxvrETm1IjSFqbM/FpMUIDn3e5KoGi7Diwg= To: "libc-alpha@sourceware.org" From: GT Reply-To: GT Subject: First in the series of patches implementing POWER8 vector math. Message-ID: MIME-Version: 1.0 Empty Message From 65fda4d67a61d7ae19e53001855cd4482e2bf59e Mon Sep 17 00:00:00 2001 From: Bert Tenjy Date: Mon, 18 Feb 2019 23:24:46 +0000 Subject: [PATCH] PPC64: First in the series of patches implementing POWER8 vector math. Implements double-precision cosine using VSX vector capability. Algorithm for cosine is from x86_64 [commit #2193311288] adapted to PPC64. Name-mangling exactly duplicates SSE ISA of the x86_64 ABI. The details are at . Adds tests of the new double-precision vector cosine. [BZ #24205] --- ChangeLog | 16 ++++ sysdeps/powerpc/bits/math-vector.h | 41 ++++++++ sysdeps/powerpc/fpu/libm-test-ulps | 3 + sysdeps/powerpc/powerpc64/fpu/Versions | 5 + .../powerpc/powerpc64/fpu/multiarch/Makefile | 17 ++++ .../multiarch/test-double-vlen2-wrappers.c | 24 +++++ .../powerpc64/fpu/multiarch/vec_d_cos2_core.c | 30 ++++++ .../fpu/multiarch/vec_d_cos2_power8.c | 93 +++++++++++++++++++ .../powerpc64/fpu/multiarch/vec_d_cos2_vmx.c | 35 +++++++ .../powerpc64/fpu/multiarch/vec_d_trig_data.h | 61 ++++++++++++ .../linux/powerpc/powerpc64/libmvec.abilist | 1 + 11 files changed, 326 insertions(+) create mode 100644 sysdeps/powerpc/bits/math-vector.h create mode 100644 sysdeps/powerpc/powerpc64/fpu/Versions create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/test-double-vlen2-wrappers.c create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/vec_d_cos2_core.c create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/vec_d_cos2_power8.c create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/vec_d_cos2_vmx.c create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/vec_d_trig_data.h create mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc64/libmvec.abilist diff --git a/ChangeLog b/ChangeLog index 312ef3bd8f..ccdd855136 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2019-02-18 + + * sysdeps/powerpc/bits/math-vector.h: New file. + * sysdeps/powerpc/fpu/libm-test-ulps (cos_vlen2): Regenerated. + * sysdeps/powerpc/powerpc64/fpu/Versions: New file. + * sysdeps/powerpc/powerpc64/multiarch/Makefile (libmvec-sysdep_routines) + (double-vlen-funcs,double-vlen-arch-ext-flags): Added build of VSX + vector cos function and its tests. + * sysdeps/powerpc/powerpc64/multiarch/test-double-vlen2-wrappers.c: New file. + * sysdeps/powerpc/powerpc64/multiarch/vec_d_cos2_core.c: New file. + * sysdeps/powerpc/powerpc64/multiarch/vec_d_cos2_power8.c: New file. + * sysdeps/powerpc/powerpc64/multiarch/vec_d_cos2_vmx.c: New file. + * sysdeps/powerpc/powerpc64/multiarch/vec_d_trig_data.h: New file. + * sysdeps/unix/sysv/linux/powerpc/powerpc64/libmvec.abilist: New file. + + 2019-02-18 Florian Weimer * resolv/compat-gethnamaddr.c (Dprintf): Remove definition. diff --git a/sysdeps/powerpc/bits/math-vector.h b/sysdeps/powerpc/bits/math-vector.h new file mode 100644 index 0000000000..a569b19e7a --- /dev/null +++ b/sysdeps/powerpc/bits/math-vector.h @@ -0,0 +1,41 @@ +/* Platform-specific SIMD declarations of math functions. + Copyright (C) 2019 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 + . */ + +#ifndef _MATH_H +# error "Never include directly;\ + include instead." +#endif + +/* Get default empty definitions for simd declarations. */ +#include + +#if defined __POWERPC64__ && defined __FAST_MATH__ +# if defined _OPENMP && _OPENMP >= 201307 +/* OpenMP case. */ +# define __DECL_SIMD_ARCH_PPC64 _Pragma ("omp declare simd notinbranch") +# elif __GNUC_PREREQ (6,0) +/* W/o OpenMP use GCC 6.* __attribute__ ((__simd__)). */ +# define __DECL_SIMD_ARCH_PPC64 __attribute__ ((__simd__ ("notinbranch"))) +# endif + +# ifdef __DECL_SIMD_ARCH_PPC64 +# undef __DECL_SIMD_cos +# define __DECL_SIMD_cos __DECL_SIMD_ARCH_PPC64 + +# endif +#endif diff --git a/sysdeps/powerpc/fpu/libm-test-ulps b/sysdeps/powerpc/fpu/libm-test-ulps index 1eec27c1dc..d392b135a7 100644 --- a/sysdeps/powerpc/fpu/libm-test-ulps +++ b/sysdeps/powerpc/fpu/libm-test-ulps @@ -1311,6 +1311,9 @@ ifloat128: 2 ildouble: 5 ldouble: 5 +Function: "cos_vlen2": +double: 2 + Function: "cosh": double: 1 float: 1 diff --git a/sysdeps/powerpc/powerpc64/fpu/Versions b/sysdeps/powerpc/powerpc64/fpu/Versions new file mode 100644 index 0000000000..9a3e1211cc --- /dev/null +++ b/sysdeps/powerpc/powerpc64/fpu/Versions @@ -0,0 +1,5 @@ +libmvec { + GLIBC_2.30 { + _ZGVbN2v_cos; + } +} diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile index 39b557604c..51e89a2532 100644 --- a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile +++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile @@ -42,3 +42,20 @@ CFLAGS-e_hypotf-power7.c = -mcpu=power7 CFLAGS-s_modf-ppc64.c += -fsignaling-nans CFLAGS-s_modff-ppc64.c += -fsignaling-nans endif + +ifeq ($(subdir),mathvec) +libmvec-sysdep_routines += vec_d_cos2_core vec_d_cos2_power8 \ + vec_d_cos2_vmx +endif + +# Variables for libmvec tests. +ifeq ($(subdir),math) +ifeq ($(build-mathvec),yes) +libmvec-tests += double-vlen2 + +double-vlen2-funcs = cos + +double-vlen2-arch-ext-cflags = -mvsx + +endif +endif diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/test-double-vlen2-wrappers.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/test-double-vlen2-wrappers.c new file mode 100644 index 0000000000..17e2cc0724 --- /dev/null +++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/test-double-vlen2-wrappers.c @@ -0,0 +1,24 @@ +/* Wrapper part of tests for VSX ISA versions of vector math functions. + Copyright (C) 2019 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 + . */ + +#include "test-double-vlen2.h" +#include + +#define VEC_TYPE vector double + +VECTOR_WRAPPER (WRAPPER_NAME (cos), _ZGVbN2v_cos) diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/vec_d_cos2_core.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/vec_d_cos2_core.c new file mode 100644 index 0000000000..e089a8d844 --- /dev/null +++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/vec_d_cos2_core.c @@ -0,0 +1,30 @@ +/* Multiple versions of vectorized cos function. + Copyright (C) 2019 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 + . */ + +#include +#include +#include "init-arch.h" + +vector double _ZGVbN2v_cos (vector double x); + +extern __typeof (_ZGVbN2v_cos) _ZGVbN2v_cos_vmx attribute_hidden; +extern __typeof (_ZGVbN2v_cos) _ZGVbN2v_cos_vsx attribute_hidden; + +libc_ifunc (_ZGVbN2v_cos, + (hwcap2 & PPC_FEATURE2_ARCH_2_07) + ? _ZGVbN2v_cos_vsx : _ZGVbN2v_cos_vmx); diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/vec_d_cos2_power8.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/vec_d_cos2_power8.c new file mode 100644 index 0000000000..4f6c9cce6b --- /dev/null +++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/vec_d_cos2_power8.c @@ -0,0 +1,93 @@ +/* Function cos vectorized with VSX. + Copyright (C) 2019 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 + . */ + +#include +#include "vec_d_trig_data.h" + +vector double +_ZGVbN2v_cos_vsx (vector double x) +{ + +/* + ARGUMENT RANGE REDUCTION: + Add Pi/2 to argument: X' = X+Pi/2 + */ + vector double x_prime = (vector double) d_half_pi + x; + +/* Get absolute argument value: X' = |X'| */ + vector double abs_x_prime = vec_abs (x_prime); + +/* Y = X'*InvPi + RS : right shifter add */ + vector double y = (x_prime * d_inv_pi) + d_rshifter; + +/* Check for large arguments path */ + vector bool long long large_in = vec_cmpgt (abs_x_prime, d_rangeval); + +/* N = Y - RS : right shifter sub */ + vector double n = y - d_rshifter; + +/* SignRes = Y<<63 : shift LSB to MSB place for result sign */ + vector double sign_res = (vector double) vec_sl ((vector long long) y, + (vector unsigned long long) + vec_splats (63)); + +/* N = N - 0.5 */ + n = n - d_one_half; + +/* R = X - N*Pi1 */ + vector double r = x - (n * d_pi1_fma); + +/* R = R - N*Pi2 */ + r = r - (n * d_pi2_fma); + +/* R = R - N*Pi3 */ + r = r - (n * d_pi3_fma); + +/* R2 = R*R */ + vector double r2 = r * r; + +/* Poly = C3+R2*(C4+R2*(C5+R2*(C6+R2*C7))) */ + vector double poly = r2 * d_coeff7 + d_coeff6; + poly = poly * r2 + d_coeff5; + poly = poly * r2 + d_coeff4; + poly = poly * r2 + d_coeff3; + +/* Poly = R+R*(R2*(C1+R2*(C2+R2*Poly))) */ + poly = poly * r2 + d_coeff2; + poly = poly * r2 + d_coeff1; + poly = poly * r2 * r + r; + +/* + RECONSTRUCTION: + Final sign setting: Res = Poly^SignRes */ + vector double out + = (vector double) ((vector long long) poly ^ (vector long long) sign_res); + + if (large_in[0] != 0) + { + out[0] = cos (x[0]); + } + + if (large_in[1] != 0) + { + out[1] = cos (x[1]); + } + + return out; + +} /* _ZGVbN2v_cos_vsx */ diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/vec_d_cos2_vmx.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/vec_d_cos2_vmx.c new file mode 100644 index 0000000000..e32fd77b6c --- /dev/null +++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/vec_d_cos2_vmx.c @@ -0,0 +1,35 @@ +/* PowerPC64 default version of vectorized cos function. + Calls scalar cos version twice. + + Copyright (C) 2019 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 + . */ + +#include +#include + +vector double +_ZGVbN2v_cos_vmx (vector double x) +{ + + vector double out; + + out[0] = cos (x[0]); + out[1] = cos (x[1]); + + return out; + +} // _ZGVbN2v_cos_vmx diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/vec_d_trig_data.h b/sysdeps/powerpc/powerpc64/fpu/multiarch/vec_d_trig_data.h new file mode 100644 index 0000000000..ae33017324 --- /dev/null +++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/vec_d_trig_data.h @@ -0,0 +1,61 @@ +/* Constants used in polynomail approximations for vectorized sin, cos, + and sincos functions. + Copyright (C) 2019 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 + . */ + +#ifndef D_TRIG_DATA_H +#define D_TRIG_DATA_H + +#include + +/* PI/2 */ +const vector double d_half_pi = {0x1.921fb54442d18p+0, 0x1.921fb54442d18p+0}; + +/* 1/PI */ +const vector double d_inv_pi = {0x1.45f306dc9c883p-2, 0x1.45f306dc9c883p-2}; + +/* right-shifter constant */ +const vector double d_rshifter = {0x1.8p+52, 0x1.8p+52}; + +/* working range threshold */ +const vector double d_rangeval = {0x1p+23, 0x1p+23}; + +/* 0.5 */ +const vector double d_one_half = {0x1p-1, 0x1p-1}; + +/* Range reduction PI-based constants if FMA available: + PI high part (FMA available) + */ +const vector double d_pi1_fma = {0x1.921fb54442d18p+1, 0x1.921fb54442d18p+1}; + +/* PI mid part (FMA available) */ +const vector double d_pi2_fma = {0x1.1a62633145c06p-53, 0x1.1a62633145c06p-53}; + +/* PI low part (FMA available) */ +const vector double d_pi3_fma += {0x1.c1cd129024e09p-106,0x1.c1cd129024e09p-106}; + +/* Polynomial coefficients (relative error 2^(-52.115)): */ +const vector double d_coeff7 = {-0x1.9f0d60811aac8p-41,-0x1.9f0d60811aac8p-41}; +const vector double d_coeff6 = {0x1.60e6857a2f22p-33,0x1.60e6857a2f22p-33}; +const vector double d_coeff5 = {-0x1.ae63546002231p-26,-0x1.ae63546002231p-26}; +const vector double d_coeff4 = {0x1.71de38030feap-19,0x1.71de38030feap-19}; +const vector double d_coeff3 = {-0x1.a01a019a5b86dp-13,-0x1.a01a019a5b86dp-13}; +const vector double d_coeff2 = {0x1.111111110a4a8p-7,0x1.111111110a4a8p-7}; +const vector double d_coeff1 = {-0x1.55555555554a7p-3,-0x1.55555555554a7p-3}; + +#endif // D_TRIG_DATA_H diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libmvec.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libmvec.abilist new file mode 100644 index 0000000000..656ce0541f --- /dev/null +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libmvec.abilist @@ -0,0 +1 @@ +GLIBC_2.30 _ZGVbN2v_cos F -- 2.20.1