public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 0/9] PowerPC: Patches to enable changing the long double default to IEEE 128-bit on little endian PowerPC 64-bit Linux systems
@ 2020-09-24 20:20 Michael Meissner
  2020-09-24 20:31 ` [PATCH 1/9] PowerPC: Map long double built-in functions if IEEE 128-bit long double Michael Meissner
                   ` (12 more replies)
  0 siblings, 13 replies; 21+ messages in thread
From: Michael Meissner @ 2020-09-24 20:20 UTC (permalink / raw)
  To: gcc-patches, Michael Meissner, Segher Boessenkool,
	David Edelsohn, Bill Schmidt, Peter Bergner, Jeff Law,
	Jonathan Wakely

This series of 9 patches is an attempt to gather together all of the patches
that are needed to be able to configure and build a little endian 64-bit
PowerPC Linux GCC compiler where the defualt long double format uses the IEEE
128-bit representation.

I have created an IBM vendor branch that includes these patches (along the
other outstanding patches that I have for IEEE 128-bit min/max/cmove on
power10, and power10 PCREL_OPT support):

	vendors/ibm/ieee-longdouble-001

You will need a new enough GLIBC in order to do this configuration.  The
Advance Toolchain AT14.0 from IBM includes the changes in the library that are
needed to build a compiler with this default.

Note, with these patches, we need the libstdc++ work that was begun last year
to be finished and committed.  This shows up in trying to build the Spec 2017
511.parest_r (rate) benchmark when long double uses the IEEE representation.

Using the steps outlined below, I have build and bootstraped current GCC
sources, comparing builds where the default long double is the current IBM
extended double to builds where long double uses the IEEE 128-bit
representation.  The only difference in C, C++, LTO, and Fortran tests are 3
Fortran tests that either were marked as XFAIL or just failed now pass.

The patches that will be posted include:

    #1	Map built-in function names for long double;
    #2	Update error messages intermixing the 2 128-bit types;
    #3	Fixes libgcc conversions between the 2 128-bit types;
    #4	Add support for converting IEEE 128-bit <-> Decimal;
    #5	Update tests to run with IEEE 128-bit long double;
    #6	Map nanq, nansq, etc. to long double if long double is IEEE;
    #7	Update power10 __float128 tests to work with IEEE long double;
    #8	Use __float128 in some of the tests instead of __ieee128; (and)
    #9	Use __builtin_pack_ieee128 in libgcc if IEEE long double.

I put the following file in the branch:

	gcc/config/rs6000/gcc-with-ieee-128bit-longdouble.txt

This is a short memo of how to build a GCC 11 compiler where the long double
type is IEEE 128-bit instead of using the IBM extended double format on the
PowerPC 64-bit little endian Linux environment.

You will likely need the Advance Toolchain AT14.0 library, as it has all of the
changes to support switching the long double default to IEEE 128-bit.

    *	https://www.ibm.com/support/pages/advance-toolchain-linux-power

You will need a recent version of binutils.  I've used the binutils that I
downloaded via git on September 14th, 2020:

    *	git clone git://sourceware.org/git/binutils-gdb.git

You will need appropriate versions of the gmp, mpfr, and mpc libraries:

    *	http://gcc.gnu.org/pub/gcc/infrastructure/gmp-6.1.0.tar.bz2
    *	http://gcc.gnu.org/pub/gcc/infrastructure/mpfr-3.1.4.tar.bz2
    *	http://gcc.gnu.org/pub/gcc/infrastructure/mpc-1.0.3.tar.gz

Currently, I use --without-ppl --without-cloog --without-isl so I haven't used
those libraries.

I currently disable plug-in support.  If you want plug-in support, you will
likely need to build a binutils with the first compiler, to use with the second
and third compilers.  If you use a binutils compiled with a compiler where the
long double format is IBM extended double, it may not work.

I found I needed the configuration option --with-system-zlib to avoid some
issues when doing a bootstrap build.

Build the first PowerPC GCC compiler (non-bootstrap) using at least the
following options:

	--prefix=<first-gcc-install>
	--enable-stage1-languages=c,c++,fortran
	--disable-bootstrap
	--disable-plugin
	--with-long-double-format=ieee
	--with-advance-toolchain=at14.0
	--with-system-zlib
	--with-native-system-header-dir=/opt/at14.0/include
	--without-ppl
	--without-cloog
	--without-isl

Other configuration options that I use but may not affect switching the long
double default include:

	--enable-checking
	--enable-languages=c,c++,fortran
	--enable-stage1-checking
	--enable-gnu-indirect-function
	--enable-decimal-float
	--with-long-double-128
	--enable-secureplt
	--enable-threads=posix
	--enable-__cxa_atexit
	--with-as=<as location>
	--with-ld=<ld location>
	--with-gnu-as=<as location>
	--with-gnu-ld=<ld location>
	--with-cpu=power9		(or --with-cpu=power8)

Build and install the first compiler.

Configure, build, and install gmp 6.1.0 using the first compiler built above
with following configuration options:

	--prefix=<gmp-install>
	--enable-static
	--disable-shared
	--enable-cxx
	CPPFLAGS=-fexceptions

Configure, build, and install mpfr 3.1.4 using the first compiler build above
with the following configuration options:

	--prefix=<mprf-install>
	--enable-static
	--disable-shared
	--with-gmp=<gmp-install>

Configure, build, and install mpc 1.0.3 using the first compiler build above
with the following configuration options:

	--prefix=<mpc-install>
	--enable-static
	--disable-shared
	--with-gmp=<gmp-install>
	--with-mpfr=<mpfr-install>

Configure, build, and install the second compiler using the first compiler to
build the second compiler, and using the gmp, mpfr, and mpc libraries built
above.  You could skip this step, but I found during development, it was useful
to shake things out before diving into a bootstrap build.  The notable
configuration options used are:

	--prefix=<second-gcc-install>
	--enable-stage1-languages=c,c++,fortran
	--disable-bootstrap
	--disable-plugin
	--with-long-double-format=ieee
	--with-system-zlib
	--with-advance-toolchain=at14.0
	--with-native-system-header-dir=/opt/at14.0/include
	--with-gmp=<gmp-install>
	--with-mpfr=<mpfr-install>
	--with-mpc=<mpc-install>
	--without-ppl
	--without-cloog
	--without-isl

As before, I tend to add these options as well:

	--enable-checking
	--enable-languages=c,c++,fortran
	--enable-stage1-checking
	--enable-gnu-indirect-function
	--enable-decimal-float
	--with-long-double-128
	--enable-secureplt
	--enable-threads=posix
	--enable-__cxa_atexit
	--with-as=<as location>
	--with-ld=<ld location>
	--with-gnu-as=<as location>
	--with-gnu-ld=<ld location>
	--with-cpu=power9		(or --with-cpu=power8)

Assuming the second compiler builds and installs, now go onto building a
bootstrap third compiler, using the second compiler to build stage1.  The
options I used include:

	--prefix=<third-gcc-install>
	--disable-plugin
	--with-long-double-format=ieee
	--with-cpu=power9
	--with-system-zlib
	--with-advance-toolchain=at14.0
	--with-native-system-header-dir=/opt/at14.0/include
	--with-gmp=<gmp-location>
	--with-mpfr=<mpfr-location>
	--with-mpc=<mpc-location>
	--without-ppl
	--without-cloog
	--without-isl

As before, I tend to add these options as well:

	--enable-languages=c,c++,fortran
	--enable-checking
	--enable-stage1-checking
	--enable-gnu-indirect-function
	--enable-decimal-float
	--with-long-double-128
	--enable-secureplt
	--enable-threads=posix
	--enable-__cxa_atexit
	--with-as=<as location>
	--with-ld=<ld location>
	--with-gnu-as=<as location>
	--with-gnu-ld=<ld location>
	--with-cpu=power9		(or --with-cpu=power8)

Three fortran tests that used to fail now succeed:

gfortran.dg/default_format_2.f90		(marked XFAIL)
gfortran.dg/default_format_denormal_2.f90	(marked XFAIL)
gfortran.dg/ieee/large_2.f90			(not marked XFAIL)

I built Spec 2017 rate benchmarks with the newest compiler.

    1)	The 500.perlbench_r benchmark uses long double in the sv.c module.  It
	looks like perl uses long double as the universal type in the sv.c
	module.  There are 2 conversions from double to long double, 1
	conversion from long double back to double, and 3 long double
	comparisons.

	In looking at the sv.c in the Spec 2017 suite, there are a bunch of
	#ifdef's to control how perl optimizes the use of long double.  The
	Spec options disables these #ifdef's, but it is likely these same
	#ifdef's are used in the current version of perl used by the
	distributions.  It is likely that if the long double change is made on
	a system wide basis, that the perl configuration will need to be
	tweaked to know that long double uses the IEEE 128-bit format.

    2)	The 510.parest_r benchmark fails to link because there are missing
	functions in libstdc++.  I'm including a simplification of the error
	messages below:

<...>/ld: source/lac/full_matrix.o: in function `dealii::FullMatrix<std::complex<__ieee128> >::ExcNotRegular::print_info(std::ostream&) const':
<...>/include/lac/full_matrix.h:1206: undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <__ieee128, char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >, std::complex<__ieee128> const&)'

<...>/ld: source/lac/full_matrix.o: in function `void dealii::LogStream::print<std::complex<__ieee128> >(std::complex<__ieee128> const&)':
<...>/include/base/logstream.h:441: undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <__ieee128, char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >, std::complex<__ieee128> const&)'

<...>/ld: source/lac/full_matrix.o: in function `void dealii::FullMatrix<std::complex<__ieee128> >::print<std::ostream>(std::ostream&, unsigned int, unsigned int) const':
<...>/include/lac/full_matrix.h:1499: undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <__ieee128, char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >, std::complex<__ieee128> const&)'

<...>/ld: source/lac/full_matrix.o: in function `dealii::FullMatrix<std::complex<__ieee128> >::print_formatted(std::ostream&, unsigned int, bool, unsigned int, char const*, double, double) const':
<...>/include/lac/full_matrix.templates.h:1479: undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <__ieee128, char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >, std::complex<__ieee128> const&)'

<...>/ld: source/lac/vector.o: in function `dealii::Vector<std::complex<__ieee128> >::print(std::ostream&, unsigned int, bool, bool) const':
<...>/include/lac/vector.templates.h:800: undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <__ieee128, char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >, std::complex<__ieee128> const&)'

<...>/ld: source/lac/vector.o:<...>/include/lac/vector.templates.h:797: more undefined references to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <__ieee128, char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >, std::complex<__ieee128> const&)' follow
collect2: error: ld returned 1 exit status

With the discusion:

    *	https://gcc.gnu.org/pipermail/gcc/2020-August/233338.html

the agreement was to continue having essentially two types (& three modes) in
the compiler.

    *	When long double uses the IEEE 128-bit representation, the type node
	for __float128/_Float128 is the same as the type node for long double,
	and __ibm128 has a unique node.

    *	When long double uses the IBM extended double representation (current
	behavior), the type node for __ibm128 is the same as for long double,
	and __float128/_Float128 have a unique node.

This means that when the long double format changes, C++ libraries cannot mix
functions with the same name using __float128 and long double types.  I.e. the
following would generate an error:

	class foo {
	  long double add (long double a, long double b) { return a+b; }
	  __float128 add (__float128 a, __float128 b) { return a+b; }
	};

But C++ users would be able say:

	class foo {
	  long double add (long double a, long double b) { return a+b; }
	  __ibm128 add (__ibm128 a, __ibm128 b) { return a+b; }
	};

The boost library is believed to have both __float128 and long double in a
class.  Boost would need to be tweaked so that if the default long double is
IEEE 128-bit, not to enable the explicit __float128 support.

The compiler defines the following macros based on the long double support:

	#define __LONG_DOUBLE_IEEE128__	1 /* if long double is IEEE 128-bit.  */
	#define __LONG_DOUBLE_IBM128__	1 /* if long double is IBM 128-bit.  */
	#define __LONG_DOUBLE_128__	1 /* if sizeof (long double) == #16.  */


-- 
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] 21+ messages in thread

* [PATCH 1/9] PowerPC: Map long double built-in functions if IEEE 128-bit long double.
  2020-09-24 20:20 [PATCH 0/9] PowerPC: Patches to enable changing the long double default to IEEE 128-bit on little endian PowerPC 64-bit Linux systems Michael Meissner
@ 2020-09-24 20:31 ` Michael Meissner
  2020-10-01 23:05   ` Joseph Myers
  2020-09-24 20:33 ` [PATCH 2/9] PowerPC: Update __float128 and __ibm128 error messages Michael Meissner
                   ` (11 subsequent siblings)
  12 siblings, 1 reply; 21+ messages in thread
From: Michael Meissner @ 2020-09-24 20:31 UTC (permalink / raw)
  To: Michael Meissner, gcc-patches, Segher Boessenkool,
	David Edelsohn, Bill Schmidt, Peter Bergner, Jeff Law,
	Jonathan Wakely

PowerPC: Map long double built-in functions if IEEE 128-bit long double.

This patch goes through the built-in functions and changes the name that is
used to the name used for __float128 and _Float128 support in glibc if the
PowerPC long double type is IEEE 128-bit instead of IBM extended double.

Normally the mapping is done in the math.h and stdio.h files.  However, not
everybody uses these files, which means we also need to change the external
name for the built-in function within the compiler.

In addition, changing the name in GCC allows the Fortran compiler to
automatically use the correct name.

To map the math functions, typically this patch changes <name>l to <name>f128.
However there are some exceptions that are handled with this patch.

To map the printf functions, <name> is mapped to __<name>ieee128.

To map the scanf functions, <name> is mapped to __isoc99<name>ieee128.

gcc/
2020-09-23  Michael Meissner  <meissner@linux.ibm.com>

	* config/rs6000/rs6000.c (rs6000_mangle_decl_assembler_name): Add
	support for mapping built-in function names for long double
	built-in functions if long double is IEEE 128-bit.

gcc/testsuite/
2020-09-23  Michael Meissner  <meissner@linux.ibm.com>

	* gcc.target/powerpc/float128-longdouble-math.c: New test.
	* gcc.target/powerpc/float128-longdouble-stdio.c: New test.
---
 gcc/config/rs6000/rs6000.c                    | 153 ++++-
 .../powerpc/float128-longdouble-math.c        | 559 ++++++++++++++++++
 .../powerpc/float128-longdouble-stdio.c       |  37 ++
 3 files changed, 718 insertions(+), 31 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/powerpc/float128-longdouble-math.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/float128-longdouble-stdio.c

diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index b589f4566c2..0ff0f31d552 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -26909,56 +26909,147 @@ rs6000_globalize_decl_name (FILE * stream, tree decl)
    library before you can switch the real*16 type at compile time.
 
    We use the TARGET_MANGLE_DECL_ASSEMBLER_NAME hook to change this name.  We
-   only do this if the default is that long double is IBM extended double, and
-   the user asked for IEEE 128-bit.  */
+   only do this transformation if the __float128 type is enabled.  This
+   prevents us from doing the transformation on older 32-bit ports that might
+   have enabled using IEEE 128-bit floating point as the default long double
+   type.  */
 
 static tree
 rs6000_mangle_decl_assembler_name (tree decl, tree id)
 {
-  if (!TARGET_IEEEQUAD_DEFAULT && TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
-      && TREE_CODE (decl) == FUNCTION_DECL && DECL_IS_BUILTIN (decl) )
+  if (TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
+      && TREE_CODE (decl) == FUNCTION_DECL
+      && fndecl_built_in_p (decl, BUILT_IN_NORMAL))
     {
       size_t len = IDENTIFIER_LENGTH (id);
       const char *name = IDENTIFIER_POINTER (id);
+      const char *newname = NULL;
 
-      if (name[len - 1] == 'l')
+      /* See if it is one of the built-in functions with an unusual name.  */
+      switch (DECL_FUNCTION_CODE (decl))
 	{
-	  bool uses_ieee128_p = false;
-	  tree type = TREE_TYPE (decl);
-	  machine_mode ret_mode = TYPE_MODE (type);
+	default:
+	  break;
 
-	  /* See if the function returns a IEEE 128-bit floating point type or
-	     complex type.  */
-	  if (ret_mode == TFmode || ret_mode == TCmode)
-	    uses_ieee128_p = true;
-	  else
+	case BUILT_IN_DREML:
+	  newname = "remainderf128";
+	  break;
+
+	case BUILT_IN_GAMMAL:
+	  newname = "lgammaf128";
+	  break;
+
+	case BUILT_IN_GAMMAL_R:
+	case BUILT_IN_LGAMMAL_R:
+	  newname = "__lgammaieee128_r";
+	  break;
+
+	case BUILT_IN_NEXTTOWARD:
+	  newname = "__nexttoward_to_ieee128";
+	  break;
+
+	case BUILT_IN_NEXTTOWARDF:
+	  newname = "__nexttowardf_to_ieee128";
+	  break;
+
+	case BUILT_IN_NEXTTOWARDL:
+	  newname = "__nexttowardieee128";
+	  break;
+
+	case BUILT_IN_POW10L:
+	  newname = "exp10f128";
+	  break;
+
+	case BUILT_IN_SCALBL:
+	  newname = "__scalbnieee128";
+	  break;
+
+	case BUILT_IN_SIGNIFICANDL:
+	  newname = "__significandieee128";
+	  break;
+
+	case BUILT_IN_SINCOSL:
+	  newname = "__sincosieee128";
+	  break;
+	}
+
+      /* Update the __builtin_*printf && __builtin_*scanf functions.  */
+      if (!newname)
+	{
+	  const size_t printf_len = sizeof ("printf") - 1;
+	  const size_t scanf_len = sizeof ("scanf") - 1;
+	  const size_t printf_extra
+	    = sizeof ("__") - 1 + sizeof ("ieee128") - 1;
+	  const size_t scanf_extra
+	    = sizeof ("__isoc99_") - 1 + sizeof ("ieee128") - 1;
+
+	  if (len >= printf_len
+	      && strcmp (name + len - printf_len, "printf") == 0)
 	    {
-	      function_args_iterator args_iter;
-	      tree arg;
+	      char *name2 = (char *) alloca (len + 1 + printf_extra);
+	      strcpy (name2, "__");
+	      memcpy (name2 + 2, name, len);
+	      strcpy (name2 + 2 + len, "ieee128");
+	      newname = (const char *) name2;
+	    }
 
-	      /* See if the function passes a IEEE 128-bit floating point type
-		 or complex type.  */
-	      FOREACH_FUNCTION_ARGS (type, arg, args_iter)
+	  else if (len >= scanf_len
+		   && strcmp (name + len - scanf_len, "scanf") == 0)
+	    {
+	      char *name2 = (char *) alloca (len + 1 + scanf_extra);
+	      strcpy (name2, "__isoc99_");
+	      memcpy (name2 + sizeof ("__isoc99") - 1, name, len);
+	      strcpy (name2 + sizeof ("__isoc99") - 1 + len, "ieee128");
+	      newname = (const char *) name2;
+	    }
+
+	  else if (name[len - 1] == 'l')
+	    {
+	      bool uses_ieee128_p = false;
+	      tree type = TREE_TYPE (decl);
+	      machine_mode ret_mode = TYPE_MODE (type);
+
+	      /* See if the function returns a IEEE 128-bit floating point type or
+		 complex type.  */
+	      if (ret_mode == TFmode || ret_mode == TCmode)
+		uses_ieee128_p = true;
+	      else
 		{
-		  machine_mode arg_mode = TYPE_MODE (arg);
-		  if (arg_mode == TFmode || arg_mode == TCmode)
+		  function_args_iterator args_iter;
+		  tree arg;
+
+		  /* See if the function passes a IEEE 128-bit floating point type
+		     or complex type.  */
+		  FOREACH_FUNCTION_ARGS (type, arg, args_iter)
 		    {
-		      uses_ieee128_p = true;
-		      break;
+		      machine_mode arg_mode = TYPE_MODE (arg);
+		      if (arg_mode == TFmode || arg_mode == TCmode)
+			{
+			  uses_ieee128_p = true;
+			  break;
+			}
 		    }
 		}
-	    }
 
-	  /* If we passed or returned an IEEE 128-bit floating point type,
-	     change the name.  */
-	  if (uses_ieee128_p)
-	    {
-	      char *name2 = (char *) alloca (len + 4);
-	      memcpy (name2, name, len - 1);
-	      strcpy (name2 + len - 1, "f128");
-	      id = get_identifier (name2);
+	      /* If we passed or returned an IEEE 128-bit floating point type,
+		 change the name.  */
+	      if (uses_ieee128_p)
+		{
+		  char *name2 = (char *) alloca (len + 4);
+		  memcpy (name2, name, len - 1);
+		  strcpy (name2 + len - 1, "f128");
+		  newname = (const char *) name2;
+		}
 	    }
 	}
+
+      if (newname)
+	{
+	  if (TARGET_DEBUG_BUILTIN)
+	    fprintf (stderr, "Map %s => %s\n", name, newname);
+
+	  id = get_identifier (newname);
+	}
     }
 
   return id;
diff --git a/gcc/testsuite/gcc.target/powerpc/float128-longdouble-math.c b/gcc/testsuite/gcc.target/powerpc/float128-longdouble-math.c
new file mode 100644
index 00000000000..e7a79f5e4e9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/float128-longdouble-math.c
@@ -0,0 +1,559 @@
+/* { dg-require-effective-target ppc_float128_hw } */
+/* { dg-require-effective-target power10_ok } */
+/* { dg-options "-mdejagnu-cpu=power9 -mno-pcrel -O2 -Wno-psabi -mabi=ieeelongdouble" } */
+
+/* Test if switching long double to IEEE 128-bit maps all of the math built-in
+   function names correctly.  We explicitly turn off PC-relative support to
+   make it simpler to compare the call without having a @notoc qualifier.  */
+
+/* Debugging support to use 'name' instead of '__builtin_name'.  Note if you
+   enable this, you will likely need additional flags to get all of the
+   functions defined.  */
+#ifdef DO_FUNC
+#ifndef DO_MATH_H
+#define DO_MATH_H	1
+#endif
+
+#define BUILTIN0(FUNC)                   FUNC ()
+#define BUILTIN1(FUNC, ARG1)             FUNC (ARG1)
+#define BUILTIN2(FUNC, ARG1, ARG2)       FUNC (ARG1, ARG2)
+#define BUILTIN3(FUNC, ARG1, ARG2, ARG3) FUNC (ARG1, ARG2, ARG3)
+
+#else
+#define BUILTIN0(FUNC)                   __builtin_ ## FUNC ()
+#define BUILTIN1(FUNC, ARG1)             __builtin_ ## FUNC (ARG1)
+#define BUILTIN2(FUNC, ARG1, ARG2)       __builtin_ ## FUNC (ARG1, ARG2)
+#define BUILTIN3(FUNC, ARG1, ARG2, ARG3) __builtin_ ## FUNC (ARG1, ARG2, ARG3)
+#endif
+
+/* Debugging support to compare using math.h with the raw built-in functions.  */
+#ifdef DO_MATH_H
+#define __STDC_WANT_IEC_60559_TYPES_EXT__	1
+#define __STDC_WANT_IEC_60559_FUNCS_EXT__	1
+#define _GNU_SOURCE				1
+#define _XOPEN_SOURCE				1
+
+#include <math.h>
+#include <complex.h>
+#endif
+
+/* Built-in functions that returns a long double and take one long double
+   argument.  */
+
+void
+return_ld_arg_ld (long double *p,
+		  long double *q)
+{
+  /* { dg-final { scan-assembler {\macoshf128\M} } }  */
+  *p++ = BUILTIN1 (acoshl, *q++);
+
+  /* { dg-final { scan-assembler {\macosf128\M} } }  */
+  *p++ = BUILTIN1 (acosl, *q++);
+
+  /* { dg-final { scan-assembler {\masinhf128\M} } }  */
+  *p++ = BUILTIN1 (asinhl, *q++);
+
+  /* { dg-final { scan-assembler {\masinf128\M} } }  */
+  *p++ = BUILTIN1 (asinl, *q++);
+
+  /* { dg-final { scan-assembler {\matanhf128\M} } }  */
+  *p++ = BUILTIN1 (atanhl, *q++);
+
+  /* { dg-final { scan-assembler {\matanf128\M} } }  */
+  *p++ = BUILTIN1 (atanl, *q++);
+
+  /* { dg-final { scan-assembler {\mcbrtf128\M} } }  */
+  *p++ = BUILTIN1 (cbrtl, *q++);
+
+  /* inline code.  */
+  *p++ = BUILTIN1 (ceill, *q++);
+
+  /* { dg-final { scan-assembler {\mcoshf128\M} } }  */
+  *p++ = BUILTIN1 (coshl, *q++);
+
+  /* { dg-final { scan-assembler {\mcosf128\M} } }  */
+  *p++ = BUILTIN1 (cosl, *q++);
+
+  /* { dg-final { scan-assembler {\merfcf128\M} } }  */
+  *p++ = BUILTIN1 (erfcl, *q++);
+
+  /* { dg-final { scan-assembler {\merff128\M} } }  */
+  *p++ = BUILTIN1 (erfl, *q++);
+
+  /* { dg-final { scan-assembler {\mexp10f128\M} } }  */
+  *p++ = BUILTIN1 (exp10l, *q++);
+
+  /* { dg-final { scan-assembler {\mexp2f128\M} } }  */
+  *p++ = BUILTIN1 (exp2l, *q++);
+
+  /* { dg-final { scan-assembler {\mexpf128\M} } }  */
+  *p++ = BUILTIN1 (expl, *q++);
+
+  /* { dg-final { scan-assembler {\mexpm1f128\M} } }  */
+  *p++ = BUILTIN1 (expm1l, *q++);
+
+  /* inline code.  */
+  *p++ = BUILTIN1 (fabsl, *q++);
+
+  /* inline code.  */
+  *p++ = BUILTIN1 (floorl, *q++);
+
+  /* { dg-final { scan-assembler {\mlgammaf128\M} } }  */
+  *p++ = BUILTIN1 (gammal, *q++);
+
+  /* { dg-final { scan-assembler {\mj0f128\M} } }  */
+  *p++ = BUILTIN1 (j0l, *q++);
+
+  /* { dg-final { scan-assembler {\mj1f128\M} } }  */
+  *p++ = BUILTIN1 (j1l, *q++);
+
+  /* lgammaf128 mentioned previously.  */
+  *p++ = BUILTIN1 (lgammal, *q++);
+
+  /* { dg-final { scan-assembler {\mlog10f128\M} } }  */
+  *p++ = BUILTIN1 (log10l, *q++);
+
+  /* { dg-final { scan-assembler {\mlog1pf128\M} } }  */
+  *p++ = BUILTIN1 (log1pl, *q++);
+
+  /* { dg-final { scan-assembler {\mlog2f128\M} } }  */
+  *p++ = BUILTIN1 (log2l, *q++);
+
+  /* { dg-final { scan-assembler {\mlogbf128\M} } }  */
+  *p++ = BUILTIN1 (logbl, *q++);
+
+  /* { dg-final { scan-assembler {\mlogf128\M} } }  */
+  *p++ = BUILTIN1 (logl, *q++);
+
+  /* { dg-final { scan-assembler {\mnearbyintf128\M} } }  */
+  *p++ = BUILTIN1 (nearbyintl, *q++);
+
+  /* { dg-final { scan-assembler {\mexp10f128\M} } }  */
+  *p++ = BUILTIN1 (pow10l, *q++);
+
+  /* { dg-final { scan-assembler {\mrintf128\M} } }  */
+  *p++ = BUILTIN1 (rintl, *q++);
+
+  /* { dg-final { scan-assembler {\mroundevenf128\M} } }  */
+  *p++ = BUILTIN1 (roundevenl, *q++);
+
+  /* inline code.  */
+  *p++ = BUILTIN1 (roundl, *q++);
+
+  /* { dg-final { scan-assembler {\m__significandieee128\M} } }  */
+  *p++ = BUILTIN1 (significandl, *q++);
+
+  /* { dg-final { scan-assembler {\msinhf128\M} } }  */
+  *p++ = BUILTIN1 (sinhl, *q++);
+
+  /* { dg-final { scan-assembler {\msinf128\M} } }  */
+  *p++ = BUILTIN1 (sinl, *q++);
+
+  /* { dg-final { scan-assembler {\msqrtf128\M} } }  */
+  *p++ = BUILTIN1 (sqrtl, *q++);
+
+  /* { dg-final { scan-assembler {\mtanhf128\M} } }  */
+  *p++ = BUILTIN1 (tanhl, *q++);
+
+  /* { dg-final { scan-assembler {\mtanf128\M} } }  */
+  *p++ = BUILTIN1 (tanl, *q++);
+
+  /* { dg-final { scan-assembler {\mtgammaf128\M} } }  */
+  *p++ = BUILTIN1 (tgammal, *q++);
+
+  /* inline code.  */
+  *p++ = BUILTIN1 (truncl, *q++);
+
+  /* { dg-final { scan-assembler {\my0f128\M} } }  */
+  *p++ = BUILTIN1 (y0l, *q++);
+
+  /* { dg-final { scan-assembler {\my1f128\M} } }  */
+  *p   = BUILTIN1 (y1l, *q);  
+
+}
+
+/* Built-in functions that returns a long double and take two long double
+   arguments.  */
+
+void
+return_ld_arg_ld_ld (long double *p,
+		     long double *q,
+		     long double *r)
+{
+  /* { dg-final { scan-assembler {\matan2f128\M} } }  */
+  *p++ = BUILTIN2 (atan2l, *q++, *r++);
+
+  /* inline code.  */
+  *p++ = BUILTIN2 (copysignl, *q++, *r++);
+
+  /* { dg-final { scan-assembler {\mremainderf128\M} } }  */
+  *p++ = BUILTIN2 (dreml, *q++, *r++);
+
+  /* { dg-final { scan-assembler {\mfdimf128\M} } }  */
+  *p++ = BUILTIN2 (fdiml, *q++, *r++);
+
+  /* { dg-final { scan-assembler {\mfmaxf128\M} } }  */
+  *p++ = BUILTIN2 (fmaxl, *q++, *r++);
+
+  /* { dg-final { scan-assembler {\mfminf128\M} } }  */
+  *p++ = BUILTIN2 (fminl, *q++, *r++);
+
+  /* { dg-final { scan-assembler {\mfmodf128\M} } }  */
+  *p++ = BUILTIN2 (fmodl, *q++, *r++);
+
+  /* { dg-final { scan-assembler {\mhypotf128\M} } }  */
+  *p++ = BUILTIN2 (hypotl, *q++, *r++);
+
+  /* { dg-final { scan-assembler {\mnextafterf128\M} } }  */
+  *p++ = BUILTIN2 (nextafterl, *q++, *r++);
+
+  /* { dg-final { scan-assembler {\m__nexttowardieee128\M} } }  */
+  *p++ = BUILTIN2 (nexttowardl, *q++, *r++);
+
+  /* { dg-final { scan-assembler {\mpowf128\M} } }  */
+  *p++ = BUILTIN2 (powl, *q++, *r++);
+
+  /* remainderf128 mentioned previously.  */
+  *p++ = BUILTIN2 (remainderl, *q++, *r++);
+
+  /* { dg-final { scan-assembler {\m__scalbnieee128\M} } }  */
+  *p   = BUILTIN2 (scalbl, *q, *r);  
+}
+
+/* Built-in function that returns a long double and take three long double
+   arguments.  */
+
+void
+return_ld_arg_ld_ld_ld (long double *p,
+			long double *q,
+			long double *r,
+			long double *s)
+{
+ /* inline code.  */
+  *p = BUILTIN3 (fmal, *q, *r, *s);
+}
+
+/* Built-in functions that returns a long double and take one
+   _Complex long double argument.  */
+
+void
+return_ld_arg_cld (long double *p,
+		   _Complex long double *q)
+{
+  /* { dg-final { scan-assembler {\mcabsf128\M} } }  */
+  *p++ = BUILTIN1 (cabsl, *q++);
+
+  /* inline code.  */
+  *p++ = BUILTIN1 (cargl, *q++);
+
+  /* inline code.  */
+  *p++ = BUILTIN1 (cimagl, *q++);
+
+  /* inline code.  */
+  *p   = BUILTIN1 (creall, *q);  
+}
+
+/* Built-in functions that returns a _Complex long double and takes one
+   _Complex long double argument.  */
+
+void
+return_cld_arg_cld (_Complex long double *p,
+		    _Complex long double *q)
+{
+  /* { dg-final { scan-assembler {\mcacoshf128\M} } }  */
+  *p++ = BUILTIN1 (cacoshl, *q++);
+
+  /* { dg-final { scan-assembler {\mcacosf128\M} } }  */
+  *p++ = BUILTIN1 (cacosl, *q++);
+
+  /* { dg-final { scan-assembler {\mcasinhf128\M} } }  */
+  *p++ = BUILTIN1 (casinhl, *q++);
+
+  /* { dg-final { scan-assembler {\mcasinf128\M} } }  */
+  *p++ = BUILTIN1 (casinl, *q++);
+
+  /* { dg-final { scan-assembler {\mcatanhf128\M} } }  */
+  *p++ = BUILTIN1 (catanhl, *q++);
+
+  /* { dg-final { scan-assembler {\mcatanf128\M} } }  */
+  *p++ = BUILTIN1 (catanl, *q++);
+
+  /* { dg-final { scan-assembler {\mccoshf128\M} } }  */
+  *p++ = BUILTIN1 (ccoshl, *q++);
+
+  /* { dg-final { scan-assembler {\mccosf128\M} } }  */
+  *p++ = BUILTIN1 (ccosl, *q++);
+
+  /* { dg-final { scan-assembler {\mcexpf128\M} } }  */
+  *p++ = BUILTIN1 (cexpl, *q++);
+
+  /* { dg-final { scan-assembler {\mclogf128\M} } }  */
+  *p++ = BUILTIN1 (clogl, *q++);
+
+  /* { dg-final { scan-assembler {\mclog10f128\M} } }  */
+  *p++ = BUILTIN1 (clog10l, *q++);
+
+  /* inline code.  */
+  *p++ = BUILTIN1 (conjl, *q++);
+
+  /* { dg-final { scan-assembler {\mcprojf128\M} } }  */
+  *p++ = BUILTIN1 (cprojl, *q++);
+
+  /* { dg-final { scan-assembler {\mcsinhf128\M} } }  */
+  *p++ = BUILTIN1 (csinhl, *q++);
+
+  /* { dg-final { scan-assembler {\mcsinf128\M} } }  */
+  *p++ = BUILTIN1 (csinl, *q++);
+
+  /* { dg-final { scan-assembler {\mcsqrtf128\M} } }  */
+  *p++ = BUILTIN1 (csqrtl, *q++);
+
+  /* { dg-final { scan-assembler {\mctanhf128\M} } }  */
+  *p++ = BUILTIN1 (ctanhl, *q++);
+
+  /* { dg-final { scan-assembler {\mctanf128\M} } }  */
+  *p   = BUILTIN1 (ctanl, *q);  
+}
+
+/* Built-in functions that returns a _Complex long double and takes one
+   long double argument.  */
+
+void
+return_cld_arg_ld (_Complex long double *p,
+		   long double *q)
+{
+  /* { dg-final { scan-assembler {\m__sincosieee128\M} } }  */
+  *p = BUILTIN1 (cexpil, *q);
+}
+
+/* Built-in function that returns a _Complex long double and takes two
+   _Complex long double arguments.  */
+
+void
+return_cld_arg_cld_cld (_Complex long double *p,
+			_Complex long double *q,
+			_Complex long double *r)
+{
+  /* { dg-final { scan-assembler {\mcpowf128\M} } }  */
+  *p = BUILTIN2 (cpowl, *q, *r);
+}
+
+/* Built-in functions that returns a long double and takes a long double and a
+   pointer to an int arguments.  */
+
+void
+return_ld_arg_ld_pi (long double *p,
+		     long double *q,
+		     int **r)
+{
+  /* { dg-final { scan-assembler {\mfrexpf128\M} } }  */
+  *p++ = BUILTIN2 (frexpl, *q++, *r++);
+
+  /* { dg-final { scan-assembler {\m__lgammaieee128_r\M} } }  */
+  *p++ = BUILTIN2 (gammal_r, *q++, *r++);
+
+  /* __lgammaieee128_r mentioned previously.  */
+  *p   = BUILTIN2 (lgammal_r, *q, *r);  
+}
+
+/* Built-in functions that returns a long double and takes a long double and an
+   int arguments.  */
+
+void
+return_ld_arg_ld_i (long double *p,
+		    long double *q,
+		    int *r)
+{
+  /* { dg-final { scan-assembler {\mldexpf128\M} } }  */
+  *p++ = BUILTIN2 (ldexpl, *q++, *r++);
+
+  /* { dg-final { scan-assembler {\m__powikf2\M} } }  */
+  *p++ = BUILTIN2 (powil, *q++, *r++);
+
+  /* { dg-final { scan-assembler {\mscalbnf128\M} } }  */
+  *p   = BUILTIN2 (scalbnl, *q, *r);  
+}
+
+/* Built-in function that returns a long double and takes a long double and a
+   long arguments.  */
+
+void
+return_ld_arg_ld_l (long double *p,
+		    long double *q,
+		    long *r)
+{
+  /* { dg-final { scan-assembler {\mscalblnf128\M} } }  */
+  *p = BUILTIN2 (scalblnl, *q, *r);
+}
+
+/* Built-in functions that returns a long double and takes a long double and a
+   long long arguments.  */
+
+void
+return_ld_arg_i_ld (long double *p,
+		    int *q,
+		    long double *r)
+{
+  /* { dg-final { scan-assembler {\mjnf128\M} } }  */
+  *p++ = BUILTIN2 (jnl, *q++, *r++);
+
+  /* { dg-final { scan-assembler {\mynf128\M} } }  */
+  *p   = BUILTIN2 (ynl, *q, *r);  
+}
+
+/* Built-in functions that returns a long double and takes a long double and a
+   pointer to a long double arguments.  */
+
+void
+return_ld_arg_ld_pld (long double *p,
+		      long double *q,
+		      long double **r)
+{
+  /* { dg-final { scan-assembler {\mmodff128\M} } }  */
+  *p = BUILTIN2 (modfl, *q, *r);
+}
+
+/* Built-in function that returns a long double and takes two long double and a
+   pointer to an int arguments.  */
+
+void
+return_ld_arg_ld_ld_pi (long double *p,
+			long double *q,
+			long double *r,
+			int **s)
+{
+  /* { dg-final { scan-assembler {\mremquof128\M} } }  */
+  *p = BUILTIN3 (remquol, *q, *r, *s);
+}
+
+/* Built-in functions that returns a long double and take no arguments.  */
+
+void
+return_ld_no_arg (long double *p)
+{
+  /* inline code.  */
+  *p++ = BUILTIN0 (huge_vall);
+
+  /* inline code.  */
+  *p   = BUILTIN0 (infl);     
+}
+
+/* Built-in functions that return san int and takes one long double argument.  */
+
+void
+return_i_arg_ld (int *p,
+		 long double *q)
+{
+  /* { dg-final { scan-assembler {\mceilf128\M} } }  */
+  *p++ = BUILTIN1 (iceill, *q++);
+
+  /* { dg-final { scan-assembler {\mfloorf128\M} } }  */
+  *p++ = BUILTIN1 (ifloorl, *q++);
+
+  /* { dg-final { scan-assembler {\milogbf128\M} } }  */
+  *p++ = BUILTIN1 (ilogbl, *q++);
+
+  /* { dg-final { scan-assembler {\mlrintf128\M} } }  */
+  *p++ = BUILTIN1 (irintl, *q++);
+
+  /* { dg-final { scan-assembler {\mlroundf128\M} } }  */
+  *p++ = BUILTIN1 (iroundl, *q++);
+
+  /* inline code.  */
+  *p++ = BUILTIN1 (signbitl, *q++);
+
+  /* inline code.  */
+  *p++ = BUILTIN1 (finitel, *q++);
+
+  /* inline code.  */
+  *p++ = BUILTIN1 (isinfl, *q++);
+
+  /* inline code.  */
+  *p   = BUILTIN1 (isnanl, *q);  
+}
+
+/* Built-in functions that returns a long and takes one long double argument.  */
+
+void
+return_l_arg_ld (long *p,
+		 long double *q)
+{
+  /* ceilf128 mentioned previouly.  */
+  *p++ = BUILTIN1 (lceill, *q++);
+
+  /* floorf128 mentioned previously.  */
+  *p++ = BUILTIN1 (lfloorl, *q++);
+
+  /* lrintf128 mentioned previously.  */
+  *p++ = BUILTIN1 (lrintl, *q++);
+
+  /* lroundf128 mentioned previously.  */
+  *p   = BUILTIN1 (lroundl, *q);  
+}
+
+/* Built-in functions that returns a long long and takes one long double
+   argument.  */
+
+void
+return_ll_arg_ld (long long *p,
+		  long double *r)
+{
+  /* ceilf128 mentioned previous.  */
+  *p++ = BUILTIN1 (llceill, *r++);
+
+  /* floorf128 mentioned previously.  */
+  *p++ = BUILTIN1 (llfloorl, *r++);
+
+  /* llrintf128 mentioned previously.  */
+  *p++ = BUILTIN1 (llrintl, *r++);
+
+  /* llroundf128 mentioned previously.  */
+  *p   = BUILTIN1 (llroundl, *r);  
+}
+
+/* Built-in function that returns a double and takes one double and one long
+   double arguments.  */
+
+void
+return_d_arg_d_ld (double *p,
+		   double *q,
+		   long double *r)
+{
+  /* { dg-final { scan-assembler {\m__nexttoward_to_ieee128\M} } }  */
+  *p = BUILTIN2 (nexttoward, *q, *r);
+}
+
+/* Built-in function that returns a float and takes one float and one long
+   double arguments.  */
+
+void
+return_f_arg_f_ld (float *p,
+		   float *q,
+		   long double *r)
+{
+  /* { dg-final { scan-assembler {\m__nexttowardf_to_ieee128\M} } }  */
+  *p = BUILTIN2 (nexttowardf, *q, *r);
+}
+
+/* Built-in function that returns void and takes one long double and two
+   pointers to long double arguments.  */
+
+void
+return_void_arg_ld_pld_pld (long double *p,
+			    long double **q,
+			    long double **r)
+{
+  /* __sincosieee128 mentioned previously.  */
+  BUILTIN3 (sincosl, *p, *q, *r);
+}
+
+/* Debug main program to determine if the library has all of the mapped
+   external functions.  Note, you need a new enough glibc to provide all of the
+   f128 functions.  */
+#ifdef DO_MAIN
+int
+main (void)
+{
+  return 0;
+}
+#endif
diff --git a/gcc/testsuite/gcc.target/powerpc/float128-longdouble-stdio.c b/gcc/testsuite/gcc.target/powerpc/float128-longdouble-stdio.c
new file mode 100644
index 00000000000..77c7b41cec9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/float128-longdouble-stdio.c
@@ -0,0 +1,37 @@
+/* { dg-require-effective-target ppc_float128_hw } */
+/* { dg-require-effective-target power10_ok } */
+/* { dg-options "-mdejagnu-cpu=power9 -mno-pcrel -O2 -Wno-psabi -mabi=ieeelongdouble" } */
+
+/* Test if switching long double to IEEE 128-bit maps the printf and scanf
+   function names correctly.  We explicitly turn off PC-relative support to
+   make it simpler to compare the call without having a @notoc qualifier.  */
+
+#include <stdlib.h>
+
+volatile long double x = 1.0L;
+volatile long double y, z;
+
+int
+main (void)
+{
+  char buffer[100];
+
+  /* { dg-final { scan-assembler {\m__sprintfieee128\M} } }  */
+  __builtin_sprintf (buffer, "%Lg", x);
+
+  /* { dg-final { scan-assembler {\m__printfieee128\M} } }  */
+  __builtin_printf ("x is %Lg [%s]\n", x, buffer);
+
+  /* { dg-final { scan-assembler {\m__isoc99sscanfieee128\M} } }  */
+  __builtin_sscanf (buffer, "%Lg", &y);
+
+  __builtin_printf ("Type 1.0: ");
+
+  /* { dg-final { scan-assembler {\m__isoc99scanfieee128\M} } }  */
+  __builtin_scanf ("%Lg", &z);
+
+  if (x != y || x != z)
+    abort ();
+
+  return 0;
+}
-- 
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] 21+ messages in thread

* [PATCH 2/9] PowerPC: Update __float128 and __ibm128 error messages.
  2020-09-24 20:20 [PATCH 0/9] PowerPC: Patches to enable changing the long double default to IEEE 128-bit on little endian PowerPC 64-bit Linux systems Michael Meissner
  2020-09-24 20:31 ` [PATCH 1/9] PowerPC: Map long double built-in functions if IEEE 128-bit long double Michael Meissner
@ 2020-09-24 20:33 ` Michael Meissner
  2020-09-24 20:34 ` [PATCH 3/9] PowerPC: Update IEEE <-> IBM 128-bit floating point conversions Michael Meissner
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Michael Meissner @ 2020-09-24 20:33 UTC (permalink / raw)
  To: Michael Meissner, gcc-patches, Segher Boessenkool,
	David Edelsohn, Bill Schmidt, Peter Bergner, Jeff Law,
	Jonathan Wakely

PowerPC: Update __float128 and __ibm128 error messages.

This patch attempts to make the error messages for intermixing IEEE 128-bit
floating point with IBM 128-bit extended double types to be clearer if the long
double type uses the IEEE 128-bit format.

gcc/
2020-09-23  Michael Meissner  <meissner@linux.ibm.com>

	* config/rs6000/rs6000.c (rs6000_invalid_binary_op): Update error
	messages about mixing IBM long double and IEEE 128-bit.

gcc/testsuite/
2020-09-23  Michael Meissner  <meissner@linux.ibm.com>

	* gcc.target/powerpc/bfp/scalar-extract-exp-4.c: Update failure
	messages.
	* gcc.target/powerpc/bfp/scalar-extract-sig-4.c: Update failure
	messages.
	* gcc.target/powerpc/bfp/scalar-test-data-class-11.c: Update
	failure messages.
	* gcc.target/powerpc/bfp/scalar-test-neg-5.c: Update failure
	messages.
	* gcc.target/powerpc/float128-mix-2.c: New test.
	* gcc.target/powerpc/float128-mix-3.c: New test.
	* gcc.target/powerpc/float128-mix.c: Update failure messages.
---
 gcc/config/rs6000/rs6000.c                    | 20 ++++---------------
 .../powerpc/bfp/scalar-extract-exp-4.c        |  4 +---
 .../powerpc/bfp/scalar-extract-sig-4.c        |  2 +-
 .../powerpc/bfp/scalar-test-data-class-11.c   |  2 +-
 .../powerpc/bfp/scalar-test-neg-5.c           |  2 +-
 .../gcc.target/powerpc/float128-mix-2.c       | 17 ++++++++++++++++
 .../gcc.target/powerpc/float128-mix-3.c       | 17 ++++++++++++++++
 .../gcc.target/powerpc/float128-mix.c         | 19 ++++++++++--------
 8 files changed, 53 insertions(+), 30 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/powerpc/float128-mix-2.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/float128-mix-3.c

diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 0ff0f31d552..97f535f0018 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -14352,22 +14352,10 @@ rs6000_invalid_binary_op (int op ATTRIBUTE_UNUSED,
 
   if (!TARGET_FLOAT128_CVT)
     {
-      if ((mode1 == KFmode && mode2 == IFmode)
-	  || (mode1 == IFmode && mode2 == KFmode))
-	return N_("__float128 and __ibm128 cannot be used in the same "
-		  "expression");
-
-      if (TARGET_IEEEQUAD
-	  && ((mode1 == IFmode && mode2 == TFmode)
-	      || (mode1 == TFmode && mode2 == IFmode)))
-	return N_("__ibm128 and long double cannot be used in the same "
-		  "expression");
-
-      if (!TARGET_IEEEQUAD
-	  && ((mode1 == KFmode && mode2 == TFmode)
-	      || (mode1 == TFmode && mode2 == KFmode)))
-	return N_("__float128 and long double cannot be used in the same "
-		  "expression");
+      if ((FLOAT128_IEEE_P (mode1) && FLOAT128_IBM_P (mode2))
+	  || (FLOAT128_IBM_P (mode1) && FLOAT128_IEEE_P (mode2)))
+	return N_("Invalid mixing of IEEE 128-bit and IBM 128-bit floating "
+		  "point types");
     }
 
   return NULL;
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-4.c b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-4.c
index 850ff620490..2065a287bb3 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-4.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-4.c
@@ -11,7 +11,5 @@ get_exponent (__ieee128 *p)
 {
   __ieee128 source = *p;
 
-  return __builtin_vec_scalar_extract_exp (source); /* { dg-error "'__builtin_vsx_scalar_extract_expq' requires" } */
+  return __builtin_vec_scalar_extract_exp (source); /* { dg-error "'__builtin_vsx_scalar_extract_exp.*' requires" } */
 }
-
-
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-4.c b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-4.c
index 32a53c6fffd..37bc8332961 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-4.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-4.c
@@ -11,5 +11,5 @@ get_significand (__ieee128 *p)
 {
   __ieee128 source = *p;
 
-  return __builtin_vec_scalar_extract_sig (source);	/* { dg-error "'__builtin_vsx_scalar_extract_sigq' requires" } */
+  return __builtin_vec_scalar_extract_sig (source);	/* { dg-error "'__builtin_vsx_scalar_extract_sig.*' requires" } */
 }
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-11.c b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-11.c
index 7c6fca2b729..ec3118792c4 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-11.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-11.c
@@ -10,5 +10,5 @@ test_data_class (__ieee128 *p)
 {
   __ieee128 source = *p;
 
-  return __builtin_vec_scalar_test_data_class (source, 3); /* { dg-error "'__builtin_vsx_scalar_test_data_class_qp' requires" } */
+  return __builtin_vec_scalar_test_data_class (source, 3); /* { dg-error "'__builtin_vsx_scalar_test_data_class_.*' requires" } */
 }
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-5.c b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-5.c
index bab86040a7b..eb9cacf8c50 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-5.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-5.c
@@ -10,5 +10,5 @@ test_neg (__ieee128 *p)
 {
   __ieee128 source = *p;
 
-  return __builtin_vec_scalar_test_neg_qp (source); /* { dg-error "'__builtin_vsx_scalar_test_neg_qp' requires" } */
+  return __builtin_vec_scalar_test_neg_qp (source); /* { dg-error "'__builtin_vsx_scalar_test_neg_.*' requires" } */
 }
diff --git a/gcc/testsuite/gcc.target/powerpc/float128-mix-2.c b/gcc/testsuite/gcc.target/powerpc/float128-mix-2.c
new file mode 100644
index 00000000000..b88102118a9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/float128-mix-2.c
@@ -0,0 +1,17 @@
+/* { dg-do compile { target { powerpc*-*-linux* } } } */
+/* { dg-require-effective-target ppc_float128_sw } */
+/* { dg-options "-O2 -mvsx -Wno-psabi -mabi=ieeelongdouble -mlong-double-128" } */
+
+/* Test to make sure that __float128 and long double do not generate errors if
+   long double uses the IEEE 128-bit format.  */
+__float128
+add (__float128 a, long double b)
+{
+  return a+b;
+}
+
+long double
+sub (long double a, __float128 b)
+{
+  return a-b;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/float128-mix-3.c b/gcc/testsuite/gcc.target/powerpc/float128-mix-3.c
new file mode 100644
index 00000000000..13fbe7fd08a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/float128-mix-3.c
@@ -0,0 +1,17 @@
+/* { dg-do compile { target { powerpc*-*-linux* } } } */
+/* { dg-require-effective-target ppc_float128_sw } */
+/* { dg-options "-O2 -mvsx" } */
+
+/* Test to make sure that __float128 and __ibm128 cannot be combined
+   together.  */
+__float128
+add (__float128 a, __ibm128 b)
+{
+  return a+b;	/* { dg-error "IEEE 128-bit and IBM 128-bit floating point" } */
+}
+
+__ibm128
+sub (__ibm128 a, __float128 b)
+{
+  return a-b;	/* { dg-error "IEEE 128-bit and IBM 128-bit floating point" } */
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/float128-mix.c b/gcc/testsuite/gcc.target/powerpc/float128-mix.c
index 71f840c9490..eb8e6ac27bc 100644
--- a/gcc/testsuite/gcc.target/powerpc/float128-mix.c
+++ b/gcc/testsuite/gcc.target/powerpc/float128-mix.c
@@ -1,15 +1,18 @@
 /* { dg-do compile { target { powerpc*-*-linux* } } } */
-/* { dg-require-effective-target powerpc_vsx_ok } */
-/* { dg-options "-O2 -mvsx" } */
+/* { dg-require-effective-target ppc_float128_sw } */
+/* { dg-options "-O2 -mvsx -Wno-psabi -mabi=ibmlongdouble -mlong-double-128" } */
 
-
-/* Test to make sure that __float128 and long double cannot be combined together.  */
-__float128 add (__float128 a, long double b)
+/* Test to make sure that __float128 and long double cannot be combined
+   together, when long double uses the IBM extended double format, and
+   __float128 uses the IEEE 128-bit format.  */
+__float128
+add (__float128 a, long double b)
 {
-  return a+b;	/* { dg-error "__float128 and long double cannot be used in the same expression" } */
+  return a+b;	/* { dg-error "IEEE 128-bit and IBM 128-bit floating point" } */
 }
 
-__ibm128 sub (long double a, __float128 b)
+long double
+sub (long double a, __float128 b)
 {
-  return a-b;	/* { dg-error "__float128 and long double cannot be used in the same expression" } */
+  return a-b;	/* { dg-error "IEEE 128-bit and IBM 128-bit floating point" } */
 }
-- 
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] 21+ messages in thread

* [PATCH 3/9] PowerPC: Update IEEE <-> IBM 128-bit floating point conversions.
  2020-09-24 20:20 [PATCH 0/9] PowerPC: Patches to enable changing the long double default to IEEE 128-bit on little endian PowerPC 64-bit Linux systems Michael Meissner
  2020-09-24 20:31 ` [PATCH 1/9] PowerPC: Map long double built-in functions if IEEE 128-bit long double Michael Meissner
  2020-09-24 20:33 ` [PATCH 2/9] PowerPC: Update __float128 and __ibm128 error messages Michael Meissner
@ 2020-09-24 20:34 ` Michael Meissner
  2020-09-24 20:35 ` [PATCH 4/9] PowerPC: Add IEEE 128-bit <-> Decimal conversions Michael Meissner
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Michael Meissner @ 2020-09-24 20:34 UTC (permalink / raw)
  To: Michael Meissner, gcc-patches, Segher Boessenkool,
	David Edelsohn, Bill Schmidt, Peter Bergner, Jeff Law,
	Jonathan Wakely

PowerPC: Update IEEE <-> IBM 128-bit floating point conversions.

This patch changes the code for doing conversions between IEEE 128-bit floating
point and IBM 128-bit extended double floating point.  It moves the conversion
functions to a separate file.  It uses explicit __ibm128 instead of long
double to allow the long double type to be set to IEEE 128-bit.

libgcc/
2020-09-23  Michael Meissner  <meissner@linux.ibm.com>

	* config/rs6000/extendkftf2-sw.c: Move __float128 to __ibm128
	conversion into float128-convert.h.
	* config/rs6000/float128-convert.h: New file.
	* config/rs6000/float128-hw.c: Move conversions between __float128
	and __ibm128 into float128-convert.h.
	* config/rs6000/quad-float128.h: Move conversions between
	__float128 and __ibm128 into float128-convert.h.
	* config/rs6000/trunctfkf2-sw.c: Move __ibm128 to __float128
	conversion to float128-convert.h.
---
 libgcc/config/rs6000/extendkftf2-sw.c   |  6 +-
 libgcc/config/rs6000/float128-convert.h | 77 +++++++++++++++++++++++++
 libgcc/config/rs6000/float128-hw.c      | 11 +---
 libgcc/config/rs6000/quad-float128.h    | 58 -------------------
 libgcc/config/rs6000/trunctfkf2-sw.c    |  6 +-
 5 files changed, 84 insertions(+), 74 deletions(-)
 create mode 100644 libgcc/config/rs6000/float128-convert.h

diff --git a/libgcc/config/rs6000/extendkftf2-sw.c b/libgcc/config/rs6000/extendkftf2-sw.c
index f0de1784c43..80b48c20d9c 100644
--- a/libgcc/config/rs6000/extendkftf2-sw.c
+++ b/libgcc/config/rs6000/extendkftf2-sw.c
@@ -38,6 +38,7 @@
 
 #include "soft-fp.h"
 #include "quad-float128.h"
+#include "float128-convert.h"
 
 #ifndef FLOAT128_HW_INSNS
 #define __extendkftf2_sw __extendkftf2
@@ -46,8 +47,5 @@
 IBM128_TYPE
 __extendkftf2_sw (TFtype value)
 {
-  IBM128_TYPE ret;
-
-  CVT_FLOAT128_TO_IBM128 (ret, value);
-  return ret;
+  return convert_float128_to_ibm128 (value);
 }
diff --git a/libgcc/config/rs6000/float128-convert.h b/libgcc/config/rs6000/float128-convert.h
new file mode 100644
index 00000000000..bb6b3d71889
--- /dev/null
+++ b/libgcc/config/rs6000/float128-convert.h
@@ -0,0 +1,77 @@
+/* Convert between IEEE 128-bit and IBM 128-bit floating point types.
+   Copyright (C) 2016-2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Michael Meissner (meissner@linux.ibm.com).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* 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.
+
+   These functions are called by the actual conversion functions called by the
+   compiler.  This code is here to allow being built at power8 (no hardware
+   float128) and power9 (hardware float128) varients that is selected by an
+   IFUNC function.  */
+
+static inline __ibm128 convert_float128_to_ibm128 (__float128);
+static inline __float128 convert_ibm128_to_float128 (__ibm128);
+
+static inline __ibm128
+convert_float128_to_ibm128 (__float128 value)
+{
+  double high, high_temp, low;
+
+  high = (double) value;
+  if (__builtin_isnan (high) || __builtin_isinf (high))
+    low = 0.0;
+
+  else
+    {
+      low = (double) (value - (__float128) high);
+      /* Renormalize low/high and move them into canonical IBM long
+	 double form.  */
+      high_temp = high + low;
+      low = (high - high_temp) + low;
+      high = high_temp;
+    }
+
+  return __builtin_pack_ibm128 (high, low);
+}
+
+static inline __float128
+convert_ibm128_to_float128 (__ibm128 value)
+{
+  double high = __builtin_unpack_ibm128 (value, 0);
+  double low = __builtin_unpack_ibm128 (value, 1);
+
+  /* Handle the special cases of NAN and infinity.  Similarly, if low is 0.0,
+     there no need to do the add.  In addition, avoiding the add produces the
+     correct sign if high is -0.0.  */
+  if (__builtin_isnan (high) || __builtin_isinf (high) || low == 0.0)
+    return (__float128) high;
+
+  else
+    return ((__float128) high) + ((__float128) low);
+}
diff --git a/libgcc/config/rs6000/float128-hw.c b/libgcc/config/rs6000/float128-hw.c
index 8705b53e22a..b9b04cd2feb 100644
--- a/libgcc/config/rs6000/float128-hw.c
+++ b/libgcc/config/rs6000/float128-hw.c
@@ -33,6 +33,7 @@
 
 #include <soft-fp.h>
 #include <quad-float128.h>
+#include "float128-convert.h"
 
 #ifndef __FLOAT128_HARDWARE__
 #error "This module must be compiled with IEEE 128-bit hardware support"
@@ -190,18 +191,12 @@ __unordkf2_hw (TFtype a, TFtype b)
 IBM128_TYPE
 __extendkftf2_hw (TFtype value)
 {
-  IBM128_TYPE ret;
-
-  CVT_FLOAT128_TO_IBM128 (ret, value);
-  return ret;
+  return convert_float128_to_ibm128 (value);
 }
 
 /* Convert __ibm128 to __float128.  */
 TFtype
 __trunctfkf2_hw (IBM128_TYPE value)
 {
-  TFtype ret;
-
-  CVT_IBM128_TO_FLOAT128 (ret, value);
-  return ret;
+  return convert_ibm128_to_float128 (value);
 }
diff --git a/libgcc/config/rs6000/quad-float128.h b/libgcc/config/rs6000/quad-float128.h
index 32ef328a8ea..15880c2ab30 100644
--- a/libgcc/config/rs6000/quad-float128.h
+++ b/libgcc/config/rs6000/quad-float128.h
@@ -170,61 +170,3 @@ extern TFtype __trunctfkf2 (IBM128_TYPE);
 /* Complex __float128 built on __float128 interfaces.  */
 extern TCtype __mulkc3 (TFtype, TFtype, TFtype, TFtype);
 extern TCtype __divkc3 (TFtype, TFtype, TFtype, TFtype);
-
-/* 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.  */
-
-union ibm128_union {
-  IBM128_TYPE ibm128;
-  double dbl[2];
-};
-
-#define CVT_FLOAT128_TO_IBM128(RESULT, VALUE)				\
-{									\
-  double __high, __low;							\
-  TFtype __value = (VALUE);						\
-  union ibm128_union u;							\
-									\
-  __high = (double) __value;						\
-  if (__builtin_isnan (__high) || __builtin_isinf (__high))		\
-    __low = 0.0;							\
-									\
-  else									\
-    {									\
-      double __high_temp;						\
-									\
-      __low = (double) (__value - (TFtype) __high);			\
-      /* Renormalize low/high and move them into canonical IBM long	\
-	 double form.  */						\
-      __high_temp = __high + __low;					\
-      __low = (__high - __high_temp) + __low;				\
-      __high = __high_temp;						\
-    }									\
-									\
-  u.dbl[0] = __high;							\
-  u.dbl[1] = __low;							\
-  RESULT = u.ibm128;							\
-}
-
-#define CVT_IBM128_TO_FLOAT128(RESULT, VALUE)				\
-{									\
-  union ibm128_union u;							\
-  double __high, __low;							\
-									\
-  u.ibm128 = (VALUE);							\
-  __high = u.dbl[0];							\
-  __low = u.dbl[1];							\
-									\
-  /* Handle the special cases of NAN and infinity.  */			\
-  if (__builtin_isnan (__high) || __builtin_isinf (__high))		\
-    RESULT = (TFtype) __high;						\
-									\
-  /* If low is 0.0, there no need to do the add.  In addition,		\
-     avoiding the add produces the correct sign if high is -0.0.  */	\
-  else if (__low == 0.0)						\
-    RESULT = (TFtype) __high;						\
-									\
-  else									\
-    RESULT = ((TFtype) __high) + ((TFtype) __low);			\
-}
diff --git a/libgcc/config/rs6000/trunctfkf2-sw.c b/libgcc/config/rs6000/trunctfkf2-sw.c
index 3e8af25a585..af52cff5954 100644
--- a/libgcc/config/rs6000/trunctfkf2-sw.c
+++ b/libgcc/config/rs6000/trunctfkf2-sw.c
@@ -38,6 +38,7 @@
 
 #include "soft-fp.h"
 #include "quad-float128.h"
+#include "float128-convert.h"
 
 #ifndef FLOAT128_HW_INSNS
 #define __trunctfkf2_sw __trunctfkf2
@@ -46,8 +47,5 @@
 TFtype
 __trunctfkf2_sw (IBM128_TYPE value)
 {
-  TFtype ret;
-
-  CVT_IBM128_TO_FLOAT128 (ret, value);
-  return ret;
+  return convert_ibm128_to_float128 (value);
 }
-- 
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] 21+ messages in thread

* [PATCH 4/9] PowerPC: Add IEEE 128-bit <-> Decimal conversions.
  2020-09-24 20:20 [PATCH 0/9] PowerPC: Patches to enable changing the long double default to IEEE 128-bit on little endian PowerPC 64-bit Linux systems Michael Meissner
                   ` (2 preceding siblings ...)
  2020-09-24 20:34 ` [PATCH 3/9] PowerPC: Update IEEE <-> IBM 128-bit floating point conversions Michael Meissner
@ 2020-09-24 20:35 ` Michael Meissner
  2020-09-24 20:36 ` [PATCH 5/9] PowerPC: Update tests to run if long double is IEEE 128-bit Michael Meissner
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Michael Meissner @ 2020-09-24 20:35 UTC (permalink / raw)
  To: Michael Meissner, gcc-patches, Segher Boessenkool,
	David Edelsohn, Bill Schmidt, Peter Bergner, Jeff Law,
	Jonathan Wakely

PowerPC: Add IEEE 128-bit <-> Decimal conversions.

This patch adds the basic support for converting between IEEE 128-bit floating
point and Decimal types.

libgcc/
2020-09-23  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/_td_to_kf.c: New file.
	* config/rs6000/t-float128: Build __floating conversions to/from
	Decimal support functions.  By default compile with long double
	being IBM extended double.
	* dfp-bit.c: Add support for building the PowerPC _Float128
	to/from Decimal conversion functions.
	* dfp-bit.h: Likewise.
---
 libgcc/config/rs6000/_dd_to_kf.c | 30 ++++++++++++++++++++++++++
 libgcc/config/rs6000/_kf_to_dd.c | 30 ++++++++++++++++++++++++++
 libgcc/config/rs6000/_kf_to_sd.c | 30 ++++++++++++++++++++++++++
 libgcc/config/rs6000/_kf_to_td.c | 30 ++++++++++++++++++++++++++
 libgcc/config/rs6000/_sd_to_kf.c | 30 ++++++++++++++++++++++++++
 libgcc/config/rs6000/_td_to_kf.c | 30 ++++++++++++++++++++++++++
 libgcc/config/rs6000/t-float128  | 30 +++++++++++++++++++++++++-
 libgcc/dfp-bit.c                 | 10 +++++++--
 libgcc/dfp-bit.h                 | 37 +++++++++++++++++++++++++++++---
 9 files changed, 251 insertions(+), 6 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/_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..081415fd393
--- /dev/null
+++ b/libgcc/config/rs6000/_dd_to_kf.c
@@ -0,0 +1,30 @@
+/* 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.  */
+#define FINE_GRAINED_LIBRARIES	1
+#define L_dd_to_kf		1
+#define WIDTH			64
+
+/* 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..09a62cbe629
--- /dev/null
+++ b/libgcc/config/rs6000/_kf_to_dd.c
@@ -0,0 +1,30 @@
+/* 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.  */
+#define FINE_GRAINED_LIBRARIES	1
+#define L_kf_to_dd		1
+#define WIDTH			64
+
+/* 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..f35b68eb4d9
--- /dev/null
+++ b/libgcc/config/rs6000/_kf_to_sd.c
@@ -0,0 +1,30 @@
+/* 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.  */
+#define FINE_GRAINED_LIBRARIES	1
+#define L_kf_to_sd		1
+#define WIDTH			32
+
+/* 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..d35d09ed848
--- /dev/null
+++ b/libgcc/config/rs6000/_kf_to_td.c
@@ -0,0 +1,30 @@
+/* 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.  */
+#define FINE_GRAINED_LIBRARIES	1
+#define L_kf_to_td		1
+#define WIDTH			128
+
+/* 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..9396b71f162
--- /dev/null
+++ b/libgcc/config/rs6000/_sd_to_kf.c
@@ -0,0 +1,30 @@
+/* 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.  */
+#define FINE_GRAINED_LIBRARIES	1
+#define L_sd_to_kf		1
+#define WIDTH			32
+
+/* Use dfp-bit.c to do the real work.  */
+#include "dfp-bit.c"
diff --git a/libgcc/config/rs6000/_td_to_kf.c b/libgcc/config/rs6000/_td_to_kf.c
new file mode 100644
index 00000000000..fade2a28859
--- /dev/null
+++ b/libgcc/config/rs6000/_td_to_kf.c
@@ -0,0 +1,30 @@
+/* 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.  */
+#define FINE_GRAINED_LIBRARIES	1
+#define L_td_to_kf		1
+#define WIDTH			128
+
+/* Use dfp-bit.c to do the real work.  */
+#include "dfp-bit.c"
diff --git a/libgcc/config/rs6000/t-float128 b/libgcc/config/rs6000/t-float128
index d5413445189..3d6054c6a54 100644
--- a/libgcc/config/rs6000/t-float128
+++ b/libgcc/config/rs6000/t-float128
@@ -22,10 +22,15 @@ 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
+
 # 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 +74,29 @@ $(fp128_ppc_obj)	 : INTERNAL_CFLAGS += $(FP128_CFLAGS_SW)
 $(fp128_obj)		 : $(fp128_includes)
 $(fp128_obj)		 : $(srcdir)/config/rs6000/quad-float128.h
 
+
+# If we are switching the default long double type, we need to use
+# -mno-gnu-attribute so that the __ibm128 support functions don't signal a
+# linker error since the default long double is now IEEE 128-bit instead of IBM
+# 128-bit.
+ibm-ldouble$(objext)	: INTERNAL_CFLAGS += -mno-gnu-attribute
+
+# Similarly for the decimal routines, compile with long double == IBM 128-bit,
+# but set the flags so that it can be linked with either long double format.
+#DECNUMINC	+= -Wno-psabi -mabi=ibmlongdouble -mno-gnu-attribute
+
+# Force the TF mode to/from decimal functions to be compiled with IBM long double
+# Add building the KF mode to/from decimal conversions
+TF_DECIMAL_OBJS		= _dd_to_tf$(objext) _sd_to_tf$(objext) \
+		          _td_to_tf$(objext) _tf_to_dd$(objext) \
+			  _tf_to_sd$(objext) _tf_to_td$(objext)
+
+CFLAGS_TF_DECIMAL	= -mno-gnu-attribute -Wno-psabi -mabi=ibmlongdouble
+CFLAGS_KF_DECIMAL	= -mno-gnu-attribute -Wno-psabi -mabi=ieeelongdouble
+CFLAGS_KF_DECIMAL_SW	= $(CFLAGS_KF_DECIMAL) -mno-float128-hardware
+
+$(TF_DECIMAL_OBJS) : INTERNAL_CFLAGS += $(CFLAGS_TF_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 $@"; \
diff --git a/libgcc/dfp-bit.c b/libgcc/dfp-bit.c
index 935a1e340db..67212daa0bd 100644
--- a/libgcc/dfp-bit.c
+++ b/libgcc/dfp-bit.c
@@ -609,7 +609,8 @@ INT_TO_DFP (INT_TYPE i)
  || ((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)) \
-     && LONG_DOUBLE_HAS_TF_MODE)
+     && LONG_DOUBLE_HAS_TF_MODE) \
+  || defined (L_sd_to_kf) || defined (L_dd_to_kf) || defined (L_td_to_kf)
 BFP_TYPE
 DFP_TO_BFP (DFP_C_TYPE f)
 {
@@ -629,7 +630,8 @@ DFP_TO_BFP (DFP_C_TYPE f)
  || ((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)) \
-     && LONG_DOUBLE_HAS_TF_MODE)
+     && LONG_DOUBLE_HAS_TF_MODE) \
+ || defined (L_kf_to_sd) || defined (L_kf_to_dd) || defined (L_kf_to_td)
 DFP_C_TYPE
 BFP_TO_DFP (BFP_TYPE x)
 {
@@ -642,7 +644,11 @@ BFP_TO_DFP (BFP_TYPE x)
   DFP_INIT_ROUNDMODE (context.round);
 
   /* Use a C library function to write the floating point value to a string.  */
+#if HAVE_KF_MODE
+  strfromf128 (buf, BUFMAX, BFP_FMT, (BFP_VIA_TYPE) x);
+#else
   sprintf (buf, BFP_FMT, (BFP_VIA_TYPE) x);
+#endif
 
   /* 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 4215241da18..91fcdcdc7eb 100644
--- a/libgcc/dfp-bit.h
+++ b/libgcc/dfp-bit.h
@@ -226,6 +226,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #define STR_TO_INT strtoull
 #endif
 
+/* Support PowerPC KF mode, which is __float128 when long double is
+   IBM extended double.  */
+#if 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 HAVE_KF_MODE 1
+#endif
+
 /* Conversions between decimal float types and binary float types use
    BFP_KIND to determine the data type and C functions to use.  */
 
@@ -239,7 +246,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
  ||   defined (L_xf_to_sd) || defined (L_xf_to_dd) || defined (L_xf_to_td)
 #define BFP_KIND 3
 #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)
+ ||   defined (L_tf_to_sd) || defined (L_tf_to_dd) || defined (L_tf_to_td) \
+ ||   defined (HAVE_KF_MODE)
 #define BFP_KIND 4
 #endif
 
@@ -277,6 +285,18 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #define STR_TO_BFP strtold
 #endif /* LONG_DOUBLE_HAS_XF_MODE */
 
+#elif BFP_KIND == 4 && HAVE_KF_MODE
+#define BFP_TYPE _Float128
+#define BFP_FMT "%.36e"
+#define STR_TO_BFP strtof128
+#define BFP_VIA_TYPE _Float128
+extern _Float128 strtof128 (const char *__restrict __nptr,
+			    char **__restrict __endptr)
+  __THROW __nonnull ((1));
+extern int strfromf128 (char *__dest, size_t __size, const char * __format,
+			_Float128 __f)
+  __THROW __nonnull ((3));
+
 #elif BFP_KIND == 4
 #if LONG_DOUBLE_HAS_TF_MODE
 #define BFP_TYPE TFtype
@@ -487,6 +507,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #elif BFP_KIND == 3
 #define BFP_TO_DFP	DPD_BID_NAME(__dpd_truncxfsd,__bid_truncxfsd)
 #define DFP_TO_BFP	DPD_BID_NAME(__dpd_extendsdxf,__bid_extendsdxf)
+#elif BFP_KIND == 4 && HAVE_KF_MODE
+#define BFP_TO_DFP	DPD_BID_NAME(__dpd_trunckfsd,__bid_trunckfsd)
+#define DFP_TO_BFP	DPD_BID_NAME(__dpd_extendsdkf,__bid_extendsdkf)
 #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)
@@ -502,6 +525,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #elif BFP_KIND == 3
 #define BFP_TO_DFP	DPD_BID_NAME(__dpd_truncxfdd,__bid_truncxfdd)
 #define DFP_TO_BFP	DPD_BID_NAME(__dpd_extendddxf,__bid_extendddxf)
+#elif BFP_KIND == 4 && HAVE_KF_MODE
+#define BFP_TO_DFP	DPD_BID_NAME(__dpd_trunckfdd,__bid_trunckfdd)
+#define DFP_TO_BFP	DPD_BID_NAME(__dpd_extendddkf,__bid_extendddkf)
 #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)
@@ -517,6 +543,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #elif BFP_KIND == 3
 #define BFP_TO_DFP	DPD_BID_NAME(__dpd_extendxftd,__bid_extendxftd)
 #define DFP_TO_BFP	DPD_BID_NAME(__dpd_trunctdxf,__bid_trunctdxf)
+#elif BFP_KIND == 4 && HAVE_KF_MODE
+#define BFP_TO_DFP	DPD_BID_NAME(__dpd_extendkftd,__bid_extendkftd)
+#define DFP_TO_BFP	DPD_BID_NAME(__dpd_trunctdkf,__bid_trunctdkf)
 #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)
@@ -612,7 +641,8 @@ extern DFP_C_TYPE INT_TO_DFP (INT_TYPE);
  || ((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)) \
-     && LONG_DOUBLE_HAS_TF_MODE)
+     && LONG_DOUBLE_HAS_TF_MODE) \
+ || defined (L_sd_to_kf) || defined (L_dd_to_kf) || defined (L_td_to_kf)
 extern BFP_TYPE DFP_TO_BFP (DFP_C_TYPE);
 #endif
 
@@ -621,7 +651,8 @@ extern BFP_TYPE DFP_TO_BFP (DFP_C_TYPE);
  || ((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)) \
-     && LONG_DOUBLE_HAS_TF_MODE)
+     && LONG_DOUBLE_HAS_TF_MODE) \
+ || defined (L_kf_to_sd) || defined (L_kf_to_dd) || defined (L_kf_to_td)
 extern DFP_C_TYPE BFP_TO_DFP (BFP_TYPE);
 #endif
 
-- 
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] 21+ messages in thread

* [PATCH 5/9] PowerPC: Update tests to run if long double is IEEE 128-bit.
  2020-09-24 20:20 [PATCH 0/9] PowerPC: Patches to enable changing the long double default to IEEE 128-bit on little endian PowerPC 64-bit Linux systems Michael Meissner
                   ` (3 preceding siblings ...)
  2020-09-24 20:35 ` [PATCH 4/9] PowerPC: Add IEEE 128-bit <-> Decimal conversions Michael Meissner
@ 2020-09-24 20:36 ` Michael Meissner
  2020-09-24 20:40 ` [PATCH 6/9] PowerPC: If long double is IEEE 128-bit, map q built-ins to *l instead of *f128 Michael Meissner
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Michael Meissner @ 2020-09-24 20:36 UTC (permalink / raw)
  To: Michael Meissner, gcc-patches, Segher Boessenkool,
	David Edelsohn, Bill Schmidt, Peter Bergner, Jeff Law,
	Jonathan Wakely

PowerPC: Update tests to run if long double is IEEE 128-bit.

gcc/testsuite/
2020-09-23  Michael Meissner  <meissner@linux.ibm.com>

	* c-c++-common/dfp/convert-bfp-11.c: If long double is IEEE
	128-bit, skip the test.
	* gcc.dg/nextafter-2.c: On PowerPC, if long double is IEEE
	128-bit, include math.h to get the built-in mapped correctly.
	* gcc.target/powerpc/pr70117.c: Add support for long double being
	IEEE 128-bit.
---
 gcc/testsuite/c-c++-common/dfp/convert-bfp-11.c |  7 +++++++
 gcc/testsuite/gcc.dg/nextafter-2.c              | 10 ++++++++++
 gcc/testsuite/gcc.target/powerpc/pr70117.c      |  6 ++++--
 3 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/gcc/testsuite/c-c++-common/dfp/convert-bfp-11.c b/gcc/testsuite/c-c++-common/dfp/convert-bfp-11.c
index 95c433d2c24..6ee0c1c6ae9 100644
--- a/gcc/testsuite/c-c++-common/dfp/convert-bfp-11.c
+++ b/gcc/testsuite/c-c++-common/dfp/convert-bfp-11.c
@@ -5,6 +5,7 @@
    Don't force 128-bit long doubles because runtime support depends
    on glibc.  */
 
+#include <float.h>
 #include "convert.h"
 
 volatile _Decimal32 sd;
@@ -39,6 +40,12 @@ main ()
   if (sizeof (long double) != 16)
     return 0;
 
+  /* This test is written to test IBM extended double, which is a pair of
+     doubles.  If long double can hold a larger value than a double can, such
+     as when long double is IEEE 128-bit, just exit immediately.  */
+  if (LDBL_MAX_10_EXP > DBL_MAX_10_EXP)
+    return 0;
+
   convert_101 ();
   convert_102 ();
 
diff --git a/gcc/testsuite/gcc.dg/nextafter-2.c b/gcc/testsuite/gcc.dg/nextafter-2.c
index e51ae94be0c..64e9e3c485f 100644
--- a/gcc/testsuite/gcc.dg/nextafter-2.c
+++ b/gcc/testsuite/gcc.dg/nextafter-2.c
@@ -13,4 +13,14 @@
 #  define NO_LONG_DOUBLE 1
 # endif
 #endif
+
+#if defined(_ARCH_PPC) && defined(__LONG_DOUBLE_IEEE128__)
+/* On PowerPC systems, long double uses either the IBM long double format, or
+   IEEE 128-bit format.  The compiler switches the long double built-in
+   function names and glibc switches the names when math.h is included.
+   Because this test is run with -fno-builtin, include math.h so that the
+   appropriate nextafter functions are called.  */
+#include <math.h>
+#endif
+
 #include "nextafter-1.c"
diff --git a/gcc/testsuite/gcc.target/powerpc/pr70117.c b/gcc/testsuite/gcc.target/powerpc/pr70117.c
index 3bbd2c595e0..928efe39c7b 100644
--- a/gcc/testsuite/gcc.target/powerpc/pr70117.c
+++ b/gcc/testsuite/gcc.target/powerpc/pr70117.c
@@ -9,9 +9,11 @@
    128-bit floating point, because the type is not enabled on those
    systems.  */
 #define LDOUBLE __ibm128
+#define IBM128_MAX ((__ibm128) 1.79769313486231580793728971405301199e+308L)
 
 #elif defined(__LONG_DOUBLE_IBM128__)
 #define LDOUBLE long double
+#define IBM128_MAX LDBL_MAX
 
 #else
 #error "long double must be either IBM 128-bit or IEEE 128-bit"
@@ -75,10 +77,10 @@ main (void)
   if (__builtin_isnormal (ld))
     __builtin_abort ();
 
-  ld = LDBL_MAX;
+  ld = IBM128_MAX;
   if (!__builtin_isnormal (ld))
     __builtin_abort ();
-  ld = -LDBL_MAX;
+  ld = -IBM128_MAX;
   if (!__builtin_isnormal (ld))
     __builtin_abort ();
 
-- 
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] 21+ messages in thread

* [PATCH 6/9] PowerPC: If long double is IEEE 128-bit, map q built-ins to *l instead of *f128.
  2020-09-24 20:20 [PATCH 0/9] PowerPC: Patches to enable changing the long double default to IEEE 128-bit on little endian PowerPC 64-bit Linux systems Michael Meissner
                   ` (4 preceding siblings ...)
  2020-09-24 20:36 ` [PATCH 5/9] PowerPC: Update tests to run if long double is IEEE 128-bit Michael Meissner
@ 2020-09-24 20:40 ` Michael Meissner
  2020-09-24 20:42 ` [PATCH 7/9] PowerPC: Update IEEE 128-bit built-in functions to work if long double is IEEE 128-bit Michael Meissner
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Michael Meissner @ 2020-09-24 20:40 UTC (permalink / raw)
  To: Michael Meissner, gcc-patches, Segher Boessenkool,
	David Edelsohn, Bill Schmidt, Peter Bergner, Jeff Law,
	Jonathan Wakely

PowerPC: If long double is IEEE 128-bit, map q built-ins to *l instead of *f128.

If we map nanq to nanf128 when long double is IEEE, it seems to lose the
special signaling vs. non-signaling NAN support.  This patch maps the functions
to the long double version if long double is IEEE 128-bit.

gcc/
2020-09-23  Michael Meissner  <meissner@linux.ibm.com>

	* config/rs6000/rs6000-c.c (rs6000_cpu_cpp_builtins): If long
	double is IEEE-128 map the nanq built-in functions to the long
	double function, not the f128 function.
---
 gcc/config/rs6000/rs6000-c.c | 31 ++++++++++++++++++++++++-------
 1 file changed, 24 insertions(+), 7 deletions(-)

diff --git a/gcc/config/rs6000/rs6000-c.c b/gcc/config/rs6000/rs6000-c.c
index f5982907e90..8f7a8eec740 100644
--- a/gcc/config/rs6000/rs6000-c.c
+++ b/gcc/config/rs6000/rs6000-c.c
@@ -681,15 +681,32 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfile)
       builtin_define ("__builtin_vsx_xvnmsubmsp=__builtin_vsx_xvnmsubsp");
     }
 
-  /* Map the old _Float128 'q' builtins into the new 'f128' builtins.  */
+  /* Map the old _Float128 'q' builtins into the new 'f128' builtins if long
+     double is IBM or 64-bit.
+
+     However, if long double is IEEE 128-bit, map both sets of built-in
+     functions to the normal long double version.  This shows up in nansf128
+     vs. nanf128.  */
   if (TARGET_FLOAT128_TYPE)
     {
-      builtin_define ("__builtin_fabsq=__builtin_fabsf128");
-      builtin_define ("__builtin_copysignq=__builtin_copysignf128");
-      builtin_define ("__builtin_nanq=__builtin_nanf128");
-      builtin_define ("__builtin_nansq=__builtin_nansf128");
-      builtin_define ("__builtin_infq=__builtin_inff128");
-      builtin_define ("__builtin_huge_valq=__builtin_huge_valf128");
+      if (FLOAT128_IEEE_P (TFmode))
+	{
+	  builtin_define ("__builtin_fabsq=__builtin_fabsl");
+	  builtin_define ("__builtin_copysignq=__builtin_copysignl");
+	  builtin_define ("__builtin_nanq=__builtin_nanl");
+	  builtin_define ("__builtin_nansq=__builtin_nansl");
+	  builtin_define ("__builtin_infq=__builtin_infl");
+	  builtin_define ("__builtin_huge_valq=__builtin_huge_vall");
+	}
+      else
+	{
+	  builtin_define ("__builtin_fabsq=__builtin_fabsf128");
+	  builtin_define ("__builtin_copysignq=__builtin_copysignf128");
+	  builtin_define ("__builtin_nanq=__builtin_nanf128");
+	  builtin_define ("__builtin_nansq=__builtin_nansf128");
+	  builtin_define ("__builtin_infq=__builtin_inff128");
+	  builtin_define ("__builtin_huge_valq=__builtin_huge_valf128");
+	}
     }
 
   /* Tell users they can use __builtin_bswap{16,64}.  */
-- 
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] 21+ messages in thread

* [PATCH 7/9] PowerPC: Update IEEE 128-bit built-in functions to work if long double is IEEE 128-bit.
  2020-09-24 20:20 [PATCH 0/9] PowerPC: Patches to enable changing the long double default to IEEE 128-bit on little endian PowerPC 64-bit Linux systems Michael Meissner
                   ` (5 preceding siblings ...)
  2020-09-24 20:40 ` [PATCH 6/9] PowerPC: If long double is IEEE 128-bit, map q built-ins to *l instead of *f128 Michael Meissner
@ 2020-09-24 20:42 ` Michael Meissner
  2020-09-24 20:45 ` [PATCH 8/9] PowerPC: Change tests to use __float128 instead of __ieee128 Michael Meissner
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Michael Meissner @ 2020-09-24 20:42 UTC (permalink / raw)
  To: Michael Meissner, gcc-patches, Segher Boessenkool,
	David Edelsohn, Bill Schmidt, Peter Bergner, Jeff Law,
	Jonathan Wakely

PowerPC: Update IEEE 128-bit built-in functions to work if long double is IEEE 128-bit.

This patch adds long double variants of the power10 __float128 built-in
functions.  This is needed because __float128 uses TFmode in this case
instead of KFmode.

gcc/
2020-09-23  Michael Meissner  <meissner@linux.ibm.com>

	* config/rs6000/rs6000-call.c (altivec_overloaded_builtins): Add
	built-in functions for long double built-ins that use IEEE
	128-bit.
	(rs6000_expand_builtin): Change the KF IEEE 128-bit comparison
	insns to TF if long double is IEEE 128-bit.
	* config/rs6000/rs6000-builtin.def (scalar_extract_exptf): Add
	support for long double being IEEE 128-bit built-in functions.
	(scalar_extract_sigtf): Likewise.
	(scalar_test_neg_tf): Likewise.
	(scalar_insert_exp_tf): Likewise.
	(scalar_insert_exp_tfp): Likewise.
	(scalar_cmp_exp_tf_gt): Likewise.
	(scalar_cmp_exp_tf_lt): Likewise.
	(scalar_cmp_exp_tf_eq): Likewise.
	(scalar_cmp_exp_tf_unordered): Likewise.
	(scalar_test_data_class_tf): Likewise.
---
 gcc/config/rs6000/rs6000-builtin.def | 11 ++++++++
 gcc/config/rs6000/rs6000-call.c      | 40 ++++++++++++++++++++++++++++
 2 files changed, 51 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def
index e91a48ddf5f..7d52961c8cf 100644
--- a/gcc/config/rs6000/rs6000-builtin.def
+++ b/gcc/config/rs6000/rs6000-builtin.def
@@ -2401,8 +2401,11 @@ BU_P9V_64BIT_VSX_1 (VSESDP,	"scalar_extract_sig",	CONST,	xsxsigdp)
 
 BU_FLOAT128_HW_VSX_1 (VSEEQP,	"scalar_extract_expq",	CONST,	xsxexpqp_kf)
 BU_FLOAT128_HW_VSX_1 (VSESQP,	"scalar_extract_sigq",	CONST,	xsxsigqp_kf)
+BU_FLOAT128_HW_VSX_1 (VSEETF,	"scalar_extract_exptf",	CONST,	xsxexpqp_tf)
+BU_FLOAT128_HW_VSX_1 (VSESTF,	"scalar_extract_sigtf",	CONST,	xsxsigqp_tf)
 
 BU_FLOAT128_HW_VSX_1 (VSTDCNQP, "scalar_test_neg_qp",	CONST,	xststdcnegqp_kf)
+BU_FLOAT128_HW_VSX_1 (VSTDCNTF, "scalar_test_neg_tf",	CONST,	xststdcnegqp_tf)
 BU_P9V_VSX_1 (VSTDCNDP,	"scalar_test_neg_dp",	CONST,	xststdcnegdp)
 BU_P9V_VSX_1 (VSTDCNSP,	"scalar_test_neg_sp",	CONST,	xststdcnegsp)
 
@@ -2420,6 +2423,8 @@ BU_P9V_64BIT_VSX_2 (VSIEDPF,	"scalar_insert_exp_dp",	CONST,	xsiexpdpf)
 
 BU_FLOAT128_HW_VSX_2 (VSIEQP,	"scalar_insert_exp_q",	CONST,	xsiexpqp_kf)
 BU_FLOAT128_HW_VSX_2 (VSIEQPF,	"scalar_insert_exp_qp",	CONST,	xsiexpqpf_kf)
+BU_FLOAT128_HW_VSX_2 (VSIETF,	"scalar_insert_exp_tf",	CONST,	xsiexpqp_tf)
+BU_FLOAT128_HW_VSX_2 (VSIETFF,	"scalar_insert_exp_tfp", CONST,	xsiexpqpf_tf)
 
 BU_P9V_VSX_2 (VSCEDPGT,	"scalar_cmp_exp_dp_gt",	CONST,	xscmpexpdp_gt)
 BU_P9V_VSX_2 (VSCEDPLT,	"scalar_cmp_exp_dp_lt",	CONST,	xscmpexpdp_lt)
@@ -2431,7 +2436,13 @@ BU_P9V_VSX_2 (VSCEQPLT,	"scalar_cmp_exp_qp_lt",	CONST,	xscmpexpqp_lt_kf)
 BU_P9V_VSX_2 (VSCEQPEQ,	"scalar_cmp_exp_qp_eq",	CONST,	xscmpexpqp_eq_kf)
 BU_P9V_VSX_2 (VSCEQPUO,	"scalar_cmp_exp_qp_unordered",	CONST,	xscmpexpqp_unordered_kf)
 
+BU_P9V_VSX_2 (VSCETFGT,	"scalar_cmp_exp_tf_gt",	CONST,	xscmpexpqp_gt_tf)
+BU_P9V_VSX_2 (VSCETFLT,	"scalar_cmp_exp_tf_lt",	CONST,	xscmpexpqp_lt_tf)
+BU_P9V_VSX_2 (VSCETFEQ,	"scalar_cmp_exp_tf_eq",	CONST,	xscmpexpqp_eq_tf)
+BU_P9V_VSX_2 (VSCETFUO,	"scalar_cmp_exp_tf_unordered", CONST, xscmpexpqp_unordered_tf)
+
 BU_FLOAT128_HW_VSX_2 (VSTDCQP, "scalar_test_data_class_qp",	CONST,	xststdcqp_kf)
+BU_FLOAT128_HW_VSX_2 (VSTDCTF, "scalar_test_data_class_tf",	CONST,	xststdcqp_tf)
 BU_P9V_VSX_2 (VSTDCDP,	"scalar_test_data_class_dp",	CONST,	xststdcdp)
 BU_P9V_VSX_2 (VSTDCSP,	"scalar_test_data_class_sp",	CONST,	xststdcsp)
 
diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index a8b520834c7..8dc779df1f9 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -4587,6 +4587,8 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
     RS6000_BTI_bool_int, RS6000_BTI_double, RS6000_BTI_INTSI, 0 },
   { P9V_BUILTIN_VEC_VSTDC, P9V_BUILTIN_VSTDCQP,
     RS6000_BTI_bool_int, RS6000_BTI_ieee128_float, RS6000_BTI_INTSI, 0 },
+  { P9V_BUILTIN_VEC_VSTDC, P9V_BUILTIN_VSTDCTF,
+    RS6000_BTI_bool_int, RS6000_BTI_long_double, RS6000_BTI_INTSI, 0 },
 
   { P9V_BUILTIN_VEC_VSTDCSP, P9V_BUILTIN_VSTDCSP,
     RS6000_BTI_bool_int, RS6000_BTI_float, RS6000_BTI_INTSI, 0 },
@@ -4594,6 +4596,8 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
     RS6000_BTI_bool_int, RS6000_BTI_double, RS6000_BTI_INTSI, 0 },
   { P9V_BUILTIN_VEC_VSTDCQP, P9V_BUILTIN_VSTDCQP,
     RS6000_BTI_bool_int, RS6000_BTI_ieee128_float, RS6000_BTI_INTSI, 0 },
+  { P9V_BUILTIN_VEC_VSTDCQP, P9V_BUILTIN_VSTDCTF,
+    RS6000_BTI_bool_int, RS6000_BTI_long_double, RS6000_BTI_INTSI, 0 },
 
   { P9V_BUILTIN_VEC_VSTDCN, P9V_BUILTIN_VSTDCNSP,
     RS6000_BTI_bool_int, RS6000_BTI_float, 0, 0 },
@@ -4601,6 +4605,8 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
     RS6000_BTI_bool_int, RS6000_BTI_double, 0, 0 },
   { P9V_BUILTIN_VEC_VSTDCN, P9V_BUILTIN_VSTDCNQP,
     RS6000_BTI_bool_int, RS6000_BTI_ieee128_float, 0, 0 },
+  { P9V_BUILTIN_VEC_VSTDCN, P9V_BUILTIN_VSTDCNTF,
+    RS6000_BTI_bool_int, RS6000_BTI_long_double, 0, 0 },
 
   { P9V_BUILTIN_VEC_VSTDCNSP, P9V_BUILTIN_VSTDCNSP,
     RS6000_BTI_bool_int, RS6000_BTI_float, 0, 0 },
@@ -4608,16 +4614,22 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
     RS6000_BTI_bool_int, RS6000_BTI_double, 0, 0 },
   { P9V_BUILTIN_VEC_VSTDCNQP, P9V_BUILTIN_VSTDCNQP,
     RS6000_BTI_bool_int, RS6000_BTI_ieee128_float, 0, 0 },
+  { P9V_BUILTIN_VEC_VSTDCNQP, P9V_BUILTIN_VSTDCNTF,
+    RS6000_BTI_bool_int, RS6000_BTI_long_double, 0, 0 },
 
   { P9V_BUILTIN_VEC_VSEEDP, P9V_BUILTIN_VSEEDP,
     RS6000_BTI_UINTSI, RS6000_BTI_double, 0, 0 },
   { P9V_BUILTIN_VEC_VSEEDP, P9V_BUILTIN_VSEEQP,
     RS6000_BTI_UINTDI, RS6000_BTI_ieee128_float, 0, 0 },
+  { P9V_BUILTIN_VEC_VSEEDP, P9V_BUILTIN_VSEETF,
+    RS6000_BTI_UINTDI, RS6000_BTI_long_double, 0, 0 },
 
   { P9V_BUILTIN_VEC_VSESDP, P9V_BUILTIN_VSESDP,
     RS6000_BTI_UINTDI, RS6000_BTI_double, 0, 0 },
   { P9V_BUILTIN_VEC_VSESDP, P9V_BUILTIN_VSESQP,
     RS6000_BTI_UINTTI, RS6000_BTI_ieee128_float, 0, 0 },
+  { P9V_BUILTIN_VEC_VSESDP, P9V_BUILTIN_VSESTF,
+    RS6000_BTI_UINTTI, RS6000_BTI_long_double, 0, 0 },
 
   { P9V_BUILTIN_VEC_VSIEDP, P9V_BUILTIN_VSIEDP,
     RS6000_BTI_double, RS6000_BTI_UINTDI, RS6000_BTI_UINTDI, 0 },
@@ -4626,25 +4638,37 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
 
   { P9V_BUILTIN_VEC_VSIEDP, P9V_BUILTIN_VSIEQP,
     RS6000_BTI_ieee128_float, RS6000_BTI_UINTTI, RS6000_BTI_UINTDI, 0 },
+  { P9V_BUILTIN_VEC_VSIEDP, P9V_BUILTIN_VSIETF,
+    RS6000_BTI_long_double, RS6000_BTI_UINTTI, RS6000_BTI_UINTDI, 0 },
   { P9V_BUILTIN_VEC_VSIEDP, P9V_BUILTIN_VSIEQPF,
     RS6000_BTI_ieee128_float, RS6000_BTI_ieee128_float, RS6000_BTI_UINTDI, 0 },
+  { P9V_BUILTIN_VEC_VSIEDP, P9V_BUILTIN_VSIETFF,
+    RS6000_BTI_long_double, RS6000_BTI_long_double, RS6000_BTI_UINTDI, 0 },
 
   { P9V_BUILTIN_VEC_VSCEGT, P9V_BUILTIN_VSCEDPGT,
     RS6000_BTI_INTSI, RS6000_BTI_double, RS6000_BTI_double, 0 },
   { P9V_BUILTIN_VEC_VSCEGT, P9V_BUILTIN_VSCEQPGT,
     RS6000_BTI_INTSI, RS6000_BTI_ieee128_float, RS6000_BTI_ieee128_float, 0 },
+  { P9V_BUILTIN_VEC_VSCEGT, P9V_BUILTIN_VSCETFGT,
+    RS6000_BTI_INTSI, RS6000_BTI_long_double, RS6000_BTI_long_double, 0 },
   { P9V_BUILTIN_VEC_VSCELT, P9V_BUILTIN_VSCEDPLT,
     RS6000_BTI_INTSI, RS6000_BTI_double, RS6000_BTI_double, 0 },
   { P9V_BUILTIN_VEC_VSCELT, P9V_BUILTIN_VSCEQPLT,
     RS6000_BTI_INTSI, RS6000_BTI_ieee128_float, RS6000_BTI_ieee128_float, 0 },
+  { P9V_BUILTIN_VEC_VSCELT, P9V_BUILTIN_VSCETFLT,
+    RS6000_BTI_INTSI, RS6000_BTI_long_double, RS6000_BTI_long_double, 0 },
   { P9V_BUILTIN_VEC_VSCEEQ, P9V_BUILTIN_VSCEDPEQ,
     RS6000_BTI_INTSI, RS6000_BTI_double, RS6000_BTI_double, 0 },
   { P9V_BUILTIN_VEC_VSCEEQ, P9V_BUILTIN_VSCEQPEQ,
     RS6000_BTI_INTSI, RS6000_BTI_ieee128_float, RS6000_BTI_ieee128_float, 0 },
+  { P9V_BUILTIN_VEC_VSCEEQ, P9V_BUILTIN_VSCETFEQ,
+    RS6000_BTI_INTSI, RS6000_BTI_long_double, RS6000_BTI_long_double, 0 },
   { P9V_BUILTIN_VEC_VSCEUO, P9V_BUILTIN_VSCEDPUO,
     RS6000_BTI_INTSI, RS6000_BTI_double, RS6000_BTI_double, 0 },
   { P9V_BUILTIN_VEC_VSCEUO, P9V_BUILTIN_VSCEQPUO,
     RS6000_BTI_INTSI, RS6000_BTI_ieee128_float, RS6000_BTI_ieee128_float, 0 },
+  { P9V_BUILTIN_VEC_VSCEUO, P9V_BUILTIN_VSCETFUO,
+    RS6000_BTI_INTSI, RS6000_BTI_long_double, RS6000_BTI_long_double, 0 },
 
   { P9V_BUILTIN_VEC_XL_LEN_R, P9V_BUILTIN_XL_LEN_R,
     RS6000_BTI_unsigned_V16QI, ~RS6000_BTI_UINTQI,
@@ -12534,6 +12558,22 @@ rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
       case CODE_FOR_xsiexpqp_kf:	icode = CODE_FOR_xsiexpqp_tf;	break;
       case CODE_FOR_xsiexpqpf_kf:	icode = CODE_FOR_xsiexpqpf_tf;	break;
       case CODE_FOR_xststdcqp_kf:	icode = CODE_FOR_xststdcqp_tf;	break;
+
+      case CODE_FOR_xscmpexpqp_eq_kf:
+	icode = CODE_FOR_xscmpexpqp_eq_tf;
+	break;
+
+      case CODE_FOR_xscmpexpqp_lt_kf:
+	icode = CODE_FOR_xscmpexpqp_lt_tf;
+	break;
+
+      case CODE_FOR_xscmpexpqp_gt_kf:
+	icode = CODE_FOR_xscmpexpqp_gt_tf;
+	break;
+
+      case CODE_FOR_xscmpexpqp_unordered_kf:
+	icode = CODE_FOR_xscmpexpqp_unordered_tf;
+	break;
       }
 
   if (TARGET_DEBUG_BUILTIN)
-- 
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] 21+ messages in thread

* [PATCH 8/9] PowerPC: Change tests to use __float128 instead of __ieee128.
  2020-09-24 20:20 [PATCH 0/9] PowerPC: Patches to enable changing the long double default to IEEE 128-bit on little endian PowerPC 64-bit Linux systems Michael Meissner
                   ` (6 preceding siblings ...)
  2020-09-24 20:42 ` [PATCH 7/9] PowerPC: Update IEEE 128-bit built-in functions to work if long double is IEEE 128-bit Michael Meissner
@ 2020-09-24 20:45 ` Michael Meissner
  2020-09-24 20:47 ` [PATCH 9/9] PowerPC: Use __builtin_pack_ieee128 if long double is IEEE 128-bit Michael Meissner
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Michael Meissner @ 2020-09-24 20:45 UTC (permalink / raw)
  To: Michael Meissner, gcc-patches, Segher Boessenkool,
	David Edelsohn, Bill Schmidt, Peter Bergner, Jeff Law,
	Jonathan Wakely

From e4114c9c13067b356f9ab5c5bb4c6a928771aef8 Mon Sep 17 00:00:00 2001
From: Michael Meissner <meissner@linux.ibm.com>
Date: Wed, 23 Sep 2020 17:12:56 -0400
Subject: [PATCH 8/9] PowerPC: Change tests to use __float128 instead of __ieee128.

Two of the tests used the __ieee128 keyword instead of __float128.  This
patch changes those cases to use the official keyword.

gcc/testsuite/
2020-09-23  Michael Meissner  <meissner@linux.ibm.com>

	* gcc.target/powerpc/float128-cmp2-runnable.c: Use __float128
	keyword instead of __ieee128.
	* gcc.target/powerpc/pr92796.c: Use __float128 keyword instead of
	__ieee128.
---
 gcc/testsuite/gcc.target/powerpc/float128-cmp2-runnable.c | 2 +-
 gcc/testsuite/gcc.target/powerpc/pr92796.c                | 8 ++++----
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/gcc/testsuite/gcc.target/powerpc/float128-cmp2-runnable.c b/gcc/testsuite/gcc.target/powerpc/float128-cmp2-runnable.c
index 93dd1128a3f..fbec5289063 100644
--- a/gcc/testsuite/gcc.target/powerpc/float128-cmp2-runnable.c
+++ b/gcc/testsuite/gcc.target/powerpc/float128-cmp2-runnable.c
@@ -16,7 +16,7 @@ int main(void)
 {
   int result;
   double a_dble, b_dble;
-  __ieee128 a_ieee128, b_ieee128;
+  __float128 a_ieee128, b_ieee128;
   
   a_dble = 3.10;
   b_dble = 3.10;
diff --git a/gcc/testsuite/gcc.target/powerpc/pr92796.c b/gcc/testsuite/gcc.target/powerpc/pr92796.c
index 1e671e175de..f2c6b8b7f5c 100644
--- a/gcc/testsuite/gcc.target/powerpc/pr92796.c
+++ b/gcc/testsuite/gcc.target/powerpc/pr92796.c
@@ -4,14 +4,14 @@
 
 typedef union
 {
-  __ieee128 a;
+  __float128 a;
   int b;
 } c;
 
-__ieee128
-d (__ieee128 x)
+__float128
+d (__float128 x)
 {
-  __ieee128 g;
+  __float128 g;
   c h;
   h.a = x;
   g = h.b & 5;
-- 
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] 21+ messages in thread

* [PATCH 9/9] PowerPC: Use __builtin_pack_ieee128 if long double is IEEE 128-bit.
  2020-09-24 20:20 [PATCH 0/9] PowerPC: Patches to enable changing the long double default to IEEE 128-bit on little endian PowerPC 64-bit Linux systems Michael Meissner
                   ` (7 preceding siblings ...)
  2020-09-24 20:45 ` [PATCH 8/9] PowerPC: Change tests to use __float128 instead of __ieee128 Michael Meissner
@ 2020-09-24 20:47 ` Michael Meissner
  2020-10-09  4:35 ` [PATCH 1/9, revised] PowerPC: Map long double built-in functions if IEEE 128-bit long double Michael Meissner
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Michael Meissner @ 2020-09-24 20:47 UTC (permalink / raw)
  To: Michael Meissner, gcc-patches, Segher Boessenkool,
	David Edelsohn, Bill Schmidt, Peter Bergner, Jeff Law,
	Jonathan Wakely

PowerPC: Use __builtin_pack_ieee128 if long double is IEEE 128-bit.

This patch changes the __ibm128 emulator to use __builtin_pack_ieee128
instead of __builtin_pack_longdouble if long double is IEEE 128-bit, and
we need to use the __ibm128 type.

libgcc/
2020-09-23  Michael Meissner  <meissner@linux.ibm.com>

	* config/rs6000/ibm-ldouble.c (pack_ldouble): Use
	__builtin_pack_ieee128 if long double is IEEE 128-bit.
---
 libgcc/config/rs6000/ibm-ldouble.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/libgcc/config/rs6000/ibm-ldouble.c b/libgcc/config/rs6000/ibm-ldouble.c
index dd2a02373f2..767fdd72683 100644
--- a/libgcc/config/rs6000/ibm-ldouble.c
+++ b/libgcc/config/rs6000/ibm-ldouble.c
@@ -102,9 +102,17 @@ __asm__ (".symver __gcc_qadd,_xlqadd@GCC_3.4\n\t"
 static inline IBM128_TYPE
 pack_ldouble (double dh, double dl)
 {
+  /* If we are building on a non-VSX system, the __ibm128 type is not defined.
+     This means we can't always use __builtin_pack_ibm128.  Instead, we use
+     __builtin_pack_longdouble if long double uses the IBM extended double
+     128-bit format, and use the explicit __builtin_pack_ibm128 if long double
+     is IEEE 128-bit.  */
 #if defined (__LONG_DOUBLE_128__) && defined (__LONG_DOUBLE_IBM128__)	\
     && !(defined (_SOFT_FLOAT) || defined (__NO_FPRS__))
   return __builtin_pack_longdouble (dh, dl);
+#elif defined (__LONG_DOUBLE_128__) && defined (__LONG_DOUBLE_IEEE128__) \
+    && !(defined (_SOFT_FLOAT) || defined (__NO_FPRS__))
+  return __builtin_pack_ibm128 (dh, dl);
 #else
   union
   {
-- 
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] 21+ messages in thread

* Re: [PATCH 1/9] PowerPC: Map long double built-in functions if IEEE 128-bit long double.
  2020-09-24 20:31 ` [PATCH 1/9] PowerPC: Map long double built-in functions if IEEE 128-bit long double Michael Meissner
@ 2020-10-01 23:05   ` Joseph Myers
  2020-10-08  5:20     ` Michael Meissner
  0 siblings, 1 reply; 21+ messages in thread
From: Joseph Myers @ 2020-10-01 23:05 UTC (permalink / raw)
  To: Michael Meissner
  Cc: gcc-patches, Segher Boessenkool, David Edelsohn, Bill Schmidt,
	Peter Bergner, Jeff Law, Jonathan Wakely

On Thu, 24 Sep 2020, Michael Meissner via Gcc-patches wrote:

> To map the math functions, typically this patch changes <name>l to <name>f128.
> However there are some exceptions that are handled with this patch.

glibc 2.32 added __*ieee128 names for the *f128 functions, to allow the 
long double functions to be called in a namespace-clean way (when the 
defined feature test macros do not enable the TS 18661-3 function names). 
So I think GCC should also prefer to map to those names where possible, 
rather than the *f128 names.

-- 
Joseph S. Myers
joseph@codesourcery.com

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

* Re: [PATCH 1/9] PowerPC: Map long double built-in functions if IEEE 128-bit long double.
  2020-10-01 23:05   ` Joseph Myers
@ 2020-10-08  5:20     ` Michael Meissner
  0 siblings, 0 replies; 21+ messages in thread
From: Michael Meissner @ 2020-10-08  5:20 UTC (permalink / raw)
  To: Joseph Myers
  Cc: Michael Meissner, gcc-patches, Segher Boessenkool,
	David Edelsohn, Bill Schmidt, Peter Bergner, Jeff Law,
	Jonathan Wakely

On Thu, Oct 01, 2020 at 11:05:04PM +0000, Joseph Myers wrote:
> On Thu, 24 Sep 2020, Michael Meissner via Gcc-patches wrote:
> 
> > To map the math functions, typically this patch changes <name>l to <name>f128.
> > However there are some exceptions that are handled with this patch.
> 
> glibc 2.32 added __*ieee128 names for the *f128 functions, to allow the 
> long double functions to be called in a namespace-clean way (when the 
> defined feature test macros do not enable the TS 18661-3 function names). 
> So I think GCC should also prefer to map to those names where possible, 
> rather than the *f128 names.

Good idea.  Thanks.

-- 
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] 21+ messages in thread

* [PATCH 1/9, revised] PowerPC: Map long double built-in functions if IEEE 128-bit long double.
  2020-09-24 20:20 [PATCH 0/9] PowerPC: Patches to enable changing the long double default to IEEE 128-bit on little endian PowerPC 64-bit Linux systems Michael Meissner
                   ` (8 preceding siblings ...)
  2020-09-24 20:47 ` [PATCH 9/9] PowerPC: Use __builtin_pack_ieee128 if long double is IEEE 128-bit Michael Meissner
@ 2020-10-09  4:35 ` Michael Meissner
  2020-10-16 20:30   ` Segher Boessenkool
  2020-10-12 23:16 ` Ping: [PATCH 0/9] PowerPC: Patches to enable changing the long double default to IEEE 128-bit on little endian PowerPC 64-bit Linux systems Michael Meissner
                   ` (2 subsequent siblings)
  12 siblings, 1 reply; 21+ messages in thread
From: Michael Meissner @ 2020-10-09  4:35 UTC (permalink / raw)
  To: Michael Meissner
  Cc: gcc-patches, Segher Boessenkool, David Edelsohn, Bill Schmidt,
	Peter Bergner, Jeff Law, Jonathan Wakely

PowerPC: Map long double built-in functions if IEEE 128-bit long double.

This patch is revised from the first version of the patch posted.  It uses the
names that are not in the user's namespace (i.e. __sinieee128 instead of
sinf128) that Joseph Myers suggested.

This patch goes through the built-in functions and changes the name of the
math, scanf, and printf built-in functions to use the functions that GLIBC
provides when long double uses the IEEE 128-bit representation.

Normally the mapping is done in the math.h and stdio.h files.  However, not
everybody uses these files, which means we also need to change the external
name for the built-in function within the compiler.

In addition, changing the name in GCC allows the Fortran compiler to
automatically use the correct name.

To map the math functions, typically this patch changes <name>l to
__<name>ieee128.  However there are some exceptions that are handled with this
patch.

To map the printf functions, <name> is mapped to __<name>ieee128.

To map the scanf functions, <name> is mapped to __isoc99<name>ieee128.

gcc/
2020-10-09  Michael Meissner  <meissner@linux.ibm.com>

	* config/rs6000/rs6000.c (rs6000_mangle_decl_assembler_name): Add
	support for mapping built-in function names for long double
	built-in functions if long double is IEEE 128-bit.

gcc/testsuite/
2020-10-09  Michael Meissner  <meissner@linux.ibm.com>

	* gcc.target/powerpc/float128-longdouble-math.c: New test.
	* gcc.target/powerpc/float128-longdouble-stdio.c: New test.
	* gcc.target/powerpc/float128-math.c: Adjust test for new name
	being generated.
---
 gcc/config/rs6000/rs6000.c                    | 162 ++++-
 .../powerpc/float128-longdouble-math.c        | 567 ++++++++++++++++++
 .../powerpc/float128-longdouble-stdio.c       |  37 ++
 .../gcc.target/powerpc/float128-math.c        |   6 +-
 4 files changed, 738 insertions(+), 34 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/powerpc/float128-longdouble-math.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/float128-longdouble-stdio.c

diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index b28f4adf464..4c141c9f276 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -26897,56 +26897,156 @@ rs6000_globalize_decl_name (FILE * stream, tree decl)
    library before you can switch the real*16 type at compile time.
 
    We use the TARGET_MANGLE_DECL_ASSEMBLER_NAME hook to change this name.  We
-   only do this if the default is that long double is IBM extended double, and
-   the user asked for IEEE 128-bit.  */
+   only do this transformation if the __float128 type is enabled.  This
+   prevents us from doing the transformation on older 32-bit ports that might
+   have enabled using IEEE 128-bit floating point as the default long double
+   type.  */
 
 static tree
 rs6000_mangle_decl_assembler_name (tree decl, tree id)
 {
-  if (!TARGET_IEEEQUAD_DEFAULT && TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
-      && TREE_CODE (decl) == FUNCTION_DECL && DECL_IS_BUILTIN (decl) )
+  if (TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
+      && TREE_CODE (decl) == FUNCTION_DECL
+      && fndecl_built_in_p (decl, BUILT_IN_NORMAL))
     {
       size_t len = IDENTIFIER_LENGTH (id);
       const char *name = IDENTIFIER_POINTER (id);
+      const char *newname = NULL;
 
-      if (name[len - 1] == 'l')
+      /* See if it is one of the built-in functions with an unusual name.  */
+      switch (DECL_FUNCTION_CODE (decl))
 	{
-	  bool uses_ieee128_p = false;
-	  tree type = TREE_TYPE (decl);
-	  machine_mode ret_mode = TYPE_MODE (type);
+	default:
+	  break;
 
-	  /* See if the function returns a IEEE 128-bit floating point type or
-	     complex type.  */
-	  if (ret_mode == TFmode || ret_mode == TCmode)
-	    uses_ieee128_p = true;
-	  else
+	case BUILT_IN_DREML:
+	  newname = "__remainderieee128";
+	  break;
+
+	case BUILT_IN_GAMMAL:
+	  newname = "__lgammaieee128";
+	  break;
+
+	case BUILT_IN_GAMMAL_R:
+	case BUILT_IN_LGAMMAL_R:
+	  newname = "__lgammaieee128_r";
+	  break;
+
+	case BUILT_IN_NEXTTOWARD:
+	  newname = "__nexttoward_to_ieee128";
+	  break;
+
+	case BUILT_IN_NEXTTOWARDF:
+	  newname = "__nexttowardf_to_ieee128";
+	  break;
+
+	case BUILT_IN_NEXTTOWARDL:
+	  newname = "__nexttowardieee128";
+	  break;
+
+	case BUILT_IN_POW10L:
+	  newname = "__exp10ieee128";
+	  break;
+
+	case BUILT_IN_SCALBL:
+	  newname = "__scalbnieee128";
+	  break;
+
+	case BUILT_IN_SIGNIFICANDL:
+	  newname = "__significandieee128";
+	  break;
+
+	case BUILT_IN_SINCOSL:
+	  newname = "__sincosieee128";
+	  break;
+	}
+
+      /* Update the __builtin_*printf && __builtin_*scanf functions.  */
+      if (!newname)
+	{
+	  const size_t printf_len = sizeof ("printf") - 1;
+	  const size_t scanf_len = sizeof ("scanf") - 1;
+	  const size_t printf_extra
+	    = sizeof ("__") - 1 + sizeof ("ieee128") - 1;
+	  const size_t scanf_extra
+	    = sizeof ("__isoc99_") - 1 + sizeof ("ieee128") - 1;
+
+	  if (len >= printf_len
+	      && strcmp (name + len - printf_len, "printf") == 0)
+	    {
+	      char *name2 = (char *) alloca (len + 1 + printf_extra);
+	      strcpy (name2, "__");
+	      memcpy (name2 + 2, name, len);
+	      strcpy (name2 + 2 + len, "ieee128");
+	      newname = (const char *) name2;
+	    }
+
+	  else if (len >= scanf_len
+		   && strcmp (name + len - scanf_len, "scanf") == 0)
 	    {
-	      function_args_iterator args_iter;
-	      tree arg;
+	      char *name2 = (char *) alloca (len + 1 + scanf_extra);
+	      strcpy (name2, "__isoc99_");
+	      memcpy (name2 + sizeof ("__isoc99") - 1, name, len);
+	      strcpy (name2 + sizeof ("__isoc99") - 1 + len, "ieee128");
+	      newname = (const char *) name2;
+	    }
 
-	      /* See if the function passes a IEEE 128-bit floating point type
-		 or complex type.  */
-	      FOREACH_FUNCTION_ARGS (type, arg, args_iter)
+	  else if (name[len - 1] == 'l')
+	    {
+	      bool uses_ieee128_p = false;
+	      tree type = TREE_TYPE (decl);
+	      machine_mode ret_mode = TYPE_MODE (type);
+
+	      /* See if the function returns a IEEE 128-bit floating point type or
+		 complex type.  */
+	      if (ret_mode == TFmode || ret_mode == TCmode)
+		uses_ieee128_p = true;
+	      else
 		{
-		  machine_mode arg_mode = TYPE_MODE (arg);
-		  if (arg_mode == TFmode || arg_mode == TCmode)
+		  function_args_iterator args_iter;
+		  tree arg;
+
+		  /* See if the function passes a IEEE 128-bit floating point type
+		     or complex type.  */
+		  FOREACH_FUNCTION_ARGS (type, arg, args_iter)
 		    {
-		      uses_ieee128_p = true;
-		      break;
+		      machine_mode arg_mode = TYPE_MODE (arg);
+		      if (arg_mode == TFmode || arg_mode == TCmode)
+			{
+			  uses_ieee128_p = true;
+			  break;
+			}
 		    }
 		}
-	    }
 
-	  /* If we passed or returned an IEEE 128-bit floating point type,
-	     change the name.  */
-	  if (uses_ieee128_p)
-	    {
-	      char *name2 = (char *) alloca (len + 4);
-	      memcpy (name2, name, len - 1);
-	      strcpy (name2 + len - 1, "f128");
-	      id = get_identifier (name2);
+	      /* If we passed or returned an IEEE 128-bit floating point type,
+		 change the name.  Use __<name>ieee128, instead of <name>l.  */
+	      if (uses_ieee128_p)
+		{
+		  size_t prefix_len = sizeof ("__") - 1;
+		  size_t suffix_len = sizeof ("ieee128") - 1;
+		  char *name2 = (char *) alloca (len + prefix_len + suffix_len + 1);
+		  char *name3 = name2;
+
+		  memcpy (name3, "__", prefix_len);
+		  name3 += prefix_len;
+
+		  memcpy (name3, name, len - 1);	/* omit trailing 'l'.  */
+		  name3 += len - 1;
+
+		  memcpy (name3, "ieee128", suffix_len + 1);
+		  newname = (const char *) name2;
+		}
 	    }
 	}
+
+      if (newname)
+	{
+	  if (TARGET_DEBUG_BUILTIN)
+	    fprintf (stderr, "Map %s => %s\n", name, newname);
+
+	  id = get_identifier (newname);
+	}
     }
 
   return id;
diff --git a/gcc/testsuite/gcc.target/powerpc/float128-longdouble-math.c b/gcc/testsuite/gcc.target/powerpc/float128-longdouble-math.c
new file mode 100644
index 00000000000..50d40180fdc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/float128-longdouble-math.c
@@ -0,0 +1,567 @@
+/* { dg-require-effective-target ppc_float128_hw } */
+/* { dg-require-effective-target power10_ok } */
+/* { dg-options "-mdejagnu-cpu=power9 -mno-pcrel -O2 -Wno-psabi -mabi=ieeelongdouble" } */
+
+/* Test if switching long double to IEEE 128-bit maps all of the math built-in
+   function names correctly.  We explicitly turn off PC-relative support to
+   make it simpler to compare the call without having a @notoc qualifier.  */
+
+/* Debugging support to use 'name' instead of '__builtin_name'.  Note if you
+   enable this, you will likely need additional flags to get all of the
+   functions defined.  */
+#ifdef DO_FUNC
+#ifndef DO_MATH_H
+#define DO_MATH_H	1
+#endif
+
+#define BUILTIN0(FUNC)                   FUNC ()
+#define BUILTIN1(FUNC, ARG1)             FUNC (ARG1)
+#define BUILTIN2(FUNC, ARG1, ARG2)       FUNC (ARG1, ARG2)
+#define BUILTIN3(FUNC, ARG1, ARG2, ARG3) FUNC (ARG1, ARG2, ARG3)
+
+#else
+#define BUILTIN0(FUNC)                   __builtin_ ## FUNC ()
+#define BUILTIN1(FUNC, ARG1)             __builtin_ ## FUNC (ARG1)
+#define BUILTIN2(FUNC, ARG1, ARG2)       __builtin_ ## FUNC (ARG1, ARG2)
+#define BUILTIN3(FUNC, ARG1, ARG2, ARG3) __builtin_ ## FUNC (ARG1, ARG2, ARG3)
+#endif
+
+/* Debugging support to compare using math.h with the raw built-in functions.  */
+#ifdef DO_MATH_H
+#define __STDC_WANT_IEC_60559_TYPES_EXT__	1
+#define __STDC_WANT_IEC_60559_FUNCS_EXT__	1
+#define _GNU_SOURCE				1
+#define _XOPEN_SOURCE				1
+
+#include <math.h>
+#include <complex.h>
+#endif
+
+/* Built-in functions that returns a long double and take one long double
+   argument.  */
+
+void
+return_ld_arg_ld (long double *p,
+		  long double *q)
+{
+  /* { dg-final { scan-assembler {\m__acoshieee128\M} } }  */
+  *p++ = BUILTIN1 (acoshl, *q++);
+
+  /* { dg-final { scan-assembler {\m__acosieee128\M} } }  */
+  *p++ = BUILTIN1 (acosl, *q++);
+
+  /* { dg-final { scan-assembler {\m__asinhieee128\M} } }  */
+  *p++ = BUILTIN1 (asinhl, *q++);
+
+  /* { dg-final { scan-assembler {\m__asinieee128\M} } }  */
+  *p++ = BUILTIN1 (asinl, *q++);
+
+  /* { dg-final { scan-assembler {\m__atanhieee128\M} } }  */
+  *p++ = BUILTIN1 (atanhl, *q++);
+
+  /* { dg-final { scan-assembler {\m__atanieee128\M} } }  */
+  *p++ = BUILTIN1 (atanl, *q++);
+
+  /* { dg-final { scan-assembler {\m__cbrtieee128\M} } }  */
+  *p++ = BUILTIN1 (cbrtl, *q++);
+
+  /* inline code.  */
+  /* { dg-final { scan-assembler {\mxsrqpi +[0-9]+,[0-9]+,[0-9]+,2\M} } }  */
+  *p++ = BUILTIN1 (ceill, *q++);
+
+  /* { dg-final { scan-assembler {\m__coshieee128\M} } }  */
+  *p++ = BUILTIN1 (coshl, *q++);
+
+  /* { dg-final { scan-assembler {\m__cosieee128\M} } }  */
+  *p++ = BUILTIN1 (cosl, *q++);
+
+  /* { dg-final { scan-assembler {\m__erfcieee128\M} } }  */
+  *p++ = BUILTIN1 (erfcl, *q++);
+
+  /* { dg-final { scan-assembler {\m__erfieee128\M} } }  */
+  *p++ = BUILTIN1 (erfl, *q++);
+
+  /* { dg-final { scan-assembler {\m__exp10ieee128\M} } }  */
+  *p++ = BUILTIN1 (exp10l, *q++);
+
+  /* { dg-final { scan-assembler {\m__exp2ieee128\M} } }  */
+  *p++ = BUILTIN1 (exp2l, *q++);
+
+  /* { dg-final { scan-assembler {\m__expieee128\M} } }  */
+  *p++ = BUILTIN1 (expl, *q++);
+
+  /* { dg-final { scan-assembler {\m__expm1ieee128\M} } }  */
+  *p++ = BUILTIN1 (expm1l, *q++);
+
+  /* inline code.  */
+  /* { dg-final { scan-assembler {\mxsabsqp\M} } }  */
+  *p++ = BUILTIN1 (fabsl, *q++);
+
+  /* inline code.  */
+  /* { dg-final { scan-assembler {\mxsrqpi +[0-9]+,[0-9]+,[0-9]+,3\M} } }  */
+  *p++ = BUILTIN1 (floorl, *q++);
+
+  /* { dg-final { scan-assembler {\m__lgammaieee128\M} } }  */
+  *p++ = BUILTIN1 (gammal, *q++);
+
+  /* { dg-final { scan-assembler {\m__j0ieee128\M} } }  */
+  *p++ = BUILTIN1 (j0l, *q++);
+
+  /* { dg-final { scan-assembler {\m__j1ieee128\M} } }  */
+  *p++ = BUILTIN1 (j1l, *q++);
+
+  /* lgammaf128 mentioned previously.  */
+  *p++ = BUILTIN1 (lgammal, *q++);
+
+  /* { dg-final { scan-assembler {\m__log10ieee128\M} } }  */
+  *p++ = BUILTIN1 (log10l, *q++);
+
+  /* { dg-final { scan-assembler {\m__log1pieee128\M} } }  */
+  *p++ = BUILTIN1 (log1pl, *q++);
+
+  /* { dg-final { scan-assembler {\m__log2ieee128\M} } }  */
+  *p++ = BUILTIN1 (log2l, *q++);
+
+  /* { dg-final { scan-assembler {\m__logbieee128\M} } }  */
+  *p++ = BUILTIN1 (logbl, *q++);
+
+  /* { dg-final { scan-assembler {\m__logieee128\M} } }  */
+  *p++ = BUILTIN1 (logl, *q++);
+
+  /* { dg-final { scan-assembler {\m__nearbyintieee128\M} } }  */
+  *p++ = BUILTIN1 (nearbyintl, *q++);
+
+  /* { dg-final { scan-assembler {\m__exp10ieee128\M} } }  */
+  *p++ = BUILTIN1 (pow10l, *q++);
+
+  /* { dg-final { scan-assembler {\m__rintieee128\M} } }  */
+  *p++ = BUILTIN1 (rintl, *q++);
+
+  /* { dg-final { scan-assembler {\m__roundevenieee128\M} } }  */
+  *p++ = BUILTIN1 (roundevenl, *q++);
+
+  /* inline code.  */
+  /* { dg-final { scan-assembler {\mxsrqpi +[0-9]+,[0-9]+,[0-9]+,0\M} } }  */
+  *p++ = BUILTIN1 (roundl, *q++);
+
+  /* { dg-final { scan-assembler {\m__significandieee128\M} } }  */
+  *p++ = BUILTIN1 (significandl, *q++);
+
+  /* { dg-final { scan-assembler {\m__sinhieee128\M} } }  */
+  *p++ = BUILTIN1 (sinhl, *q++);
+
+  /* { dg-final { scan-assembler {\m__sinieee128\M} } }  */
+  *p++ = BUILTIN1 (sinl, *q++);
+
+  /* { dg-final { scan-assembler {\m__sqrtieee128\M} } }  */
+  *p++ = BUILTIN1 (sqrtl, *q++);
+
+  /* { dg-final { scan-assembler {\m__tanhieee128\M} } }  */
+  *p++ = BUILTIN1 (tanhl, *q++);
+
+  /* { dg-final { scan-assembler {\m__tanieee128\M} } }  */
+  *p++ = BUILTIN1 (tanl, *q++);
+
+  /* { dg-final { scan-assembler {\m__tgammaieee128\M} } }  */
+  *p++ = BUILTIN1 (tgammal, *q++);
+
+  /* inline code.  */
+  /* { dg-final { scan-assembler {\mxsrqpi +[0-9]+,[0-9]+,[0-9]+,1\M} } }  */
+  *p++ = BUILTIN1 (truncl, *q++);
+
+  /* { dg-final { scan-assembler {\m__y0ieee128\M} } }  */
+  *p++ = BUILTIN1 (y0l, *q++);
+
+  /* { dg-final { scan-assembler {\m__y1ieee128\M} } }  */
+  *p   = BUILTIN1 (y1l, *q);  
+
+}
+
+/* Built-in functions that returns a long double and take two long double
+   arguments.  */
+
+void
+return_ld_arg_ld_ld (long double *p,
+		     long double *q,
+		     long double *r)
+{
+  /* { dg-final { scan-assembler {\m__atan2ieee128\M} } }  */
+  *p++ = BUILTIN2 (atan2l, *q++, *r++);
+
+  /* inline code.  */
+  /* { dg-final { scan-assembler {\mxscpsgnqp\M} } }  */
+  *p++ = BUILTIN2 (copysignl, *q++, *r++);
+
+  /* { dg-final { scan-assembler {\m__remainderieee128\M} } }  */
+  *p++ = BUILTIN2 (dreml, *q++, *r++);
+
+  /* { dg-final { scan-assembler {\m__fdimieee128\M} } }  */
+  *p++ = BUILTIN2 (fdiml, *q++, *r++);
+
+  /* { dg-final { scan-assembler {\m__fmaxieee128\M} } }  */
+  *p++ = BUILTIN2 (fmaxl, *q++, *r++);
+
+  /* { dg-final { scan-assembler {\m__fminieee128\M} } }  */
+  *p++ = BUILTIN2 (fminl, *q++, *r++);
+
+  /* { dg-final { scan-assembler {\m__fmodieee128\M} } }  */
+  *p++ = BUILTIN2 (fmodl, *q++, *r++);
+
+  /* { dg-final { scan-assembler {\m__hypotieee128\M} } }  */
+  *p++ = BUILTIN2 (hypotl, *q++, *r++);
+
+  /* { dg-final { scan-assembler {\m__nextafterieee128\M} } }  */
+  *p++ = BUILTIN2 (nextafterl, *q++, *r++);
+
+  /* { dg-final { scan-assembler {\m__nexttowardieee128\M} } }  */
+  *p++ = BUILTIN2 (nexttowardl, *q++, *r++);
+
+  /* { dg-final { scan-assembler {\m__powieee128\M} } }  */
+  *p++ = BUILTIN2 (powl, *q++, *r++);
+
+  /* remainderf128 mentioned previously.  */
+  *p++ = BUILTIN2 (remainderl, *q++, *r++);
+
+  /* { dg-final { scan-assembler {\m__scalbnieee128\M} } }  */
+  *p   = BUILTIN2 (scalbl, *q, *r);  
+}
+
+/* Built-in function that returns a long double and take three long double
+   arguments.  */
+
+void
+return_ld_arg_ld_ld_ld (long double *p,
+			long double *q,
+			long double *r,
+			long double *s)
+{
+  /* inline code.  */
+  /* { dg-final { scan-assembler {\mxsmaddqp\M} } }  */
+  *p = BUILTIN3 (fmal, *q, *r, *s);
+}
+
+/* Built-in functions that returns a long double and take one
+   _Complex long double argument.  */
+
+void
+return_ld_arg_cld (long double *p,
+		   _Complex long double *q)
+{
+  /* { dg-final { scan-assembler {\m__cabsieee128\M} } }  */
+  *p++ = BUILTIN1 (cabsl, *q++);
+
+  /* inline code.  */
+  *p++ = BUILTIN1 (cargl, *q++);
+
+  /* inline code.  */
+  *p++ = BUILTIN1 (cimagl, *q++);
+
+  /* inline code.  */
+  *p   = BUILTIN1 (creall, *q);  
+}
+
+/* Built-in functions that returns a _Complex long double and takes one
+   _Complex long double argument.  */
+
+void
+return_cld_arg_cld (_Complex long double *p,
+		    _Complex long double *q)
+{
+  /* { dg-final { scan-assembler {\m__cacoshieee128\M} } }  */
+  *p++ = BUILTIN1 (cacoshl, *q++);
+
+  /* { dg-final { scan-assembler {\m__cacosieee128\M} } }  */
+  *p++ = BUILTIN1 (cacosl, *q++);
+
+  /* { dg-final { scan-assembler {\m__casinhieee128\M} } }  */
+  *p++ = BUILTIN1 (casinhl, *q++);
+
+  /* { dg-final { scan-assembler {\m__casinieee128\M} } }  */
+  *p++ = BUILTIN1 (casinl, *q++);
+
+  /* { dg-final { scan-assembler {\m__catanhieee128\M} } }  */
+  *p++ = BUILTIN1 (catanhl, *q++);
+
+  /* { dg-final { scan-assembler {\m__catanieee128\M} } }  */
+  *p++ = BUILTIN1 (catanl, *q++);
+
+  /* { dg-final { scan-assembler {\m__ccoshieee128\M} } }  */
+  *p++ = BUILTIN1 (ccoshl, *q++);
+
+  /* { dg-final { scan-assembler {\m__ccosieee128\M} } }  */
+  *p++ = BUILTIN1 (ccosl, *q++);
+
+  /* { dg-final { scan-assembler {\m__cexpieee128\M} } }  */
+  *p++ = BUILTIN1 (cexpl, *q++);
+
+  /* { dg-final { scan-assembler {\m__clogieee128\M} } }  */
+  *p++ = BUILTIN1 (clogl, *q++);
+
+  /* { dg-final { scan-assembler {\m__clog10ieee128\M} } }  */
+  *p++ = BUILTIN1 (clog10l, *q++);
+
+  /* inline code.  */
+  *p++ = BUILTIN1 (conjl, *q++);
+
+  /* { dg-final { scan-assembler {\m__cprojieee128\M} } }  */
+  *p++ = BUILTIN1 (cprojl, *q++);
+
+  /* { dg-final { scan-assembler {\m__csinhieee128\M} } }  */
+  *p++ = BUILTIN1 (csinhl, *q++);
+
+  /* { dg-final { scan-assembler {\m__csinieee128\M} } }  */
+  *p++ = BUILTIN1 (csinl, *q++);
+
+  /* { dg-final { scan-assembler {\m__csqrtieee128\M} } }  */
+  *p++ = BUILTIN1 (csqrtl, *q++);
+
+  /* { dg-final { scan-assembler {\m__ctanhieee128\M} } }  */
+  *p++ = BUILTIN1 (ctanhl, *q++);
+
+  /* { dg-final { scan-assembler {\m__ctanieee128\M} } }  */
+  *p   = BUILTIN1 (ctanl, *q);  
+}
+
+/* Built-in functions that returns a _Complex long double and takes one
+   long double argument.  */
+
+void
+return_cld_arg_ld (_Complex long double *p,
+		   long double *q)
+{
+  /* { dg-final { scan-assembler {\m__sincosieee128\M} } }  */
+  *p = BUILTIN1 (cexpil, *q);
+}
+
+/* Built-in function that returns a _Complex long double and takes two
+   _Complex long double arguments.  */
+
+void
+return_cld_arg_cld_cld (_Complex long double *p,
+			_Complex long double *q,
+			_Complex long double *r)
+{
+  /* { dg-final { scan-assembler {\m__cpowieee128\M} } }  */
+  *p = BUILTIN2 (cpowl, *q, *r);
+}
+
+/* Built-in functions that returns a long double and takes a long double and a
+   pointer to an int arguments.  */
+
+void
+return_ld_arg_ld_pi (long double *p,
+		     long double *q,
+		     int **r)
+{
+  /* { dg-final { scan-assembler {\m__frexpieee128\M} } }  */
+  *p++ = BUILTIN2 (frexpl, *q++, *r++);
+
+  /* { dg-final { scan-assembler {\m__lgammaieee128_r\M} } }  */
+  *p++ = BUILTIN2 (gammal_r, *q++, *r++);
+
+  /* __lgammaieee128_r mentioned previously.  */
+  *p   = BUILTIN2 (lgammal_r, *q, *r);  
+}
+
+/* Built-in functions that returns a long double and takes a long double and an
+   int arguments.  */
+
+void
+return_ld_arg_ld_i (long double *p,
+		    long double *q,
+		    int *r)
+{
+  /* { dg-final { scan-assembler {\m__ldexpieee128\M} } }  */
+  *p++ = BUILTIN2 (ldexpl, *q++, *r++);
+
+  /* { dg-final { scan-assembler {\m__powikf2\M} } }  */
+  *p++ = BUILTIN2 (powil, *q++, *r++);
+
+  /* { dg-final { scan-assembler {\m__scalbnieee128\M} } }  */
+  *p   = BUILTIN2 (scalbnl, *q, *r);  
+}
+
+/* Built-in function that returns a long double and takes a long double and a
+   long arguments.  */
+
+void
+return_ld_arg_ld_l (long double *p,
+		    long double *q,
+		    long *r)
+{
+  /* { dg-final { scan-assembler {\m__scalblnieee128\M} } }  */
+  *p = BUILTIN2 (scalblnl, *q, *r);
+}
+
+/* Built-in functions that returns a long double and takes a long double and a
+   long long arguments.  */
+
+void
+return_ld_arg_i_ld (long double *p,
+		    int *q,
+		    long double *r)
+{
+  /* { dg-final { scan-assembler {\m__jnieee128\M} } }  */
+  *p++ = BUILTIN2 (jnl, *q++, *r++);
+
+  /* { dg-final { scan-assembler {\m__ynieee128\M} } }  */
+  *p   = BUILTIN2 (ynl, *q, *r);  
+}
+
+/* Built-in functions that returns a long double and takes a long double and a
+   pointer to a long double arguments.  */
+
+void
+return_ld_arg_ld_pld (long double *p,
+		      long double *q,
+		      long double **r)
+{
+  /* { dg-final { scan-assembler {\m__modfieee128\M} } }  */
+  *p = BUILTIN2 (modfl, *q, *r);
+}
+
+/* Built-in function that returns a long double and takes two long double and a
+   pointer to an int arguments.  */
+
+void
+return_ld_arg_ld_ld_pi (long double *p,
+			long double *q,
+			long double *r,
+			int **s)
+{
+  /* { dg-final { scan-assembler {\m__remquoieee128\M} } }  */
+  *p = BUILTIN3 (remquol, *q, *r, *s);
+}
+
+/* Built-in functions that returns a long double and take no arguments.  */
+
+void
+return_ld_no_arg (long double *p)
+{
+  /* inline code.  */
+  *p++ = BUILTIN0 (huge_vall);
+
+  /* inline code.  */
+  *p   = BUILTIN0 (infl);     
+}
+
+/* Built-in functions that return san int and takes one long double argument.  */
+
+void
+return_i_arg_ld (int *p,
+		 long double *q)
+{
+  /* { dg-final { scan-assembler {\m__ceilieee128\M} } }  */
+  *p++ = BUILTIN1 (iceill, *q++);
+
+  /* { dg-final { scan-assembler {\m__floorieee128\M} } }  */
+  *p++ = BUILTIN1 (ifloorl, *q++);
+
+  /* { dg-final { scan-assembler {\m__ilogbieee128\M} } }  */
+  *p++ = BUILTIN1 (ilogbl, *q++);
+
+  /* { dg-final { scan-assembler {\m__lrintieee128\M} } }  */
+  *p++ = BUILTIN1 (irintl, *q++);
+
+  /* { dg-final { scan-assembler {\m__lroundieee128\M} } }  */
+  *p++ = BUILTIN1 (iroundl, *q++);
+
+  /* inline code.  */
+  /* { dg-final { scan-assembler {\mxscvqpswz\M} } }  */
+  *p++ = BUILTIN1 (signbitl, *q++);
+
+  /* inline code.  */
+  *p++ = BUILTIN1 (finitel, *q++);
+
+  /* inline code.  */
+  *p++ = BUILTIN1 (isinfl, *q++);
+
+  /* inline code.  */
+  *p   = BUILTIN1 (isnanl, *q);  
+}
+
+/* Built-in functions that returns a long and takes one long double argument.  */
+
+void
+return_l_arg_ld (long *p,
+		 long double *q)
+{
+  /* ceilf128 mentioned previouly.  */
+  *p++ = BUILTIN1 (lceill, *q++);
+
+  /* floorf128 mentioned previously.  */
+  *p++ = BUILTIN1 (lfloorl, *q++);
+
+  /* lrintf128 mentioned previously.  */
+  *p++ = BUILTIN1 (lrintl, *q++);
+
+  /* lroundf128 mentioned previously.  */
+  *p   = BUILTIN1 (lroundl, *q);  
+}
+
+/* Built-in functions that returns a long long and takes one long double
+   argument.  */
+
+void
+return_ll_arg_ld (long long *p,
+		  long double *r)
+{
+  /* ceilf128 mentioned previous.  */
+  *p++ = BUILTIN1 (llceill, *r++);
+
+  /* floorf128 mentioned previously.  */
+  *p++ = BUILTIN1 (llfloorl, *r++);
+
+  /* llrintf128 mentioned previously.  */
+  *p++ = BUILTIN1 (llrintl, *r++);
+
+  /* llroundf128 mentioned previously.  */
+  *p   = BUILTIN1 (llroundl, *r);  
+}
+
+/* Built-in function that returns a double and takes one double and one long
+   double arguments.  */
+
+void
+return_d_arg_d_ld (double *p,
+		   double *q,
+		   long double *r)
+{
+  /* { dg-final { scan-assembler {\m__nexttoward_to_ieee128\M} } }  */
+  *p = BUILTIN2 (nexttoward, *q, *r);
+}
+
+/* Built-in function that returns a float and takes one float and one long
+   double arguments.  */
+
+void
+return_f_arg_f_ld (float *p,
+		   float *q,
+		   long double *r)
+{
+  /* { dg-final { scan-assembler {\m__nexttowardf_to_ieee128\M} } }  */
+  *p = BUILTIN2 (nexttowardf, *q, *r);
+}
+
+/* Built-in function that returns void and takes one long double and two
+   pointers to long double arguments.  */
+
+void
+return_void_arg_ld_pld_pld (long double *p,
+			    long double **q,
+			    long double **r)
+{
+  /* __sincosieee128 mentioned previously.  */
+  BUILTIN3 (sincosl, *p, *q, *r);
+}
+
+/* Debug main program to determine if the library has all of the mapped
+   external functions.  Note, you need a new enough glibc to provide all of the
+   f128 functions.  */
+#ifdef DO_MAIN
+int
+main (void)
+{
+  return 0;
+}
+#endif
diff --git a/gcc/testsuite/gcc.target/powerpc/float128-longdouble-stdio.c b/gcc/testsuite/gcc.target/powerpc/float128-longdouble-stdio.c
new file mode 100644
index 00000000000..77c7b41cec9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/float128-longdouble-stdio.c
@@ -0,0 +1,37 @@
+/* { dg-require-effective-target ppc_float128_hw } */
+/* { dg-require-effective-target power10_ok } */
+/* { dg-options "-mdejagnu-cpu=power9 -mno-pcrel -O2 -Wno-psabi -mabi=ieeelongdouble" } */
+
+/* Test if switching long double to IEEE 128-bit maps the printf and scanf
+   function names correctly.  We explicitly turn off PC-relative support to
+   make it simpler to compare the call without having a @notoc qualifier.  */
+
+#include <stdlib.h>
+
+volatile long double x = 1.0L;
+volatile long double y, z;
+
+int
+main (void)
+{
+  char buffer[100];
+
+  /* { dg-final { scan-assembler {\m__sprintfieee128\M} } }  */
+  __builtin_sprintf (buffer, "%Lg", x);
+
+  /* { dg-final { scan-assembler {\m__printfieee128\M} } }  */
+  __builtin_printf ("x is %Lg [%s]\n", x, buffer);
+
+  /* { dg-final { scan-assembler {\m__isoc99sscanfieee128\M} } }  */
+  __builtin_sscanf (buffer, "%Lg", &y);
+
+  __builtin_printf ("Type 1.0: ");
+
+  /* { dg-final { scan-assembler {\m__isoc99scanfieee128\M} } }  */
+  __builtin_scanf ("%Lg", &z);
+
+  if (x != y || x != z)
+    abort ();
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/float128-math.c b/gcc/testsuite/gcc.target/powerpc/float128-math.c
index 4ad3b5b8363..ea5cb43bcf1 100644
--- a/gcc/testsuite/gcc.target/powerpc/float128-math.c
+++ b/gcc/testsuite/gcc.target/powerpc/float128-math.c
@@ -10,11 +10,11 @@
 
 extern __float128 sinf128 (__float128);
 
-void foo (__float128 *p, long double *q, long double *r)
+void foo (__float128 *p, long double *q)
 {
   *p = sinf128 (*p);
   *q = __builtin_sinl (*q);
 }
 
-/* { dg-final { scan-assembler-times {\mbl sinf128\M} 2 } } */
-/* { dg-final { scan-assembler-not   {\mbl sinl\M}      } } */
+/* { dg-final { scan-assembler     {\mbl __sinieee128\M} } } */
+/* { dg-final { scan-assembler-not {\mbl sinl\M}         } } */
-- 
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] 21+ messages in thread

* Ping: [PATCH 0/9] PowerPC: Patches to enable changing the long double default to IEEE 128-bit on little endian PowerPC 64-bit Linux systems
  2020-09-24 20:20 [PATCH 0/9] PowerPC: Patches to enable changing the long double default to IEEE 128-bit on little endian PowerPC 64-bit Linux systems Michael Meissner
                   ` (9 preceding siblings ...)
  2020-10-09  4:35 ` [PATCH 1/9, revised] PowerPC: Map long double built-in functions if IEEE 128-bit long double Michael Meissner
@ 2020-10-12 23:16 ` Michael Meissner
  2020-10-16 14:37 ` Ping #2: " Michael Meissner
  2020-10-16 19:14 ` Segher Boessenkool
  12 siblings, 0 replies; 21+ messages in thread
From: Michael Meissner @ 2020-10-12 23:16 UTC (permalink / raw)
  To: Michael Meissner, Segher Boessenkool
  Cc: gcc-patches, David Edelsohn, Bill Schmidt, Peter Bergner,
	Jeff Law, Jonathan Wakely

Ping the following 9 patches to add support for building a GCC toolchain where
the default long double is IEEE 128-bit floating point instead of the IBM
extended double floating point.

The first patch was revised with input from Joesph Myers.  I will list that
patch in this list.  Most of these patches are independent of each other, so if
there are problems with some of the patches, please look at the other patches
after that patch:

Patch #1: Map built-in long double functions to an alternate name if long
double is IEEE 128-bit.
https://gcc.gnu.org/pipermail/gcc-patches/2020-October/555855.html

Patch #2: Update error messages about mixing __float128 and __ibm128 to deal
with long double being IEEE 128-bit:
https://gcc.gnu.org/pipermail/gcc-patches/2020-September/554767.html

Patch #3: Rework libgcc 128-bit floating point conversion support:
https://gcc.gnu.org/pipermail/gcc-patches/2020-September/554768.html

Patch #4: Add support in libgcc to convert between IEEE 128-bit and the three
Decimal types:
https://gcc.gnu.org/pipermail/gcc-patches/2020-September/554770.html

Patch #5: Fix some tests that break if long double is IEEE 128-bit:
https://gcc.gnu.org/pipermail/gcc-patches/2020-September/554772.html

Patch #6: Map the 'q' built-ins to 'l' built-ins if long double is IEEE
128-bit:
https://gcc.gnu.org/pipermail/gcc-patches/2020-September/554773.html

Patch #7: Update the power10 built-in functions for IEEE 128-bit support to
support long double if long double is IEEE 128-bit:
https://gcc.gnu.org/pipermail/gcc-patches/2020-September/554774.html

Patch #8: Change tests that use an explicit '__ieee128' keywork to use the
keyword we document ('__float128'):
https://gcc.gnu.org/pipermail/gcc-patches/2020-September/554775.html

Patch #9: If long double is IEEE 128-bit, use the pack_ibm128 built-in instead
of the pack_longdouble built-in in libgcc:
https://gcc.gnu.org/pipermail/gcc-patches/2020-September/554776.html

-- 
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] 21+ messages in thread

* Ping #2: [PATCH 0/9] PowerPC: Patches to enable changing the long double default to IEEE 128-bit on little endian PowerPC 64-bit Linux systems
  2020-09-24 20:20 [PATCH 0/9] PowerPC: Patches to enable changing the long double default to IEEE 128-bit on little endian PowerPC 64-bit Linux systems Michael Meissner
                   ` (10 preceding siblings ...)
  2020-10-12 23:16 ` Ping: [PATCH 0/9] PowerPC: Patches to enable changing the long double default to IEEE 128-bit on little endian PowerPC 64-bit Linux systems Michael Meissner
@ 2020-10-16 14:37 ` Michael Meissner
  2020-10-16 19:14 ` Segher Boessenkool
  12 siblings, 0 replies; 21+ messages in thread
From: Michael Meissner @ 2020-10-16 14:37 UTC (permalink / raw)
  To: Michael Meissner, Segher Boessenkool, Bill Schmidt
  Cc: gcc-patches, David Edelsohn, Peter Bergner, Jeff Law, Jonathan Wakely

Ping (#2) the following 9 patches to add support for building a GCC toolchain
where the default long double is IEEE 128-bit floating point instead of the IBM
extended double floating point.

The first patch was revised with input from Joesph Myers.  I will list that
patch in this list.  Most of these patches are independent of each other, so if
there are problems with some of the patches, please look at the other patches
after that patch:

Patch #1: Map built-in long double functions to an alternate name if long
double is IEEE 128-bit.
https://gcc.gnu.org/pipermail/gcc-patches/2020-October/555855.html

Patch #2: Update error messages about mixing __float128 and __ibm128 to deal
with long double being IEEE 128-bit:
https://gcc.gnu.org/pipermail/gcc-patches/2020-September/554767.html

Patch #3: Rework libgcc 128-bit floating point conversion support:
https://gcc.gnu.org/pipermail/gcc-patches/2020-September/554768.html

Patch #4: Add support in libgcc to convert between IEEE 128-bit and the three
Decimal types:
https://gcc.gnu.org/pipermail/gcc-patches/2020-September/554770.html

Patch #5: Fix some tests that break if long double is IEEE 128-bit:
https://gcc.gnu.org/pipermail/gcc-patches/2020-September/554772.html

Patch #6: Map the 'q' built-ins to 'l' built-ins if long double is IEEE
128-bit:
https://gcc.gnu.org/pipermail/gcc-patches/2020-September/554773.html

Patch #7: Update the power10 built-in functions for IEEE 128-bit support to
support long double if long double is IEEE 128-bit:
https://gcc.gnu.org/pipermail/gcc-patches/2020-September/554774.html

Patch #8: Change tests that use an explicit '__ieee128' keywork to use the
keyword we document ('__float128'):
https://gcc.gnu.org/pipermail/gcc-patches/2020-September/554775.html

Patch #9: If long double is IEEE 128-bit, use the pack_ibm128 built-in instead
of the pack_longdouble built-in in libgcc:
https://gcc.gnu.org/pipermail/gcc-patches/2020-September/554776.html

-- 
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] 21+ messages in thread

* Re: [PATCH 0/9] PowerPC: Patches to enable changing the long double default to IEEE 128-bit on little endian PowerPC 64-bit Linux systems
  2020-09-24 20:20 [PATCH 0/9] PowerPC: Patches to enable changing the long double default to IEEE 128-bit on little endian PowerPC 64-bit Linux systems Michael Meissner
                   ` (11 preceding siblings ...)
  2020-10-16 14:37 ` Ping #2: " Michael Meissner
@ 2020-10-16 19:14 ` Segher Boessenkool
  2020-10-19 19:12   ` Michael Meissner
  12 siblings, 1 reply; 21+ messages in thread
From: Segher Boessenkool @ 2020-10-16 19:14 UTC (permalink / raw)
  To: Michael Meissner, gcc-patches, David Edelsohn, Bill Schmidt,
	Peter Bergner, Jeff Law, Jonathan Wakely

On Thu, Sep 24, 2020 at 04:20:36PM -0400, Michael Meissner wrote:
> This series of 9 patches is an attempt to gather together all of the patches
> that are needed to be able to configure and build a little endian 64-bit
> PowerPC Linux GCC compiler where the defualt long double format uses the IEEE
> 128-bit representation.
> 
> I have created an IBM vendor branch that includes these patches (along the
> other outstanding patches that I have for IEEE 128-bit min/max/cmove on
> power10, and power10 PCREL_OPT support):
> 
> 	vendors/ibm/ieee-longdouble-001
> 
> You will need a new enough GLIBC in order to do this configuration.

What happens if you glibc is older, and you try?


Segher

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

* Re: [PATCH 1/9, revised] PowerPC: Map long double built-in functions if IEEE 128-bit long double.
  2020-10-09  4:35 ` [PATCH 1/9, revised] PowerPC: Map long double built-in functions if IEEE 128-bit long double Michael Meissner
@ 2020-10-16 20:30   ` Segher Boessenkool
  2020-10-19 19:30     ` Michael Meissner
  2020-10-19 21:24     ` Michael Meissner
  0 siblings, 2 replies; 21+ messages in thread
From: Segher Boessenkool @ 2020-10-16 20:30 UTC (permalink / raw)
  To: Michael Meissner, gcc-patches, David Edelsohn, Bill Schmidt,
	Peter Bergner, Jeff Law, Jonathan Wakely

On Fri, Oct 09, 2020 at 12:35:44AM -0400, Michael Meissner wrote:
> This patch is revised from the first version of the patch posted.

In the future, please send a NEW series, in a NEW thread, when you have
a new series.  I was waiting for a new series (because you needed
changes), and I missed that you posted it in the old thread.

If you do not want to because the patches are independent (and not
actually a series), you can send them as independent patches as well
(and that is easier to handle, independent things become much more
obviously independent!)

> Normally the mapping is done in the math.h and stdio.h files.  However, not
> everybody uses these files, which means we also need to change the external
> name for the built-in function within the compiler.

Because those are *not* defined in those headers.  So those headers are
completely irrelevant to this.

> --- a/gcc/config/rs6000/rs6000.c
> +++ b/gcc/config/rs6000/rs6000.c
> @@ -26897,56 +26897,156 @@ rs6000_globalize_decl_name (FILE * stream, tree decl)
>     library before you can switch the real*16 type at compile time.
>  
>     We use the TARGET_MANGLE_DECL_ASSEMBLER_NAME hook to change this name.  We
> -   only do this if the default is that long double is IBM extended double, and
> -   the user asked for IEEE 128-bit.  */
> +   only do this transformation if the __float128 type is enabled.  This
> +   prevents us from doing the transformation on older 32-bit ports that might
> +   have enabled using IEEE 128-bit floating point as the default long double
> +   type.  */

But that is just as broken then?

> +	default:
> +	  break;

Please don't invert the natural order, leave the default at the bottom.
Just like you should not write "0 == x".

> +	case BUILT_IN_NEXTTOWARD:
> +	  newname = "__nexttoward_to_ieee128";
> +	  break;
> +
> +	case BUILT_IN_NEXTTOWARDF:
> +	  newname = "__nexttowardf_to_ieee128";
> +	  break;

Why the "_to_" in those?  How irregular.

> +	case BUILT_IN_SCALBL:
> +	  newname = "__scalbnieee128";
> +	  break;

Should that be __scalbieee128?

> +      /* Update the __builtin_*printf && __builtin_*scanf functions.  */
> +      if (!newname)
> +	{
> +	  const size_t printf_len = sizeof ("printf") - 1;

The "const" here has no function; the compiler *knows* this is a
constant number.

Please use strlen, and no - 1.

> +	  if (len >= printf_len
> +	      && strcmp (name + len - printf_len, "printf") == 0)

Thew first test is unnecessary.

> +	    {
> +	      char *name2 = (char *) alloca (len + 1 + printf_extra);
> +	      strcpy (name2, "__");
> +	      memcpy (name2 + 2, name, len);
> +	      strcpy (name2 + 2 + len, "ieee128");
> +	      newname = (const char *) name2;
> +	    }

Maybe just use asprintf and simplify all of this massively?  It's not
like a malloc here or there will be measurably slower (if it was, you
need to do all of this differently anyway, with some caching etc.)

> +		  /* See if the function passes a IEEE 128-bit floating point type
> +		     or complex type.  */
> +		  FOREACH_FUNCTION_ARGS (type, arg, args_iter)
>  		    {
> -		      uses_ieee128_p = true;
> -		      break;
> +		      machine_mode arg_mode = TYPE_MODE (arg);
> +		      if (arg_mode == TFmode || arg_mode == TCmode)
> +			{
> +			  uses_ieee128_p = true;
> +			  break;
> +			}

I don't see why TFmode would mean it is IEEE?  TFmode can be IBM128 as
well?


Segher

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

* Re: [PATCH 0/9] PowerPC: Patches to enable changing the long double default to IEEE 128-bit on little endian PowerPC 64-bit Linux systems
  2020-10-16 19:14 ` Segher Boessenkool
@ 2020-10-19 19:12   ` Michael Meissner
  2020-10-19 21:50     ` Segher Boessenkool
  0 siblings, 1 reply; 21+ messages in thread
From: Michael Meissner @ 2020-10-19 19:12 UTC (permalink / raw)
  To: Segher Boessenkool
  Cc: Michael Meissner, gcc-patches, David Edelsohn, Bill Schmidt,
	Peter Bergner, Jeff Law, Jonathan Wakely

On Fri, Oct 16, 2020 at 02:14:04PM -0500, Segher Boessenkool wrote:
> On Thu, Sep 24, 2020 at 04:20:36PM -0400, Michael Meissner wrote:
> > This series of 9 patches is an attempt to gather together all of the patches
> > that are needed to be able to configure and build a little endian 64-bit
> > PowerPC Linux GCC compiler where the defualt long double format uses the IEEE
> > 128-bit representation.
> > 
> > I have created an IBM vendor branch that includes these patches (along the
> > other outstanding patches that I have for IEEE 128-bit min/max/cmove on
> > power10, and power10 PCREL_OPT support):
> > 
> > 	vendors/ibm/ieee-longdouble-001
> > 
> > You will need a new enough GLIBC in order to do this configuration.
> 
> What happens if you glibc is older, and you try?

You get linker errors due to the older GLIBC not using -mno-gnu-attribute in
all of the appropriate places, and and not all of the names that are renamed
will be present.

-marlin-> ./xgcc -B./ -O2 -g foo.c -lm -mabi=ieeelongdouble -Wno-psabi && ./a.out
/home3/meissner/fsf-install-ppc64le/binutils-gdb/bin/ld: /opt/at13.0/lib/../lib64/libm.so uses IBM long double, /home/meissner/tmp/gcc-tmp/ccvzdRyj.o uses IEEE long double
/home3/meissner/fsf-install-ppc64le/binutils-gdb/bin/ld: ./libgcc_s.so.1 uses IBM long double, /home/meissner/tmp/gcc-tmp/ccvzdRyj.o uses IEEE long double
/home3/meissner/fsf-install-ppc64le/binutils-gdb/bin/ld: /opt/at13.0/lib/../lib64/libc.so.6 uses IBM long double, /home/meissner/tmp/gcc-tmp/ccvzdRyj.o uses IEEE long double
/home3/meissner/fsf-install-ppc64le/binutils-gdb/bin/ld: ./libgcc_s.so.1 uses IBM long double, /home/meissner/tmp/gcc-tmp/ccvzdRyj.o uses IEEE long double
/home3/meissner/fsf-install-ppc64le/binutils-gdb/bin/ld: /home/meissner/tmp/gcc-tmp/ccvzdRyj.o: in function `main':
/home3/meissner/fsf-build-ppc64le/work020-at13.0/gcc/foo.c:8: undefined reference to `__sinieee128'
/home3/meissner/fsf-install-ppc64le/binutils-gdb/bin/ld: /home3/meissner/fsf-build-ppc64le/work020-at13.0/gcc/foo.c:8: undefined reference to `__printfieee128'
collect2: error: ld returned 1 exit status

-- 
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] 21+ messages in thread

* Re: [PATCH 1/9, revised] PowerPC: Map long double built-in functions if IEEE 128-bit long double.
  2020-10-16 20:30   ` Segher Boessenkool
@ 2020-10-19 19:30     ` Michael Meissner
  2020-10-19 21:24     ` Michael Meissner
  1 sibling, 0 replies; 21+ messages in thread
From: Michael Meissner @ 2020-10-19 19:30 UTC (permalink / raw)
  To: Segher Boessenkool
  Cc: Michael Meissner, gcc-patches, David Edelsohn, Bill Schmidt,
	Peter Bergner, Jeff Law, Jonathan Wakely

On Fri, Oct 16, 2020 at 03:30:56PM -0500, Segher Boessenkool wrote:
> On Fri, Oct 09, 2020 at 12:35:44AM -0400, Michael Meissner wrote:
> > This patch is revised from the first version of the patch posted.
> 
> In the future, please send a NEW series, in a NEW thread, when you have
> a new series.  I was waiting for a new series (because you needed
> changes), and I missed that you posted it in the old thread.
> 
> If you do not want to because the patches are independent (and not
> actually a series), you can send them as independent patches as well
> (and that is easier to handle, independent things become much more
> obviously independent!)

In this case, they are grouped together because various people (Tulio, Jonathan
Wakely) need to know all of the patches that they need to apply to get their
various work (GLIBC, Libstc++, etc.) to work before the patches are installed.

> > Normally the mapping is done in the math.h and stdio.h files.  However, not
> > everybody uses these files, which means we also need to change the external
> > name for the built-in function within the compiler.
> 
> Because those are *not* defined in those headers.  So those headers are
> completely irrelevant to this.

The current glibc stdio.h and math.h takes care of the mapping for the
functions without having the compiler do the mapping.  But not everybody uses
those headers (there are a few test cases for instance that do not include
math.h).

But more importantly, we need the mapping for Fortran to access the right
functions for the math library, since they do not have an equivalent of math.h.

> 
> > --- a/gcc/config/rs6000/rs6000.c
> > +++ b/gcc/config/rs6000/rs6000.c
> > @@ -26897,56 +26897,156 @@ rs6000_globalize_decl_name (FILE * stream, tree decl)
> >     library before you can switch the real*16 type at compile time.
> >  
> >     We use the TARGET_MANGLE_DECL_ASSEMBLER_NAME hook to change this name.  We
> > -   only do this if the default is that long double is IBM extended double, and
> > -   the user asked for IEEE 128-bit.  */
> > +   only do this transformation if the __float128 type is enabled.  This
> > +   prevents us from doing the transformation on older 32-bit ports that might
> > +   have enabled using IEEE 128-bit floating point as the default long double
> > +   type.  */
> 
> But that is just as broken then?

I'm not sure what you mean is broken.  We currently do not provide the float128
emulation functions on any system other than little endian PowerPC.  If
somebody goes through and adds the work, then obviously, we can change the
code.

> 
> > +	default:
> > +	  break;
> 
> Please don't invert the natural order, leave the default at the bottom.
> Just like you should not write "0 == x".

Ok.

> 
> > +	case BUILT_IN_NEXTTOWARD:
> > +	  newname = "__nexttoward_to_ieee128";
> > +	  break;
> > +
> > +	case BUILT_IN_NEXTTOWARDF:
> > +	  newname = "__nexttowardf_to_ieee128";
> > +	  break;
> 
> Why the "_to_" in those?  How irregular.

No idea.  I was just using the names that are in glibc.

> > +	case BUILT_IN_SCALBL:
> > +	  newname = "__scalbnieee128";
> > +	  break;
> 
> Should that be __scalbieee128?

Yes, thanks.

> > +      /* Update the __builtin_*printf && __builtin_*scanf functions.  */
> > +      if (!newname)
> > +	{
> > +	  const size_t printf_len = sizeof ("printf") - 1;
> 
> The "const" here has no function; the compiler *knows* this is a
> constant number.
> 
> Please use strlen, and no - 1.

Ok.

> > +	  if (len >= printf_len
> > +	      && strcmp (name + len - printf_len, "printf") == 0)
> 
> Thew first test is unnecessary.
> 
> > +	    {
> > +	      char *name2 = (char *) alloca (len + 1 + printf_extra);
> > +	      strcpy (name2, "__");
> > +	      memcpy (name2 + 2, name, len);
> > +	      strcpy (name2 + 2 + len, "ieee128");
> > +	      newname = (const char *) name2;
> > +	    }
> 
> Maybe just use asprintf and simplify all of this massively?  It's not
> like a malloc here or there will be measurably slower (if it was, you
> need to do all of this differently anyway, with some caching etc.)

Ok.

> > +		  /* See if the function passes a IEEE 128-bit floating point type
> > +		     or complex type.  */
> > +		  FOREACH_FUNCTION_ARGS (type, arg, args_iter)
> >  		    {
> > -		      uses_ieee128_p = true;
> > -		      break;
> > +		      machine_mode arg_mode = TYPE_MODE (arg);
> > +		      if (arg_mode == TFmode || arg_mode == TCmode)
> > +			{
> > +			  uses_ieee128_p = true;
> > +			  break;
> > +			}
> 
> I don't see why TFmode would mean it is IEEE?  TFmode can be IBM128 as
> well?

The whole section is inside of the test:

  if (TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
      && TREE_CODE (decl) == FUNCTION_DECL
      && fndecl_built_in_p (decl, BUILT_IN_NORMAL))

-- 
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] 21+ messages in thread

* Re: [PATCH 1/9, revised] PowerPC: Map long double built-in functions if IEEE 128-bit long double.
  2020-10-16 20:30   ` Segher Boessenkool
  2020-10-19 19:30     ` Michael Meissner
@ 2020-10-19 21:24     ` Michael Meissner
  1 sibling, 0 replies; 21+ messages in thread
From: Michael Meissner @ 2020-10-19 21:24 UTC (permalink / raw)
  To: Segher Boessenkool
  Cc: Michael Meissner, gcc-patches, David Edelsohn, Bill Schmidt,
	Peter Bergner, Jeff Law, Jonathan Wakely

On Fri, Oct 16, 2020 at 03:30:56PM -0500, Segher Boessenkool wrote:
> > +	  if (len >= printf_len
> > +	      && strcmp (name + len - printf_len, "printf") == 0)
> 
> Thew first test is unnecessary.

Actually no, it is necessary.  If you are looking at a builtin function with 4
or fewer characters, if you don't check if len is at least 5 (i.e. >=
printf_len), the expression:

	name + len - printf_len

would be before the beginning of the name pointer.

-- 
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] 21+ messages in thread

* Re: [PATCH 0/9] PowerPC: Patches to enable changing the long double default to IEEE 128-bit on little endian PowerPC 64-bit Linux systems
  2020-10-19 19:12   ` Michael Meissner
@ 2020-10-19 21:50     ` Segher Boessenkool
  0 siblings, 0 replies; 21+ messages in thread
From: Segher Boessenkool @ 2020-10-19 21:50 UTC (permalink / raw)
  To: Michael Meissner, gcc-patches, David Edelsohn, Bill Schmidt,
	Peter Bergner, Jeff Law, Jonathan Wakely

On Mon, Oct 19, 2020 at 03:12:13PM -0400, Michael Meissner wrote:
> On Fri, Oct 16, 2020 at 02:14:04PM -0500, Segher Boessenkool wrote:
> > On Thu, Sep 24, 2020 at 04:20:36PM -0400, Michael Meissner wrote:
> > > You will need a new enough GLIBC in order to do this configuration.
> > 
> > What happens if you glibc is older, and you try?
> 
> You get linker errors due to the older GLIBC not using -mno-gnu-attribute in
> all of the appropriate places, and and not all of the names that are renamed
> will be present.
> 
> -marlin-> ./xgcc -B./ -O2 -g foo.c -lm -mabi=ieeelongdouble -Wno-psabi && ./a.out
> /home3/meissner/fsf-install-ppc64le/binutils-gdb/bin/ld: /opt/at13.0/lib/../lib64/libm.so uses IBM long double, /home/meissner/tmp/gcc-tmp/ccvzdRyj.o uses IEEE long double
> /home3/meissner/fsf-install-ppc64le/binutils-gdb/bin/ld: ./libgcc_s.so.1 uses IBM long double, /home/meissner/tmp/gcc-tmp/ccvzdRyj.o uses IEEE long double
> /home3/meissner/fsf-install-ppc64le/binutils-gdb/bin/ld: /opt/at13.0/lib/../lib64/libc.so.6 uses IBM long double, /home/meissner/tmp/gcc-tmp/ccvzdRyj.o uses IEEE long double
> /home3/meissner/fsf-install-ppc64le/binutils-gdb/bin/ld: ./libgcc_s.so.1 uses IBM long double, /home/meissner/tmp/gcc-tmp/ccvzdRyj.o uses IEEE long double
> /home3/meissner/fsf-install-ppc64le/binutils-gdb/bin/ld: /home/meissner/tmp/gcc-tmp/ccvzdRyj.o: in function `main':
> /home3/meissner/fsf-build-ppc64le/work020-at13.0/gcc/foo.c:8: undefined reference to `__sinieee128'
> /home3/meissner/fsf-install-ppc64le/binutils-gdb/bin/ld: /home3/meissner/fsf-build-ppc64le/work020-at13.0/gcc/foo.c:8: undefined reference to `__printfieee128'
> collect2: error: ld returned 1 exit status

So this requirement needs to be put in the release notes.  It also is a
regression, but I guess we will just have to live with that :-(


Segher

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

end of thread, other threads:[~2020-10-19 21:51 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-24 20:20 [PATCH 0/9] PowerPC: Patches to enable changing the long double default to IEEE 128-bit on little endian PowerPC 64-bit Linux systems Michael Meissner
2020-09-24 20:31 ` [PATCH 1/9] PowerPC: Map long double built-in functions if IEEE 128-bit long double Michael Meissner
2020-10-01 23:05   ` Joseph Myers
2020-10-08  5:20     ` Michael Meissner
2020-09-24 20:33 ` [PATCH 2/9] PowerPC: Update __float128 and __ibm128 error messages Michael Meissner
2020-09-24 20:34 ` [PATCH 3/9] PowerPC: Update IEEE <-> IBM 128-bit floating point conversions Michael Meissner
2020-09-24 20:35 ` [PATCH 4/9] PowerPC: Add IEEE 128-bit <-> Decimal conversions Michael Meissner
2020-09-24 20:36 ` [PATCH 5/9] PowerPC: Update tests to run if long double is IEEE 128-bit Michael Meissner
2020-09-24 20:40 ` [PATCH 6/9] PowerPC: If long double is IEEE 128-bit, map q built-ins to *l instead of *f128 Michael Meissner
2020-09-24 20:42 ` [PATCH 7/9] PowerPC: Update IEEE 128-bit built-in functions to work if long double is IEEE 128-bit Michael Meissner
2020-09-24 20:45 ` [PATCH 8/9] PowerPC: Change tests to use __float128 instead of __ieee128 Michael Meissner
2020-09-24 20:47 ` [PATCH 9/9] PowerPC: Use __builtin_pack_ieee128 if long double is IEEE 128-bit Michael Meissner
2020-10-09  4:35 ` [PATCH 1/9, revised] PowerPC: Map long double built-in functions if IEEE 128-bit long double Michael Meissner
2020-10-16 20:30   ` Segher Boessenkool
2020-10-19 19:30     ` Michael Meissner
2020-10-19 21:24     ` Michael Meissner
2020-10-12 23:16 ` Ping: [PATCH 0/9] PowerPC: Patches to enable changing the long double default to IEEE 128-bit on little endian PowerPC 64-bit Linux systems Michael Meissner
2020-10-16 14:37 ` Ping #2: " Michael Meissner
2020-10-16 19:14 ` Segher Boessenkool
2020-10-19 19:12   ` Michael Meissner
2020-10-19 21:50     ` Segher Boessenkool

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).