This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH 5/8] float128: Add public _Float128 declarations to libm.


On Wed, 9 Nov 2016, Gabriel F. T. Gomes wrote:

> This introduces the machine-dependent bits/floatn.h to control
> the inclusion of _Float128 ABI.
> 
> This leverages the _Generic feature of C11 as __USE_FLOAT128
> must imply a test for __STDC_WANT_IEC_60559_TYPES_EXT__
> which requires C11 to prevent increasingly complex math
> macros for the sake of old (and unsupported?) GCC toolchains.

Older tools are supported for compiling code using glibc.  4.7 and later 
are supported for building glibc (I'd hope we can add float128 support on 
x86-64 / x86 without needing to increase the minimum GCC version for 
building glibc there).

> +/* Defined if the compiler supports the _Float128 (and __float128) type.  */
> +#define __USE_FLOAT128 0

Support for _Float128 and __float128 are distinct things.  GCC 7 supports 
_Float128 on lots of platforms where long double has that format, but not 
__float128.

> +/* Defined if the runtime supports _Float128.  */
> +#define __HAVE_FLOAT128 0

You appear to be using __USE_FLOAT128 conditionals on things assuming 
library facilities to be present.

You need to be very careful in designing exactly what macros are needed to 
specify the available types and their properties, and in writing the 
comments documenting the design.

> +#if __GNUC_PREREQ (7, 0)
> +# define HUGE_VAL_F128	(__builtin_huge_valf128 ())
> +#elif __GNUC_PREREQ (6,2)

Missing space after comma.

> +# define HUGE_VAL_F128	(__builtin_huge_valq ())

My inclination would be to localize the workarounds for old compilers to 
one place, that defines __builtin_huge_valf128 as a macro.  And the choice 
of 6.2 as version here is questionable.  A generic header here should not 
have architecture-specific version conditionals.  For x86, GCC supports 
__builtin_huge_valq long before 6.2 - but even 6.2 doesn't support it in 
static initializers for x86.  So the definition casting HUGE_VAL is safer 
for old compilers.  That is, a bits/floatn-compat.h header could do

#if !__GNUC_PREREQ (7, 0)
# define __builtin_huge_valf128() ((_Float128) __builtin_huge_val ())
#endif

and similarly for defining _Float128 to __float128 and defining other 
__builtin_* macros as needed.  Of course that header would only be needed 
for certain architectures.

> @@ -55,6 +59,10 @@ __BEGIN_DECLS
>  # define CMPLXL(x, y) __builtin_complex ((long double) (x), (long double) (y))
>  #endif
>  
> +#if __USE_FLOAT128
> +# define CMPLXF128(x, y) __builtin_complex ((__float128) (x), (__float128) (y))
> +#endif

CMPLXF128 is only reserved when TS 18661-3 names are defined.  That is, 
all function or macro definitions for the new types need to be conditional 
on an __GLIBC_USE conditional for TS 18661-3 *and* on the particular type 
in question being supported.  Whereas type-generic macros in <math.h>, as 
opposed to those in <tgmath.h>, should support the new types even if the 
__GLIBC_USE conditional for TS 18661-3 is false (meaning you might need to 
split <bits/mathcalls.h> so you can declare e.g. __signbitf128 when not 
declaring sinf128).

> +#if __USE_FLOAT128
> +# ifndef _Mfloat128_
> +#  define _Mfloat128_		_Float128
> +# endif
> +/* GCC < 7 requires extra convincing to expose a complex float128 type.  */
> +# ifdef __CFLOAT128
> +#  undef _Mdouble_complex_
> +#  define _Mdouble_complex_	__CFLOAT128
> +# endif
> +# define _Mdouble_ 		_Mfloat128_
> +# define __MATH_PRECNAME(name)	name##f128
> +# include <bits/cmathcalls.h>

Likewise.

> +#if __USE_FLOAT128
> +# include <bits/huge_val_flt128.h>
> +#endif

Likewise.

> +/* Include the file of declarations again, this time using `_Float128'
> +   instead of `double' and appending f128 to each function name.  */
> +
> +#if __USE_FLOAT128
> +#ifndef _Mfloat128_
> +# define _Mfloat128_		_Float128
> +#endif
> +#define __FLOATN_TYPE		1
> +#define _Mdouble_		_Mfloat128_
> +#define __MATH_PRECNAME(name,r) name##f128##r
> +#define __MATH_DECLARING_DOUBLE  0
> +#define _Mdouble_BEGIN_NAMESPACE __BEGIN_NAMESPACE_C99
> +#define _Mdouble_END_NAMESPACE   __END_NAMESPACE_C99
> +#include <bits/mathcalls.h>

Likewise.

>  /* Return nonzero value if sign of X is negative.  */
> -# if __GNUC_PREREQ (4,0)
> +# if __GNUC_PREREQ (6,2)
> +#  define signbit(x) __builtin_signbit (x)

6.2 isn't the right version.  __builtin_signbit is type-generic in GCC 
from before GCC 6 branched, so use 6.0.

> @@ -299,8 +363,20 @@ enum
>  # endif
>  
>  /* Return nonzero value if X is positive or negative infinity.  */
> -# if __GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__
> +# if __USE_FLOAT128 && !defined __SUPPORT_SNAN__ && defined __GNUC__
> +/* __builtin_isinf_sign is broken for float128.  */

Only broken before GCC 7.

> +#if __USE_FLOAT128

__USE_GNU conditional needed as well.

-- 
Joseph S. Myers
joseph@codesourcery.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]