ldbl-128ibm: make ieee754.h work with IEEE 128 long double

Instead of attempting something more creative, just copy
the small struct from ldbl-128 and enable it when IEEE
long double is present, and update the ibm long double
variant if supported.

Likewise, provide a shadow copy of math_ldbl.h to prevent
the ibm128 specific long double header from poisoning
unrelated files due to it's usage in math_private.h.

Reviewed-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
This commit is contained in:
Paul E. Murphy 2020-02-07 14:07:01 -06:00
parent bb05281822
commit a92ac9f494
2 changed files with 96 additions and 2 deletions

View File

@ -0,0 +1,30 @@
/* Manipulation of the bit representation of 'long double' quantities.
Copyright (C) 2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#ifndef _MATH_LDBL_H_IBM128_COMPAT
#define _MATH_LDBL_H_IBM128_COMPAT 1
#include <bits/floatn.h>
/* Trampoline in the ldbl-128ibm headers if building against the
old abi. Otherwise, we have nothing to add. */
#if __LONG_DOUBLE_USES_FLOAT128 == 0
#include_next <math_ldbl.h>
#endif
#endif /* _MATH_LDBL_H_IBM128_COMPAT */

View File

@ -21,6 +21,7 @@
#include <features.h>
#include <bits/endian.h>
#include <bits/floatn.h>
__BEGIN_DECLS
@ -111,6 +112,65 @@ union ieee754_double
#define IEEE754_DOUBLE_BIAS 0x3ff /* Added to exponent. */
#if __LONG_DOUBLE_USES_FLOAT128 == 1
/* long double is IEEE 128 bit */
union ieee854_long_double
{
long double d;
/* This is the IEEE 854 quad-precision format. */
struct
{
#if __BYTE_ORDER == __BIG_ENDIAN
unsigned int negative:1;
unsigned int exponent:15;
/* Together these comprise the mantissa. */
unsigned int mantissa0:16;
unsigned int mantissa1:32;
unsigned int mantissa2:32;
unsigned int mantissa3:32;
#endif /* Big endian. */
#if __BYTE_ORDER == __LITTLE_ENDIAN
/* Together these comprise the mantissa. */
unsigned int mantissa3:32;
unsigned int mantissa2:32;
unsigned int mantissa1:32;
unsigned int mantissa0:16;
unsigned int exponent:15;
unsigned int negative:1;
#endif /* Little endian. */
} ieee;
/* This format makes it easier to see if a NaN is a signalling NaN. */
struct
{
#if __BYTE_ORDER == __BIG_ENDIAN
unsigned int negative:1;
unsigned int exponent:15;
unsigned int quiet_nan:1;
/* Together these comprise the mantissa. */
unsigned int mantissa0:15;
unsigned int mantissa1:32;
unsigned int mantissa2:32;
unsigned int mantissa3:32;
#else
/* Together these comprise the mantissa. */
unsigned int mantissa3:32;
unsigned int mantissa2:32;
unsigned int mantissa1:32;
unsigned int mantissa0:15;
unsigned int quiet_nan:1;
unsigned int exponent:15;
unsigned int negative:1;
#endif
} ieee_nan;
};
#define IEEE854_LONG_DOUBLE_BIAS 0x3fff /* Added to exponent. */
#endif
#if __LONG_DOUBLE_USES_FLOAT128 == 0 || __GNUC_PREREQ (7, 0)
/* IBM extended format for long double.
Each long double is made up of two IEEE doubles. The value of the
@ -121,12 +181,16 @@ union ieee754_double
-0.0. No other requirements are made; so, for example, 1.0 may be
represented as (1.0, +0.0) or (1.0, -0.0), and the low part of a
NaN is don't-care. */
union ibm_extended_long_double
{
long double ld;
# if __LONG_DOUBLE_USES_FLOAT128 == 1 && __GNUC_PREREQ (7, 0)
__ibm128 ld;
# else
long double ld;
# endif
union ieee754_double d[2];
};
#endif
__END_DECLS