1ifeq ($(subdir),math) 2 3# 4# Only enable ifunc _Float128 support if the baseline cpu support 5# is older than power9. 6ifneq (yes,$(libc-submachine-power9)) 7do_f128_multiarch = yes 8endif 9 10# 11# This is an ugly, but contained, mechanism to provide hardware optimized 12# _Float128 and ldouble == ieee128 optimized routines for P9 and beyond 13# hardware. At a very high level, we rely on ASM renames, and rarely 14# macro renames to build two sets of _Float128 ABI, one with _power8 (the 15# baseline powerpc64le cpu) and _power9 (the first powerpc64le cpu to introduce 16# hardware support for _Float128). 17# 18# At a high level, we compile 3 files for each object file. 19# 1. The baseline soft-float128, unsuffixed objects $(object).$(sfx) 20# The symbols contained in these files is suffixed by _power8. 21# 2. The hard-float128, power9, suffixed objects $(object)-power9.$(sfx). 22# The symbols contained in these files is suffixed by _power9. 23# 3. The IFUNC wrapper object to export ABI, $(object)-ifunc.$(sfx) 24# This glues the above together and implements the ABI. 25# 26# 2 & 3 are automatically generated by Makefile rule. Placing the exported 27# ABI into a separate file allows reuse of existing aliasing macros 28# with minimal hassle. 29# 30# 31# If the float128 ABI is expanded, and a new ifunc wrappers are desired, 32# the following lists how to map new symbols from the shared headers into 33# their local overrides here: 34# 35# float128_private.h 36# 37# is used to rename the ldouble == ieee128 object files. This takes 38# it a step further and redirects symbols to a local name. This supports 39# nearly all files in sysdeps/ieee754/float128, but not all _Float128 40# objects. However, this is only meant to be used internally to support 41# compilation of ldbl-128 into float128. 42# 43# math-type-macros-float128.h 44# 45# renames symbols which are generated via shared templated in math/. 46# 47# math_private.h 48# 49# provides internal declarations for common macros and functions which 50# are called from within libm. Note, float128_private.h duplicates 51# some of these declarations as these headers are generally not included 52# in the same translation unit. 53# 54# The above is supported by several header files as described below: 55# 56# float128-ifunc.h 57# 58# provides support for generating the IFUNC objects in part 3 above. 59# This header is only included with wrapper functions. 60# 61# float128-ifunc-macros.h 62# 63# disables all first-order float128 aliasing macros used in libm, 64# and libm wrappers around libc-symbols.h. 65# 66# float128-ifunc-redirect-macros.h 67# 68# provides macros which implement the appending of the suffix to 69# symbols what have been selected. 70# 71# float128-ifunc-redirects.h 72# 73# provides ASM redirects for symbols which are redirected in the 74# private copy of math.h used by glibc, but not declared by math_private.h 75# 76# float128-ifunc-redirects-mp.h 77# 78# provides ASM redirects which are used by math_private.h (the -mp suffix) 79# and the interposer float128_private.h discussed late. 80# 81# Notably, this enforces a slightly different mechanism for machine specific 82# overrides. Optimizations for all targets must all be reachable from the same 83# file. See the history to fmaf128 or sqrtf128 to understand how this looks 84# in practice. 85# 86ifeq ($(do_f128_multiarch),yes) 87 88f128-ifunc-calls = s_modff128 s_scalbnf128 s_frexpf128 s_ldexpf128 89gen-libm-f128-ifunc-routines = \ 90 e_acosf128 e_acoshf128 e_asinf128 e_atan2f128 e_atanhf128 e_coshf128 \ 91 e_expf128 e_fmodf128 e_hypotf128 e_j0f128 e_j1f128 e_jnf128 \ 92 e_lgammaf128_r e_logf128 e_log10f128 e_powf128 e_remainderf128 \ 93 e_sinhf128 e_sqrtf128 e_gammaf128_r e_ilogbf128 k_tanf128 s_asinhf128 \ 94 s_atanf128 s_cbrtf128 s_ceilf128 s_cosf128 s_erff128 s_expm1f128 \ 95 s_fabsf128 s_floorf128 s_log1pf128 s_logbf128 \ 96 s_rintf128 s_scalblnf128 s_sinf128 s_tanf128 \ 97 s_tanhf128 s_truncf128 s_remquof128 e_log2f128 \ 98 s_roundf128 s_nearbyintf128 s_sincosf128 s_fmaf128 s_lrintf128 \ 99 s_llrintf128 s_lroundf128 s_llroundf128 e_exp10f128 \ 100 $(f128-ifunc-calls) $(f128-ifunc-calls:s_%=m_%) x2y2m1f128 \ 101 gamma_productf128 lgamma_negf128 lgamma_productf128 s_roundevenf128 \ 102 cargf128 conjf128 cimagf128 crealf128 cabsf128 e_scalbf128 s_cacosf128 \ 103 s_cacoshf128 s_ccosf128 s_ccoshf128 s_casinf128 s_csinf128 \ 104 s_casinhf128 k_casinhf128 s_csinhf128 k_casinhf128 s_csinhf128 \ 105 s_catanhf128 s_catanf128 s_ctanf128 s_ctanhf128 s_cexpf128 s_clogf128 \ 106 s_cprojf128 s_csqrtf128 s_cpowf128 s_clog10f128 s_fdimf128 \ 107 s_fmaxf128 s_fminf128 w_ilogbf128 w_llogbf128 \ 108 w_log1pf128 w_scalblnf128 w_acosf128 \ 109 w_acoshf128 w_asinf128 w_atan2f128 w_atanhf128 w_coshf128 w_exp10f128 \ 110 w_exp2f128 w_fmodf128 w_hypotf128 w_j0f128 w_j1f128 w_jnf128 \ 111 w_logf128 w_log10f128 w_log2f128 w_powf128 w_remainderf128 \ 112 w_scalbf128 w_sinhf128 w_sqrtf128 w_tgammaf128 w_lgammaf128 \ 113 w_lgammaf128_r w_expf128 e_exp2f128 \ 114 k_sinf128 k_cosf128 k_sincosf128 e_rem_pio2f128 115 116 117f128-march-routines-p9 = $(addsuffix -power9,$(gen-libm-f128-ifunc-routines)) 118f128-march-routines-ifunc = $(addsuffix -ifunc,$(gen-libm-f128-ifunc-routines)) 119f128-march-routines = $(f128-march-routines-p9) $(f128-march-routines-ifunc) 120f128-march-cpus = power9 121 122f128-march-calls-p9 = $(addsuffix -power9,$(f128-ifunc-calls)) 123f128-march-calls-ifunc = $(addsuffix -ifunc,$(f128-ifunc-calls)) 124f128-march-calls = $(f128-march-calls-p9) $(f128-march-calls-ifunc) 125 126calls += $(f128-march-calls) 127libm-routines += $(filter-out $(f128-march-calls), $(f128-march-routines)) 128generated += $(f128-march-routines) 129 130CFLAGS-float128-ifunc.c += $(type-float128-CFLAGS) $(no-gnu-attribute-CFLAGS) 131 132# Copy special CFLAGS for some functions 133CFLAGS-s_modff128-power9.c += -fsignaling-nans 134CFLAGS-m_modff128-power9.c += -fsignaling-nans 135 136# Generate ifunc wrapper files and target specific wrappers around 137# each routine above. Note, m_%.c files are fixed up to include 138# s_%.c files. This is an artifact of the makefile rules which allow 139# some files to be compiled for libc and libm. 140$(objpfx)gen-float128-ifuncs.stmp: \ 141 Makefile $(..)sysdeps/powerpc/powerpc64/le/fpu/multiarch/Makefile 142 $(make-target-directory) 143 for gcall in $(gen-libm-f128-ifunc-routines); do \ 144 ifile="$${gcall}"; \ 145 if [ $${gcall##m_} != $${gcall} ]; then \ 146 ifile="s_$${gcall##m_}"; \ 147 fi; \ 148 for cpu in $(f128-march-cpus); do \ 149 file=$(objpfx)$${gcall}-$${cpu}.c; \ 150 { \ 151 echo "#include <$${ifile}.c>"; \ 152 } > $${file}; \ 153 done; \ 154 name="$${gcall##?_}"; \ 155 pfx="$${gcall%%_*}"; \ 156 R=""; \ 157 r=""; \ 158 if [ $${gcall##m_} != $${gcall} ]; then \ 159 pfx="s"; \ 160 fi; \ 161 if [ $${#pfx} != 1 ]; then \ 162 pfx=""; \ 163 else \ 164 pfx="_$${pfx}"; \ 165 fi; \ 166 if [ $${name%%_r} != $${name} ]; then \ 167 R="_R"; \ 168 r="_r"; \ 169 name="$${name%%_r}"; \ 170 fi; \ 171 name="$${name%%f128}"; \ 172 decl="DECL_ALIAS$${pfx}_$${name}$${r}"; \ 173 compat="GEN_COMPAT$${pfx}_$${name}$${r}"; \ 174 declc="DECL_ALIAS$${R}$${pfx}"; \ 175 { \ 176 echo "#include <float128-ifunc.h>"; \ 177 echo "#ifndef $${decl}"; \ 178 echo "# define $${decl}(f) $${declc} (f)"; \ 179 echo "#endif"; \ 180 echo "#ifndef $${compat}"; \ 181 echo "# define $${compat}(f)"; \ 182 echo "#endif"; \ 183 echo "$${decl} ($${name});"; \ 184 echo "$${compat} ($${name});"; \ 185 } > $(objpfx)$${gcall}-ifunc.c; \ 186 done; \ 187 echo > $(@) 188 189$(foreach f,$(f128-march-routines),$(objpfx)$(f).c): \ 190 $(objpfx)gen-float128-ifuncs.stmp $(objpfx)gen-libm-templates.stmp 191 192enable-f128-ifunc-CFLAGS = -D_F128_ENABLE_IFUNC $(no-gnu-attributes-CFLAGS) $(type-float128-CFLAGS) 193 194# Enable IFUNC on baseline (power8) implementations 195include $(o-iterator) 196define o-iterator-doit 197$(foreach f,$(gen-libm-f128-ifunc-routines),$(objpfx)$(f)$(o)): sysdep-CFLAGS += -D_F128_ENABLE_IFUNC 198endef 199object-suffixes-left := $(all-object-suffixes) 200include $(o-iterator) 201 202# Likewise, but for power9. 203include $(o-iterator) 204define o-iterator-doit 205$(foreach f,$(f128-march-routines-p9),$(objpfx)$(f)$(o)): sysdep-CFLAGS += $$(enable-f128-ifunc-CFLAGS) -mcpu=power9 206endef 207object-suffixes-left := $(all-object-suffixes) 208include $(o-iterator) 209 210endif # do_f128_multiarch 211 212libm-sysdep_routines += e_log-ppc64 213 214ifeq ($(mcpu-power10), yes) 215libm-sysdep_routines += e_log-power10 216CFLAGS-e_log-power10.c += -mcpu=power10 217endif 218 219endif 220