1 | /* Macros to control TS 18661-3 glibc features where the same |
2 | definitions are appropriate for all platforms. |
3 | Copyright (C) 2017-2018 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 | <http://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 any _FloatN or _FloatNx types that are not |
60 | ABI-distinct are however distinct types at the C language level (so |
61 | for the purposes of __builtin_types_compatible_p and _Generic). */ |
62 | #if __GNUC_PREREQ (7, 0) && !defined __cplusplus |
63 | # define __HAVE_FLOATN_NOT_TYPEDEF 1 |
64 | #else |
65 | # define __HAVE_FLOATN_NOT_TYPEDEF 0 |
66 | #endif |
67 | |
68 | #ifndef __ASSEMBLER__ |
69 | |
70 | /* Defined to concatenate the literal suffix to be used with _FloatN |
71 | or _FloatNx types, if __HAVE_<type> is 1. The corresponding |
72 | literal suffixes exist since GCC 7, for C only. */ |
73 | # if __HAVE_FLOAT16 |
74 | # if !__GNUC_PREREQ (7, 0) || defined __cplusplus |
75 | /* No corresponding suffix available for this type. */ |
76 | # define __f16(x) ((_Float16) x##f) |
77 | # else |
78 | # define __f16(x) x##f16 |
79 | # endif |
80 | # endif |
81 | |
82 | # if __HAVE_FLOAT32 |
83 | # if !__GNUC_PREREQ (7, 0) || defined __cplusplus |
84 | # define __f32(x) x##f |
85 | # else |
86 | # define __f32(x) x##f32 |
87 | # endif |
88 | # endif |
89 | |
90 | # if __HAVE_FLOAT64 |
91 | # if !__GNUC_PREREQ (7, 0) || defined __cplusplus |
92 | # ifdef __NO_LONG_DOUBLE_MATH |
93 | # define __f64(x) x##l |
94 | # else |
95 | # define __f64(x) x |
96 | # endif |
97 | # else |
98 | # define __f64(x) x##f64 |
99 | # endif |
100 | # endif |
101 | |
102 | # if __HAVE_FLOAT32X |
103 | # if !__GNUC_PREREQ (7, 0) || defined __cplusplus |
104 | # define __f32x(x) x |
105 | # else |
106 | # define __f32x(x) x##f32x |
107 | # endif |
108 | # endif |
109 | |
110 | # if __HAVE_FLOAT64X |
111 | # if !__GNUC_PREREQ (7, 0) || defined __cplusplus |
112 | # if __HAVE_FLOAT64X_LONG_DOUBLE |
113 | # define __f64x(x) x##l |
114 | # else |
115 | # define __f64x(x) __f128 (x) |
116 | # endif |
117 | # else |
118 | # define __f64x(x) x##f64x |
119 | # endif |
120 | # endif |
121 | |
122 | # if __HAVE_FLOAT128X |
123 | # if !__GNUC_PREREQ (7, 0) || defined __cplusplus |
124 | # error "_Float128X supported but no constant suffix" |
125 | # else |
126 | # define __f128x(x) x##f128x |
127 | # endif |
128 | # endif |
129 | |
130 | /* Defined to a complex type if __HAVE_<type> is 1. */ |
131 | # if __HAVE_FLOAT16 |
132 | # if !__GNUC_PREREQ (7, 0) || defined __cplusplus |
133 | typedef _Complex float __cfloat16 __attribute__ ((__mode__ (__HC__))); |
134 | # define __CFLOAT16 __cfloat16 |
135 | # else |
136 | # define __CFLOAT16 _Complex _Float16 |
137 | # endif |
138 | # endif |
139 | |
140 | # if __HAVE_FLOAT32 |
141 | # if !__GNUC_PREREQ (7, 0) || defined __cplusplus |
142 | # define __CFLOAT32 _Complex float |
143 | # else |
144 | # define __CFLOAT32 _Complex _Float32 |
145 | # endif |
146 | # endif |
147 | |
148 | # if __HAVE_FLOAT64 |
149 | # if !__GNUC_PREREQ (7, 0) || defined __cplusplus |
150 | # ifdef __NO_LONG_DOUBLE_MATH |
151 | # define __CFLOAT64 _Complex long double |
152 | # else |
153 | # define __CFLOAT64 _Complex double |
154 | # endif |
155 | # else |
156 | # define __CFLOAT64 _Complex _Float64 |
157 | # endif |
158 | # endif |
159 | |
160 | # if __HAVE_FLOAT32X |
161 | # if !__GNUC_PREREQ (7, 0) || defined __cplusplus |
162 | # define __CFLOAT32X _Complex double |
163 | # else |
164 | # define __CFLOAT32X _Complex _Float32x |
165 | # endif |
166 | # endif |
167 | |
168 | # if __HAVE_FLOAT64X |
169 | # if !__GNUC_PREREQ (7, 0) || defined __cplusplus |
170 | # if __HAVE_FLOAT64X_LONG_DOUBLE |
171 | # define __CFLOAT64X _Complex long double |
172 | # else |
173 | # define __CFLOAT64X __CFLOAT128 |
174 | # endif |
175 | # else |
176 | # define __CFLOAT64X _Complex _Float64x |
177 | # endif |
178 | # endif |
179 | |
180 | # if __HAVE_FLOAT128X |
181 | # if !__GNUC_PREREQ (7, 0) || defined __cplusplus |
182 | # error "_Float128X supported but no complex type" |
183 | # else |
184 | # define __CFLOAT128X _Complex _Float128x |
185 | # endif |
186 | # endif |
187 | |
188 | /* The remaining of this file provides support for older compilers. */ |
189 | # if __HAVE_FLOAT16 |
190 | |
191 | # if !__GNUC_PREREQ (7, 0) || defined __cplusplus |
192 | typedef float _Float16 __attribute__ ((__mode__ (__HF__))); |
193 | # endif |
194 | |
195 | # if !__GNUC_PREREQ (7, 0) |
196 | # define __builtin_huge_valf16() ((_Float16) __builtin_huge_val ()) |
197 | # define __builtin_inff16() ((_Float16) __builtin_inf ()) |
198 | # define __builtin_nanf16(x) ((_Float16) __builtin_nan (x)) |
199 | # define __builtin_nansf16(x) ((_Float16) __builtin_nans (x)) |
200 | # endif |
201 | |
202 | # endif |
203 | |
204 | # if __HAVE_FLOAT32 |
205 | |
206 | # if !__GNUC_PREREQ (7, 0) || defined __cplusplus |
207 | typedef float _Float32; |
208 | # endif |
209 | |
210 | # if !__GNUC_PREREQ (7, 0) |
211 | # define __builtin_huge_valf32() (__builtin_huge_valf ()) |
212 | # define __builtin_inff32() (__builtin_inff ()) |
213 | # define __builtin_nanf32(x) (__builtin_nanf (x)) |
214 | # define __builtin_nansf32(x) (__builtin_nansf (x)) |
215 | # endif |
216 | |
217 | # endif |
218 | |
219 | # if __HAVE_FLOAT64 |
220 | |
221 | /* If double, long double and _Float64 all have the same set of |
222 | values, TS 18661-3 requires the usual arithmetic conversions on |
223 | long double and _Float64 to produce _Float64. For this to be the |
224 | case when building with a compiler without a distinct _Float64 |
225 | type, _Float64 must be a typedef for long double, not for |
226 | double. */ |
227 | |
228 | # ifdef __NO_LONG_DOUBLE_MATH |
229 | |
230 | # if !__GNUC_PREREQ (7, 0) || defined __cplusplus |
231 | typedef long double _Float64; |
232 | # endif |
233 | |
234 | # if !__GNUC_PREREQ (7, 0) |
235 | # define __builtin_huge_valf64() (__builtin_huge_vall ()) |
236 | # define __builtin_inff64() (__builtin_infl ()) |
237 | # define __builtin_nanf64(x) (__builtin_nanl (x)) |
238 | # define __builtin_nansf64(x) (__builtin_nansl (x)) |
239 | # endif |
240 | |
241 | # else |
242 | |
243 | # if !__GNUC_PREREQ (7, 0) || defined __cplusplus |
244 | typedef double _Float64; |
245 | # endif |
246 | |
247 | # if !__GNUC_PREREQ (7, 0) |
248 | # define __builtin_huge_valf64() (__builtin_huge_val ()) |
249 | # define __builtin_inff64() (__builtin_inf ()) |
250 | # define __builtin_nanf64(x) (__builtin_nan (x)) |
251 | # define __builtin_nansf64(x) (__builtin_nans (x)) |
252 | # endif |
253 | |
254 | # endif |
255 | |
256 | # endif |
257 | |
258 | # if __HAVE_FLOAT32X |
259 | |
260 | # if !__GNUC_PREREQ (7, 0) || defined __cplusplus |
261 | typedef double _Float32x; |
262 | # endif |
263 | |
264 | # if !__GNUC_PREREQ (7, 0) |
265 | # define __builtin_huge_valf32x() (__builtin_huge_val ()) |
266 | # define __builtin_inff32x() (__builtin_inf ()) |
267 | # define __builtin_nanf32x(x) (__builtin_nan (x)) |
268 | # define __builtin_nansf32x(x) (__builtin_nans (x)) |
269 | # endif |
270 | |
271 | # endif |
272 | |
273 | # if __HAVE_FLOAT64X |
274 | |
275 | # if __HAVE_FLOAT64X_LONG_DOUBLE |
276 | |
277 | # if !__GNUC_PREREQ (7, 0) || defined __cplusplus |
278 | typedef long double _Float64x; |
279 | # endif |
280 | |
281 | # if !__GNUC_PREREQ (7, 0) |
282 | # define __builtin_huge_valf64x() (__builtin_huge_vall ()) |
283 | # define __builtin_inff64x() (__builtin_infl ()) |
284 | # define __builtin_nanf64x(x) (__builtin_nanl (x)) |
285 | # define __builtin_nansf64x(x) (__builtin_nansl (x)) |
286 | # endif |
287 | |
288 | # else |
289 | |
290 | # if !__GNUC_PREREQ (7, 0) || defined __cplusplus |
291 | typedef _Float128 _Float64x; |
292 | # endif |
293 | |
294 | # if !__GNUC_PREREQ (7, 0) |
295 | # define __builtin_huge_valf64x() (__builtin_huge_valf128 ()) |
296 | # define __builtin_inff64x() (__builtin_inff128 ()) |
297 | # define __builtin_nanf64x(x) (__builtin_nanf128 (x)) |
298 | # define __builtin_nansf64x(x) (__builtin_nansf128 (x)) |
299 | # endif |
300 | |
301 | # endif |
302 | |
303 | # endif |
304 | |
305 | # if __HAVE_FLOAT128X |
306 | |
307 | # if !__GNUC_PREREQ (7, 0) || defined __cplusplus |
308 | # error "_Float128x supported but no type" |
309 | # endif |
310 | |
311 | # if !__GNUC_PREREQ (7, 0) |
312 | # define __builtin_huge_valf128x() ((_Float128x) __builtin_huge_val ()) |
313 | # define __builtin_inff128x() ((_Float128x) __builtin_inf ()) |
314 | # define __builtin_nanf128x(x) ((_Float128x) __builtin_nan (x)) |
315 | # define __builtin_nansf128x(x) ((_Float128x) __builtin_nans (x)) |
316 | # endif |
317 | |
318 | # endif |
319 | |
320 | #endif /* !__ASSEMBLER__. */ |
321 | |
322 | #endif /* _BITS_FLOATN_COMMON_H */ |
323 | |