This is the mail archive of the glibc-cvs@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]

GNU C Library master sources branch master updated. glibc-2.25-426-gcf2046e


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, master has been updated
       via  cf2046ec7dd4b233180377cc5b8debcf551d1fc9 (commit)
       via  2bc646c9e95b7c0005b2bc09c06671ffbb509629 (commit)
       via  aab0f374e7c43f6baf88db271865feabb7bcc1b2 (commit)
       via  32bf1d09dadee5b60df869ed3567a2b12c04e3fc (commit)
       via  82c19bdfe39164fda779c79a925c2050b19e421b (commit)
      from  81df4d253dc3184fb003e4737b917e8d35c341d1 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=cf2046ec7dd4b233180377cc5b8debcf551d1fc9

commit cf2046ec7dd4b233180377cc5b8debcf551d1fc9
Author: Gabriel F. T. Gomes <gftg@linux.vnet.ibm.com>
Date:   Thu Nov 3 12:37:08 2016 -0200

    float128: Add strfromf128
    
    Add strfromf128 to stdlib when _Float128 support is enabled.
    
    	* stdio-common/printf-parsemb.c (__parse_one_specmb): Initialize
    	spec->info.is_binary128 to zero.
    	* stdio-common/printf.h (printf_info): Add new member is_binary128
    	to indicate that the number being converted to string is compatible
    	with the IEC 60559 binary128 format.
    	* stdio-common/printf_fp.c (__printf_fp_l): Add code to deal with
    	_Float128 numbers.
    	* stdio-common/printf_fphex.c: Include ieee754_float128.h and
    	ldbl-128/printf_fphex_macros.h
    	(__printf_fphex): Add code to deal with _Float128 numbers.
    	* stdio-common/printf_size.c (__printf_size): Likewise.
    	* stdio-common/vfprintf.c (process_arg): Initialize member
    	info.is_binary128 to zero.
    	* stdlib/fpioconst.h (FLT128_MAX_10_EXP_LOG): New macro.
    	* stdlib/stdlib.h: Include bits/floatn.h for _Float128 support.
    	(strfromf128): New declaration.
    	* stdlib/strfrom-skeleton.c (STRFROM): Set member info.is_binary128
    	to one.
    	* sysdeps/ieee754/float128/Makefile: Add strfromf128.
    	* sysdeps/ieee754/float128/Versions: Likewise.
    	* sysdeps/ieee754/float128/strfromf128.c: New file.

diff --git a/ChangeLog b/ChangeLog
index 9d033b5..88483ae 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,29 @@
 2017-06-07  Gabriel F. T. Gomes  <gftg@linux.vnet.ibm.com>
 
+	* stdio-common/printf-parsemb.c (__parse_one_specmb): Initialize
+	spec->info.is_binary128 to zero.
+	* stdio-common/printf.h (printf_info): Add new member is_binary128
+	to indicate that the number being converted to string is compatible
+	with the IEC 60559 binary128 format.
+	* stdio-common/printf_fp.c (__printf_fp_l): Add code to deal with
+	_Float128 numbers.
+	* stdio-common/printf_fphex.c: Include ieee754_float128.h and
+	ldbl-128/printf_fphex_macros.h
+	(__printf_fphex): Add code to deal with _Float128 numbers.
+	* stdio-common/printf_size.c (__printf_size): Likewise.
+	* stdio-common/vfprintf.c (process_arg): Initialize member
+	info.is_binary128 to zero.
+	* stdlib/fpioconst.h (FLT128_MAX_10_EXP_LOG): New macro.
+	* stdlib/stdlib.h: Include bits/floatn.h for _Float128 support.
+	(strfromf128): New declaration.
+	* stdlib/strfrom-skeleton.c (STRFROM): Set member info.is_binary128
+	to one.
+	* sysdeps/ieee754/float128/Makefile: Add strfromf128.
+	* sysdeps/ieee754/float128/Versions: Likewise.
+	* sysdeps/ieee754/float128/strfromf128.c: New file.
+
+2017-06-07  Gabriel F. T. Gomes  <gftg@linux.vnet.ibm.com>
+
 	* sysdeps/ieee754/ldbl-128/printf_fphex.c: Include
 	ldbl-128/printf_fphex_macros.h for the definition of PRINT_FPHEX.
 	(PRINT_FPHEX_LONG_DOUBLE): Define based on PRINT_FPHEX.
diff --git a/stdio-common/printf-parsemb.c b/stdio-common/printf-parsemb.c
index edb066e..a42336c 100644
--- a/stdio-common/printf-parsemb.c
+++ b/stdio-common/printf-parsemb.c
@@ -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))
diff --git a/stdio-common/printf.h b/stdio-common/printf.h
index 5d82e8d..6b207d2 100644
--- a/stdio-common/printf.h
+++ b/stdio-common/printf.h
@@ -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.  */
 };
diff --git a/stdio-common/printf_fp.c b/stdio-common/printf_fp.c
index 65ee9a7..514b698 100644
--- a/stdio-common/printf_fp.c
+++ b/stdio-common/printf_fp.c
@@ -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;
 
@@ -371,6 +382,11 @@ __printf_fp_l (FILE *fp, locale_t loc,
   }
 
   /* Fetch the argument value.	*/
+#if __HAVE_DISTINCT_FLOAT128
+  if (info->is_binary128)
+    PRINTF_FP_FETCH (_Float128, fpnum.f128, float128, FLT128_MANT_DIG)
+  else
+#endif
 #ifndef __NO_LONG_DOUBLE_MATH
   if (info->is_long_double && sizeof (long double) > sizeof (double))
     PRINTF_FP_FETCH (long double, fpnum.ldbl, long_double, LDBL_MANT_DIG)
@@ -414,7 +430,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);
@@ -429,7 +446,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 = FLT128_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;
@@ -463,6 +488,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)
@@ -603,7 +649,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 = FLT128_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.	*/
diff --git a/stdio-common/printf_fphex.c b/stdio-common/printf_fphex.c
index 7b469c0..004d2aa 100644
--- a/stdio-common/printf_fphex.c
+++ b/stdio-common/printf_fphex.c
@@ -31,6 +31,14 @@
 #include <stdbool.h>
 #include <rounding-mode.h>
 
+#if __HAVE_DISTINCT_FLOAT128
+# include "ieee754_float128.h"
+# include <ldbl-128/printf_fphex_macros.h>
+# define PRINT_FPHEX_FLOAT128 \
+   PRINT_FPHEX (_Float128, fpnum.flt128, ieee854_float128, \
+		IEEE854_FLOAT128_BIAS)
+#endif
+
 /* #define NDEBUG 1*/		/* Undefine this for debugging assertions.  */
 #include <assert.h>
 
@@ -94,6 +102,9 @@ __printf_fphex (FILE *fp,
     {
       union ieee754_double dbl;
       long double ldbl;
+#if __HAVE_DISTINCT_FLOAT128
+      _Float128 flt128;
+#endif
     }
   fpnum;
 
@@ -195,6 +206,11 @@ __printf_fphex (FILE *fp,
   }
 
   /* Fetch the argument value.	*/
+#if __HAVE_DISTINCT_FLOAT128
+  if (info->is_binary128)
+    PRINTF_FPHEX_FETCH (_Float128, fpnum.flt128)
+  else
+#endif
 #ifndef __NO_LONG_DOUBLE_MATH
   if (info->is_long_double && sizeof (long double) > sizeof (double))
     PRINTF_FPHEX_FETCH (long double, fpnum.ldbl)
@@ -230,6 +246,11 @@ __printf_fphex (FILE *fp,
       return done;
     }
 
+#if __HAVE_DISTINCT_FLOAT128
+  if (info->is_binary128)
+    PRINT_FPHEX_FLOAT128;
+  else
+#endif
   if (info->is_long_double == 0 || sizeof (double) == sizeof (long double))
     {
       /* We have 52 bits of mantissa plus one implicit digit.  Since
diff --git a/stdio-common/printf_size.c b/stdio-common/printf_size.c
index bc953dc..e20b76c 100644
--- a/stdio-common/printf_size.c
+++ b/stdio-common/printf_size.c
@@ -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;
@@ -144,6 +147,11 @@ __printf_size (FILE *fp, const struct printf_info *info,
   }
 
   /* Fetch the argument value.	*/
+#if __HAVE_DISTINCT_FLOAT128
+  if (info->is_binary128)
+    PRINTF_SIZE_FETCH (_Float128, fpnum.f128)
+  else
+#endif
 #ifndef __NO_LONG_DOUBLE_MATH
   if (info->is_long_double && sizeof (long double) > sizeof (double))
     PRINTF_SIZE_FETCH (long double, fpnum.ldbl)
diff --git a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c
index 2cf7c8a..b8c87a5 100644
--- a/stdio-common/vfprintf.c
+++ b/stdio-common/vfprintf.c
@@ -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);	      \
 	  }								      \
diff --git a/stdlib/fpioconst.h b/stdlib/fpioconst.h
index 2559d7a..c05f8e7 100644
--- a/stdlib/fpioconst.h
+++ b/stdlib/fpioconst.h
@@ -44,6 +44,10 @@
    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)).  When _Float128 is enabled in libm and it is
    ABI-distinct from long double (e.g. on powerpc64le), we also need powers
diff --git a/stdlib/stdlib.h b/stdlib/stdlib.h
index 428ca2e..0a693c2 100644
--- a/stdlib/stdlib.h
+++ b/stdlib/stdlib.h
@@ -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
   {
@@ -175,6 +178,12 @@ extern int strfroml (char *__dest, size_t __size, const char *__format,
      __THROW __nonnull ((3));
 #endif
 
+#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
+
 
 #ifdef __USE_GNU
 /* The concept of one static locale per category is not very well
diff --git a/stdlib/strfrom-skeleton.c b/stdlib/strfrom-skeleton.c
index 811a29c..5841919 100644
--- a/stdlib/strfrom-skeleton.c
+++ b/stdlib/strfrom-skeleton.c
@@ -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;
diff --git a/sysdeps/ieee754/float128/Makefile b/sysdeps/ieee754/float128/Makefile
index 6a7b0e0..c07586c 100644
--- a/sysdeps/ieee754/float128/Makefile
+++ b/sysdeps/ieee754/float128/Makefile
@@ -1,3 +1,3 @@
 ifeq ($(subdir),stdlib)
-routines += float1282mpn
+routines += float1282mpn strfromf128
 endif
diff --git a/sysdeps/ieee754/float128/Versions b/sysdeps/ieee754/float128/Versions
index 9f431d9..caf2064 100644
--- a/sysdeps/ieee754/float128/Versions
+++ b/sysdeps/ieee754/float128/Versions
@@ -2,6 +2,11 @@
 %ifndef FLOAT128_VERSION
 % error "float128-abi.h must define FLOAT128_VERSION"
 %endif
+libc {
+  FLOAT128_VERSION {
+    strfromf128;
+  }
+}
 libm {
   FLOAT128_VERSION {
     __acosf128_finite;
diff --git a/sysdeps/ieee754/float128/strfromf128.c b/sysdeps/ieee754/float128/strfromf128.c
new file mode 100644
index 0000000..597c7e6
--- /dev/null
+++ b/sysdeps/ieee754/float128/strfromf128.c
@@ -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>

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=2bc646c9e95b7c0005b2bc09c06671ffbb509629

commit 2bc646c9e95b7c0005b2bc09c06671ffbb509629
Author: Gabriel F. T. Gomes <gftg@linux.vnet.ibm.com>
Date:   Fri Jun 2 16:03:40 2017 -0300

    Refactor PRINT_FPHEX_LONG_DOUBLE into a reusable macro
    
    This patch refactors the macro PRINT_FPHEX_LONG_DOUBLE from the file
    sysdeps/ieee754/ldbl-128/printf_fphex.c into a function-like macro to
    enable its use for both long double and _Float128, when they are
    ABI-distinct.
    
    	* sysdeps/ieee754/ldbl-128/printf_fphex.c: Include
    	ldbl-128/printf_fphex_macros.h for the definition of PRINT_FPHEX.
    	(PRINT_FPHEX_LONG_DOUBLE): Define based on PRINT_FPHEX.
    	* sysdeps/ieee754/ldbl-128/printf_fphex_macros.h
    	(PRINT_FPHEX): New function-like macro that can be used for long
    	double, as well as for _Float128

diff --git a/ChangeLog b/ChangeLog
index 429fe41..9d033b5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
 2017-06-07  Gabriel F. T. Gomes  <gftg@linux.vnet.ibm.com>
 
+	* sysdeps/ieee754/ldbl-128/printf_fphex.c: Include
+	ldbl-128/printf_fphex_macros.h for the definition of PRINT_FPHEX.
+	(PRINT_FPHEX_LONG_DOUBLE): Define based on PRINT_FPHEX.
+	* sysdeps/ieee754/ldbl-128/printf_fphex_macros.h
+	(PRINT_FPHEX): New function-like macro that can be used for long
+	double, as well as for _Float128
+
+2017-06-07  Gabriel F. T. Gomes  <gftg@linux.vnet.ibm.com>
+
 	* stdio-common/printf_fp.c (PRINTF_FP_FETCH): New macro.
 	(__printf_fp_l): Use the new macro to avoid duplicating code.
 	* stdio-common/printf_fphex.c (PRINTF_FPHEX_FETCH): New macro.
diff --git a/sysdeps/ieee754/ldbl-128/printf_fphex.c b/sysdeps/ieee754/ldbl-128/printf_fphex.c
index d9eaf8d..294464e 100644
--- a/sysdeps/ieee754/ldbl-128/printf_fphex.c
+++ b/sysdeps/ieee754/ldbl-128/printf_fphex.c
@@ -17,91 +17,9 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#include <ldbl-128/printf_fphex_macros.h>
 #define PRINT_FPHEX_LONG_DOUBLE \
-do {									      \
-      /* 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_long_double u;					      \
-      u.d = fpnum.ldbl;							      \
-									      \
-      assert (sizeof (long double) == 16);				      \
-									      \
-      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_LONG_DOUBLE_BIAS - 1;			      \
-	    }								      \
-	}								      \
-      else if (exponent >= IEEE854_LONG_DOUBLE_BIAS)			      \
-	{								      \
-	  expnegative = 0;						      \
-	  exponent -= IEEE854_LONG_DOUBLE_BIAS;				      \
-	}								      \
-      else								      \
-	{								      \
-	  expnegative = 1;						      \
-	  exponent = -(exponent - IEEE854_LONG_DOUBLE_BIAS);		      \
-	}								      \
-} while (0)
+  PRINT_FPHEX (long double, fpnum.ldbl, ieee854_long_double, \
+	       IEEE854_LONG_DOUBLE_BIAS)
 
 #include <stdio-common/printf_fphex.c>
diff --git a/sysdeps/ieee754/ldbl-128/printf_fphex.c b/sysdeps/ieee754/ldbl-128/printf_fphex_macros.h
similarity index 85%
copy from sysdeps/ieee754/ldbl-128/printf_fphex.c
copy to sysdeps/ieee754/ldbl-128/printf_fphex_macros.h
index d9eaf8d..86681c4 100644
--- a/sysdeps/ieee754/ldbl-128/printf_fphex.c
+++ b/sysdeps/ieee754/ldbl-128/printf_fphex_macros.h
@@ -1,6 +1,5 @@
-/* Print floating point number in hexadecimal notation according to
-   ISO C99.
-   Copyright (C) 1997-2017 Free Software Foundation, Inc.
+/* Macro to print floating point numbers in hexadecimal notation.
+   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
@@ -17,17 +16,17 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#define PRINT_FPHEX_LONG_DOUBLE \
+#define PRINT_FPHEX(FLOAT, VAR, IEEE854_UNION, IEEE854_BIAS)		      \
 do {									      \
       /* 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_long_double u;					      \
-      u.d = fpnum.ldbl;							      \
+      union IEEE854_UNION u;						      \
+      u.d = VAR;							      \
 									      \
-      assert (sizeof (long double) == 16);				      \
+      assert (sizeof (FLOAT) == 16);					      \
 									      \
       num0 = (((unsigned long long int) u.ieee.mantissa0) << 32		      \
 	     | u.ieee.mantissa1);					      \
@@ -89,19 +88,17 @@ do {									      \
 	    {								      \
 	      /* This is a denormalized number.  */			      \
 	      expnegative = 1;						      \
-	      exponent = IEEE854_LONG_DOUBLE_BIAS - 1;			      \
+	      exponent = IEEE854_BIAS - 1;				      \
 	    }								      \
 	}								      \
-      else if (exponent >= IEEE854_LONG_DOUBLE_BIAS)			      \
+      else if (exponent >= IEEE854_BIAS)				      \
 	{								      \
 	  expnegative = 0;						      \
-	  exponent -= IEEE854_LONG_DOUBLE_BIAS;				      \
+	  exponent -= IEEE854_BIAS;					      \
 	}								      \
       else								      \
 	{								      \
 	  expnegative = 1;						      \
-	  exponent = -(exponent - IEEE854_LONG_DOUBLE_BIAS);		      \
+	  exponent = -(exponent - IEEE854_BIAS);			      \
 	}								      \
 } while (0)
-
-#include <stdio-common/printf_fphex.c>

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=aab0f374e7c43f6baf88db271865feabb7bcc1b2

commit aab0f374e7c43f6baf88db271865feabb7bcc1b2
Author: Gabriel F. T. Gomes <gftg@linux.vnet.ibm.com>
Date:   Mon May 29 10:49:42 2017 -0300

    Remove duplicated code from __printf_fp_l, __printf_fphex, and __printf_size
    
    In __printf_fp_l, __printf_fphex, and __printf_size the blocks of code that are
    used to read a double or long double argument, check for special values and
    convert to multiprecision are similar.  When adding float128 support to libc,
    more code would be duplicated to deal with the extra type.  This patch moves
    the repetitive code to a macro which is now used by double and long double and
    will be used for float128 when support is added, thus avoiding more
    duplication.
    
    Tested for powerpc64le and s390x.
    
    	* stdio-common/printf_fp.c (PRINTF_FP_FETCH): New macro.
    	(__printf_fp_l): Use the new macro to avoid duplicating code.
    	* stdio-common/printf_fphex.c (PRINTF_FPHEX_FETCH): New macro.
    	(__printf_fphex): Use the new macro to avoid duplicating code.
    	* stdio-common/printf_size.c (PRINTF_SIZE_FETCH): New macro.
    	(__printf_size): Use the new macro to avoid duplicating code.

diff --git a/ChangeLog b/ChangeLog
index 0b75c87..429fe41 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
 2017-06-07  Gabriel F. T. Gomes  <gftg@linux.vnet.ibm.com>
 
+	* stdio-common/printf_fp.c (PRINTF_FP_FETCH): New macro.
+	(__printf_fp_l): Use the new macro to avoid duplicating code.
+	* stdio-common/printf_fphex.c (PRINTF_FPHEX_FETCH): New macro.
+	(__printf_fphex): Use the new macro to avoid duplicating code.
+	* stdio-common/printf_size.c (PRINTF_SIZE_FETCH): New macro.
+	(__printf_size): Use the new macro to avoid duplicating code.
+
+2017-06-07  Gabriel F. T. Gomes  <gftg@linux.vnet.ibm.com>
+
 	* include/gmp.h: Include bits/floatn.h
 	(__mpn_extract_float128): Declare when __HAVE_DISTINCT_FLOAT128 is 1.
 	* stdlib/gmp-impl.h: Also check if alloca is not defined before
diff --git a/stdio-common/printf_fp.c b/stdio-common/printf_fp.c
index 7845d96..65ee9a7 100644
--- a/stdio-common/printf_fp.c
+++ b/stdio-common/printf_fp.c
@@ -327,94 +327,58 @@ __printf_fp_l (FILE *fp, locale_t loc,
   else
     grouping = NULL;
 
+#define PRINTF_FP_FETCH(FLOAT, VAR, SUFFIX, MANT_DIG)			\
+  {									\
+    (VAR) = *(const FLOAT *) args[0];					\
+									\
+    /* Check for special values: not a number or infinity.  */		\
+    if (isnan (VAR))							\
+      {									\
+	is_neg = signbit (VAR);						\
+	if (isupper (info->spec))					\
+	  {								\
+	    special = "NAN";						\
+	    wspecial = L"NAN";						\
+	  }								\
+	else								\
+	  {								\
+	    special = "nan";						\
+	    wspecial = L"nan";						\
+	  }								\
+      }									\
+    else if (isinf (VAR))						\
+      {									\
+	is_neg = signbit (VAR);						\
+	if (isupper (info->spec))					\
+	  {								\
+	    special = "INF";						\
+	    wspecial = L"INF";						\
+	  }								\
+	else								\
+	  {								\
+	    special = "inf";						\
+	    wspecial = L"inf";						\
+	  }								\
+      }									\
+    else								\
+      {									\
+	p.fracsize = __mpn_extract_##SUFFIX				\
+		     (fp_input,						\
+		      (sizeof (fp_input) / sizeof (fp_input[0])),	\
+		      &p.exponent, &is_neg, VAR);			\
+	to_shift = 1 + p.fracsize * BITS_PER_MP_LIMB - MANT_DIG;	\
+      }									\
+  }
+
   /* Fetch the argument value.	*/
 #ifndef __NO_LONG_DOUBLE_MATH
   if (info->is_long_double && sizeof (long double) > sizeof (double))
-    {
-      fpnum.ldbl = *(const long double *) args[0];
-
-      /* Check for special values: not a number or infinity.  */
-      if (isnan (fpnum.ldbl))
-	{
-	  is_neg = signbit (fpnum.ldbl);
-	  if (isupper (info->spec))
-	    {
-	      special = "NAN";
-	      wspecial = L"NAN";
-	    }
-	    else
-	      {
-		special = "nan";
-		wspecial = L"nan";
-	      }
-	}
-      else if (isinf (fpnum.ldbl))
-	{
-	  is_neg = signbit (fpnum.ldbl);
-	  if (isupper (info->spec))
-	    {
-	      special = "INF";
-	      wspecial = L"INF";
-	    }
-	  else
-	    {
-	      special = "inf";
-	      wspecial = L"inf";
-	    }
-	}
-      else
-	{
-	  p.fracsize = __mpn_extract_long_double (fp_input,
-						(sizeof (fp_input) /
-						 sizeof (fp_input[0])),
-						&p.exponent, &is_neg,
-						fpnum.ldbl);
-	  to_shift = 1 + p.fracsize * BITS_PER_MP_LIMB - LDBL_MANT_DIG;
-	}
-    }
+    PRINTF_FP_FETCH (long double, fpnum.ldbl, long_double, LDBL_MANT_DIG)
   else
-#endif	/* no long double */
-    {
-      fpnum.dbl = *(const double *) args[0];
+#endif
+    PRINTF_FP_FETCH (double, fpnum.dbl, double, DBL_MANT_DIG)
 
-      /* Check for special values: not a number or infinity.  */
-      if (isnan (fpnum.dbl))
-	{
-	  is_neg = signbit (fpnum.dbl);
-	  if (isupper (info->spec))
-	    {
-	      special = "NAN";
-	      wspecial = L"NAN";
-	    }
-	  else
-	    {
-	      special = "nan";
-	      wspecial = L"nan";
-	    }
-	}
-      else if (isinf (fpnum.dbl))
-	{
-	  is_neg = signbit (fpnum.dbl);
-	  if (isupper (info->spec))
-	    {
-	      special = "INF";
-	      wspecial = L"INF";
-	    }
-	  else
-	    {
-	      special = "inf";
-	      wspecial = L"inf";
-	    }
-	}
-      else
-	{
-	  p.fracsize = __mpn_extract_double (fp_input,
-					   (sizeof (fp_input)
-					    / sizeof (fp_input[0])),
-					   &p.exponent, &is_neg, fpnum.dbl);
-	  to_shift = 1 + p.fracsize * BITS_PER_MP_LIMB - DBL_MANT_DIG;
-	}
-    }
+#undef PRINTF_FP_FETCH
 
   if (special)
     {
diff --git a/stdio-common/printf_fphex.c b/stdio-common/printf_fphex.c
index b207e00..7b469c0 100644
--- a/stdio-common/printf_fphex.c
+++ b/stdio-common/printf_fphex.c
@@ -157,82 +157,52 @@ __printf_fphex (FILE *fp,
   /* The decimal point character must never be zero.  */
   assert (*decimal != '\0' && decimalwc != L'\0');
 
+#define PRINTF_FPHEX_FETCH(FLOAT, VAR)					\
+  {									\
+    (VAR) = *(const FLOAT *) args[0];					\
+									\
+    /* Check for special values: not a number or infinity.  */		\
+    if (isnan (VAR))							\
+      {									\
+	if (isupper (info->spec))					\
+	  {								\
+	    special = "NAN";						\
+	    wspecial = L"NAN";						\
+	  }								\
+	else								\
+	  {								\
+	    special = "nan";						\
+	    wspecial = L"nan";						\
+	  }								\
+      }									\
+    else								\
+      {									\
+	if (isinf (VAR))						\
+	  {								\
+	    if (isupper (info->spec))					\
+	      {								\
+		special = "INF";					\
+		wspecial = L"INF";					\
+	      }								\
+	    else							\
+	      {								\
+		special = "inf";					\
+		wspecial = L"inf";					\
+	      }								\
+	  }								\
+      }									\
+    negative = signbit (VAR);						\
+  }
 
   /* Fetch the argument value.	*/
 #ifndef __NO_LONG_DOUBLE_MATH
   if (info->is_long_double && sizeof (long double) > sizeof (double))
-    {
-      fpnum.ldbl = *(const long double *) args[0];
-
-      /* Check for special values: not a number or infinity.  */
-      if (isnan (fpnum.ldbl))
-	{
-	  if (isupper (info->spec))
-	    {
-	      special = "NAN";
-	      wspecial = L"NAN";
-	    }
-	  else
-	    {
-	      special = "nan";
-	      wspecial = L"nan";
-	    }
-	}
-      else
-	{
-	  if (isinf (fpnum.ldbl))
-	    {
-	      if (isupper (info->spec))
-		{
-		  special = "INF";
-		  wspecial = L"INF";
-		}
-	      else
-		{
-		  special = "inf";
-		  wspecial = L"inf";
-		}
-	    }
-	}
-      negative = signbit (fpnum.ldbl);
-    }
+    PRINTF_FPHEX_FETCH (long double, fpnum.ldbl)
   else
-#endif	/* no long double */
-    {
-      fpnum.dbl.d = *(const double *) args[0];
+#endif
+    PRINTF_FPHEX_FETCH (double, fpnum.dbl.d)
 
-      /* Check for special values: not a number or infinity.  */
-      if (isnan (fpnum.dbl.d))
-	{
-	  if (isupper (info->spec))
-	    {
-	      special = "NAN";
-	      wspecial = L"NAN";
-	    }
-	  else
-	    {
-	      special = "nan";
-	      wspecial = L"nan";
-	    }
-	}
-      else
-	{
-	  if (isinf (fpnum.dbl.d))
-	    {
-	      if (isupper (info->spec))
-		{
-		  special = "INF";
-		  wspecial = L"INF";
-		}
-	      else
-		{
-		  special = "inf";
-		  wspecial = L"inf";
-		}
-	    }
-	}
-      negative = signbit (fpnum.dbl.d);
-    }
+#undef PRINTF_FPHEX_FETCH
 
   if (special)
     {
diff --git a/stdio-common/printf_size.c b/stdio-common/printf_size.c
index 9403aea..bc953dc 100644
--- a/stdio-common/printf_size.c
+++ b/stdio-common/printf_size.c
@@ -118,57 +118,40 @@ __printf_size (FILE *fp, const struct printf_info *info,
   int done = 0;
   int wide = info->wide;
 
+#define PRINTF_SIZE_FETCH(FLOAT, VAR)					\
+  {									\
+    (VAR) = *(const FLOAT *) args[0];					\
+									\
+    /* Check for special values: not a number or infinity.  */		\
+    if (isnan (VAR))							\
+      {									\
+	special = "nan";						\
+	wspecial = L"nan";						\
+	/* is_neg = 0; Already zero */					\
+      }									\
+    else if (isinf (VAR))						\
+      {									\
+	is_neg = signbit (VAR);						\
+	special = "inf";						\
+	wspecial = L"inf";						\
+      }									\
+    else								\
+      while ((VAR) >= divisor && tag[1] != '\0')			\
+	{								\
+	  (VAR) /= divisor;						\
+	  ++tag;							\
+	}								\
+  }
+
   /* Fetch the argument value.	*/
 #ifndef __NO_LONG_DOUBLE_MATH
   if (info->is_long_double && sizeof (long double) > sizeof (double))
-    {
-      fpnum.ldbl = *(const long double *) args[0];
-
-      /* Check for special values: not a number or infinity.  */
-      if (isnan (fpnum.ldbl))
-	{
-	  special = "nan";
-	  wspecial = L"nan";
-	  // is_neg = 0;	Already zero
-	}
-      else if (isinf (fpnum.ldbl))
-	{
-	  is_neg = signbit (fpnum.ldbl);
-	  special = "inf";
-	  wspecial = L"inf";
-	}
-      else
-	while (fpnum.ldbl >= divisor && tag[1] != '\0')
-	  {
-	    fpnum.ldbl /= divisor;
-	    ++tag;
-	  }
-    }
+    PRINTF_SIZE_FETCH (long double, fpnum.ldbl)
   else
-#endif	/* no long double */
-    {
-      fpnum.dbl.d = *(const double *) args[0];
+#endif
+    PRINTF_SIZE_FETCH (double, fpnum.dbl.d)
 
-      /* Check for special values: not a number or infinity.  */
-      if (isnan (fpnum.dbl.d))
-	{
-	  special = "nan";
-	  wspecial = L"nan";
-	  // is_neg = 0;	Already zero
-	}
-      else if (isinf (fpnum.dbl.d))
-	{
-	  is_neg = signbit (fpnum.dbl.d);
-	  special = "inf";
-	  wspecial = L"inf";
-	}
-      else
-	while (fpnum.dbl.d >= divisor && tag[1] != '\0')
-	  {
-	    fpnum.dbl.d /= divisor;
-	    ++tag;
-	  }
-    }
+#undef PRINTF_SIZE_FETCH
 
   if (special)
     {

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=32bf1d09dadee5b60df869ed3567a2b12c04e3fc

commit 32bf1d09dadee5b60df869ed3567a2b12c04e3fc
Author: Gabriel F. T. Gomes <gftg@linux.vnet.ibm.com>
Date:   Thu Nov 3 12:26:52 2016 -0200

    float128: Add conversion from float128 to mpn
    
    Reuse the code for __mpn_extract_long_double to implement
    __mpn_extract_float128.
    
    	* include/gmp.h: Include bits/floatn.h
    	(__mpn_extract_float128): Declare when __HAVE_DISTINCT_FLOAT128 is 1.
    	* stdlib/gmp-impl.h: Also check if alloca is not defined before
    	including stack-alloc.h.  It could have been defined by other header
    	which not necessarily defines HAVE_ALLOCA.
    	* sysdeps/ieee754/float128/Makefile: New file.
    	* sysdeps/ieee754/float128/float1282mpn.c: New file.
    	* sysdeps/ieee754/float128/float128_private.h: Include gmp.h before
    	redefining __mpn_extract_long_double to __mpn_extract_float128, then
    	redefine __mpn_extract_long_double to __mpn_extract_float128.
    	* sysdeps/ieee754/ldbl-128/ldbl2mpn.c: Replace long double with
    	_Float128 to allow float128_private.h overrides.

diff --git a/ChangeLog b/ChangeLog
index 742e492..0b75c87 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2017-06-07  Gabriel F. T. Gomes  <gftg@linux.vnet.ibm.com>
+
+	* include/gmp.h: Include bits/floatn.h
+	(__mpn_extract_float128): Declare when __HAVE_DISTINCT_FLOAT128 is 1.
+	* stdlib/gmp-impl.h: Also check if alloca is not defined before
+	including stack-alloc.h.  It could have been defined by other header
+	which not necessarily defines HAVE_ALLOCA.
+	* sysdeps/ieee754/float128/Makefile: New file.
+	* sysdeps/ieee754/float128/float1282mpn.c: New file.
+	* sysdeps/ieee754/float128/float128_private.h: Include gmp.h before
+	redefining __mpn_extract_long_double to __mpn_extract_float128, then
+	redefine __mpn_extract_long_double to __mpn_extract_float128.
+	* sysdeps/ieee754/ldbl-128/ldbl2mpn.c: Replace long double with
+	_Float128 to allow float128_private.h overrides.
+
 2017-06-07  Paul E. Murphy  <murphyp@linux.vnet.ibm.com>
 
 	* stdlib/fpioconst.h: Include bits/floatn.h.
diff --git a/include/gmp.h b/include/gmp.h
index b741670..e6f635e 100644
--- a/include/gmp.h
+++ b/include/gmp.h
@@ -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,
diff --git a/stdlib/gmp-impl.h b/stdlib/gmp-impl.h
index 89693c4..42d3e4a 100644
--- a/stdlib/gmp-impl.h
+++ b/stdlib/gmp-impl.h
@@ -47,7 +47,8 @@ along with the GNU MP Library; see the file COPYING.LIB.  If not, see
 #endif
 #endif
 
-#if ! defined (HAVE_ALLOCA) || defined (USE_STACK_ALLOC)
+#if (! defined (alloca) && ! defined (HAVE_ALLOCA)) \
+    || defined (USE_STACK_ALLOC)
 #include "stack-alloc.h"
 #else
 #define TMP_DECL(m)
diff --git a/sysdeps/ieee754/float128/Makefile b/sysdeps/ieee754/float128/Makefile
new file mode 100644
index 0000000..6a7b0e0
--- /dev/null
+++ b/sysdeps/ieee754/float128/Makefile
@@ -0,0 +1,3 @@
+ifeq ($(subdir),stdlib)
+routines += float1282mpn
+endif
diff --git a/sysdeps/ieee754/float128/float1282mpn.c b/sysdeps/ieee754/float128/float1282mpn.c
new file mode 100644
index 0000000..f012ccf
--- /dev/null
+++ b/sysdeps/ieee754/float128/float1282mpn.c
@@ -0,0 +1,20 @@
+/* Convert a _Float128 type to multiprecision.
+   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 <float128_private.h>
+#include "../ldbl-128/ldbl2mpn.c"
diff --git a/sysdeps/ieee754/float128/float128_private.h b/sysdeps/ieee754/float128/float128_private.h
index 894e6ac..1e00853 100644
--- a/sysdeps/ieee754/float128/float128_private.h
+++ b/sysdeps/ieee754/float128/float128_private.h
@@ -17,6 +17,7 @@
    <http://www.gnu.org/licenses/>.  */
 
 /* This must be included before the function renames below.  */
+#include <gmp.h>
 #include <math.h>
 #undef HUGE_VALL
 #define HUGE_VALL HUGE_VAL_F128
@@ -291,6 +292,7 @@
 #define __kernel_tanl __kernel_tanf128
 #define __lgamma_negl __lgamma_negf128
 #define __lgamma_productl __lgamma_productf128
+#define __mpn_extract_long_double __mpn_extract_float128
 #define __sincosl_table __sincosf128_table
 #define mul_splitl mul_splitf128
 
diff --git a/sysdeps/ieee754/ldbl-128/ldbl2mpn.c b/sysdeps/ieee754/ldbl-128/ldbl2mpn.c
index 71a6f04..1c79a5d 100644
--- a/sysdeps/ieee754/ldbl-128/ldbl2mpn.c
+++ b/sysdeps/ieee754/ldbl-128/ldbl2mpn.c
@@ -21,6 +21,7 @@
 #include <ieee754.h>
 #include <float.h>
 #include <math.h>
+#include <math_private.h>
 #include <stdlib.h>
 
 /* Convert a `long double' in IEEE854 quad-precision format to a
@@ -31,7 +32,7 @@
 mp_size_t
 __mpn_extract_long_double (mp_ptr res_ptr, mp_size_t size,
 			   int *expt, int *is_neg,
-			   long double value)
+			   _Float128 value)
 {
   union ieee854_long_double u;
   u.d = value;

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=82c19bdfe39164fda779c79a925c2050b19e421b

commit 82c19bdfe39164fda779c79a925c2050b19e421b
Author: Paul E. Murphy <murphyp@linux.vnet.ibm.com>
Date:   Fri Nov 4 09:57:27 2016 -0200

    float128: Extend the power of ten tables
    
    Update the power of ten tables used by the common implementation when long
    double is not the most expressive real type.
    
    	* stdlib/fpioconst.h: Include bits/floatn.h.
    	(FPIOCONST_HAVE_EXTENDED_RANGE): New macro for testing how big the
    	power of ten table should be.
    	(FPIOCONST_POW10_ARRAY_SIZE): Use larger table if above is true.
    	* stdlib/fpioconst.c (__tens): Use FPIOCONST_HAVE_EXTENDED_RANGE
    	to include larger tables when _Float128 support is enabled.
    	(_fpioconst_pow10): Likewise.

diff --git a/ChangeLog b/ChangeLog
index e571155..742e492 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2017-06-07  Paul E. Murphy  <murphyp@linux.vnet.ibm.com>
+
+	* stdlib/fpioconst.h: Include bits/floatn.h.
+	(FPIOCONST_HAVE_EXTENDED_RANGE): New macro for testing how big the
+	power of ten table should be.
+	(FPIOCONST_POW10_ARRAY_SIZE): Use larger table if above is true.
+	* stdlib/fpioconst.c (__tens): Use FPIOCONST_HAVE_EXTENDED_RANGE
+	to include larger tables when _Float128 support is enabled.
+	(_fpioconst_pow10): Likewise.
+
 2017-06-07  Joseph Myers  <joseph@codesourcery.com>
 
 	* include/bits/types/clock_t.h: Use #include <path> instead of
diff --git a/stdlib/fpioconst.c b/stdlib/fpioconst.c
index 7db7fa4..a0563b9 100644
--- a/stdlib/fpioconst.c
+++ b/stdlib/fpioconst.c
@@ -112,7 +112,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 FPIOCONST_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 +659,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	/* FPIOCONST_HAVE_EXTENDED_RANGE */
 };
 
 #elif BITS_PER_MP_LIMB == 64
@@ -748,7 +748,7 @@ const mp_limb_t __tens[] =
   0xd2db49ef47187094ull, 0xae6209d4926c3f5bull, 0x34f4a3c62d433949ull,
   0xd9d61a05d4305d94ull, 0x0000000000000325ull,
 
-#if !defined __NO_LONG_DOUBLE_MATH && __LDBL_MAX_EXP__ > 1024
+#if FPIOCONST_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 +1320,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 FPIOCONST_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 },
diff --git a/stdlib/fpioconst.h b/stdlib/fpioconst.h
index 6fc476b..2559d7a 100644
--- a/stdlib/fpioconst.h
+++ b/stdlib/fpioconst.h
@@ -40,9 +40,19 @@
 #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>
+
 /* 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)).  */
+#define FPIOCONST_HAVE_EXTENDED_RANGE \
+  ((!defined __NO_LONG_DOUBLE_MATH && __LDBL_MAX_EXP__ > 1024) \
+   || __HAVE_DISTINCT_FLOAT128)
+
+#if FPIOCONST_HAVE_EXTENDED_RANGE
 # define FPIOCONST_POW10_ARRAY_SIZE	15
 #else
 # define FPIOCONST_POW10_ARRAY_SIZE	11

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                                      |   67 ++++++++
 include/gmp.h                                  |    8 +
 stdio-common/printf-parsemb.c                  |    1 +
 stdio-common/printf.h                          |    4 +-
 stdio-common/printf_fp.c                       |  192 +++++++++++++-----------
 stdio-common/printf_fphex.c                    |  131 ++++++++---------
 stdio-common/printf_size.c                     |   85 +++++------
 stdio-common/vfprintf.c                        |   10 +-
 stdlib/fpioconst.c                             |    8 +-
 stdlib/fpioconst.h                             |   18 ++-
 stdlib/gmp-impl.h                              |    3 +-
 stdlib/stdlib.h                                |    9 +
 stdlib/strfrom-skeleton.c                      |    6 +
 sysdeps/ieee754/float128/Makefile              |    3 +
 sysdeps/ieee754/float128/Versions              |    5 +
 sysdeps/ieee754/float128/float1282mpn.c        |   20 +++
 sysdeps/ieee754/float128/float128_private.h    |    2 +
 sysdeps/ieee754/float128/strfromf128.c         |   25 +++
 sysdeps/ieee754/ldbl-128/ldbl2mpn.c            |    3 +-
 sysdeps/ieee754/ldbl-128/printf_fphex.c        |   88 +-----------
 sysdeps/ieee754/ldbl-128/printf_fphex_macros.h |  104 +++++++++++++
 21 files changed, 492 insertions(+), 300 deletions(-)
 create mode 100644 sysdeps/ieee754/float128/Makefile
 create mode 100644 sysdeps/ieee754/float128/float1282mpn.c
 create mode 100644 sysdeps/ieee754/float128/strfromf128.c
 create mode 100644 sysdeps/ieee754/ldbl-128/printf_fphex_macros.h


hooks/post-receive
-- 
GNU C Library master sources


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