1 | /* Macros to control TS 18661-3 glibc features where the same |
2 | definitions are appropriate for all platforms. |
3 | Copyright (C) 2017-2022 Free Software Foundation, Inc. |
4 | This file is part of the GNU C Library. |
5 | |
6 | The GNU C Library is free software; you can redistribute it and/or |
7 | modify it under the terms of the GNU Lesser General Public |
8 | License as published by the Free Software Foundation; either |
9 | version 2.1 of the License, or (at your option) any later version. |
10 | |
11 | The GNU C Library is distributed in the hope that it will be useful, |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | Lesser General Public License for more details. |
15 | |
16 | You should have received a copy of the GNU Lesser General Public |
17 | License along with the GNU C Library; if not, see |
18 | <https://www.gnu.org/licenses/>. */ |
19 | |
20 | #ifndef _BITS_FLOATN_COMMON_H |
21 | #define _BITS_FLOATN_COMMON_H |
22 | |
23 | #include <features.h> |
24 | #include <bits/long-double.h> |
25 | |
26 | /* This header should be included at the bottom of each bits/floatn.h. |
27 | It defines the following macros for each _FloatN and _FloatNx type, |
28 | where the same definitions, or definitions based only on the macros |
29 | in bits/floatn.h, are appropriate for all glibc configurations. */ |
30 | |
31 | /* Defined to 1 if the current compiler invocation provides a |
32 | floating-point type with the right format for this type, and this |
33 | glibc includes corresponding *fN or *fNx interfaces for it. */ |
34 | #define __HAVE_FLOAT16 0 |
35 | #define __HAVE_FLOAT32 1 |
36 | #define __HAVE_FLOAT64 1 |
37 | #define __HAVE_FLOAT32X 1 |
38 | #define __HAVE_FLOAT128X 0 |
39 | |
40 | /* Defined to 1 if the corresponding __HAVE_<type> macro is 1 and the |
41 | type is the first with its format in the sequence of (the default |
42 | choices for) float, double, long double, _Float16, _Float32, |
43 | _Float64, _Float128, _Float32x, _Float64x, _Float128x for this |
44 | glibc; that is, if functions present once per floating-point format |
45 | rather than once per type are present for this type. |
46 | |
47 | All configurations supported by glibc have _Float32 the same format |
48 | as float, _Float64 and _Float32x the same format as double, the |
49 | _Float64x the same format as either long double or _Float128. No |
50 | configurations support _Float128x or, as of GCC 7, have compiler |
51 | support for a type meeting the requirements for _Float128x. */ |
52 | #define __HAVE_DISTINCT_FLOAT16 __HAVE_FLOAT16 |
53 | #define __HAVE_DISTINCT_FLOAT32 0 |
54 | #define __HAVE_DISTINCT_FLOAT64 0 |
55 | #define __HAVE_DISTINCT_FLOAT32X 0 |
56 | #define __HAVE_DISTINCT_FLOAT64X 0 |
57 | #define __HAVE_DISTINCT_FLOAT128X __HAVE_FLOAT128X |
58 | |
59 | /* Defined to 1 if the corresponding _FloatN type is not binary compatible |
60 | with the corresponding ISO C type in the current compilation unit as |
61 | opposed to __HAVE_DISTINCT_FLOATN, which indicates the default types built |
62 | in glibc. */ |
63 | #define __HAVE_FLOAT128_UNLIKE_LDBL (__HAVE_DISTINCT_FLOAT128 \ |
64 | && __LDBL_MANT_DIG__ != 113) |
65 | |
66 | /* Defined to 1 if any _FloatN or _FloatNx types that are not |
67 | ABI-distinct are however distinct types at the C language level (so |
68 | for the purposes of __builtin_types_compatible_p and _Generic). */ |
69 | #if __GNUC_PREREQ (7, 0) && !defined __cplusplus |
70 | # define __HAVE_FLOATN_NOT_TYPEDEF 1 |
71 | #else |
72 | # define __HAVE_FLOATN_NOT_TYPEDEF 0 |
73 | #endif |
74 | |
75 | #ifndef __ASSEMBLER__ |
76 | |
77 | /* Defined to concatenate the literal suffix to be used with _FloatN |
78 | or _FloatNx types, if __HAVE_<type> is 1. The corresponding |
79 | literal suffixes exist since GCC 7, for C only. */ |
80 | # if __HAVE_FLOAT16 |
81 | # if !__GNUC_PREREQ (7, 0) || defined __cplusplus |
82 | /* No corresponding suffix available for this type. */ |
83 | # define __f16(x) ((_Float16) x##f) |
84 | # else |
85 | # define __f16(x) x##f16 |
86 | # endif |
87 | # endif |
88 | |
89 | # if __HAVE_FLOAT32 |
90 | # if !__GNUC_PREREQ (7, 0) || defined __cplusplus |
91 | # define __f32(x) x##f |
92 | # else |
93 | # define __f32(x) x##f32 |
94 | # endif |
95 | # endif |
96 | |
97 | # if __HAVE_FLOAT64 |
98 | # if !__GNUC_PREREQ (7, 0) || defined __cplusplus |
99 | # ifdef __NO_LONG_DOUBLE_MATH |
100 | # define __f64(x) x##l |
101 | # else |
102 | # define __f64(x) x |
103 | # endif |
104 | # else |
105 | # define __f64(x) x##f64 |
106 | # endif |
107 | # endif |
108 | |
109 | # if __HAVE_FLOAT32X |
110 | # if !__GNUC_PREREQ (7, 0) || defined __cplusplus |
111 | # define __f32x(x) x |
112 | # else |
113 | # define __f32x(x) x##f32x |
114 | # endif |
115 | # endif |
116 | |
117 | # if __HAVE_FLOAT64X |
118 | # if !__GNUC_PREREQ (7, 0) || defined __cplusplus |
119 | # if __HAVE_FLOAT64X_LONG_DOUBLE |
120 | # define __f64x(x) x##l |
121 | # else |
122 | # define __f64x(x) __f128 (x) |
123 | # endif |
124 | # else |
125 | # define __f64x(x) x##f64x |
126 | # endif |
127 | # endif |
128 | |
129 | # if __HAVE_FLOAT128X |
130 | # if !__GNUC_PREREQ (7, 0) || defined __cplusplus |
131 | # error "_Float128X supported but no constant suffix" |
132 | # else |
133 | # define __f128x(x) x##f128x |
134 | # endif |
135 | # endif |
136 | |
137 | /* Defined to a complex type if __HAVE_<type> is 1. */ |
138 | # if __HAVE_FLOAT16 |
139 | # if !__GNUC_PREREQ (7, 0) || defined __cplusplus |
140 | typedef _Complex float __cfloat16 __attribute__ ((__mode__ (__HC__))); |
141 | # define __CFLOAT16 __cfloat16 |
142 | # else |
143 | # define __CFLOAT16 _Complex _Float16 |
144 | # endif |
145 | # endif |
146 | |
147 | # if __HAVE_FLOAT32 |
148 | # if !__GNUC_PREREQ (7, 0) || defined __cplusplus |
149 | # define __CFLOAT32 _Complex float |
150 | # else |
151 | # define __CFLOAT32 _Complex _Float32 |
152 | # endif |
153 | # endif |
154 | |
155 | # if __HAVE_FLOAT64 |
156 | # if !__GNUC_PREREQ (7, 0) || defined __cplusplus |
157 | # ifdef __NO_LONG_DOUBLE_MATH |
158 | # define __CFLOAT64 _Complex long double |
159 | # else |
160 | # define __CFLOAT64 _Complex double |
161 | # endif |
162 | # else |
163 | # define __CFLOAT64 _Complex _Float64 |
164 | # endif |
165 | # endif |
166 | |
167 | # if __HAVE_FLOAT32X |
168 | # if !__GNUC_PREREQ (7, 0) || defined __cplusplus |
169 | # define __CFLOAT32X _Complex double |
170 | # else |
171 | # define __CFLOAT32X _Complex _Float32x |
172 | # endif |
173 | # endif |
174 | |
175 | # if __HAVE_FLOAT64X |
176 | # if !__GNUC_PREREQ (7, 0) || defined __cplusplus |
177 | # if __HAVE_FLOAT64X_LONG_DOUBLE |
178 | # define __CFLOAT64X _Complex long double |
179 | # else |
180 | # define __CFLOAT64X __CFLOAT128 |
181 | # endif |
182 | # else |
183 | # define __CFLOAT64X _Complex _Float64x |
184 | # endif |
185 | # endif |
186 | |
187 | # if __HAVE_FLOAT128X |
188 | # if !__GNUC_PREREQ (7, 0) || defined __cplusplus |
189 | # error "_Float128X supported but no complex type" |
190 | # else |
191 | # define __CFLOAT128X _Complex _Float128x |
192 | # endif |
193 | # endif |
194 | |
195 | /* The remaining of this file provides support for older compilers. */ |
196 | # if __HAVE_FLOAT16 |
197 | |
198 | # if !__GNUC_PREREQ (7, 0) || defined __cplusplus |
199 | typedef float _Float16 __attribute__ ((__mode__ (__HF__))); |
200 | # endif |
201 | |
202 | # if !__GNUC_PREREQ (7, 0) |
203 | # define __builtin_huge_valf16() ((_Float16) __builtin_huge_val ()) |
204 | # define __builtin_inff16() ((_Float16) __builtin_inf ()) |
205 | # define __builtin_nanf16(x) ((_Float16) __builtin_nan (x)) |
206 | # define __builtin_nansf16(x) ((_Float16) __builtin_nans (x)) |
207 | # endif |
208 | |
209 | # endif |
210 | |
211 | # if __HAVE_FLOAT32 |
212 | |
213 | # if !__GNUC_PREREQ (7, 0) || defined __cplusplus |
214 | typedef float _Float32; |
215 | # endif |
216 | |
217 | # if !__GNUC_PREREQ (7, 0) |
218 | # define __builtin_huge_valf32() (__builtin_huge_valf ()) |
219 | # define __builtin_inff32() (__builtin_inff ()) |
220 | # define __builtin_nanf32(x) (__builtin_nanf (x)) |
221 | # define __builtin_nansf32(x) (__builtin_nansf (x)) |
222 | # endif |
223 | |
224 | # endif |
225 | |
226 | # if __HAVE_FLOAT64 |
227 | |
228 | /* If double, long double and _Float64 all have the same set of |
229 | values, TS 18661-3 requires the usual arithmetic conversions on |
230 | long double and _Float64 to produce _Float64. For this to be the |
231 | case when building with a compiler without a distinct _Float64 |
232 | type, _Float64 must be a typedef for long double, not for |
233 | double. */ |
234 | |
235 | # ifdef __NO_LONG_DOUBLE_MATH |
236 | |
237 | # if !__GNUC_PREREQ (7, 0) || defined __cplusplus |
238 | typedef long double _Float64; |
239 | # endif |
240 | |
241 | # if !__GNUC_PREREQ (7, 0) |
242 | # define __builtin_huge_valf64() (__builtin_huge_vall ()) |
243 | # define __builtin_inff64() (__builtin_infl ()) |
244 | # define __builtin_nanf64(x) (__builtin_nanl (x)) |
245 | # define __builtin_nansf64(x) (__builtin_nansl (x)) |
246 | # endif |
247 | |
248 | # else |
249 | |
250 | # if !__GNUC_PREREQ (7, 0) || defined __cplusplus |
251 | typedef double _Float64; |
252 | # endif |
253 | |
254 | # if !__GNUC_PREREQ (7, 0) |
255 | # define __builtin_huge_valf64() (__builtin_huge_val ()) |
256 | # define __builtin_inff64() (__builtin_inf ()) |
257 | # define __builtin_nanf64(x) (__builtin_nan (x)) |
258 | # define __builtin_nansf64(x) (__builtin_nans (x)) |
259 | # endif |
260 | |
261 | # endif |
262 | |
263 | # endif |
264 | |
265 | # if __HAVE_FLOAT32X |
266 | |
267 | # if !__GNUC_PREREQ (7, 0) || defined __cplusplus |
268 | typedef double _Float32x; |
269 | # endif |
270 | |
271 | # if !__GNUC_PREREQ (7, 0) |
272 | # define __builtin_huge_valf32x() (__builtin_huge_val ()) |
273 | # define __builtin_inff32x() (__builtin_inf ()) |
274 | # define __builtin_nanf32x(x) (__builtin_nan (x)) |
275 | # define __builtin_nansf32x(x) (__builtin_nans (x)) |
276 | # endif |
277 | |
278 | # endif |
279 | |
280 | # if __HAVE_FLOAT64X |
281 | |
282 | # if __HAVE_FLOAT64X_LONG_DOUBLE |
283 | |
284 | # if !__GNUC_PREREQ (7, 0) || defined __cplusplus |
285 | typedef long double _Float64x; |
286 | # endif |
287 | |
288 | # if !__GNUC_PREREQ (7, 0) |
289 | # define __builtin_huge_valf64x() (__builtin_huge_vall ()) |
290 | # define __builtin_inff64x() (__builtin_infl ()) |
291 | # define __builtin_nanf64x(x) (__builtin_nanl (x)) |
292 | # define __builtin_nansf64x(x) (__builtin_nansl (x)) |
293 | # endif |
294 | |
295 | # else |
296 | |
297 | # if !__GNUC_PREREQ (7, 0) || defined __cplusplus |
298 | typedef _Float128 _Float64x; |
299 | # endif |
300 | |
301 | # if !__GNUC_PREREQ (7, 0) |
302 | # define __builtin_huge_valf64x() (__builtin_huge_valf128 ()) |
303 | # define __builtin_inff64x() (__builtin_inff128 ()) |
304 | # define __builtin_nanf64x(x) (__builtin_nanf128 (x)) |
305 | # define __builtin_nansf64x(x) (__builtin_nansf128 (x)) |
306 | # endif |
307 | |
308 | # endif |
309 | |
310 | # endif |
311 | |
312 | # if __HAVE_FLOAT128X |
313 | |
314 | # if !__GNUC_PREREQ (7, 0) || defined __cplusplus |
315 | # error "_Float128x supported but no type" |
316 | # endif |
317 | |
318 | # if !__GNUC_PREREQ (7, 0) |
319 | # define __builtin_huge_valf128x() ((_Float128x) __builtin_huge_val ()) |
320 | # define __builtin_inff128x() ((_Float128x) __builtin_inf ()) |
321 | # define __builtin_nanf128x(x) ((_Float128x) __builtin_nan (x)) |
322 | # define __builtin_nansf128x(x) ((_Float128x) __builtin_nans (x)) |
323 | # endif |
324 | |
325 | # endif |
326 | |
327 | #endif /* !__ASSEMBLER__. */ |
328 | |
329 | #endif /* _BITS_FLOATN_COMMON_H */ |
330 | |