[02/14] Prepare vfscanf to use __strtof128_internal

Message ID 20180621021023.17036-3-gabriel@inconstante.eti.br
State New
Headers show
Series
  • Functions with format string for IEEE128 on powercpc64le
Related show

Commit Message

Gabriel F. T. Gomes June 21, 2018, 2:10 a.m.
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(-)

-- 
2.14.4

Comments

Joseph Myers June 21, 2018, 9:35 p.m. | #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.

-- 
Joseph S. Myers
joseph@codesourcery.com
Zack Weinberg June 21, 2018, 9:39 p.m. | #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
Gabriel F. T. Gomes Dec. 7, 2018, 8:09 p.m. | #3
On Thu, 21 Jun 2018, Joseph Myers 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.


I have now committed this patch, adapted for current master, and
with the descriptive comment for the SCANF_LDBL_USES_FLOAT128 macro.


From 10446f5d9f2cf4d91c8ae483fd2b5470242ae2a1 Mon Sep 17 00:00:00 2001
From: "Gabriel F. T. Gomes" <gabriel@inconstante.eti.br>

Date: Sun, 10 Jun 2018 22:42:34 -0300
Subject: [PATCH] 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.
---
 ChangeLog                       | 12 ++++++++++++
 libio/libioP.h                  | 18 +++++++++++++++---
 stdio-common/vfscanf-internal.c | 14 ++++++++++++++
 3 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 998f4c153f..c6ad912b11 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
diff --git a/libio/libioP.h b/libio/libioP.h
index ce5228e382..958ef9bffe 100644
--- a/libio/libioP.h
+++ b/libio/libioP.h
@@ -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)
diff --git a/stdio-common/vfscanf-internal.c b/stdio-common/vfscanf-internal.c
index 19cfef0906..5d002078d8 100644
--- a/stdio-common/vfscanf-internal.c
+++ b/stdio-common/vfscanf-internal.c
@@ -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))
 	    {
-- 
2.14.5

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