mirror of
git://sourceware.org/git/glibc.git
synced 2026-09-10 12:05:30 +08:00
Compare commits
8
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0ded00553f | ||
|
|
6675666a82 | ||
|
|
60195247ad | ||
|
|
aee0db1113 | ||
|
|
3d9c4a4779 | ||
|
|
b2da97305c | ||
|
|
fb91e22c25 | ||
|
|
ec9052ea0c |
@@ -66,6 +66,13 @@ Version 2.26
|
||||
* The port to Native Client running on ARMv7-A (--host=arm-nacl) has been
|
||||
removed.
|
||||
|
||||
* The function strfromf128, from ISO/IEC TS 18661-3:2015, is added to libc.
|
||||
It converts a _Float128 value into string.
|
||||
|
||||
* The function strtof128, from ISO/IEC TS 18661-3:2015, is added to libc.
|
||||
It converts a string into a floating-point number of _Float128 type. Its
|
||||
wide character counterpart, wsctof128, is added as a GNU extension.
|
||||
|
||||
Security related changes:
|
||||
|
||||
* The DNS stub resolver limits the advertised UDP buffer size to 1200 bytes,
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
|
||||
#include <stdlib/gmp.h>
|
||||
|
||||
#include <bits/floatn.h>
|
||||
|
||||
/* Now define the internal interfaces. */
|
||||
extern mp_size_t __mpn_extract_double (mp_ptr res_ptr, mp_size_t size,
|
||||
int *expt, int *is_neg,
|
||||
@@ -15,6 +17,12 @@ extern mp_size_t __mpn_extract_long_double (mp_ptr res_ptr, mp_size_t size,
|
||||
int *expt, int *is_neg,
|
||||
long double value);
|
||||
|
||||
#if __HAVE_DISTINCT_FLOAT128
|
||||
extern mp_size_t __mpn_extract_float128 (mp_ptr res_ptr, mp_size_t size,
|
||||
int *expt, int *is_neg,
|
||||
_Float128 value);
|
||||
#endif
|
||||
|
||||
extern float __mpn_construct_float (mp_srcptr frac_ptr, int expt, int sign);
|
||||
|
||||
extern double __mpn_construct_double (mp_srcptr frac_ptr, int expt,
|
||||
@@ -23,5 +31,9 @@ extern double __mpn_construct_double (mp_srcptr frac_ptr, int expt,
|
||||
extern long double __mpn_construct_long_double (mp_srcptr frac_ptr, int expt,
|
||||
int sign);
|
||||
|
||||
#if __HAVE_DISTINCT_FLOAT128
|
||||
extern _Float128 __mpn_construct_float128 (mp_srcptr frac_ptr, int expt,
|
||||
int sign);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -215,6 +215,35 @@ libc_hidden_proto (__wcstof_nan)
|
||||
libc_hidden_proto (__wcstod_nan)
|
||||
libc_hidden_proto (__wcstold_nan)
|
||||
|
||||
/* Enable _FloatN bits as needed. */
|
||||
#include <bits/floatn.h>
|
||||
|
||||
#if __HAVE_DISTINCT_FLOAT128
|
||||
extern __typeof (strtof128_l) __strtof128_l;
|
||||
|
||||
libc_hidden_proto (__strtof128_l)
|
||||
libc_hidden_proto (strtof128)
|
||||
|
||||
extern _Float128 __strtof128_nan (const char *, char **, char)
|
||||
internal_function;
|
||||
extern _Float128 __wcstof128_nan (const wchar_t *, wchar_t **, wchar_t)
|
||||
internal_function;
|
||||
|
||||
libc_hidden_proto (__strtof128_nan)
|
||||
libc_hidden_proto (__wcstof128_nan)
|
||||
|
||||
extern _Float128 __strtof128_internal (const char *__restrict __nptr,
|
||||
char **__restrict __endptr,
|
||||
int __group);
|
||||
libc_hidden_proto (__strtof128_internal)
|
||||
|
||||
extern _Float128 ____strtof128_l_internal (const char *__restrict __nptr,
|
||||
char **__restrict __endptr,
|
||||
int __group, __locale_t __loc);
|
||||
|
||||
libc_hidden_proto (____strtof128_l_internal)
|
||||
#endif
|
||||
|
||||
extern char *__ecvt (double __value, int __ndigit, int *__restrict __decpt,
|
||||
int *__restrict __sign);
|
||||
extern char *__fcvt (double __value, int __ndigit, int *__restrict __decpt,
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
# ifndef _ISOMAC
|
||||
# ifdef _WCHAR_H
|
||||
|
||||
#include <bits/floatn.h>
|
||||
|
||||
extern __typeof (wcscasecmp_l) __wcscasecmp_l;
|
||||
extern __typeof (wcsncasecmp_l) __wcsncasecmp_l;
|
||||
extern __typeof (wcscoll_l) __wcscoll_l;
|
||||
@@ -70,6 +72,17 @@ libc_hidden_proto (wcstoll)
|
||||
libc_hidden_proto (wcstoul)
|
||||
libc_hidden_proto (wcstoull)
|
||||
|
||||
#if __HAVE_DISTINCT_FLOAT128
|
||||
extern __typeof (wcstof128_l) __wcstof128_l;
|
||||
libc_hidden_proto (__wcstof128_l)
|
||||
extern _Float128 __wcstof128_internal (const wchar_t *__restrict __nptr,
|
||||
wchar_t **__restrict __endptr,
|
||||
int __group) __THROW;
|
||||
|
||||
libc_hidden_proto (__wcstof128_internal)
|
||||
libc_hidden_proto (wcstof128)
|
||||
#endif
|
||||
|
||||
libc_hidden_proto (__wcscasecmp_l)
|
||||
libc_hidden_proto (__wcsncasecmp_l)
|
||||
|
||||
|
||||
+33
-6
@@ -2990,23 +2990,38 @@ double} is a separate type).
|
||||
These functions have been GNU extensions and are new to @w{ISO C99}.
|
||||
@end deftypefun
|
||||
|
||||
@comment stdlib.h
|
||||
@comment ISO/IEC TS 18661-3
|
||||
@deftypefun _Float128 strtof128 (const char *@var{string}, char **@var{tailptr})
|
||||
@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
|
||||
The @code{strtof128} function (``string-to-float128'') is like
|
||||
@code{strtod}, except that it returns a @code{_Float128} value.
|
||||
|
||||
The @code{strtof128} function was introduced in @w{ISO/IEC TS 18661-3}.
|
||||
@end deftypefun
|
||||
|
||||
@comment wchar.h
|
||||
@comment ISO
|
||||
@deftypefun double wcstod (const wchar_t *restrict @var{string}, wchar_t **restrict @var{tailptr})
|
||||
@comment stdlib.h
|
||||
@comment wchar.h
|
||||
@comment ISO
|
||||
@deftypefunx float wcstof (const wchar_t *@var{string}, wchar_t **@var{tailptr})
|
||||
@comment stdlib.h
|
||||
@comment wchar.h
|
||||
@comment ISO
|
||||
@deftypefunx {long double} wcstold (const wchar_t *@var{string}, wchar_t **@var{tailptr})
|
||||
@comment wchar.h
|
||||
@deftypefunx _Float128 wcstof128 (const wchar_t *@var{string}, wchar_t **@var{tailptr})
|
||||
@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
|
||||
The @code{wcstod}, @code{wcstof}, and @code{wcstol} functions are
|
||||
equivalent in nearly all aspect to the @code{strtod}, @code{strtof}, and
|
||||
@code{strtold} functions but it handles wide character string.
|
||||
The @code{wcstod}, @code{wcstof}, @code{wcstol}, and @code{wcstof128}
|
||||
functions are equivalent in nearly all aspect to the @code{strtod},
|
||||
@code{strtof}, @code{strtold}, and @code{strtof128} functions but they
|
||||
handle wide character string.
|
||||
|
||||
The @code{wcstod} function was introduced in @w{Amendment 1} of @w{ISO
|
||||
C90}. The @code{wcstof} and @code{wcstold} functions were introduced in
|
||||
@w{ISO C99}.
|
||||
@w{ISO C99}. The @code{wcstof128} function is not in any standard, but is
|
||||
added to provide completeness for the non-deprecated interface of wide
|
||||
character string to floating-point conversion functions.
|
||||
@end deftypefun
|
||||
|
||||
@comment stdlib.h
|
||||
@@ -3064,6 +3079,18 @@ has been completely written if and only if the returned value is less than
|
||||
These functions were introduced by ISO/IEC TS 18661-1.
|
||||
@end deftypefun
|
||||
|
||||
@comment stdlib.h
|
||||
@comment ISO/IEC TS 18661-3
|
||||
@deftypefun int strfromf128 (char *restrict @var{string}, size_t @var{size}, const char *restrict @var{format}, _Float128 @var{value})
|
||||
@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
|
||||
@comment this function depends on __printf_fp and __printf_fphex, which are
|
||||
@comment AS-unsafe (ascuheap) and AC-unsafe (acsmem).
|
||||
The @code{strfromf128} function (``string-from-float128'') is like
|
||||
@code{strfromd}, except that @var{value} has floating type _Float128.
|
||||
|
||||
The @code{strfromf128} function was introduced by ISO/IEC TS 18661-3.
|
||||
@end deftypefun
|
||||
|
||||
@node System V Number Conversion
|
||||
@section Old-fashioned System V number-to-string functions
|
||||
|
||||
|
||||
@@ -45,13 +45,15 @@ use vars qw (%auto_tests);
|
||||
|
||||
# all_floats is sorted and contains all recognised float types
|
||||
@all_floats = ('double', 'float', 'idouble',
|
||||
'ifloat', 'ildouble', 'ldouble');
|
||||
'ifloat', 'ildouble', 'ldouble',
|
||||
'ifloat128', 'float128');
|
||||
|
||||
# all_floats_pfx maps C types to their C like prefix for macros.
|
||||
%all_floats_pfx =
|
||||
( "double" => "DBL",
|
||||
"ldouble" => "LDBL",
|
||||
"float" => "FLT",
|
||||
"float128" => "FLT128",
|
||||
);
|
||||
|
||||
%beautify =
|
||||
|
||||
@@ -39,8 +39,10 @@ exp10_test (void)
|
||||
static void
|
||||
pow10_test (void)
|
||||
{
|
||||
#if !TEST_FLOATN
|
||||
/* pow10 uses the same test data as exp10. */
|
||||
ALL_RM_TEST (pow10, 0, exp10_test_data, RUN_TEST_LOOP_f_f, END);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -45,8 +45,10 @@ lgamma_test (void)
|
||||
static void
|
||||
gamma_test (void)
|
||||
{
|
||||
#if !TEST_FLOATN
|
||||
/* gamma uses the same test data as lgamma. */
|
||||
ALL_RM_TEST (gamma, 0, lgamma_test_data, RUN_TEST_LOOP_f_f1, END, signgam);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
static const struct test_fj_f_data nexttoward_test_data[] =
|
||||
{
|
||||
#if !TEST_FLOATN
|
||||
TEST_fj_f (nexttoward, 0, 0, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||
TEST_fj_f (nexttoward, minus_zero, 0, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||
TEST_fj_f (nexttoward, 0, minus_zero, minus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||
@@ -80,6 +81,7 @@ static const struct test_fj_f_data nexttoward_test_data[] =
|
||||
TEST_fj_f (nexttoward, min_subnorm_value, minus_zero, 0, INEXACT_EXCEPTION|UNDERFLOW_EXCEPTION|ERRNO_ERANGE),
|
||||
TEST_fj_f (nexttoward, -min_subnorm_value, 0, minus_zero, INEXACT_EXCEPTION|UNDERFLOW_EXCEPTION|ERRNO_ERANGE),
|
||||
TEST_fj_f (nexttoward, -min_subnorm_value, minus_zero, minus_zero, INEXACT_EXCEPTION|UNDERFLOW_EXCEPTION|ERRNO_ERANGE),
|
||||
#endif
|
||||
|
||||
#if TEST_COND_binary32
|
||||
TEST_fj_f (nexttoward, 1.0, 1.1L, 0x1.000002p0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||
@@ -153,7 +155,9 @@ static const struct test_fj_f_data nexttoward_test_data[] =
|
||||
static void
|
||||
nexttoward_test (void)
|
||||
{
|
||||
#if !TEST_FLOATN
|
||||
ALL_RM_TEST (nexttoward, 1, nexttoward_test_data, RUN_TEST_LOOP_fj_f, END);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -184,8 +184,10 @@ remainder_test (void)
|
||||
static void
|
||||
drem_test (void)
|
||||
{
|
||||
#if !TEST_FLOATN
|
||||
/* drem uses the same test data as remainder. */
|
||||
ALL_RM_TEST (drem, 1, remainder_test_data, RUN_TEST_LOOP_ff_f, END);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
static const struct test_ff_f_data scalb_test_data[] =
|
||||
{
|
||||
#if !TEST_FLOATN
|
||||
/* Results in this case are unspecified by POSIX, so, for an
|
||||
otherwise fully-determined function, spurious "inexact"
|
||||
exceptions are OK. */
|
||||
@@ -144,12 +145,15 @@ static const struct test_ff_f_data scalb_test_data[] =
|
||||
|
||||
TEST_ff_f (scalb, 0.8L, 4, 12.8L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||
TEST_ff_f (scalb, -0.854375L, 5, -27.34L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||
#endif
|
||||
};
|
||||
|
||||
static void
|
||||
scalb_test (void)
|
||||
{
|
||||
#if !TEST_FLOATN
|
||||
ALL_RM_TEST (scalb, 1, scalb_test_data, RUN_TEST_LOOP_ff_f, END);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
static const struct test_f_f_data significand_test_data[] =
|
||||
{
|
||||
#if !TEST_FLOATN
|
||||
/* significand returns the mantissa of the exponential
|
||||
representation. Tests for infinities, zero and NaNs reflect
|
||||
the implementation (including possibility of "inexact" and
|
||||
@@ -45,12 +46,15 @@ static const struct test_f_f_data significand_test_data[] =
|
||||
TEST_f_f (significand, -6.0, -1.5, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||
TEST_f_f (significand, 8.0, 1.0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||
TEST_f_f (significand, -8.0, -1.0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||
#endif
|
||||
};
|
||||
|
||||
static void
|
||||
significand_test (void)
|
||||
{
|
||||
#if !TEST_FLOATN
|
||||
ALL_RM_TEST (significand, 1, significand_test_data, RUN_TEST_LOOP_f_f, END);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -732,8 +732,8 @@ check_float (const char *test_name, FLOAT computed, FLOAT expected,
|
||||
|
||||
|
||||
void
|
||||
check_complex (const char *test_name, __complex__ FLOAT computed,
|
||||
__complex__ FLOAT expected,
|
||||
check_complex (const char *test_name, CFLOAT computed,
|
||||
CFLOAT expected,
|
||||
int exception)
|
||||
{
|
||||
FLOAT part_comp, part_exp;
|
||||
|
||||
@@ -138,12 +138,20 @@ extern const char doc[];
|
||||
#define TEST_COND_before_rounding (!TININESS_AFTER_ROUNDING)
|
||||
#define TEST_COND_after_rounding TININESS_AFTER_ROUNDING
|
||||
|
||||
#ifndef TEST_FLOATN
|
||||
# define TEST_FLOATN 0
|
||||
#endif
|
||||
|
||||
#ifndef CFLOAT
|
||||
# define CFLOAT __complex__ FLOAT
|
||||
#endif
|
||||
|
||||
int enable_test (int);
|
||||
void init_max_error (const char *, int);
|
||||
void print_max_error (const char *);
|
||||
void print_complex_max_error (const char *);
|
||||
void check_float (const char *, FLOAT, FLOAT, int);
|
||||
void check_complex (const char *, __complex__ FLOAT, __complex__ FLOAT, int);
|
||||
void check_complex (const char *, CFLOAT, CFLOAT, int);
|
||||
void check_int (const char *, int, int, int);
|
||||
void check_long (const char *, long int, long int, int);
|
||||
void check_bool (const char *, int, int, int);
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/* Common definitions for libm tests for _Float128.
|
||||
|
||||
Copyright (C) 2017 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
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define FUNC(function) function ## f128
|
||||
#define PRINTF_EXPR "e"
|
||||
#define PRINTF_XEXPR "a"
|
||||
#define PRINTF_NEXPR "f"
|
||||
#define BUILD_COMPLEX(real, imag) (CMPLXF128 ((real), (imag)))
|
||||
#define PREFIX FLT128
|
||||
#define TYPE_STR "float128"
|
||||
#define LITM(x) x ## f128
|
||||
#define FTOSTR strfromf128
|
||||
#define snan_value_MACRO SNANF128
|
||||
|
||||
/* Fixup builtins and constants for older compilers. */
|
||||
#include <features.h>
|
||||
#if !__GNUC_PREREQ (7, 0)
|
||||
# define LIT(x) (x ## Q)
|
||||
# define FLOAT __float128
|
||||
# define CFLOAT __CFLOAT128
|
||||
/* The following macros are only provided since GCC 7.0. */
|
||||
# define FLT128_MANT_DIG 113
|
||||
# define FLT128_DECIMAL_DIG 36
|
||||
# define FLT128_DIG 33
|
||||
# define FLT128_MIN_EXP (-16381)
|
||||
# define FLT128_MIN_10_EXP (-4931)
|
||||
# define FLT128_MAX_EXP 16384
|
||||
# define FLT128_MAX_10_EXP 4932
|
||||
# define FLT128_MAX 1.18973149535723176508575932662800702e+4932Q
|
||||
# define FLT128_EPSILON 1.92592994438723585305597794258492732e-34Q
|
||||
# define FLT128_MIN 3.36210314311209350626267781732175260e-4932Q
|
||||
# define FLT128_TRUE_MIN 6.47517511943802511092443895822764655e-4966Q
|
||||
#else
|
||||
# define LIT(x) (x ## f128)
|
||||
# define FLOAT _Float128
|
||||
#endif
|
||||
|
||||
#include "test-math-floatn.h"
|
||||
|
||||
/* Similarly, finitef128 is not API */
|
||||
extern int __finitef128 (FLOAT);
|
||||
|
||||
static inline int
|
||||
finitef128(FLOAT f)
|
||||
{
|
||||
return __finitef128 (f);
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/* Common definitions for libm tests for TS 18661-3 derived types.
|
||||
Copyright (C) 2017 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
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_FLOATN 1
|
||||
#define __STDC_WANT_IEC_60559_BFP_EXT__
|
||||
#define __STDC_WANT_IEC_60559_TYPES_EXT__
|
||||
+6
-2
@@ -99,8 +99,12 @@
|
||||
#define powerof2(x) ((((x) - 1) & (x)) == 0)
|
||||
|
||||
/* Macros for min/max. */
|
||||
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||
#define MAX(a,b) (((a)>(b))?(a):(b))
|
||||
#ifndef MIN
|
||||
# define MIN(a,b) (((a)<(b))?(a):(b))
|
||||
#endif
|
||||
#ifndef MAX
|
||||
# define MAX(a,b) (((a)>(b))?(a):(b))
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* sys/param.h */
|
||||
|
||||
@@ -79,6 +79,7 @@ __parse_one_specmb (const UCHAR_T *format, size_t posn,
|
||||
spec->info.extra = 0;
|
||||
spec->info.pad = ' ';
|
||||
spec->info.wide = sizeof (UCHAR_T) > 1;
|
||||
spec->info.is_binary128 = 0;
|
||||
|
||||
/* Test for positional argument. */
|
||||
if (ISDIGIT (*format))
|
||||
|
||||
@@ -47,7 +47,9 @@ struct printf_info
|
||||
unsigned int is_char:1; /* hh flag. */
|
||||
unsigned int wide:1; /* Nonzero for wide character streams. */
|
||||
unsigned int i18n:1; /* I flag. */
|
||||
unsigned int __pad:4; /* Unused so far. */
|
||||
unsigned int is_binary128:1; /* Floating-point argument is ABI-compatible
|
||||
with IEC 60559 binary128. */
|
||||
unsigned int __pad:3; /* Unused so far. */
|
||||
unsigned short int user; /* Bits for user-installed modifiers. */
|
||||
wchar_t pad; /* Padding character. */
|
||||
};
|
||||
|
||||
@@ -218,6 +218,9 @@ __printf_fp_l (FILE *fp, locale_t loc,
|
||||
{
|
||||
double dbl;
|
||||
__long_double_t ldbl;
|
||||
#if __HAVE_DISTINCT_FLOAT128
|
||||
_Float128 f128;
|
||||
#endif
|
||||
}
|
||||
fpnum;
|
||||
|
||||
@@ -234,9 +237,17 @@ __printf_fp_l (FILE *fp, locale_t loc,
|
||||
const char *special = NULL;
|
||||
const wchar_t *wspecial = NULL;
|
||||
|
||||
/* When _Float128 is enabled in the library and ABI-distinct from long
|
||||
double, we need mp_limbs enough for any of them. */
|
||||
#if __HAVE_DISTINCT_FLOAT128
|
||||
# define GREATER_MANT_DIG FLT128_MANT_DIG
|
||||
#else
|
||||
# define GREATER_MANT_DIG LDBL_MANT_DIG
|
||||
#endif
|
||||
/* We need just a few limbs for the input before shifting to the right
|
||||
position. */
|
||||
mp_limb_t fp_input[(LDBL_MANT_DIG + BITS_PER_MP_LIMB - 1) / BITS_PER_MP_LIMB];
|
||||
mp_limb_t fp_input[(GREATER_MANT_DIG + BITS_PER_MP_LIMB - 1)
|
||||
/ BITS_PER_MP_LIMB];
|
||||
/* We need to shift the contents of fp_input by this amount of bits. */
|
||||
int to_shift = 0;
|
||||
|
||||
@@ -328,6 +339,52 @@ __printf_fp_l (FILE *fp, locale_t loc,
|
||||
grouping = NULL;
|
||||
|
||||
/* Fetch the argument value. */
|
||||
#if __HAVE_DISTINCT_FLOAT128
|
||||
if (info->is_binary128)
|
||||
{
|
||||
fpnum.f128 = *(const _Float128 *) args[0];
|
||||
|
||||
/* Check for special values: not a number or infinity. */
|
||||
if (isnan (fpnum.f128))
|
||||
{
|
||||
is_neg = signbit (fpnum.f128);
|
||||
if (isupper (info->spec))
|
||||
{
|
||||
special = "NAN";
|
||||
wspecial = L"NAN";
|
||||
}
|
||||
else
|
||||
{
|
||||
special = "nan";
|
||||
wspecial = L"nan";
|
||||
}
|
||||
}
|
||||
else if (isinf (fpnum.f128))
|
||||
{
|
||||
is_neg = signbit (fpnum.f128);
|
||||
if (isupper (info->spec))
|
||||
{
|
||||
special = "INF";
|
||||
wspecial = L"INF";
|
||||
}
|
||||
else
|
||||
{
|
||||
special = "inf";
|
||||
wspecial = L"inf";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
p.fracsize = __mpn_extract_float128 (fp_input,
|
||||
(sizeof (fp_input) /
|
||||
sizeof (fp_input[0])),
|
||||
&p.exponent, &is_neg,
|
||||
fpnum.f128);
|
||||
to_shift = 1 + p.fracsize * BITS_PER_MP_LIMB - FLT128_MANT_DIG;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif /* __HAVE_DISTINCT_FLOAT128 */
|
||||
#ifndef __NO_LONG_DOUBLE_MATH
|
||||
if (info->is_long_double && sizeof (long double) > sizeof (double))
|
||||
{
|
||||
@@ -450,7 +507,8 @@ __printf_fp_l (FILE *fp, locale_t loc,
|
||||
{
|
||||
mp_size_t bignum_size = ((abs (p.exponent) + BITS_PER_MP_LIMB - 1)
|
||||
/ BITS_PER_MP_LIMB
|
||||
+ (LDBL_MANT_DIG / BITS_PER_MP_LIMB > 2 ? 8 : 4))
|
||||
+ (GREATER_MANT_DIG / BITS_PER_MP_LIMB > 2
|
||||
? 8 : 4))
|
||||
* sizeof (mp_limb_t);
|
||||
p.frac = (mp_limb_t *) alloca (bignum_size);
|
||||
p.tmp = (mp_limb_t *) alloca (bignum_size);
|
||||
@@ -465,7 +523,15 @@ __printf_fp_l (FILE *fp, locale_t loc,
|
||||
{
|
||||
/* |FP| >= 8.0. */
|
||||
int scaleexpo = 0;
|
||||
int explog = LDBL_MAX_10_EXP_LOG;
|
||||
int explog;
|
||||
#if __HAVE_DISTINCT_FLOAT128
|
||||
if (info->is_binary128)
|
||||
explog = FLT_MAX_10_EXP_LOG;
|
||||
else
|
||||
explog = LDBL_MAX_10_EXP_LOG;
|
||||
#else
|
||||
explog = LDBL_MAX_10_EXP_LOG;
|
||||
#endif
|
||||
int exp10 = 0;
|
||||
const struct mp_power *powers = &_fpioconst_pow10[explog + 1];
|
||||
int cnt_h, cnt_l, i;
|
||||
@@ -499,6 +565,27 @@ __printf_fp_l (FILE *fp, locale_t loc,
|
||||
{
|
||||
if (p.scalesize == 0)
|
||||
{
|
||||
#if __HAVE_DISTINCT_FLOAT128
|
||||
if ((FLT128_MANT_DIG
|
||||
> _FPIO_CONST_OFFSET * BITS_PER_MP_LIMB)
|
||||
&& info->is_binary128)
|
||||
{
|
||||
#define _FLT128_FPIO_CONST_SHIFT \
|
||||
(((FLT128_MANT_DIG + BITS_PER_MP_LIMB - 1) / BITS_PER_MP_LIMB) \
|
||||
- _FPIO_CONST_OFFSET)
|
||||
/* 64bit const offset is not enough for
|
||||
IEEE 854 quad long double (_Float128). */
|
||||
p.tmpsize = powers->arraysize + _FLT128_FPIO_CONST_SHIFT;
|
||||
memcpy (p.tmp + _FLT128_FPIO_CONST_SHIFT,
|
||||
&__tens[powers->arrayoff],
|
||||
p.tmpsize * sizeof (mp_limb_t));
|
||||
MPN_ZERO (p.tmp, _FLT128_FPIO_CONST_SHIFT);
|
||||
/* Adjust p.exponent, as scaleexpo will be this much
|
||||
bigger too. */
|
||||
p.exponent += _FLT128_FPIO_CONST_SHIFT * BITS_PER_MP_LIMB;
|
||||
}
|
||||
else
|
||||
#endif /* __HAVE_DISTINCT_FLOAT128 */
|
||||
#ifndef __NO_LONG_DOUBLE_MATH
|
||||
if (LDBL_MANT_DIG > _FPIO_CONST_OFFSET * BITS_PER_MP_LIMB
|
||||
&& info->is_long_double)
|
||||
@@ -639,7 +726,15 @@ __printf_fp_l (FILE *fp, locale_t loc,
|
||||
{
|
||||
/* |FP| < 1.0. */
|
||||
int exp10 = 0;
|
||||
int explog = LDBL_MAX_10_EXP_LOG;
|
||||
int explog;
|
||||
#if __HAVE_DISTINCT_FLOAT128
|
||||
if (info->is_binary128)
|
||||
explog = FLT_MAX_10_EXP_LOG;
|
||||
else
|
||||
explog = LDBL_MAX_10_EXP_LOG;
|
||||
#else
|
||||
explog = LDBL_MAX_10_EXP_LOG;
|
||||
#endif
|
||||
const struct mp_power *powers = &_fpioconst_pow10[explog + 1];
|
||||
|
||||
/* Now shift the input value to its right place. */
|
||||
|
||||
@@ -31,6 +31,10 @@
|
||||
#include <stdbool.h>
|
||||
#include <rounding-mode.h>
|
||||
|
||||
#if __HAVE_DISTINCT_FLOAT128
|
||||
# include "ieee754_float128.h"
|
||||
#endif
|
||||
|
||||
/* #define NDEBUG 1*/ /* Undefine this for debugging assertions. */
|
||||
#include <assert.h>
|
||||
|
||||
@@ -94,6 +98,9 @@ __printf_fphex (FILE *fp,
|
||||
{
|
||||
union ieee754_double dbl;
|
||||
long double ldbl;
|
||||
#if __HAVE_DISTINCT_FLOAT128
|
||||
_Float128 flt128;
|
||||
#endif
|
||||
}
|
||||
fpnum;
|
||||
|
||||
@@ -159,6 +166,45 @@ __printf_fphex (FILE *fp,
|
||||
|
||||
|
||||
/* Fetch the argument value. */
|
||||
#if __HAVE_DISTINCT_FLOAT128
|
||||
if (info->is_binary128)
|
||||
{
|
||||
fpnum.flt128 = *(const _Float128 *) args[0];
|
||||
|
||||
/* Check for special values: not a number or infinity. */
|
||||
if (isnan (fpnum.flt128))
|
||||
{
|
||||
if (isupper (info->spec))
|
||||
{
|
||||
special = "NAN";
|
||||
wspecial = L"NAN";
|
||||
}
|
||||
else
|
||||
{
|
||||
special = "nan";
|
||||
wspecial = L"nan";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isinf (fpnum.flt128))
|
||||
{
|
||||
if (isupper (info->spec))
|
||||
{
|
||||
special = "INF";
|
||||
wspecial = L"INF";
|
||||
}
|
||||
else
|
||||
{
|
||||
special = "inf";
|
||||
wspecial = L"inf";
|
||||
}
|
||||
}
|
||||
}
|
||||
negative = signbit (fpnum.flt128);
|
||||
}
|
||||
else
|
||||
#endif /* __HAVE_DISTINCT_FLOAT128 */
|
||||
#ifndef __NO_LONG_DOUBLE_MATH
|
||||
if (info->is_long_double && sizeof (long double) > sizeof (double))
|
||||
{
|
||||
@@ -260,6 +306,94 @@ __printf_fphex (FILE *fp,
|
||||
return done;
|
||||
}
|
||||
|
||||
#if __HAVE_DISTINCT_FLOAT128
|
||||
/* This block is copied from sysdeps/ieee754/ldbl-128/printf_fphex.c. */
|
||||
if (info->is_binary128)
|
||||
{
|
||||
/* We have 112 bits of mantissa plus one implicit digit. Since
|
||||
112 bits are representable without rest using hexadecimal
|
||||
digits we use only the implicit digits for the number before
|
||||
the decimal point. */
|
||||
unsigned long long int num0, num1;
|
||||
union ieee854_float128 u;
|
||||
u.d = fpnum.flt128;
|
||||
|
||||
num0 = (((unsigned long long int) u.ieee.mantissa0) << 32
|
||||
| u.ieee.mantissa1);
|
||||
num1 = (((unsigned long long int) u.ieee.mantissa2) << 32
|
||||
| u.ieee.mantissa3);
|
||||
|
||||
zero_mantissa = (num0|num1) == 0;
|
||||
|
||||
if (sizeof (unsigned long int) > 6)
|
||||
{
|
||||
numstr = _itoa_word (num1, numbuf + sizeof numbuf, 16,
|
||||
info->spec == 'A');
|
||||
wnumstr = _itowa_word (num1,
|
||||
wnumbuf + sizeof (wnumbuf) / sizeof (wchar_t),
|
||||
16, info->spec == 'A');
|
||||
}
|
||||
else
|
||||
{
|
||||
numstr = _itoa (num1, numbuf + sizeof numbuf, 16,
|
||||
info->spec == 'A');
|
||||
wnumstr = _itowa (num1,
|
||||
wnumbuf + sizeof (wnumbuf) / sizeof (wchar_t),
|
||||
16, info->spec == 'A');
|
||||
}
|
||||
|
||||
while (numstr > numbuf + (sizeof numbuf - 64 / 4))
|
||||
{
|
||||
*--numstr = '0';
|
||||
*--wnumstr = L'0';
|
||||
}
|
||||
|
||||
if (sizeof (unsigned long int) > 6)
|
||||
{
|
||||
numstr = _itoa_word (num0, numstr, 16, info->spec == 'A');
|
||||
wnumstr = _itowa_word (num0, wnumstr, 16, info->spec == 'A');
|
||||
}
|
||||
else
|
||||
{
|
||||
numstr = _itoa (num0, numstr, 16, info->spec == 'A');
|
||||
wnumstr = _itowa (num0, wnumstr, 16, info->spec == 'A');
|
||||
}
|
||||
|
||||
/* Fill with zeroes. */
|
||||
while (numstr > numbuf + (sizeof numbuf - 112 / 4))
|
||||
{
|
||||
*--numstr = '0';
|
||||
*--wnumstr = L'0';
|
||||
}
|
||||
|
||||
leading = u.ieee.exponent == 0 ? '0' : '1';
|
||||
|
||||
exponent = u.ieee.exponent;
|
||||
|
||||
if (exponent == 0)
|
||||
{
|
||||
if (zero_mantissa)
|
||||
expnegative = 0;
|
||||
else
|
||||
{
|
||||
/* This is a denormalized number. */
|
||||
expnegative = 1;
|
||||
exponent = IEEE854_FLOAT128_BIAS - 1;
|
||||
}
|
||||
}
|
||||
else if (exponent >= IEEE854_FLOAT128_BIAS)
|
||||
{
|
||||
expnegative = 0;
|
||||
exponent -= IEEE854_FLOAT128_BIAS;
|
||||
}
|
||||
else
|
||||
{
|
||||
expnegative = 1;
|
||||
exponent = -(exponent - IEEE854_FLOAT128_BIAS);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif /* __HAVE_DISTINCT_FLOAT128 */
|
||||
if (info->is_long_double == 0 || sizeof (double) == sizeof (long double))
|
||||
{
|
||||
/* We have 52 bits of mantissa plus one implicit digit. Since
|
||||
|
||||
@@ -104,6 +104,9 @@ __printf_size (FILE *fp, const struct printf_info *info,
|
||||
{
|
||||
union ieee754_double dbl;
|
||||
long double ldbl;
|
||||
#if __HAVE_DISTINCT_FLOAT128
|
||||
_Float128 f128;
|
||||
#endif
|
||||
}
|
||||
fpnum;
|
||||
const void *ptr = &fpnum;
|
||||
@@ -119,6 +122,32 @@ __printf_size (FILE *fp, const struct printf_info *info,
|
||||
int wide = info->wide;
|
||||
|
||||
/* Fetch the argument value. */
|
||||
#if __HAVE_DISTINCT_FLOAT128
|
||||
if (info->is_binary128)
|
||||
{
|
||||
fpnum.f128 = *(const _Float128 *) args[0];
|
||||
|
||||
/* Check for special values: not a number or infinity. */
|
||||
if (isnan (fpnum.f128))
|
||||
{
|
||||
special = "nan";
|
||||
wspecial = L"nan";
|
||||
}
|
||||
else if (isinf (fpnum.f128))
|
||||
{
|
||||
is_neg = signbit (fpnum.f128);
|
||||
special = "inf";
|
||||
wspecial = L"inf";
|
||||
}
|
||||
else
|
||||
while (fpnum.f128 >= divisor && tag[1] != '\0')
|
||||
{
|
||||
fpnum.f128 /= divisor;
|
||||
++tag;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif /* __HAVE_DISTINCT_FLOAT128 */
|
||||
#ifndef __NO_LONG_DOUBLE_MATH
|
||||
if (info->is_long_double && sizeof (long double) > sizeof (double))
|
||||
{
|
||||
|
||||
@@ -770,7 +770,8 @@ static const uint8_t jump_table[] =
|
||||
.pad = pad, \
|
||||
.extra = 0, \
|
||||
.i18n = use_outdigits, \
|
||||
.wide = sizeof (CHAR_T) != 1 }; \
|
||||
.wide = sizeof (CHAR_T) != 1, \
|
||||
.is_binary128 = 0}; \
|
||||
\
|
||||
if (is_long_double) \
|
||||
the_arg.pa_long_double = va_arg (ap, long double); \
|
||||
@@ -788,6 +789,8 @@ static const uint8_t jump_table[] =
|
||||
fspec->data_arg_type = PA_DOUBLE; \
|
||||
fspec->info.is_long_double = 0; \
|
||||
} \
|
||||
/* Not supported by *printf functions. */ \
|
||||
fspec->info.is_binary128 = 0; \
|
||||
\
|
||||
function_done = __printf_fp (s, &fspec->info, &ptr); \
|
||||
} \
|
||||
@@ -827,7 +830,8 @@ static const uint8_t jump_table[] =
|
||||
.group = group, \
|
||||
.pad = pad, \
|
||||
.extra = 0, \
|
||||
.wide = sizeof (CHAR_T) != 1 }; \
|
||||
.wide = sizeof (CHAR_T) != 1, \
|
||||
.is_binary128 = 0}; \
|
||||
\
|
||||
if (is_long_double) \
|
||||
the_arg.pa_long_double = va_arg (ap, long double); \
|
||||
@@ -842,6 +846,8 @@ static const uint8_t jump_table[] =
|
||||
ptr = (const void *) &args_value[fspec->data_arg]; \
|
||||
if (__ldbl_is_dbl) \
|
||||
fspec->info.is_long_double = 0; \
|
||||
/* Not supported by *printf functions. */ \
|
||||
fspec->info.is_binary128 = 0; \
|
||||
\
|
||||
function_done = __printf_fphex (s, &fspec->info, &ptr); \
|
||||
} \
|
||||
|
||||
@@ -198,6 +198,7 @@ $(objpfx)tst-putenvmod.so: $(objpfx)tst-putenvmod.os $(link-libc-deps)
|
||||
libof-tst-putenvmod = extramodules
|
||||
|
||||
$(objpfx)bug-getcontext: $(libm)
|
||||
$(objpfx)bug-strtod2: $(libm)
|
||||
$(objpfx)tst-strtod-round: $(libm)
|
||||
$(objpfx)tst-tininess: $(libm)
|
||||
$(objpfx)tst-strtod-underflow: $(libm)
|
||||
|
||||
+7
-4
@@ -27,6 +27,9 @@
|
||||
with gen-fpioconst.c.
|
||||
*/
|
||||
|
||||
#define HAVE_EXTENDED_RANGE ((!defined __NO_LONG_DOUBLE_MATH \
|
||||
&& __LDBL_MAX_EXP__ > 1024) || __HAVE_DISTINCT_FLOAT128)
|
||||
|
||||
#if BITS_PER_MP_LIMB == 32
|
||||
|
||||
/* Table with constants of 10^(2^i), i=0..12 for 32-bit limbs. */
|
||||
@@ -112,7 +115,7 @@ const mp_limb_t __tens[] =
|
||||
0xd2db49ef, 0x926c3f5b, 0xae6209d4, 0x2d433949, 0x34f4a3c6, 0xd4305d94,
|
||||
0xd9d61a05, 0x00000325,
|
||||
|
||||
#if !defined __NO_LONG_DOUBLE_MATH && __LDBL_MAX_EXP__ > 1024
|
||||
#if HAVE_EXTENDED_RANGE
|
||||
# define TENS_P11_IDX (TENS_P10_IDX + TENS_P10_SIZE)
|
||||
# define TENS_P11_SIZE 215
|
||||
[TENS_P11_IDX] = 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
@@ -659,7 +662,7 @@ const mp_limb_t __tens[] =
|
||||
0x6d6c0267, 0x06f9c25b, 0xbd6078e0, 0xb5fcdc81, 0xd742fa41, 0xcccc2399,
|
||||
0xc691adc0, 0x215ad82c, 0xea73b0c3, 0xa511e5b0, 0xf499e0a6, 0x53e27ab0,
|
||||
0xd94440a2, 0x47752521, 0x9a6e3644, 0xab113708, 0x8f8b301d, 0x058a42a3,
|
||||
#endif /* !__NO_LONG_DOUBLE_MATH */
|
||||
#endif /* HAVE_EXTENDED_RANGE */
|
||||
};
|
||||
|
||||
#elif BITS_PER_MP_LIMB == 64
|
||||
@@ -748,7 +751,7 @@ const mp_limb_t __tens[] =
|
||||
0xd2db49ef47187094ull, 0xae6209d4926c3f5bull, 0x34f4a3c62d433949ull,
|
||||
0xd9d61a05d4305d94ull, 0x0000000000000325ull,
|
||||
|
||||
#if !defined __NO_LONG_DOUBLE_MATH && __LDBL_MAX_EXP__ > 1024
|
||||
#if HAVE_EXTENDED_RANGE
|
||||
# define TENS_P11_IDX (TENS_P10_IDX + TENS_P10_SIZE)
|
||||
# define TENS_P11_SIZE 108
|
||||
[TENS_P11_IDX] = 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
@@ -1320,7 +1323,7 @@ const struct mp_power _fpioconst_pow10[FPIOCONST_POW10_ARRAY_SIZE] =
|
||||
{ TENS_P8_IDX, TENS_P8_SIZE, 851, 848 },
|
||||
{ TENS_P9_IDX, TENS_P9_SIZE, 1701, 1698 },
|
||||
{ TENS_P10_IDX, TENS_P10_SIZE, 3402, 3399 },
|
||||
#if !defined __NO_LONG_DOUBLE_MATH && __LDBL_MAX_EXP__ > 1024
|
||||
#if HAVE_EXTENDED_RANGE
|
||||
{ TENS_P11_IDX, TENS_P11_SIZE, 6804, 6800 },
|
||||
{ TENS_P12_IDX, TENS_P12_SIZE, 13607, 13604 },
|
||||
{ TENS_P13_IDX, TENS_P13_SIZE, 27214, 27210 },
|
||||
|
||||
+13
-2
@@ -40,9 +40,20 @@
|
||||
#define DBL_MAX_10_EXP_LOG 8 /* = floor(log_2(DBL_MAX_10_EXP)) */
|
||||
#define FLT_MAX_10_EXP_LOG 5 /* = floor(log_2(FLT_MAX_10_EXP)) */
|
||||
|
||||
/* On some machines, _Float128 may be ABI-distinct from long double (e.g
|
||||
IBM extended precision). */
|
||||
#include <bits/floatn.h>
|
||||
|
||||
#if __HAVE_DISTINCT_FLOAT128
|
||||
# define FLT128_MAX_10_EXP_LOG 12 /* = floor(log_2(FLT128_MAX_10_EXP)) */
|
||||
#endif
|
||||
|
||||
/* For strtold, we need powers of 10 up to floor (log_2 (LDBL_MANT_DIG
|
||||
- LDBL_MIN_EXP + 2)). */
|
||||
#if !defined __NO_LONG_DOUBLE_MATH && __LDBL_MAX_EXP__ > 1024
|
||||
- LDBL_MIN_EXP + 2)). When _Float128 is enabled in libm and it is
|
||||
ABI-distinct from long double (e.g. on powerpc64le), we also need powers
|
||||
of 10 up to floor (log_2 (FLT128_MANT_DIG - FLT128_MIN_EXP + 2)). */
|
||||
#if (!defined __NO_LONG_DOUBLE_MATH && __LDBL_MAX_EXP__ > 1024) \
|
||||
|| __HAVE_DISTINCT_FLOAT128
|
||||
# define FPIOCONST_POW10_ARRAY_SIZE 15
|
||||
#else
|
||||
# define FPIOCONST_POW10_ARRAY_SIZE 11
|
||||
|
||||
@@ -51,6 +51,9 @@ __BEGIN_DECLS
|
||||
# endif
|
||||
#endif /* X/Open or XPG7 and <sys/wait.h> not included. */
|
||||
|
||||
/* _FloatN API tests for enablement. */
|
||||
#include <bits/floatn.h>
|
||||
|
||||
/* Returned by `div'. */
|
||||
typedef struct
|
||||
{
|
||||
@@ -125,6 +128,13 @@ extern long double strtold (const char *__restrict __nptr,
|
||||
__THROW __nonnull ((1));
|
||||
#endif
|
||||
|
||||
#if __HAVE_FLOAT128 && __GLIBC_USE (IEC_60559_TYPES_EXT)
|
||||
/* Likewise for the '_Float128' format */
|
||||
extern _Float128 strtof128 (const char *__restrict __nptr,
|
||||
char **__restrict __endptr)
|
||||
__THROW __nonnull ((1));
|
||||
#endif
|
||||
|
||||
/* Convert a string to a long integer. */
|
||||
extern long int strtol (const char *__restrict __nptr,
|
||||
char **__restrict __endptr, int __base)
|
||||
@@ -173,6 +183,11 @@ extern int strfromf (char *__dest, size_t __size, const char *__format,
|
||||
extern int strfroml (char *__dest, size_t __size, const char *__format,
|
||||
long double __f)
|
||||
__THROW __nonnull ((3));
|
||||
# if __HAVE_FLOAT128 && __GLIBC_USE (IEC_60559_TYPES_EXT)
|
||||
extern int strfromf128 (char *__dest, size_t __size, const char * __format,
|
||||
_Float128 __f)
|
||||
__THROW __nonnull ((3));
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
@@ -227,6 +242,14 @@ extern long double strtold_l (const char *__restrict __nptr,
|
||||
char **__restrict __endptr,
|
||||
__locale_t __loc)
|
||||
__THROW __nonnull ((1, 3));
|
||||
|
||||
# if __HAVE_FLOAT128 && __GLIBC_USE (IEC_60559_TYPES_EXT)
|
||||
extern _Float128 strtof128_l (const char *__restrict __nptr,
|
||||
char **__restrict __endptr,
|
||||
__locale_t __loc)
|
||||
__THROW __nonnull ((1, 3));
|
||||
# endif
|
||||
|
||||
#endif /* GNU */
|
||||
|
||||
|
||||
|
||||
@@ -132,6 +132,12 @@ STRFROM (char *dest, size_t size, const char *format, FLOAT f)
|
||||
which type of floating-point number is being passed. */
|
||||
info.is_long_double = __builtin_types_compatible_p (FLOAT, long double);
|
||||
|
||||
/* Similarly, the function strfromf128 passes a floating-point number in
|
||||
_Float128 format to printf_fp. */
|
||||
#if __HAVE_DISTINCT_FLOAT128
|
||||
info.is_binary128 = __builtin_types_compatible_p (FLOAT, _Float128);
|
||||
#endif
|
||||
|
||||
/* Set info according to the format string. */
|
||||
info.prec = precision;
|
||||
info.spec = specifier;
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#include <stdlib/tst-strtod.h>
|
||||
|
||||
#define STR_(X) #X
|
||||
#define STR(X) STR_(X)
|
||||
#define FNPFXS STR (FNPFX)
|
||||
@@ -30,20 +32,22 @@
|
||||
#define CONCAT(X, Y) CONCAT_ (X, Y)
|
||||
#define FNX(FN) CONCAT (FNPFX, FN)
|
||||
|
||||
#define TEST(LOC, STR, FN, TYPE) \
|
||||
do \
|
||||
#define TEST_STRTOD(FSUF, FTYPE, FTOSTR, LSUF, CSUF) \
|
||||
static int \
|
||||
test_strto ## FSUF (const char * loc, CHAR * s) \
|
||||
{ \
|
||||
CHAR *ep; \
|
||||
FTYPE val = FNX (FSUF) (s, &ep); \
|
||||
if (isnan (val) && *ep == 0) \
|
||||
printf ("PASS: %s: " FNPFXS #FSUF " (" SFMT ")\n", loc, s); \
|
||||
else \
|
||||
{ \
|
||||
CHAR *ep; \
|
||||
TYPE val = FNX (FN) (STR, &ep); \
|
||||
if (isnan (val) && *ep == 0) \
|
||||
printf ("PASS: %s: " FNPFXS #FN " (" SFMT ")\n", LOC, STR); \
|
||||
else \
|
||||
{ \
|
||||
printf ("FAIL: %s: " FNPFXS #FN " (" SFMT ")\n", LOC, STR); \
|
||||
result = 1; \
|
||||
} \
|
||||
printf ("FAIL: %s: " FNPFXS #FSUF " (" SFMT ")\n", loc, s); \
|
||||
return 1; \
|
||||
} \
|
||||
while (0)
|
||||
return 0; \
|
||||
}
|
||||
GEN_TEST_STRTOD_FOREACH (TEST_STRTOD)
|
||||
|
||||
static int
|
||||
test_one_locale (const char *loc)
|
||||
@@ -64,13 +68,9 @@ test_one_locale (const char *loc)
|
||||
s[4] = L_('A') + i - 10;
|
||||
s[5] = L_(')');
|
||||
s[6] = 0;
|
||||
TEST (loc, s, f, float);
|
||||
TEST (loc, s, d, double);
|
||||
TEST (loc, s, ld, long double);
|
||||
result |= STRTOD_TEST_FOREACH (test_strto, loc, s);
|
||||
s[4] = L_('a') + i - 10;
|
||||
TEST (loc, s, f, float);
|
||||
TEST (loc, s, d, double);
|
||||
TEST (loc, s, ld, long double);
|
||||
result |= STRTOD_TEST_FOREACH (test_strto, loc, s);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -93,6 +93,7 @@
|
||||
/* Add type specific choosing macros below. */
|
||||
#define CHOOSE_f(f,...) f
|
||||
#define CHOOSE_d(f,d,...) d
|
||||
#define CHOOSE_f128(f,d,ld64i,ld64m,ld106,ld113,...) ld113
|
||||
/* long double is special, and handled above. */
|
||||
|
||||
/* Selector for expected result field of a given type. */
|
||||
|
||||
+34
-8
@@ -21,11 +21,36 @@
|
||||
|
||||
#define FSTRLENMAX 128
|
||||
|
||||
#include <bits/floatn.h>
|
||||
|
||||
#if !__GNUC_PREREQ(7,0)
|
||||
# define F128 Q
|
||||
#endif
|
||||
|
||||
/* Test strfromf128 and strtof128 on all platforms that provide them,
|
||||
whether or not the type _FLoat128 is ABI-distinct from long double. */
|
||||
#if __HAVE_FLOAT128
|
||||
# define _GEN_f128(mfunc, ...) mfunc (__VA_ARGS__)
|
||||
# define _DO_f128(mfunc,...) (mfunc ## f128) (__VA_ARGS__)
|
||||
# ifndef CHAR
|
||||
# define CHAR char
|
||||
# endif
|
||||
#else
|
||||
# define _GEN_f128(...)
|
||||
# define _DO_f128(...) 0
|
||||
#endif
|
||||
|
||||
#define _GEN(mfunc, type, ...) _GENx(_GEN_ ## type, mfunc, type, __VA_ARGS__)
|
||||
#define _GENx(mmfunc, mfunc, type, ...) mmfunc (mfunc, type, __VA_ARGS__)
|
||||
#define _DO(mfunc, type, ...) _DOx(_DO_ ## type, mfunc, ##__VA_ARGS__)
|
||||
#define _DOx(mmfunc, mfunc, ...) mmfunc (mfunc, ##__VA_ARGS__)
|
||||
|
||||
/* Splat n variants of the same test for the various strtod functions. */
|
||||
#define GEN_TEST_STRTOD_FOREACH(mfunc, ...) \
|
||||
mfunc ( f, float, strfromf, f, f, ##__VA_ARGS__) \
|
||||
mfunc ( d, double, strfromd, , , ##__VA_ARGS__) \
|
||||
mfunc ( ld, long double, strfroml, L, l, ##__VA_ARGS__)
|
||||
mfunc ( ld, long double, strfroml, L, l, ##__VA_ARGS__) \
|
||||
_GEN ( mfunc, f128, _Float128, strfromf128, F128, f128, ##__VA_ARGS__)
|
||||
/* The arguments to the generated macros are:
|
||||
FSUF - Function suffix
|
||||
FTYPE - float type
|
||||
@@ -36,13 +61,14 @@
|
||||
|
||||
|
||||
|
||||
#define STRTOD_TEST_FOREACH(mfunc, ...) \
|
||||
({ \
|
||||
int result = 0; \
|
||||
result |= mfunc ## f (__VA_ARGS__); \
|
||||
result |= mfunc ## d (__VA_ARGS__); \
|
||||
result |= mfunc ## ld (__VA_ARGS__); \
|
||||
result; \
|
||||
#define STRTOD_TEST_FOREACH(mfunc, ...) \
|
||||
({ \
|
||||
int result = 0; \
|
||||
result |= mfunc ## f (__VA_ARGS__); \
|
||||
result |= mfunc ## d (__VA_ARGS__); \
|
||||
result |= mfunc ## ld (__VA_ARGS__); \
|
||||
result |= _DO (mfunc, f128, ##__VA_ARGS__); \
|
||||
result; \
|
||||
})
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
ifeq ($(subdir),stdlib)
|
||||
routines += float1282mpn strfromf128
|
||||
routines += strtof128 strtof128_l strtof128_nan mpn2float128
|
||||
endif
|
||||
|
||||
ifeq ($(subdir),wcsmbs)
|
||||
routines += wcstof128_l wcstof128 wcstof128_nan
|
||||
endif
|
||||
@@ -2,6 +2,21 @@
|
||||
%ifndef FLOAT128_VERSION
|
||||
% error "float128-abi.h must define FLOAT128_VERSION"
|
||||
%endif
|
||||
libc {
|
||||
FLOAT128_VERSION {
|
||||
__strtof128_internal;
|
||||
__wcstof128_internal;
|
||||
strfromf128;
|
||||
strtof128;
|
||||
strtof128_l;
|
||||
wcstof128;
|
||||
wcstof128_l;
|
||||
}
|
||||
GLIBC_PRIVATE {
|
||||
# For __nanf128.
|
||||
__strtof128_nan;
|
||||
}
|
||||
}
|
||||
libm {
|
||||
FLOAT128_VERSION {
|
||||
__acosf128_finite;
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/* Copyright (C) 2017 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
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define __FLOAT128_OVERRIDE
|
||||
|
||||
#include "../ldbl-128/ldbl2mpn.c"
|
||||
@@ -0,0 +1,53 @@
|
||||
/* Copyright (C) 2017 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
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "gmp.h"
|
||||
#include "gmp-impl.h"
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "ieee754_float128.h"
|
||||
|
||||
/* Convert a multi-precision integer of the needed number of bits (113 for
|
||||
binary128) and an integral power of two to a `__float128' in IEEE854
|
||||
quad-precision format. */
|
||||
|
||||
_Float128
|
||||
__mpn_construct_float128 (mp_srcptr frac_ptr, int expt, int sign)
|
||||
{
|
||||
union ieee854_float128 u;
|
||||
|
||||
u.ieee.negative = sign;
|
||||
u.ieee.exponent = expt + IEEE854_FLOAT128_BIAS;
|
||||
#if BITS_PER_MP_LIMB == 32
|
||||
u.ieee.mantissa3 = frac_ptr[0];
|
||||
u.ieee.mantissa2 = frac_ptr[1];
|
||||
u.ieee.mantissa1 = frac_ptr[2];
|
||||
u.ieee.mantissa0 = frac_ptr[3] & (((mp_limb_t) 1
|
||||
<< (FLT128_MANT_DIG - 96)) - 1);
|
||||
#elif BITS_PER_MP_LIMB == 64
|
||||
u.ieee.mantissa3 = frac_ptr[0] & (((mp_limb_t) 1 << 32) - 1);
|
||||
u.ieee.mantissa2 = frac_ptr[0] >> 32;
|
||||
u.ieee.mantissa1 = frac_ptr[1] & (((mp_limb_t) 1 << 32) - 1);
|
||||
u.ieee.mantissa0 = (frac_ptr[1] >> 32) & (((mp_limb_t) 1
|
||||
<< (FLT128_MANT_DIG - 96)) - 1);
|
||||
#else
|
||||
#error "mp_limb size " BITS_PER_MP_LIMB "not accounted for"
|
||||
#endif
|
||||
|
||||
return u.d;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/* Definitions for strfromf128. Implementation in stdlib/strfrom-skeleton.c.
|
||||
|
||||
Copyright (C) 2017 Free Software Foundation, Inc.
|
||||
|
||||
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
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define FLOAT _Float128
|
||||
#define STRFROM strfromf128
|
||||
|
||||
#include <bits/floatn.h>
|
||||
#include <float128_private.h>
|
||||
|
||||
#include <stdlib/strfrom-skeleton.c>
|
||||
@@ -0,0 +1,33 @@
|
||||
/* Convert string for NaN payload to corresponding NaN. For _Float128.
|
||||
Copyright (C) 2017 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
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define FLOAT _Float128
|
||||
#define SET_MANTISSA(flt, mant) \
|
||||
do \
|
||||
{ \
|
||||
union ieee854_float128 u; \
|
||||
u.d = (flt); \
|
||||
u.ieee_nan.mantissa0 = 0; \
|
||||
u.ieee_nan.mantissa1 = 0; \
|
||||
u.ieee_nan.mantissa2 = (mant) >> 32; \
|
||||
u.ieee_nan.mantissa3 = (mant); \
|
||||
if ((u.ieee.mantissa0 | u.ieee.mantissa1 \
|
||||
| u.ieee.mantissa2 | u.ieee.mantissa3) != 0) \
|
||||
(flt) = u.d; \
|
||||
} \
|
||||
while (0)
|
||||
@@ -0,0 +1,34 @@
|
||||
/* strtof128 wrapper of strtof128_l.
|
||||
Copyright (C) 2017 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
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* The actual implementation for all floating point sizes is in strtod.c.
|
||||
These macros tell it to produce the `_Float128' version, `strtof128'. */
|
||||
|
||||
#define FLOAT _Float128
|
||||
#define FLT FLT128
|
||||
#ifdef USE_WIDE_CHAR
|
||||
# define STRTOF wcstof128
|
||||
# define STRTOF_L __wcstof128_l
|
||||
#else
|
||||
# define STRTOF strtof128
|
||||
# define STRTOF_L __strtof128_l
|
||||
#endif
|
||||
|
||||
#include <float128_private.h>
|
||||
|
||||
#include <stdlib/strtod.c>
|
||||
@@ -0,0 +1,43 @@
|
||||
/* Convert string representing a number to a _Float128 value, with locale.
|
||||
Copyright (C) 2017 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
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <xlocale.h>
|
||||
|
||||
/* Bring in potential typedef for _Float128 early for declaration below. */
|
||||
#include <bits/floatn.h>
|
||||
|
||||
extern _Float128 ____strtof128_l_internal (const char *, char **,
|
||||
int, __locale_t);
|
||||
|
||||
#define FLOAT _Float128
|
||||
#define FLT FLT128
|
||||
#ifdef USE_WIDE_CHAR
|
||||
# define STRTOF wcstof128_l
|
||||
# define __STRTOF __wcstof128_l
|
||||
# define STRTOF_NAN __wcstof128_nan
|
||||
#else
|
||||
# define STRTOF strtof128_l
|
||||
# define __STRTOF __strtof128_l
|
||||
# define STRTOF_NAN __strtof128_nan
|
||||
#endif
|
||||
#define MPN2FLOAT __mpn_construct_float128
|
||||
#define FLOAT_HUGE_VAL __builtin_huge_valf128 ()
|
||||
|
||||
#include <float128_private.h>
|
||||
|
||||
#include <stdlib/strtod_l.c>
|
||||
@@ -0,0 +1,28 @@
|
||||
/* Convert string for NaN payload to corresponding NaN. Narrow
|
||||
strings, __float128.
|
||||
Copyright (C) 2017 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
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include <float128_private.h>
|
||||
|
||||
#include <strtod_nan_narrow.h>
|
||||
#include <strtod_nan_float128.h>
|
||||
|
||||
#define STRTOD_NAN __strtof128_nan
|
||||
#include <stdlib/strtod_nan_main.c>
|
||||
@@ -0,0 +1,29 @@
|
||||
/* Copyright (C) 2017 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
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <xlocale.h>
|
||||
|
||||
#define USE_WIDE_CHAR 1
|
||||
|
||||
/* Bring in _Float128 typedef if needed. */
|
||||
#include <bits/floatn.h>
|
||||
|
||||
extern _Float128 ____wcstof128_l_internal (const wchar_t *, wchar_t **, int,
|
||||
__locale_t);
|
||||
|
||||
#include "strtof128.c"
|
||||
@@ -0,0 +1,30 @@
|
||||
/* Convert string representing a number to integer value, using given locale.
|
||||
Copyright (C) 2017 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
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <xlocale.h>
|
||||
|
||||
|
||||
#define USE_WIDE_CHAR 1
|
||||
|
||||
#include <bits/floatn.h>
|
||||
|
||||
extern _Float128 ____wcstof128_l_internal (const wchar_t *, wchar_t **, int,
|
||||
__locale_t);
|
||||
|
||||
#include "strtof128_l.c"
|
||||
@@ -0,0 +1,24 @@
|
||||
/* Convert string for NaN payload to corresponding NaN. Wide strings,
|
||||
_Float128.
|
||||
Copyright (C) 2017 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
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <stdlib/strtod_nan_wide.h>
|
||||
#include <float128_private.h>
|
||||
#include <strtod_nan_float128.h>
|
||||
#define STRTOD_NAN __wcstof128_nan
|
||||
#include <stdlib/strtod_nan_main.c>
|
||||
@@ -18,10 +18,14 @@
|
||||
#include "gmp.h"
|
||||
#include "gmp-impl.h"
|
||||
#include "longlong.h"
|
||||
#include <ieee754.h>
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __FLOAT128_OVERRIDE
|
||||
# include <float128_private.h>
|
||||
#else
|
||||
# include <ieee754.h>
|
||||
# include <float.h>
|
||||
# include <math.h>
|
||||
#endif
|
||||
|
||||
/* Convert a `long double' in IEEE854 quad-precision format to a
|
||||
multi-precision integer representing the significand scaled up by its
|
||||
@@ -29,9 +33,15 @@
|
||||
(MPN frexpl). */
|
||||
|
||||
mp_size_t
|
||||
#ifdef __FLOAT128_OVERRIDE
|
||||
__mpn_extract_float128 (mp_ptr res_ptr, mp_size_t size,
|
||||
int *expt, int *is_neg,
|
||||
_Float128 value)
|
||||
#else
|
||||
__mpn_extract_long_double (mp_ptr res_ptr, mp_size_t size,
|
||||
int *expt, int *is_neg,
|
||||
long double value)
|
||||
#endif
|
||||
{
|
||||
union ieee854_long_double u;
|
||||
u.d = value;
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
/* Macros to control TS 18661-3 glibc features on powerpc.
|
||||
Copyright (C) 2017 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
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define __GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION
|
||||
#include <bits/libc-header-start.h>
|
||||
|
||||
/* Defined to 1 if the current compiler invocation provides a
|
||||
floating-point type with the IEEE 754 binary128 format, and this glibc
|
||||
includes corresponding *f128 interfaces for it. */
|
||||
#if defined _ARCH_PWR8 && defined __LITTLE_ENDIAN__ && (_CALL_ELF == 2) \
|
||||
&& defined __FLOAT128__
|
||||
# define __HAVE_FLOAT128 1
|
||||
#else
|
||||
# define __HAVE_FLOAT128 0
|
||||
#endif
|
||||
|
||||
/* Defined to 1 if __HAVE_FLOAT128 is 1 and the type is ABI-distinct
|
||||
from the default float, double and long double types in this glibc. */
|
||||
#if __HAVE_FLOAT128
|
||||
# define __HAVE_DISTINCT_FLOAT128 1
|
||||
#else
|
||||
# define __HAVE_DISTINCT_FLOAT128 0
|
||||
#endif
|
||||
|
||||
/* Defined to concatenate the literal suffix to be used with _Float128
|
||||
types, if __HAVE_FLOAT128 is 1. */
|
||||
#if __HAVE_FLOAT128
|
||||
# if !__GNUC_PREREQ (7, 0)
|
||||
/* The literal suffix (f128) exist for powerpc only since GCC 7.0. */
|
||||
# define __f128(x) x##q
|
||||
# else
|
||||
# define __f128(x) x##f128
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Defined to a complex binary128 type if __HAVE_FLOAT128 is 1. */
|
||||
#if __HAVE_FLOAT128
|
||||
# if !__GNUC_PREREQ (7, 0)
|
||||
/* Add a typedef for older GCC compilers which don't natively support
|
||||
_Complex _Float128. */
|
||||
typedef _Complex float __cfloat128 __attribute__ ((__mode__ (__KC__)));
|
||||
# define __CFLOAT128 __cfloat128
|
||||
# else
|
||||
# define __CFLOAT128 _Complex _Float128
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* The remaining of this file provides support for older compilers. */
|
||||
#if __HAVE_FLOAT128
|
||||
|
||||
/* The type _Float128 exist for powerpc only since GCC 7.0. */
|
||||
# if !__GNUC_PREREQ (7, 0)
|
||||
typedef __float128 _Float128;
|
||||
# endif
|
||||
|
||||
/* Builtin __builtin_huge_valf128 doesn't exist before GCC 7.0. */
|
||||
# if !__GNUC_PREREQ (7, 0)
|
||||
# define __builtin_huge_valf128() ((_Float128) __builtin_huge_val ())
|
||||
# endif
|
||||
|
||||
/* The following builtins (suffixed with 'q') are available in GCC >= 6.2,
|
||||
which is the minimum version required for float128 support on powerpc64le.
|
||||
Since GCC 7.0 the builtins suffixed with f128 are also available, then
|
||||
there is no need to redefined them. */
|
||||
# if !__GNUC_PREREQ (7, 0)
|
||||
# define __builtin_copysignf128 __builtin_copysignq
|
||||
# define __builtin_fabsf128 __builtin_fabsq
|
||||
# define __builtin_inff128 __builtin_infq
|
||||
# define __builtin_nanf128 __builtin_nanq
|
||||
# define __builtin_nansf128 __builtin_nansq
|
||||
# endif
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -23,8 +23,19 @@
|
||||
#include <ldsodefs.h>
|
||||
#include <dl-procinfo.h>
|
||||
#include <fenv_private.h>
|
||||
|
||||
#include_next <math_private.h>
|
||||
|
||||
#if defined _ARCH_PWR9 && __HAVE_DISTINCT_FLOAT128
|
||||
extern __always_inline _Float128
|
||||
__ieee754_sqrtf128 (_Float128 __x)
|
||||
{
|
||||
_Float128 __z;
|
||||
asm ("xssqrtqp %0,%1" : "=wq" (__z) : "wq" (__x));
|
||||
return __z;
|
||||
}
|
||||
#endif
|
||||
|
||||
extern double __slow_ieee754_sqrt (double);
|
||||
extern __always_inline double
|
||||
__ieee754_sqrt (double __x)
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
ieee754/float128
|
||||
@@ -0,0 +1,48 @@
|
||||
# When building float128 we need to ensure -mfloat128 is
|
||||
# passed to all such object files.
|
||||
|
||||
ifeq ($(subdir),math)
|
||||
# sqrtf128 requires emulation on POWER8 and below.
|
||||
CPPFLAGS += -I../soft-fp
|
||||
|
||||
# float128 requires adding a handful of extra flags.
|
||||
%f128.o %f128.os %f128_r.o %f128_r.os: CFLAGS += -mfloat128
|
||||
$(objpfx)test-float128%.o $(objpfx)test-float128%.os: CFLAGS += -mfloat128
|
||||
$(objpfx)test-ifloat128%.o $(objpfx)test-ifloat128%.os: CFLAGS += -mfloat128
|
||||
CFLAGS-libm-test-support-float128.c += -mfloat128
|
||||
endif
|
||||
|
||||
# Append flags to string <-> _Float128 routines.
|
||||
ifneq ($(filter $(subdir),wcsmbs stdlib),)
|
||||
%f128.o %f128.os %f128_l.o %f128_l.os %f128_nan.o %f128_nan.os %float1282mpn.o %float1282mpn.os %mpn2float128.o %mpn2float128.os: CFLAGS += -mfloat128
|
||||
CFLAGS-bug-strtod.c += -mfloat128
|
||||
CFLAGS-bug-strtod2.c += -mfloat128
|
||||
CFLAGS-tst-strtod-round.c += -mfloat128
|
||||
CFLAGS-tst-wcstod-round.c += -mfloat128
|
||||
CFLAGS-tst-strtod6.c += -mfloat128
|
||||
CFLAGS-tst-strfrom.c += -mfloat128
|
||||
CFLAGS-tst-strfrom-locale.c += -mfloat128
|
||||
CFLAGS-strfrom-skeleton.c += -mfloat128
|
||||
|
||||
# The strfrom class of functions call __printf_fp in order to convert the
|
||||
# floating-point value to characters. This requires the value of IO_MTSAFE_IO.
|
||||
CFLAGS-strfromf128.c += $(libio-mtsafe)
|
||||
|
||||
# When building glibc with support for _Float128, the powers of ten tables in
|
||||
# fpioconst.c and in the string conversion functions must be extended.
|
||||
sysdep-CFLAGS += $(sysdep-CFLAGS-$(<F))
|
||||
sysdep-CFLAGS-fpioconst.c += -mfloat128
|
||||
sysdep-CFLAGS-strtod_l.c += -mfloat128
|
||||
sysdep-CFLAGS-strtof_l.c += -mfloat128
|
||||
sysdep-CFLAGS-strtold_l.c += -mfloat128
|
||||
sysdep-CFLAGS-wcstod_l.c += -mfloat128
|
||||
sysdep-CFLAGS-wcstof_l.c += -mfloat128
|
||||
sysdep-CFLAGS-wcstold_l.c += -mfloat128
|
||||
endif
|
||||
|
||||
# Append flags to printf routines.
|
||||
ifeq ($(subdir),stdio-common)
|
||||
CFLAGS-printf_fp.c = -mfloat128
|
||||
CFLAGS-printf_fphex.c = -mfloat128
|
||||
CFLAGS-printf_size.c = -mfloat128
|
||||
endif
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
|
||||
|
||||
# ac_fn_c_try_cpp LINENO
|
||||
# ----------------------
|
||||
# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
|
||||
ac_fn_c_try_cpp ()
|
||||
{
|
||||
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
|
||||
if { { ac_try="$ac_cpp conftest.$ac_ext"
|
||||
case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
|
||||
$as_echo "$ac_try_echo"; } >&5
|
||||
(eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
|
||||
ac_status=$?
|
||||
if test -s conftest.err; then
|
||||
grep -v '^ *+' conftest.err >conftest.er1
|
||||
cat conftest.er1 >&5
|
||||
mv -f conftest.er1 conftest.err
|
||||
fi
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||
test $ac_status = 0; } > conftest.i && {
|
||||
test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
|
||||
test ! -s conftest.err
|
||||
}; then :
|
||||
ac_retval=0
|
||||
else
|
||||
$as_echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
ac_retval=1
|
||||
fi
|
||||
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
|
||||
as_fn_set_status $ac_retval
|
||||
|
||||
} # ac_fn_c_try_cpp
|
||||
# This file is generated from configure.ac by Autoconf. DO NOT EDIT!
|
||||
# Local configure fragment for sysdeps/powerpc/powerpc64le.
|
||||
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC is sufficient to build libc for powerpc64le" >&5
|
||||
$as_echo_n "checking if $CC is sufficient to build libc for powerpc64le... " >&6; }
|
||||
if ${libc_cv_compiler_powerpc64le_compiler_ok+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
#if !defined __GNUC__ || __GNUC__ < 6 || (__GNUC__ == 6 && __GNUC_MINOR__ < 2)
|
||||
#error insufficient compiler
|
||||
#endif
|
||||
|
||||
_ACEOF
|
||||
if ac_fn_c_try_cpp "$LINENO"; then :
|
||||
libc_cv_compiler_powerpc64le_compiler_ok=yes
|
||||
else
|
||||
libc_cv_compiler_powerpc64le_compiler_ok=no
|
||||
fi
|
||||
rm -f conftest.err conftest.i conftest.$ac_ext
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_compiler_powerpc64le_compiler_ok" >&5
|
||||
$as_echo "$libc_cv_compiler_powerpc64le_compiler_ok" >&6; }
|
||||
if test "$libc_cv_compiler_powerpc64le_compiler_ok" != "yes"; then :
|
||||
critic_missing="$critic_missing GCC >= 6.2 is required on powerpc64le."
|
||||
fi
|
||||
|
||||
test -n "$critic_missing" && as_fn_error $? "*** $critic_missing" "$LINENO" 5
|
||||
@@ -0,0 +1,17 @@
|
||||
GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
|
||||
# Local configure fragment for sysdeps/powerpc/powerpc64le.
|
||||
|
||||
dnl Require __float128 support on powerpc64le (available in GCC 6.2).
|
||||
AC_CACHE_CHECK([if $CC is sufficient to build libc for powerpc64le],
|
||||
libc_cv_compiler_powerpc64le_compiler_ok, [
|
||||
AC_PREPROC_IFELSE([AC_LANG_SOURCE([[
|
||||
#if !defined __GNUC__ || __GNUC__ < 6 || (__GNUC__ == 6 && __GNUC_MINOR__ < 2)
|
||||
#error insufficient compiler
|
||||
#endif
|
||||
]])],
|
||||
[libc_cv_compiler_powerpc64le_compiler_ok=yes],
|
||||
[libc_cv_compiler_powerpc64le_compiler_ok=no])])
|
||||
AS_IF([test "$libc_cv_compiler_powerpc64le_compiler_ok" != "yes"],
|
||||
[critic_missing="$critic_missing GCC >= 6.2 is required on powerpc64le."])
|
||||
|
||||
test -n "$critic_missing" && AC_MSG_ERROR([*** $critic_missing])
|
||||
@@ -0,0 +1,57 @@
|
||||
/* soft-fp sqrt for _Float128
|
||||
Return sqrt(a)
|
||||
Copyright (C) 2017 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.
|
||||
|
||||
In addition to the permissions in the GNU Lesser General Public
|
||||
License, the Free Software Foundation gives you unlimited
|
||||
permission to link the compiled version of this file into
|
||||
combinations with other programs, and to distribute those
|
||||
combinations without any restriction coming from the use of this
|
||||
file. (The Lesser General Public License restrictions do apply in
|
||||
other respects; for example, they cover modification of the file,
|
||||
and distribution when not linked into a combine executable.)
|
||||
|
||||
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
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Unavoidable hacks since TFmode is assumed to be binary128. */
|
||||
#define TFtype KFtype
|
||||
#define TF KF
|
||||
|
||||
#include <soft-fp.h>
|
||||
#include <quad.h>
|
||||
|
||||
__float128
|
||||
__ieee754_sqrtf128 (__float128 a)
|
||||
{
|
||||
#ifndef _ARCH_PWR9
|
||||
FP_DECL_EX;
|
||||
FP_DECL_Q (A);
|
||||
FP_DECL_Q (R);
|
||||
__float128 r;
|
||||
|
||||
FP_INIT_ROUNDMODE;
|
||||
FP_UNPACK_Q (A, a);
|
||||
FP_SQRT_Q (R, A);
|
||||
FP_PACK_Q (r, R);
|
||||
FP_HANDLE_EXCEPTIONS;
|
||||
return r;
|
||||
#else
|
||||
__float128 z;
|
||||
asm ("xssqrtqp %0,%1" : "=wq" (z) : "wq" (a));
|
||||
return z;
|
||||
#endif
|
||||
}
|
||||
strong_alias (__ieee754_sqrtf128, __sqrtf128_finite)
|
||||
@@ -0,0 +1,158 @@
|
||||
/* Decide whether to use 64 or 32-bit types to do the emulation. If we are
|
||||
doing IEEE-128 with VSX, use 64-bit emulation even if we are compiling for a
|
||||
32-bit target. */
|
||||
|
||||
#if defined(_ARCH_PPC64) || defined(__VSX__) || defined(__FLOAT128__)
|
||||
#define _FP_W_TYPE_SIZE 64
|
||||
#define _FP_W_TYPE unsigned long long
|
||||
#define _FP_WS_TYPE signed long long
|
||||
#define _FP_I_TYPE long long
|
||||
|
||||
#ifdef _ARCH_PPC64
|
||||
typedef int TItype __attribute__ ((mode (TI)));
|
||||
typedef unsigned int UTItype __attribute__ ((mode (TI)));
|
||||
|
||||
#define TI_BITS (__CHAR_BIT__ * (int)sizeof(TItype))
|
||||
#endif
|
||||
|
||||
#else /* 32-bits */
|
||||
#define _FP_W_TYPE_SIZE 32
|
||||
#define _FP_W_TYPE unsigned int
|
||||
#define _FP_WS_TYPE signed int
|
||||
#define _FP_I_TYPE int
|
||||
#endif /* 32-bits */
|
||||
|
||||
/* The type of the result of a floating point comparison. This must
|
||||
match `__libgcc_cmp_return__' in GCC for the target. */
|
||||
typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
|
||||
#define CMPtype __gcc_CMPtype
|
||||
|
||||
#define _FP_MUL_MEAT_S(R,X,Y) \
|
||||
_FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
|
||||
|
||||
#if (_FP_W_TYPE_SIZE==64)
|
||||
#define _FP_MUL_MEAT_D(R,X,Y) \
|
||||
_FP_MUL_MEAT_1_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
|
||||
#define _FP_MUL_MEAT_Q(R,X,Y) \
|
||||
_FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
|
||||
#else
|
||||
#define _FP_MUL_MEAT_D(R,X,Y) \
|
||||
_FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
|
||||
#define _FP_MUL_MEAT_Q(R,X,Y) \
|
||||
_FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
|
||||
#endif
|
||||
|
||||
#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_loop(S,R,X,Y)
|
||||
|
||||
#if (_FP_W_TYPE_SIZE==64)
|
||||
#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_1_udiv(D,R,X,Y)
|
||||
#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
|
||||
#else
|
||||
#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv(D,R,X,Y)
|
||||
#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_4_udiv(Q,R,X,Y)
|
||||
#endif
|
||||
|
||||
#define _FP_NANFRAC_S ((_FP_QNANBIT_S << 1) - 1)
|
||||
|
||||
#if (_FP_W_TYPE_SIZE==64)
|
||||
#define _FP_NANFRAC_D ((_FP_QNANBIT_D << 1) - 1)
|
||||
#define _FP_NANFRAC_Q ((_FP_QNANBIT_Q << 1) - 1), -1
|
||||
#else
|
||||
#define _FP_NANFRAC_D ((_FP_QNANBIT_D << 1) - 1), -1
|
||||
#define _FP_NANFRAC_Q ((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1
|
||||
#endif
|
||||
|
||||
#define _FP_NANSIGN_S 0
|
||||
#define _FP_NANSIGN_D 0
|
||||
#define _FP_NANSIGN_Q 0
|
||||
|
||||
#define _FP_KEEPNANFRACP 1
|
||||
#define _FP_QNANNEGATEDP 0
|
||||
|
||||
/* Someone please check this. */
|
||||
#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
|
||||
do { \
|
||||
if ((_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs) \
|
||||
&& !(_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs)) \
|
||||
{ \
|
||||
R##_s = Y##_s; \
|
||||
_FP_FRAC_COPY_##wc(R,Y); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
R##_s = X##_s; \
|
||||
_FP_FRAC_COPY_##wc(R,X); \
|
||||
} \
|
||||
R##_c = FP_CLS_NAN; \
|
||||
} while (0)
|
||||
|
||||
#define _FP_TININESS_AFTER_ROUNDING 0
|
||||
|
||||
#define __LITTLE_ENDIAN 1234
|
||||
#define __BIG_ENDIAN 4321
|
||||
|
||||
#if defined __BIG_ENDIAN__ || defined _BIG_ENDIAN
|
||||
# if defined __LITTLE_ENDIAN__ || defined _LITTLE_ENDIAN
|
||||
# error "Both BIG_ENDIAN and LITTLE_ENDIAN defined!"
|
||||
# endif
|
||||
# define __BYTE_ORDER __BIG_ENDIAN
|
||||
#else
|
||||
# if defined __LITTLE_ENDIAN__ || defined _LITTLE_ENDIAN
|
||||
# define __BYTE_ORDER __LITTLE_ENDIAN
|
||||
# else
|
||||
# error "Cannot determine current byte order"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Only provide exception support if we have hardware floating point using
|
||||
floating point registers and we can execute the mtfsf instruction. This
|
||||
would only be true if we are using the emulation routines for IEEE 128-bit
|
||||
floating point on pre-ISA 3.0 machines without the IEEE 128-bit floating
|
||||
point support. */
|
||||
|
||||
#ifdef __FLOAT128__
|
||||
#define ISA_BIT(x) (1LL << (63 - x))
|
||||
|
||||
/* Use the same bits of the FPSCR. */
|
||||
# define FP_EX_INVALID ISA_BIT(34)
|
||||
# define FP_EX_OVERFLOW ISA_BIT(35)
|
||||
# define FP_EX_UNDERFLOW ISA_BIT(36)
|
||||
# define FP_EX_DIVZERO ISA_BIT(37)
|
||||
# define FP_EX_INEXACT ISA_BIT(38)
|
||||
# define FP_EX_ALL (FP_EX_INVALID | FP_EX_OVERFLOW \
|
||||
| FP_EX_UNDERFLOW | FP_EX_DIVZERO \
|
||||
| FP_EX_INEXACT)
|
||||
|
||||
void __sfp_handle_exceptions (int);
|
||||
|
||||
# define FP_HANDLE_EXCEPTIONS \
|
||||
do { \
|
||||
if (__builtin_expect (_fex, 0)) \
|
||||
__sfp_handle_exceptions (_fex); \
|
||||
} while (0);
|
||||
|
||||
/* The FP_EX_* bits track whether the exception has occurred. This macro
|
||||
must set the FP_EX_* bits of those exceptions which are configured to
|
||||
trap. The FPSCR bit which indicates this is 22 ISA bits above the
|
||||
respective FP_EX_* bit. Note, the ISA labels bits from msb to lsb,
|
||||
so 22 ISA bits above is 22 bits below when counted from the lsb. */
|
||||
# define FP_TRAPPING_EXCEPTIONS ((_fpscr.i << 22) & FP_EX_ALL)
|
||||
|
||||
# define FP_RND_NEAREST 0x0
|
||||
# define FP_RND_ZERO 0x1
|
||||
# define FP_RND_PINF 0x2
|
||||
# define FP_RND_MINF 0x3
|
||||
# define FP_RND_MASK 0x3
|
||||
|
||||
# define _FP_DECL_EX \
|
||||
union { unsigned long long i; double d; } _fpscr __attribute__ ((unused)) = \
|
||||
{ .i = FP_RND_NEAREST }
|
||||
|
||||
#define FP_INIT_ROUNDMODE \
|
||||
do { \
|
||||
__asm__ __volatile__ ("mffs %0" \
|
||||
: "=f" (_fpscr.d)); \
|
||||
} while (0)
|
||||
|
||||
# define FP_ROUNDMODE (_fpscr.i & FP_RND_MASK)
|
||||
#endif /* !__FLOAT128__ */
|
||||
@@ -0,0 +1,36 @@
|
||||
/* POWER9 sqrt for _Float128
|
||||
Return sqrt(a)
|
||||
Copyright (C) 2017 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.
|
||||
|
||||
In addition to the permissions in the GNU Lesser General Public
|
||||
License, the Free Software Foundation gives you unlimited
|
||||
permission to link the compiled version of this file into
|
||||
combinations with other programs, and to distribute those
|
||||
combinations without any restriction coming from the use of this
|
||||
file. (The Lesser General Public License restrictions do apply in
|
||||
other respects; for example, they cover modification of the file,
|
||||
and distribution when not linked into a combine executable.)
|
||||
|
||||
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
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
__float128
|
||||
__ieee754_sqrtf128 (__float128 a)
|
||||
{
|
||||
__float128 z;
|
||||
asm ("xssqrtqp %0,%1" : "=wq" (z) : "wq" (a));
|
||||
return z;
|
||||
}
|
||||
strong_alias (__ieee754_sqrtf128, __sqrtf128_finite)
|
||||
@@ -2179,9 +2179,16 @@ GLIBC_2.24 GLIBC_2.24 A
|
||||
GLIBC_2.24 quick_exit F
|
||||
GLIBC_2.25 GLIBC_2.25 A
|
||||
GLIBC_2.25 __explicit_bzero_chk F
|
||||
GLIBC_2.25 __strtof128_internal F
|
||||
GLIBC_2.25 __wcstof128_internal F
|
||||
GLIBC_2.25 explicit_bzero F
|
||||
GLIBC_2.25 getentropy F
|
||||
GLIBC_2.25 getrandom F
|
||||
GLIBC_2.25 strfromd F
|
||||
GLIBC_2.25 strfromf F
|
||||
GLIBC_2.25 strfromf128 F
|
||||
GLIBC_2.25 strfroml F
|
||||
GLIBC_2.25 strtof128 F
|
||||
GLIBC_2.25 strtof128_l F
|
||||
GLIBC_2.25 wcstof128 F
|
||||
GLIBC_2.25 wcstof128_l F
|
||||
|
||||
@@ -416,54 +416,191 @@ GLIBC_2.24 nextup F
|
||||
GLIBC_2.24 nextupf F
|
||||
GLIBC_2.24 nextupl F
|
||||
GLIBC_2.25 GLIBC_2.25 A
|
||||
GLIBC_2.25 __acosf128_finite F
|
||||
GLIBC_2.25 __acoshf128_finite F
|
||||
GLIBC_2.25 __asinf128_finite F
|
||||
GLIBC_2.25 __atan2f128_finite F
|
||||
GLIBC_2.25 __atanhf128_finite F
|
||||
GLIBC_2.25 __coshf128_finite F
|
||||
GLIBC_2.25 __exp10f128_finite F
|
||||
GLIBC_2.25 __exp2f128_finite F
|
||||
GLIBC_2.25 __expf128_finite F
|
||||
GLIBC_2.25 __fe_dfl_mode D 0x8
|
||||
GLIBC_2.25 __finitef128 F
|
||||
GLIBC_2.25 __fmodf128_finite F
|
||||
GLIBC_2.25 __fpclassifyf128 F
|
||||
GLIBC_2.25 __gammaf128_r_finite F
|
||||
GLIBC_2.25 __hypotf128_finite F
|
||||
GLIBC_2.25 __iscanonicall F
|
||||
GLIBC_2.25 __iseqsig F
|
||||
GLIBC_2.25 __iseqsigf F
|
||||
GLIBC_2.25 __iseqsigf128 F
|
||||
GLIBC_2.25 __iseqsigl F
|
||||
GLIBC_2.25 __isinff128 F
|
||||
GLIBC_2.25 __isnanf128 F
|
||||
GLIBC_2.25 __issignalingf128 F
|
||||
GLIBC_2.25 __j0f128_finite F
|
||||
GLIBC_2.25 __j1f128_finite F
|
||||
GLIBC_2.25 __jnf128_finite F
|
||||
GLIBC_2.25 __lgammaf128_r_finite F
|
||||
GLIBC_2.25 __log10f128_finite F
|
||||
GLIBC_2.25 __log2f128_finite F
|
||||
GLIBC_2.25 __logf128_finite F
|
||||
GLIBC_2.25 __powf128_finite F
|
||||
GLIBC_2.25 __remainderf128_finite F
|
||||
GLIBC_2.25 __signbitf128 F
|
||||
GLIBC_2.25 __sinhf128_finite F
|
||||
GLIBC_2.25 __sqrtf128_finite F
|
||||
GLIBC_2.25 __y0f128_finite F
|
||||
GLIBC_2.25 __y1f128_finite F
|
||||
GLIBC_2.25 __ynf128_finite F
|
||||
GLIBC_2.25 acosf128 F
|
||||
GLIBC_2.25 acoshf128 F
|
||||
GLIBC_2.25 asinf128 F
|
||||
GLIBC_2.25 asinhf128 F
|
||||
GLIBC_2.25 atan2f128 F
|
||||
GLIBC_2.25 atanf128 F
|
||||
GLIBC_2.25 atanhf128 F
|
||||
GLIBC_2.25 cabsf128 F
|
||||
GLIBC_2.25 cacosf128 F
|
||||
GLIBC_2.25 cacoshf128 F
|
||||
GLIBC_2.25 canonicalize F
|
||||
GLIBC_2.25 canonicalizef F
|
||||
GLIBC_2.25 canonicalizef128 F
|
||||
GLIBC_2.25 canonicalizel F
|
||||
GLIBC_2.25 cargf128 F
|
||||
GLIBC_2.25 casinf128 F
|
||||
GLIBC_2.25 casinhf128 F
|
||||
GLIBC_2.25 catanf128 F
|
||||
GLIBC_2.25 catanhf128 F
|
||||
GLIBC_2.25 cbrtf128 F
|
||||
GLIBC_2.25 ccosf128 F
|
||||
GLIBC_2.25 ccoshf128 F
|
||||
GLIBC_2.25 ceilf128 F
|
||||
GLIBC_2.25 cexpf128 F
|
||||
GLIBC_2.25 cimagf128 F
|
||||
GLIBC_2.25 clog10f128 F
|
||||
GLIBC_2.25 clogf128 F
|
||||
GLIBC_2.25 conjf128 F
|
||||
GLIBC_2.25 copysignf128 F
|
||||
GLIBC_2.25 cosf128 F
|
||||
GLIBC_2.25 coshf128 F
|
||||
GLIBC_2.25 cpowf128 F
|
||||
GLIBC_2.25 cprojf128 F
|
||||
GLIBC_2.25 crealf128 F
|
||||
GLIBC_2.25 csinf128 F
|
||||
GLIBC_2.25 csinhf128 F
|
||||
GLIBC_2.25 csqrtf128 F
|
||||
GLIBC_2.25 ctanf128 F
|
||||
GLIBC_2.25 ctanhf128 F
|
||||
GLIBC_2.25 erfcf128 F
|
||||
GLIBC_2.25 erff128 F
|
||||
GLIBC_2.25 exp10f128 F
|
||||
GLIBC_2.25 exp2f128 F
|
||||
GLIBC_2.25 expf128 F
|
||||
GLIBC_2.25 expm1f128 F
|
||||
GLIBC_2.25 fabsf128 F
|
||||
GLIBC_2.25 fdimf128 F
|
||||
GLIBC_2.25 fegetmode F
|
||||
GLIBC_2.25 fesetexcept F
|
||||
GLIBC_2.25 fesetmode F
|
||||
GLIBC_2.25 fetestexceptflag F
|
||||
GLIBC_2.25 floorf128 F
|
||||
GLIBC_2.25 fmaf128 F
|
||||
GLIBC_2.25 fmaxf128 F
|
||||
GLIBC_2.25 fmaxmag F
|
||||
GLIBC_2.25 fmaxmagf F
|
||||
GLIBC_2.25 fmaxmagf128 F
|
||||
GLIBC_2.25 fmaxmagl F
|
||||
GLIBC_2.25 fminf128 F
|
||||
GLIBC_2.25 fminmag F
|
||||
GLIBC_2.25 fminmagf F
|
||||
GLIBC_2.25 fminmagf128 F
|
||||
GLIBC_2.25 fminmagl F
|
||||
GLIBC_2.25 fmodf128 F
|
||||
GLIBC_2.25 frexpf128 F
|
||||
GLIBC_2.25 fromfp F
|
||||
GLIBC_2.25 fromfpf F
|
||||
GLIBC_2.25 fromfpf128 F
|
||||
GLIBC_2.25 fromfpl F
|
||||
GLIBC_2.25 fromfpx F
|
||||
GLIBC_2.25 fromfpxf F
|
||||
GLIBC_2.25 fromfpxf128 F
|
||||
GLIBC_2.25 fromfpxl F
|
||||
GLIBC_2.25 getpayload F
|
||||
GLIBC_2.25 getpayloadf F
|
||||
GLIBC_2.25 getpayloadf128 F
|
||||
GLIBC_2.25 getpayloadl F
|
||||
GLIBC_2.25 hypotf128 F
|
||||
GLIBC_2.25 ilogbf128 F
|
||||
GLIBC_2.25 j0f128 F
|
||||
GLIBC_2.25 j1f128 F
|
||||
GLIBC_2.25 jnf128 F
|
||||
GLIBC_2.25 ldexpf128 F
|
||||
GLIBC_2.25 lgammaf128 F
|
||||
GLIBC_2.25 lgammaf128_r F
|
||||
GLIBC_2.25 llogb F
|
||||
GLIBC_2.25 llogbf F
|
||||
GLIBC_2.25 llogbf128 F
|
||||
GLIBC_2.25 llogbl F
|
||||
GLIBC_2.25 llrintf128 F
|
||||
GLIBC_2.25 llroundf128 F
|
||||
GLIBC_2.25 log10f128 F
|
||||
GLIBC_2.25 log1pf128 F
|
||||
GLIBC_2.25 log2f128 F
|
||||
GLIBC_2.25 logbf128 F
|
||||
GLIBC_2.25 logf128 F
|
||||
GLIBC_2.25 lrintf128 F
|
||||
GLIBC_2.25 lroundf128 F
|
||||
GLIBC_2.25 modff128 F
|
||||
GLIBC_2.25 nanf128 F
|
||||
GLIBC_2.25 nearbyintf128 F
|
||||
GLIBC_2.25 nextafterf128 F
|
||||
GLIBC_2.25 nextdownf128 F
|
||||
GLIBC_2.25 nextupf128 F
|
||||
GLIBC_2.25 powf128 F
|
||||
GLIBC_2.25 remainderf128 F
|
||||
GLIBC_2.25 remquof128 F
|
||||
GLIBC_2.25 rintf128 F
|
||||
GLIBC_2.25 roundeven F
|
||||
GLIBC_2.25 roundevenf F
|
||||
GLIBC_2.25 roundevenf128 F
|
||||
GLIBC_2.25 roundevenl F
|
||||
GLIBC_2.25 roundf128 F
|
||||
GLIBC_2.25 scalblnf128 F
|
||||
GLIBC_2.25 scalbnf128 F
|
||||
GLIBC_2.25 setpayload F
|
||||
GLIBC_2.25 setpayloadf F
|
||||
GLIBC_2.25 setpayloadf128 F
|
||||
GLIBC_2.25 setpayloadl F
|
||||
GLIBC_2.25 setpayloadsig F
|
||||
GLIBC_2.25 setpayloadsigf F
|
||||
GLIBC_2.25 setpayloadsigf128 F
|
||||
GLIBC_2.25 setpayloadsigl F
|
||||
GLIBC_2.25 sincosf128 F
|
||||
GLIBC_2.25 sinf128 F
|
||||
GLIBC_2.25 sinhf128 F
|
||||
GLIBC_2.25 sqrtf128 F
|
||||
GLIBC_2.25 tanf128 F
|
||||
GLIBC_2.25 tanhf128 F
|
||||
GLIBC_2.25 tgammaf128 F
|
||||
GLIBC_2.25 totalorder F
|
||||
GLIBC_2.25 totalorderf F
|
||||
GLIBC_2.25 totalorderf128 F
|
||||
GLIBC_2.25 totalorderl F
|
||||
GLIBC_2.25 totalordermag F
|
||||
GLIBC_2.25 totalordermagf F
|
||||
GLIBC_2.25 totalordermagf128 F
|
||||
GLIBC_2.25 totalordermagl F
|
||||
GLIBC_2.25 truncf128 F
|
||||
GLIBC_2.25 ufromfp F
|
||||
GLIBC_2.25 ufromfpf F
|
||||
GLIBC_2.25 ufromfpf128 F
|
||||
GLIBC_2.25 ufromfpl F
|
||||
GLIBC_2.25 ufromfpx F
|
||||
GLIBC_2.25 ufromfpxf F
|
||||
GLIBC_2.25 ufromfpxf128 F
|
||||
GLIBC_2.25 ufromfpxl F
|
||||
GLIBC_2.25 y0f128 F
|
||||
GLIBC_2.25 y1f128 F
|
||||
GLIBC_2.25 ynf128 F
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
/* ABI version for _Float128 ABI introduction. */
|
||||
#define FLOAT128_VERSION GLIBC_2.25
|
||||
@@ -81,6 +81,7 @@ CFLAGS-wcstoll.c = $(strtox-CFLAGS)
|
||||
CFLAGS-wcstoull.c = $(strtox-CFLAGS)
|
||||
CFLAGS-wcstod.c = $(strtox-CFLAGS)
|
||||
CFLAGS-wcstold.c = $(strtox-CFLAGS)
|
||||
CFLAGS-wcstof128.c = $(strtox-CFLAGS)
|
||||
CFLAGS-wcstof.c = $(strtox-CFLAGS)
|
||||
CFLAGS-wcstol_l.c = $(strtox-CFLAGS)
|
||||
CFLAGS-wcstoul_l.c = $(strtox-CFLAGS)
|
||||
@@ -88,6 +89,7 @@ CFLAGS-wcstoll_l.c = $(strtox-CFLAGS)
|
||||
CFLAGS-wcstoull_l.c = $(strtox-CFLAGS)
|
||||
CFLAGS-wcstod_l.c = $(strtox-CFLAGS)
|
||||
CFLAGS-wcstold_l.c = $(strtox-CFLAGS)
|
||||
CFLAGS-wcstof128_l.c = $(strtox-CFLAGS)
|
||||
CFLAGS-wcstof_l.c = $(strtox-CFLAGS)
|
||||
CPPFLAGS-tst-wchar-h.c = -D_FORTIFY_SOURCE=2
|
||||
|
||||
|
||||
@@ -468,6 +468,15 @@ __extension__
|
||||
extern unsigned long long int wcstouq (const wchar_t *__restrict __nptr,
|
||||
wchar_t **__restrict __endptr,
|
||||
int __base) __THROW;
|
||||
|
||||
/* Include _Float128 variants of strtof128 if available. */
|
||||
#include <bits/floatn.h>
|
||||
|
||||
#if __HAVE_FLOAT128 && __GLIBC_USE (IEC_60559_TYPES_EXT)
|
||||
extern _Float128 wcstof128 (const wchar_t *__restrict __nptr,
|
||||
wchar_t **__restrict __endptr) __THROW;
|
||||
#endif
|
||||
|
||||
#endif /* Use GNU. */
|
||||
|
||||
#ifdef __USE_GNU
|
||||
@@ -518,6 +527,13 @@ extern float wcstof_l (const wchar_t *__restrict __nptr,
|
||||
extern long double wcstold_l (const wchar_t *__restrict __nptr,
|
||||
wchar_t **__restrict __endptr,
|
||||
__locale_t __loc) __THROW;
|
||||
|
||||
#if __HAVE_FLOAT128 && __GLIBC_USE (IEC_60559_TYPES_EXT)
|
||||
extern _Float128 wcstof128_l (const wchar_t *__restrict __nptr,
|
||||
wchar_t **__restrict __endptr,
|
||||
__locale_t __loc) __THROW;
|
||||
#endif
|
||||
|
||||
#endif /* use GNU */
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user