Add build infrastructure for narrowing libm functions.
[glibc.git] / math / math-narrow.h
blob1a3a5c57d74231d319beaaa7b323067085e144b7
1 /* Helper macros for functions returning a narrower type.
2 Copyright (C) 2018 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
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.
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.
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 <http://www.gnu.org/licenses/>. */
19 #ifndef _MATH_NARROW_H
20 #define _MATH_NARROW_H 1
22 #include <bits/floatn.h>
23 #include <bits/long-double.h>
24 #include <errno.h>
25 #include <fenv.h>
26 #include <ieee754.h>
27 #include <math_private.h>
29 /* Carry out a computation using round-to-odd. The computation is
30 EXPR; the union type in which to store the result is UNION and the
31 subfield of the "ieee" field of that union with the low part of the
32 mantissa is MANTISSA; SUFFIX is the suffix for the libc_fe* macros
33 to ensure that the correct rounding mode is used, for platforms
34 with multiple rounding modes where those macros set only the
35 relevant mode. This macro does not work correctly if the sign of
36 an exact zero result depends on the rounding mode, so that case
37 must be checked for separately. */
38 #define ROUND_TO_ODD(EXPR, UNION, SUFFIX, MANTISSA) \
39 ({ \
40 fenv_t env; \
41 UNION u; \
43 libc_feholdexcept_setround ## SUFFIX (&env, FE_TOWARDZERO); \
44 u.d = (EXPR); \
45 math_force_eval (u.d); \
46 u.ieee.MANTISSA \
47 |= libc_feupdateenv_test ## SUFFIX (&env, FE_INEXACT) != 0; \
49 u.d; \
52 /* The following macros declare aliases for a narrowing function. The
53 sole argument is the base name of a family of functions, such as
54 "add". If any platform changes long double format after the
55 introduction of narrowing functions, in a way requiring symbol
56 versioning compatibility, additional variants of these macros will
57 be needed. */
59 #define libm_alias_float_double_main(func) \
60 weak_alias (__f ## func, f ## func) \
61 weak_alias (__f ## func, f32 ## func ## f64) \
62 weak_alias (__f ## func, f32 ## func ## f32x)
64 #ifdef NO_LONG_DOUBLE
65 # define libm_alias_float_double(func) \
66 libm_alias_float_double_main (func) \
67 weak_alias (__f ## func, f ## func ## l)
68 #else
69 # define libm_alias_float_double(func) \
70 libm_alias_float_double_main (func)
71 #endif
73 #define libm_alias_float32x_float64_main(func) \
74 weak_alias (__f32x ## func ## f64, f32x ## func ## f64)
76 #ifdef NO_LONG_DOUBLE
77 # define libm_alias_float32x_float64(func) \
78 libm_alias_float32x_float64_main (func) \
79 weak_alias (__f32x ## func ## f64, d ## func ## l)
80 #elif defined __LONG_DOUBLE_MATH_OPTIONAL
81 # define libm_alias_float32x_float64(func) \
82 libm_alias_float32x_float64_main (func) \
83 weak_alias (__f32x ## func ## f64, __nldbl_d ## func ## l)
84 #else
85 # define libm_alias_float32x_float64(func) \
86 libm_alias_float32x_float64_main (func)
87 #endif
89 #if __HAVE_FLOAT128 && !__HAVE_DISTINCT_FLOAT128
90 # define libm_alias_float_ldouble_f128(func) \
91 weak_alias (__f ## func ## l, f32 ## func ## f128)
92 # define libm_alias_double_ldouble_f128(func) \
93 weak_alias (__d ## func ## l, f32x ## func ## f128) \
94 weak_alias (__d ## func ## l, f64 ## func ## f128)
95 #else
96 # define libm_alias_float_ldouble_f128(func)
97 # define libm_alias_double_ldouble_f128(func)
98 #endif
100 #if __HAVE_FLOAT64X_LONG_DOUBLE
101 # define libm_alias_float_ldouble_f64x(func) \
102 weak_alias (__f ## func ## l, f32 ## func ## f64x)
103 # define libm_alias_double_ldouble_f64x(func) \
104 weak_alias (__d ## func ## l, f32x ## func ## f64x) \
105 weak_alias (__d ## func ## l, f64 ## func ## f64x)
106 #else
107 # define libm_alias_float_ldouble_f64x(func)
108 # define libm_alias_double_ldouble_f64x(func)
109 #endif
111 #define libm_alias_float_ldouble(func) \
112 weak_alias (__f ## func ## l, f ## func ## l) \
113 libm_alias_float_ldouble_f128 (func) \
114 libm_alias_float_ldouble_f64x (func)
116 #define libm_alias_double_ldouble(func) \
117 weak_alias (__d ## func ## l, d ## func ## l) \
118 libm_alias_double_ldouble_f128 (func) \
119 libm_alias_double_ldouble_f64x (func)
121 #define libm_alias_float64x_float128(func) \
122 weak_alias (__f64x ## func ## f128, f64x ## func ## f128)
124 #define libm_alias_float32_float128_main(func) \
125 weak_alias (__f32 ## func ## f128, f32 ## func ## f128)
127 #define libm_alias_float64_float128_main(func) \
128 weak_alias (__f64 ## func ## f128, f64 ## func ## f128) \
129 weak_alias (__f64 ## func ## f128, f32x ## func ## f128)
131 #if __HAVE_FLOAT64X_LONG_DOUBLE
132 # define libm_alias_float32_float128(func) \
133 libm_alias_float32_float128_main (func)
134 # define libm_alias_float64_float128(func) \
135 libm_alias_float64_float128_main (func)
136 #else
137 # define libm_alias_float32_float128(func) \
138 libm_alias_float32_float128_main (func) \
139 weak_alias (__f32 ## func ## f128, f32 ## func ## f64x)
140 # define libm_alias_float64_float128(func) \
141 libm_alias_float64_float128_main (func) \
142 weak_alias (__f64 ## func ## f128, f64 ## func ## f64x) \
143 weak_alias (__f64 ## func ## f128, f32x ## func ## f64x)
144 #endif
146 #endif /* math-narrow.h. */