Prepare vfscanf to use __strtof128_internal

On powerpc64le, long double can currently take two formats: the same as
double (-mlong-double-64) or IBM Extended Precision (default with
-mlong-double-128 or explicitly with -mabi=ibmlongdouble).  The internal
implementation of scanf-like functions is aware of these possibilites
and, based on the format in use, properly calls __strtold_internal or
__strtod_internal, saving the return to a variable of type double or
long double.

When library support for TS 18661-3 was added to glibc, a new function,
__strtof128_internal, was added to enable reading of floating-point
values with IEEE binary128 format into the _Float128 type.  Now that
powerpc64le is getting support for its third long double format, and
taking into account that this format is the same as the format of
_Float128, this patch extends __vfscanf_internal and __vfwscanf_internal
to call __strtof128_internal or __wcstof128_internal when appropriate.
The result gets saved into a variable of _Float128 type.

Tested for powerpc64le.
This commit is contained in:
Gabriel F. T. Gomes 2018-06-10 22:42:34 -03:00
parent 45f33aac78
commit 10446f5d9f
3 changed files with 41 additions and 3 deletions

View file

@ -1,3 +1,15 @@
2018-12-07 Gabriel F. T. Gomes <gabriel@inconstante.eti.br>
* libio/libioP.h (SCANF_LDBL_USES_FLOAT128): New macro to be
used as a mask for the mode argument of __vfscanf_internal and
__vfwscanf_internal.
* stdio-common/vfscanf-internal.c
[defined COMPILE_WSCANF && __HAVE_FLOAT128_UNLIKE_LDBL]
(__strtof128_internal): Define to __wcstof128_internal.
[__HAVE_FLOAT128_UNLIKE_LDBL] (__vfscanf_internal): Call
__strtof128_internal or __wcstof128_internal when the format of
long double is the same as _Float128.
2018-12-05 Samuel Thibault <samuel.thibault@ens-lyon.org>
* include/unistd.h (__confstr): Add prototype and hidden prototype.

View file

@ -759,9 +759,21 @@ extern off64_t _IO_seekpos_unlocked (FILE *, off64_t, int)
allocation for input strings with %as, %aS and %a[, a GNU extension,
is disabled. This is the behavior that the __isoc99_scanf family of
functions use. When the flag is set to zero, automatic allocation is
enabled. */
#define SCANF_LDBL_IS_DBL 0x0001
#define SCANF_ISOC99_A 0x0002
enabled.
SCANF_LDBL_USES_FLOAT128 is used on platforms where the long double
format used to be different from the IEC 60559 double format *and*
also different from the Quadruple 128-bits IEC 60559 format (such as
the IBM Extended Precision format on powerpc or the 80-bits IEC 60559
format on x86), but was later converted to the Quadruple 128-bits IEC
60559 format, which is the same format that the _Float128 always has
(hence the `USES_FLOAT128' suffix in the name of the flag). When set
to one, this macros indicates that long double values are to be
handled as having this new format. Otherwise, they should be handled
as the previous format on that platform. */
#define SCANF_LDBL_IS_DBL 0x0001
#define SCANF_ISOC99_A 0x0002
#define SCANF_LDBL_USES_FLOAT128 0x0004
extern int __vfscanf_internal (FILE *fp, const char *format, va_list argp,
unsigned int flags)

View file

@ -98,6 +98,9 @@
# define __strtold_internal __wcstold_internal
# define __strtod_internal __wcstod_internal
# define __strtof_internal __wcstof_internal
# if __HAVE_FLOAT128_UNLIKE_LDBL
# define __strtof128_internal __wcstof128_internal
# endif
# define L_(Str) L##Str
# define CHAR_T wchar_t
@ -2420,6 +2423,17 @@ __vfscanf_internal (FILE *s, const char *format, va_list argptr,
done = EOF;
goto errout;
}
#if __HAVE_FLOAT128_UNLIKE_LDBL
if ((flags & LONGDBL) \
&& (mode_flags & SCANF_LDBL_USES_FLOAT128) != 0)
{
_Float128 d = __strtof128_internal
(char_buffer_start (&charbuf), &tw, flags & GROUP);
if (!(flags & SUPPRESS) && tw != char_buffer_start (&charbuf))
*ARG (_Float128 *) = d;
}
else
#endif
if ((flags & LONGDBL) \
&& __glibc_likely ((mode_flags & SCANF_LDBL_IS_DBL) == 0))
{