This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[RFC] Support for type-generic libm function implementations libm
- From: "Paul E. Murphy" <murphyp at linux dot vnet dot ibm dot com>
- To: "libc-alpha at sourceware dot org" <libc-alpha at sourceware dot org>
- Date: Tue, 14 Jun 2016 15:40:42 -0500
- Subject: [RFC] Support for type-generic libm function implementations libm
- Authentication-results: sourceware.org; auth=none
This builds from https://sourceware.org/ml/libc-alpha/2016-06/msg00550.html
to further tweak the math Makefile.
As it stands, there is much duplication when building
wrappers for IEEE functions and complex functions.
With a little creativity, this can reduce much
redundant source, and simplify supporting new types.
Only two platforms (alpha and m68k) override complex
functions. Both should work with the approach.
---8<---
This defines two new classes of libm objects. g for
generated objects, and t for templates to generate
those objects.
As a simple example, carg is converted to use this
new infrastructure.
This uses some makefile hackery to generate g_*
objects from from the base t_*.c. The intent is to
convert most or all of the complex function wrappers,
possibly even the wrappers for the e functions.
The only interesting gotcha's are alpha and m68k
which override an interesting subset of the complex
functions. m68k conversions should be fairly trivial,
as they already use a similar approach to what is
done here. Likewise, alpha requires legacy support
for an older ABI for complex floats. This mechanism
can also be used there too.
Note, I have not tested this on alpha. If anyone can
assist me in testing (or just point out a reasonable
mechanism to do it myself) it would be much
appreciated. Likewise for m68k.
* math/Makefile: Add support for routines generated
via a macroed template file.
(gen-libm-calls): New variable.
(gen-suffixes): Likewise.
(CPPFLAGS-mtype_l): Likewise.
(CPPFLAGS-mtype_): Likewise.
(CPPFLAGS-mtype_f): Likewise.
* math/carg.c: Refactor using new template infrastructe.
* math/math-type-macros.h: New file.
* math/cargf.c: Removed.
* math/cargl.c: Removed.
* sysdeps/alpha/fpu/cargf.c: Refactor into
* sysdeps/alpha/fpu/t_carg.c: New file.
---
math/Makefile | 38 ++++++++++++++++++++++++++++++-
math/carg.c | 32 --------------------------
math/cargf.c | 28 -----------------------
math/cargl.c | 28 -----------------------
math/math-type-macros.h | 57 ++++++++++++++++++++++++++++++++++++++++++++++
math/t_carg.c | 30 ++++++++++++++++++++++++
sysdeps/alpha/fpu/cargf.c | 41 ---------------------------------
sysdeps/alpha/fpu/t_carg.c | 49 +++++++++++++++++++++++++++++++++++++++
8 files changed, 173 insertions(+), 130 deletions(-)
delete mode 100644 math/carg.c
delete mode 100644 math/cargf.c
delete mode 100644 math/cargl.c
create mode 100644 math/math-type-macros.h
create mode 100644 math/t_carg.c
delete mode 100644 sysdeps/alpha/fpu/cargf.c
create mode 100644 sysdeps/alpha/fpu/t_carg.c
diff --git a/math/Makefile b/math/Makefile
index 9d18ade..f19cdfd 100644
--- a/math/Makefile
+++ b/math/Makefile
@@ -43,6 +43,12 @@ libm-support = s_lib_version s_matherr s_signgam \
fesetenv feupdateenv t_exp fedisblxcpt feenablxcpt \
fegetexcept
+# These functions are generated from a common source with a select macros
+# for each type they built for. There is an explicit underscore between
+# the function name and the type suffix to simplify matching to the
+# rule used to build it. These all build from a common t_func.c file.
+gen-libm-calls = g_carg_F
+
libm-calls = e_acosF e_acoshF e_asinF e_atan2F e_atanhF e_coshF e_expF e_fmodF \
e_hypotF e_j0F e_j1F e_jnF e_lgammaF_r e_logF e_log10F e_powF \
e_rem_pio2F e_remainderF e_scalbF e_sinhF e_sqrtF e_gammaF_r \
@@ -58,12 +64,13 @@ libm-calls = e_acosF e_acoshF e_asinF e_atan2F e_atanhF e_coshF e_expF e_fmodF \
w_ilogbF \
s_fpclassifyF s_fmaxF s_fminF s_fdimF s_nanF s_truncF \
s_remquoF e_log2F e_exp2F s_roundF s_nearbyintF s_sincosF \
- conjF cimagF crealF cabsF cargF s_cexpF s_csinhF s_ccoshF s_clogF \
+ conjF cimagF crealF cabsF s_cexpF s_csinhF s_ccoshF s_clogF \
s_catanF s_casinF s_ccosF s_csinF s_ctanF s_ctanhF s_cacosF \
s_casinhF s_cacoshF s_catanhF s_csqrtF s_cpowF s_cprojF s_clog10F \
s_fmaF s_lrintF s_llrintF s_lroundF s_llroundF e_exp10F w_log2F \
s_issignalingF $(calls:s_%=m_%) x2y2m1F k_casinhF \
gamma_productF k_standardF lgamma_negF lgamma_productF \
+ $(gen-libm-calls)
libm-compat-calls = w_lgamma_compatf w_lgamma_compat w_lgamma_compatl
@@ -114,6 +121,9 @@ calls = s_isinfF s_isnanF s_finiteF s_copysignF s_modfF s_scalbnF s_frexpF \
generated += $(foreach s,.c .S,$(call type-foreach, $(calls:s_%=m_%)))
routines = $(call type-foreach, $(calls))
+# Wrappers and what not are generated per type to keep the noise down.
+generated += $(foreach g,.c .S,$(call type-foreach, $(gen-libm-calls)))
+
ifeq ($(build-mathvec),yes)
# We need to install libm.so as linker script
# for more comfortable use of vector math library.
@@ -301,6 +311,32 @@ endef
object-suffixes-left := $(all-object-suffixes)
include $(o-iterator)
+# Generated per-type files.
+#
+# Suffixes for each generated file. This hackery makes it possible
+# to correctly identify name of the templated file.
+gen-suffixes := $(foreach s,$(all-object-suffixes), \
+ $(foreach t,$(types),_$(type-$(t)-suffix)$s))
+
+# Declare the type for each build of the type-generic files.
+CPPFLAGS-mtype_l = -DM_TYPE=M_LDOUBLE
+CPPFLAGS-mtype_ = -DM_TYPE=M_DOUBLE
+CPPFLAGS-mtype_f = -DM_TYPE=M_FLOAT
+
+# One rule to build to them all.
+define o-iterator-doit
+$(objpfx)g_%$o: t_%.c $(before-compile); $$(compile-command.c)
+endef
+object-suffixes-left := $(gen-suffixes)
+include $(o-iterator)
+
+# And anther one to pass in the extra cpp flags to build them
+# correctly.
+define o-iterator-doit
+$(objpfx)g_%$o: CPPFLAGS += $(CPPFLAGS-mtype$(basename $o))
+endef
+object-suffixes-left := $(gen-suffixes)
+include $(o-iterator)
# This file defines the default _LIB_VERSION variable that controls
# the error return conventions for the math functions.
diff --git a/math/carg.c b/math/carg.c
deleted file mode 100644
index 61f1e0d..0000000
--- a/math/carg.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/* Compute argument of complex double value.
- Copyright (C) 1997-2016 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
-
- 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 <complex.h>
-#include <math.h>
-
-double
-__carg (__complex__ double x)
-{
- return __atan2 (__imag__ x, __real__ x);
-}
-weak_alias (__carg, carg)
-#ifdef NO_LONG_DOUBLE
-strong_alias (__carg, __cargl)
-weak_alias (__carg, cargl)
-#endif
diff --git a/math/cargf.c b/math/cargf.c
deleted file mode 100644
index 620db3e..0000000
--- a/math/cargf.c
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Compute argument of complex float value.
- Copyright (C) 1997-2016 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
-
- 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 <complex.h>
-#include <math.h>
-
-float
-__cargf (__complex__ float x)
-{
- return __atan2f (__imag__ x, __real__ x);
-}
-weak_alias (__cargf, cargf)
diff --git a/math/cargl.c b/math/cargl.c
deleted file mode 100644
index 31b7292..0000000
--- a/math/cargl.c
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Compute argument of complex long double value.
- Copyright (C) 1997-2016 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
-
- 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 <complex.h>
-#include <math.h>
-
-long double
-__cargl (__complex__ long double x)
-{
- return __atan2l (__imag__ x, __real__ x);
-}
-weak_alias (__cargl, cargl)
diff --git a/math/math-type-macros.h b/math/math-type-macros.h
new file mode 100644
index 0000000..a80bb18
--- /dev/null
+++ b/math/math-type-macros.h
@@ -0,0 +1,57 @@
+/* Helper macros for type generic function implementations within libm.
+ Copyright (C) 2016 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/>. */
+
+#ifndef _MATH_TYPE_MACROS
+#define _MATH_TYPE_MACROS
+
+#define M_FLOAT 1
+#define M_DOUBLE 2
+#define M_LDOUBLE 3
+
+#if M_TYPE == M_FLOAT
+# define M_PFX FLT
+# define M_LIT f
+# define M_SUF(c) c ## f
+# define FLOAT float
+#elif M_TYPE == M_DOUBLE
+# define M_PFX DBL
+# define M_LIT
+# define M_SUF(c) c
+# define FLOAT double
+#elif M_TYPE == M_LDOUBLE
+# define M_PFX LDBL
+# define M_LIT L
+# define M_SUF(c) c ## l
+# define FLOAT long double
+#else
+# error Error: M_TYPE must be defined before including
+#endif
+
+/* Optional long double aliasing for targets without a distinct
+ long double type. */
+#if M_TYPE == M_DOUBLE && defined NO_LONG_DOUBLE
+# define declare_mgen_alias(from, to) \
+ weak_alias (from, to ## l) \
+ strong_alias (from, to ## l) \
+ weak_alias (from, to ## l)
+#else
+# define declare_mgen_alias(from, to) \
+ weak_alias (M_SUF (from), M_SUF (to))
+#endif
+
+#endif
diff --git a/math/t_carg.c b/math/t_carg.c
new file mode 100644
index 0000000..4bf6e53
--- /dev/null
+++ b/math/t_carg.c
@@ -0,0 +1,30 @@
+/* Compute argument of complex float type.
+ Copyright (C) 1997-2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ 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 <complex.h>
+#include <math.h>
+
+#include "math-type-macros.h"
+
+FLOAT
+M_SUF (__carg) (__complex__ FLOAT x)
+{
+ return M_SUF (__atan2) (__imag__ x, __real__ x);
+}
+declare_mgen_alias (__carg, carg)
diff --git a/sysdeps/alpha/fpu/cargf.c b/sysdeps/alpha/fpu/cargf.c
deleted file mode 100644
index d798a5b..0000000
--- a/sysdeps/alpha/fpu/cargf.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Compute argument of complex float value.
- Copyright (C) 2004-2016 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 __cargf __cargf_not_defined
-#define cargf cargf_not_defined
-
-#include <complex.h>
-#include <math.h>
-#include "cfloat-compat.h"
-
-#undef __cargf
-#undef cargf
-
-float
-__c1_cargf (c1_cfloat_decl (x))
-{
- return __atan2f (c1_cfloat_imag (x), c1_cfloat_real (x));
-}
-
-float
-__c2_cargf (c2_cfloat_decl (x))
-{
- return __atan2f (c2_cfloat_imag (x), c2_cfloat_real (x));
-}
-
-cfloat_versions (cargf);
diff --git a/sysdeps/alpha/fpu/t_carg.c b/sysdeps/alpha/fpu/t_carg.c
new file mode 100644
index 0000000..3f5619b
--- /dev/null
+++ b/sysdeps/alpha/fpu/t_carg.c
@@ -0,0 +1,49 @@
+/* Compute argument of complex float value.
+ Copyright (C) 2004-2016 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-type-macros.h"
+
+#if M_TYPE == M_FLOAT
+
+# define __cargf __cargf_not_defined
+# define cargf cargf_not_defined
+
+# include <complex.h>
+# include <math.h>
+# include "cfloat-compat.h"
+
+# undef __cargf
+# undef cargf
+
+float
+__c1_cargf (c1_cfloat_decl (x))
+{
+ return __atan2f (c1_cfloat_imag (x), c1_cfloat_real (x));
+}
+
+float
+__c2_cargf (c2_cfloat_decl (x))
+{
+ return __atan2f (c2_cfloat_imag (x), c2_cfloat_real (x));
+}
+
+cfloat_versions (cargf);
+
+#else
+# include <math/t_carg.c>
+#endif
--
2.4.11