[PATCHv2 4/4] powerpc64le: ifunc (almost) all *f128 routines in multiarch mode

Matheus Castanho msc@linux.ibm.com
Wed Jun 3 17:34:26 GMT 2020


Hi Paul,

I'm not yet that familiar with libm code, but here goes some high-level
comments.

Thanks,
Matheus Castanho

On 5/6/20 5:45 PM, Paul E. Murphy via Libc-alpha wrote:
> See the Makefile changes for high level design/commentary.
> 
> V2 changes -
>   * move duplicate redirect macros into float128-ifunc-redirect-macros.h
>   * replace subshell usage with command sequencing
>   * Add more instructive documentation in Makefile about how all
>     these ugly pieces work togethor
>   * Minor comment cleanup throughout
>   * Improve inline documentation/commentary throughout
> 
> To test, this depends on the 3 small unchanged pending patches:
> 
> https://sourceware.org/pipermail/libc-alpha/2020-May/113590.html
> https://sourceware.org/pipermail/libc-alpha/2020-May/113588.html
> https://sourceware.org/pipermail/libc-alpha/2020-May/113589.html
> 
> ---8<---
> 
> Programatically generate simple wrappers for most libm *f128
> objects and a set of ifunc objects to unify them.
> 
> A second set of implementation files are generated which simply
> include the first implementation encountered along the search
> path.  This usually works, excepting when a wrapper is overriden
> and makefile search order slightly diverges from include order.
> 

[..]

> diff --git a/sysdeps/powerpc/powerpc64/le/fpu/multiarch/Makefile b/sysdeps/powerpc/powerpc64/le/fpu/multiarch/Makefile
> index 8747b02127..c946d4e51e 100644
> --- a/sysdeps/powerpc/powerpc64/le/fpu/multiarch/Makefile
> +++ b/sysdeps/powerpc/powerpc64/le/fpu/multiarch/Makefile
> @@ -1,10 +1,209 @@
>  ifeq ($(subdir),math)
> -libm-sysdep_routines += s_fmaf128-ppc64 s_fmaf128-power9 \
> -			w_sqrtf128-power9 w_sqrtf128-ppc64le
> +# Only enable this for generic (P8 or older) multiarch builds
> +# TODO: this should be updated to use the inferred minimum
> +#       target architecture when supported by powerpc64le.
> +ifeq ($(cflags-cpu),)
> +do_f128_multiarch = yes
> +else ifneq ($(filter %power8,$(cflags-cpu)),)
> +do_f128_multiarch = yes
> +endif
> +
> +#
> +# This is an ugly, but contained, mechanism to provide hardware optimized
> +# _Float128 and ldouble == ieee128 optimized routines for P9 and beyond
> +# hardware.  At a very high level, we rely on ASM renames, and rarely
> +# macro renames to build two sets of _Float128 ABI, one with _power8 (the
> +# baseline powerpc64le cpu) and power9 (the first powerpc64le cpu to introduce
> +# hardware support for _Float128).
> +#
> +# At a high level, we compile 3 files for each object file.
> +#   1.  The basline soft-float128, unsuffixed objects $(object).$(sfx).

s/basline/baseline/

> +#       This ABI is suffixed with _power8.
> +#   2.  The hard-float128, power9, suffixed objects $(object)-power9.$(sfx)
> +#   3.  The IFUNC wrapper object to export ABI, $(object)-ifunc.$(sfx)
> +#
> +# 2 & 3 are automatically generated by Makefile rule.  Placing the exported
> +# ABI into a separate file allows reuse of existing aliasing macros
> +# with minimal hassle.  Likewise, a backdoor is provided to unilaterally
> +# disable this support per object.
> +#
> +# Changes to APIs will require minor updates to one (or two) places:
> +#
> +#   * Internal float128 API: the float128_private.h interposer.
> +#   * math_private.h API: float128-ifunc-redirects-mp.h
> +#   * templated math API: the math-type-macros-float128.h interposer.
> +#
> +# Some redirects are duplicated between both float128_private.h and
> +# math-type-macros-float128.h as they are not usually included togethor

s/togethor/together/

> +# when building libm.  The hope is this provides minimal burden on
> +# maintainers, and is readily caught by build-many-glibcs.py.
> +#
> +# The above is supported by several carefully crafted header files as
> +# described below:
> +#
> +#   * float128-ifunc.h provides support for generating the IFUNC objects
> +#                      in part 3 above.  It also enables case-by-case
> +#                      overriding as some objects do not expose a uniform
> +#                      ABI.
> +#   * float128-ifunc.c provides compatability ABI using the IFUNC objects.

s/compatability/compatibility/

> +#                      These should rarely change and don't cause trouble
> +#                      when grouped into a single object file as they are
> +#                      on needed for the shared library.

s/on/only/ (?)

> +#   * float128-ifunc-macros.h disables all first-order aliasing macros
> +#                      used in libm/_Float128, but not the backing
> +#                      impementations provide by libc-symbols.h as some

s/impementations/implementation/
s/provide/provided/

> +#                      objects generate strong aliases which make this
> +#                      work easier.
> +#   * float128-ifunc-redirect-macros.h provides macros to support ASM
> +#                      redirect of _Float128 ABI.
> +#   * float128-ifunc-redirects.h provides ASM redirects for functions
> +#                      which are nominally redirected in the private
> +#                      copy of math.h.
> +#   * float128-ifunc-redirects-mp.h provides ASM redirects which are used
> +#                      by math_private.h (the -mp suffix) and the interposer
> +#                      float128_private.h discussed late.
> +#
> +# The headers above should only be included via the interposed headers
> +# discussed below.  Several commonly used headers are interposed to rename all
> +# via ASM redirects.  This requires careful orchestration of header inclusion
> +# to ensure headers are redirected to exlusively _power8 or _power9 suffixed

s/exlusively/exclusively/

> +# ABI.  This also has the desirable side-effect of bypassing the PLT locally
> +# and generating compile time errors if a function is missed or changed.
> +#
> +#   * float128_private.h is currently used to rename the ldouble == ieee128
> +#                      object files today.  This takes it a step further and
> +#                      redirects symbols to _power9 or _power8 variants of the
> +#                      functions.  This supports nearly all files in
> +#                      sysdeps/ieee754/float128, but not all _Float128 objects.
> +#                      However, there are three distinct build configurations
> +#                      used to compile _Float128 support.  Two other headers
> +#                      below complete the ABI redirection.
> +#   * math-type-macros-float128.h supports renames for the common object files
> +#                      which are built from templates in math/.
> +#   * math_private.h provides rename support for the common files built in math/
> +#                      which are neither template generated nor ldbl-128 specific.
> +#                      It should be noted that float128_private.h and math_private.h
> +#                      overlap in their declarations, and are used orthognally.

s/orthognally/orthogonally

> +#
> +#
> +# The above usually works out very well, but there are sometimes special cases
> +# so special you need throw your hands up and give up.  For that, support
> +# is provided to disable the above entirely at an object level.  Today this
> +# includes objects which only provide tables, or have macros so unspeakably
> +# heinous that no reasonable fixup can be provided.  Such objects are declared
> +# in gen-libm-f128-no-ifunc-calls.
> +#
> +# Secondly, this enforces a slightly different mechanism for machine specific
> +# overrides.  That is, all optimizations for all targets must all be reachable
> +# from the same file as the above relies on rebuilding the same file with
> +# different compiler settings.  Most arch specific overrides should be trivial
> +# implementations (e.g sqrt or fma), thus it should present no obstacle.
> +# Likewise, this also enforces them to use the same language (C or ASM today).
> +#
> +# Finally, some designer notes/rambling.  One could naively use target cloning,
> +# but that generates an ifunc per function, not per entry point.  The above
> +# gives us two copies of _Float128 ABI which are entirely isolated, and
> +# need no internal ifunc usage to disambiguate.  ASM renames are preferable
> +# to macro renames.  The latter causes many macro expansion bugs which require
> +# many ugly fixups (that was my first attempt).  Secondly, one may note libgcc
> +# provides ifunc routines for soft-fp functions, why this?  Such callouts
> +# inhibit most compiler optimization and result in not so great code.  Next,
> +# why not libc too?  Inspecting libc, the reachable _Float128 code only makes
> +# a single digit number of soft-fp calls.  The benefit of the above is limited.
> +#
> +ifeq ($(do_f128_multiarch),yes)
> +
> +gen-libm-all-f128-ifunc-calls = \
> +	$(strip $(subst F,$(type-float128-suffix),$(libm-calls)) \
> +		$(foreach f,$(libm-narrow-fns),$(subst F,$(f),$(libm-narrow-types-float128-yes))) \
> +		$(type-float128-routines))
> +
> +# Some functions are not trivial to ifunc today without some extensive refactoring.
> +# totalorder{,mag} have no benefit to native IEEE support and have complex versioning requirements.
> +# Likewise, tables require no special treatment.
> +gen-libm-f128-no-ifunc-calls := s_totalorderf128 s_totalordermagf128 t_sincosf128
> +gen-libm-f128-ifunc-calls = $(filter-out $(gen-libm-f128-no-ifunc-calls),$(gen-libm-all-f128-ifunc-calls))
> +
> +f128-march-routines-p9 = $(addsuffix -power9,$(gen-libm-f128-ifunc-calls))
> +f128-march-routines-ifunc = $(addsuffix -ifunc,$(gen-libm-f128-ifunc-calls))
> +f128-march-routines = $(f128-march-routines-p9) $(f128-march-routines-ifunc)
> +f128-march-cpus = power9
> +
> +libm-routines += $(f128-march-routines) float128-ifunc
> +generated += $(f128-march-routines)
> +
> +# These are files should disable multi arch support entirely.  This

I believe this sentence could be rephrased. Do you mean something like
below?

  These are files for which we should disable multi arch support entirely.

> +# list should include all files used to build the objects listed in
> +# gen-libm-f128-no-ifunc-calls.
> +CPPFLAGS-s_totalorderf128.c += -D_F128_DISABLE_IFUNC
> +CPPFLAGS-s_totalordermagf128.c += -D_F128_DISABLE_IFUNC
> +CPPFLAGS-float128-ifunc.c += -D_F128_DISABLE_IFUNC
> +
> +CFLAGS-float128-ifunc.c += $(type-float128-CFLAGS) $(no-gnu-attribute-CFLAGS)
> +
> +# Copy special CFLAGS for some functions
> +CFLAGS-m_modff128-power9.c += -fsignaling-nans
> +
> +# Generate wrapper objects for each machine,
> +# and a separate ifunc wrapper.  Likewise substitute
> +# m_%.c files should include s_%.c to match common libm rules
> +# for files built in both libm and libc.
> +$(objpfx)gen-float128-ifuncs.stmp: Makefile
> +	$(make-target-directory)
> +	for gcall in $(gen-libm-f128-ifunc-calls); do    \
> +	  ifile="$${gcall}";                             \
> +	  if [ $${gcall##m_} != $${gcall} ]; then        \
> +	    ifile="s_$${gcall##m_}";                     \
> +	  fi;                                            \
> +	  for cpu in $(f128-march-cpus); do              \
> +	    file=$(objpfx)$${gcall}-$${cpu}.c;           \
> +	    {                                            \
> +	      echo "#include <$${ifile}.c>";             \
> +	    } > $${file};                                \
> +	    done;                                        \

Align done; with for.

> +	  name="$${gcall##?_}";                          \
> +	  pfx="$${gcall%%_*}";                           \
> +	  R="";                                          \
> +	  r="";                                          \
> +	  if [ $${gcall##m_} != $${gcall} ]; then        \
> +	    pfx="s";                                     \
> +	  fi;                                            \

Why do you need this extra check? Won't $pfx already be 's' if
$name is something like 's_somefunc'?

> +	  if [ $${#pfx} != 1 ]; then                     \
> +	    pfx="";                                      \
> +	  else                                           \
> +	    pfx="_$${pfx}";                              \
> +	  fi;                                            \
> +	  if [ $${name%%_r} != $${name} ]; then          \
> +	    R="_R";                                      \
> +	    r="_r";                                      \
> +	    name="$${name%%_r}";                         \
> +	  fi;                                            \
> +	  name="$${name%%f128}";                         \
> +	  decl="DECL_ALIAS$${pfx}_$${name}$${r}";        \
> +	  declc="DECL_ALIAS$${R}$${pfx}";                \
> +	  {                                              \
> +	    echo "#include <float128-ifunc.h>";          \
> +	    echo "#ifndef $${decl}";                     \
> +	    echo "# define $${decl}(f) $${declc} (f)";   \
> +	    echo "#endif";                               \
> +	    echo "$${decl} ($${name});";                 \
> +	  } > $(objpfx)$${gcall}-ifunc.c;                \
> +	done;                                            \
> +	echo > $(@)
> +
> +$(foreach f,$(f128-march-routines),$(objpfx)$(f).c): $(objpfx)gen-float128-ifuncs.stmp
> +
> +include $(o-iterator)
> +define o-iterator-doit
> +$(foreach f,$(f128-march-routines-p9),$(objpfx)$(f)$(o)): sysdep-CFLAGS += -mcpu=power9 $$(type-float128-CFLAGS) $$(no-gnu-attributes-CFLAGS)
> +endef
> +object-suffixes-left := $(all-object-suffixes)
> +include $(o-iterator)
> +
> +else
>  
> -CFLAGS-s_fmaf128-ppc64.c += $(type-float128-CFLAGS) $(no-gnu-attribute-CFLAGS)
> -CFLAGS-s_fmaf128-power9.c += $(type-float128-CFLAGS) -mcpu=power9 $(no-gnu-attribute-CFLAGS)
> +# Minimum CPU is more than POWER9, this support is not needed.

Shouldn't this be 'more than or equal to POWER9' (or 'at least POWER9')
since the ifunc
code is only used for P8 or less?

> +math-CPPFLAGS += -D_F128_DISABLE_IFUNC
>  
> -CFLAGS-w_sqrtf128-ppc64le.c += $(type-float128-CFLAGS) $(no-gnu-attribute-CFLAGS)
> -CFLAGS-w_sqrtf128-power9.c += $(type-float128-CFLAGS) -mcpu=power9 $(no-gnu-attribute-CFLAGS)
> +endif # do_f128_multiarch
>  endif
> diff --git a/sysdeps/powerpc/powerpc64/le/fpu/multiarch/float128-ifunc-macros.h b/sysdeps/powerpc/powerpc64/le/fpu/multiarch/float128-ifunc-macros.h
> new file mode 100644
> index 0000000000..bfc371310d
> --- /dev/null
> +++ b/sysdeps/powerpc/powerpc64/le/fpu/multiarch/float128-ifunc-macros.h
> @@ -0,0 +1,68 @@
> +/* _Float128 aliasing macro support for ifunc generation on PPC.
> +   Copyright (C) 2020 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#ifndef _FLOAT128_IFUNC_MACROS_PPC64LE
> +#define _FLOAT128_IFUNC_MACROS_PPC64LE 1
> +
> +/* Bring in the various alias providing headers, and disable
> +   those used for _Float128.  This prevents exporting any ABI
> +   from _Float128 impementation objects, or confusing errors

s/impementation/implementation

> +   when a renamed symbol fails to compile.  */
> +#include <libm-alias-float128.h>
> +#include <math-narrow.h>
> +#include <libm-alias-finite.h>
> +
> +#undef libm_alias_float32_float128
> +#undef libm_alias_float64_float128
> +#undef libm_alias_float64x_float128
> +#undef libm_alias_float128_r
> +#undef libm_alias_finite
> +#undef libm_alias_exclusive_ldouble
> +#undef libm_alias_float128_other_r_ldbl
> +#undef declare_mgen_finite_alias
> +#undef declare_mgen_alias
> +#undef declare_mgen_alias_r
> +
> +#define libm_alias_finite(from, to)
> +#define libm_alias_float128_r(from, to, r)
> +#define libm_alias_float32_float128(func)
> +#define libm_alias_float64_float128(func)
> +#define libm_alias_float64x_float128(func)
> +#define libm_alias_exclusive_ldouble(from, to)
> +#define libm_alias_float128_other_r_ldbl(from, to, r)
> +#define declare_mgen_finite_alias(from, to)
> +#define declare_mgen_alias(from, to)
> +#define declare_mgen_alias_r(from, to)

Maybe a nitpick, but having the defines in the same order as the undefs
would make it easier to see that all macros are being properly redefined.

> +
> +/*  Likewise, disable hidden symbol support.  This is not needed
> +    for the implementation objects as the redirects already give
> +    us this support.  This also means any non-_Float128 headers
> +    which provide hidden_def's should be include prior to this

s/include/included/

> +    header (only fenv.h during initial support).  */
> +#undef mathx_hidden_def
> +#define mathx_hidden_def(func)
> +#undef libm_hidden_def
> +#define libm_hidden_def(func)
> +#undef libm_hidden_proto
> +#define libm_hidden_proto(f)
> +#undef hidden_proto
> +#define hidden_proto(f)
> +
> +#include <float128-ifunc-redirect-macros.h>
> +
> +#endif /* _FLOAT128_IFUNC_MACROS_PPC64LE */
> diff --git a/sysdeps/powerpc/powerpc64/le/fpu/multiarch/float128-ifunc-redirect-macros.h b/sysdeps/powerpc/powerpc64/le/fpu/multiarch/float128-ifunc-redirect-macros.h
> new file mode 100644
> index 0000000000..03be468782
> --- /dev/null
> +++ b/sysdeps/powerpc/powerpc64/le/fpu/multiarch/float128-ifunc-redirect-macros.h
> @@ -0,0 +1,53 @@
> +/* _Float128 aliasing macro support for ifunc generation on PPC.
> +   Copyright (C) 2020 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#ifndef _FLOAT128_IFUNC_REDIRECT_MACROS_PPC64LE
> +#define _FLOAT128_IFUNC_REDIRECT_MACROS_PPC64LE 1
> +
> +/*
> +   Define the redirection macros use throughout most of the IFUNC headers.

s/use/used/

> +
> +   F128_REDIR_PFX_R(function, destination_prefix, reentrant_suffix)
> +     Redirect function, optionally suffixed by reentrant_suffix, to a function
> +     named destination_prefix ## function ## cpu ## reentrant_suffix where cpu
> +     is either _power8 or _power9 as inferred by compiler options.
> +
> +    F128_SFX_APPEND(sym)
> +      Append the the multiarch cpu specific suffix to the sym. sym is not
> +      expanded.  This is sym ## cpu, where cpu is eiter power8 or power9
> +      inferred by compiler options.
> +
> +    F128_REDIR_R(func, reentrant_suffix)
> +       Redirect func to a function named function ## cpu ## reentrant_suffix
> +       where cpu is either _power8 or _power9 as inferred by compiler options.
> +
> +    F128_REDIR(function)
> +       Redirect function, to a function named function ## cpu 
> +       where cpu is either _power8 or _power9 as inferred by compiler options.

Use same indentation level for all paragraphs?

> +*/
> +#ifndef _ARCH_PWR9
> +#define F128_REDIR_PFX_R(func, pfx, r) extern __typeof(func ## r) func ## r __asm( #pfx #func "_power8" #r );
> +#define F128_SFX_APPEND(x) x ## _power8
> +#else
> +#define F128_REDIR_PFX_R(func, pfx, r) extern __typeof(func ## r) func ## r __asm( #pfx #func "_power9" #r );
> +#define F128_SFX_APPEND(x) x ## _power9
> +#endif
> +#define F128_REDIR_R(func, r) F128_REDIR_PFX_R (func, , r)
> +#define F128_REDIR(func) F128_REDIR_R (func, )
> +
> +#endif /*_FLOAT128_IFUNC_REDIRECT_MACROS_PPC64LE */
> diff --git a/sysdeps/powerpc/powerpc64/le/fpu/multiarch/float128-ifunc-redirects-mp.h b/sysdeps/powerpc/powerpc64/le/fpu/multiarch/float128-ifunc-redirects-mp.h
> new file mode 100644
> index 0000000000..3c8b6f1291
> --- /dev/null
> +++ b/sysdeps/powerpc/powerpc64/le/fpu/multiarch/float128-ifunc-redirects-mp.h
> @@ -0,0 +1,64 @@
> +/* _Float128 multiarch redirects shared with math_private.h
> +   Copyright (C) 2020 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#ifndef _FLOAT128_IFUNC_REDIRECTS_MP_H
> +#define _FLOAT128_IFUNC_REDIRECTS_MP_H 1
> +
> +#include <float128-ifunc-redirect-macros.h>
> +
> +F128_REDIR (__ieee754_acosf128)
> +F128_REDIR (__ieee754_acoshf128)
> +F128_REDIR (__ieee754_asinf128)
> +F128_REDIR (__ieee754_atan2f128)
> +F128_REDIR (__ieee754_atanhf128)
> +F128_REDIR (__ieee754_coshf128)
> +F128_REDIR (__ieee754_expf128)
> +F128_REDIR (__ieee754_exp10f128)
> +F128_REDIR (__ieee754_exp2f128)
> +F128_REDIR (__ieee754_fmodf128)
> +F128_REDIR (__ieee754_gammaf128)
> +F128_REDIR_R (__ieee754_gammaf128, _r)
> +F128_REDIR (__ieee754_hypotf128)
> +F128_REDIR (__ieee754_j0f128)
> +F128_REDIR (__ieee754_j1f128)
> +F128_REDIR (__ieee754_jnf128)
> +F128_REDIR (__ieee754_lgammaf128)
> +F128_REDIR_R (__ieee754_lgammaf128, _r)
> +F128_REDIR (__ieee754_logf128)
> +F128_REDIR (__ieee754_log10f128)
> +F128_REDIR (__ieee754_log2f128)
> +F128_REDIR (__ieee754_powf128)
> +F128_REDIR (__ieee754_remainderf128)
> +F128_REDIR (__ieee754_sinhf128)
> +F128_REDIR (__ieee754_sqrtf128)
> +F128_REDIR (__ieee754_y0f128)
> +F128_REDIR (__ieee754_y1f128)
> +F128_REDIR (__ieee754_ynf128)
> +F128_REDIR (__ieee754_scalbf128)
> +F128_REDIR (__ieee754_ilogbf128)
> +F128_REDIR (__ieee754_rem_pio2f128)
> +F128_REDIR (__kernel_sinf128)
> +F128_REDIR (__kernel_cosf128)
> +F128_REDIR (__kernel_tanf128)
> +F128_REDIR (__kernel_sincosf128)
> +F128_REDIR (__kernel_rem_pio2f128)
> +F128_REDIR (__x2y2m1f128)
> +F128_REDIR (__gamma_productf128)
> +F128_REDIR (__lgamma_negf128)
> +
> +#endif /*_FLOAT128_IFUNC_REDIRECTS_MP_H */
> diff --git a/sysdeps/powerpc/powerpc64/le/fpu/multiarch/float128-ifunc-redirects.h b/sysdeps/powerpc/powerpc64/le/fpu/multiarch/float128-ifunc-redirects.h
> new file mode 100644
> index 0000000000..88b71558b0
> --- /dev/null
> +++ b/sysdeps/powerpc/powerpc64/le/fpu/multiarch/float128-ifunc-redirects.h
> @@ -0,0 +1,40 @@
> +/* _Float128 redirects for ppc64le multiarch env.
> +   Copyright (C) 2020 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#ifndef _FLOAT128_IFUNC_REDIRECTS
> +#define _FLOAT128_IFUNC_REDIRECTS 1
> +
> +#include <float128-ifunc-macros.h>
> +
> +F128_REDIR_PFX_R (sqrtf128, __,);
> +F128_REDIR_PFX_R (rintf128, __,);
> +F128_REDIR_PFX_R (ceilf128, __,);
> +F128_REDIR_PFX_R (floorf128, __,);
> +F128_REDIR_PFX_R (truncf128, __,);
> +F128_REDIR_PFX_R (roundf128, __,);
> +F128_REDIR_PFX_R (fabsf128, __,);
> +F128_REDIR (__issignalingf128)
> +
> +extern __typeof (ldexpf128) F128_SFX_APPEND (__ldexpf128);
> +
> +#define __isinff128 F128_SFX_APPEND (__isinff128)
> +#define __isnanf128 F128_SFX_APPEND (__isnanf128)
> +#define __finitef128 F128_SFX_APPEND (__finitef128)
> +#define __ldexpf128 F128_SFX_APPEND (__ldexpf128)
> +
> +#endif /* _FLOAT128_IFUNC_REDIRECTS */
> diff --git a/sysdeps/powerpc/powerpc64/le/fpu/multiarch/float128-ifunc.c b/sysdeps/powerpc/powerpc64/le/fpu/multiarch/float128-ifunc.c
> new file mode 100644
> index 0000000000..7436180bbf
> --- /dev/null
> +++ b/sysdeps/powerpc/powerpc64/le/fpu/multiarch/float128-ifunc.c
> @@ -0,0 +1,66 @@
> +/* _Float128 ifunc definitions for compat symbols.
> +   Copyright (C) 2017-2020 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#include <float128-ifunc.h>
> +#include <libm-alias-finite.h>
> +
> +#if SHLIB_COMPAT (libm, GLIBC_2_15, GLIBC_2_31)
> +
> +/* __gammaf128_r is a special case.  This prototype keeps compat macro simple. */
> +extern _Float128 gammaf128_r (_Float128 x, int *signamp);
> +
> +/* Generate compatability alias macros for finite math functions.  IFUNC is

s/compatability/compatibility

> +   used to avoid complicating the macros in float128-ifunc.h, and avoids the
> +   need to use special macros while constructing the baseline objects.  */
> +#define MAKE_IFUNC_COMPAT_R(func, r) \
> +	extern __typeof(func ## r) __ieee754_ ## func ## _power8 ## r; \
> +	extern __typeof(func ## r) __ieee754_ ## func ## _power9 ## r; \
> +	extern __typeof(func ## r) __ieee754_ ## func ## r; \
> +	_F128_IFUNC(__ieee754_ ## func, r); \
> +	libm_alias_finite (__ieee754_ ## func ## r, __ ## func ## r)
> +
> +#define MAKE_IFUNC_COMPAT(func) MAKE_IFUNC_COMPAT_R (func,)
> +
> +MAKE_IFUNC_COMPAT (acosf128)
> +MAKE_IFUNC_COMPAT (acoshf128)
> +MAKE_IFUNC_COMPAT (asinf128)
> +MAKE_IFUNC_COMPAT (atan2f128)
> +MAKE_IFUNC_COMPAT (atanhf128)
> +MAKE_IFUNC_COMPAT (coshf128)
> +MAKE_IFUNC_COMPAT (exp10f128)
> +MAKE_IFUNC_COMPAT (exp2f128)
> +MAKE_IFUNC_COMPAT (expf128)
> +MAKE_IFUNC_COMPAT (fmodf128)
> +MAKE_IFUNC_COMPAT_R (gammaf128, _r)
> +MAKE_IFUNC_COMPAT (hypotf128)
> +MAKE_IFUNC_COMPAT (j0f128)
> +MAKE_IFUNC_COMPAT (j1f128)
> +MAKE_IFUNC_COMPAT (jnf128)
> +MAKE_IFUNC_COMPAT_R (lgammaf128, _r)
> +MAKE_IFUNC_COMPAT (log10f128)
> +MAKE_IFUNC_COMPAT (log2f128)
> +MAKE_IFUNC_COMPAT (logf128)
> +MAKE_IFUNC_COMPAT (powf128)
> +MAKE_IFUNC_COMPAT (remainderf128)
> +MAKE_IFUNC_COMPAT (sinhf128)
> +MAKE_IFUNC_COMPAT (sqrtf128)
> +MAKE_IFUNC_COMPAT (y0f128)
> +MAKE_IFUNC_COMPAT (y1f128)
> +MAKE_IFUNC_COMPAT (ynf128)
> +
> +#endif
> diff --git a/sysdeps/powerpc/powerpc64/le/fpu/multiarch/float128-ifunc.h b/sysdeps/powerpc/powerpc64/le/fpu/multiarch/float128-ifunc.h
> new file mode 100644
> index 0000000000..0da732ec36
> --- /dev/null
> +++ b/sysdeps/powerpc/powerpc64/le/fpu/multiarch/float128-ifunc.h
> @@ -0,0 +1,218 @@
> +/* _Float128 ifunc symboling macros.
> +   Copyright (C) 2020 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <https://www.gnu.org/licenses/>.  */
> +

Looks like this file is missing header guards.

> +/* These cause conflicts when aliasing.  Hide their definitions. */
> +#define f32addf64x __hide_f32addf64x
> +#define f32subf64x __hide_f32subf64x
> +#define f32mulf64x __hide_f32mulf64x
> +#define f32divf64x __hide_f32divf64x
> +#define f32xaddf64x __hide_f32xaddf64x
> +#define f32xsubf64x __hide_f32xsubf64x
> +#define f32xmulf64x __hide_f32xmulf64x
> +#define f32xdivf64x __hide_f32xdivf64x
> +#define f32xaddf128 __hide_f32xaddf128
> +#define f32xsubf128 __hide_f32xsubf128
> +#define f32xmulf128 __hide_f32xmulf128
> +#define f32xdivf128 __hide_f32xdivf128
> +#define f32addf64 __hide_f32addf64
> +#define f32subf64 __hide_f32subf64
> +#define f32mulf64 __hide_f32mulf64
> +#define f32divf64 __hide_f32divf64
> +#define f64addf64x __hide_f64addf64x
> +#define f64subf64x __hide_f64subf64x
> +#define f64mulf64x __hide_f64mulf64x
> +#define f64divf64x __hide_f64divf64x
> +
> +/* We want the real prototypes. */
> +#include <math/math.h>
> +#include <math/complex.h>
> +#include <first-versions.h>
> +#include <shlib-compat.h>
> +#include "init-arch.h"
> +
> +#undef f32addf64x
> +#undef f32subf64x
> +#undef f32mulf64x
> +#undef f32divf64x
> +#undef f32xaddf64x
> +#undef f32xsubf64x
> +#undef f32xmulf64x
> +#undef f32xdivf64x
> +#undef f32xaddf128
> +#undef f32xsubf128
> +#undef f32xmulf128
> +#undef f32xdivf128
> +#undef f32addf64
> +#undef f32subf64
> +#undef f32mulf64
> +#undef f32divf64
> +#undef f64addf64x
> +#undef f64subf64x
> +#undef f64mulf64x
> +#undef f64divf64x
> +
> +#include <libm-alias-float128.h>
> +#include <math-narrow.h>
> +
> +/*
> +   _F128_IFUNC2(func, from, r)
> +      Generate an ifunc symbol func ## r from the symbols
> +	from ## {power8, power9} ## r
> +
> +      We use the PPC hwcap bit HAS_IEEE128 to select between the two with
> +      the assumption all P9 features are available on such targets.
> +*/

End of comment should be on the previous line.

> +#define _F128_IFUNC2(func, from, r) \
> +	libc_ifunc (func ## r, (hwcap2 & PPC_FEATURE2_HAS_IEEE128) \
> +                                ? from ## _power9 ## r : from ## _power8 ## r)
> +
> +/*
> +   _F128_IFUNC(func, r)
> +      Similar to above, except the exported symbol name trivially remaps from
> +      func ## {cpu} ## r to func ## r.
> +*/

Same.

> +#define _F128_IFUNC(func, r) _F128_IFUNC2(func, func, r)
> +
> +/*
> +   MAKE_IMPL_IFUNC2(func, pfx1, pfx2, r)
> +     Declare external symbols of type pfx1 ## func ## f128 ## r with the name
> +                                      pfx2 ## func ## f128 ## _{cpu} ## r
> +     which are exported as implementation specific symbols (i.e backing support
> +     for type classification macros).  */
> +#define MAKE_IMPL_IFUNC2(func, pfx1, pfx2, r) \
> +	extern __typeof (pfx1 ## func ## f128 ## r) pfx2 ## func ## f128_power8 ## r; \
> +	extern __typeof (pfx1 ## func ## f128 ## r) pfx2 ## func ## f128_power9 ## r; \
> +        _F128_IFUNC2 (__ ## func ## f128, pfx2 ## func ## f128, r);
> +
> +/*
> +   MAKE_IMPL_IFUNC(func, pfx1, r)
> +     Same as MAKE_IMPL_IFUNC2, but pfx2 is assumed to be '__'.  */
> +#define MAKE_IMPL_IFUNC(func, pfx1, r) MAKE_IMPL_IFUNC2(func,pfx1,__,r)
> +
> +/*
> +   _libm_alias_narrow(func, size)
> +     Export a narrowing function func of type _Float{size}.  This is
> +     worked to reuse the exist aliasing macros provide by glibc.  */

s/provide/provided/

> +#define _libm_alias_narrow(func, size) \
> +	extern __typeof (f ## size ## func ## f128) __f ## size ## func ## f128; \
> +	MAKE_IMPL_IFUNC (f ## size ## func,,) \
> +	libm_alias_float ## size ## _float128 (func)
> +

[..]


More information about the Libc-alpha mailing list