diff --git a/math/Makefile b/math/Makefile
index 9d18ade..f19cdfd 100644
--- a/math/Makefile
+++ b/math/Makefile
@@ -43,6 +43,12 @@ libm-support = s_lib_version s_matherr s_signgam			\
 	       fesetenv feupdateenv t_exp fedisblxcpt feenablxcpt	\
 	       fegetexcept
 
+# These functions are generated from a common source with a select macros
+# for each type they built for.  There is an explicit underscore between
+# the function name and the type suffix to simplify matching to the
+# rule used to build it.  These all build from a common t_func.c file.
+gen-libm-calls = g_carg_F
+
 libm-calls = e_acosF e_acoshF e_asinF e_atan2F e_atanhF e_coshF e_expF e_fmodF	\
 	     e_hypotF e_j0F e_j1F e_jnF e_lgammaF_r e_logF e_log10F e_powF	\
 	     e_rem_pio2F e_remainderF e_scalbF e_sinhF e_sqrtF e_gammaF_r	\
@@ -58,12 +64,13 @@ libm-calls = e_acosF e_acoshF e_asinF e_atan2F e_atanhF e_coshF e_expF e_fmodF	\
 	     w_ilogbF								\
 	     s_fpclassifyF s_fmaxF s_fminF s_fdimF s_nanF s_truncF		\
 	     s_remquoF e_log2F e_exp2F s_roundF s_nearbyintF s_sincosF		\
-	     conjF cimagF crealF cabsF cargF s_cexpF s_csinhF s_ccoshF s_clogF	\
+	     conjF cimagF crealF cabsF s_cexpF s_csinhF s_ccoshF s_clogF	\
 	     s_catanF s_casinF s_ccosF s_csinF s_ctanF s_ctanhF s_cacosF	\
 	     s_casinhF s_cacoshF s_catanhF s_csqrtF s_cpowF s_cprojF s_clog10F 	\
 	     s_fmaF s_lrintF s_llrintF s_lroundF s_llroundF e_exp10F w_log2F	\
 	     s_issignalingF $(calls:s_%=m_%) x2y2m1F k_casinhF			\
 	     gamma_productF k_standardF lgamma_negF lgamma_productF		\
+	     $(gen-libm-calls)
 
 libm-compat-calls = w_lgamma_compatf w_lgamma_compat w_lgamma_compatl
 
@@ -114,6 +121,9 @@ calls = s_isinfF s_isnanF s_finiteF s_copysignF s_modfF s_scalbnF s_frexpF \
 generated += $(foreach s,.c .S,$(call type-foreach, $(calls:s_%=m_%)))
 routines = $(call type-foreach, $(calls))
 
+# Wrappers and what not are generated per type to keep the noise down.
+generated += $(foreach g,.c .S,$(call type-foreach, $(gen-libm-calls)))
+
 ifeq ($(build-mathvec),yes)
 # We need to install libm.so as linker script
 # for more comfortable use of vector math library.
@@ -301,6 +311,32 @@ endef
 object-suffixes-left := $(all-object-suffixes)
 include $(o-iterator)
 
+# Generated per-type files.
+#
+# Suffixes for each generated file.  This hackery makes it possible
+# to correctly identify name of the templated file.
+gen-suffixes := $(foreach s,$(all-object-suffixes), \
+			$(foreach t,$(types),_$(type-$(t)-suffix)$s))
+
+# Declare the type for each build of the type-generic files.
+CPPFLAGS-mtype_l = -DM_TYPE=M_LDOUBLE
+CPPFLAGS-mtype_  = -DM_TYPE=M_DOUBLE
+CPPFLAGS-mtype_f = -DM_TYPE=M_FLOAT
+
+# One rule to build to them all.
+define o-iterator-doit
+$(objpfx)g_%$o: t_%.c $(before-compile); $$(compile-command.c)
+endef
+object-suffixes-left := $(gen-suffixes)
+include $(o-iterator)
+
+# And anther one to pass in the extra cpp flags to build them
+# correctly.
+define o-iterator-doit
+$(objpfx)g_%$o: CPPFLAGS += $(CPPFLAGS-mtype$(basename $o))
+endef
+object-suffixes-left := $(gen-suffixes)
+include $(o-iterator)
 
 # This file defines the default _LIB_VERSION variable that controls
 # the error return conventions for the math functions.
diff --git a/math/carg.c b/math/carg.c
deleted file mode 100644
index 61f1e0d..0000000
--- a/math/carg.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/* Compute argument of complex double value.
-   Copyright (C) 1997-2016 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <complex.h>
-#include <math.h>
-
-double
-__carg (__complex__ double x)
-{
-  return __atan2 (__imag__ x, __real__ x);
-}
-weak_alias (__carg, carg)
-#ifdef NO_LONG_DOUBLE
-strong_alias (__carg, __cargl)
-weak_alias (__carg, cargl)
-#endif
diff --git a/math/cargf.c b/math/cargf.c
deleted file mode 100644
index 620db3e..0000000
--- a/math/cargf.c
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Compute argument of complex float value.
-   Copyright (C) 1997-2016 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <complex.h>
-#include <math.h>
-
-float
-__cargf (__complex__ float x)
-{
-  return __atan2f (__imag__ x, __real__ x);
-}
-weak_alias (__cargf, cargf)
diff --git a/math/cargl.c b/math/cargl.c
deleted file mode 100644
index 31b7292..0000000
--- a/math/cargl.c
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Compute argument of complex long double value.
-   Copyright (C) 1997-2016 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <complex.h>
-#include <math.h>
-
-long double
-__cargl (__complex__ long double x)
-{
-  return __atan2l (__imag__ x, __real__ x);
-}
-weak_alias (__cargl, cargl)
diff --git a/math/math-type-macros.h b/math/math-type-macros.h
new file mode 100644
index 0000000..a80bb18
--- /dev/null
+++ b/math/math-type-macros.h
@@ -0,0 +1,57 @@
+/* Helper macros for type generic function implementations within libm.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _MATH_TYPE_MACROS
+#define _MATH_TYPE_MACROS
+
+#define M_FLOAT 1
+#define M_DOUBLE 2
+#define M_LDOUBLE 3
+
+#if M_TYPE == M_FLOAT
+# define M_PFX FLT
+# define M_LIT f
+# define M_SUF(c) c ## f
+# define FLOAT float
+#elif M_TYPE == M_DOUBLE
+# define M_PFX DBL
+# define M_LIT
+# define M_SUF(c) c
+# define FLOAT double
+#elif M_TYPE == M_LDOUBLE
+# define M_PFX LDBL
+# define M_LIT L
+# define M_SUF(c) c ## l
+# define FLOAT long double
+#else
+# error Error: M_TYPE must be defined before including
+#endif
+
+/* Optional long double aliasing for targets without a distinct
+   long double type.  */
+#if M_TYPE == M_DOUBLE && defined NO_LONG_DOUBLE
+# define declare_mgen_alias(from, to)	  \
+    weak_alias (from, to ## l)		  \
+    strong_alias (from, to ## l)	  \
+    weak_alias (from, to ## l)
+#else
+# define declare_mgen_alias(from, to)	  \
+    weak_alias (M_SUF (from), M_SUF (to))
+#endif
+
+#endif
diff --git a/math/t_carg.c b/math/t_carg.c
new file mode 100644
index 0000000..4bf6e53
--- /dev/null
+++ b/math/t_carg.c
@@ -0,0 +1,30 @@
+/* Compute argument of complex float type.
+   Copyright (C) 1997-2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <complex.h>
+#include <math.h>
+
+#include "math-type-macros.h"
+
+FLOAT
+M_SUF (__carg) (__complex__ FLOAT x)
+{
+  return M_SUF (__atan2) (__imag__ x, __real__ x);
+}
+declare_mgen_alias (__carg, carg)
diff --git a/sysdeps/alpha/fpu/cargf.c b/sysdeps/alpha/fpu/cargf.c
deleted file mode 100644
index d798a5b..0000000
--- a/sysdeps/alpha/fpu/cargf.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Compute argument of complex float value.
-   Copyright (C) 2004-2016 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library.  If not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#define __cargf __cargf_not_defined
-#define cargf cargf_not_defined
-
-#include <complex.h>
-#include <math.h>
-#include "cfloat-compat.h"
-
-#undef __cargf
-#undef cargf
-
-float
-__c1_cargf (c1_cfloat_decl (x))
-{
-  return __atan2f (c1_cfloat_imag (x), c1_cfloat_real (x));
-}
-
-float
-__c2_cargf (c2_cfloat_decl (x))
-{
-  return __atan2f (c2_cfloat_imag (x), c2_cfloat_real (x));
-}
-
-cfloat_versions (cargf);
diff --git a/sysdeps/alpha/fpu/t_carg.c b/sysdeps/alpha/fpu/t_carg.c
new file mode 100644
index 0000000..3f5619b
--- /dev/null
+++ b/sysdeps/alpha/fpu/t_carg.c
@@ -0,0 +1,49 @@
+/* Compute argument of complex float value.
+   Copyright (C) 2004-2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "math-type-macros.h"
+
+#if M_TYPE == M_FLOAT
+
+# define __cargf __cargf_not_defined
+# define cargf cargf_not_defined
+
+# include <complex.h>
+# include <math.h>
+# include "cfloat-compat.h"
+
+# undef __cargf
+# undef cargf
+
+float
+__c1_cargf (c1_cfloat_decl (x))
+{
+  return __atan2f (c1_cfloat_imag (x), c1_cfloat_real (x));
+}
+
+float
+__c2_cargf (c2_cfloat_decl (x))
+{
+  return __atan2f (c2_cfloat_imag (x), c2_cfloat_real (x));
+}
+
+cfloat_versions (cargf);
+
+#else
+# include <math/t_carg.c>
+#endif
