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]

Adding __float128 (i.e TS 18661-3)


This is a big change. First and foremost, any changes *must* not change
any of the artifacts of the build process, or reduce the effectiveness
of testing. As a corollary, nothing should be exposed until we have
sufficient testing in place to ensure a good, maintainable user
experience.

As Joseph pointed out earlier in [1] and [2] we can't hack and slash our
way into supporting this, but IMO, the consensus driven model doesn't
encourage a large upfront design, as interested parties only seem to
show up at the tail end (during patch submissions). I think we need
consensus on what the end result will look like, and what steps will
get us there.

In addition, I would like to narrow the focus of the discussion to switch
the PPC64 long double type [3] to the more immediate goal of supporting
__float128 in glibc. Arguably, it is the first step towards the larger
goal of changing the underlying implementation of long double on PPC64.
And, other architectures could benefit from having a better supported
binary128 type.

For the initial support, I want to focus on math.h. I suggest the
following should be the minimal set of libm/c functions required to
enable a new TS 18661-3 type:

copysign modf scalbn frexp ldexp sin cos ceil erf expm1 fabs
floor log1p logb nextafter rint scalbln tan tanh fmax fmin fdim trunc
remquo round lround llround nextup nextdown acos acosh asin asinh
atan2 atanh cosh exp exp10 fmod hypot log log2 log10 pow scalbn ilogb
exp2 lgamma_r lgamma

likewise for libc:

strto strto*_l wcsto wcsto*_l strfrom strfrom*_l wcsfrom wcsfrom*_l

Note that the _l suffixed and wcs prefixed functions are not called out
by TS 18661-3, but for the sake of completeness and API symmetry they
ought to be included as gnu extensions.

math.h will add support for the type generic classification macros, and
expose the above if the user defines __STDC_WANT_IEC_60559_TYPES_EXT__
and builds with C11 support. I.e

#define __C11_GENEN(t,f)  \
           t: f,         \
  const    t: f,         \
  volatile t: f,         \
  volatile const t: f,

# if __GNUC_PREREQ (4,6) && !defined __SUPPORT_SNAN__                        \
     && !defined __OPTIMIZE_SIZE__
#  define fpclassify(x) __builtin_fpclassify (FP_NAN, FP_INFINITE,           \
     FP_NORMAL, FP_SUBNORMAL, FP_ZERO, x)
# else
#  define fpclassify(x) _Generic( (x),                 \
       __C11_GENEN (float, __fpclassifyf)              \
       __C11_GENEN (double, __fpclassify)              \
       __C11_GENFLT128 (__fpclassifyf128)              \
       default: __FPCLASSIFYL) (x)                     \
# endif

Where __C11_GENFLT128(x) is defined to __C11_GENEN(__float128,x) or
nothing depending on what is supported. This seems slightly better than
extending the existing macros with a GNU specific test.


TS 18661-3 also calls out a number of macros which should be included by
float.h, which would need to be added through GCC. Would adding a new
public header like float-ts18661.h be permissible or should such
definitions be held in private headers for internal usage in the meantime?


I consider the build changes as including the test fixtures. How
exactly the test fixtures are extended is less important, it just needs
to work, and should be easily expandable to future formats.

My proposed design for source structure is:
* sysdeps/ieee754/f128/ holds all the __float128
  (e.g sysdeps/ieee754/f64x-ibm for a _Float64x type based off ibm128)
* sysdeps/ieee754/f128/Makeconfig which defines
  f128-fcts := yes
* sysdeps/{arch}/Makeconfig can optionally declare
  f128-CFLAGS to add extra build options for these files
* matherr and other legacy behavior should stick around.
  Why? This should enable trivial mapping between similar
  ldbl and f128 symbols, saving a little codespace.
* stdio/ and wcsmbs/ will hold analogues to the various
  libc functions called out above, there are a number
  of them.
* Arches desiring the new type would add the new directory
  to their respective Implies file.
* Use the macro __STDC_WANT_IEC_60559_TYPES_EXT__ to control
  enablement of these features inside glibc.

As for source, we should avoid duplication of non-trivial assets, and
that requires refactoring most of the ldbl-128 sources. I'd rather
not use Makefile/script tricks to generate the files. The only truly
ugly thing I've encountered thus far is using a macro to add the
correct suffix (L for long double, Q for __float128).

I.e slip in a header defining something like:

#ifdef __STDC_WANT_IEC_60559_TYPES_EXT__
  /* build ldbl-128 file as a f128 file.  */
  #define GET_F128_MSW64 GET_FLOAT128_MSW64
  #define GET_F128_LSW64 GET_FLOAT128_LSW64
  #define GET_F128_WORDS64 GET_FLOAT128_WORDS64
  #define SET_F128_WORDS64 SET_FLOAT128_WORDS64
  #define F128(_x) _x ## Q
  #define F128_NAME(_n) _n ## f128
  #define weak_alias_f128(_t, _f) weak_alias(_t ## f128, _f ## f128)
  typedef __float128 F128;
#else
  /* build ldbl-128 file normally (as long double).  */
  #define GET_F128_MSW64 GET_LDOUBLE_MSW64
  #define GET_F128_LSW64 GET_LDOUBLE_LSW64
  #define GET_F128_WORDS64 GET_LDOUBLE_WORDS64
  #define SET_F128_WORDS64 SET_LDOUBLE_WORDS64
  #define F128(_x) _x ## L
  #define F128_NAME(_n) _n ## l
  #define weak_alias_f128(_t, _f) weak_alias(_t ## l, _f ## l)
  typedef long double F128;
#endif

And make the necessary changes to the shared lbdl-128 files. Such
changes will be verbose, a little more intrusive, but less
haphazard. Such a strategy could be adopted for future transition
(e.g _Float64x). Likewise, where ldbl is already binary128, the
__float128 symbols can just be aliased to their ldbl analogues.

Thanks,
Paul

[1] https://sourceware.org/ml/libc-alpha/2015-11/msg00162.html
[2] https://sourceware.org/ml/libc-alpha/2015-11/msg00390.html
[3] https://sourceware.org/ml/libc-alpha/2016-04/msg00466.html


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