builtin-types.def (BT_FN_FLOAT_CONST_STRING): New.

gcc/
        * builtin-types.def (BT_FN_FLOAT_CONST_STRING): New.
        (BT_FN_DOUBLE_CONST_STRING, BT_FN_LONG_DOUBLE_CONST_STRING): New.
        * builtins.def (__builtin_nan, __builtin_nanf, __builtin_nanl): New.
        (__builtin_nans, __builtin_nansf, __builtin_nansl): New.
        * builtins.c (fold_builtin_nan): New.
        (fold_builtin): Call it.
        * real.c (real_nan): Parse a non-empty string.
        (round_for_format): Fix NaN significand truncation.
        * real.h (real_nan): Return bool.
        * doc/extend.texi: Document new builtins.

libstdc++/
        * include/std/std_limits.h (__glibcpp_f32_QNaN_bytes,
        __glibcpp_f32_has_QNaN, __glibcpp_f32_SNaN_bytes,
        __glibcpp_f32_has_SNaN, __glibcpp_f64_QNaN_bytes,
        __glibcpp_f64_has_QNaN, __glibcpp_f64_SNaN_bytes,
        __glibcpp_f64_has_SNaN, __glibcpp_f80_QNaN_bytes,
        __glibcpp_f80_has_QNaN, __glibcpp_f80_SNaN_bytes,
        __glibcpp_f80_has_SNaN, __glibcpp_f96_QNaN_bytes,
        __glibcpp_f96_has_QNaN, __glibcpp_f96_SNaN_bytes,
        __glibcpp_f96_has_SNaN, __glibcpp_f128_QNaN_bytes,
        __glibcpp_f128_has_QNaN, __glibcpp_f128_SNaN_bytes,
        __glibcpp_f128_has_SNaN, __glibcpp_float_QNaN_bytes,
        __glibcpp_float_has_QNaN, __glibcpp_float_SNaN_bytes,
        __glibcpp_float_has_SNaN, __glibcpp_double_QNaN_bytes,
        __glibcpp_double_has_QNaN, __glibcpp_double_SNaN_bytes,
        __glibcpp_double_has_SNaN, __glibcpp_long_double_QNaN_bytes,
        __glibcpp_long_double_has_QNaN, __glibcpp_long_double_SNaN_bytes,
        __glibcpp_long_double_has_SNaN): Remove.
        (__glibcpp_f128_is_iec559): True if IEEE.
        (__glibcpp_float_QNaN, __glibcpp_float_SNaN): Remove.
        (__glibcpp_double_QNaN, __glibcpp_double_SNaN): Remove.
        (__glibcpp_long_double_QNaN, __glibcpp_long_double_SNaN): Remove.
        (std::numeric_limits<float>::has_quiet_NaN): Use __builtin_nanf.
        (std::numeric_limits<float>::has_signaling_NaN): Mirror has_quiet_NaN.
        (std::numeric_limits<float>::quiet_NaN): Use __builtin_nanf.
        (std::numeric_limits<float>::signaling_NaN): Use __builtin_nansf.
        (std::numeric_limits<double>): Similarly.
        (std::numeric_limits<long double>): Similarly.
        * src/limits.cc (__glibcpp_float_QNaN, __glibcpp_float_SNaN): Remove.
        (__glibcpp_double_QNaN, __glibcpp_double_SNaN): Remove.
        (__glibcpp_long_double_QNaN, __glibcpp_long_double_SNaN): Remove.

        * testsuite/18_support/numeric_limits.cc (test_infinity): New.
        (test_denorm_min, test_qnan, test_is_iec559): New.

From-SVN: r57221
This commit is contained in:
Richard Henderson 2002-09-16 18:28:50 -07:00 committed by Richard Henderson
parent f354b82835
commit 1472e41cb3
11 changed files with 359 additions and 214 deletions

View File

@ -1,3 +1,16 @@
2002-09-16 Richard Henderson <rth@redhat.com>
* builtin-types.def (BT_FN_FLOAT_CONST_STRING): New.
(BT_FN_DOUBLE_CONST_STRING, BT_FN_LONG_DOUBLE_CONST_STRING): New.
* builtins.def (__builtin_nan, __builtin_nanf, __builtin_nanl): New.
(__builtin_nans, __builtin_nansf, __builtin_nansl): New.
* builtins.c (fold_builtin_nan): New.
(fold_builtin): Call it.
* real.c (real_nan): Parse a non-empty string.
(round_for_format): Fix NaN significand truncation.
* real.h (real_nan): Return bool.
* doc/extend.texi: Document new builtins.
2002-09-16 Jason Merrill <jason@redhat.com>
Danny Smith <dannysmith@users.sourceforge.net>

View File

@ -117,6 +117,10 @@ DEF_FUNCTION_TYPE_1 (BT_FN_INT_CONST_STRING, BT_INT, BT_CONST_STRING)
DEF_FUNCTION_TYPE_1 (BT_FN_PTR_PTR, BT_PTR, BT_PTR)
DEF_FUNCTION_TYPE_1 (BT_FN_VOID_VALIST_REF, BT_VOID, BT_VALIST_REF)
DEF_FUNCTION_TYPE_1 (BT_FN_VOID_INT, BT_VOID, BT_INT)
DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT_CONST_STRING, BT_FLOAT, BT_CONST_STRING)
DEF_FUNCTION_TYPE_1 (BT_FN_DOUBLE_CONST_STRING, BT_DOUBLE, BT_CONST_STRING)
DEF_FUNCTION_TYPE_1 (BT_FN_LONG_DOUBLE_CONST_STRING,
BT_LONG_DOUBLE, BT_CONST_STRING)
DEF_FUNCTION_TYPE_2 (BT_FN_VOID_PTR_INT, BT_VOID, BT_PTR, BT_INT)
DEF_FUNCTION_TYPE_2 (BT_FN_STRING_STRING_CONST_STRING,

View File

@ -149,6 +149,7 @@ static rtx expand_builtin_expect PARAMS ((tree, rtx));
static tree fold_builtin_constant_p PARAMS ((tree));
static tree fold_builtin_classify_type PARAMS ((tree));
static tree fold_builtin_inf PARAMS ((tree, int));
static tree fold_builtin_nan PARAMS ((tree, tree, int));
static tree build_function_call_expr PARAMS ((tree, tree));
static int validate_arglist PARAMS ((tree, ...));
@ -4149,6 +4150,28 @@ fold_builtin_inf (type, warn)
return build_real (type, real);
}
/* Fold a call to __builtin_nan or __builtin_nans. */
static tree
fold_builtin_nan (arglist, type, quiet)
tree arglist, type;
int quiet;
{
REAL_VALUE_TYPE real;
const char *str;
if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
return 0;
str = c_getstr (TREE_VALUE (arglist));
if (!str)
return 0;
if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
return 0;
return build_real (type, real);
}
/* Used by constant folding to eliminate some builtin calls early. EXP is
the CALL_EXPR of a call to a builtin function. */
@ -4190,6 +4213,16 @@ fold_builtin (exp)
case BUILT_IN_HUGE_VALL:
return fold_builtin_inf (TREE_TYPE (TREE_TYPE (fndecl)), false);
case BUILT_IN_NAN:
case BUILT_IN_NANF:
case BUILT_IN_NANL:
return fold_builtin_nan (arglist, TREE_TYPE (TREE_TYPE (fndecl)), true);
case BUILT_IN_NANS:
case BUILT_IN_NANSF:
case BUILT_IN_NANSL:
return fold_builtin_nan (arglist, TREE_TYPE (TREE_TYPE (fndecl)), false);
default:
break;
}

View File

@ -427,6 +427,32 @@ DEF_GCC_BUILTIN(BUILT_IN_HUGE_VALL,
BT_FN_LONG_DOUBLE,
ATTR_CONST_NOTHROW_LIST)
DEF_LIB_BUILTIN(BUILT_IN_NAN,
"__builtin_nan",
BT_FN_DOUBLE_CONST_STRING,
ATTR_CONST_NOTHROW_LIST)
DEF_LIB_BUILTIN(BUILT_IN_NANF,
"__builtin_nanf",
BT_FN_FLOAT_CONST_STRING,
ATTR_CONST_NOTHROW_LIST)
DEF_LIB_BUILTIN(BUILT_IN_NANL,
"__builtin_nanl",
BT_FN_LONG_DOUBLE_CONST_STRING,
ATTR_CONST_NOTHROW_LIST)
DEF_LIB_BUILTIN(BUILT_IN_NANS,
"__builtin_nans",
BT_FN_DOUBLE_CONST_STRING,
ATTR_CONST_NOTHROW_LIST)
DEF_LIB_BUILTIN(BUILT_IN_NANSF,
"__builtin_nansf",
BT_FN_FLOAT_CONST_STRING,
ATTR_CONST_NOTHROW_LIST)
DEF_LIB_BUILTIN(BUILT_IN_NANSL,
"__builtin_nansl",
BT_FN_LONG_DOUBLE_CONST_STRING,
ATTR_CONST_NOTHROW_LIST)
DEF_GCC_BUILTIN(BUILT_IN_SAVEREGS,
"__builtin_saveregs",
BT_FN_PTR_VAR,

View File

@ -4863,6 +4863,44 @@ Similar to @code{__builtin_inf}, except the return
type is @code{long double}.
@end deftypefn
@deftypefn {Built-in Function} double __builtin_nan (const char *str)
This is an implementation of the ISO C99 function @code{nan}.
Since ISO C99 defines this function in terms of @code{strtod}, which we
do not implement, a desription of the parsing is in order. The string
is parsed as by @code{strtol}; that is, the base is recognized by
leading @samp{0} or @samp{0x} prefixes. The number parsed is placed
in the significand such that the least significant bit of the number
is at the least significant bit of the significand. The number is
truncated to fit the significand field provided. The significand is
forced to be a quiet NaN.
This function, if given a string literal, is evaluated early enough
that it is considered a compile-time constant.
@end deftypefn
@deftypefn {Built-in Function} float __builtin_nanf (const char *str)
Similar to @code{__builtin_nan}, except the return type is @code{float}.
@end deftypefn
@deftypefn {Built-in Function} long double __builtin_nanl (const char *str)
Similar to @code{__builtin_nan}, except the return type is @code{long double}.
@end deftypefn
@deftypefn {Built-in Function} double __builtin_nans (const char *str)
Similar to @code{__builtin_nan}, except the significand is forced
to be a signaling NaN. The @code{nans} function is proposed by
@uref{http://std.dkuug.dk/JTC1/SC22/WG14/www/docs/n965.htm,,WG14 N956}.
@end deftypefn
@deftypefn {Built-in Function} float __builtin_nansf (const char *str)
Similar to @code{__builtin_nans}, except the return type is @code{float}.
@end deftypefn
@deftypefn {Built-in Function} long double __builtin_nansl (const char *str)
Similar to @code{__builtin_nans}, except the return type is @code{long double}.
@end deftypefn
@node Target Builtins
@section Built-in Functions Specific to Particular Target Machines

View File

@ -1946,16 +1946,22 @@ real_inf (tr)
/* Fills R with a NaN whose significand is described by STR. If QUIET,
we force a QNaN, else we force an SNaN. The string, if not empty,
is parsed as a number and placed in the significand. */
is parsed as a number and placed in the significand. Return true
if the string was successfully parsed. */
void
bool
real_nan (tr, str, quiet, mode)
REAL_VALUE_TYPE *tr;
const char *str;
int quiet;
enum machine_mode mode ATTRIBUTE_UNUSED;
enum machine_mode mode;
{
struct real_value *r = (struct real_value *) tr;
const struct real_format *fmt;
fmt = fmt_for_mode[mode - QFmode];
if (fmt == NULL)
abort ();
if (*str == 0)
{
@ -1965,8 +1971,89 @@ real_nan (tr, str, quiet, mode)
get_canonical_snan (r, 0);
}
else
/* FIXME */
abort ();
{
int base = 10, d;
bool neg = false;
memset (r, 0, sizeof (*r));
r->class = rvc_nan;
/* Parse akin to strtol into the significand of R. */
while (ISSPACE (*str))
str++;
if (*str == '-')
str++, neg = true;
else if (*str == '+')
str++;
if (*str == '0')
{
if (*++str == 'x')
str++, base = 16;
else
base = 8;
}
while ((d = hex_value (*str)) < base)
{
struct real_value u;
switch (base)
{
case 8:
lshift_significand (r, r, 3);
break;
case 16:
lshift_significand (r, r, 4);
break;
case 10:
lshift_significand_1 (&u, r);
lshift_significand (r, r, 3);
add_significands (r, r, &u);
break;
default:
abort ();
}
get_zero (&u, 0);
u.sig[0] = d;
add_significands (r, r, &u);
str++;
}
/* Must have consumed the entire string for success. */
if (*str != 0)
return false;
/* Shift the significand into place such that the bits
are in the most significant bits for the format. */
lshift_significand (r, r, SIGNIFICAND_BITS - fmt->p);
/* Our MSB is always unset for NaNs. */
r->sig[SIGSZ-1] &= ~SIG_MSB;
/* Force quiet or signalling NaN. */
if (quiet)
r->sig[SIGSZ-1] |= SIG_MSB >> 1;
else
r->sig[SIGSZ-1] &= ~(SIG_MSB >> 1);
/* Force at least one bit of the significand set. */
for (d = 0; d < SIGSZ; ++d)
if (r->sig[d])
break;
if (d == SIGSZ)
r->sig[SIGSZ-1] |= SIG_MSB >> 2;
/* Our intermediate format forces QNaNs to have MSB-1 set.
If the target format has QNaNs with the top bit unset,
mirror the output routines and invert the top two bits. */
if (!fmt->qnan_msb_set)
r->sig[SIGSZ-1] ^= (SIG_MSB >> 1) | (SIG_MSB >> 2);
}
return true;
}
/* Fills R with 2**N. */
@ -2023,7 +2110,7 @@ round_for_format (fmt, r)
return;
case rvc_nan:
clear_significand_below (r, np2 + 1);
clear_significand_below (r, np2);
/* If we've cleared the entire significand, we need one bit
set for this to continue to be a NaN. */
@ -2031,7 +2118,7 @@ round_for_format (fmt, r)
if (r->sig[i])
break;
if (i == SIGSZ)
r->sig[SIGSZ-1] = SIG_MSB >> 1;
r->sig[SIGSZ-1] = SIG_MSB >> 2;
return;
case rvc_normal:

View File

@ -143,7 +143,7 @@ extern void real_from_target PARAMS ((REAL_VALUE_TYPE *, const long *,
extern void real_inf PARAMS ((REAL_VALUE_TYPE *));
extern void real_nan PARAMS ((REAL_VALUE_TYPE *, const char *,
extern bool real_nan PARAMS ((REAL_VALUE_TYPE *, const char *,
int, enum machine_mode));
extern void real_2expN PARAMS ((REAL_VALUE_TYPE *, int));

View File

@ -1,3 +1,39 @@
2002-09-16 Richard Henderson <rth@redhat.com>
* include/std/std_limits.h (__glibcpp_f32_QNaN_bytes,
__glibcpp_f32_has_QNaN, __glibcpp_f32_SNaN_bytes,
__glibcpp_f32_has_SNaN, __glibcpp_f64_QNaN_bytes,
__glibcpp_f64_has_QNaN, __glibcpp_f64_SNaN_bytes,
__glibcpp_f64_has_SNaN, __glibcpp_f80_QNaN_bytes,
__glibcpp_f80_has_QNaN, __glibcpp_f80_SNaN_bytes,
__glibcpp_f80_has_SNaN, __glibcpp_f96_QNaN_bytes,
__glibcpp_f96_has_QNaN, __glibcpp_f96_SNaN_bytes,
__glibcpp_f96_has_SNaN, __glibcpp_f128_QNaN_bytes,
__glibcpp_f128_has_QNaN, __glibcpp_f128_SNaN_bytes,
__glibcpp_f128_has_SNaN, __glibcpp_float_QNaN_bytes,
__glibcpp_float_has_QNaN, __glibcpp_float_SNaN_bytes,
__glibcpp_float_has_SNaN, __glibcpp_double_QNaN_bytes,
__glibcpp_double_has_QNaN, __glibcpp_double_SNaN_bytes,
__glibcpp_double_has_SNaN, __glibcpp_long_double_QNaN_bytes,
__glibcpp_long_double_has_QNaN, __glibcpp_long_double_SNaN_bytes,
__glibcpp_long_double_has_SNaN): Remove.
(__glibcpp_f128_is_iec559): True if IEEE.
(__glibcpp_float_QNaN, __glibcpp_float_SNaN): Remove.
(__glibcpp_double_QNaN, __glibcpp_double_SNaN): Remove.
(__glibcpp_long_double_QNaN, __glibcpp_long_double_SNaN): Remove.
(std::numeric_limits<float>::has_quiet_NaN): Use __builtin_nanf.
(std::numeric_limits<float>::has_signaling_NaN): Mirror has_quiet_NaN.
(std::numeric_limits<float>::quiet_NaN): Use __builtin_nanf.
(std::numeric_limits<float>::signaling_NaN): Use __builtin_nansf.
(std::numeric_limits<double>): Similarly.
(std::numeric_limits<long double>): Similarly.
* src/limits.cc (__glibcpp_float_QNaN, __glibcpp_float_SNaN): Remove.
(__glibcpp_double_QNaN, __glibcpp_double_SNaN): Remove.
(__glibcpp_long_double_QNaN, __glibcpp_long_double_SNaN): Remove.
* testsuite/18_support/numeric_limits.cc (test_infinity): New.
(test_denorm_min, test_qnan, test_is_iec559): New.
2002-09-16 Phil Edwards <pme@gcc.gnu.org>
* testsuite/abi_check.cc: Pull shell fragments out into...

View File

@ -152,115 +152,32 @@
#define __glibcpp_f32_round_error 1.0F
#if __GCC_FLOAT_FORMAT__ == __IEEE_FORMAT__
# define __glibcpp_f32_QNaN_bytes { 0x7fc00000 }
# define __glibcpp_f32_has_QNaN true
# define __glibcpp_f32_SNaN_bytes { 0x7f800001 }
# define __glibcpp_f32_has_SNaN true
# define __glibcpp_f32_is_iec559 true
#endif
#ifndef __glibcpp_f32_QNaN_bytes
# define __glibcpp_f32_QNaN_bytes { }
# define __glibcpp_f32_has_QNaN false
#endif
#ifndef __glibcpp_f32_SNaN_bytes
# define __glibcpp_f32_SNaN_bytes { }
# define __glibcpp_f32_has_SNaN false
#endif
#ifndef __glibcpp_f32_is_iec559
# define __glibcpp_f32_is_iec559 false
#endif
#define __glibcpp_f64_round_error 1.0
#if __GCC_FLOAT_FORMAT__ == __IEEE_FORMAT__
# if __TARGET_FLOAT_WORDS_ORDER__ == __GCC_BIG_ENDIAN__
# define __glibcpp_f64_QNaN_bytes { 0x7ff80000, 0x0 }
# define __glibcpp_f64_SNaN_bytes { 0x7ff00000, 0x1 }
# else
# define __glibcpp_f64_QNaN_bytes { 0x0, 0x7ff80000 }
# define __glibcpp_f64_SNaN_bytes { 0x1, 0x7ff00000 }
# endif
# define __glibcpp_f64_has_QNaN true
# define __glibcpp_f64_has_SNaN true
# define __glibcpp_f64_is_iec559 true
#endif
#ifndef __glibcpp_f64_QNaN_bytes
# define __glibcpp_f64_QNaN_bytes { }
# define __glibcpp_f64_has_QNaN false
#endif
#ifndef __glibcpp_f64_SNaN_bytes
# define __glibcpp_f64_SNaN_bytes { }
# define __glibcpp_f64_has_SNaN false
#endif
#ifndef __glibcpp_f64_is_iec559
# define __glibcpp_f64_is_iec559 false
#endif
#define __glibcpp_f80_round_error 1.0L
#if __GCC_FLOAT_FORMAT__ == __IEEE_FORMAT__
# if __TARGET_BYTES_ORDER__ == __GCC_BIG_ENDIAN__
# define __glibcpp_f80_QNaN_bytes \
{ 0x7f, 0xff, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }
# define __glibcpp_f80_SNaN_bytes \
{ 0x7f, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1 }
# else
# define __glibcpp_f80_QNaN_bytes \
{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xC0, 0xff, 0x7f }
# define __glibcpp_f80_SNaN_bytes \
{ 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0xff, 0x7f }
# endif
# define __glibcpp_f80_has_QNaN true
# define __glibcpp_f80_has_SNaN true
# define __glibcpp_f80_is_iec559 true
#endif
#ifndef __glibcpp_f80_QNaN_bytes
# define __glibcpp_f80_QNaN_bytes { }
# define __glibcpp_f80_has_QNaN false
#endif
#ifndef __glibcpp_f80_SNaN_bytes
# define __glibcpp_f80_SNaN_bytes { }
# define __glibcpp_f80_has_SNaN false
#endif
#ifndef __glibcpp_f80_is_iec559
# define __glibcpp_f80_is_iec559 false
#endif
#define __glibcpp_f96_round_error 1.0L
#if __GCC_FLOAT_FORMAT__ == __IEEE_FORMAT__
# if __TARGET_BYTES_ORDER__ == __GCC_BIG_ENDIAN__
# define __glibcpp_f96_QNaN_bytes { 0x7ff80000, 0x0, 0x0 }
# define __glibcpp_f96_SNaN_bytes { 0x7ff00000, 0x0, 0x1 }
# else
# define __glibcpp_f96_QNaN_bytes { 0x0, 0x0, 0x7ff80000 }
# define __glibcpp_f96_SNaN_bytes { 0x1, 0x0, 0x7ff00000 }
# endif
# define __glibcpp_f96_has_QNaN true
# define __glibcpp_f96_has_SNaN true
# define __glibcpp_f96_is_iec559 true
#endif
#ifndef __glibcpp_f96_QNaN_bytes
# define __glibcpp_f96_QNaN_bytes { }
# define __glibcpp_f96_has_QNaN false
#endif
#ifndef __glibcpp_f96_SNaN_bytes
# define __glibcpp_f96_SNaN_bytes { }
# define __glibcpp_f96_has_SNaN false
#endif
#define __glibcpp_f128_round_error 1.0L
#if __GCC_FLOAT_FORMAT__ == __IEEE_FORMAT__
# if __TARGET_FLOAT_WORDS_ORDER__ == __GCC_BIG_ENDIAN__
# define __glibcpp_f128_QNaN_bytes { 0x7fff0800, 0x0, 0x0, 0x0 }
# define __glibcpp_f128_SNaN_bytes { 0x7fff0000, 0x0, 0x0, 0x1 }
# else
# define __glibcpp_f128_QNaN_bytes { 0x0, 0x0, 0x0, 0x7fff0800 }
# define __glibcpp_f128_SNaN_bytes { 0x1, 0x0, 0x0, 0x7fff0000 }
# endif
# define __glibcpp_f128_has_QNaN true
# define __glibcpp_f128_has_SNaN true
#endif
#ifndef __glibcpp_f128_QNaN_bytes
# define __glibcpp_f128_QNaN_bytes { }
# define __glibcpp_f128_has_QNaN false
#endif
#ifndef __glibcpp_f128_SNaN_bytes
# define __glibcpp_f128_SNaN_bytes { }
# define __glibcpp_f128_has_SNaN false
# define __glibcpp_f128_is_iec559 true
#endif
#ifndef __glibcpp_f128_is_iec559
# define __glibcpp_f128_is_iec559 false
@ -587,24 +504,12 @@
#if __FLOAT_BIT__ == 32
# define __glibcpp_float_round_error __glibcpp_f32_round_error
# define __glibcpp_float_QNaN_bytes __glibcpp_f32_QNaN_bytes
# define __glibcpp_float_SNaN_bytes __glibcpp_f32_SNaN_bytes
# define __glibcpp_float_has_QNaN __glibcpp_f32_has_QNaN
# define __glibcpp_float_has_SNaN __glibcpp_f32_has_SNaN
# define __glibcpp_float_is_iec559 __glibcpp_f32_is_iec559
#elif __FLOAT_BIT__ == 64
# define __glibcpp_float_round_error __glibcpp_f64_round_error
# define __glibcpp_float_QNaN_bytes __glibcpp_f64_QNaN_bytes
# define __glibcpp_float_SNaN_bytes __glibcpp_f64_SNaN_bytes
# define __glibcpp_float_has_QNaN __glibcpp_f64_has_QNaN
# define __glibcpp_float_has_SNaN __glibcpp_f64_has_SNaN
# define __glibcpp_float_is_iec559 __glibcpp_f64_is_iec559
#elif __FLOAT_BIT__ == 80
# define __glibcpp_float_round_error __glibcpp_f80_round_error
# define __glibcpp_float_QNaN_bytes __glibcpp_f80_QNaN_bytes
# define __glibcpp_float_SNaN_bytes __glibcpp_f80_SNaN_bytes
# define __glibcpp_float_has_QNaN __glibcpp_f80_has_QNaN
# define __glibcpp_float_has_SNaN __glibcpp_f80_has_SNaN
# define __glibcpp_float_is_iec559 __glibcpp_f80_is_iec559
#else
// You must define these macros in the configuration file.
@ -612,16 +517,6 @@
// Default values. Should be overriden in configuration files if necessary.
#ifndef __glibcpp_float_QNaN_bytes
# define __glibcpp_float_QNaN_bytes { }
# define __glibcpp_float_has_QNaN false
#endif
#ifndef __glibcpp_float_SNaN_bytes
# define __glibcpp_float_SNaN_bytes { }
# define __glibcpp_float_has_SNaN false
#endif
#ifndef __glibcpp_float_has_denorm_loss
# define __glibcpp_float_has_denorm_loss false
#endif
@ -654,24 +549,12 @@
#if __DOUBLE_BIT__ == 32
# define __glibcpp_double_round_error __glibcpp_f32_round_error
# define __glibcpp_double_QNaN_bytes __glibcpp_f32_QNaN_bytes
# define __glibcpp_double_SNaN_bytes __glibcpp_f32_SNaN_bytes
# define __glibcpp_double_has_QNaN __glibcpp_f32_has_QNaN
# define __glibcpp_double_has_SNaN __glibcpp_f32_has_SNaN
# define __glibcpp_double_is_iec559 __glibcpp_f32_is_iec559
#elif __DOUBLE_BIT__ == 64
# define __glibcpp_double_round_error __glibcpp_f64_round_error
# define __glibcpp_double_QNaN_bytes __glibcpp_f64_QNaN_bytes
# define __glibcpp_double_SNaN_bytes __glibcpp_f64_SNaN_bytes
# define __glibcpp_double_has_QNaN __glibcpp_f64_has_QNaN
# define __glibcpp_double_has_SNaN __glibcpp_f64_has_SNaN
# define __glibcpp_double_is_iec559 __glibcpp_f64_is_iec559
#elif __DOUBLE_BIT__ == 80
# define __glibcpp_double_round_error __glibcpp_f80_round_error
# define __glibcpp_double_QNaN_bytes __glibcpp_f80_QNaN_bytes
# define __glibcpp_double_SNaN_bytes __glibcpp_f80_SNaN_bytes
# define __glibcpp_double_has_QNaN __glibcpp_f80_has_QNaN
# define __glibcpp_double_has_SNaN __glibcpp_f80_has_SNaN
# define __glibcpp_double_is_iec559 __glibcpp_f80_is_iec559
#else
// You must define these macros in the configuration file.
@ -679,16 +562,6 @@
// Default values. Should be overriden in configuration files if necessary.
#ifndef __glibcpp_double_QNaN_bytes
# define __glibcpp_double_QNaN_bytes { }
# define __glibcpp_double_has_QNaN false
#endif
#ifndef __glibcpp_double_SNaN_bytes
# define __glibcpp_double_SNaN_bytes { }
# define __glibcpp_double_has_SNaN false
#endif
#ifndef __glibcpp_double_has_denorm_loss
# define __glibcpp_double_has_denorm_loss false
#endif
@ -721,38 +594,18 @@
#if __LONG_DOUBLE_BIT__ == 32
# define __glibcpp_long_double_round_error __glibcpp_f32_round_error
# define __glibcpp_long_double_QNaN_bytes __glibcpp_f32_QNaN_bytes
# define __glibcpp_long_double_SNaN_bytes __glibcpp_f32_SNaN_bytes
# define __glibcpp_long_double_has_QNaN __glibcpp_f32_has_QNaN
# define __glibcpp_long_double_has_SNaN __glibcpp_f32_has_SNaN
# define __glibcpp_long_double_is_iec559 __glibcpp_f32_is_iec559
#elif __LONG_DOUBLE_BIT__ == 64
# define __glibcpp_long_double_round_error __glibcpp_f64_round_error
# define __glibcpp_long_double_QNaN_bytes __glibcpp_f64_QNaN_bytes
# define __glibcpp_long_double_SNaN_bytes __glibcpp_f64_SNaN_bytes
# define __glibcpp_long_double_has_QNaN __glibcpp_f64_has_QNaN
# define __glibcpp_long_double_has_SNaN __glibcpp_f64_has_SNaN
# define __glibcpp_long_double_is_iec559 __glibcpp_f64_is_iec559
#elif __LONG_DOUBLE_BIT__ == 80
# define __glibcpp_long_double_round_error __glibcpp_f80_round_error
# define __glibcpp_long_double_QNaN_bytes __glibcpp_f80_QNaN_bytes
# define __glibcpp_long_double_SNaN_bytes __glibcpp_f80_SNaN_bytes
# define __glibcpp_long_double_has_QNaN __glibcpp_f80_has_QNaN
# define __glibcpp_long_double_has_SNaN __glibcpp_f80_has_SNaN
# define __glibcpp_long_double_is_iec559 __glibcpp_f80_is_iec559
#elif __LONG_DOUBLE_BIT__ == 96
# define __glibcpp_long_double_round_error __glibcpp_f96_round_error
# define __glibcpp_long_double_QNaN_bytes __glibcpp_f96_QNaN_bytes
# define __glibcpp_long_double_SNaN_bytes __glibcpp_f96_SNaN_bytes
# define __glibcpp_long_double_has_QNaN __glibcpp_f96_has_QNaN
# define __glibcpp_long_double_has_SNaN __glibcpp_f96_has_SNaN
# define __glibcpp_long_double_is_iec559 __glibcpp_f96_is_iec559
#elif __LONG_DOUBLE_BIT__ == 128
# define __glibcpp_long_double_round_error __glibcpp_f128_round_error
# define __glibcpp_long_double_QNaN_bytes __glibcpp_f128_QNaN_bytes
# define __glibcpp_long_double_SNaN_bytes __glibcpp_f128_SNaN_bytes
# define __glibcpp_long_double_has_QNaN __glibcpp_f128_has_QNaN
# define __glibcpp_long_double_has_SNaN __glibcpp_f128_has_SNaN
# define __glibcpp_long_double_is_iec559 __glibcpp_f128_is_iec559
#else
// You must define these macros in the configuration file.
@ -760,16 +613,6 @@
// Default values. Should be overriden in configuration files if necessary.
#ifndef __glibcpp_long_double_QNaN_bytes
# define __glibcpp_long_double_QNaN_bytes { }
# define __glibcpp_long_double_has_QNaN false
#endif
#ifndef __glibcpp_long_double_SNaN_bytes
# define __glibcpp_long_double_SNaN_bytes { }
# define __glibcpp_long_double_has_SNaN false
#endif
#ifndef __glibcpp_long_double_has_denorm_loss
# define __glibcpp_long_double_has_denorm_loss false
#endif
@ -843,15 +686,6 @@ namespace std
#endif
__attribute__((__aligned__(__alignof__(long double))));
extern const __float_storage __glibcpp_float_QNaN;
extern const __float_storage __glibcpp_float_SNaN;
extern const __double_storage __glibcpp_double_QNaN;
extern const __double_storage __glibcpp_double_SNaN;
extern const __long_double_storage __glibcpp_long_double_QNaN;
extern const __long_double_storage __glibcpp_long_double_SNaN;
enum float_round_style
{
round_indeterminate = -1,
@ -1680,8 +1514,9 @@ namespace std
static const bool has_infinity
= __builtin_huge_valf () / 2 == __builtin_huge_valf ();
static const bool has_quiet_NaN = __glibcpp_float_has_QNaN;
static const bool has_signaling_NaN = __glibcpp_float_has_SNaN;
static const bool has_quiet_NaN
= __builtin_nanf ("") != __builtin_nanf ("");
static const bool has_signaling_NaN = has_quiet_NaN;
static const float_denorm_style has_denorm
= __FLT_DENORM_MIN__ ? denorm_present : denorm_absent;
static const bool has_denorm_loss = __glibcpp_float_has_denorm_loss;
@ -1689,9 +1524,9 @@ namespace std
static float infinity() throw()
{ return __builtin_huge_valf (); }
static float quiet_NaN() throw()
{ return *reinterpret_cast<const float*>(__glibcpp_float_QNaN); }
{ return __builtin_nanf (""); }
static float signaling_NaN() throw()
{ return *reinterpret_cast<const float*>(__glibcpp_float_SNaN); }
{ return __builtin_nansf (""); }
static float denorm_min() throw()
{ return __FLT_DENORM_MIN__; }
@ -1705,8 +1540,6 @@ namespace std
};
#undef __glibcpp_float_round_error
#undef __glibcpp_float_has_QNaN
#undef __glibcpp_float_has_SNaN
#undef __glibcpp_float_has_denorm_loss
#undef __glibcpp_float_is_iec559
#undef __glibcpp_float_is_bounded
@ -1743,8 +1576,9 @@ namespace std
static const bool has_infinity
= __builtin_huge_val () / 2 == __builtin_huge_val ();
static const bool has_quiet_NaN = __glibcpp_double_has_QNaN;
static const bool has_signaling_NaN = __glibcpp_double_has_SNaN;
static const bool has_quiet_NaN
= __builtin_nan ("") != __builtin_nan ("");
static const bool has_signaling_NaN = has_quiet_NaN;
static const float_denorm_style has_denorm
= __DBL_DENORM_MIN__ ? denorm_present : denorm_absent;
static const bool has_denorm_loss = __glibcpp_double_has_denorm_loss;
@ -1752,9 +1586,9 @@ namespace std
static double infinity() throw()
{ return __builtin_huge_val(); }
static double quiet_NaN() throw()
{ return *reinterpret_cast<const double*>(__glibcpp_double_QNaN); }
{ return __builtin_nan (""); }
static double signaling_NaN() throw()
{ return *reinterpret_cast<const double*>(__glibcpp_double_SNaN); }
{ return __builtin_nans (""); }
static double denorm_min() throw()
{ return __DBL_DENORM_MIN__; }
@ -1769,8 +1603,6 @@ namespace std
};
#undef __glibcpp_double_round_error
#undef __glibcpp_double_has_QNaN
#undef __glibcpp_double_has_SNaN
#undef __glibcpp_double_has_denorm_loss
#undef __glibcpp_double_is_iec559
#undef __glibcpp_double_is_bounded
@ -1808,8 +1640,9 @@ namespace std
static const bool has_infinity
= __builtin_huge_vall () / 2 == __builtin_huge_vall ();
static const bool has_quiet_NaN = __glibcpp_long_double_has_SNaN;
static const bool has_signaling_NaN = __glibcpp_long_double_has_SNaN;
static const bool has_quiet_NaN
= __builtin_nanl ("") != __builtin_nanl ("");
static const bool has_signaling_NaN = has_quiet_NaN;
static const float_denorm_style has_denorm
= __LDBL_DENORM_MIN__ ? denorm_present : denorm_absent;
static const bool has_denorm_loss
@ -1817,19 +1650,10 @@ namespace std
static long double infinity() throw()
{ return __builtin_huge_vall (); }
static long double quiet_NaN() throw()
{
return *reinterpret_cast<const long double*>
(__glibcpp_long_double_QNaN);
}
{ return __builtin_nanl (""); }
static long double signaling_NaN() throw()
{
return *reinterpret_cast<const long double*>
(__glibcpp_long_double_SNaN);
}
{ return __builtin_nansl (""); }
static long double denorm_min() throw()
{ return __LDBL_DENORM_MIN__; }
@ -1844,8 +1668,6 @@ namespace std
};
#undef __glibcpp_long_double_round_error
#undef __glibcpp_long_double_has_QNaN
#undef __glibcpp_long_double_has_SNaN
#undef __glibcpp_long_double_has_denorm_loss
#undef __glibcpp_long_double_is_iec559
#undef __glibcpp_long_double_is_bounded

View File

@ -38,17 +38,6 @@
namespace std
{
const __float_storage __glibcpp_float_QNaN = __glibcpp_float_QNaN_bytes;
const __float_storage __glibcpp_float_SNaN = __glibcpp_float_SNaN_bytes;
const __double_storage __glibcpp_double_QNaN = __glibcpp_double_QNaN_bytes;
const __double_storage __glibcpp_double_SNaN = __glibcpp_double_SNaN_bytes;
const __long_double_storage __glibcpp_long_double_QNaN =
__glibcpp_long_double_QNaN_bytes;
const __long_double_storage __glibcpp_long_double_SNaN =
__glibcpp_long_double_SNaN_bytes;
const bool __numeric_limits_base::is_specialized;
const int __numeric_limits_base::digits;
const int __numeric_limits_base::digits10;

View File

@ -116,6 +116,83 @@ void test_sign()
}
template<typename T>
void
test_infinity()
{
bool test;
if (std::numeric_limits<T>::has_infinity)
{
T inf = std::numeric_limits<T>::infinity();
test = (inf + inf == inf);
}
else
test = true;
VERIFY (test);
}
template<typename T>
void
test_denorm_min()
{
bool test;
if (std::numeric_limits<T>::has_denorm == std::denorm_present)
{
T denorm = std::numeric_limits<T>::denorm_min();
test = (denorm > 0);
}
else
test = true;
VERIFY (test);
}
template<typename T>
void
test_qnan()
{
bool test;
if (std::numeric_limits<T>::has_quiet_NaN)
{
T nan = std::numeric_limits<T>::quiet_NaN();
test = (nan != nan);
}
else
test = true;
VERIFY (test);
}
template<typename T>
void
test_is_iec559()
{
bool test;
if (std::numeric_limits<T>::is_iec559)
{
// IEC 559 requires all of the following.
test = (std::numeric_limits<T>::has_infinity
&& std::numeric_limits<T>::has_quiet_NaN
&& std::numeric_limits<T>::has_signaling_NaN);
}
else
{
// If we had all of the following, why didn't we set IEC 559?
test = (!std::numeric_limits<T>::has_infinity
|| !std::numeric_limits<T>::has_quiet_NaN
|| !std::numeric_limits<T>::has_signaling_NaN);
}
VERIFY (test);
}
template<typename T>
struct A
{
@ -237,5 +314,25 @@ int main()
test_sign();
return 0;
test_infinity<float>();
test_infinity<double>();
test_infinity<long double>();
test_denorm_min<float>();
test_denorm_min<double>();
test_denorm_min<long double>();
test_qnan<float>();
test_qnan<double>();
test_qnan<long double>();
// ??? How to test SNaN? We'd perhaps have to be prepared
// to catch SIGFPE. Can't rely on a signal getting through
// since the exception can be disabled in the FPU.
test_is_iec559<float>();
test_is_iec559<double>();
test_is_iec559<long double>();
return 0;
}