1 /* _Float128 ifunc ABI/ifunc generation macros. 2 Copyright (C) 2020-2022 Free Software Foundation, Inc. 3 This file is part of the GNU C Library. 4 5 The GNU C Library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 The GNU C Library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with the GNU C Library; if not, see 17 <https://www.gnu.org/licenses/>. */ 18 19 #ifndef _FLOAT128_IFUNC_H 20 #define _FLOAT128_IFUNC_H 1 21 22 /* Disable hidden prototypes. These perform function renames which 23 prevent the ifunc functions from working. */ 24 #undef hidden_proto 25 #define hidden_proto(x) 26 #define NO_MATH_REDIRECT 1 27 28 /* Include the real math.h to avoid optimizations caused by include/math.h 29 (e.x fabsf128 prototype is masked by an inline definition).*/ 30 #define f64xfmaf128 __hide_f64xfmaf128 31 #define f64xsqrtf128 __hide_f64xsqrtf128 32 #include <math/math.h> 33 #undef f64xfmaf128 34 #undef f64xsqrtf128 35 #include <math_private.h> 36 #include <complex.h> 37 #include <first-versions.h> 38 #include <shlib-compat.h> 39 #include "init-arch.h" 40 41 #include <libm-alias-float128.h> 42 #include <libm-alias-finite.h> 43 #include <math-narrow-alias.h> 44 45 /* _F128_IFUNC2(func, from, r) 46 Generate an ifunc symbol func ## r from the symbols 47 from ## {power8, power9} ## r 48 49 We use the PPC hwcap bit HAS_IEEE128 to select between the two with 50 the assumption all P9 features are available on such targets. */ 51 #define _F128_IFUNC2(func, from, r) \ 52 libc_ifunc (func ## r, (hwcap2 & PPC_FEATURE2_HAS_IEEE128) \ 53 ? from ## _power9 ## r : from ## _power8 ## r) 54 55 /* _F128_IFUNC(func, r) 56 Similar to above, except the exported symbol name trivially remaps from 57 func ## {cpu} ## r to func ## r. */ 58 #define _F128_IFUNC(func, r) _F128_IFUNC2(func, func, r) 59 60 /* MAKE_IMPL_IFUNC2(func, pfx1, pfx2, r) 61 Declare external symbols of type pfx1 ## func ## f128 ## r with the name 62 pfx2 ## func ## f128 ## _{cpu} ## r 63 which are exported as implementation specific symbols (i.e backing support 64 for type classification macros). */ 65 #define MAKE_IMPL_IFUNC2(func, pfx1, pfx2, r) \ 66 extern __typeof (pfx1 ## func ## f128 ## r) pfx2 ## func ## f128_power8 ## r; \ 67 extern __typeof (pfx1 ## func ## f128 ## r) pfx2 ## func ## f128_power9 ## r; \ 68 _F128_IFUNC2 (__ ## func ## f128, pfx2 ## func ## f128, r); 69 70 /* GEN_COMPAT_R_e(f) 71 Generate a compatability symbol for finite alias of ieee function. */ 72 #define GEN_COMPAT_R_e(f, r) \ 73 libm_alias_finite (__ieee754_ ## f ## f128 ## r, __ ## f ## f128 ## r) 74 75 #define GEN_COMPAT_e_acos(f) GEN_COMPAT_R_e(f,) 76 #define GEN_COMPAT_e_acosh(f) GEN_COMPAT_R_e(f,) 77 #define GEN_COMPAT_e_asin(f) GEN_COMPAT_R_e(f,) 78 #define GEN_COMPAT_e_sinh(f) GEN_COMPAT_R_e(f,) 79 #define GEN_COMPAT_e_atan2(f) GEN_COMPAT_R_e(f,) 80 #define GEN_COMPAT_e_atanh(f) GEN_COMPAT_R_e(f,) 81 #define GEN_COMPAT_e_cosh(f) GEN_COMPAT_R_e(f,) 82 #define GEN_COMPAT_e_exp10(f) GEN_COMPAT_R_e(f,) 83 #define GEN_COMPAT_e_exp2(f) GEN_COMPAT_R_e(f,) 84 #define GEN_COMPAT_e_exp(f) GEN_COMPAT_R_e(f,) 85 #define GEN_COMPAT_e_fmod(f) GEN_COMPAT_R_e(f,) 86 #define GEN_COMPAT_e_gamma_r(f) GEN_COMPAT_R_e(f,_r) 87 #define GEN_COMPAT_e_hypot(f) GEN_COMPAT_R_e(f,) 88 #define GEN_COMPAT_e_j0(f) GEN_COMPAT_R_e(f,) GEN_COMPAT_R_e(y0,) 89 #define GEN_COMPAT_e_j1(f) GEN_COMPAT_R_e(f,) GEN_COMPAT_R_e(y1,) 90 #define GEN_COMPAT_e_jn(f) GEN_COMPAT_R_e(f,) GEN_COMPAT_R_e(yn,) 91 #define GEN_COMPAT_e_lgamma_r(f) GEN_COMPAT_R_e(f,_r) 92 #define GEN_COMPAT_e_log10(f) GEN_COMPAT_R_e(f,) 93 #define GEN_COMPAT_e_log2(f) GEN_COMPAT_R_e(f,) 94 #define GEN_COMPAT_e_log(f) GEN_COMPAT_R_e(f,) 95 #define GEN_COMPAT_e_pow(f) GEN_COMPAT_R_e(f,) 96 #define GEN_COMPAT_e_remainder(f) GEN_COMPAT_R_e(f,) 97 #define GEN_COMPAT_e_sqrt(f) GEN_COMPAT_R_e(f,) 98 99 /* MAKE_IEEE_IFUNC_R(func, pfx, r) 100 Declare an ieee ifunc symbol used internally by libm. E.g __ieee754_sinf128 */ 101 #define MAKE_IEEE_IFUNC_R(func, r) \ 102 extern __typeof (__ieee754_ ## func ## f128 ## r) __ieee754_ ## func ## f128_power8 ## r; \ 103 extern __typeof (__ieee754_ ## func ## f128 ## r) __ieee754_ ## func ## f128_power9 ## r; \ 104 _F128_IFUNC2 (__ieee754_ ## func ## f128, __ieee754_ ## func ## f128, r); 105 106 /* MAKE_IFUNCP_WRAP_R(w, func, r) 107 Export a function which the implementation wraps with prefix w to 108 to func ## r. */ 109 #define MAKE_IFUNCP_WRAP_R(w, func, r) \ 110 extern __typeof (func ## f128 ## r) __ ## func ## f128 ## r; \ 111 MAKE_IMPL_IFUNC2 (func,__,__ ## w, r) \ 112 weak_alias (__ ## func ## f128 ## r, func ## f128 ## r); \ 113 libm_alias_float128_other_r (__ ## func, func, r); 114 115 /* MAKE_IFUNCP_R(func, r) 116 The default IFUNC generator for all libm _Float128 ABI except 117 when specifically overwritten. This is a convenience wrapper 118 around MAKE_IFUNCP_R where w is not used. */ 119 #define MAKE_IFUNCP_R(func,r) MAKE_IFUNCP_WRAP_R (,func,r) 120 121 /* Generic aliasing functions. */ 122 #define DECL_ALIAS(f) MAKE_IFUNCP_R (f,) 123 #define DECL_ALIAS_s(f) MAKE_IFUNCP_R (f,) 124 #define DECL_ALIAS_w(f) MAKE_IFUNCP_R (f,) 125 #define DECL_ALIAS_e(f) MAKE_IEEE_IFUNC_R (f,) 126 #define DECL_ALIAS_k(f) 127 #define DECL_ALIAS_R_w(f) MAKE_IFUNCP_R (f, _r) 128 #define DECL_ALIAS_R_e(f) MAKE_IEEE_IFUNC_R (f,_r) 129 130 /* No symbols are defined in these helper/wrapper objects. */ 131 #define DECL_ALIAS_lgamma_neg(x) 132 #define DECL_ALIAS_lgamma_product(x) 133 #define DECL_ALIAS_gamma_product(x) 134 #define DECL_ALIAS_x2y2m1(x) 135 #define DECL_ALIAS_s_log1p(x) 136 #define DECL_ALIAS_s_scalbln(x) 137 #define DECL_ALIAS_s_scalbn(x) 138 139 /* Ensure the wrapper functions get exposed via IFUNC, not the 140 wrappee (e.g __w_log1pf128_power8 instead of __log1pf128_power8. */ 141 #define DECL_ALIAS_w_log1p(x) MAKE_IFUNCP_WRAP_R(w_,x,) 142 #define DECL_ALIAS_w_scalbln(x) MAKE_IFUNCP_WRAP_R(w_,x,) 143 144 /* These are declared in their respective jX objects. */ 145 #define DECL_ALIAS_w_j0(f) MAKE_IFUNCP_R (f,) MAKE_IFUNCP_R (y0,) 146 #define DECL_ALIAS_w_j1(f) MAKE_IFUNCP_R (f,) MAKE_IFUNCP_R (y1,) 147 #define DECL_ALIAS_w_jn(f) MAKE_IFUNCP_R (f,) MAKE_IFUNCP_R (yn,) 148 #define DECL_ALIAS_e_j0(f) MAKE_IEEE_IFUNC_R (f,) MAKE_IEEE_IFUNC_R (y0,) 149 #define DECL_ALIAS_e_j1(f) MAKE_IEEE_IFUNC_R (f,) MAKE_IEEE_IFUNC_R (y1,) 150 #define DECL_ALIAS_e_jn(f) MAKE_IEEE_IFUNC_R (f,) MAKE_IEEE_IFUNC_R (yn,) 151 152 #define DECL_ALIAS_s_erf(f) MAKE_IFUNCP_R (f,) MAKE_IFUNCP_R (erfc,) 153 154 /* scalbnf128 is an alias of ldexpf128. */ 155 #define DECL_ALIAS_s_ldexp(f) MAKE_IFUNCP_R (f,) MAKE_IFUNCP_WRAP_R (wrap_, scalbn,) 156 157 /* f64xfmaf128 is an alias of fmaf128. */ 158 #define DECL_ALIAS_s_fma(f) MAKE_IFUNCP_R (f,) libm_alias_float128_narrow (__fma, fma) 159 160 /* f64xsqrtf128 is an alias of sqrtf128. */ 161 #define DECL_ALIAS_w_sqrt(f) MAKE_IFUNCP_R (f,) libm_alias_float128_narrow (__sqrt, sqrt) 162 163 /* Declare an IFUNC for a symbol which only exists 164 to provide long double == ieee128 ABI. */ 165 #define DECL_LDOUBLE_ALIAS(func, RTYPE, ARGS) \ 166 extern RTYPE func ARGS; \ 167 extern __typeof (func) func ## _power8; \ 168 extern __typeof (func) func ## _power9; \ 169 _F128_IFUNC ( func,) 170 171 /* Handle the special case functions which exist only to support 172 ldouble == ieee128. */ 173 #define DECL_ALIAS_w_scalb(x) \ 174 DECL_LDOUBLE_ALIAS (__scalbf128,_Float128, (_Float128, _Float128)) \ 175 libm_alias_float128_other_r_ldbl (__scalb, scalb,) 176 177 #endif /* ifndef _FLOAT128_IFUNC_H */ 178