This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 02/14] 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 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(-)

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
-- 
2.14.4


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]