4 # Only enable ifunc _Float128 support if the baseline cpu support
5 # is older than power9.
6 ifneq (yes
,$(libc-submachine-power9
))
7 do_f128_multiarch
= yes
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).
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.
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.
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:
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.
43 # math-type-macros-float128.h
45 # renames symbols which are generated via shared templated in math/.
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.
54 # The above is supported by several header files as described below:
58 # provides support for generating the IFUNC objects in part 3 above.
59 # This header is only included with wrapper functions.
61 # float128-ifunc-macros.h
63 # disables all first-order float128 aliasing macros used in libm,
64 # and libm wrappers around libc-symbols.h.
66 # float128-ifunc-redirect-macros.h
68 # provides macros which implement the appending of the suffix to
69 # symbols what have been selected.
71 # float128-ifunc-redirects.h
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
76 # float128-ifunc-redirects-mp.h
78 # provides ASM redirects which are used by math_private.h (the -mp suffix)
79 # and the interposer float128_private.h discussed late.
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
86 ifeq ($(do_f128_multiarch
),yes
)
88 f128-ifunc-calls
= s_modff128 s_scalbnf128 s_frexpf128 s_ldexpf128
89 gen-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
117 f128-march-routines-p9
= $(addsuffix -power9
,$(gen-libm-f128-ifunc-routines
))
118 f128-march-routines-ifunc
= $(addsuffix -ifunc
,$(gen-libm-f128-ifunc-routines
))
119 f128-march-routines
= $(f128-march-routines-p9
) $(f128-march-routines-ifunc
)
120 f128-march-cpus
= power9
122 f128-march-calls-p9
= $(addsuffix -power9
,$(f128-ifunc-calls
))
123 f128-march-calls-ifunc
= $(addsuffix -ifunc
,$(f128-ifunc-calls
))
124 f128-march-calls
= $(f128-march-calls-p9
) $(f128-march-calls-ifunc
)
126 calls
+= $(f128-march-calls
)
127 libm-routines
+= $(filter-out $(f128-march-calls
), $(f128-march-routines
))
128 generated
+= $(f128-march-routines
)
130 CFLAGS-float128-ifunc.c
+= $(type-float128-CFLAGS
) $(no-gnu-attribute-CFLAGS
)
132 # Copy special CFLAGS for some functions
133 CFLAGS-s_modff128-power9.c
+= -fsignaling-nans
134 CFLAGS-m_modff128-power9.c
+= -fsignaling-nans
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 \
145 if
[ $${gcall
##m_} != $${gcall} ]; then \
146 ifile
="s_$${gcall##m_}"; \
148 for cpu in
$(f128-march-cpus
); do \
149 file
=$(objpfx
)$${gcall}-$${cpu}.c
; \
151 echo
"#include <$${ifile}.c>"; \
154 name
="$${gcall##?_}"; \
155 pfx
="$${gcall%%_*}"; \
158 if
[ $${gcall
##m_} != $${gcall} ]; then \
161 if
[ $${#pfx} != 1 ]; then \
166 if
[ $${name
%%_r
} != $${name} ]; then \
169 name
="$${name%%_r}"; \
171 name
="$${name%%f128}"; \
172 decl
="DECL_ALIAS$${pfx}_$${name}$${r}"; \
173 compat
="GEN_COMPAT$${pfx}_$${name}$${r}"; \
174 declc
="DECL_ALIAS$${R}$${pfx}"; \
176 echo
"#include <float128-ifunc.h>"; \
177 echo
"#ifndef $${decl}"; \
178 echo
"# define $${decl}(f) $${declc} (f)"; \
180 echo
"#ifndef $${compat}"; \
181 echo
"# define $${compat}(f)"; \
183 echo
"$${decl} ($${name});"; \
184 echo
"$${compat} ($${name});"; \
185 } > $(objpfx
)$${gcall}-ifunc.c
; \
189 $(foreach f
,$(f128-march-routines
),$(objpfx
)$(f
).c
): \
190 $(objpfx
)gen-float128-ifuncs.stmp
$(objpfx
)gen-libm-templates.stmp
192 enable-f128-ifunc-CFLAGS
= -D_F128_ENABLE_IFUNC
$(no-gnu-attributes-CFLAGS
) $(type-float128-CFLAGS
)
194 # Enable IFUNC on baseline (power8) implementations
195 include $(o-iterator
)
196 define o-iterator-doit
197 $(foreach f
,$(gen-libm-f128-ifunc-routines
),$(objpfx
)$(f
)$(o
)): sysdep-CFLAGS
+= -D_F128_ENABLE_IFUNC
199 object-suffixes-left
:= $(all-object-suffixes
)
200 include $(o-iterator
)
202 # Likewise, but for power9.
203 include $(o-iterator
)
204 define o-iterator-doit
205 $(foreach f
,$(f128-march-routines-p9
),$(objpfx
)$(f
)$(o
)): sysdep-CFLAGS
+= $$(enable-f128-ifunc-CFLAGS
) -mcpu
=power9
207 object-suffixes-left
:= $(all-object-suffixes
)
208 include $(o-iterator
)
210 endif # do_f128_multiarch
212 libm-sysdep_routines
+= e_log-ppc64
214 ifeq ($(mcpu-power10
), yes
)
215 libm-sysdep_routines
+= e_log-power10
216 CFLAGS-e_log-power10.c
+= -mcpu
=power10