master
  1/* Macros to control TS 18661-3 glibc features where the same
  2   definitions are appropriate for all platforms.
  3   Copyright (C) 2017-2025 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 && !__GNUC_PREREQ (13, 0))
 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 && !__GNUC_PREREQ (13, 0))
 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 && !__GNUC_PREREQ (13, 0))
 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 && !__GNUC_PREREQ (13, 0))
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 && !__GNUC_PREREQ (13, 0))
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 && !__GNUC_PREREQ (13, 0))
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 && !__GNUC_PREREQ (13, 0))
140typedef _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 && !__GNUC_PREREQ (13, 0))
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 && !__GNUC_PREREQ (13, 0))
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 && !__GNUC_PREREQ (13, 0))
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 && !__GNUC_PREREQ (13, 0))
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 && !__GNUC_PREREQ (13, 0))
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 && !__GNUC_PREREQ (13, 0))
199typedef 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 && !__GNUC_PREREQ (13, 0))
214typedef 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 && !__GNUC_PREREQ (13, 0))
238typedef 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 && !__GNUC_PREREQ (13, 0))
251typedef 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 && !__GNUC_PREREQ (13, 0))
268typedef 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 && !__GNUC_PREREQ (13, 0))
285typedef 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 && !__GNUC_PREREQ (13, 0))
298typedef _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 && !__GNUC_PREREQ (13, 0))
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 */