public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] PowerPC: Add float128/Decimal conversions.
@ 2021-01-14 17:09 Michael Meissner
  2021-01-15 21:52 ` Segher Boessenkool
                   ` (2 more replies)
  0 siblings, 3 replies; 17+ messages in thread
From: Michael Meissner @ 2021-01-14 17:09 UTC (permalink / raw)
  To: gcc-patches, Michael Meissner, Segher Boessenkool,
	David Edelsohn, Bill Schmidt, Peter Bergner

[PATCH] PowerPC: Add float128/Decimal conversions.

This patch replaces the following two patches:

September 24th, 2020:
Message-ID: <20200924203545.GD31597@ibm-toto.the-meissners.org>

October 22nd, 2020:
Message-ID: <20201022220603.GA11658@ibm-toto.the-meissners.org>

This patch rewrites those patches.  In order to run with older GLIBC's, this
patch uses weak references to the IEEE 128-bit conversions to/from string that
are found in GLIBC 2.32.

If the user uses GLIBC 2.32 or later, the Decimal <-> Float128 conversions will
call the functions in that library.  This isn't ideal, as IEEE 128-bit has more
exponent range than IBM 128-bit.

If an older library is used, these patches will convert IEEE 128-bit to IBM
128-bit and do the conversion with IBM 128-bit.  I have tested this with a
compiler configured to use an older library, and it worked for the conversion
if the number could be represented in the IBM 128-bit format.

While most of the Decimal <-> Long double tests now pass when long doubles are
IEEE 128-bit, there are two tests that fails:

    *	c-c++-common/dfp/convert-bfp-6.c
    *	c-c++-common/dfp/convert-bfp-11.c

I have patches for the bfp-11 test (which requires that long double be IBM
128-bit).  I have not looked at the bfp-6 test but I will shortly.

I have tested this patch by doing builds, bootstraps, and make check with 3
builds on a power9 little endian server:

    *   Build one used the default long double being IBM 128-bit;
    *   Build two set the long double default to IEEE 128-bit; (and)
    *   Build three set the long double default to 64-bit.

The compilers built fine providing I recompiled gmp, mpc, and mpfr with the
appropriate long double options.  There were a few differences in the test
suite runs that will be addressed in later patches, but over all it works
well.  This patch is required to be able to build a toolchain where the default
long double is IEEE 128-bit.  Can I check this patch into the master branch for
GCC 11?

libgcc/
2021-01-14  Michael Meissner  <meissner@linux.ibm.com>

	* config/rs6000/_dd_to_kf.c: New file.
	* config/rs6000/_kf_to_dd.c: New file.
	* config/rs6000/_kf_to_sd.c: New file.
	* config/rs6000/_kf_to_td.c: New file.
	* config/rs6000/_sd_to_kf.c: New file.
	* config/rs6000/_sprintfkf.c: New file.
	* config/rs6000/_sprintfkf.h: New file.
	* config/rs6000/_strtokf.h: New file.
	* config/rs6000/_strtokf.c: New file.
	* config/rs6000/_td_to_kf.c: New file.
	* config/rs6000/quad-float128.h: Add new declarations.
	* config/rs6000/t-float128 (fp128_dec_funcs): New macro.
	(fp128_decstr_funcs): New macro.
	(ibm128_dec_funcs): New macro.
	(fp128_ppc_funcs): Add the new conversions.
	(fp128_dec_objs): Force Decimal <-> __float128 conversions to be
	compiled with -mabi=ieeelongdouble.
	(fp128_decstr_objs): Force __float128 <-> string conversions to be
	compiled with -mabi=ibmlongdouble.
	(ibm128_dec_objs): Force Decimal <-> __float128 conversions to be
	compiled with -mabi=ieeelongdouble.
	(FP128_CFLAGS_DECIMAL): New macro.
	(IBM128_CFLAGS_DECIMAL): New macro.
	* dfp-bit.c (DFP_TO_BFP): Add PowerPC _Float128 support.
	(BFP_TO_DFP): Add PowerPC _Float128 support.
	* dfp-bit.h (BFP_KIND): Add new binary floating point kind for
	IEEE 128-bit floating point.
	(DFP_TO_BFP): Add PowerPC _Float128 support.
	(BFP_TO_DFP): Add PowerPC _Float128 support.
	(BFP_SPRINTF): New macro.
---
 libgcc/config/rs6000/_dd_to_kf.c     | 37 ++++++++++++++++++
 libgcc/config/rs6000/_kf_to_dd.c     | 37 ++++++++++++++++++
 libgcc/config/rs6000/_kf_to_sd.c     | 37 ++++++++++++++++++
 libgcc/config/rs6000/_kf_to_td.c     | 37 ++++++++++++++++++
 libgcc/config/rs6000/_sd_to_kf.c     | 37 ++++++++++++++++++
 libgcc/config/rs6000/_sprintfkf.c    | 57 ++++++++++++++++++++++++++++
 libgcc/config/rs6000/_sprintfkf.h    | 28 ++++++++++++++
 libgcc/config/rs6000/_strtokf.c      | 56 +++++++++++++++++++++++++++
 libgcc/config/rs6000/_strtokf.h      | 27 +++++++++++++
 libgcc/config/rs6000/_td_to_kf.c     | 37 ++++++++++++++++++
 libgcc/config/rs6000/quad-float128.h |  8 ++++
 libgcc/config/rs6000/t-float128      | 37 +++++++++++++++++-
 libgcc/dfp-bit.c                     | 12 +++++-
 libgcc/dfp-bit.h                     | 26 +++++++++++++
 14 files changed, 470 insertions(+), 3 deletions(-)
 create mode 100644 libgcc/config/rs6000/_dd_to_kf.c
 create mode 100644 libgcc/config/rs6000/_kf_to_dd.c
 create mode 100644 libgcc/config/rs6000/_kf_to_sd.c
 create mode 100644 libgcc/config/rs6000/_kf_to_td.c
 create mode 100644 libgcc/config/rs6000/_sd_to_kf.c
 create mode 100644 libgcc/config/rs6000/_sprintfkf.c
 create mode 100644 libgcc/config/rs6000/_sprintfkf.h
 create mode 100644 libgcc/config/rs6000/_strtokf.c
 create mode 100644 libgcc/config/rs6000/_strtokf.h
 create mode 100644 libgcc/config/rs6000/_td_to_kf.c

diff --git a/libgcc/config/rs6000/_dd_to_kf.c b/libgcc/config/rs6000/_dd_to_kf.c
new file mode 100644
index 00000000000..3b4d8500a57
--- /dev/null
+++ b/libgcc/config/rs6000/_dd_to_kf.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1989-2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC 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 General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+/* Decimal64 -> _Float128 conversion.  */
+
+/* FINE_GRAINED_LIBRARIES is used so we can isolate just to dd_to_tf conversion
+   function from dp-bits.c.  */
+#define FINE_GRAINED_LIBRARIES	1
+#define L_dd_to_kf		1
+#define WIDTH			64
+
+#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IEEE128__)
+#error "Long double is not IEEE 128-bit"
+#endif
+
+/* Use dfp-bit.c to do the real work.  */
+#include "dfp-bit.c"
diff --git a/libgcc/config/rs6000/_kf_to_dd.c b/libgcc/config/rs6000/_kf_to_dd.c
new file mode 100644
index 00000000000..8d1c49dd396
--- /dev/null
+++ b/libgcc/config/rs6000/_kf_to_dd.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1989-2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC 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 General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+/* _Float128 -> Decimal64 conversion.  */
+
+/* FINE_GRAINED_LIBRARIES is used so we can isolate just to tf_to_dd conversion
+   function from dp-bits.c.  */
+#define FINE_GRAINED_LIBRARIES	1
+#define L_kf_to_dd		1
+#define WIDTH			64
+
+#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IEEE128__)
+#error "Long double is not IEEE 128-bit"
+#endif
+
+/* Use dfp-bit.c to do the real work.  */
+#include "dfp-bit.c"
diff --git a/libgcc/config/rs6000/_kf_to_sd.c b/libgcc/config/rs6000/_kf_to_sd.c
new file mode 100644
index 00000000000..b02082d6f52
--- /dev/null
+++ b/libgcc/config/rs6000/_kf_to_sd.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1989-2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC 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 General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+/* _Float128 -> Decimal32 conversion.  */
+
+/* FINE_GRAINED_LIBRARIES is used so we can isolate just to tf_to_sd conversion
+   function from dp-bits.c.  */
+#define FINE_GRAINED_LIBRARIES	1
+#define L_kf_to_sd		1
+#define WIDTH			32
+
+#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IEEE128__)
+#error "Long double is not IEEE 128-bit"
+#endif
+
+/* Use dfp-bit.c to do the real work.  */
+#include "dfp-bit.c"
diff --git a/libgcc/config/rs6000/_kf_to_td.c b/libgcc/config/rs6000/_kf_to_td.c
new file mode 100644
index 00000000000..f120709bb42
--- /dev/null
+++ b/libgcc/config/rs6000/_kf_to_td.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1989-2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC 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 General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+/* _Float128 -> Decimal128 conversion.  */
+
+/* FINE_GRAINED_LIBRARIES is used so we can isolate just to tf_to_td conversion
+   function from dp-bits.c.  */
+#define FINE_GRAINED_LIBRARIES	1
+#define L_kf_to_td		1
+#define WIDTH			128
+
+#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IEEE128__)
+#error "Long double is not IEEE 128-bit"
+#endif
+
+/* Use dfp-bit.c to do the real work.  */
+#include "dfp-bit.c"
diff --git a/libgcc/config/rs6000/_sd_to_kf.c b/libgcc/config/rs6000/_sd_to_kf.c
new file mode 100644
index 00000000000..df222abdeab
--- /dev/null
+++ b/libgcc/config/rs6000/_sd_to_kf.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1989-2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC 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 General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+/* Decimal32 -> _Float128 conversion.  */
+
+/* FINE_GRAINED_LIBRARIES is used so we can isolate just to sd_to_tf conversion
+   function from dp-bits.c.  */
+#define FINE_GRAINED_LIBRARIES	1
+#define L_sd_to_kf		1
+#define WIDTH			32
+
+#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IEEE128__)
+#error "Long double is not IEEE 128-bit"
+#endif
+
+/* Use dfp-bit.c to do the real work.  */
+#include "dfp-bit.c"
diff --git a/libgcc/config/rs6000/_sprintfkf.c b/libgcc/config/rs6000/_sprintfkf.c
new file mode 100644
index 00000000000..e5ea8eb3b4e
--- /dev/null
+++ b/libgcc/config/rs6000/_sprintfkf.c
@@ -0,0 +1,57 @@
+/* Copyright (C) 1989-2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC 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 General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+/* Conversion to IEEE 128-bit floating point from string using snprintf.  */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <soft-fp.h>
+#include <quad-float128.h>
+#include <stdio.h>
+
+/* This function must be built with IBM 128-bit as long double, so that we can
+   access the strfroml function if do not have an IEEE 128-bit version, and if
+   that is not available, use sprintf.  */
+#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IBM128__)
+#error "Long double is not IBM 128-bit"
+#endif
+
+/* If the user is using GLIBC 2.32, we can use the __snprintfieee128 function.
+
+   If we are linked against an earlier library, we will have fake it by
+   converting the value to long double, and using sprinf to do the conversion.
+   This isn't ideal, as IEEE 128-bit has more exponent range than IBM
+   128-bit.  */
+
+extern int __sprintfieee128 (char *restrict, const char *restrict, ...)
+  __attribute__ ((__weak__));
+
+int __sprintfkf (char *restrict string,
+		 const char *restrict format,
+		 _Float128 number)
+{
+  if (__sprintfieee128)
+    return __sprintfieee128 (string, format, number);
+
+  return sprintf (string, format, (long double)number);
+}
diff --git a/libgcc/config/rs6000/_sprintfkf.h b/libgcc/config/rs6000/_sprintfkf.h
new file mode 100644
index 00000000000..637d104c882
--- /dev/null
+++ b/libgcc/config/rs6000/_sprintfkf.h
@@ -0,0 +1,28 @@
+/* Copyright (C) 1989-2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC 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 General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+/* Declaration of the conversion function to IEEE 128-bit floating point from
+   string using snprintf.  */
+
+extern int __sprintfkf (char *restrict, const char *restrict, ...);
+
diff --git a/libgcc/config/rs6000/_strtokf.c b/libgcc/config/rs6000/_strtokf.c
new file mode 100644
index 00000000000..696a2c907bb
--- /dev/null
+++ b/libgcc/config/rs6000/_strtokf.c
@@ -0,0 +1,56 @@
+/* Copyright (C) 1989-2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC 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 General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+/* Conversion to IEEE 128-bit floating point from string.  */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <soft-fp.h>
+#include <quad-float128.h>
+
+/* This function must be built with IBM 128-bit as long double, so that we can
+   access the strtold function if do not have an IEEE 128-bit version.  */
+#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IBM128__)
+#error "Long double is not IBM 128-bit"
+#endif
+
+/* If the user is using GLIBC 2.32, we can use the __strtoieee128 function.
+
+   If we are linked against an earlier library, we will have fake it by
+   converting the string to IBM 128-bit long double, and then converting that to
+   __float128.  This isn't ideal, as IEEE 128-bit has more exponent range than
+   IBM 128-bit.  */
+
+extern _Float128 __strtoieee128 (const char *, char **) __attribute__ ((__weak__));
+
+_Float128
+__strtokf (const char *string, char **endptr)
+{
+  long double num;
+
+  if (__strtoieee128)
+    return __strtoieee128 (string, endptr);
+
+  num = strtold (string, endptr);
+  return (_Float128) num;
+}
diff --git a/libgcc/config/rs6000/_strtokf.h b/libgcc/config/rs6000/_strtokf.h
new file mode 100644
index 00000000000..a7ca8e09244
--- /dev/null
+++ b/libgcc/config/rs6000/_strtokf.h
@@ -0,0 +1,27 @@
+/* Copyright (C) 1989-2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC 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 General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+/* Declaration of the conversion function to IEEE 128-bit floating point from
+   string.  */
+
+extern _Float128 __strtokf (const char *, char **);
diff --git a/libgcc/config/rs6000/_td_to_kf.c b/libgcc/config/rs6000/_td_to_kf.c
new file mode 100644
index 00000000000..330a7802827
--- /dev/null
+++ b/libgcc/config/rs6000/_td_to_kf.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1989-2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC 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 General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+/* Decimal128 -> _Float128 conversion.  */
+
+/* FINE_GRAINED_LIBRARIES is used so we can isolate just to td_to_tf conversion
+   function from dp-bits.c.  */
+#define FINE_GRAINED_LIBRARIES	1
+#define L_td_to_kf		1
+#define WIDTH			128
+
+#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IEEE128__)
+#error "Long double is not IEEE 128-bit"
+#endif
+
+/* Use dfp-bit.c to do the real work.  */
+#include "dfp-bit.c"
diff --git a/libgcc/config/rs6000/quad-float128.h b/libgcc/config/rs6000/quad-float128.h
index 0eb1d34691f..5beb1531d2b 100644
--- a/libgcc/config/rs6000/quad-float128.h
+++ b/libgcc/config/rs6000/quad-float128.h
@@ -49,6 +49,7 @@ typedef __complex float TCtype __attribute__ ((mode (TC)));
 #pragma GCC target ("vsx,float128")
 #endif
 
+#include <stddef.h>
 #include <quad.h>
 
 #define IBM128_TYPE	__ibm128
@@ -171,6 +172,13 @@ extern TFtype __trunctfkf2 (IBM128_TYPE);
 extern TCtype __mulkc3 (TFtype, TFtype, TFtype, TFtype);
 extern TCtype __divkc3 (TFtype, TFtype, TFtype, TFtype);
 
+/* Convert IEEE 128-bit floating point to/from string.  We explicitly use
+   _Float128 instead of TFmode because _strtokf and _strfromkf must be compiled
+   with long double being IBM 128.  */
+extern _Float128 __strtokf (const char *, char **);
+extern int __strfromkf (char *restrict, size_t, const char *restrict,
+			_Float128);
+
 /* Implementation of conversions between __ibm128 and __float128, to allow the
    same code to be used on systems with IEEE 128-bit emulation and with IEEE
    128-bit hardware support.  */
diff --git a/libgcc/config/rs6000/t-float128 b/libgcc/config/rs6000/t-float128
index d5413445189..6fb1a3d871b 100644
--- a/libgcc/config/rs6000/t-float128
+++ b/libgcc/config/rs6000/t-float128
@@ -22,10 +22,23 @@ fp128_softfp_static_obj	= $(addsuffix -sw$(objext),$(fp128_softfp_funcs))
 fp128_softfp_shared_obj	= $(addsuffix -sw_s$(objext),$(fp128_softfp_funcs))
 fp128_softfp_obj	= $(fp128_softfp_static_obj) $(fp128_softfp_shared_obj)
 
+# Decimal <-> _Float128 conversions
+fp128_dec_funcs		= _kf_to_sd _kf_to_dd _kf_to_td \
+			  _sd_to_kf _dd_to_kf _td_to_kf
+
+# _Float128 to/from string conversions that must be compiled with IBM 128-bit
+# long double.
+fp128_decstr_funcs	= _strtokf _sprintfkf
+
+# Decimal <-> __ibm128 conversions
+ibm128_dec_funcs	= _tf_to_sd _tf_to_dd _tf_to_td \
+			  _sd_to_tf _dd_to_tf _td_to_tf
+
 # New functions for software emulation
 fp128_ppc_funcs		= floattikf floatuntikf fixkfti fixunskfti \
 			  extendkftf2-sw trunctfkf2-sw \
-			  sfp-exceptions _mulkc3 _divkc3 _powikf2
+			  sfp-exceptions _mulkc3 _divkc3 _powikf2 \
+			  $(fp128_dec_funcs) $(fp128_decstr_funcs)
 
 fp128_ppc_src		= $(addprefix $(srcdir)/config/rs6000/,$(addsuffix \
 				.c,$(fp128_ppc_funcs)))
@@ -69,6 +82,28 @@ $(fp128_ppc_obj)	 : INTERNAL_CFLAGS += $(FP128_CFLAGS_SW)
 $(fp128_obj)		 : $(fp128_includes)
 $(fp128_obj)		 : $(srcdir)/config/rs6000/quad-float128.h
 
+# Force the TF mode to/from decimal functions to be compiled with IBM long
+# double.  Add building the KF mode to/from decimal conversions with explict
+# IEEE long double.
+fp128_dec_objs		= $(addsuffix $(objext),$(fp128_dec_funcs)) \
+			  $(addsuffix _s$(objext),$(fp128_dec_funcs))
+
+fp128_decstr_objs	= $(addsuffix $(objext),$(fp128_decstr_funcs)) \
+			  $(addsuffix _s$(objext),$(fp128_decstr_funcs))
+
+ibm128_dec_objs		= $(addsuffix $(objext),$(ibm128_dec_funcs)) \
+			  $(addsuffix _s$(objext),$(ibm128_dec_funcs))
+
+FP128_CFLAGS_DECIMAL	= -mno-gnu-attribute -Wno-psabi -mabi=ieeelongdouble
+IBM128_CFLAGS_DECIMAL	= -mno-gnu-attribute -Wno-psabi -mabi=ibmlongdouble
+
+$(fp128_dec_objs)	: INTERNAL_CFLAGS += $(FP128_CFLAGS_DECIMAL)
+$(fp128_decstr_objs)	: INTERNAL_CFLAGS += $(IBM128_CFLAGS_DECIMAL)
+$(ibm128_dec_objs)	: INTERNAL_CFLAGS += $(IBM128_CFLAGS_DECIMAL)
+
+$(fp128_decstr_objs)	: $(srcdir)/config/rs6000/_strtokf.h \
+			  $(srcdir)/config/rs6000/_sprintfkf.h \
+
 $(fp128_softfp_src) : $(srcdir)/soft-fp/$(subst -sw,,$(subst kf,tf,$@)) $(fp128_dep)
 	@src="$(srcdir)/soft-fp/$(subst -sw,,$(subst kf,tf,$@))"; \
 	echo "Create $@"; \
diff --git a/libgcc/dfp-bit.c b/libgcc/dfp-bit.c
index 17bca9cf203..0b0f9ace1fa 100644
--- a/libgcc/dfp-bit.c
+++ b/libgcc/dfp-bit.c
@@ -606,6 +606,7 @@ INT_TO_DFP (INT_TYPE i)
 
 #if defined (L_sd_to_sf) || defined (L_dd_to_sf) || defined (L_td_to_sf) \
  || defined (L_sd_to_df) || defined (L_dd_to_df) || defined (L_td_to_df) \
+ || defined (L_sd_to_kf) || defined (L_dd_to_kf) || defined (L_td_to_kf) \
  || ((defined (L_sd_to_xf) || defined (L_dd_to_xf) || defined (L_td_to_xf)) \
      && LONG_DOUBLE_HAS_XF_MODE) \
  || ((defined (L_sd_to_tf) || defined (L_dd_to_tf) || defined (L_td_to_tf)) \
@@ -626,6 +627,7 @@ DFP_TO_BFP (DFP_C_TYPE f)
                                                                                 
 #if defined (L_sf_to_sd) || defined (L_sf_to_dd) || defined (L_sf_to_td) \
  || defined (L_df_to_sd) || defined (L_df_to_dd) || defined (L_df_to_td) \
+ || defined (L_kf_to_sd) || defined (L_kf_to_dd) || defined (L_kf_to_td) \
  || ((defined (L_xf_to_sd) || defined (L_xf_to_dd) || defined (L_xf_to_td)) \
      && LONG_DOUBLE_HAS_XF_MODE) \
  || ((defined (L_tf_to_sd) || defined (L_tf_to_dd) || defined (L_tf_to_td)) \
@@ -641,8 +643,14 @@ BFP_TO_DFP (BFP_TYPE x)
   decContextDefault (&context, CONTEXT_INIT);
   DFP_INIT_ROUNDMODE (context.round);
 
-  /* Use a C library function to write the floating point value to a string.  */
-  sprintf (buf, BFP_FMT, (BFP_VIA_TYPE) x);
+  /* Use the sprintf library function to write the floating point value to a string.
+
+     If we are handling the IEEE 128-bit floating point on PowerPC, use the
+     special function __sprintfkf instead of sprintf.  This function allows us
+     to use __sprintfieee128 if we have a new enough GLIBC, and it can fall back
+     to using the traditional sprintf via conversion to IBM 128-bit if the glibc
+     is older.  */
+  BFP_SPRINTF (buf, BFP_FMT, (BFP_VIA_TYPE) x);
 
   /* Convert from the floating point string to a decimal* type.  */
   FROM_STRING (&s, buf, &context);
diff --git a/libgcc/dfp-bit.h b/libgcc/dfp-bit.h
index 1fa42ee621f..e33bc22f7cc 100644
--- a/libgcc/dfp-bit.h
+++ b/libgcc/dfp-bit.h
@@ -241,6 +241,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #elif defined (L_sd_to_tf) || defined (L_dd_to_tf) || defined (L_td_to_tf) \
  ||   defined (L_tf_to_sd) || defined (L_tf_to_dd) || defined (L_tf_to_td)
 #define BFP_KIND 4
+#elif defined (L_sd_to_kf) || defined (L_dd_to_kf) || defined (L_td_to_kf) \
+ ||   defined (L_kf_to_sd) || defined (L_kf_to_dd) || defined (L_kf_to_td)
+#define BFP_KIND 5
 #endif
 
 /*  If BFP_KIND is defined, define additional macros:
@@ -291,6 +294,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #define BFP_VIA_TYPE long double
 #endif /* LONG_DOUBLE_HAS_TF_MODE */
 
+#elif BFP_KIND == 5
+#define BFP_TYPE _Float128
+#define BFP_FMT "%.21Le"
+#define BFP_VIA_TYPE _Float128
+#define STR_TO_BFP __strtokf
+#include <_strtokf.h>
+
 #endif /* BFP_KIND */
 
 #if WIDTH == 128 || WIDTH_TO == 128
@@ -490,6 +500,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #elif BFP_KIND == 4
 #define BFP_TO_DFP	DPD_BID_NAME(__dpd_trunctfsd,__bid_trunctfsd)
 #define DFP_TO_BFP	DPD_BID_NAME(__dpd_extendsdtf,__bid_extendsdtf)
+#elif BFP_KIND == 5
+#define BFP_TO_DFP	DPD_BID_NAME(__dpd_trunckfsd,__bid_trunckfsd)
+#define DFP_TO_BFP	DPD_BID_NAME(__dpd_extendsdkf,__bid_extendsdkf)
 #endif /* BFP_KIND */
 
 #elif WIDTH == 64
@@ -505,6 +518,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #elif BFP_KIND == 4
 #define BFP_TO_DFP	DPD_BID_NAME(__dpd_trunctfdd,__bid_trunctfdd)
 #define DFP_TO_BFP	DPD_BID_NAME(__dpd_extendddtf,__bid_extendddtf)
+#elif BFP_KIND == 5
+#define BFP_TO_DFP	DPD_BID_NAME(__dpd_trunckfdd,__bid_trunckfdd)
+#define DFP_TO_BFP	DPD_BID_NAME(__dpd_extendddkf,__bid_extendddkf)
 #endif /* BFP_KIND */
 
 #elif WIDTH == 128
@@ -520,6 +536,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #elif BFP_KIND == 4
 #define BFP_TO_DFP	DPD_BID_NAME(__dpd_extendtftd,__bid_extendtftd)
 #define DFP_TO_BFP	DPD_BID_NAME(__dpd_trunctdtf,__bid_trunctdtf)
+#elif BFP_KIND == 5
+#define BFP_TO_DFP	DPD_BID_NAME(__dpd_extendkftd,__bid_extendkftd)
+#define DFP_TO_BFP	DPD_BID_NAME(__dpd_trunctdkf,__bid_trunctdkf)
 #endif /* BFP_KIND */
 
 #endif /* WIDTH */
@@ -609,6 +628,7 @@ extern DFP_C_TYPE INT_TO_DFP (INT_TYPE);
 
 #if defined (L_sd_to_sf) || defined (L_dd_to_sf) || defined (L_td_to_sf) \
  || defined (L_sd_to_df) || defined (L_dd_to_df) || defined (L_td_to_df) \
+ || defined (L_sd_to_kf) || defined (L_dd_to_kf) || defined (L_td_to_kf) \
  || ((defined (L_sd_to_xf) || defined (L_dd_to_xf) || defined (L_td_to_xf)) \
      && LONG_DOUBLE_HAS_XF_MODE) \
  || ((defined (L_sd_to_tf) || defined (L_dd_to_tf) || defined (L_td_to_tf)) \
@@ -623,6 +643,12 @@ extern BFP_TYPE DFP_TO_BFP (DFP_C_TYPE);
  || ((defined (L_tf_to_sd) || defined (L_tf_to_dd) || defined (L_tf_to_td)) \
      && LONG_DOUBLE_HAS_TF_MODE)
 extern DFP_C_TYPE BFP_TO_DFP (BFP_TYPE);
+#define BFP_SPRINTF sprintf
+
+#elif defined (L_kf_to_sd) || defined (L_kf_to_dd) || defined (L_kf_to_td)
+extern DFP_C_TYPE BFP_TO_DFP (BFP_TYPE);
+#include <_sprintfkf.h>
+#define BFP_SPRINTF __sprintfkf
 #endif
 
 #endif /* _DFPBIT_H */
-- 
2.22.0


-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meissner@linux.ibm.com, phone: +1 (978) 899-4797

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH] PowerPC: Add float128/Decimal conversions.
  2021-01-14 17:09 [PATCH] PowerPC: Add float128/Decimal conversions Michael Meissner
@ 2021-01-15 21:52 ` Segher Boessenkool
  2021-01-19 17:30   ` Michael Meissner
  2021-01-26 23:43 ` [Ping] " Michael Meissner
  2021-01-27 21:05 ` [PATCH, revised] " Michael Meissner
  2 siblings, 1 reply; 17+ messages in thread
From: Segher Boessenkool @ 2021-01-15 21:52 UTC (permalink / raw)
  To: Michael Meissner, gcc-patches, David Edelsohn, Bill Schmidt,
	Peter Bergner

On Thu, Jan 14, 2021 at 12:09:36PM -0500, Michael Meissner wrote:
> [PATCH] PowerPC: Add float128/Decimal conversions.

Same question here.


Segher

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH] PowerPC: Add float128/Decimal conversions.
  2021-01-15 21:52 ` Segher Boessenkool
@ 2021-01-19 17:30   ` Michael Meissner
  0 siblings, 0 replies; 17+ messages in thread
From: Michael Meissner @ 2021-01-19 17:30 UTC (permalink / raw)
  To: Segher Boessenkool
  Cc: Michael Meissner, gcc-patches, David Edelsohn, Bill Schmidt,
	Peter Bergner

On Fri, Jan 15, 2021 at 03:52:44PM -0600, Segher Boessenkool wrote:
> On Thu, Jan 14, 2021 at 12:09:36PM -0500, Michael Meissner wrote:
> > [PATCH] PowerPC: Add float128/Decimal conversions.
> 
> Same question here.

In your last message, you said that it was unacceptable that the conversion
fails if the user uses an old GLIBC.  So I rewrote the code using weak
references.  If the user has at least GLIBC 2.32, it will use the IEEE 128-bit
string support in the library.

If an older GLIBC is used, I then use the IBM 128-bit format as an intermediate
value.  Obviously there are cases where IEEE 128-bit can hold values that IBM
128-bit can't (mostly due to the increased exponent range in IEEE 128-bit), but
it at least does the conversion for the numbers in the common range.

In doing this transformation, I needed to do minor edits to the main decimal
to/from binary conversion functions to allow the KF functions to be declared.
Previously, I used preprocessor magic to rename the functions.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meissner@linux.ibm.com, phone: +1 (978) 899-4797

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [Ping] PowerPC: Add float128/Decimal conversions.
  2021-01-14 17:09 [PATCH] PowerPC: Add float128/Decimal conversions Michael Meissner
  2021-01-15 21:52 ` Segher Boessenkool
@ 2021-01-26 23:43 ` Michael Meissner
  2021-01-28  3:11   ` Segher Boessenkool
  2021-01-27 21:05 ` [PATCH, revised] " Michael Meissner
  2 siblings, 1 reply; 17+ messages in thread
From: Michael Meissner @ 2021-01-26 23:43 UTC (permalink / raw)
  To: Michael Meissner, gcc-patches, Segher Boessenkool,
	David Edelsohn, Bill Schmidt, Peter Bergner

I posted this patch on January 14th, 2021:
https://gcc.gnu.org/pipermail/gcc-patches/2021-January/563498.html

| Date: Thu, 14 Jan 2021 12:09:36 -0500
| Subject: [PATCH] PowerPC: Add float128/Decimal conversions.
| Message-ID: <20210114170936.GA3319@ibm-toto.the-meissners.org>

You had a question about what changed, and I replied:

| In your last message, you said that it was unacceptable that the conversion
| fails if the user uses an old GLIBC.  So I rewrote the code using weak
| references.  If the user has at least GLIBC 2.32, it will use the IEEE 128-bit
| string support in the library.
|
| If an older GLIBC is used, I then use the IBM 128-bit format as an intermediate
| value.  Obviously there are cases where IEEE 128-bit can hold values that IBM
| 128-bit can't (mostly due to the increased exponent range in IEEE 128-bit), but
| it at least does the conversion for the numbers in the common range.
|
| In doing this transformation, I needed to do minor edits to the main decimal
| to/from binary conversion functions to allow the KF functions to be declared.
| Previously, I used preprocessor magic to rename the functions.

This is the second most important patch in the IEEE 128-bit work.  What do I
need to do to be able to commit the patch?


-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meissner@linux.ibm.com, phone: +1 (978) 899-4797

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH, revised] PowerPC: Add float128/Decimal conversions.
  2021-01-14 17:09 [PATCH] PowerPC: Add float128/Decimal conversions Michael Meissner
  2021-01-15 21:52 ` Segher Boessenkool
  2021-01-26 23:43 ` [Ping] " Michael Meissner
@ 2021-01-27 21:05 ` Michael Meissner
  2021-01-27 21:19   ` [PATCH, revised, #2] " Michael Meissner
  2 siblings, 1 reply; 17+ messages in thread
From: Michael Meissner @ 2021-01-27 21:05 UTC (permalink / raw)
  To: Michael Meissner, gcc-patches, Segher Boessenkool,
	David Edelsohn, Bill Schmidt, Peter Bergner

[PATCH, revised] PowerPC: Add float128/Decimal conversions.

This patch revises the patch on January 14th.  The only change in this patch
compared to the previous patch is to change the format string for converting
IEEE 128-bit to string.  This allows the c-c++-common/dfp/convert-bfp-6.c test
now passes.

This patch replaces the following three patches:

September 24th, 2020:
Message-ID: <20200924203545.GD31597@ibm-toto.the-meissners.org>

October 22nd, 2020:
Message-ID: <20201022220603.GA11658@ibm-toto.the-meissners.org>

January 14th, 2021:
Message-ID: <20210114170936.GA3319@ibm-toto.the-meissners.org>
https://gcc.gnu.org/pipermail/gcc-patches/2021-January/563498.html

This patch rewrites those patches.  In order to run with older GLIBC's, this
patch uses weak references to the IEEE 128-bit conversions to/from string that
are found in GLIBC 2.32.

If the user uses GLIBC 2.32 or later, the Decimal <-> Float128 conversions will
call the functions in that library.  This isn't ideal, as IEEE 128-bit has more
exponent range than IBM 128-bit.

If an older library is used, these patches will convert IEEE 128-bit to IBM
128-bit and do the conversion with IBM 128-bit.  I have tested this with a
compiler configured to use an older library, and it worked for the conversion
if the number could be represented in the IBM 128-bit format.

While most of the Decimal <-> Long double tests now pass when long doubles are
IEEE 128-bit, there is one test that fails:

    *	c-c++-common/dfp/convert-bfp-11.c

I have patches for the bfp-11 test (which requires that long double be IBM
128-bit).

I have tested this patch by doing builds, bootstraps, and make check with 3
builds on a power9 little endian server:

    *   Build one used the default long double being IBM 128-bit;
    *   Build two set the long double default to IEEE 128-bit; (and)
    *   Build three set the long double default to 64-bit.

I have also built and tested this patch on a big endian Power8 system with
both 64 and 32-bit targets.  There were no regressions.

The compilers built fine providing I recompiled gmp, mpc, and mpfr with the
appropriate long double options.  There were a few differences in the test
suite runs that will be addressed in later patches, but over all it works
well.  This patch is required to be able to build a toolchain where the default
long double is IEEE 128-bit.  Can I check this patch into the master branch for
GCC 11?

libgcc/
2021-01-27  Michael Meissner  <meissner@linux.ibm.com>

	* config/rs6000/_dd_to_kf.c: New file.
	* config/rs6000/_kf_to_dd.c: New file.
	* config/rs6000/_kf_to_sd.c: New file.
	* config/rs6000/_kf_to_td.c: New file.
	* config/rs6000/_sd_to_kf.c: New file.
	* config/rs6000/_sprintfkf.c: New file.
	* config/rs6000/_sprintfkf.h: New file.
	* config/rs6000/_strtokf.h: New file.
	* config/rs6000/_strtokf.c: New file.
	* config/rs6000/_td_to_kf.c: New file.
	* config/rs6000/quad-float128.h: Add new declarations.
	* config/rs6000/t-float128 (fp128_dec_funcs): New macro.
	(fp128_decstr_funcs): New macro.
	(ibm128_dec_funcs): New macro.
	(fp128_ppc_funcs): Add the new conversions.
	(fp128_dec_objs): Force Decimal <-> __float128 conversions to be
	compiled with -mabi=ieeelongdouble.
	(fp128_decstr_objs): Force __float128 <-> string conversions to be
	compiled with -mabi=ibmlongdouble.
	(ibm128_dec_objs): Force Decimal <-> __float128 conversions to be
	compiled with -mabi=ieeelongdouble.
	(FP128_CFLAGS_DECIMAL): New macro.
	(IBM128_CFLAGS_DECIMAL): New macro.
	* dfp-bit.c (DFP_TO_BFP): Add PowerPC _Float128 support.
	(BFP_TO_DFP): Add PowerPC _Float128 support.
	* dfp-bit.h (BFP_KIND): Add new binary floating point kind for
	IEEE 128-bit floating point.
	(DFP_TO_BFP): Add PowerPC _Float128 support.
	(BFP_TO_DFP): Add PowerPC _Float128 support.
	(BFP_SPRINTF): New macro.
---
 libgcc/config/rs6000/_dd_to_kf.c     | 37 ++++++++++++++++++
 libgcc/config/rs6000/_kf_to_dd.c     | 37 ++++++++++++++++++
 libgcc/config/rs6000/_kf_to_sd.c     | 37 ++++++++++++++++++
 libgcc/config/rs6000/_kf_to_td.c     | 37 ++++++++++++++++++
 libgcc/config/rs6000/_sd_to_kf.c     | 37 ++++++++++++++++++
 libgcc/config/rs6000/_sprintfkf.c    | 57 ++++++++++++++++++++++++++++
 libgcc/config/rs6000/_sprintfkf.h    | 28 ++++++++++++++
 libgcc/config/rs6000/_strtokf.c      | 56 +++++++++++++++++++++++++++
 libgcc/config/rs6000/_strtokf.h      | 27 +++++++++++++
 libgcc/config/rs6000/_td_to_kf.c     | 37 ++++++++++++++++++
 libgcc/config/rs6000/quad-float128.h |  8 ++++
 libgcc/config/rs6000/t-float128      | 37 +++++++++++++++++-
 libgcc/dfp-bit.c                     | 12 +++++-
 libgcc/dfp-bit.h                     | 26 +++++++++++++
 14 files changed, 470 insertions(+), 3 deletions(-)
 create mode 100644 libgcc/config/rs6000/_dd_to_kf.c
 create mode 100644 libgcc/config/rs6000/_kf_to_dd.c
 create mode 100644 libgcc/config/rs6000/_kf_to_sd.c
 create mode 100644 libgcc/config/rs6000/_kf_to_td.c
 create mode 100644 libgcc/config/rs6000/_sd_to_kf.c
 create mode 100644 libgcc/config/rs6000/_sprintfkf.c
 create mode 100644 libgcc/config/rs6000/_sprintfkf.h
 create mode 100644 libgcc/config/rs6000/_strtokf.c
 create mode 100644 libgcc/config/rs6000/_strtokf.h
 create mode 100644 libgcc/config/rs6000/_td_to_kf.c

diff --git a/libgcc/config/rs6000/_dd_to_kf.c b/libgcc/config/rs6000/_dd_to_kf.c
new file mode 100644
index 00000000000..3b4d8500a57
--- /dev/null
+++ b/libgcc/config/rs6000/_dd_to_kf.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1989-2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC 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 General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+/* Decimal64 -> _Float128 conversion.  */
+
+/* FINE_GRAINED_LIBRARIES is used so we can isolate just to dd_to_tf conversion
+   function from dp-bits.c.  */
+#define FINE_GRAINED_LIBRARIES	1
+#define L_dd_to_kf		1
+#define WIDTH			64
+
+#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IEEE128__)
+#error "Long double is not IEEE 128-bit"
+#endif
+
+/* Use dfp-bit.c to do the real work.  */
+#include "dfp-bit.c"
diff --git a/libgcc/config/rs6000/_kf_to_dd.c b/libgcc/config/rs6000/_kf_to_dd.c
new file mode 100644
index 00000000000..8d1c49dd396
--- /dev/null
+++ b/libgcc/config/rs6000/_kf_to_dd.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1989-2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC 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 General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+/* _Float128 -> Decimal64 conversion.  */
+
+/* FINE_GRAINED_LIBRARIES is used so we can isolate just to tf_to_dd conversion
+   function from dp-bits.c.  */
+#define FINE_GRAINED_LIBRARIES	1
+#define L_kf_to_dd		1
+#define WIDTH			64
+
+#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IEEE128__)
+#error "Long double is not IEEE 128-bit"
+#endif
+
+/* Use dfp-bit.c to do the real work.  */
+#include "dfp-bit.c"
diff --git a/libgcc/config/rs6000/_kf_to_sd.c b/libgcc/config/rs6000/_kf_to_sd.c
new file mode 100644
index 00000000000..b02082d6f52
--- /dev/null
+++ b/libgcc/config/rs6000/_kf_to_sd.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1989-2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC 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 General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+/* _Float128 -> Decimal32 conversion.  */
+
+/* FINE_GRAINED_LIBRARIES is used so we can isolate just to tf_to_sd conversion
+   function from dp-bits.c.  */
+#define FINE_GRAINED_LIBRARIES	1
+#define L_kf_to_sd		1
+#define WIDTH			32
+
+#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IEEE128__)
+#error "Long double is not IEEE 128-bit"
+#endif
+
+/* Use dfp-bit.c to do the real work.  */
+#include "dfp-bit.c"
diff --git a/libgcc/config/rs6000/_kf_to_td.c b/libgcc/config/rs6000/_kf_to_td.c
new file mode 100644
index 00000000000..f120709bb42
--- /dev/null
+++ b/libgcc/config/rs6000/_kf_to_td.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1989-2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC 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 General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+/* _Float128 -> Decimal128 conversion.  */
+
+/* FINE_GRAINED_LIBRARIES is used so we can isolate just to tf_to_td conversion
+   function from dp-bits.c.  */
+#define FINE_GRAINED_LIBRARIES	1
+#define L_kf_to_td		1
+#define WIDTH			128
+
+#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IEEE128__)
+#error "Long double is not IEEE 128-bit"
+#endif
+
+/* Use dfp-bit.c to do the real work.  */
+#include "dfp-bit.c"
diff --git a/libgcc/config/rs6000/_sd_to_kf.c b/libgcc/config/rs6000/_sd_to_kf.c
new file mode 100644
index 00000000000..df222abdeab
--- /dev/null
+++ b/libgcc/config/rs6000/_sd_to_kf.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1989-2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC 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 General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+/* Decimal32 -> _Float128 conversion.  */
+
+/* FINE_GRAINED_LIBRARIES is used so we can isolate just to sd_to_tf conversion
+   function from dp-bits.c.  */
+#define FINE_GRAINED_LIBRARIES	1
+#define L_sd_to_kf		1
+#define WIDTH			32
+
+#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IEEE128__)
+#error "Long double is not IEEE 128-bit"
+#endif
+
+/* Use dfp-bit.c to do the real work.  */
+#include "dfp-bit.c"
diff --git a/libgcc/config/rs6000/_sprintfkf.c b/libgcc/config/rs6000/_sprintfkf.c
new file mode 100644
index 00000000000..e5ea8eb3b4e
--- /dev/null
+++ b/libgcc/config/rs6000/_sprintfkf.c
@@ -0,0 +1,57 @@
+/* Copyright (C) 1989-2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC 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 General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+/* Conversion to IEEE 128-bit floating point from string using snprintf.  */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <soft-fp.h>
+#include <quad-float128.h>
+#include <stdio.h>
+
+/* This function must be built with IBM 128-bit as long double, so that we can
+   access the strfroml function if do not have an IEEE 128-bit version, and if
+   that is not available, use sprintf.  */
+#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IBM128__)
+#error "Long double is not IBM 128-bit"
+#endif
+
+/* If the user is using GLIBC 2.32, we can use the __snprintfieee128 function.
+
+   If we are linked against an earlier library, we will have fake it by
+   converting the value to long double, and using sprinf to do the conversion.
+   This isn't ideal, as IEEE 128-bit has more exponent range than IBM
+   128-bit.  */
+
+extern int __sprintfieee128 (char *restrict, const char *restrict, ...)
+  __attribute__ ((__weak__));
+
+int __sprintfkf (char *restrict string,
+		 const char *restrict format,
+		 _Float128 number)
+{
+  if (__sprintfieee128)
+    return __sprintfieee128 (string, format, number);
+
+  return sprintf (string, format, (long double)number);
+}
diff --git a/libgcc/config/rs6000/_sprintfkf.h b/libgcc/config/rs6000/_sprintfkf.h
new file mode 100644
index 00000000000..637d104c882
--- /dev/null
+++ b/libgcc/config/rs6000/_sprintfkf.h
@@ -0,0 +1,28 @@
+/* Copyright (C) 1989-2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC 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 General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+/* Declaration of the conversion function to IEEE 128-bit floating point from
+   string using snprintf.  */
+
+extern int __sprintfkf (char *restrict, const char *restrict, ...);
+
diff --git a/libgcc/config/rs6000/_strtokf.c b/libgcc/config/rs6000/_strtokf.c
new file mode 100644
index 00000000000..696a2c907bb
--- /dev/null
+++ b/libgcc/config/rs6000/_strtokf.c
@@ -0,0 +1,56 @@
+/* Copyright (C) 1989-2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC 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 General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+/* Conversion to IEEE 128-bit floating point from string.  */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <soft-fp.h>
+#include <quad-float128.h>
+
+/* This function must be built with IBM 128-bit as long double, so that we can
+   access the strtold function if do not have an IEEE 128-bit version.  */
+#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IBM128__)
+#error "Long double is not IBM 128-bit"
+#endif
+
+/* If the user is using GLIBC 2.32, we can use the __strtoieee128 function.
+
+   If we are linked against an earlier library, we will have fake it by
+   converting the string to IBM 128-bit long double, and then converting that to
+   __float128.  This isn't ideal, as IEEE 128-bit has more exponent range than
+   IBM 128-bit.  */
+
+extern _Float128 __strtoieee128 (const char *, char **) __attribute__ ((__weak__));
+
+_Float128
+__strtokf (const char *string, char **endptr)
+{
+  long double num;
+
+  if (__strtoieee128)
+    return __strtoieee128 (string, endptr);
+
+  num = strtold (string, endptr);
+  return (_Float128) num;
+}
diff --git a/libgcc/config/rs6000/_strtokf.h b/libgcc/config/rs6000/_strtokf.h
new file mode 100644
index 00000000000..a7ca8e09244
--- /dev/null
+++ b/libgcc/config/rs6000/_strtokf.h
@@ -0,0 +1,27 @@
+/* Copyright (C) 1989-2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC 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 General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+/* Declaration of the conversion function to IEEE 128-bit floating point from
+   string.  */
+
+extern _Float128 __strtokf (const char *, char **);
diff --git a/libgcc/config/rs6000/_td_to_kf.c b/libgcc/config/rs6000/_td_to_kf.c
new file mode 100644
index 00000000000..330a7802827
--- /dev/null
+++ b/libgcc/config/rs6000/_td_to_kf.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1989-2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC 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 General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+/* Decimal128 -> _Float128 conversion.  */
+
+/* FINE_GRAINED_LIBRARIES is used so we can isolate just to td_to_tf conversion
+   function from dp-bits.c.  */
+#define FINE_GRAINED_LIBRARIES	1
+#define L_td_to_kf		1
+#define WIDTH			128
+
+#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IEEE128__)
+#error "Long double is not IEEE 128-bit"
+#endif
+
+/* Use dfp-bit.c to do the real work.  */
+#include "dfp-bit.c"
diff --git a/libgcc/config/rs6000/quad-float128.h b/libgcc/config/rs6000/quad-float128.h
index 0eb1d34691f..5beb1531d2b 100644
--- a/libgcc/config/rs6000/quad-float128.h
+++ b/libgcc/config/rs6000/quad-float128.h
@@ -49,6 +49,7 @@ typedef __complex float TCtype __attribute__ ((mode (TC)));
 #pragma GCC target ("vsx,float128")
 #endif
 
+#include <stddef.h>
 #include <quad.h>
 
 #define IBM128_TYPE	__ibm128
@@ -171,6 +172,13 @@ extern TFtype __trunctfkf2 (IBM128_TYPE);
 extern TCtype __mulkc3 (TFtype, TFtype, TFtype, TFtype);
 extern TCtype __divkc3 (TFtype, TFtype, TFtype, TFtype);
 
+/* Convert IEEE 128-bit floating point to/from string.  We explicitly use
+   _Float128 instead of TFmode because _strtokf and _strfromkf must be compiled
+   with long double being IBM 128.  */
+extern _Float128 __strtokf (const char *, char **);
+extern int __strfromkf (char *restrict, size_t, const char *restrict,
+			_Float128);
+
 /* Implementation of conversions between __ibm128 and __float128, to allow the
    same code to be used on systems with IEEE 128-bit emulation and with IEEE
    128-bit hardware support.  */
diff --git a/libgcc/config/rs6000/t-float128 b/libgcc/config/rs6000/t-float128
index d5413445189..6fb1a3d871b 100644
--- a/libgcc/config/rs6000/t-float128
+++ b/libgcc/config/rs6000/t-float128
@@ -22,10 +22,23 @@ fp128_softfp_static_obj	= $(addsuffix -sw$(objext),$(fp128_softfp_funcs))
 fp128_softfp_shared_obj	= $(addsuffix -sw_s$(objext),$(fp128_softfp_funcs))
 fp128_softfp_obj	= $(fp128_softfp_static_obj) $(fp128_softfp_shared_obj)
 
+# Decimal <-> _Float128 conversions
+fp128_dec_funcs		= _kf_to_sd _kf_to_dd _kf_to_td \
+			  _sd_to_kf _dd_to_kf _td_to_kf
+
+# _Float128 to/from string conversions that must be compiled with IBM 128-bit
+# long double.
+fp128_decstr_funcs	= _strtokf _sprintfkf
+
+# Decimal <-> __ibm128 conversions
+ibm128_dec_funcs	= _tf_to_sd _tf_to_dd _tf_to_td \
+			  _sd_to_tf _dd_to_tf _td_to_tf
+
 # New functions for software emulation
 fp128_ppc_funcs		= floattikf floatuntikf fixkfti fixunskfti \
 			  extendkftf2-sw trunctfkf2-sw \
-			  sfp-exceptions _mulkc3 _divkc3 _powikf2
+			  sfp-exceptions _mulkc3 _divkc3 _powikf2 \
+			  $(fp128_dec_funcs) $(fp128_decstr_funcs)
 
 fp128_ppc_src		= $(addprefix $(srcdir)/config/rs6000/,$(addsuffix \
 				.c,$(fp128_ppc_funcs)))
@@ -69,6 +82,28 @@ $(fp128_ppc_obj)	 : INTERNAL_CFLAGS += $(FP128_CFLAGS_SW)
 $(fp128_obj)		 : $(fp128_includes)
 $(fp128_obj)		 : $(srcdir)/config/rs6000/quad-float128.h
 
+# Force the TF mode to/from decimal functions to be compiled with IBM long
+# double.  Add building the KF mode to/from decimal conversions with explict
+# IEEE long double.
+fp128_dec_objs		= $(addsuffix $(objext),$(fp128_dec_funcs)) \
+			  $(addsuffix _s$(objext),$(fp128_dec_funcs))
+
+fp128_decstr_objs	= $(addsuffix $(objext),$(fp128_decstr_funcs)) \
+			  $(addsuffix _s$(objext),$(fp128_decstr_funcs))
+
+ibm128_dec_objs		= $(addsuffix $(objext),$(ibm128_dec_funcs)) \
+			  $(addsuffix _s$(objext),$(ibm128_dec_funcs))
+
+FP128_CFLAGS_DECIMAL	= -mno-gnu-attribute -Wno-psabi -mabi=ieeelongdouble
+IBM128_CFLAGS_DECIMAL	= -mno-gnu-attribute -Wno-psabi -mabi=ibmlongdouble
+
+$(fp128_dec_objs)	: INTERNAL_CFLAGS += $(FP128_CFLAGS_DECIMAL)
+$(fp128_decstr_objs)	: INTERNAL_CFLAGS += $(IBM128_CFLAGS_DECIMAL)
+$(ibm128_dec_objs)	: INTERNAL_CFLAGS += $(IBM128_CFLAGS_DECIMAL)
+
+$(fp128_decstr_objs)	: $(srcdir)/config/rs6000/_strtokf.h \
+			  $(srcdir)/config/rs6000/_sprintfkf.h \
+
 $(fp128_softfp_src) : $(srcdir)/soft-fp/$(subst -sw,,$(subst kf,tf,$@)) $(fp128_dep)
 	@src="$(srcdir)/soft-fp/$(subst -sw,,$(subst kf,tf,$@))"; \
 	echo "Create $@"; \
diff --git a/libgcc/dfp-bit.c b/libgcc/dfp-bit.c
index 17bca9cf203..0b0f9ace1fa 100644
--- a/libgcc/dfp-bit.c
+++ b/libgcc/dfp-bit.c
@@ -606,6 +606,7 @@ INT_TO_DFP (INT_TYPE i)
 
 #if defined (L_sd_to_sf) || defined (L_dd_to_sf) || defined (L_td_to_sf) \
  || defined (L_sd_to_df) || defined (L_dd_to_df) || defined (L_td_to_df) \
+ || defined (L_sd_to_kf) || defined (L_dd_to_kf) || defined (L_td_to_kf) \
  || ((defined (L_sd_to_xf) || defined (L_dd_to_xf) || defined (L_td_to_xf)) \
      && LONG_DOUBLE_HAS_XF_MODE) \
  || ((defined (L_sd_to_tf) || defined (L_dd_to_tf) || defined (L_td_to_tf)) \
@@ -626,6 +627,7 @@ DFP_TO_BFP (DFP_C_TYPE f)
                                                                                 
 #if defined (L_sf_to_sd) || defined (L_sf_to_dd) || defined (L_sf_to_td) \
  || defined (L_df_to_sd) || defined (L_df_to_dd) || defined (L_df_to_td) \
+ || defined (L_kf_to_sd) || defined (L_kf_to_dd) || defined (L_kf_to_td) \
  || ((defined (L_xf_to_sd) || defined (L_xf_to_dd) || defined (L_xf_to_td)) \
      && LONG_DOUBLE_HAS_XF_MODE) \
  || ((defined (L_tf_to_sd) || defined (L_tf_to_dd) || defined (L_tf_to_td)) \
@@ -641,8 +643,14 @@ BFP_TO_DFP (BFP_TYPE x)
   decContextDefault (&context, CONTEXT_INIT);
   DFP_INIT_ROUNDMODE (context.round);
 
-  /* Use a C library function to write the floating point value to a string.  */
-  sprintf (buf, BFP_FMT, (BFP_VIA_TYPE) x);
+  /* Use the sprintf library function to write the floating point value to a string.
+
+     If we are handling the IEEE 128-bit floating point on PowerPC, use the
+     special function __sprintfkf instead of sprintf.  This function allows us
+     to use __sprintfieee128 if we have a new enough GLIBC, and it can fall back
+     to using the traditional sprintf via conversion to IBM 128-bit if the glibc
+     is older.  */
+  BFP_SPRINTF (buf, BFP_FMT, (BFP_VIA_TYPE) x);
 
   /* Convert from the floating point string to a decimal* type.  */
   FROM_STRING (&s, buf, &context);
diff --git a/libgcc/dfp-bit.h b/libgcc/dfp-bit.h
index 1fa42ee621f..e33bc22f7cc 100644
--- a/libgcc/dfp-bit.h
+++ b/libgcc/dfp-bit.h
@@ -241,6 +241,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #elif defined (L_sd_to_tf) || defined (L_dd_to_tf) || defined (L_td_to_tf) \
  ||   defined (L_tf_to_sd) || defined (L_tf_to_dd) || defined (L_tf_to_td)
 #define BFP_KIND 4
+#elif defined (L_sd_to_kf) || defined (L_dd_to_kf) || defined (L_td_to_kf) \
+ ||   defined (L_kf_to_sd) || defined (L_kf_to_dd) || defined (L_kf_to_td)
+#define BFP_KIND 5
 #endif
 
 /*  If BFP_KIND is defined, define additional macros:
@@ -291,6 +294,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #define BFP_VIA_TYPE long double
 #endif /* LONG_DOUBLE_HAS_TF_MODE */
 
+#elif BFP_KIND == 5
+#define BFP_TYPE _Float128
+#define BFP_FMT "%.21Le"
+#define BFP_VIA_TYPE _Float128
+#define STR_TO_BFP __strtokf
+#include <_strtokf.h>
+
 #endif /* BFP_KIND */
 
 #if WIDTH == 128 || WIDTH_TO == 128
@@ -490,6 +500,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #elif BFP_KIND == 4
 #define BFP_TO_DFP	DPD_BID_NAME(__dpd_trunctfsd,__bid_trunctfsd)
 #define DFP_TO_BFP	DPD_BID_NAME(__dpd_extendsdtf,__bid_extendsdtf)
+#elif BFP_KIND == 5
+#define BFP_TO_DFP	DPD_BID_NAME(__dpd_trunckfsd,__bid_trunckfsd)
+#define DFP_TO_BFP	DPD_BID_NAME(__dpd_extendsdkf,__bid_extendsdkf)
 #endif /* BFP_KIND */
 
 #elif WIDTH == 64
@@ -505,6 +518,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #elif BFP_KIND == 4
 #define BFP_TO_DFP	DPD_BID_NAME(__dpd_trunctfdd,__bid_trunctfdd)
 #define DFP_TO_BFP	DPD_BID_NAME(__dpd_extendddtf,__bid_extendddtf)
+#elif BFP_KIND == 5
+#define BFP_TO_DFP	DPD_BID_NAME(__dpd_trunckfdd,__bid_trunckfdd)
+#define DFP_TO_BFP	DPD_BID_NAME(__dpd_extendddkf,__bid_extendddkf)
 #endif /* BFP_KIND */
 
 #elif WIDTH == 128
@@ -520,6 +536,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #elif BFP_KIND == 4
 #define BFP_TO_DFP	DPD_BID_NAME(__dpd_extendtftd,__bid_extendtftd)
 #define DFP_TO_BFP	DPD_BID_NAME(__dpd_trunctdtf,__bid_trunctdtf)
+#elif BFP_KIND == 5
+#define BFP_TO_DFP	DPD_BID_NAME(__dpd_extendkftd,__bid_extendkftd)
+#define DFP_TO_BFP	DPD_BID_NAME(__dpd_trunctdkf,__bid_trunctdkf)
 #endif /* BFP_KIND */
 
 #endif /* WIDTH */
@@ -609,6 +628,7 @@ extern DFP_C_TYPE INT_TO_DFP (INT_TYPE);
 
 #if defined (L_sd_to_sf) || defined (L_dd_to_sf) || defined (L_td_to_sf) \
  || defined (L_sd_to_df) || defined (L_dd_to_df) || defined (L_td_to_df) \
+ || defined (L_sd_to_kf) || defined (L_dd_to_kf) || defined (L_td_to_kf) \
  || ((defined (L_sd_to_xf) || defined (L_dd_to_xf) || defined (L_td_to_xf)) \
      && LONG_DOUBLE_HAS_XF_MODE) \
  || ((defined (L_sd_to_tf) || defined (L_dd_to_tf) || defined (L_td_to_tf)) \
@@ -623,6 +643,12 @@ extern BFP_TYPE DFP_TO_BFP (DFP_C_TYPE);
  || ((defined (L_tf_to_sd) || defined (L_tf_to_dd) || defined (L_tf_to_td)) \
      && LONG_DOUBLE_HAS_TF_MODE)
 extern DFP_C_TYPE BFP_TO_DFP (BFP_TYPE);
+#define BFP_SPRINTF sprintf
+
+#elif defined (L_kf_to_sd) || defined (L_kf_to_dd) || defined (L_kf_to_td)
+extern DFP_C_TYPE BFP_TO_DFP (BFP_TYPE);
+#include <_sprintfkf.h>
+#define BFP_SPRINTF __sprintfkf
 #endif
 
 #endif /* _DFPBIT_H */
-- 
2.22.0


-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meissner@linux.ibm.com, phone: +1 (978) 899-4797

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH, revised, #2] PowerPC: Add float128/Decimal conversions.
  2021-01-27 21:05 ` [PATCH, revised] " Michael Meissner
@ 2021-01-27 21:19   ` Michael Meissner
  0 siblings, 0 replies; 17+ messages in thread
From: Michael Meissner @ 2021-01-27 21:19 UTC (permalink / raw)
  To: Michael Meissner, gcc-patches, Segher Boessenkool,
	David Edelsohn, Bill Schmidt, Peter Bergner

From 02b04aed77130f2ec9156d2f7ff89d4cc6b5a78b Mon Sep 17 00:00:00 2001
From: Michael Meissner <meissner@linux.ibm.com>
Date: Thu, 21 Jan 2021 12:58:56 -0500
Subject: [PATCH, revised] PowerPC: Add float128/Decimal conversions.

[PATCH, revised] PowerPC: Add float128/Decimal conversions.

Unfortunately, the revision I just posted had the old patch, and not the new
patch.  This patch actually has the BFP_FMT set to "%.36Le" which gives enough
accuracy to allow c-c++-common/dfp/convert-bfp-6.c test to pass.

This patch replaces the following three patches:

September 24th, 2020:
Message-ID: <20200924203545.GD31597@ibm-toto.the-meissners.org>

October 22nd, 2020:
Message-ID: <20201022220603.GA11658@ibm-toto.the-meissners.org>

January 14th, 2021:
Message-ID: <20210114170936.GA3319@ibm-toto.the-meissners.org>
https://gcc.gnu.org/pipermail/gcc-patches/2021-January/563498.html

This patch rewrites those patches.  In order to run with older GLIBC's, this
patch uses weak references to the IEEE 128-bit conversions to/from string that
are found in GLIBC 2.32.

If the user uses GLIBC 2.32 or later, the Decimal <-> Float128 conversions will
call the functions in that library.  This isn't ideal, as IEEE 128-bit has more
exponent range than IBM 128-bit.

If an older library is used, these patches will convert IEEE 128-bit to IBM
128-bit and do the conversion with IBM 128-bit.  I have tested this with a
compiler configured to use an older library, and it worked for the conversion
if the number could be represented in the IBM 128-bit format.

While most of the Decimal <-> Long double tests now pass when long doubles are
IEEE 128-bit, there is one test that fails:

    *	c-c++-common/dfp/convert-bfp-11.c

I have patches for the bfp-11 test (which requires that long double be IBM
128-bit).

Compared to the patch on January 14th, this patch fixes the format string
for converting IEEE 128-bit floating point to string.  This in turn allows
the c-c++-common/dfp/convert-bfp-6.c to pass.

I have tested this patch by doing builds, bootstraps, and make check with 3
builds on a power9 little endian server:

    *   Build one used the default long double being IBM 128-bit;
    *   Build two set the long double default to IEEE 128-bit; (and)
    *   Build three set the long double default to 64-bit.

I have also built and tested this patch on a big endian Power8 system with
both 64 and 32-bit targets.  There were no regressions.

The compilers built fine providing I recompiled gmp, mpc, and mpfr with the
appropriate long double options.  There were a few differences in the test
suite runs that will be addressed in later patches, but over all it works
well.  This patch is required to be able to build a toolchain where the default
long double is IEEE 128-bit.  Can I check this patch into the master branch for
GCC 11?

libgcc/
2021-01-27  Michael Meissner  <meissner@linux.ibm.com>

	* config/rs6000/_dd_to_kf.c: New file.
	* config/rs6000/_kf_to_dd.c: New file.
	* config/rs6000/_kf_to_sd.c: New file.
	* config/rs6000/_kf_to_td.c: New file.
	* config/rs6000/_sd_to_kf.c: New file.
	* config/rs6000/_sprintfkf.c: New file.
	* config/rs6000/_sprintfkf.h: New file.
	* config/rs6000/_strtokf.h: New file.
	* config/rs6000/_strtokf.c: New file.
	* config/rs6000/_td_to_kf.c: New file.
	* config/rs6000/quad-float128.h: Add new declarations.
	* config/rs6000/t-float128 (fp128_dec_funcs): New macro.
	(fp128_decstr_funcs): New macro.
	(ibm128_dec_funcs): New macro.
	(fp128_ppc_funcs): Add the new conversions.
	(fp128_dec_objs): Force Decimal <-> __float128 conversions to be
	compiled with -mabi=ieeelongdouble.
	(fp128_decstr_objs): Force __float128 <-> string conversions to be
	compiled with -mabi=ibmlongdouble.
	(ibm128_dec_objs): Force Decimal <-> __float128 conversions to be
	compiled with -mabi=ieeelongdouble.
	(FP128_CFLAGS_DECIMAL): New macro.
	(IBM128_CFLAGS_DECIMAL): New macro.
	* dfp-bit.c (DFP_TO_BFP): Add PowerPC _Float128 support.
	(BFP_TO_DFP): Add PowerPC _Float128 support.
	* dfp-bit.h (BFP_KIND): Add new binary floating point kind for
	IEEE 128-bit floating point.
	(DFP_TO_BFP): Add PowerPC _Float128 support.
	(BFP_TO_DFP): Add PowerPC _Float128 support.
	(BFP_SPRINTF): New macro.
---
 libgcc/config/rs6000/_dd_to_kf.c     | 37 ++++++++++++++++++
 libgcc/config/rs6000/_kf_to_dd.c     | 37 ++++++++++++++++++
 libgcc/config/rs6000/_kf_to_sd.c     | 37 ++++++++++++++++++
 libgcc/config/rs6000/_kf_to_td.c     | 37 ++++++++++++++++++
 libgcc/config/rs6000/_sd_to_kf.c     | 37 ++++++++++++++++++
 libgcc/config/rs6000/_sprintfkf.c    | 57 ++++++++++++++++++++++++++++
 libgcc/config/rs6000/_sprintfkf.h    | 28 ++++++++++++++
 libgcc/config/rs6000/_strtokf.c      | 56 +++++++++++++++++++++++++++
 libgcc/config/rs6000/_strtokf.h      | 27 +++++++++++++
 libgcc/config/rs6000/_td_to_kf.c     | 37 ++++++++++++++++++
 libgcc/config/rs6000/quad-float128.h |  8 ++++
 libgcc/config/rs6000/t-float128      | 37 +++++++++++++++++-
 libgcc/dfp-bit.c                     | 12 +++++-
 libgcc/dfp-bit.h                     | 26 +++++++++++++
 14 files changed, 470 insertions(+), 3 deletions(-)
 create mode 100644 libgcc/config/rs6000/_dd_to_kf.c
 create mode 100644 libgcc/config/rs6000/_kf_to_dd.c
 create mode 100644 libgcc/config/rs6000/_kf_to_sd.c
 create mode 100644 libgcc/config/rs6000/_kf_to_td.c
 create mode 100644 libgcc/config/rs6000/_sd_to_kf.c
 create mode 100644 libgcc/config/rs6000/_sprintfkf.c
 create mode 100644 libgcc/config/rs6000/_sprintfkf.h
 create mode 100644 libgcc/config/rs6000/_strtokf.c
 create mode 100644 libgcc/config/rs6000/_strtokf.h
 create mode 100644 libgcc/config/rs6000/_td_to_kf.c

diff --git a/libgcc/config/rs6000/_dd_to_kf.c b/libgcc/config/rs6000/_dd_to_kf.c
new file mode 100644
index 00000000000..3b4d8500a57
--- /dev/null
+++ b/libgcc/config/rs6000/_dd_to_kf.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1989-2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC 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 General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+/* Decimal64 -> _Float128 conversion.  */
+
+/* FINE_GRAINED_LIBRARIES is used so we can isolate just to dd_to_tf conversion
+   function from dp-bits.c.  */
+#define FINE_GRAINED_LIBRARIES	1
+#define L_dd_to_kf		1
+#define WIDTH			64
+
+#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IEEE128__)
+#error "Long double is not IEEE 128-bit"
+#endif
+
+/* Use dfp-bit.c to do the real work.  */
+#include "dfp-bit.c"
diff --git a/libgcc/config/rs6000/_kf_to_dd.c b/libgcc/config/rs6000/_kf_to_dd.c
new file mode 100644
index 00000000000..8d1c49dd396
--- /dev/null
+++ b/libgcc/config/rs6000/_kf_to_dd.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1989-2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC 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 General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+/* _Float128 -> Decimal64 conversion.  */
+
+/* FINE_GRAINED_LIBRARIES is used so we can isolate just to tf_to_dd conversion
+   function from dp-bits.c.  */
+#define FINE_GRAINED_LIBRARIES	1
+#define L_kf_to_dd		1
+#define WIDTH			64
+
+#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IEEE128__)
+#error "Long double is not IEEE 128-bit"
+#endif
+
+/* Use dfp-bit.c to do the real work.  */
+#include "dfp-bit.c"
diff --git a/libgcc/config/rs6000/_kf_to_sd.c b/libgcc/config/rs6000/_kf_to_sd.c
new file mode 100644
index 00000000000..b02082d6f52
--- /dev/null
+++ b/libgcc/config/rs6000/_kf_to_sd.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1989-2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC 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 General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+/* _Float128 -> Decimal32 conversion.  */
+
+/* FINE_GRAINED_LIBRARIES is used so we can isolate just to tf_to_sd conversion
+   function from dp-bits.c.  */
+#define FINE_GRAINED_LIBRARIES	1
+#define L_kf_to_sd		1
+#define WIDTH			32
+
+#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IEEE128__)
+#error "Long double is not IEEE 128-bit"
+#endif
+
+/* Use dfp-bit.c to do the real work.  */
+#include "dfp-bit.c"
diff --git a/libgcc/config/rs6000/_kf_to_td.c b/libgcc/config/rs6000/_kf_to_td.c
new file mode 100644
index 00000000000..f120709bb42
--- /dev/null
+++ b/libgcc/config/rs6000/_kf_to_td.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1989-2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC 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 General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+/* _Float128 -> Decimal128 conversion.  */
+
+/* FINE_GRAINED_LIBRARIES is used so we can isolate just to tf_to_td conversion
+   function from dp-bits.c.  */
+#define FINE_GRAINED_LIBRARIES	1
+#define L_kf_to_td		1
+#define WIDTH			128
+
+#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IEEE128__)
+#error "Long double is not IEEE 128-bit"
+#endif
+
+/* Use dfp-bit.c to do the real work.  */
+#include "dfp-bit.c"
diff --git a/libgcc/config/rs6000/_sd_to_kf.c b/libgcc/config/rs6000/_sd_to_kf.c
new file mode 100644
index 00000000000..df222abdeab
--- /dev/null
+++ b/libgcc/config/rs6000/_sd_to_kf.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1989-2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC 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 General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+/* Decimal32 -> _Float128 conversion.  */
+
+/* FINE_GRAINED_LIBRARIES is used so we can isolate just to sd_to_tf conversion
+   function from dp-bits.c.  */
+#define FINE_GRAINED_LIBRARIES	1
+#define L_sd_to_kf		1
+#define WIDTH			32
+
+#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IEEE128__)
+#error "Long double is not IEEE 128-bit"
+#endif
+
+/* Use dfp-bit.c to do the real work.  */
+#include "dfp-bit.c"
diff --git a/libgcc/config/rs6000/_sprintfkf.c b/libgcc/config/rs6000/_sprintfkf.c
new file mode 100644
index 00000000000..e5ea8eb3b4e
--- /dev/null
+++ b/libgcc/config/rs6000/_sprintfkf.c
@@ -0,0 +1,57 @@
+/* Copyright (C) 1989-2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC 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 General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+/* Conversion to IEEE 128-bit floating point from string using snprintf.  */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <soft-fp.h>
+#include <quad-float128.h>
+#include <stdio.h>
+
+/* This function must be built with IBM 128-bit as long double, so that we can
+   access the strfroml function if do not have an IEEE 128-bit version, and if
+   that is not available, use sprintf.  */
+#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IBM128__)
+#error "Long double is not IBM 128-bit"
+#endif
+
+/* If the user is using GLIBC 2.32, we can use the __snprintfieee128 function.
+
+   If we are linked against an earlier library, we will have fake it by
+   converting the value to long double, and using sprinf to do the conversion.
+   This isn't ideal, as IEEE 128-bit has more exponent range than IBM
+   128-bit.  */
+
+extern int __sprintfieee128 (char *restrict, const char *restrict, ...)
+  __attribute__ ((__weak__));
+
+int __sprintfkf (char *restrict string,
+		 const char *restrict format,
+		 _Float128 number)
+{
+  if (__sprintfieee128)
+    return __sprintfieee128 (string, format, number);
+
+  return sprintf (string, format, (long double)number);
+}
diff --git a/libgcc/config/rs6000/_sprintfkf.h b/libgcc/config/rs6000/_sprintfkf.h
new file mode 100644
index 00000000000..637d104c882
--- /dev/null
+++ b/libgcc/config/rs6000/_sprintfkf.h
@@ -0,0 +1,28 @@
+/* Copyright (C) 1989-2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC 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 General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+/* Declaration of the conversion function to IEEE 128-bit floating point from
+   string using snprintf.  */
+
+extern int __sprintfkf (char *restrict, const char *restrict, ...);
+
diff --git a/libgcc/config/rs6000/_strtokf.c b/libgcc/config/rs6000/_strtokf.c
new file mode 100644
index 00000000000..696a2c907bb
--- /dev/null
+++ b/libgcc/config/rs6000/_strtokf.c
@@ -0,0 +1,56 @@
+/* Copyright (C) 1989-2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC 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 General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+/* Conversion to IEEE 128-bit floating point from string.  */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <soft-fp.h>
+#include <quad-float128.h>
+
+/* This function must be built with IBM 128-bit as long double, so that we can
+   access the strtold function if do not have an IEEE 128-bit version.  */
+#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IBM128__)
+#error "Long double is not IBM 128-bit"
+#endif
+
+/* If the user is using GLIBC 2.32, we can use the __strtoieee128 function.
+
+   If we are linked against an earlier library, we will have fake it by
+   converting the string to IBM 128-bit long double, and then converting that to
+   __float128.  This isn't ideal, as IEEE 128-bit has more exponent range than
+   IBM 128-bit.  */
+
+extern _Float128 __strtoieee128 (const char *, char **) __attribute__ ((__weak__));
+
+_Float128
+__strtokf (const char *string, char **endptr)
+{
+  long double num;
+
+  if (__strtoieee128)
+    return __strtoieee128 (string, endptr);
+
+  num = strtold (string, endptr);
+  return (_Float128) num;
+}
diff --git a/libgcc/config/rs6000/_strtokf.h b/libgcc/config/rs6000/_strtokf.h
new file mode 100644
index 00000000000..a7ca8e09244
--- /dev/null
+++ b/libgcc/config/rs6000/_strtokf.h
@@ -0,0 +1,27 @@
+/* Copyright (C) 1989-2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC 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 General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+/* Declaration of the conversion function to IEEE 128-bit floating point from
+   string.  */
+
+extern _Float128 __strtokf (const char *, char **);
diff --git a/libgcc/config/rs6000/_td_to_kf.c b/libgcc/config/rs6000/_td_to_kf.c
new file mode 100644
index 00000000000..330a7802827
--- /dev/null
+++ b/libgcc/config/rs6000/_td_to_kf.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1989-2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC 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 General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+/* Decimal128 -> _Float128 conversion.  */
+
+/* FINE_GRAINED_LIBRARIES is used so we can isolate just to td_to_tf conversion
+   function from dp-bits.c.  */
+#define FINE_GRAINED_LIBRARIES	1
+#define L_td_to_kf		1
+#define WIDTH			128
+
+#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IEEE128__)
+#error "Long double is not IEEE 128-bit"
+#endif
+
+/* Use dfp-bit.c to do the real work.  */
+#include "dfp-bit.c"
diff --git a/libgcc/config/rs6000/quad-float128.h b/libgcc/config/rs6000/quad-float128.h
index 0eb1d34691f..5beb1531d2b 100644
--- a/libgcc/config/rs6000/quad-float128.h
+++ b/libgcc/config/rs6000/quad-float128.h
@@ -49,6 +49,7 @@ typedef __complex float TCtype __attribute__ ((mode (TC)));
 #pragma GCC target ("vsx,float128")
 #endif
 
+#include <stddef.h>
 #include <quad.h>
 
 #define IBM128_TYPE	__ibm128
@@ -171,6 +172,13 @@ extern TFtype __trunctfkf2 (IBM128_TYPE);
 extern TCtype __mulkc3 (TFtype, TFtype, TFtype, TFtype);
 extern TCtype __divkc3 (TFtype, TFtype, TFtype, TFtype);
 
+/* Convert IEEE 128-bit floating point to/from string.  We explicitly use
+   _Float128 instead of TFmode because _strtokf and _strfromkf must be compiled
+   with long double being IBM 128.  */
+extern _Float128 __strtokf (const char *, char **);
+extern int __strfromkf (char *restrict, size_t, const char *restrict,
+			_Float128);
+
 /* Implementation of conversions between __ibm128 and __float128, to allow the
    same code to be used on systems with IEEE 128-bit emulation and with IEEE
    128-bit hardware support.  */
diff --git a/libgcc/config/rs6000/t-float128 b/libgcc/config/rs6000/t-float128
index d5413445189..6fb1a3d871b 100644
--- a/libgcc/config/rs6000/t-float128
+++ b/libgcc/config/rs6000/t-float128
@@ -22,10 +22,23 @@ fp128_softfp_static_obj	= $(addsuffix -sw$(objext),$(fp128_softfp_funcs))
 fp128_softfp_shared_obj	= $(addsuffix -sw_s$(objext),$(fp128_softfp_funcs))
 fp128_softfp_obj	= $(fp128_softfp_static_obj) $(fp128_softfp_shared_obj)
 
+# Decimal <-> _Float128 conversions
+fp128_dec_funcs		= _kf_to_sd _kf_to_dd _kf_to_td \
+			  _sd_to_kf _dd_to_kf _td_to_kf
+
+# _Float128 to/from string conversions that must be compiled with IBM 128-bit
+# long double.
+fp128_decstr_funcs	= _strtokf _sprintfkf
+
+# Decimal <-> __ibm128 conversions
+ibm128_dec_funcs	= _tf_to_sd _tf_to_dd _tf_to_td \
+			  _sd_to_tf _dd_to_tf _td_to_tf
+
 # New functions for software emulation
 fp128_ppc_funcs		= floattikf floatuntikf fixkfti fixunskfti \
 			  extendkftf2-sw trunctfkf2-sw \
-			  sfp-exceptions _mulkc3 _divkc3 _powikf2
+			  sfp-exceptions _mulkc3 _divkc3 _powikf2 \
+			  $(fp128_dec_funcs) $(fp128_decstr_funcs)
 
 fp128_ppc_src		= $(addprefix $(srcdir)/config/rs6000/,$(addsuffix \
 				.c,$(fp128_ppc_funcs)))
@@ -69,6 +82,28 @@ $(fp128_ppc_obj)	 : INTERNAL_CFLAGS += $(FP128_CFLAGS_SW)
 $(fp128_obj)		 : $(fp128_includes)
 $(fp128_obj)		 : $(srcdir)/config/rs6000/quad-float128.h
 
+# Force the TF mode to/from decimal functions to be compiled with IBM long
+# double.  Add building the KF mode to/from decimal conversions with explict
+# IEEE long double.
+fp128_dec_objs		= $(addsuffix $(objext),$(fp128_dec_funcs)) \
+			  $(addsuffix _s$(objext),$(fp128_dec_funcs))
+
+fp128_decstr_objs	= $(addsuffix $(objext),$(fp128_decstr_funcs)) \
+			  $(addsuffix _s$(objext),$(fp128_decstr_funcs))
+
+ibm128_dec_objs		= $(addsuffix $(objext),$(ibm128_dec_funcs)) \
+			  $(addsuffix _s$(objext),$(ibm128_dec_funcs))
+
+FP128_CFLAGS_DECIMAL	= -mno-gnu-attribute -Wno-psabi -mabi=ieeelongdouble
+IBM128_CFLAGS_DECIMAL	= -mno-gnu-attribute -Wno-psabi -mabi=ibmlongdouble
+
+$(fp128_dec_objs)	: INTERNAL_CFLAGS += $(FP128_CFLAGS_DECIMAL)
+$(fp128_decstr_objs)	: INTERNAL_CFLAGS += $(IBM128_CFLAGS_DECIMAL)
+$(ibm128_dec_objs)	: INTERNAL_CFLAGS += $(IBM128_CFLAGS_DECIMAL)
+
+$(fp128_decstr_objs)	: $(srcdir)/config/rs6000/_strtokf.h \
+			  $(srcdir)/config/rs6000/_sprintfkf.h \
+
 $(fp128_softfp_src) : $(srcdir)/soft-fp/$(subst -sw,,$(subst kf,tf,$@)) $(fp128_dep)
 	@src="$(srcdir)/soft-fp/$(subst -sw,,$(subst kf,tf,$@))"; \
 	echo "Create $@"; \
diff --git a/libgcc/dfp-bit.c b/libgcc/dfp-bit.c
index 17bca9cf203..0b0f9ace1fa 100644
--- a/libgcc/dfp-bit.c
+++ b/libgcc/dfp-bit.c
@@ -606,6 +606,7 @@ INT_TO_DFP (INT_TYPE i)
 
 #if defined (L_sd_to_sf) || defined (L_dd_to_sf) || defined (L_td_to_sf) \
  || defined (L_sd_to_df) || defined (L_dd_to_df) || defined (L_td_to_df) \
+ || defined (L_sd_to_kf) || defined (L_dd_to_kf) || defined (L_td_to_kf) \
  || ((defined (L_sd_to_xf) || defined (L_dd_to_xf) || defined (L_td_to_xf)) \
      && LONG_DOUBLE_HAS_XF_MODE) \
  || ((defined (L_sd_to_tf) || defined (L_dd_to_tf) || defined (L_td_to_tf)) \
@@ -626,6 +627,7 @@ DFP_TO_BFP (DFP_C_TYPE f)
                                                                                 
 #if defined (L_sf_to_sd) || defined (L_sf_to_dd) || defined (L_sf_to_td) \
  || defined (L_df_to_sd) || defined (L_df_to_dd) || defined (L_df_to_td) \
+ || defined (L_kf_to_sd) || defined (L_kf_to_dd) || defined (L_kf_to_td) \
  || ((defined (L_xf_to_sd) || defined (L_xf_to_dd) || defined (L_xf_to_td)) \
      && LONG_DOUBLE_HAS_XF_MODE) \
  || ((defined (L_tf_to_sd) || defined (L_tf_to_dd) || defined (L_tf_to_td)) \
@@ -641,8 +643,14 @@ BFP_TO_DFP (BFP_TYPE x)
   decContextDefault (&context, CONTEXT_INIT);
   DFP_INIT_ROUNDMODE (context.round);
 
-  /* Use a C library function to write the floating point value to a string.  */
-  sprintf (buf, BFP_FMT, (BFP_VIA_TYPE) x);
+  /* Use the sprintf library function to write the floating point value to a string.
+
+     If we are handling the IEEE 128-bit floating point on PowerPC, use the
+     special function __sprintfkf instead of sprintf.  This function allows us
+     to use __sprintfieee128 if we have a new enough GLIBC, and it can fall back
+     to using the traditional sprintf via conversion to IBM 128-bit if the glibc
+     is older.  */
+  BFP_SPRINTF (buf, BFP_FMT, (BFP_VIA_TYPE) x);
 
   /* Convert from the floating point string to a decimal* type.  */
   FROM_STRING (&s, buf, &context);
diff --git a/libgcc/dfp-bit.h b/libgcc/dfp-bit.h
index 1fa42ee621f..e33bc22f7cc 100644
--- a/libgcc/dfp-bit.h
+++ b/libgcc/dfp-bit.h
@@ -241,6 +241,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #elif defined (L_sd_to_tf) || defined (L_dd_to_tf) || defined (L_td_to_tf) \
  ||   defined (L_tf_to_sd) || defined (L_tf_to_dd) || defined (L_tf_to_td)
 #define BFP_KIND 4
+#elif defined (L_sd_to_kf) || defined (L_dd_to_kf) || defined (L_td_to_kf) \
+ ||   defined (L_kf_to_sd) || defined (L_kf_to_dd) || defined (L_kf_to_td)
+#define BFP_KIND 5
 #endif
 
 /*  If BFP_KIND is defined, define additional macros:
@@ -291,6 +294,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #define BFP_VIA_TYPE long double
 #endif /* LONG_DOUBLE_HAS_TF_MODE */
 
+#elif BFP_KIND == 5
+#define BFP_TYPE _Float128
+#define BFP_FMT "%.36Le"
+#define BFP_VIA_TYPE _Float128
+#define STR_TO_BFP __strtokf
+#include <_strtokf.h>
+
 #endif /* BFP_KIND */
 
 #if WIDTH == 128 || WIDTH_TO == 128
@@ -490,6 +500,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #elif BFP_KIND == 4
 #define BFP_TO_DFP	DPD_BID_NAME(__dpd_trunctfsd,__bid_trunctfsd)
 #define DFP_TO_BFP	DPD_BID_NAME(__dpd_extendsdtf,__bid_extendsdtf)
+#elif BFP_KIND == 5
+#define BFP_TO_DFP	DPD_BID_NAME(__dpd_trunckfsd,__bid_trunckfsd)
+#define DFP_TO_BFP	DPD_BID_NAME(__dpd_extendsdkf,__bid_extendsdkf)
 #endif /* BFP_KIND */
 
 #elif WIDTH == 64
@@ -505,6 +518,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #elif BFP_KIND == 4
 #define BFP_TO_DFP	DPD_BID_NAME(__dpd_trunctfdd,__bid_trunctfdd)
 #define DFP_TO_BFP	DPD_BID_NAME(__dpd_extendddtf,__bid_extendddtf)
+#elif BFP_KIND == 5
+#define BFP_TO_DFP	DPD_BID_NAME(__dpd_trunckfdd,__bid_trunckfdd)
+#define DFP_TO_BFP	DPD_BID_NAME(__dpd_extendddkf,__bid_extendddkf)
 #endif /* BFP_KIND */
 
 #elif WIDTH == 128
@@ -520,6 +536,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #elif BFP_KIND == 4
 #define BFP_TO_DFP	DPD_BID_NAME(__dpd_extendtftd,__bid_extendtftd)
 #define DFP_TO_BFP	DPD_BID_NAME(__dpd_trunctdtf,__bid_trunctdtf)
+#elif BFP_KIND == 5
+#define BFP_TO_DFP	DPD_BID_NAME(__dpd_extendkftd,__bid_extendkftd)
+#define DFP_TO_BFP	DPD_BID_NAME(__dpd_trunctdkf,__bid_trunctdkf)
 #endif /* BFP_KIND */
 
 #endif /* WIDTH */
@@ -609,6 +628,7 @@ extern DFP_C_TYPE INT_TO_DFP (INT_TYPE);
 
 #if defined (L_sd_to_sf) || defined (L_dd_to_sf) || defined (L_td_to_sf) \
  || defined (L_sd_to_df) || defined (L_dd_to_df) || defined (L_td_to_df) \
+ || defined (L_sd_to_kf) || defined (L_dd_to_kf) || defined (L_td_to_kf) \
  || ((defined (L_sd_to_xf) || defined (L_dd_to_xf) || defined (L_td_to_xf)) \
      && LONG_DOUBLE_HAS_XF_MODE) \
  || ((defined (L_sd_to_tf) || defined (L_dd_to_tf) || defined (L_td_to_tf)) \
@@ -623,6 +643,12 @@ extern BFP_TYPE DFP_TO_BFP (DFP_C_TYPE);
  || ((defined (L_tf_to_sd) || defined (L_tf_to_dd) || defined (L_tf_to_td)) \
      && LONG_DOUBLE_HAS_TF_MODE)
 extern DFP_C_TYPE BFP_TO_DFP (BFP_TYPE);
+#define BFP_SPRINTF sprintf
+
+#elif defined (L_kf_to_sd) || defined (L_kf_to_dd) || defined (L_kf_to_td)
+extern DFP_C_TYPE BFP_TO_DFP (BFP_TYPE);
+#include <_sprintfkf.h>
+#define BFP_SPRINTF __sprintfkf
 #endif
 
 #endif /* _DFPBIT_H */
-- 
2.22.0


-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meissner@linux.ibm.com, phone: +1 (978) 899-4797

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Ping] PowerPC: Add float128/Decimal conversions.
  2021-01-26 23:43 ` [Ping] " Michael Meissner
@ 2021-01-28  3:11   ` Segher Boessenkool
  2021-01-28 18:10     ` Michael Meissner
  0 siblings, 1 reply; 17+ messages in thread
From: Segher Boessenkool @ 2021-01-28  3:11 UTC (permalink / raw)
  To: Michael Meissner, gcc-patches, David Edelsohn, Bill Schmidt,
	Peter Bergner

On Tue, Jan 26, 2021 at 06:43:06PM -0500, Michael Meissner wrote:
> I posted this patch on January 14th, 2021:
> https://gcc.gnu.org/pipermail/gcc-patches/2021-January/563498.html
> 
> | Date: Thu, 14 Jan 2021 12:09:36 -0500
> | Subject: [PATCH] PowerPC: Add float128/Decimal conversions.
> | Message-ID: <20210114170936.GA3319@ibm-toto.the-meissners.org>
> 
> You had a question about what changed, and I replied:
> 
> | In your last message, you said that it was unacceptable that the conversion
> | fails if the user uses an old GLIBC.  So I rewrote the code using weak
> | references.  If the user has at least GLIBC 2.32, it will use the IEEE 128-bit
> | string support in the library.
> |
> | If an older GLIBC is used, I then use the IBM 128-bit format as an intermediate
> | value.  Obviously there are cases where IEEE 128-bit can hold values that IBM
> | 128-bit can't (mostly due to the increased exponent range in IEEE 128-bit), but
> | it at least does the conversion for the numbers in the common range.
> |
> | In doing this transformation, I needed to do minor edits to the main decimal
> | to/from binary conversion functions to allow the KF functions to be declared.
> | Previously, I used preprocessor magic to rename the functions.
> 
> This is the second most important patch in the IEEE 128-bit work.  What do I
> need to do to be able to commit the patch?

The whole thread is at https://patchwork.ozlabs.org/project/gcc/patch/20201120000524.GA903@ibm-toto.the-meissners.org/ .

I approved *that* version of the patch.


Segher

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Ping] PowerPC: Add float128/Decimal conversions.
  2021-01-28  3:11   ` Segher Boessenkool
@ 2021-01-28 18:10     ` Michael Meissner
  2021-01-28 18:59       ` Segher Boessenkool
  0 siblings, 1 reply; 17+ messages in thread
From: Michael Meissner @ 2021-01-28 18:10 UTC (permalink / raw)
  To: Segher Boessenkool
  Cc: Michael Meissner, gcc-patches, David Edelsohn, Bill Schmidt,
	Peter Bergner

On Wed, Jan 27, 2021 at 09:11:49PM -0600, Segher Boessenkool wrote:
> On Tue, Jan 26, 2021 at 06:43:06PM -0500, Michael Meissner wrote:
> > I posted this patch on January 14th, 2021:
> > https://gcc.gnu.org/pipermail/gcc-patches/2021-January/563498.html
> > 
> > | Date: Thu, 14 Jan 2021 12:09:36 -0500
> > | Subject: [PATCH] PowerPC: Add float128/Decimal conversions.
> > | Message-ID: <20210114170936.GA3319@ibm-toto.the-meissners.org>
> > 
> > You had a question about what changed, and I replied:
> > 
> > | In your last message, you said that it was unacceptable that the conversion
> > | fails if the user uses an old GLIBC.  So I rewrote the code using weak
> > | references.  If the user has at least GLIBC 2.32, it will use the IEEE 128-bit
> > | string support in the library.
> > |
> > | If an older GLIBC is used, I then use the IBM 128-bit format as an intermediate
> > | value.  Obviously there are cases where IEEE 128-bit can hold values that IBM
> > | 128-bit can't (mostly due to the increased exponent range in IEEE 128-bit), but
> > | it at least does the conversion for the numbers in the common range.
> > |
> > | In doing this transformation, I needed to do minor edits to the main decimal
> > | to/from binary conversion functions to allow the KF functions to be declared.
> > | Previously, I used preprocessor magic to rename the functions.
> > 
> > This is the second most important patch in the IEEE 128-bit work.  What do I
> > need to do to be able to commit the patch?
> 
> The whole thread is at https://patchwork.ozlabs.org/project/gcc/patch/20201120000524.GA903@ibm-toto.the-meissners.org/ .
> 
> I approved *that* version of the patch.

Yes you approved the built-in renaming patch and I checked in the patch that
you approved (rather than the modifications that I submitted).

However, this is about the second patch (that provides conversions between
_Float128 and Decimal), which as far as I can tell was not approved.  That is
what this particular question is about.

You did not like the previous _Float128 <-> Decimal conversion patch because it
was tied into having a minimum GLIBC version.

So, I rewrote the whole patch so that it will work with older GLIBC's.

If you have a newer GLIBC (detected at runtime via a weak reference), it uses
the support functions in the new GLIBC to do the conversion.  I had a cut+paste
error in the original patch that I resubmitted, and I resubmitted with the
changed line.

If you have an older GLIBC and want to convert _Float128 to one of the Decimal
types, it will convert the _Float128 to __ibm128 and then convert that to
Decimal.

Similarly if you have one of the Decimal types, and want to convert to
_Float128, it will first convert the Decimal type to __ibm128, and then convert
__ibm128 to _Float128.

So what do I do?  Can I check in this patch or do I need to do further
modifications.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meissner@linux.ibm.com, phone: +1 (978) 899-4797

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Ping] PowerPC: Add float128/Decimal conversions.
  2021-01-28 18:10     ` Michael Meissner
@ 2021-01-28 18:59       ` Segher Boessenkool
  2021-01-28 19:30         ` Michael Meissner
  0 siblings, 1 reply; 17+ messages in thread
From: Segher Boessenkool @ 2021-01-28 18:59 UTC (permalink / raw)
  To: Michael Meissner, gcc-patches, David Edelsohn, Bill Schmidt,
	Peter Bergner

On Thu, Jan 28, 2021 at 01:10:39PM -0500, Michael Meissner wrote:
> > The whole thread is at https://patchwork.ozlabs.org/project/gcc/patch/20201120000524.GA903@ibm-toto.the-meissners.org/ .
> > 
> > I approved *that* version of the patch.
> 
> Yes you approved the built-in renaming patch and I checked in the patch that
> you approved (rather than the modifications that I submitted).
> 
> However, this is about the second patch (that provides conversions between
> _Float128 and Decimal), which as far as I can tell was not approved.  That is
> what this particular question is about.

I see no second patch?

> So, I rewrote the whole patch so that it will work with older GLIBC's.

Did you check in what I approved or not?  It is a very simple question,
it's just about facts, with a simple yes/no answer.


Segher

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Ping] PowerPC: Add float128/Decimal conversions.
  2021-01-28 18:59       ` Segher Boessenkool
@ 2021-01-28 19:30         ` Michael Meissner
  2021-01-28 19:47           ` Segher Boessenkool
  0 siblings, 1 reply; 17+ messages in thread
From: Michael Meissner @ 2021-01-28 19:30 UTC (permalink / raw)
  To: Segher Boessenkool
  Cc: Michael Meissner, gcc-patches, David Edelsohn, Bill Schmidt,
	Peter Bergner

On Thu, Jan 28, 2021 at 12:59:18PM -0600, Segher Boessenkool wrote:
> On Thu, Jan 28, 2021 at 01:10:39PM -0500, Michael Meissner wrote:
> > > The whole thread is at https://patchwork.ozlabs.org/project/gcc/patch/20201120000524.GA903@ibm-toto.the-meissners.org/ .
> > > 
> > > I approved *that* version of the patch.
> > 
> > Yes you approved the built-in renaming patch and I checked in the patch that
> > you approved (rather than the modifications that I submitted).
> > 
> > However, this is about the second patch (that provides conversions between
> > _Float128 and Decimal), which as far as I can tell was not approved.  That is
> > what this particular question is about.
> 
> I see no second patch?
> 
> > So, I rewrote the whole patch so that it will work with older GLIBC's.
> 
> Did you check in what I approved or not?  It is a very simple question,
> it's just about facts, with a simple yes/no answer.

Yes I checked in that patch earlier this morning (the original patch that you
approved).

The second patch I want you to review is:
https://gcc.gnu.org/pipermail/gcc-patches/2021-January/564407.html

| Date: Wed, 27 Jan 2021 16:19:52 -0500
| Subject: [PATCH, revised, #2] PowerPC: Add float128/Decimal conversions.
| Message-ID: <20210127211952.GA28165@ibm-toto.the-meissners.org>

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meissner@linux.ibm.com, phone: +1 (978) 899-4797

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Ping] PowerPC: Add float128/Decimal conversions.
  2021-01-28 19:30         ` Michael Meissner
@ 2021-01-28 19:47           ` Segher Boessenkool
  2021-01-28 19:58             ` Peter Bergner
  0 siblings, 1 reply; 17+ messages in thread
From: Segher Boessenkool @ 2021-01-28 19:47 UTC (permalink / raw)
  To: Michael Meissner, gcc-patches, David Edelsohn, Bill Schmidt,
	Peter Bergner

On Thu, Jan 28, 2021 at 02:30:56PM -0500, Michael Meissner wrote:
> On Thu, Jan 28, 2021 at 12:59:18PM -0600, Segher Boessenkool wrote:
> > On Thu, Jan 28, 2021 at 01:10:39PM -0500, Michael Meissner wrote:
> > > > The whole thread is at https://patchwork.ozlabs.org/project/gcc/patch/20201120000524.GA903@ibm-toto.the-meissners.org/ .
> > > > 
> > > > I approved *that* version of the patch.
> > > 
> > > Yes you approved the built-in renaming patch and I checked in the patch that
> > > you approved (rather than the modifications that I submitted).
> > > 
> > > However, this is about the second patch (that provides conversions between
> > > _Float128 and Decimal), which as far as I can tell was not approved.  That is
> > > what this particular question is about.
> > 
> > I see no second patch?
> > 
> > > So, I rewrote the whole patch so that it will work with older GLIBC's.
> > 
> > Did you check in what I approved or not?  It is a very simple question,
> > it's just about facts, with a simple yes/no answer.
> 
> Yes I checked in that patch earlier this morning (the original patch that you
> approved).
> 
> The second patch I want you to review is:

"This patch replaces the following three patches:"

Please send a patch that modifies *current* code, and that is *tested*
with that.  With a good explanation, and a commit message for *that*
patch (not for other, older patches).


Segher

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Ping] PowerPC: Add float128/Decimal conversions.
  2021-01-28 19:47           ` Segher Boessenkool
@ 2021-01-28 19:58             ` Peter Bergner
  2021-01-28 21:26               ` Segher Boessenkool
  0 siblings, 1 reply; 17+ messages in thread
From: Peter Bergner @ 2021-01-28 19:58 UTC (permalink / raw)
  To: Segher Boessenkool, Michael Meissner, gcc-patches,
	David Edelsohn, Bill Schmidt

On 1/28/21 1:47 PM, Segher Boessenkool wrote:
> On Thu, Jan 28, 2021 at 02:30:56PM -0500, Michael Meissner wrote:
>> The second patch I want you to review is:
> 
> "This patch replaces the following three patches:"
> 
> Please send a patch that modifies *current* code, and that is *tested*
> with that.  With a good explanation, and a commit message for *that*
> patch (not for other, older patches).

Isn't the email Mike linked to which was submitted yesterday exactly this?
Admittedly, it doesn't have a "commit message header", but it does seem to
be against current code and he did say he tested it and there is some
explanation given, just not in a commit message form.  Is it just a nice
commit message you're looking for now?


Peter




^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Ping] PowerPC: Add float128/Decimal conversions.
  2021-01-28 19:58             ` Peter Bergner
@ 2021-01-28 21:26               ` Segher Boessenkool
  2021-01-29  2:45                 ` Michael Meissner
  0 siblings, 1 reply; 17+ messages in thread
From: Segher Boessenkool @ 2021-01-28 21:26 UTC (permalink / raw)
  To: Peter Bergner; +Cc: Michael Meissner, gcc-patches, David Edelsohn, Bill Schmidt

On Thu, Jan 28, 2021 at 01:58:26PM -0600, Peter Bergner wrote:
> On 1/28/21 1:47 PM, Segher Boessenkool wrote:
> > On Thu, Jan 28, 2021 at 02:30:56PM -0500, Michael Meissner wrote:
> >> The second patch I want you to review is:
> > 
> > "This patch replaces the following three patches:"
> > 
> > Please send a patch that modifies *current* code, and that is *tested*
> > with that.  With a good explanation, and a commit message for *that*
> > patch (not for other, older patches).
> 
> Isn't the email Mike linked to which was submitted yesterday exactly this?

It says it is not.  That is where I stopped reading.

> Admittedly, it doesn't have a "commit message header", but it does seem to
> be against current code and he did say he tested it and there is some
> explanation given, just not in a commit message form.  Is it just a nice
> commit message you're looking for now?

Just like for any other patch, I need to know what it *is*, why this is
an improvement, and all that.  The usual.  And not in ten pages but in a
few sentences.

After such an introduction you can go into detail where that is
warranted, for example necessary to understand the patch, but you do not
explain the history of the world in a commit message.

I do not have the bandwidth to spend hours on this again today trying to
figure out what this patch is.


Segher

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Ping] PowerPC: Add float128/Decimal conversions.
  2021-01-28 21:26               ` Segher Boessenkool
@ 2021-01-29  2:45                 ` Michael Meissner
  0 siblings, 0 replies; 17+ messages in thread
From: Michael Meissner @ 2021-01-29  2:45 UTC (permalink / raw)
  To: Segher Boessenkool
  Cc: Peter Bergner, Michael Meissner, gcc-patches, David Edelsohn,
	Bill Schmidt

I rebusmitted the patch after verifying it still builds and works with the
current branch as:

https://gcc.gnu.org/pipermail/gcc-patches/2021-January/564486.html

| Subject: [PATCH] Add conversions between _Float128 and Decimal.
| Message-ID: <20210129024208.GA25608@ibm-toto.the-meissners.org>

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meissner@linux.ibm.com, phone: +1 (978) 899-4797

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH] PowerPC: Add float128/Decimal conversions
  2020-12-11 19:51 ` Segher Boessenkool
@ 2020-12-17 18:09   ` Michael Meissner
  0 siblings, 0 replies; 17+ messages in thread
From: Michael Meissner @ 2020-12-17 18:09 UTC (permalink / raw)
  To: Segher Boessenkool
  Cc: Michael Meissner, gcc-patches, David Edelsohn, Bill Schmidt,
	Peter Bergner

On Fri, Dec 11, 2020 at 01:51:44PM -0600, Segher Boessenkool wrote:
> Hi!
> 
> On Thu, Nov 19, 2020 at 07:05:24PM -0500, Michael Meissner wrote:
> > If the glibc is not 2.32 or later, this code just compiles to using abort.
> 
> That is the compile-time target glibc.  That is often *not* the glibc
> your program runs with, as I said before.  And this is a huge problem
> still.
> 
> > That way the user won't get unknown reference errors due to the calls to the
> > glibc 2.32 functions that aren't in previous glibcs.
> 
> See above.
> 
> Also, tight version dependencies like this are problematic: glibc has
> version dependencies on GCC already!
> 
> You should do the conversion *inside of libgcc*.  As said many times
> before.

Note, NONE of the other Decimal conversion functions are done within LIBGCC.
All use sprintf/scanf.  It is just that until GLIBC 2.32, we did not have the
necessary support in GLIBC.

I just don't think LIBGCC is the place to do this conversion, given the nature
of decimal arithmetic.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meissner@linux.ibm.com, phone: +1 (978) 899-4797

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH] PowerPC: Add float128/Decimal conversions
  2020-11-20  0:05 [PATCH] " Michael Meissner
@ 2020-12-11 19:51 ` Segher Boessenkool
  2020-12-17 18:09   ` Michael Meissner
  0 siblings, 1 reply; 17+ messages in thread
From: Segher Boessenkool @ 2020-12-11 19:51 UTC (permalink / raw)
  To: Michael Meissner, gcc-patches, David Edelsohn, Bill Schmidt,
	Peter Bergner

Hi!

On Thu, Nov 19, 2020 at 07:05:24PM -0500, Michael Meissner wrote:
> If the glibc is not 2.32 or later, this code just compiles to using abort.

That is the compile-time target glibc.  That is often *not* the glibc
your program runs with, as I said before.  And this is a huge problem
still.

> That way the user won't get unknown reference errors due to the calls to the
> glibc 2.32 functions that aren't in previous glibcs.

See above.

Also, tight version dependencies like this are problematic: glibc has
version dependencies on GCC already!

You should do the conversion *inside of libgcc*.  As said many times
before.

> +/* If we don't have at least GLIBC 2.32, the strtold used by dfp-bit.c does not
> +   have support for float128.  Add an abort in case this is called.  */
> +#include <features.h>
> +
> +#if ((__GLIBC__ * 1000) + __GLIBC_MINOR__) < 2032
> +
> +#include <stdlib.h>
> +extern long double __dpd_extendddkf (_Decimal64);
> +
> +long double
> +__dpd_extendddkf (_Decimal64 x __attribute__ ((unused)))
> +{
> +  abort ();
> +}

Put that comment above *here*, right before the abort, so that the
victim who will have to debug this at least immediately gets to see
what is happening.


So, as on the other patch: okay for trunk, but you get to deal with all
the fallout.  If you do not want to fix the obvious problems now,
you'll get to do it later.


Segher

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH] PowerPC: Add float128/Decimal conversions
@ 2020-11-20  0:05 Michael Meissner
  2020-12-11 19:51 ` Segher Boessenkool
  0 siblings, 1 reply; 17+ messages in thread
From: Michael Meissner @ 2020-11-20  0:05 UTC (permalink / raw)
  To: gcc-patches, Michael Meissner, Segher Boessenkool,
	David Edelsohn, Bill Schmidt, Peter Bergner

[PATCH] PowerPC: Add float128/Decimal conversions.

I accidently posted this patch on an internal IBM mailing list instead of
gcc-patches.

This patch replaces the following two patches:

September 24th, 2020:
Message-ID: <20200924203545.GD31597@ibm-toto.the-meissners.org>

October 22nd, 2020:
Message-ID: <20201022220603.GA11658@ibm-toto.the-meissners.org>

This is a simplification of those patches.  Those patches were initially
written before I was using the final glibc 2.32 (Advance Toolchain AT14.0).
With using that glibc and with the previous IEEE patches submitted, I can
simplify the conversions to just use the long double defaults, compiling the
modules for IEEE 128-bit long double.  It works because stdio.h/gcc switches
the sprintf call to __sprintfieee128, and the strtold call to __strtof128.

While most of the Decimal <-> Long double tests now pass when long doubles are
IEEE 128-bit, there is one test that fails:

	c-c++-common/dfp/convert-bfp-11.c

This test explicitly expects long double to be IBM 128-bit extended double.  A
later patch will fix this.

If the glibc is not 2.32 or later, this code just compiles to using abort.
That way the user won't get unknown reference errors due to the calls to the
glibc 2.32 functions that aren't in previous glibcs.

This patch is one of three critical patches needed to be able to build
compilers where the default is IEEE 128-bit.  The other patches were the
patches to rename the built-in functions, and the patches for prs 97543 and
97643 that were both posted earlier.

I have tested this patch on a little endian power9 system running Linux,
building bootstrap compilers with the 3 long double flavors (long double is
128-bit IEEE, long double is 128-bit IBM, and long double is 64-bit).  There
are no regressions with long double set to 128-bit IBM.

With the exception of convert-bfp-11.c mentioned above, none of the regressions
in the long double set to 128-bit IEEE affect the decimal support.

Can I check this into the master branch?

libgcc/
2020-11-17  Michael Meissner  <meissner@linux.ibm.com>

	* config/rs6000/t-float128 (fp128_dec_funcs): New macro.
	(ibm128_dec_funcs): New macro.
	(fp128_ppc_funcs): Add the Decimal <-> __float128 conversions.
	(fp128_dec_objs): Force Decimal <-> __float128 conversions to be
	compiled with -mabi=ieeelongdouble.
	(ibm128_dec_objs): Force Decimal <-> __float128 conversions to be
	compiled with -mabi=ieeelongdouble.
	(FP128_CFLAGS_DECIMAL): New macro.
	(IBM128_CFLAGS_DECIMAL): New macro.
	* config/rs6000/_dd_to_kf.c: New file.
	* config/rs6000/_kf_to_dd.c: New file.
	* config/rs6000/_kf_to_sd.c: New file.
	* config/rs6000/_kf_to_td.c: New file.
	* config/rs6000/_sd_to_kf.c: New file.
	* config/rs6000/_td_to_kf.c: New file.
---
 libgcc/config/rs6000/_dd_to_kf.c | 58 +++++++++++++++++++++++++++++++
 libgcc/config/rs6000/_kf_to_dd.c | 57 ++++++++++++++++++++++++++++++
 libgcc/config/rs6000/_kf_to_sd.c | 58 +++++++++++++++++++++++++++++++
 libgcc/config/rs6000/_kf_to_td.c | 56 ++++++++++++++++++++++++++++++
 libgcc/config/rs6000/_sd_to_kf.c | 59 ++++++++++++++++++++++++++++++++
 libgcc/config/rs6000/_td_to_kf.c | 58 +++++++++++++++++++++++++++++++
 libgcc/config/rs6000/t-float128  | 26 +++++++++++++-
 7 files changed, 371 insertions(+), 1 deletion(-)
 create mode 100644 libgcc/config/rs6000/_dd_to_kf.c
 create mode 100644 libgcc/config/rs6000/_kf_to_dd.c
 create mode 100644 libgcc/config/rs6000/_kf_to_sd.c
 create mode 100644 libgcc/config/rs6000/_kf_to_td.c
 create mode 100644 libgcc/config/rs6000/_sd_to_kf.c
 create mode 100644 libgcc/config/rs6000/_td_to_kf.c

diff --git a/libgcc/config/rs6000/_dd_to_kf.c b/libgcc/config/rs6000/_dd_to_kf.c
new file mode 100644
index 00000000000..93601fa280e
--- /dev/null
+++ b/libgcc/config/rs6000/_dd_to_kf.c
@@ -0,0 +1,58 @@
+/* Copyright (C) 1989-2020 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC 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 General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+/* Decimal64 -> _Float128 conversion.  */
+
+/* FINE_GRAINED_LIBRARIES is used so we can isolate just to dd_to_tf conversion
+   function from dp-bits.c.  */
+#define FINE_GRAINED_LIBRARIES	1
+#define L_dd_to_tf		1
+#define WIDTH			64
+
+#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IEEE128__)
+#error "Long double is not IEEE 128-bit"
+#endif
+
+/* If we don't have at least GLIBC 2.32, the strtold used by dfp-bit.c does not
+   have support for float128.  Add an abort in case this is called.  */
+#include <features.h>
+
+#if ((__GLIBC__ * 1000) + __GLIBC_MINOR__) < 2032
+
+#include <stdlib.h>
+extern long double __dpd_extendddkf (_Decimal64);
+
+long double
+__dpd_extendddkf (_Decimal64 x __attribute__ ((unused)))
+{
+  abort ();
+}
+
+#else
+
+/* Map the external name to the float128 default.  */
+#define __dpd_extendddtf	__dpd_extendddkf
+
+/* Use dfp-bit.c to do the real work.  */
+#include "dfp-bit.c"
+#endif
diff --git a/libgcc/config/rs6000/_kf_to_dd.c b/libgcc/config/rs6000/_kf_to_dd.c
new file mode 100644
index 00000000000..fa4cc7e1716
--- /dev/null
+++ b/libgcc/config/rs6000/_kf_to_dd.c
@@ -0,0 +1,57 @@
+/* Copyright (C) 1989-2020 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC 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 General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+/* _Float128 -> Decimal64 conversion.  */
+
+/* FINE_GRAINED_LIBRARIES is used so we can isolate just to tf_to_dd conversion
+   function from dp-bits.c.  */
+#define FINE_GRAINED_LIBRARIES	1
+#define L_tf_to_dd		1
+#define WIDTH			64
+
+#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IEEE128__)
+#error "Long double is not IEEE 128-bit"
+#endif
+
+/* If we don't have at least GLIBC 2.32, the strtold used by dfp-bit.c does not
+   have support for float128.  Add an abort in case this is called.  */
+#include <features.h>
+
+#if ((__GLIBC__ * 1000) + __GLIBC_MINOR__) < 2032
+
+#include <stdlib.h>
+extern _Decimal64 __dpd_trunckfdd (long double);
+
+_Decimal64
+__dpd_trunckfdd (long double x __attribute__ ((unused)))
+{
+  abort ();
+}
+
+#else
+/* Map the external name to the float128 default.  */
+#define __dpd_trunctfdd		__dpd_trunckfdd
+
+/* Use dfp-bit.c to do the real work.  */
+#include "dfp-bit.c"
+#endif
diff --git a/libgcc/config/rs6000/_kf_to_sd.c b/libgcc/config/rs6000/_kf_to_sd.c
new file mode 100644
index 00000000000..ec92d697f84
--- /dev/null
+++ b/libgcc/config/rs6000/_kf_to_sd.c
@@ -0,0 +1,58 @@
+/* Copyright (C) 1989-2020 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC 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 General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+/* _Float128 -> Decimal32 conversion.  */
+
+/* FINE_GRAINED_LIBRARIES is used so we can isolate just to tf_to_sd conversion
+   function from dp-bits.c.  */
+#define FINE_GRAINED_LIBRARIES	1
+#define L_tf_to_sd		1
+#define WIDTH			32
+
+#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IEEE128__)
+#error "Long double is not IEEE 128-bit"
+#endif
+
+/* If we don't have at least GLIBC 2.32, the strtold used by dfp-bit.c does not
+   have support for float128.  Add an abort in case this is called.  */
+#include <features.h>
+
+#if ((__GLIBC__ * 1000) + __GLIBC_MINOR__) < 2032
+
+#include <stdlib.h>
+extern _Decimal32 __dpd_extendkfsd (long double);
+
+_Decimal32
+__dpd_extendkfsd (long double x __attribute__ ((unused)))
+{
+  abort ();
+}
+
+#else
+
+/* Map the external name to the float128 default.  */
+#define __dpd_trunctfsd	__dpd_trunckfsd
+
+/* Use dfp-bit.c to do the real work.  */
+#include "dfp-bit.c"
+#endif
diff --git a/libgcc/config/rs6000/_kf_to_td.c b/libgcc/config/rs6000/_kf_to_td.c
new file mode 100644
index 00000000000..9a8f65647ea
--- /dev/null
+++ b/libgcc/config/rs6000/_kf_to_td.c
@@ -0,0 +1,56 @@
+/* Copyright (C) 1989-2020 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC 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 General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+/* _Float128 -> Decimal128 conversion.  */
+
+/* FINE_GRAINED_LIBRARIES is used so we can isolate just to tf_to_td conversion
+   function from dp-bits.c.  */
+#define FINE_GRAINED_LIBRARIES	1
+#define L_tf_to_td		1
+#define WIDTH			128
+
+#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IEEE128__)
+#error "Long double is not IEEE 128-bit"
+#endif
+
+/* If we don't have at least GLIBC 2.32, the strtold used by dfp-bit.c does not
+   have support for float128.  Add an abort in case this is called.  */
+#include <features.h>
+
+#if ((__GLIBC__ * 1000) + __GLIBC_MINOR__) < 2032
+
+extern _Decimal128 __dpd_extendkftd (long double);
+
+_Decimal128
+__dpd_extendkftd (long double x __attribute__ ((unused)))
+{
+  abort ();
+}
+
+#else
+/* Map the external name to the float128 default.  */
+#define __dpd_extendtftd	__dpd_extendkftd
+
+/* Use dfp-bit.c to do the real work.  */
+#include "dfp-bit.c"
+#endif
diff --git a/libgcc/config/rs6000/_sd_to_kf.c b/libgcc/config/rs6000/_sd_to_kf.c
new file mode 100644
index 00000000000..3c2f04d3f78
--- /dev/null
+++ b/libgcc/config/rs6000/_sd_to_kf.c
@@ -0,0 +1,59 @@
+/* Copyright (C) 1989-2020 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC 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 General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+/* Decimal32 -> _Float128 conversion.  */
+
+/* FINE_GRAINED_LIBRARIES is used so we can isolate just to sd_to_tf conversion
+   function from dp-bits.c.  */
+#define FINE_GRAINED_LIBRARIES	1
+#define L_sd_to_tf		1
+#define WIDTH			32
+
+#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IEEE128__)
+#error "Long double is not IEEE 128-bit"
+#endif
+
+/* If we don't have at least GLIBC 2.32, the strtold used by dfp-bit.c does not
+   have support for float128.  Add an abort in case this is called.  */
+#include <features.h>
+
+#if ((__GLIBC__ * 1000) + __GLIBC_MINOR__) < 2032
+
+#include <stdlib.h>
+extern long double __dpd_extendsdkf (_Decimal32);
+
+long double
+__dpd_extendsdkf (_Decimal32 x __attribute__ ((unused)))
+{
+  abort ();
+}
+
+#else
+
+
+/* Map the external name to the float128 default.  */
+#define __dpd_extendsdtf	__dpd_extendsdkf
+
+/* Use dfp-bit.c to do the real work.  */
+#include "dfp-bit.c"
+#endif
diff --git a/libgcc/config/rs6000/_td_to_kf.c b/libgcc/config/rs6000/_td_to_kf.c
new file mode 100644
index 00000000000..26eefabdabc
--- /dev/null
+++ b/libgcc/config/rs6000/_td_to_kf.c
@@ -0,0 +1,58 @@
+/* Copyright (C) 1989-2020 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC 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 General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+/* Decimal128 -> _Float128 conversion.  */
+
+/* FINE_GRAINED_LIBRARIES is used so we can isolate just to td_to_tf conversion
+   function from dp-bits.c.  */
+#define FINE_GRAINED_LIBRARIES	1
+#define L_td_to_tf		1
+#define WIDTH			128
+
+#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IEEE128__)
+#error "Long double is not IEEE 128-bit"
+#endif
+
+/* If we don't have at least GLIBC 2.32, the strtold used by dfp-bit.c does not
+   have support for float128.  Add an abort in case this is called.  */
+#include <features.h>
+
+#if ((__GLIBC__ * 1000) + __GLIBC_MINOR__) < 2032
+
+#include <stdlib.h>
+extern long double __dpd_trunctdkf (_Decimal128);
+
+long double
+__dpd_trunctdkf (_Decimal128 x __attribute__ ((unused)))
+{
+  abort ();
+}
+
+#else
+
+/* Map the external name to the float128 default.  */
+#define __dpd_trunctdtf	__dpd_trunctdkf
+
+/* Use dfp-bit.c to do the real work.  */
+#include "dfp-bit.c"
+#endif
diff --git a/libgcc/config/rs6000/t-float128 b/libgcc/config/rs6000/t-float128
index d5413445189..8b089d4433c 100644
--- a/libgcc/config/rs6000/t-float128
+++ b/libgcc/config/rs6000/t-float128
@@ -22,10 +22,19 @@ fp128_softfp_static_obj	= $(addsuffix -sw$(objext),$(fp128_softfp_funcs))
 fp128_softfp_shared_obj	= $(addsuffix -sw_s$(objext),$(fp128_softfp_funcs))
 fp128_softfp_obj	= $(fp128_softfp_static_obj) $(fp128_softfp_shared_obj)
 
+# Decimal <-> _Float128 conversions
+fp128_dec_funcs		= _kf_to_sd _kf_to_dd _kf_to_td \
+			  _sd_to_kf _dd_to_kf _td_to_kf
+
+# Decimal <-> __ibm128 conversions
+ibm128_dec_funcs	= _tf_to_sd _tf_to_dd _tf_to_td \
+			  _sd_to_tf _dd_to_tf _td_to_tf
+
 # New functions for software emulation
 fp128_ppc_funcs		= floattikf floatuntikf fixkfti fixunskfti \
 			  extendkftf2-sw trunctfkf2-sw \
-			  sfp-exceptions _mulkc3 _divkc3 _powikf2
+			  sfp-exceptions _mulkc3 _divkc3 _powikf2 \
+			  $(fp128_dec_funcs)
 
 fp128_ppc_src		= $(addprefix $(srcdir)/config/rs6000/,$(addsuffix \
 				.c,$(fp128_ppc_funcs)))
@@ -69,6 +78,21 @@ $(fp128_ppc_obj)	 : INTERNAL_CFLAGS += $(FP128_CFLAGS_SW)
 $(fp128_obj)		 : $(fp128_includes)
 $(fp128_obj)		 : $(srcdir)/config/rs6000/quad-float128.h
 
+# Force the TF mode to/from decimal functions to be compiled with IBM long
+# double.  Add building the KF mode to/from decimal conversions with explict
+# IEEE long double.
+fp128_dec_objs		= $(addsuffix $(objext),$(fp128_dec_funcs)) \
+			  $(addsuffix _s$(objext),$(fp128_dec_funcs))
+
+ibm128_dec_objs		= $(addsuffix $(objext),$(ibm128_dec_funcs)) \
+			  $(addsuffix _s$(objext),$(ibm128_dec_funcs))
+
+FP128_CFLAGS_DECIMAL	= -mno-gnu-attribute -Wno-psabi -mabi=ieeelongdouble
+IBM128_CFLAGS_DECIMAL	= -mno-gnu-attribute -Wno-psabi -mabi=ibmlongdouble
+
+$(fp128_dec_objs)	: INTERNAL_CFLAGS += $(FP128_CFLAGS_DECIMAL)
+$(ibm128_dec_objs)	: INTERNAL_CFLAGS += $(IBM128_CFLAGS_DECIMAL)
+
 $(fp128_softfp_src) : $(srcdir)/soft-fp/$(subst -sw,,$(subst kf,tf,$@)) $(fp128_dep)
 	@src="$(srcdir)/soft-fp/$(subst -sw,,$(subst kf,tf,$@))"; \
 	echo "Create $@"; \
-- 
2.22.0


-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meissner@linux.ibm.com, phone: +1 (978) 899-4797

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2021-01-29  2:45 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-14 17:09 [PATCH] PowerPC: Add float128/Decimal conversions Michael Meissner
2021-01-15 21:52 ` Segher Boessenkool
2021-01-19 17:30   ` Michael Meissner
2021-01-26 23:43 ` [Ping] " Michael Meissner
2021-01-28  3:11   ` Segher Boessenkool
2021-01-28 18:10     ` Michael Meissner
2021-01-28 18:59       ` Segher Boessenkool
2021-01-28 19:30         ` Michael Meissner
2021-01-28 19:47           ` Segher Boessenkool
2021-01-28 19:58             ` Peter Bergner
2021-01-28 21:26               ` Segher Boessenkool
2021-01-29  2:45                 ` Michael Meissner
2021-01-27 21:05 ` [PATCH, revised] " Michael Meissner
2021-01-27 21:19   ` [PATCH, revised, #2] " Michael Meissner
  -- strict thread matches above, loose matches on Subject: below --
2020-11-20  0:05 [PATCH] " Michael Meissner
2020-12-11 19:51 ` Segher Boessenkool
2020-12-17 18:09   ` Michael Meissner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).