[2/6] Support for type-generic libm function implementations libm
diff mbox

Message ID b8125c18fc66fa15669271886879baf6078c97c4.1467323999.git.murphyp@linux.vnet.ibm.com
State New
Headers show

Commit Message

Paul E. Murphy June 30, 2016, 10:20 p.m. UTC
This defines two new classes of libm objects.  g for
generated objects, and b for basic templates to
generate those objects.  The end result should be
much less duplication, and no function changes,
other than potential shuffling of the code within
libm.

As a simple example, the trivial complex functions
are converted to use the new infrastructure.

This uses some makefile hackery to generate g_*
objects from from the base b_*.c.  The intent is to
convert most or all of the complex function wrappers,
possibly even the wrappers for the e functions.

Hooks are added to enable a platform to override a
subset of generated files and replace them with a
platform supplied list of files via the
libm-gen-replacement-calls variable.  This is a
little kludgy as the set of files being moved
to this will likely include both unprefixed and
w_ prefixed files.  The intent is to minimize
awkward file renames.

Likewise, the alias for platforms which previously
didn't have long double support in glibc is handled
for trivial cases.  The more complex cases are left
to be handled individually.

I have verified the built objects for ppc64, x86_64,
alpha, arm, and m68k do not change in any meaningful
way with these changes using the Fedora cross toolchains.
I have verified the x86_64 and ppc64 changes still
run.

Verification is done by checking the objdump of
the g_*.{o,os} files with their equivalent s_
object prior to the patch.  Additionally nm is
used to verify the same set of symbols are
exported.

	* math/Makefile: Add support for routines generated
	via a macroed template file.
	(gen-libm-calls): New variable.
	(libm-calls-compat): Likewise.
	(gen-suffixes): Likewise.
	(g_CPPFLAGS): Likewise.
	(g__CPPFLAGS): Likewise.
	(g__fCPPFLAGS): Likewise.
	(g__lCPPFLAGS): Likewise.

	* sysdeps/generic/math-type-macros.h: New file.
	* sysdeps/ieee754/ldbl-opt/math-type-macros.h: Likewise.

	* math/cabs.c: Refactor into
	* math/b_cabs.c: new file.
	* math/cabsf.c: Removed.
	* math/cabsl.c: Removed.
	* sysdeps/ieee754/ldbl-opt/cabsf.c: Removed.
	* sysdeps/ieee754/ldbl-opt/cabsl.c: Removed.

	* math/carg.c: Refactor into
	* math/b_carg.c: new file.
	* math/cargf.c: Removed.
	* math/cargl.c: Removed.
	* sysdeps/ieee754/ldbl-opt/cargf.c: Removed.
	* sysdeps/ieee754/ldbl-opt/cargl.c: Removed.

	* math/conj.c: Refactor into
	* math/b_conj.c: new file.
	* math/conjf.c: Removed.
	* math/conjl.c: Removed.
	* sysdeps/ieee754/ldbl-opt/conjf.c: Removed.
	* sysdeps/ieee754/ldbl-opt/conjl.c: Removed.

	* math/cimag.c: Refactor into
	* math/b_cimag.c: new file.
	* math/cimagf.c: Removed.
	* math/cimagl.c: Removed.
	* sysdeps/ieee754/ldbl-opt/cimagf.c: Removed.
	* sysdeps/ieee754/ldbl-opt/cimagl.c: Removed.

	* math/cimag.c: Refactor into
	* math/b_cimag.c: new file.
	* math/cimagf.c: Removed.
	* math/cimagl.c: Removed.
	* sysdeps/ieee754/ldbl-opt/cimagf.c: Removed.
	* sysdeps/ieee754/ldbl-opt/cimagl.c: Removed.

	* sysdeps/ieee754/Makeconfig: New file.
	* Makeconfig: Move m_% sysd pattern rule into above.

	* scripts/sysd-rules.awk: Handle multiple rules
	with same DEP length correctly.

Fix intial generated code patch.
---
 Makeconfig                                  |   2 +-
 math/Makefile                               |  51 ++++++++-
 math/b_cabs.c                               |  33 ++++++
 math/b_carg.c                               |  33 ++++++
 math/b_cimag.c                              |  32 ++++++
 math/b_conj.c                               |  32 ++++++
 math/b_creal.c                              |  32 ++++++
 math/cabs.c                                 |  32 ------
 math/cabsf.c                                |  28 -----
 math/cabsl.c                                |  28 -----
 math/carg.c                                 |  32 ------
 math/cargf.c                                |  28 -----
 math/cargl.c                                |  28 -----
 math/cimag.c                                |  31 ------
 math/cimagf.c                               |  27 -----
 math/cimagl.c                               |  27 -----
 math/conj.c                                 |  31 ------
 math/conjf.c                                |  27 -----
 math/conjl.c                                |  27 -----
 math/creal.c                                |  31 ------
 math/crealf.c                               |  27 -----
 math/creall.c                               |  27 -----
 scripts/sysd-rules.awk                      |   5 +-
 sysdeps/alpha/fpu/Makefile                  |   4 +
 sysdeps/generic/math-type-macros.h          | 159 ++++++++++++++++++++++++++++
 sysdeps/ieee754/Makeconfig                  |   6 ++
 sysdeps/ieee754/ldbl-opt/cabs.c             |   6 --
 sysdeps/ieee754/ldbl-opt/cabsl.c            |   6 --
 sysdeps/ieee754/ldbl-opt/carg.c             |   6 --
 sysdeps/ieee754/ldbl-opt/cargl.c            |   6 --
 sysdeps/ieee754/ldbl-opt/cimag.c            |   6 --
 sysdeps/ieee754/ldbl-opt/cimagl.c           |   6 --
 sysdeps/ieee754/ldbl-opt/conj.c             |   6 --
 sysdeps/ieee754/ldbl-opt/conjl.c            |   6 --
 sysdeps/ieee754/ldbl-opt/creal.c            |   6 --
 sysdeps/ieee754/ldbl-opt/creall.c           |   6 --
 sysdeps/ieee754/ldbl-opt/math-type-macros.h |  11 ++
 37 files changed, 395 insertions(+), 496 deletions(-)
 create mode 100644 math/b_cabs.c
 create mode 100644 math/b_carg.c
 create mode 100644 math/b_cimag.c
 create mode 100644 math/b_conj.c
 create mode 100644 math/b_creal.c
 delete mode 100644 math/cabs.c
 delete mode 100644 math/cabsf.c
 delete mode 100644 math/cabsl.c
 delete mode 100644 math/carg.c
 delete mode 100644 math/cargf.c
 delete mode 100644 math/cargl.c
 delete mode 100644 math/cimag.c
 delete mode 100644 math/cimagf.c
 delete mode 100644 math/cimagl.c
 delete mode 100644 math/conj.c
 delete mode 100644 math/conjf.c
 delete mode 100644 math/conjl.c
 delete mode 100644 math/creal.c
 delete mode 100644 math/crealf.c
 delete mode 100644 math/creall.c
 create mode 100644 sysdeps/alpha/fpu/Makefile
 create mode 100644 sysdeps/generic/math-type-macros.h
 create mode 100644 sysdeps/ieee754/Makeconfig
 delete mode 100644 sysdeps/ieee754/ldbl-opt/cabs.c
 delete mode 100644 sysdeps/ieee754/ldbl-opt/cabsl.c
 delete mode 100644 sysdeps/ieee754/ldbl-opt/carg.c
 delete mode 100644 sysdeps/ieee754/ldbl-opt/cargl.c
 delete mode 100644 sysdeps/ieee754/ldbl-opt/cimag.c
 delete mode 100644 sysdeps/ieee754/ldbl-opt/cimagl.c
 delete mode 100644 sysdeps/ieee754/ldbl-opt/conj.c
 delete mode 100644 sysdeps/ieee754/ldbl-opt/conjl.c
 delete mode 100644 sysdeps/ieee754/ldbl-opt/creal.c
 delete mode 100644 sysdeps/ieee754/ldbl-opt/creall.c
 create mode 100644 sysdeps/ieee754/ldbl-opt/math-type-macros.h

Comments

Adhemerval Zanella Aug. 3, 2016, 8:10 p.m. UTC | #1
On 30/06/2016 19:20, Paul E. Murphy wrote:
> This defines two new classes of libm objects.  g for
> generated objects, and b for basic templates to
> generate those objects.  The end result should be
> much less duplication, and no function changes,
> other than potential shuffling of the code within
> libm.
> 

I am in favor of such cleanup and it seems a good strategy to
avoid code duplication.  I do not have much experience to review
the Makefile changes requires, so below just some general remarks.

> As a simple example, the trivial complex functions
> are converted to use the new infrastructure.
> 
> This uses some makefile hackery to generate g_*
> objects from from the base b_*.c.  The intent is to
> convert most or all of the complex function wrappers,
> possibly even the wrappers for the e functions.
> 
> Hooks are added to enable a platform to override a
> subset of generated files and replace them with a
> platform supplied list of files via the
> libm-gen-replacement-calls variable.  This is a
> little kludgy as the set of files being moved
> to this will likely include both unprefixed and
> w_ prefixed files.  The intent is to minimize
> awkward file renames.
> 
> Likewise, the alias for platforms which previously
> didn't have long double support in glibc is handled
> for trivial cases.  The more complex cases are left
> to be handled individually.
> 
> I have verified the built objects for ppc64, x86_64,
> alpha, arm, and m68k do not change in any meaningful
> way with these changes using the Fedora cross toolchains.
> I have verified the x86_64 and ppc64 changes still
> run.
> 
> Verification is done by checking the objdump of
> the g_*.{o,os} files with their equivalent s_
> object prior to the patch.  Additionally nm is
> used to verify the same set of symbols are
> exported.
> 
> 	* math/Makefile: Add support for routines generated
> 	via a macroed template file.
> 	(gen-libm-calls): New variable.
> 	(libm-calls-compat): Likewise.
> 	(gen-suffixes): Likewise.
> 	(g_CPPFLAGS): Likewise.
> 	(g__CPPFLAGS): Likewise.
> 	(g__fCPPFLAGS): Likewise.
> 	(g__lCPPFLAGS): Likewise.
> 
> 	* sysdeps/generic/math-type-macros.h: New file.
> 	* sysdeps/ieee754/ldbl-opt/math-type-macros.h: Likewise.
> 
> 	* math/cabs.c: Refactor into
> 	* math/b_cabs.c: new file.
> 	* math/cabsf.c: Removed.
> 	* math/cabsl.c: Removed.
> 	* sysdeps/ieee754/ldbl-opt/cabsf.c: Removed.
> 	* sysdeps/ieee754/ldbl-opt/cabsl.c: Removed.
> 
> 	* math/carg.c: Refactor into
> 	* math/b_carg.c: new file.
> 	* math/cargf.c: Removed.
> 	* math/cargl.c: Removed.
> 	* sysdeps/ieee754/ldbl-opt/cargf.c: Removed.
> 	* sysdeps/ieee754/ldbl-opt/cargl.c: Removed.
> 
> 	* math/conj.c: Refactor into
> 	* math/b_conj.c: new file.
> 	* math/conjf.c: Removed.
> 	* math/conjl.c: Removed.
> 	* sysdeps/ieee754/ldbl-opt/conjf.c: Removed.
> 	* sysdeps/ieee754/ldbl-opt/conjl.c: Removed.
> 
> 	* math/cimag.c: Refactor into
> 	* math/b_cimag.c: new file.
> 	* math/cimagf.c: Removed.
> 	* math/cimagl.c: Removed.
> 	* sysdeps/ieee754/ldbl-opt/cimagf.c: Removed.
> 	* sysdeps/ieee754/ldbl-opt/cimagl.c: Removed.
> 
> 	* math/cimag.c: Refactor into
> 	* math/b_cimag.c: new file.
> 	* math/cimagf.c: Removed.
> 	* math/cimagl.c: Removed.
> 	* sysdeps/ieee754/ldbl-opt/cimagf.c: Removed.
> 	* sysdeps/ieee754/ldbl-opt/cimagl.c: Removed.
> 
> 	* sysdeps/ieee754/Makeconfig: New file.
> 	* Makeconfig: Move m_% sysd pattern rule into above.
> 
> 	* scripts/sysd-rules.awk: Handle multiple rules
> 	with same DEP length correctly.
> 
> Fix intial generated code patch.
> ---
>  Makeconfig                                  |   2 +-
>  math/Makefile                               |  51 ++++++++-
>  math/b_cabs.c                               |  33 ++++++
>  math/b_carg.c                               |  33 ++++++
>  math/b_cimag.c                              |  32 ++++++
>  math/b_conj.c                               |  32 ++++++
>  math/b_creal.c                              |  32 ++++++
>  math/cabs.c                                 |  32 ------
>  math/cabsf.c                                |  28 -----
>  math/cabsl.c                                |  28 -----
>  math/carg.c                                 |  32 ------
>  math/cargf.c                                |  28 -----
>  math/cargl.c                                |  28 -----
>  math/cimag.c                                |  31 ------
>  math/cimagf.c                               |  27 -----
>  math/cimagl.c                               |  27 -----
>  math/conj.c                                 |  31 ------
>  math/conjf.c                                |  27 -----
>  math/conjl.c                                |  27 -----
>  math/creal.c                                |  31 ------
>  math/crealf.c                               |  27 -----
>  math/creall.c                               |  27 -----
>  scripts/sysd-rules.awk                      |   5 +-
>  sysdeps/alpha/fpu/Makefile                  |   4 +
>  sysdeps/generic/math-type-macros.h          | 159 ++++++++++++++++++++++++++++
>  sysdeps/ieee754/Makeconfig                  |   6 ++
>  sysdeps/ieee754/ldbl-opt/cabs.c             |   6 --
>  sysdeps/ieee754/ldbl-opt/cabsl.c            |   6 --
>  sysdeps/ieee754/ldbl-opt/carg.c             |   6 --
>  sysdeps/ieee754/ldbl-opt/cargl.c            |   6 --
>  sysdeps/ieee754/ldbl-opt/cimag.c            |   6 --
>  sysdeps/ieee754/ldbl-opt/cimagl.c           |   6 --
>  sysdeps/ieee754/ldbl-opt/conj.c             |   6 --
>  sysdeps/ieee754/ldbl-opt/conjl.c            |   6 --
>  sysdeps/ieee754/ldbl-opt/creal.c            |   6 --
>  sysdeps/ieee754/ldbl-opt/creall.c           |   6 --
>  sysdeps/ieee754/ldbl-opt/math-type-macros.h |  11 ++
>  37 files changed, 395 insertions(+), 496 deletions(-)
>  create mode 100644 math/b_cabs.c
>  create mode 100644 math/b_carg.c
>  create mode 100644 math/b_cimag.c
>  create mode 100644 math/b_conj.c
>  create mode 100644 math/b_creal.c
>  delete mode 100644 math/cabs.c
>  delete mode 100644 math/cabsf.c
>  delete mode 100644 math/cabsl.c
>  delete mode 100644 math/carg.c
>  delete mode 100644 math/cargf.c
>  delete mode 100644 math/cargl.c
>  delete mode 100644 math/cimag.c
>  delete mode 100644 math/cimagf.c
>  delete mode 100644 math/cimagl.c
>  delete mode 100644 math/conj.c
>  delete mode 100644 math/conjf.c
>  delete mode 100644 math/conjl.c
>  delete mode 100644 math/creal.c
>  delete mode 100644 math/crealf.c
>  delete mode 100644 math/creall.c
>  create mode 100644 sysdeps/alpha/fpu/Makefile
>  create mode 100644 sysdeps/generic/math-type-macros.h
>  create mode 100644 sysdeps/ieee754/Makeconfig
>  delete mode 100644 sysdeps/ieee754/ldbl-opt/cabs.c
>  delete mode 100644 sysdeps/ieee754/ldbl-opt/cabsl.c
>  delete mode 100644 sysdeps/ieee754/ldbl-opt/carg.c
>  delete mode 100644 sysdeps/ieee754/ldbl-opt/cargl.c
>  delete mode 100644 sysdeps/ieee754/ldbl-opt/cimag.c
>  delete mode 100644 sysdeps/ieee754/ldbl-opt/cimagl.c
>  delete mode 100644 sysdeps/ieee754/ldbl-opt/conj.c
>  delete mode 100644 sysdeps/ieee754/ldbl-opt/conjl.c
>  delete mode 100644 sysdeps/ieee754/ldbl-opt/creal.c
>  delete mode 100644 sysdeps/ieee754/ldbl-opt/creall.c
>  create mode 100644 sysdeps/ieee754/ldbl-opt/math-type-macros.h
> 
> diff --git a/Makeconfig b/Makeconfig
> index 901e253..8a7b5f2 100644
> --- a/Makeconfig
> +++ b/Makeconfig
> @@ -1124,7 +1124,7 @@ endif
>  # emitted into sysd-rules.  A sysdeps Makeconfig fragment can
>  # add its own special object file prefix to this list with e.g. foo-%:%
>  # to have foo-*.? compiled from *.? using $(foo-CPPFLAGS).
> -sysd-rules-patterns := %:% rtld-%:rtld-% rtld-%:% m_%:s_%
> +sysd-rules-patterns := %:% rtld-%:rtld-% rtld-%:%
>  
>  # Let sysdeps/ subdirs contain a Makeconfig fragment for us to include here.
>  sysdep-makeconfigs := $(wildcard $(+sysdep_dirs:=/Makeconfig))
> diff --git a/math/Makefile b/math/Makefile
> index 89002a8..14f8f42 100644
> --- a/math/Makefile
> +++ b/math/Makefile
> @@ -43,6 +43,18 @@ 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 b_func.c file.
> +#
> +# Similarly, a platform can override any of these generated functions
> +# (after type suffix substitution occurs) by adding a fragment which
> +# defines libm-gen-calls-override and lists each function which should
> +# not use the default version. If declared, it is assumed the target
> +# will match the name s_<func><type suffix>
> +gen-libm-calls = g_carg_F g_conj_F g_cimag_F g_creal_F g_cabs_F
> +

It is not clear to me based on these comments how an architecture would
override a specific implementation.  After I read the alpha change it
become move evident.  So if I understood correctly, besides adding the
arch specific implementation in the sysdep folder, one must also add
two more make specific rules (libm-gen-calls-override and 
libm-gen-replacement-calls) to actually override the building?

It would be good to add some documentation on how to actually override a
symbol based on an example.

>  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	  \
> @@ -59,13 +71,13 @@ libm-calls =								  \
>  	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 \
> +	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 lgamma_negF lgamma_productF			  \
> -	s_nextupF s_nextdownF
> +	s_nextupF s_nextdownF $(gen-libm-calls)
>  
>  libm-compat-calls-ldouble-yes = w_lgamma_compatl k_standardl
>  libm-compat-calls = w_lgamma_compatf w_lgamma_compat k_standard k_standardf \
> @@ -105,7 +117,9 @@ type-float-routines :=
>  type-foreach = $(foreach t,$(types),$(subst F,$(type-$(t)-suffix),$(1)))
>  
>  libm-routines = $(strip $(libm-support) $(libm-compat-calls)		\
> -			$(call type-foreach, $(libm-calls))		\
> +			$(filter-out $(libm-gen-calls-override),	\
> +				$(call type-foreach, $(libm-calls)))	\
> +			$(libm-gen-replacement-calls)			\
>  			$(foreach t, $(types), $(type-$(t)-routines))) 	\
>  
>  # These functions are in libc instead of libm because __printf_fp
> @@ -118,6 +132,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_%$(s))))
>  routines = $(call type-foreach, $(calls))
>  
> +# Wrappers and what not are generated per type to keep the noise down.
> +generated += $(foreach s,.c .S,$(call type-foreach,$(gen-libm-calls:%=%$(s))))
> +
>  ifeq ($(build-mathvec),yes)
>  # We need to install libm.so as linker script
>  # for more comfortable use of vector math library.
> @@ -303,6 +320,34 @@ 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))
> +
> +# Add special flags to control how the templated functions
> +# are built.
> +g_CPPFLAGS = -include math-type-macros.h
> +g__fCPPFLAGS = $(g_CPPFLAGS) -DM_TYPE=M_FLOAT
> +g__CPPFLAGS = $(g_CPPFLAGS) -DM_TYPE=M_DOUBLE
> +g__lCPPFLAGS = $(g_CPPFLAGS) -DM_TYPE=M_LDOUBLE
> +
> +# Like m_% above, this builds the generic sources.  Makeconfig
> +# enumerates the sysd-rules for overriding.
> +define o-iterator-doit
> +$(objpfx)g_%$o: b_%.c $(before-compile); $$(compile-command.c)
> +endef
> +object-suffixes-left := $(gen-suffixes)
> +include $(o-iterator)
> +
> +# Tack on the appropriate CPPFLAGS to match sysd-rules
> +define o-iterator-doit
> +$(objpfx)g_%$o: CPPFLAGS += $(g_$(basename $o)CPPFLAGS)
> +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/b_cabs.c b/math/b_cabs.c
> new file mode 100644
> index 0000000..64265f1
> --- /dev/null
> +++ b/math/b_cabs.c
> @@ -0,0 +1,33 @@
> +/* Return the complex absolute value 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.

As a new file I think we can use just current year and drop the old 'Contributed by'
(this happens in all b_xxxx.c new files as well).

> +
> +   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
> +M_SUF (__cabs) (CFLOAT z)
> +{
> +  return M_SUF (__hypot) (__real__ z, __imag__ z);
> +}
> +
> +declare_mgen_alias (__cabs, cabs)
> +
> +#if M_LIBM_NEED_COMPAT (cabs)
> +  declare_mgen_libm_compat (__cabs, cabs)
> +#endif
> diff --git a/math/b_carg.c b/math/b_carg.c
> new file mode 100644
> index 0000000..004e14d
> --- /dev/null
> +++ b/math/b_carg.c
> @@ -0,0 +1,33 @@
> +/* 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>
> +
> +FLOAT
> +M_SUF (__carg) (CFLOAT x)
> +{
> +  return M_SUF (__atan2) (__imag__ x, __real__ x);
> +}
> +
> +declare_mgen_alias (__carg, carg)
> +
> +#if M_LIBM_NEED_COMPAT (carg)
> +  declare_mgen_libm_compat (__carg, carg)
> +#endif
> diff --git a/math/b_cimag.c b/math/b_cimag.c
> new file mode 100644
> index 0000000..73450f3
> --- /dev/null
> +++ b/math/b_cimag.c
> @@ -0,0 +1,32 @@
> +/* Return imaginary part 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>
> +
> +FLOAT
> +M_SUF (__cimag) (CFLOAT z)
> +{
> +  return __imag__ z;
> +}
> +
> +declare_mgen_alias (__cimag, cimag)
> +
> +#if M_LIBM_NEED_COMPAT (cimag)
> +  declare_mgen_libm_compat (__cimag, cimag)
> +#endif
> diff --git a/math/b_conj.c b/math/b_conj.c
> new file mode 100644
> index 0000000..979a759
> --- /dev/null
> +++ b/math/b_conj.c
> @@ -0,0 +1,32 @@
> +/* Return complex conjugate 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>
> +
> +CFLOAT
> +M_SUF (__conj) (CFLOAT z)
> +{
> +  return ~z;
> +}
> +
> +declare_mgen_alias (__conj, conj)
> +
> +#if M_LIBM_NEED_COMPAT (conj)
> +  declare_mgen_libm_compat (__conj, conj)
> +#endif
> diff --git a/math/b_creal.c b/math/b_creal.c
> new file mode 100644
> index 0000000..b92e0a3
> --- /dev/null
> +++ b/math/b_creal.c
> @@ -0,0 +1,32 @@
> +/* Return real part 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>
> +
> +FLOAT
> +M_SUF (__creal) (CFLOAT z)
> +{
> +  return __real__ z;
> +}
> +
> +declare_mgen_alias (__creal, creal)
> +
> +#if M_LIBM_NEED_COMPAT (creal)
> +  declare_mgen_libm_compat (__creal, creal)
> +#endif
> diff --git a/math/cabs.c b/math/cabs.c
> deleted file mode 100644
> index d7e0665..0000000
> --- a/math/cabs.c
> +++ /dev/null
> @@ -1,32 +0,0 @@
> -/* Return the complex absolute value of double complex 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
> -__cabs (double _Complex z)
> -{
> -  return __hypot (__real__ z, __imag__ z);
> -}
> -weak_alias (__cabs, cabs)
> -#ifdef NO_LONG_DOUBLE
> -strong_alias (__cabs, __cabsl)
> -weak_alias (__cabs, cabsl)
> -#endif
> diff --git a/math/cabsf.c b/math/cabsf.c
> deleted file mode 100644
> index 431a244..0000000
> --- a/math/cabsf.c
> +++ /dev/null
> @@ -1,28 +0,0 @@
> -/* Return the complex absolute value of float complex 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
> -__cabsf (float _Complex z)
> -{
> -  return __hypotf (__real__ z, __imag__ z);
> -}
> -weak_alias (__cabsf, cabsf)
> diff --git a/math/cabsl.c b/math/cabsl.c
> deleted file mode 100644
> index d87e3a2..0000000
> --- a/math/cabsl.c
> +++ /dev/null
> @@ -1,28 +0,0 @@
> -/* Return the complex absolute value of long double complex 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
> -__cabsl (long double _Complex z)
> -{
> -  return __hypotl (__real__ z, __imag__ z);
> -}
> -weak_alias (__cabsl, cabsl)
> 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/cimag.c b/math/cimag.c
> deleted file mode 100644
> index 1807ac2..0000000
> --- a/math/cimag.c
> +++ /dev/null
> @@ -1,31 +0,0 @@
> -/* Return imaginary part 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>
> -
> -double
> -__cimag (double _Complex z)
> -{
> -  return __imag__ z;
> -}
> -weak_alias (__cimag, cimag)
> -#ifdef NO_LONG_DOUBLE
> -strong_alias (__cimag, __cimagl)
> -weak_alias (__cimag, cimagl)
> -#endif
> diff --git a/math/cimagf.c b/math/cimagf.c
> deleted file mode 100644
> index 67c37f4..0000000
> --- a/math/cimagf.c
> +++ /dev/null
> @@ -1,27 +0,0 @@
> -/* Return imaginary part 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>
> -
> -float
> -__cimagf (float _Complex z)
> -{
> -  return __imag__ z;
> -}
> -weak_alias (__cimagf, cimagf)
> diff --git a/math/cimagl.c b/math/cimagl.c
> deleted file mode 100644
> index c1d0910..0000000
> --- a/math/cimagl.c
> +++ /dev/null
> @@ -1,27 +0,0 @@
> -/* Return imaginary part 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>
> -
> -long double
> -__cimagl (long double _Complex z)
> -{
> -  return __imag__ z;
> -}
> -weak_alias (__cimagl, cimagl)
> diff --git a/math/conj.c b/math/conj.c
> deleted file mode 100644
> index d282985..0000000
> --- a/math/conj.c
> +++ /dev/null
> @@ -1,31 +0,0 @@
> -/* Return complex conjugate 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>
> -
> -double _Complex
> -__conj (double _Complex z)
> -{
> -  return ~z;
> -}
> -weak_alias (__conj, conj)
> -#ifdef NO_LONG_DOUBLE
> -strong_alias (__conj, __conjl)
> -weak_alias (__conj, conjl)
> -#endif
> diff --git a/math/conjf.c b/math/conjf.c
> deleted file mode 100644
> index 3587c94..0000000
> --- a/math/conjf.c
> +++ /dev/null
> @@ -1,27 +0,0 @@
> -/* Return complex conjugate 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>
> -
> -float _Complex
> -__conjf (float _Complex z)
> -{
> -  return ~z;
> -}
> -weak_alias (__conjf, conjf)
> diff --git a/math/conjl.c b/math/conjl.c
> deleted file mode 100644
> index 55bb393..0000000
> --- a/math/conjl.c
> +++ /dev/null
> @@ -1,27 +0,0 @@
> -/* Return complex conjugate 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>
> -
> -long double _Complex
> -__conjl (long double _Complex z)
> -{
> -  return ~z;
> -}
> -weak_alias (__conjl, conjl)
> diff --git a/math/creal.c b/math/creal.c
> deleted file mode 100644
> index 231d3b0..0000000
> --- a/math/creal.c
> +++ /dev/null
> @@ -1,31 +0,0 @@
> -/* Return real part 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>
> -
> -double
> -__creal (double _Complex z)
> -{
> -  return __real__ z;
> -}
> -weak_alias (__creal, creal)
> -#ifdef NO_LONG_DOUBLE
> -strong_alias (__creal, __creall)
> -weak_alias (__creal, creall)
> -#endif
> diff --git a/math/crealf.c b/math/crealf.c
> deleted file mode 100644
> index 5883849..0000000
> --- a/math/crealf.c
> +++ /dev/null
> @@ -1,27 +0,0 @@
> -/* Return real part 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>
> -
> -float
> -__crealf (float _Complex z)
> -{
> -  return __real__ z;
> -}
> -weak_alias (__crealf, crealf)
> diff --git a/math/creall.c b/math/creall.c
> deleted file mode 100644
> index 4a31557..0000000
> --- a/math/creall.c
> +++ /dev/null
> @@ -1,27 +0,0 @@
> -/* Return real part 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>
> -
> -long double
> -__creall (long double _Complex z)
> -{
> -  return __real__ z;
> -}
> -weak_alias (__creall, creall)
> diff --git a/scripts/sysd-rules.awk b/scripts/sysd-rules.awk
> index 69af400..ccf1dff 100644
> --- a/scripts/sysd-rules.awk
> +++ b/scripts/sysd-rules.awk
> @@ -18,6 +18,9 @@ BEGIN {
>    # They are no in particular order.  We need to sort them so that
>    # the longest TARGET is first, and, among elements with the same
>    # TARGET, the longest DEP is first.
> +  #
> +  # If two TARGETs have the same length DEP, the first TARGET is
> +  # always listed first.
>    for (i = 1; i <= npatterns; ++i) {
>      if (split(patterns[i], td, ":") != 2) {
>        msg = "bad sysd-rules-patterns element '" patterns[i] "'";
> @@ -25,7 +28,7 @@ BEGIN {
>        exit 2;
>      }
>      target_order = sprintf("%09d", npatterns + 1 - length(td[1]));
> -    dep_order = sprintf("%09d", npatterns - length(td[2]));
> +    dep_order = sprintf("%09d%03d", npatterns - length(td[2]), i);
>      sort_patterns[target_order SUBSEP dep_order] = patterns[i];
>    }
>    asorti(sort_patterns, map_patterns);
> diff --git a/sysdeps/alpha/fpu/Makefile b/sysdeps/alpha/fpu/Makefile
> new file mode 100644
> index 0000000..c49c302
> --- /dev/null
> +++ b/sysdeps/alpha/fpu/Makefile
> @@ -0,0 +1,4 @@
> +# Inhibit generation of these math files as they are supplied via
> +# the respectic s_*.c versions here.
> +libm-gen-calls-override = g_cabs_f g_carg_f g_cimag_f g_creal_f g_conj_f
> +libm-gen-replacement-calls = cabsf cargf cimagf crealf conjf
> diff --git a/sysdeps/generic/math-type-macros.h b/sysdeps/generic/math-type-macros.h
> new file mode 100644
> index 0000000..3befde1
> --- /dev/null
> +++ b/sysdeps/generic/math-type-macros.h
> @@ -0,0 +1,159 @@
> +/* 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(c) c ## f
> +/* Use the double version instead.  */
> +# define M_MLIT(c) c
> +# define M_SUF(c) c ## f
> +# define M_FUNC(c) c ## f
> +# define FLOAT float
> +# define CFLOAT __complex__ float
> +# define M_HUGE_VAL HUGE_VALF
> +#elif M_TYPE == M_DOUBLE
> +# define M_PFX DBL
> +# define M_LIT(c) c
> +# define M_MLIT(c) c
> +# define M_SUF(c) c
> +# define M_FUNC(c) c
> +# define FLOAT double
> +# define CFLOAT __complex__ double
> +# define M_HUGE_VAL HUGE_VAL
> +#elif M_TYPE == M_LDOUBLE
> +# define M_PFX LDBL
> +# define M_LIT(c) c ## L
> +# define M_MLIT(c) c ## l
> +# define M_SUF(c) c ## l
> +# define M_FUNC(c) c ## l
> +# define FLOAT long double
> +# define CFLOAT __complex__ long double
> +# define M_HUGE_VAL HUGE_VALL
> +#else
> +# error Error: M_TYPE is not a known floating point type
> +#endif
> +
> +#define __M_CONCAT(a,b) a ## b
> +#define __M_CONCATX(a,b) __M_CONCAT(a,b)
> +
> +#define M_NAN M_FUNC (__nan) ("")
> +#define M_MAX_EXP __M_CONCATX (M_PFX, _MAX_EXP)
> +#define M_MIN __M_CONCATX (M_PFX, _MIN)
> +#define M_MAX __M_CONCATX (M_PFX, _MAX)
> +#define M_MANT_DIG __M_CONCATX (M_PFX, _MANT_DIG)
> +
> +/* Helper macros for commonly used functions.  */
> +#define M_COPYSIGN M_FUNC (__copysign)
> +#define M_FABS M_FUNC (fabs)
> +#define M_SINCOS M_FUNC (__sincos)
> +#define M_SCALBN M_FUNC (__scalbn)
> +#define M_LOG1P M_FUNC (__log1p)
> +
> +#define M_ATAN2 M_FUNC (__ieee754_atan2)
> +#define M_COSH M_FUNC (__ieee754_cosh)
> +#define M_EXP M_FUNC (__ieee754_exp)
> +#define M_HYPOT M_FUNC (__ieee754_hypot)
> +#define M_LOG M_FUNC (__ieee754_log)
> +#define M_SINH M_FUNC (__ieee754_sinh)
> +#define M_SQRT M_FUNC (__ieee754_sqrt)
> +
> +/* Needed to evaluate M_MANT_DIG below.  */
> +#include <float.h>
> +
> +/* Use a special epsilon value for IBM long double
> +   to avoid spurious overflows.  */
> +#if M_MANT_DIG != 106
> +# define M_EPSILON __M_CONCATX (M_PFX, _EPSILON)
> +#else
> +# define M_EPSILON 0x1p-106L
> +#endif
> +
> +/* Enable overloading of function name to assist
> +   reuse.  */
> +#ifndef M_DECL_FUNC
> +# define M_DECL_FUNC(f) M_FUNC(f)
> +#endif
> +
> +/* Rules for aliasing the currently generated math files.  */
> +
> +/* Aliasing rules for float are straight forward.  */
> +#if M_TYPE == M_FLOAT
> +# define declare_mgen_alias(from, to) weak_alias (M_SUF (from), M_SUF (to))
> +#endif
> +
> +/* Aliasing rules for double are sightly more
> +   complicated.
> +   1. long double == double.
> +   2. long double used to be double.
> +   3. double has always been unique. */
> +#if M_TYPE == M_DOUBLE
> +# if defined NO_LONG_DOUBLE
> +#  define declare_mgen_alias(from, to)	    \
> +    weak_alias (from, to)		    \
> +    strong_alias (from, from ## l)	    \
> +    weak_alias (from, to ## l)
> +# else
> +#  define declare_mgen_alias(from, to)	    \
> +    weak_alias (M_SUF (from), M_SUF (to))
> +# endif
> +#endif
> +
> +/* Slightly simpler for long double.
> +   1. long double used to be double.
> +   2. long double has always been unique.  */
> +#if M_TYPE == M_LDOUBLE
> +# if defined LONG_DOUBLE_COMPAT_VERSION
> +#  define declare_mgen_alias(from, to)		  \
> +    long_double_symbol (libm, from ## l, to ## l);
> +# else
> +#  define declare_mgen_alias(from, to)	    \
> +    weak_alias (M_SUF (from), M_SUF (to))
> +# endif
> +#endif
> +
> +#if ! defined declare_mgen_alias
> +# error Alias rules not defined for M_TYPE
> +#endif
> +
> +/* From case 2 for double, we may need to declare compat
> +   aliases for double symbols mapping to long double.
> +
> +   This suffices for the majority of the complex functions.
> +   More interesting cases need to be handled on a case by
> +   case basis.  */
> +#if M_TYPE == M_DOUBLE && defined LONG_DOUBLE_COMPAT_VERSION
> +# define M_LIBM_NEED_COMPAT(f)				      \
> +  LONG_DOUBLE_COMPAT (libm, LDOUBLE_ ## f ## l_libm_version)
> +# define declare_mgen_libm_compat(from, to)	      \
> +    compat_symbol (libm,			      \
> +		   from,			      \
> +		   to ## l,			      \
> +		   LDOUBLE_ ## to ## l_libm_version);
> +#else
> +# define M_LIBM_NEED_COMPAT(func) 0
> +# define declare_mgen_libm_compat(from, to)
> +#endif
> +
> +#endif /* _MATH_TYPE_MACROS */
> diff --git a/sysdeps/ieee754/Makeconfig b/sysdeps/ieee754/Makeconfig
> new file mode 100644
> index 0000000..15fd238
> --- /dev/null
> +++ b/sysdeps/ieee754/Makeconfig
> @@ -0,0 +1,6 @@
> +# Add the rules for generated math files in sysdeps
> +# Not the perfect place, but close enough.
> +#
> +# Each type supported by libm should have a g_%_SUFFIX
> +# pattern to match its suffix.
> +sysd-rules-patterns += m_%:s_% g_%_f:b_% g_%_l:b_% g_%_:b_%
> diff --git a/sysdeps/ieee754/ldbl-opt/cabs.c b/sysdeps/ieee754/ldbl-opt/cabs.c
> deleted file mode 100644
> index a181de2..0000000
> --- a/sysdeps/ieee754/ldbl-opt/cabs.c
> +++ /dev/null
> @@ -1,6 +0,0 @@
> -#include <complex.h>
> -#include <math_ldbl_opt.h>
> -#include <math/cabs.c>
> -#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
> -compat_symbol (libm, __cabs, cabsl, GLIBC_2_1);
> -#endif
> diff --git a/sysdeps/ieee754/ldbl-opt/cabsl.c b/sysdeps/ieee754/ldbl-opt/cabsl.c
> deleted file mode 100644
> index b861633..0000000
> --- a/sysdeps/ieee754/ldbl-opt/cabsl.c
> +++ /dev/null
> @@ -1,6 +0,0 @@
> -#include <complex.h>
> -#include <math_ldbl_opt.h>
> -#undef weak_alias
> -#define weak_alias(n,a)
> -#include <math/cabsl.c>
> -long_double_symbol (libm, __cabsl, cabsl);
> diff --git a/sysdeps/ieee754/ldbl-opt/carg.c b/sysdeps/ieee754/ldbl-opt/carg.c
> deleted file mode 100644
> index 2ed3581..0000000
> --- a/sysdeps/ieee754/ldbl-opt/carg.c
> +++ /dev/null
> @@ -1,6 +0,0 @@
> -#include <complex.h>
> -#include <math_ldbl_opt.h>
> -#include <math/carg.c>
> -#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
> -compat_symbol (libm, __carg, cargl, GLIBC_2_1);
> -#endif
> diff --git a/sysdeps/ieee754/ldbl-opt/cargl.c b/sysdeps/ieee754/ldbl-opt/cargl.c
> deleted file mode 100644
> index 952dc60..0000000
> --- a/sysdeps/ieee754/ldbl-opt/cargl.c
> +++ /dev/null
> @@ -1,6 +0,0 @@
> -#include <complex.h>
> -#include <math_ldbl_opt.h>
> -#undef weak_alias
> -#define weak_alias(n,a)
> -#include <math/cargl.c>
> -long_double_symbol (libm, __cargl, cargl);
> diff --git a/sysdeps/ieee754/ldbl-opt/cimag.c b/sysdeps/ieee754/ldbl-opt/cimag.c
> deleted file mode 100644
> index f805258..0000000
> --- a/sysdeps/ieee754/ldbl-opt/cimag.c
> +++ /dev/null
> @@ -1,6 +0,0 @@
> -#include <complex.h>
> -#include <math_ldbl_opt.h>
> -#include <math/cimag.c>
> -#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
> -compat_symbol (libm, __cimag, cimagl, GLIBC_2_1);
> -#endif
> diff --git a/sysdeps/ieee754/ldbl-opt/cimagl.c b/sysdeps/ieee754/ldbl-opt/cimagl.c
> deleted file mode 100644
> index 112365e..0000000
> --- a/sysdeps/ieee754/ldbl-opt/cimagl.c
> +++ /dev/null
> @@ -1,6 +0,0 @@
> -#include <complex.h>
> -#include <math_ldbl_opt.h>
> -#undef weak_alias
> -#define weak_alias(n,a)
> -#include <math/cimagl.c>
> -long_double_symbol (libm, __cimagl, cimagl);
> diff --git a/sysdeps/ieee754/ldbl-opt/conj.c b/sysdeps/ieee754/ldbl-opt/conj.c
> deleted file mode 100644
> index e4edade..0000000
> --- a/sysdeps/ieee754/ldbl-opt/conj.c
> +++ /dev/null
> @@ -1,6 +0,0 @@
> -#include <complex.h>
> -#include <math_ldbl_opt.h>
> -#include <math/conj.c>
> -#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
> -compat_symbol (libm, __conj, conjl, GLIBC_2_1);
> -#endif
> diff --git a/sysdeps/ieee754/ldbl-opt/conjl.c b/sysdeps/ieee754/ldbl-opt/conjl.c
> deleted file mode 100644
> index c98e0ed..0000000
> --- a/sysdeps/ieee754/ldbl-opt/conjl.c
> +++ /dev/null
> @@ -1,6 +0,0 @@
> -#include <complex.h>
> -#include <math_ldbl_opt.h>
> -#undef weak_alias
> -#define weak_alias(n,a)
> -#include <math/conjl.c>
> -long_double_symbol (libm, __conjl, conjl);
> diff --git a/sysdeps/ieee754/ldbl-opt/creal.c b/sysdeps/ieee754/ldbl-opt/creal.c
> deleted file mode 100644
> index 0d1c93e..0000000
> --- a/sysdeps/ieee754/ldbl-opt/creal.c
> +++ /dev/null
> @@ -1,6 +0,0 @@
> -#include <complex.h>
> -#include <math_ldbl_opt.h>
> -#include <math/creal.c>
> -#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
> -compat_symbol (libm, __creal, creall, GLIBC_2_1);
> -#endif
> diff --git a/sysdeps/ieee754/ldbl-opt/creall.c b/sysdeps/ieee754/ldbl-opt/creall.c
> deleted file mode 100644
> index 68fedd4..0000000
> --- a/sysdeps/ieee754/ldbl-opt/creall.c
> +++ /dev/null
> @@ -1,6 +0,0 @@
> -#include <complex.h>
> -#include <math_ldbl_opt.h>
> -#undef weak_alias
> -#define weak_alias(n,a)
> -#include <math/creall.c>
> -long_double_symbol (libm, __creall, creall);
> diff --git a/sysdeps/ieee754/ldbl-opt/math-type-macros.h b/sysdeps/ieee754/ldbl-opt/math-type-macros.h
> new file mode 100644
> index 0000000..f963f77
> --- /dev/null
> +++ b/sysdeps/ieee754/ldbl-opt/math-type-macros.h
> @@ -0,0 +1,11 @@
> +/* Include the long double compatability support for generated math files.  */
> +#include <math_ldbl_opt.h>
> +
> +/* Declare compat versions for generated functions.  */
> +#define LDOUBLE_cabsl_libm_version GLIBC_2_1
> +#define LDOUBLE_cargl_libm_version GLIBC_2_1
> +#define LDOUBLE_cimagl_libm_version GLIBC_2_1
> +#define LDOUBLE_conjl_libm_version GLIBC_2_1
> +#define LDOUBLE_creall_libm_version GLIBC_2_1
> +
> +#include_next <math-type-macros.h>
>

Patch
diff mbox

diff --git a/Makeconfig b/Makeconfig
index 901e253..8a7b5f2 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -1124,7 +1124,7 @@  endif
 # emitted into sysd-rules.  A sysdeps Makeconfig fragment can
 # add its own special object file prefix to this list with e.g. foo-%:%
 # to have foo-*.? compiled from *.? using $(foo-CPPFLAGS).
-sysd-rules-patterns := %:% rtld-%:rtld-% rtld-%:% m_%:s_%
+sysd-rules-patterns := %:% rtld-%:rtld-% rtld-%:%
 
 # Let sysdeps/ subdirs contain a Makeconfig fragment for us to include here.
 sysdep-makeconfigs := $(wildcard $(+sysdep_dirs:=/Makeconfig))
diff --git a/math/Makefile b/math/Makefile
index 89002a8..14f8f42 100644
--- a/math/Makefile
+++ b/math/Makefile
@@ -43,6 +43,18 @@  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 b_func.c file.
+#
+# Similarly, a platform can override any of these generated functions
+# (after type suffix substitution occurs) by adding a fragment which
+# defines libm-gen-calls-override and lists each function which should
+# not use the default version. If declared, it is assumed the target
+# will match the name s_<func><type suffix>
+gen-libm-calls = g_carg_F g_conj_F g_cimag_F g_creal_F g_cabs_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	  \
@@ -59,13 +71,13 @@  libm-calls =								  \
 	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 \
+	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 lgamma_negF lgamma_productF			  \
-	s_nextupF s_nextdownF
+	s_nextupF s_nextdownF $(gen-libm-calls)
 
 libm-compat-calls-ldouble-yes = w_lgamma_compatl k_standardl
 libm-compat-calls = w_lgamma_compatf w_lgamma_compat k_standard k_standardf \
@@ -105,7 +117,9 @@  type-float-routines :=
 type-foreach = $(foreach t,$(types),$(subst F,$(type-$(t)-suffix),$(1)))
 
 libm-routines = $(strip $(libm-support) $(libm-compat-calls)		\
-			$(call type-foreach, $(libm-calls))		\
+			$(filter-out $(libm-gen-calls-override),	\
+				$(call type-foreach, $(libm-calls)))	\
+			$(libm-gen-replacement-calls)			\
 			$(foreach t, $(types), $(type-$(t)-routines))) 	\
 
 # These functions are in libc instead of libm because __printf_fp
@@ -118,6 +132,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_%$(s))))
 routines = $(call type-foreach, $(calls))
 
+# Wrappers and what not are generated per type to keep the noise down.
+generated += $(foreach s,.c .S,$(call type-foreach,$(gen-libm-calls:%=%$(s))))
+
 ifeq ($(build-mathvec),yes)
 # We need to install libm.so as linker script
 # for more comfortable use of vector math library.
@@ -303,6 +320,34 @@  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))
+
+# Add special flags to control how the templated functions
+# are built.
+g_CPPFLAGS = -include math-type-macros.h
+g__fCPPFLAGS = $(g_CPPFLAGS) -DM_TYPE=M_FLOAT
+g__CPPFLAGS = $(g_CPPFLAGS) -DM_TYPE=M_DOUBLE
+g__lCPPFLAGS = $(g_CPPFLAGS) -DM_TYPE=M_LDOUBLE
+
+# Like m_% above, this builds the generic sources.  Makeconfig
+# enumerates the sysd-rules for overriding.
+define o-iterator-doit
+$(objpfx)g_%$o: b_%.c $(before-compile); $$(compile-command.c)
+endef
+object-suffixes-left := $(gen-suffixes)
+include $(o-iterator)
+
+# Tack on the appropriate CPPFLAGS to match sysd-rules
+define o-iterator-doit
+$(objpfx)g_%$o: CPPFLAGS += $(g_$(basename $o)CPPFLAGS)
+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/b_cabs.c b/math/b_cabs.c
new file mode 100644
index 0000000..64265f1
--- /dev/null
+++ b/math/b_cabs.c
@@ -0,0 +1,33 @@ 
+/* Return the complex absolute value 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>
+
+FLOAT
+M_SUF (__cabs) (CFLOAT z)
+{
+  return M_SUF (__hypot) (__real__ z, __imag__ z);
+}
+
+declare_mgen_alias (__cabs, cabs)
+
+#if M_LIBM_NEED_COMPAT (cabs)
+  declare_mgen_libm_compat (__cabs, cabs)
+#endif
diff --git a/math/b_carg.c b/math/b_carg.c
new file mode 100644
index 0000000..004e14d
--- /dev/null
+++ b/math/b_carg.c
@@ -0,0 +1,33 @@ 
+/* 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>
+
+FLOAT
+M_SUF (__carg) (CFLOAT x)
+{
+  return M_SUF (__atan2) (__imag__ x, __real__ x);
+}
+
+declare_mgen_alias (__carg, carg)
+
+#if M_LIBM_NEED_COMPAT (carg)
+  declare_mgen_libm_compat (__carg, carg)
+#endif
diff --git a/math/b_cimag.c b/math/b_cimag.c
new file mode 100644
index 0000000..73450f3
--- /dev/null
+++ b/math/b_cimag.c
@@ -0,0 +1,32 @@ 
+/* Return imaginary part 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>
+
+FLOAT
+M_SUF (__cimag) (CFLOAT z)
+{
+  return __imag__ z;
+}
+
+declare_mgen_alias (__cimag, cimag)
+
+#if M_LIBM_NEED_COMPAT (cimag)
+  declare_mgen_libm_compat (__cimag, cimag)
+#endif
diff --git a/math/b_conj.c b/math/b_conj.c
new file mode 100644
index 0000000..979a759
--- /dev/null
+++ b/math/b_conj.c
@@ -0,0 +1,32 @@ 
+/* Return complex conjugate 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>
+
+CFLOAT
+M_SUF (__conj) (CFLOAT z)
+{
+  return ~z;
+}
+
+declare_mgen_alias (__conj, conj)
+
+#if M_LIBM_NEED_COMPAT (conj)
+  declare_mgen_libm_compat (__conj, conj)
+#endif
diff --git a/math/b_creal.c b/math/b_creal.c
new file mode 100644
index 0000000..b92e0a3
--- /dev/null
+++ b/math/b_creal.c
@@ -0,0 +1,32 @@ 
+/* Return real part 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>
+
+FLOAT
+M_SUF (__creal) (CFLOAT z)
+{
+  return __real__ z;
+}
+
+declare_mgen_alias (__creal, creal)
+
+#if M_LIBM_NEED_COMPAT (creal)
+  declare_mgen_libm_compat (__creal, creal)
+#endif
diff --git a/math/cabs.c b/math/cabs.c
deleted file mode 100644
index d7e0665..0000000
--- a/math/cabs.c
+++ /dev/null
@@ -1,32 +0,0 @@ 
-/* Return the complex absolute value of double complex 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
-__cabs (double _Complex z)
-{
-  return __hypot (__real__ z, __imag__ z);
-}
-weak_alias (__cabs, cabs)
-#ifdef NO_LONG_DOUBLE
-strong_alias (__cabs, __cabsl)
-weak_alias (__cabs, cabsl)
-#endif
diff --git a/math/cabsf.c b/math/cabsf.c
deleted file mode 100644
index 431a244..0000000
--- a/math/cabsf.c
+++ /dev/null
@@ -1,28 +0,0 @@ 
-/* Return the complex absolute value of float complex 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
-__cabsf (float _Complex z)
-{
-  return __hypotf (__real__ z, __imag__ z);
-}
-weak_alias (__cabsf, cabsf)
diff --git a/math/cabsl.c b/math/cabsl.c
deleted file mode 100644
index d87e3a2..0000000
--- a/math/cabsl.c
+++ /dev/null
@@ -1,28 +0,0 @@ 
-/* Return the complex absolute value of long double complex 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
-__cabsl (long double _Complex z)
-{
-  return __hypotl (__real__ z, __imag__ z);
-}
-weak_alias (__cabsl, cabsl)
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/cimag.c b/math/cimag.c
deleted file mode 100644
index 1807ac2..0000000
--- a/math/cimag.c
+++ /dev/null
@@ -1,31 +0,0 @@ 
-/* Return imaginary part 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>
-
-double
-__cimag (double _Complex z)
-{
-  return __imag__ z;
-}
-weak_alias (__cimag, cimag)
-#ifdef NO_LONG_DOUBLE
-strong_alias (__cimag, __cimagl)
-weak_alias (__cimag, cimagl)
-#endif
diff --git a/math/cimagf.c b/math/cimagf.c
deleted file mode 100644
index 67c37f4..0000000
--- a/math/cimagf.c
+++ /dev/null
@@ -1,27 +0,0 @@ 
-/* Return imaginary part 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>
-
-float
-__cimagf (float _Complex z)
-{
-  return __imag__ z;
-}
-weak_alias (__cimagf, cimagf)
diff --git a/math/cimagl.c b/math/cimagl.c
deleted file mode 100644
index c1d0910..0000000
--- a/math/cimagl.c
+++ /dev/null
@@ -1,27 +0,0 @@ 
-/* Return imaginary part 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>
-
-long double
-__cimagl (long double _Complex z)
-{
-  return __imag__ z;
-}
-weak_alias (__cimagl, cimagl)
diff --git a/math/conj.c b/math/conj.c
deleted file mode 100644
index d282985..0000000
--- a/math/conj.c
+++ /dev/null
@@ -1,31 +0,0 @@ 
-/* Return complex conjugate 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>
-
-double _Complex
-__conj (double _Complex z)
-{
-  return ~z;
-}
-weak_alias (__conj, conj)
-#ifdef NO_LONG_DOUBLE
-strong_alias (__conj, __conjl)
-weak_alias (__conj, conjl)
-#endif
diff --git a/math/conjf.c b/math/conjf.c
deleted file mode 100644
index 3587c94..0000000
--- a/math/conjf.c
+++ /dev/null
@@ -1,27 +0,0 @@ 
-/* Return complex conjugate 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>
-
-float _Complex
-__conjf (float _Complex z)
-{
-  return ~z;
-}
-weak_alias (__conjf, conjf)
diff --git a/math/conjl.c b/math/conjl.c
deleted file mode 100644
index 55bb393..0000000
--- a/math/conjl.c
+++ /dev/null
@@ -1,27 +0,0 @@ 
-/* Return complex conjugate 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>
-
-long double _Complex
-__conjl (long double _Complex z)
-{
-  return ~z;
-}
-weak_alias (__conjl, conjl)
diff --git a/math/creal.c b/math/creal.c
deleted file mode 100644
index 231d3b0..0000000
--- a/math/creal.c
+++ /dev/null
@@ -1,31 +0,0 @@ 
-/* Return real part 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>
-
-double
-__creal (double _Complex z)
-{
-  return __real__ z;
-}
-weak_alias (__creal, creal)
-#ifdef NO_LONG_DOUBLE
-strong_alias (__creal, __creall)
-weak_alias (__creal, creall)
-#endif
diff --git a/math/crealf.c b/math/crealf.c
deleted file mode 100644
index 5883849..0000000
--- a/math/crealf.c
+++ /dev/null
@@ -1,27 +0,0 @@ 
-/* Return real part 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>
-
-float
-__crealf (float _Complex z)
-{
-  return __real__ z;
-}
-weak_alias (__crealf, crealf)
diff --git a/math/creall.c b/math/creall.c
deleted file mode 100644
index 4a31557..0000000
--- a/math/creall.c
+++ /dev/null
@@ -1,27 +0,0 @@ 
-/* Return real part 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>
-
-long double
-__creall (long double _Complex z)
-{
-  return __real__ z;
-}
-weak_alias (__creall, creall)
diff --git a/scripts/sysd-rules.awk b/scripts/sysd-rules.awk
index 69af400..ccf1dff 100644
--- a/scripts/sysd-rules.awk
+++ b/scripts/sysd-rules.awk
@@ -18,6 +18,9 @@  BEGIN {
   # They are no in particular order.  We need to sort them so that
   # the longest TARGET is first, and, among elements with the same
   # TARGET, the longest DEP is first.
+  #
+  # If two TARGETs have the same length DEP, the first TARGET is
+  # always listed first.
   for (i = 1; i <= npatterns; ++i) {
     if (split(patterns[i], td, ":") != 2) {
       msg = "bad sysd-rules-patterns element '" patterns[i] "'";
@@ -25,7 +28,7 @@  BEGIN {
       exit 2;
     }
     target_order = sprintf("%09d", npatterns + 1 - length(td[1]));
-    dep_order = sprintf("%09d", npatterns - length(td[2]));
+    dep_order = sprintf("%09d%03d", npatterns - length(td[2]), i);
     sort_patterns[target_order SUBSEP dep_order] = patterns[i];
   }
   asorti(sort_patterns, map_patterns);
diff --git a/sysdeps/alpha/fpu/Makefile b/sysdeps/alpha/fpu/Makefile
new file mode 100644
index 0000000..c49c302
--- /dev/null
+++ b/sysdeps/alpha/fpu/Makefile
@@ -0,0 +1,4 @@ 
+# Inhibit generation of these math files as they are supplied via
+# the respectic s_*.c versions here.
+libm-gen-calls-override = g_cabs_f g_carg_f g_cimag_f g_creal_f g_conj_f
+libm-gen-replacement-calls = cabsf cargf cimagf crealf conjf
diff --git a/sysdeps/generic/math-type-macros.h b/sysdeps/generic/math-type-macros.h
new file mode 100644
index 0000000..3befde1
--- /dev/null
+++ b/sysdeps/generic/math-type-macros.h
@@ -0,0 +1,159 @@ 
+/* 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(c) c ## f
+/* Use the double version instead.  */
+# define M_MLIT(c) c
+# define M_SUF(c) c ## f
+# define M_FUNC(c) c ## f
+# define FLOAT float
+# define CFLOAT __complex__ float
+# define M_HUGE_VAL HUGE_VALF
+#elif M_TYPE == M_DOUBLE
+# define M_PFX DBL
+# define M_LIT(c) c
+# define M_MLIT(c) c
+# define M_SUF(c) c
+# define M_FUNC(c) c
+# define FLOAT double
+# define CFLOAT __complex__ double
+# define M_HUGE_VAL HUGE_VAL
+#elif M_TYPE == M_LDOUBLE
+# define M_PFX LDBL
+# define M_LIT(c) c ## L
+# define M_MLIT(c) c ## l
+# define M_SUF(c) c ## l
+# define M_FUNC(c) c ## l
+# define FLOAT long double
+# define CFLOAT __complex__ long double
+# define M_HUGE_VAL HUGE_VALL
+#else
+# error Error: M_TYPE is not a known floating point type
+#endif
+
+#define __M_CONCAT(a,b) a ## b
+#define __M_CONCATX(a,b) __M_CONCAT(a,b)
+
+#define M_NAN M_FUNC (__nan) ("")
+#define M_MAX_EXP __M_CONCATX (M_PFX, _MAX_EXP)
+#define M_MIN __M_CONCATX (M_PFX, _MIN)
+#define M_MAX __M_CONCATX (M_PFX, _MAX)
+#define M_MANT_DIG __M_CONCATX (M_PFX, _MANT_DIG)
+
+/* Helper macros for commonly used functions.  */
+#define M_COPYSIGN M_FUNC (__copysign)
+#define M_FABS M_FUNC (fabs)
+#define M_SINCOS M_FUNC (__sincos)
+#define M_SCALBN M_FUNC (__scalbn)
+#define M_LOG1P M_FUNC (__log1p)
+
+#define M_ATAN2 M_FUNC (__ieee754_atan2)
+#define M_COSH M_FUNC (__ieee754_cosh)
+#define M_EXP M_FUNC (__ieee754_exp)
+#define M_HYPOT M_FUNC (__ieee754_hypot)
+#define M_LOG M_FUNC (__ieee754_log)
+#define M_SINH M_FUNC (__ieee754_sinh)
+#define M_SQRT M_FUNC (__ieee754_sqrt)
+
+/* Needed to evaluate M_MANT_DIG below.  */
+#include <float.h>
+
+/* Use a special epsilon value for IBM long double
+   to avoid spurious overflows.  */
+#if M_MANT_DIG != 106
+# define M_EPSILON __M_CONCATX (M_PFX, _EPSILON)
+#else
+# define M_EPSILON 0x1p-106L
+#endif
+
+/* Enable overloading of function name to assist
+   reuse.  */
+#ifndef M_DECL_FUNC
+# define M_DECL_FUNC(f) M_FUNC(f)
+#endif
+
+/* Rules for aliasing the currently generated math files.  */
+
+/* Aliasing rules for float are straight forward.  */
+#if M_TYPE == M_FLOAT
+# define declare_mgen_alias(from, to) weak_alias (M_SUF (from), M_SUF (to))
+#endif
+
+/* Aliasing rules for double are sightly more
+   complicated.
+   1. long double == double.
+   2. long double used to be double.
+   3. double has always been unique. */
+#if M_TYPE == M_DOUBLE
+# if defined NO_LONG_DOUBLE
+#  define declare_mgen_alias(from, to)	    \
+    weak_alias (from, to)		    \
+    strong_alias (from, from ## l)	    \
+    weak_alias (from, to ## l)
+# else
+#  define declare_mgen_alias(from, to)	    \
+    weak_alias (M_SUF (from), M_SUF (to))
+# endif
+#endif
+
+/* Slightly simpler for long double.
+   1. long double used to be double.
+   2. long double has always been unique.  */
+#if M_TYPE == M_LDOUBLE
+# if defined LONG_DOUBLE_COMPAT_VERSION
+#  define declare_mgen_alias(from, to)		  \
+    long_double_symbol (libm, from ## l, to ## l);
+# else
+#  define declare_mgen_alias(from, to)	    \
+    weak_alias (M_SUF (from), M_SUF (to))
+# endif
+#endif
+
+#if ! defined declare_mgen_alias
+# error Alias rules not defined for M_TYPE
+#endif
+
+/* From case 2 for double, we may need to declare compat
+   aliases for double symbols mapping to long double.
+
+   This suffices for the majority of the complex functions.
+   More interesting cases need to be handled on a case by
+   case basis.  */
+#if M_TYPE == M_DOUBLE && defined LONG_DOUBLE_COMPAT_VERSION
+# define M_LIBM_NEED_COMPAT(f)				      \
+  LONG_DOUBLE_COMPAT (libm, LDOUBLE_ ## f ## l_libm_version)
+# define declare_mgen_libm_compat(from, to)	      \
+    compat_symbol (libm,			      \
+		   from,			      \
+		   to ## l,			      \
+		   LDOUBLE_ ## to ## l_libm_version);
+#else
+# define M_LIBM_NEED_COMPAT(func) 0
+# define declare_mgen_libm_compat(from, to)
+#endif
+
+#endif /* _MATH_TYPE_MACROS */
diff --git a/sysdeps/ieee754/Makeconfig b/sysdeps/ieee754/Makeconfig
new file mode 100644
index 0000000..15fd238
--- /dev/null
+++ b/sysdeps/ieee754/Makeconfig
@@ -0,0 +1,6 @@ 
+# Add the rules for generated math files in sysdeps
+# Not the perfect place, but close enough.
+#
+# Each type supported by libm should have a g_%_SUFFIX
+# pattern to match its suffix.
+sysd-rules-patterns += m_%:s_% g_%_f:b_% g_%_l:b_% g_%_:b_%
diff --git a/sysdeps/ieee754/ldbl-opt/cabs.c b/sysdeps/ieee754/ldbl-opt/cabs.c
deleted file mode 100644
index a181de2..0000000
--- a/sysdeps/ieee754/ldbl-opt/cabs.c
+++ /dev/null
@@ -1,6 +0,0 @@ 
-#include <complex.h>
-#include <math_ldbl_opt.h>
-#include <math/cabs.c>
-#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
-compat_symbol (libm, __cabs, cabsl, GLIBC_2_1);
-#endif
diff --git a/sysdeps/ieee754/ldbl-opt/cabsl.c b/sysdeps/ieee754/ldbl-opt/cabsl.c
deleted file mode 100644
index b861633..0000000
--- a/sysdeps/ieee754/ldbl-opt/cabsl.c
+++ /dev/null
@@ -1,6 +0,0 @@ 
-#include <complex.h>
-#include <math_ldbl_opt.h>
-#undef weak_alias
-#define weak_alias(n,a)
-#include <math/cabsl.c>
-long_double_symbol (libm, __cabsl, cabsl);
diff --git a/sysdeps/ieee754/ldbl-opt/carg.c b/sysdeps/ieee754/ldbl-opt/carg.c
deleted file mode 100644
index 2ed3581..0000000
--- a/sysdeps/ieee754/ldbl-opt/carg.c
+++ /dev/null
@@ -1,6 +0,0 @@ 
-#include <complex.h>
-#include <math_ldbl_opt.h>
-#include <math/carg.c>
-#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
-compat_symbol (libm, __carg, cargl, GLIBC_2_1);
-#endif
diff --git a/sysdeps/ieee754/ldbl-opt/cargl.c b/sysdeps/ieee754/ldbl-opt/cargl.c
deleted file mode 100644
index 952dc60..0000000
--- a/sysdeps/ieee754/ldbl-opt/cargl.c
+++ /dev/null
@@ -1,6 +0,0 @@ 
-#include <complex.h>
-#include <math_ldbl_opt.h>
-#undef weak_alias
-#define weak_alias(n,a)
-#include <math/cargl.c>
-long_double_symbol (libm, __cargl, cargl);
diff --git a/sysdeps/ieee754/ldbl-opt/cimag.c b/sysdeps/ieee754/ldbl-opt/cimag.c
deleted file mode 100644
index f805258..0000000
--- a/sysdeps/ieee754/ldbl-opt/cimag.c
+++ /dev/null
@@ -1,6 +0,0 @@ 
-#include <complex.h>
-#include <math_ldbl_opt.h>
-#include <math/cimag.c>
-#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
-compat_symbol (libm, __cimag, cimagl, GLIBC_2_1);
-#endif
diff --git a/sysdeps/ieee754/ldbl-opt/cimagl.c b/sysdeps/ieee754/ldbl-opt/cimagl.c
deleted file mode 100644
index 112365e..0000000
--- a/sysdeps/ieee754/ldbl-opt/cimagl.c
+++ /dev/null
@@ -1,6 +0,0 @@ 
-#include <complex.h>
-#include <math_ldbl_opt.h>
-#undef weak_alias
-#define weak_alias(n,a)
-#include <math/cimagl.c>
-long_double_symbol (libm, __cimagl, cimagl);
diff --git a/sysdeps/ieee754/ldbl-opt/conj.c b/sysdeps/ieee754/ldbl-opt/conj.c
deleted file mode 100644
index e4edade..0000000
--- a/sysdeps/ieee754/ldbl-opt/conj.c
+++ /dev/null
@@ -1,6 +0,0 @@ 
-#include <complex.h>
-#include <math_ldbl_opt.h>
-#include <math/conj.c>
-#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
-compat_symbol (libm, __conj, conjl, GLIBC_2_1);
-#endif
diff --git a/sysdeps/ieee754/ldbl-opt/conjl.c b/sysdeps/ieee754/ldbl-opt/conjl.c
deleted file mode 100644
index c98e0ed..0000000
--- a/sysdeps/ieee754/ldbl-opt/conjl.c
+++ /dev/null
@@ -1,6 +0,0 @@ 
-#include <complex.h>
-#include <math_ldbl_opt.h>
-#undef weak_alias
-#define weak_alias(n,a)
-#include <math/conjl.c>
-long_double_symbol (libm, __conjl, conjl);
diff --git a/sysdeps/ieee754/ldbl-opt/creal.c b/sysdeps/ieee754/ldbl-opt/creal.c
deleted file mode 100644
index 0d1c93e..0000000
--- a/sysdeps/ieee754/ldbl-opt/creal.c
+++ /dev/null
@@ -1,6 +0,0 @@ 
-#include <complex.h>
-#include <math_ldbl_opt.h>
-#include <math/creal.c>
-#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
-compat_symbol (libm, __creal, creall, GLIBC_2_1);
-#endif
diff --git a/sysdeps/ieee754/ldbl-opt/creall.c b/sysdeps/ieee754/ldbl-opt/creall.c
deleted file mode 100644
index 68fedd4..0000000
--- a/sysdeps/ieee754/ldbl-opt/creall.c
+++ /dev/null
@@ -1,6 +0,0 @@ 
-#include <complex.h>
-#include <math_ldbl_opt.h>
-#undef weak_alias
-#define weak_alias(n,a)
-#include <math/creall.c>
-long_double_symbol (libm, __creall, creall);
diff --git a/sysdeps/ieee754/ldbl-opt/math-type-macros.h b/sysdeps/ieee754/ldbl-opt/math-type-macros.h
new file mode 100644
index 0000000..f963f77
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-opt/math-type-macros.h
@@ -0,0 +1,11 @@ 
+/* Include the long double compatability support for generated math files.  */
+#include <math_ldbl_opt.h>
+
+/* Declare compat versions for generated functions.  */
+#define LDOUBLE_cabsl_libm_version GLIBC_2_1
+#define LDOUBLE_cargl_libm_version GLIBC_2_1
+#define LDOUBLE_cimagl_libm_version GLIBC_2_1
+#define LDOUBLE_conjl_libm_version GLIBC_2_1
+#define LDOUBLE_creall_libm_version GLIBC_2_1
+
+#include_next <math-type-macros.h>