[02/14] Prepare vfscanf to use __strtof128_internal

Message ID 20180621021023.17036-3-gabriel@inconstante.eti.br
State Superseded
Headers

Commit Message

Gabriel F. T. Gomes June 21, 2018, 2:10 a.m. UTC
  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 when appropriate.  The result gets saved
into a variable of _Float128 type.

	* 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.
	(LDBL_USES_FLOAT128): New macro.
	[__HAVE_FLOAT128_UNLIKE_LDBL] (__vfscanf_internal): Call
	__strtof128_internal when the format of long double is the same
	as _Float128.
---
 libio/libioP.h                  |  5 +++--
 stdio-common/vfscanf-internal.c | 14 ++++++++++++++
 2 files changed, 17 insertions(+), 2 deletions(-)
  

Comments

Joseph Myers June 21, 2018, 9:35 p.m. UTC | #1
On Wed, 20 Jun 2018, Gabriel F. T. Gomes wrote:

> 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 when appropriate.  The result gets saved
> into a variable of _Float128 type.

This patch is OK once Zack's patches are reviewed and checked in.
  
Zack Weinberg June 21, 2018, 9:39 p.m. UTC | #2
On Thu, Jun 21, 2018 at 5:35 PM, Joseph Myers <joseph@codesourcery.com> wrote:
> On Wed, 20 Jun 2018, Gabriel F. T. Gomes wrote:
>
>> 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 when appropriate.  The result gets saved
>> into a variable of _Float128 type.
>
> This patch is OK once Zack's patches are reviewed and checked in.

FYI, it now looks like I will _not_ have time to revise and resubmit
that patchset before the freeze.  Sorry, dayjob is extremely demanding
right now.  Don't expect to hear much from me until, like, October.

zw
  

Patch

diff --git a/libio/libioP.h b/libio/libioP.h
index fba4b52460..6858d8ee88 100644
--- a/libio/libioP.h
+++ b/libio/libioP.h
@@ -731,8 +731,9 @@  extern off64_t _IO_seekpos_unlocked (FILE *, off64_t, int)
 #endif /* _G_HAVE_MMAP */
 
 /* Flags for __vfscanf_internal and __vfwscanf_internal.  */
-#define SCANF_LDBL_IS_DBL 0x0001
-#define SCANF_ISOC99_A    0x0002
+#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);
diff --git a/stdio-common/vfscanf-internal.c b/stdio-common/vfscanf-internal.c
index 0eb6b5e655..d333def905 100644
--- a/stdio-common/vfscanf-internal.c
+++ b/stdio-common/vfscanf-internal.c
@@ -97,6 +97,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
@@ -332,6 +335,7 @@  __vfscanf_internal (FILE *s, const char *format, va_list argptr,
   scratch_buffer_init (&charbuf.scratch);
 
 #define LDBL_DISTINCT (__glibc_likely ((mode_flags & SCANF_LDBL_IS_DBL) == 0))
+#define LDBL_USES_FLOAT128 ((mode_flags & SCANF_LDBL_USES_FLOAT128) != 0)
 #define USE_ISOC99_A  (__glibc_likely (mode_flags & SCANF_ISOC99_A))
 
 #ifdef __va_copy
@@ -2422,6 +2426,16 @@  __vfscanf_internal (FILE *s, const char *format, va_list argptr,
 	      done = EOF;
 	      goto errout;
 	    }
+#if __HAVE_FLOAT128_UNLIKE_LDBL
+	  if ((flags & LONGDBL) && LDBL_USES_FLOAT128)
+	    {
+	      _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) && LDBL_DISTINCT)
 	    {
 	      long double d = __strtold_internal