aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Meissner <meissner@linux.vnet.ibm.com>2016-01-21 17:52:33 +0000
committerMichael Meissner <meissner@linux.vnet.ibm.com>2016-01-21 17:52:33 +0000
commit55eb6ed9303b8b1a8d2c7b0e9cdbec8e55557de8 (patch)
tree90eca52bf2db615ce98efa5556f166e841b61aed
parent07fdaa54d646506bb38cdb9d3751c313391fbba0 (diff)
2016-01-21 Michael Meissner <meissner@linux.vnet.ibm.com>
Steven Munroe <munroesj@linux.vnet.ibm.com> Tulio Magno Quites Machado Filho <tulioqm@br.ibm.com> * config/rs6000/float128-sed: New files to convert TF names to KF names for PowerPC IEEE 128-bit floating point support. * config/rs6000/float128-sed-hw: Likewise. * config/rs6000/float128-hw.c: New file for ISA 3.0 IEEE 128-bit floating point hardware support. * config/rs6000/float128-ifunc.c: New file to pick either IEEE 128-bit floating point software emulation or use ISA 3.0 hardware support if it is available. * config/rs6000/quad-float128.h: New file to support IEEE 128-bit floating point. * config/rs6000/extendkftf2-sw.c: New file, convert IEEE 128-bit floating point to IBM extended double. * config/rs6000/trunctfkf2-sw.c: New file, convert IBM extended double to IEEE 128-bit floating point. * config/rs6000/t-float128: New Makefile fragments to enable building __float128 emulation support. * config/rs6000/t-float128-hw: Likewise. * config/rs6000/sfp-exceptions.c: New file to provide exception support for IEEE 128-bit floating point. * config/rs6000/floattikf.c: New files for converting between IEEE 128-bit floating point and signed/unsigned 128-bit integers. * config/rs6000/fixunskfti.c: Likewise. * config/rs6000/fixkfti.c: Likewise. * config/rs6000/floatuntikf.c: Likewise. * config/rs6000/sfp-machine.h (_FP_W_TYPE_SIZE): Use 64-bit types when building on 64-bit systems, or when VSX is enabled. (_FP_W_TYPE): Likewise. (_FP_WS_TYPE): Likewise. (_FP_I_TYPE): Likewise. (TItype): Define on 64-bit systems. (UTItype): Likewise. (TI_BITS): Likewise. (_FP_MUL_MEAT_D): Add support for using 64-bit types. (_FP_MUL_MEAT_Q): Likewise. (_FP_DIV_MEAT_D): Likewise. (_FP_DIV_MEAT_Q): Likewise. (_FP_NANFRAC_D): Likewise. (_FP_NANFRAC_Q): Likewise. (ISA_BIT): Add exception support if we are being compiled on a machine with hardware floating point support to build the IEEE 128-bit emulation functions. (FP_EX_INVALID): Likewise. (FP_EX_OVERFLOW): Likewise. (FP_EX_UNDERFLOW): Likewise. (FP_EX_DIVZERO): Likewise. (FP_EX_INEXACT): Likewise. (FP_EX_ALL): Likewise. (__sfp_handle_exceptions): Likewise. (FP_HANDLE_EXCEPTIONS): Likewise. (FP_RND_NEAREST): Likewise. (FP_RND_ZERO): Likewise. (FP_RND_PINF): Likewise. (FP_RND_MINF): Likewise. (FP_RND_MASK): Likewise. (_FP_DECL_EX): Likewise. (FP_INIT_ROUNDMODE): Likewise. (FP_ROUNDMODE): Likewise. * libgcc/config.host (powerpc*-*-linux*): If compiler can compile VSX code, enable IEEE 128-bit floating point. If the compiler can compile IEEE 128-bit floating point code with ISA 3.0 IEEE 128-bit floating point hardware instructions and it supports declaring functions with the ifunc attribute, enable ifunc functions to switch between software and hardware support. * configure.ac (powerpc*-*-linux*): Likewise. * configure: Regenerate. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@232685 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--libgcc/ChangeLog80
-rw-r--r--libgcc/config.host9
-rw-r--r--libgcc/config/rs6000/extendkftf2-sw.c49
-rw-r--r--libgcc/config/rs6000/fixkfti.c51
-rw-r--r--libgcc/config/rs6000/fixunskfti.c51
-rw-r--r--libgcc/config/rs6000/float128-hw.c207
-rw-r--r--libgcc/config/rs6000/float128-ifunc.c362
-rw-r--r--libgcc/config/rs6000/float128-sed25
-rw-r--r--libgcc/config/rs6000/floattikf.c51
-rw-r--r--libgcc/config/rs6000/floatuntikf.c51
-rw-r--r--libgcc/config/rs6000/quad-float128.h213
-rw-r--r--libgcc/config/rs6000/sfp-exceptions.c72
-rw-r--r--libgcc/config/rs6000/sfp-machine.h94
-rw-r--r--libgcc/config/rs6000/t-float12895
-rw-r--r--libgcc/config/rs6000/t-float128-hw35
-rw-r--r--libgcc/config/rs6000/trunctfkf2-sw.c53
-rw-r--r--libgcc/configure55
-rw-r--r--libgcc/configure.ac31
18 files changed, 1581 insertions, 3 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index 4cd8f01addf..5e4dea4cc37 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,83 @@
+2016-01-21 Michael Meissner <meissner@linux.vnet.ibm.com>
+ Steven Munroe <munroesj@linux.vnet.ibm.com>
+ Tulio Magno Quites Machado Filho <tulioqm@br.ibm.com>
+
+ * config/rs6000/float128-sed: New files to convert TF names to KF
+ names for PowerPC IEEE 128-bit floating point support.
+ * config/rs6000/float128-sed-hw: Likewise.
+
+ * config/rs6000/float128-hw.c: New file for ISA 3.0 IEEE 128-bit
+ floating point hardware support.
+
+ * config/rs6000/float128-ifunc.c: New file to pick either IEEE
+ 128-bit floating point software emulation or use ISA 3.0 hardware
+ support if it is available.
+
+ * config/rs6000/quad-float128.h: New file to support IEEE 128-bit
+ floating point.
+
+ * config/rs6000/extendkftf2-sw.c: New file, convert IEEE 128-bit
+ floating point to IBM extended double.
+
+ * config/rs6000/trunctfkf2-sw.c: New file, convert IBM extended
+ double to IEEE 128-bit floating point.
+
+ * config/rs6000/t-float128: New Makefile fragments to enable
+ building __float128 emulation support.
+ * config/rs6000/t-float128-hw: Likewise.
+
+ * config/rs6000/sfp-exceptions.c: New file to provide exception
+ support for IEEE 128-bit floating point.
+
+ * config/rs6000/floattikf.c: New files for converting between IEEE
+ 128-bit floating point and signed/unsigned 128-bit integers.
+ * config/rs6000/fixunskfti.c: Likewise.
+ * config/rs6000/fixkfti.c: Likewise.
+ * config/rs6000/floatuntikf.c: Likewise.
+
+ * config/rs6000/sfp-machine.h (_FP_W_TYPE_SIZE): Use 64-bit types
+ when building on 64-bit systems, or when VSX is enabled.
+ (_FP_W_TYPE): Likewise.
+ (_FP_WS_TYPE): Likewise.
+ (_FP_I_TYPE): Likewise.
+ (TItype): Define on 64-bit systems.
+ (UTItype): Likewise.
+ (TI_BITS): Likewise.
+ (_FP_MUL_MEAT_D): Add support for using 64-bit types.
+ (_FP_MUL_MEAT_Q): Likewise.
+ (_FP_DIV_MEAT_D): Likewise.
+ (_FP_DIV_MEAT_Q): Likewise.
+ (_FP_NANFRAC_D): Likewise.
+ (_FP_NANFRAC_Q): Likewise.
+ (ISA_BIT): Add exception support if we are being compiled on a
+ machine with hardware floating point support to build the IEEE
+ 128-bit emulation functions.
+ (FP_EX_INVALID): Likewise.
+ (FP_EX_OVERFLOW): Likewise.
+ (FP_EX_UNDERFLOW): Likewise.
+ (FP_EX_DIVZERO): Likewise.
+ (FP_EX_INEXACT): Likewise.
+ (FP_EX_ALL): Likewise.
+ (__sfp_handle_exceptions): Likewise.
+ (FP_HANDLE_EXCEPTIONS): Likewise.
+ (FP_RND_NEAREST): Likewise.
+ (FP_RND_ZERO): Likewise.
+ (FP_RND_PINF): Likewise.
+ (FP_RND_MINF): Likewise.
+ (FP_RND_MASK): Likewise.
+ (_FP_DECL_EX): Likewise.
+ (FP_INIT_ROUNDMODE): Likewise.
+ (FP_ROUNDMODE): Likewise.
+
+ * libgcc/config.host (powerpc*-*-linux*): If compiler can compile
+ VSX code, enable IEEE 128-bit floating point. If the compiler can
+ compile IEEE 128-bit floating point code with ISA 3.0 IEEE 128-bit
+ floating point hardware instructions and it supports declaring
+ functions with the ifunc attribute, enable ifunc functions to
+ switch between software and hardware support.
+ * configure.ac (powerpc*-*-linux*): Likewise.
+ * configure: Regenerate.
+
2016-01-15 Nick Clifton <nickc@redhat.com>
* config/msp430/t-msp430 (lib2_mul_none.o): Only use the first
diff --git a/libgcc/config.host b/libgcc/config.host
index f58ee4555f5..d8efd82d213 100644
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -1063,6 +1063,15 @@ powerpc*-*-linux*)
exit 1
;;
esac
+
+ if test $libgcc_cv_powerpc_float128 = yes; then
+ tmake_file="${tmake_file} rs6000/t-float128"
+ fi
+
+ if test $libgcc_cv_powerpc_float128_hw = yes; then
+ tmake_file="${tmake_file} rs6000/t-float128-hw"
+ fi
+
extra_parts="$extra_parts ecrti.o ecrtn.o ncrti.o ncrtn.o"
md_unwind_header=rs6000/linux-unwind.h
;;
diff --git a/libgcc/config/rs6000/extendkftf2-sw.c b/libgcc/config/rs6000/extendkftf2-sw.c
new file mode 100644
index 00000000000..3be88bf6128
--- /dev/null
+++ b/libgcc/config/rs6000/extendkftf2-sw.c
@@ -0,0 +1,49 @@
+/* Software IEEE 128-bit floating-point emulation for PowerPC.
+
+ Copyright (C) 2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Michael Meissner (meissner@linux.vnet.ibm.com)
+ Code is based on the main soft-fp library written by:
+ Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ 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/>. */
+
+/* Convert IEEE 128-bit floating point to IBM long double. */
+
+#ifdef __FLOAT128_HARDWARE__
+#error "This module must not be compiled with IEEE 128-bit hardware support"
+#endif
+
+#include "soft-fp.h"
+#include "quad-float128.h"
+
+IBM128_TYPE
+__extendkftf2_sw (__float128 value)
+{
+ IBM128_TYPE ret;
+
+ CVT_FLOAT128_TO_IBM128 (ret, value);
+ return ret;
+}
diff --git a/libgcc/config/rs6000/fixkfti.c b/libgcc/config/rs6000/fixkfti.c
new file mode 100644
index 00000000000..80e10f078c0
--- /dev/null
+++ b/libgcc/config/rs6000/fixkfti.c
@@ -0,0 +1,51 @@
+/* Software floating-point emulation, convert IEEE quad to 128bit signed
+ integer.
+
+ Copyright (C) 2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Steven Munroe (munroesj@linux.vnet.ibm.com)
+ Code is based on the main soft-fp library written by:
+ Uros Bizjak (ubizjak@gmail.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/>. */
+
+#ifdef _ARCH_PPC64
+#include "soft-fp.h"
+#include "quad-float128.h"
+
+TItype
+__fixkfti (TFtype a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q (A);
+ UTItype r;
+
+ FP_INIT_EXCEPTIONS;
+ FP_UNPACK_RAW_Q (A, a);
+ FP_TO_INT_Q (r, A, TI_BITS, 1);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
+#endif
diff --git a/libgcc/config/rs6000/fixunskfti.c b/libgcc/config/rs6000/fixunskfti.c
new file mode 100644
index 00000000000..56c36716120
--- /dev/null
+++ b/libgcc/config/rs6000/fixunskfti.c
@@ -0,0 +1,51 @@
+/* Software floating-point emulation, convert IEEE quad to 128bit unsigned
+ integer.
+
+ Copyright (C) 2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Steven Munroe (munroesj@linux.vnet.ibm.com)
+ Code is based on the main soft-fp library written by:
+ Uros Bizjak (ubizjak@gmail.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/>. */
+
+#ifdef _ARCH_PPC64
+#include "soft-fp.h"
+#include "quad-float128.h"
+
+UTItype
+__fixunskfti (TFtype a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q (A);
+ UTItype r;
+
+ FP_INIT_EXCEPTIONS;
+ FP_UNPACK_RAW_Q (A, a);
+ FP_TO_INT_Q (r, A, TI_BITS, 0);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
+#endif
diff --git a/libgcc/config/rs6000/float128-hw.c b/libgcc/config/rs6000/float128-hw.c
new file mode 100644
index 00000000000..43f70f4e7fd
--- /dev/null
+++ b/libgcc/config/rs6000/float128-hw.c
@@ -0,0 +1,207 @@
+/* Automatic switching between software and hardware IEEE 128-bit
+ floating-point emulation for PowerPC.
+
+ Copyright (C) 2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Michael Meissner (meissner@linux.vnet.ibm.com)
+ Code is based on the main soft-fp library written by:
+ Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ 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/>. */
+
+#include <soft-fp.h>
+#include <quad-float128.h>
+
+#ifndef __FLOAT128_HARDWARE__
+#error "This module must be compiled with IEEE 128-bit hardware support"
+#endif
+
+TFtype
+__addkf3_hw (TFtype a, TFtype b)
+{
+ return a + b;
+}
+
+TFtype
+__subkf3_hw (TFtype a, TFtype b)
+{
+ return a - b;
+}
+
+TFtype
+__mulkf3_hw (TFtype a, TFtype b)
+{
+ return a * b;
+}
+
+TFtype
+__divkf3_hw (TFtype a, TFtype b)
+{
+ return a / b;
+}
+
+TFtype
+__negkf2_hw (TFtype a)
+{
+ return -a;
+}
+
+TFtype
+__floatsikf_hw (SItype_ppc a)
+{
+ return (TFtype) a;
+}
+
+TFtype
+__floatunsikf_hw (USItype_ppc a)
+{
+ return (TFtype) a;
+}
+
+TFtype
+__floatdikf_hw (DItype_ppc a)
+{
+ return (TFtype) a;
+}
+
+TFtype
+__floatundikf_hw (UDItype_ppc a)
+{
+ return (TFtype) a;
+}
+
+SItype_ppc
+__fixkfsi_hw (TFtype a)
+{
+ return (SItype_ppc) a;
+}
+
+USItype_ppc
+__fixunskfsi_hw (TFtype a)
+{
+ return (USItype_ppc) a;
+}
+
+DItype_ppc
+__fixkfdi_hw (TFtype a)
+{
+ return (DItype_ppc) a;
+}
+
+UDItype_ppc
+__fixunskfdi_hw (TFtype a)
+{
+ return (UDItype_ppc) a;
+}
+
+TFtype
+__extendsfkf2_hw (float a)
+{
+ return (TFtype) a;
+}
+
+TFtype
+__extenddfkf2_hw (double a)
+{
+ return (TFtype) a;
+}
+
+float
+__trunckfsf2_hw (TFtype a)
+{
+ return (float) a;
+}
+
+double
+__trunckfdf2_hw (TFtype a)
+{
+ return (double) a;
+}
+
+/* __eqkf2 returns 0 if equal, or 1 if not equal or NaN. */
+CMPtype
+__eqkf2_hw (TFtype a, TFtype b)
+{
+ return (a != b);
+}
+
+/* __gekf2 returns -1 if a < b, 0 if a == b, +1 if a > b, or -2 if NaN. */
+CMPtype
+__gekf2_hw (TFtype a, TFtype b)
+{
+ if (a < b)
+ return -1;
+
+ else if (__builtin_isunordered (a, b))
+ return -2;
+
+ else if (a == b)
+ return 0;
+
+ return 1;
+}
+
+/* __lekf2 returns -1 if a < b, 0 if a == b, +1 if a > b, or +2 if NaN. */
+CMPtype
+__lekf2_hw (TFtype a, TFtype b)
+{
+ if (a < b)
+ return -1;
+
+ else if (__builtin_isunordered (a, b))
+ return 2;
+
+ else if (a == b)
+ return 0;
+
+ return 1;
+}
+
+/* __unordkf2 returns 1 if NaN or 0 otherwise. */
+CMPtype
+__unordkf2_hw (TFtype a, TFtype b)
+{
+ return (__builtin_isunordered (a, b)) ? 1 : 0;
+}
+
+/* Convert __float128 to __ibm128. */
+IBM128_TYPE
+__extendkftf2_hw (TFtype value)
+{
+ IBM128_TYPE ret;
+
+ CVT_FLOAT128_TO_IBM128 (ret, value);
+ return ret;
+}
+
+/* Convert __ibm128 to __float128. */
+TFtype
+__trunctfkf2_hw (IBM128_TYPE value)
+{
+ TFtype ret;
+
+ CVT_IBM128_TO_FLOAT128 (ret, value);
+ return ret;
+}
diff --git a/libgcc/config/rs6000/float128-ifunc.c b/libgcc/config/rs6000/float128-ifunc.c
new file mode 100644
index 00000000000..d21010557d4
--- /dev/null
+++ b/libgcc/config/rs6000/float128-ifunc.c
@@ -0,0 +1,362 @@
+/* Automatic switching between software and hardware IEEE 128-bit
+ floating-point emulation for PowerPC.
+
+ Copyright (C) 2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Michael Meissner (meissner@linux.vnet.ibm.com)
+ Code is based on the main soft-fp library written by:
+ Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ 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/>. */
+
+#include <soft-fp.h>
+#include <quad-float128.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#ifndef FLOAT128_HW_INSNS
+#error "float128-ifunc.c needs access to ISA 3.0 instructions and ifunc"
+#endif
+
+#ifdef __FLOAT128_HARDWARE__
+#error "This module must not be compiled with IEEE 128-bit hardware support"
+#endif
+
+#include <sys/auxv.h>
+
+/* Use the namespace clean version of getauxval. However, not all versions of
+ sys/auxv.h declare it, so declare it here. This code is intended to be
+ temporary until a suitable version of __builtin_cpu_supports is added that
+ allows us to tell quickly if the machine supports IEEE 128-bit hardware. */
+extern unsigned long __getauxval (unsigned long);
+
+static int
+have_ieee_hw_p (void)
+{
+ static int ieee_hw_p = -1;
+
+ if (ieee_hw_p < 0)
+ {
+ char *p = (char *) __getauxval (AT_PLATFORM);
+
+ ieee_hw_p = 0;
+
+ /* Don't use atoi/strtol/strncmp/etc. These may require the normal
+ environment to be setup to set errno to 0, and the ifunc resolvers run
+ before the whole glibc environment is initialized. */
+ if (p && p[0] == 'p' && p[1] == 'o' && p[2] == 'w' && p[3] == 'e'
+ && p[4] == 'r')
+ {
+ long n = 0;
+ char ch;
+
+ p += 5;
+ while ((ch = *p++) >= '0' && (ch <= '9'))
+ n = (n * 10) + (ch - '0');
+
+ if (n >= 9)
+ ieee_hw_p = 1;
+ }
+ }
+
+ return ieee_hw_p;
+}
+
+#define SW_OR_HW(SW, HW) (have_ieee_hw_p () ? HW : SW)
+
+/* Resolvers. */
+
+/* We do not provide ifunc resolvers for __fixkfti, __fixunskfti, __floattikf,
+ and __floatuntikf. There is no ISA 3.0 instruction that converts between
+ 128-bit integer types and 128-bit IEEE floating point, or vice versa. So
+ use the emulator functions for these conversions. */
+
+static void *__addkf3_resolve (void);
+static void *__subkf3_resolve (void);
+static void *__mulkf3_resolve (void);
+static void *__divkf3_resolve (void);
+static void *__negkf2_resolve (void);
+static void *__eqkf2_resolve (void);
+static void *__nekf2_resolve (void);
+static void *__gekf2_resolve (void);
+static void *__gtkf2_resolve (void);
+static void *__lekf2_resolve (void);
+static void *__ltkf2_resolve (void);
+static void *__unordkf2_resolve (void);
+static void *__extendsfkf2_resolve (void);
+static void *__extenddfkf2_resolve (void);
+static void *__trunckfsf2_resolve (void);
+static void *__trunckfdf2_resolve (void);
+static void *__fixkfsi_resolve (void);
+static void *__fixkfdi_resolve (void);
+static void *__fixunskfsi_resolve (void);
+static void *__fixunskfdi_resolve (void);
+static void *__floatsikf_resolve (void);
+static void *__floatdikf_resolve (void);
+static void *__floatunsikf_resolve (void);
+static void *__floatundikf_resolve (void);
+static void *__extendkftf2_resolve (void);
+static void *__trunctfkf2_resolve (void);
+
+static void *
+__addkf3_resolve (void)
+{
+ return (void *) SW_OR_HW (__addkf3_sw, __addkf3_hw);
+}
+
+static void *
+__subkf3_resolve (void)
+{
+ return (void *) SW_OR_HW (__subkf3_sw, __subkf3_hw);
+}
+
+static void *
+__mulkf3_resolve (void)
+{
+ return (void *) SW_OR_HW (__mulkf3_sw, __mulkf3_hw);
+}
+
+static void *
+__divkf3_resolve (void)
+{
+ return (void *) SW_OR_HW (__divkf3_sw, __divkf3_hw);
+}
+
+static void *
+__negkf2_resolve (void)
+{
+ return (void *) SW_OR_HW (__negkf2_sw, __negkf2_hw);
+}
+
+static void *
+__floatsikf_resolve (void)
+{
+ return (void *) SW_OR_HW (__floatsikf_sw, __floatsikf_hw);
+}
+
+static void *
+__floatdikf_resolve (void)
+{
+ return (void *) SW_OR_HW (__floatdikf_sw, __floatdikf_hw);
+}
+
+static void *
+__floatunsikf_resolve (void)
+{
+ return (void *) SW_OR_HW (__floatunsikf_sw, __floatunsikf_hw);
+}
+
+static void *
+__floatundikf_resolve (void)
+{
+ return (void *) SW_OR_HW (__floatundikf_sw, __floatundikf_hw);
+}
+
+static void *
+__fixkfsi_resolve (void)
+{
+ return (void *) SW_OR_HW (__fixkfsi_sw, __fixkfsi_hw);
+}
+
+static void *
+__fixkfdi_resolve (void)
+{
+ return (void *) SW_OR_HW (__fixkfdi_sw, __fixkfdi_hw);
+}
+
+static void *
+__fixunskfsi_resolve (void)
+{
+ return (void *) SW_OR_HW (__fixunskfsi_sw, __fixunskfsi_hw);
+}
+
+static void *
+__fixunskfdi_resolve (void)
+{
+ return (void *) SW_OR_HW (__fixunskfdi_sw, __fixunskfdi_hw);
+}
+
+static void *
+__extendsfkf2_resolve (void)
+{
+ return (void *) SW_OR_HW (__extendsfkf2_sw, __extendsfkf2_hw);
+}
+
+static void *
+__extenddfkf2_resolve (void)
+{
+ return (void *) SW_OR_HW (__extenddfkf2_sw, __extenddfkf2_hw);
+}
+
+static void *
+__trunckfsf2_resolve (void)
+{
+ return (void *) SW_OR_HW (__trunckfsf2_sw, __trunckfsf2_hw);
+}
+
+static void *
+__trunckfdf2_resolve (void)
+{
+ return (void *) SW_OR_HW (__trunckfdf2_sw, __trunckfdf2_hw);
+}
+
+static void *
+__extendkftf2_resolve (void)
+{
+ return (void *) SW_OR_HW (__extendkftf2_sw, __extendkftf2_hw);
+}
+
+static void *
+__trunctfkf2_resolve (void)
+{
+ return (void *) SW_OR_HW (__trunctfkf2_sw, __trunctfkf2_hw);
+}
+
+static void *
+__eqkf2_resolve (void)
+{
+ return (void *) SW_OR_HW (__eqkf2_sw, __eqkf2_hw);
+}
+
+static void *
+__gekf2_resolve (void)
+{
+ return (void *) SW_OR_HW (__gekf2_sw, __gekf2_hw);
+}
+
+static void *
+__lekf2_resolve (void)
+{
+ return (void *) SW_OR_HW (__lekf2_sw, __lekf2_hw);
+}
+
+static void *
+__unordkf2_resolve (void)
+{
+ return (void *) SW_OR_HW (__unordkf2_sw, __unordkf2_hw);
+}
+
+/* Resolve __nekf2, __gtkf2, __ltkf2 like __eqkf2, __gekf2, and __lekf2, since
+ the functions return the same values. */
+
+static void *
+__nekf2_resolve (void)
+{
+ return (void *) SW_OR_HW (__eqkf2_sw, __eqkf2_hw);
+}
+
+static void *
+__gtkf2_resolve (void)
+{
+ return (void *) SW_OR_HW (__gekf2_sw, __gekf2_hw);
+}
+
+static void *
+__ltkf2_resolve (void)
+{
+ return (void *) SW_OR_HW (__lekf2_sw, __lekf2_hw);
+}
+
+
+
+/* Ifunc definitions. */
+TFtype __addkf3 (TFtype, TFtype)
+ __attribute__ ((__ifunc__ ("__addkf3_resolve")));
+
+TFtype __subkf3 (TFtype, TFtype)
+ __attribute__ ((__ifunc__ ("__subkf3_resolve")));
+
+TFtype __mulkf3 (TFtype, TFtype)
+ __attribute__ ((__ifunc__ ("__mulkf3_resolve")));
+
+TFtype __divkf3 (TFtype, TFtype)
+ __attribute__ ((__ifunc__ ("__divkf3_resolve")));
+
+TFtype __negkf2 (TFtype)
+ __attribute__ ((__ifunc__ ("__negkf2_resolve")));
+
+CMPtype __eqkf2 (TFtype, TFtype)
+ __attribute__ ((__ifunc__ ("__eqkf2_resolve")));
+
+CMPtype __nekf2 (TFtype, TFtype)
+ __attribute__ ((__ifunc__ ("__nekf2_resolve")));
+
+CMPtype __gekf2 (TFtype, TFtype)
+ __attribute__ ((__ifunc__ ("__gekf2_resolve")));
+
+CMPtype __gtkf2 (TFtype, TFtype)
+ __attribute__ ((__ifunc__ ("__gtkf2_resolve")));
+
+CMPtype __lekf2 (TFtype, TFtype)
+ __attribute__ ((__ifunc__ ("__lekf2_resolve")));
+
+CMPtype __ltkf2 (TFtype, TFtype)
+ __attribute__ ((__ifunc__ ("__ltkf2_resolve")));
+
+CMPtype __unordkf2 (TFtype, TFtype)
+ __attribute__ ((__ifunc__ ("__unordkf2_resolve")));
+
+TFtype __extendsfkf2 (float)
+ __attribute__ ((__ifunc__ ("__extendsfkf2_resolve")));
+
+TFtype __extenddfkf2 (double)
+ __attribute__ ((__ifunc__ ("__extenddfkf2_resolve")));
+
+float __trunckfsf2 (TFtype)
+ __attribute__ ((__ifunc__ ("__trunckfsf2_resolve")));
+
+double __trunckfdf2 (TFtype)
+ __attribute__ ((__ifunc__ ("__trunckfdf2_resolve")));
+
+SItype_ppc __fixkfsi (TFtype)
+ __attribute__ ((__ifunc__ ("__fixkfsi_resolve")));
+
+DItype_ppc __fixkfdi (TFtype)
+ __attribute__ ((__ifunc__ ("__fixkfdi_resolve")));
+
+USItype_ppc __fixunskfsi (TFtype)
+ __attribute__ ((__ifunc__ ("__fixunskfsi_resolve")));
+
+UDItype_ppc __fixunskfdi (TFtype)
+ __attribute__ ((__ifunc__ ("__fixunskfdi_resolve")));
+
+TFtype __floatsikf (SItype_ppc)
+ __attribute__ ((__ifunc__ ("__floatsikf_resolve")));
+
+TFtype __floatdikf (DItype_ppc)
+ __attribute__ ((__ifunc__ ("__floatdikf_resolve")));
+
+TFtype __floatunsikf (USItype_ppc)
+ __attribute__ ((__ifunc__ ("__floatunsikf_resolve")));
+
+TFtype __floatundikf (UDItype_ppc)
+ __attribute__ ((__ifunc__ ("__floatundikf_resolve")));
+
+IBM128_TYPE __extendkftf2 (TFtype)
+ __attribute__ ((__ifunc__ ("__extendkftf2_resolve")));
+
+TFtype __trunctfkf2 (IBM128_TYPE)
+ __attribute__ ((__ifunc__ ("__trunctfkf2_resolve")));
diff --git a/libgcc/config/rs6000/float128-sed b/libgcc/config/rs6000/float128-sed
new file mode 100644
index 00000000000..d9a089ff9ba
--- /dev/null
+++ b/libgcc/config/rs6000/float128-sed
@@ -0,0 +1,25 @@
+s/__addtf3/__addkf3/g
+s/__divtf3/__divkf3/g
+s/__eqtf2/__eqkf2/g
+s/__extenddftf2/__extenddfkf2/g
+s/__extendsftf2/__extendsfkf2/g
+s/__fixtfdi/__fixkfdi/g
+s/__fixtfsi/__fixkfsi/g
+s/__fixunstfdi/__fixunskfdi/g
+s/__fixunstfsi/__fixunskfsi/g
+s/__floatditf/__floatdikf/g
+s/__floatsitf/__floatsikf/g
+s/__floatunditf/__floatundikf/g
+s/__floatunsitf/__floatunsikf/g
+s/__getf2/__gekf2/g
+s/__gttf2/__gtkf2/g
+s/__letf2/__lekf2/g
+s/__lttf2/__ltkf2/g
+s/__multf3/__mulkf3/g
+s/__negtf2/__negkf2/g
+s/__netf2/__nekf2/g
+s/quad[.]h/quad-float128.h/g
+s/__subtf3/__subkf3/g
+s/__trunctfdf2/__trunckfdf2/g
+s/__trunctfsf2/__trunckfsf2/g
+s/__unordtf2/__unordkf2/g
diff --git a/libgcc/config/rs6000/floattikf.c b/libgcc/config/rs6000/floattikf.c
new file mode 100644
index 00000000000..4c652308158
--- /dev/null
+++ b/libgcc/config/rs6000/floattikf.c
@@ -0,0 +1,51 @@
+/* Software floating-point emulation, convert a 128bit signed integer to IEEE
+ quad.
+
+ Copyright (C) 2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Steven Munroe (munroesj@linux.vnet.ibm.com)
+ Code is based on the main soft-fp library written by:
+ Uros Bizjak (ubizjak@gmail.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/>. */
+
+#ifdef _ARCH_PPC64
+#include "soft-fp.h"
+#include "quad-float128.h"
+
+TFtype
+__floattikf (TItype i)
+{
+ FP_DECL_EX;
+ FP_DECL_Q (A);
+ TFtype a;
+
+ FP_INIT_ROUNDMODE;
+ FP_FROM_INT_Q (A, i, TI_BITS, UTItype);
+ FP_PACK_RAW_Q (a, A);
+ FP_HANDLE_EXCEPTIONS;
+
+ return a;
+}
+#endif
diff --git a/libgcc/config/rs6000/floatuntikf.c b/libgcc/config/rs6000/floatuntikf.c
new file mode 100644
index 00000000000..6dabf7b33bd
--- /dev/null
+++ b/libgcc/config/rs6000/floatuntikf.c
@@ -0,0 +1,51 @@
+/* Software floating-point emulation, convert a 128bit unsigned integer to IEEE
+ quad.
+
+ Copyright (C) 2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Steven Munroe (munroesj@linux.vnet.ibm.com)
+ Code is based on the main soft-fp library written by:
+ Uros Bizjak (ubizjak@gmail.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/>. */
+
+#ifdef _ARCH_PPC64
+#include "soft-fp.h"
+#include "quad-float128.h"
+
+TFtype
+__floatuntikf (UTItype i)
+{
+ FP_DECL_EX;
+ FP_DECL_Q (A);
+ TFtype a;
+
+ FP_INIT_ROUNDMODE;
+ FP_FROM_INT_Q (A, i, TI_BITS, UTItype);
+ FP_PACK_RAW_Q (a, A);
+ FP_HANDLE_EXCEPTIONS;
+
+ return a;
+}
+#endif
diff --git a/libgcc/config/rs6000/quad-float128.h b/libgcc/config/rs6000/quad-float128.h
new file mode 100644
index 00000000000..62d198db20d
--- /dev/null
+++ b/libgcc/config/rs6000/quad-float128.h
@@ -0,0 +1,213 @@
+/* Software floating-point emulation.
+ Definitions for IEEE Quad Precision on the PowerPC.
+ Copyright (C) 2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Michael Meissner (meissner@linux.vnet.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/>. */
+
+/* quad.h defines the TFtype type by:
+ typedef float TFtype __attribute__ ((mode (TF)));
+
+ This define forces it to use KFmode (aka, ieee 128-bit floating point). */
+#define TF KF
+
+/* Force the use of the VSX instruction set. */
+#if defined(_ARCH_PPC) && (!defined(__VSX__) || !defined(__FLOAT128__))
+#pragma GCC target ("vsx,float128")
+#endif
+
+#include <quad.h>
+
+#ifdef __LONG_DOUBLE_IEEE128__
+#define IBM128_TYPE __ibm128
+
+#else
+#define IBM128_TYPE long double
+#endif
+
+/* Add prototypes of the library functions created. In case the appropriate
+ int/long types are not declared in scope by the time quad.h is included,
+ provide our own version. */
+typedef int SItype_ppc __attribute__ ((__mode__ (__SI__)));
+typedef int DItype_ppc __attribute__ ((__mode__ (__DI__)));
+typedef unsigned USItype_ppc __attribute__ ((__mode__ (__SI__)));
+typedef unsigned UDItype_ppc __attribute__ ((__mode__ (__DI__)));
+
+#ifdef _ARCH_PPC64
+typedef int TItype_ppc __attribute__ ((__mode__ (__TI__)));
+typedef unsigned UTItype_ppc __attribute__ ((__mode__ (__TI__)));
+#endif
+
+/* Software emulation functions. */
+extern TFtype __addkf3_sw (TFtype, TFtype);
+extern TFtype __subkf3_sw (TFtype, TFtype);
+extern TFtype __mulkf3_sw (TFtype, TFtype);
+extern TFtype __divkf3_sw (TFtype, TFtype);
+extern TFtype __negkf2_sw (TFtype);
+extern CMPtype __eqkf2_sw (TFtype, TFtype);
+extern CMPtype __gekf2_sw (TFtype, TFtype);
+extern CMPtype __lekf2_sw (TFtype, TFtype);
+extern CMPtype __unordkf2_sw (TFtype, TFtype);
+extern TFtype __extendsfkf2_sw (float);
+extern TFtype __extenddfkf2_sw (double);
+extern float __trunckfsf2_sw (TFtype);
+extern double __trunckfdf2_sw (TFtype);
+extern SItype_ppc __fixkfsi_sw (TFtype);
+extern DItype_ppc __fixkfdi_sw (TFtype);
+extern USItype_ppc __fixunskfsi_sw (TFtype);
+extern UDItype_ppc __fixunskfdi_sw (TFtype);
+extern TFtype __floatsikf_sw (SItype_ppc);
+extern TFtype __floatdikf_sw (DItype_ppc);
+extern TFtype __floatunsikf_sw (USItype_ppc);
+extern TFtype __floatundikf_sw (UDItype_ppc);
+extern IBM128_TYPE __extendkftf2_sw (TFtype);
+extern TFtype __trunctfkf2_sw (IBM128_TYPE);
+
+#ifdef _ARCH_PPC64
+/* We do not provide ifunc resolvers for __fixkfti, __fixunskfti, __floattikf,
+ and __floatuntikf. There is no ISA 3.0 instruction that converts between
+ 128-bit integer types and 128-bit IEEE floating point, or vice versa. So
+ use the emulator functions for these conversions. */
+
+extern TItype_ppc __fixkfti (TFtype);
+extern UTItype_ppc __fixunskfti (TFtype);
+extern TFtype __floattikf (TItype_ppc);
+extern TFtype __floatuntikf (UTItype_ppc);
+#endif
+
+/* Functions using the ISA 3.0 hardware support. If the code is compiled with
+ -mcpu=power9, it will not use these functions, but if it was compiled with
+ -mcpu=power7 or -mcpu=power8 and run on a ISA 3.0 system, it will use the
+ hardware instruction. */
+extern TFtype __addkf3_hw (TFtype, TFtype);
+extern TFtype __subkf3_hw (TFtype, TFtype);
+extern TFtype __mulkf3_hw (TFtype, TFtype);
+extern TFtype __divkf3_hw (TFtype, TFtype);
+extern TFtype __negkf2_hw (TFtype);
+extern CMPtype __eqkf2_hw (TFtype, TFtype);
+extern CMPtype __gekf2_hw (TFtype, TFtype);
+extern CMPtype __lekf2_hw (TFtype, TFtype);
+extern CMPtype __unordkf2_hw (TFtype, TFtype);
+extern TFtype __extendsfkf2_hw (float);
+extern TFtype __extenddfkf2_hw (double);
+extern float __trunckfsf2_hw (TFtype);
+extern double __trunckfdf2_hw (TFtype);
+extern SItype_ppc __fixkfsi_hw (TFtype);
+extern DItype_ppc __fixkfdi_hw (TFtype);
+extern USItype_ppc __fixunskfsi_hw (TFtype);
+extern UDItype_ppc __fixunskfdi_hw (TFtype);
+extern TFtype __floatsikf_hw (SItype_ppc);
+extern TFtype __floatdikf_hw (DItype_ppc);
+extern TFtype __floatunsikf_hw (USItype_ppc);
+extern TFtype __floatundikf_hw (UDItype_ppc);
+extern IBM128_TYPE __extendkftf2_hw (TFtype);
+extern TFtype __trunctfkf2_hw (IBM128_TYPE);
+
+/* Ifunc function declarations, to automatically switch between software
+ emulation and hardware support. */
+extern TFtype __addkf3 (TFtype, TFtype);
+extern TFtype __subkf3 (TFtype, TFtype);
+extern TFtype __mulkf3 (TFtype, TFtype);
+extern TFtype __divkf3 (TFtype, TFtype);
+extern TFtype __negkf2 (TFtype);
+extern CMPtype __eqkf2 (TFtype, TFtype);
+extern CMPtype __nekf2 (TFtype, TFtype);
+extern CMPtype __gekf2 (TFtype, TFtype);
+extern CMPtype __gtkf2 (TFtype, TFtype);
+extern CMPtype __lekf2 (TFtype, TFtype);
+extern CMPtype __ltkf2 (TFtype, TFtype);
+extern CMPtype __unordkf2 (TFtype, TFtype);
+extern TFtype __extendsfkf2 (float);
+extern TFtype __extenddfkf2 (double);
+extern float __trunckfsf2 (TFtype);
+extern double __trunckfdf2 (TFtype);
+extern SItype_ppc __fixkfsi (TFtype);
+extern DItype_ppc __fixkfdi (TFtype);
+extern USItype_ppc __fixunskfsi (TFtype);
+extern UDItype_ppc __fixunskfdi (TFtype);
+extern TFtype __floatsikf (SItype_ppc);
+extern TFtype __floatdikf (DItype_ppc);
+extern TFtype __floatunsikf (USItype_ppc);
+extern TFtype __floatundikf (UDItype_ppc);
+extern IBM128_TYPE __extendkftf2 (TFtype);
+extern TFtype __trunctfkf2 (IBM128_TYPE);
+
+/* 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; \
+ __float128 __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 - (__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; \
+ } \
+ \
+ 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 = (__float128) __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 = (__float128) __high; \
+ \
+ else \
+ RESULT = ((__float128) __high) + ((__float128) __low); \
+}
diff --git a/libgcc/config/rs6000/sfp-exceptions.c b/libgcc/config/rs6000/sfp-exceptions.c
new file mode 100644
index 00000000000..efd21da5320
--- /dev/null
+++ b/libgcc/config/rs6000/sfp-exceptions.c
@@ -0,0 +1,72 @@
+/* Copyright (C) 2016 Free Software Foundation, Inc.
+
+ This file 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.
+
+ This file 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/>. */
+
+#include "sfp-machine.h"
+
+/* Only provide exception support if we have hardware floating point and we can
+ execute the mtfsf instruction. This would only be true if we are using the
+ emulation routines for IEEE 128-bit floating point on pre-ISA 3.0 machines
+ without the IEEE 128-bit floating point support. */
+
+#ifndef __NO_FPRS__
+
+void
+__sfp_handle_exceptions (int _fex)
+{
+ const double fp_max = __DBL_MAX__;
+ const double fp_min = __DBL_MIN__;
+ const double fp_zero = (double) 0.0;
+ const double fp_one = 1.0;
+ double tmp;
+
+ if (_fex & FP_EX_INVALID)
+ {
+ __asm__ __volatile__ ("fdiv %0, %1, %1"
+ : "=f" (tmp)
+ : "f" (fp_zero));
+ }
+ if (_fex & FP_EX_DIVZERO)
+ {
+ __asm__ __volatile__ ("fdiv %0, %1, %2"
+ : "=f" (tmp)
+ : "f" (fp_one), "f" (fp_zero));
+ }
+ if (_fex & FP_EX_OVERFLOW)
+ {
+ __asm__ __volatile__ ("fadd %0, %1, %1"
+ : "=f" (tmp)
+ : "f" (fp_max));
+ }
+ if (_fex & FP_EX_UNDERFLOW)
+ {
+ __asm__ __volatile__ ("fmul %0, %1, %1"
+ : "=f" (tmp)
+ : "f" (fp_min));
+ }
+ if (_fex & FP_EX_INEXACT)
+ {
+ __asm__ __volatile__ ("fsub %0, %1, %2"
+ : "=f" (tmp)
+ : "f" (fp_max), "f" (fp_one));
+ }
+}
+
+#endif /* !__NO_FPRS__ */
diff --git a/libgcc/config/rs6000/sfp-machine.h b/libgcc/config/rs6000/sfp-machine.h
index 40436337ffb..91f82ae1f09 100644
--- a/libgcc/config/rs6000/sfp-machine.h
+++ b/libgcc/config/rs6000/sfp-machine.h
@@ -1,7 +1,26 @@
+/* Decide whether to use 64 or 32-bit types to do the emulation. If we are
+ doing IEEE-128 with VSX, use 64-bit emulation even if we are compiling for a
+ 32-bit target. */
+
+#if defined(_ARCH_PPC64) || defined(__VSX__) || defined(__FLOAT128__)
+#define _FP_W_TYPE_SIZE 64
+#define _FP_W_TYPE unsigned long long
+#define _FP_WS_TYPE signed long long
+#define _FP_I_TYPE long long
+
+#ifdef _ARCH_PPC64
+typedef int TItype __attribute__ ((mode (TI)));
+typedef unsigned int UTItype __attribute__ ((mode (TI)));
+
+#define TI_BITS (__CHAR_BIT__ * (int)sizeof(TItype))
+#endif
+
+#else /* 32-bits */
#define _FP_W_TYPE_SIZE 32
-#define _FP_W_TYPE unsigned long
-#define _FP_WS_TYPE signed long
-#define _FP_I_TYPE long
+#define _FP_W_TYPE unsigned int
+#define _FP_WS_TYPE signed int
+#define _FP_I_TYPE int
+#endif /* 32-bits */
/* The type of the result of a floating point comparison. This must
match `__libgcc_cmp_return__' in GCC for the target. */
@@ -10,18 +29,39 @@ typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
#define _FP_MUL_MEAT_S(R,X,Y) \
_FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
+
+#if (_FP_W_TYPE_SIZE==64)
+#define _FP_MUL_MEAT_D(R,X,Y) \
+ _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_Q(R,X,Y) \
+ _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+#else
#define _FP_MUL_MEAT_D(R,X,Y) \
_FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
#define _FP_MUL_MEAT_Q(R,X,Y) \
_FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+#endif
#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_loop(S,R,X,Y)
+
+#if (_FP_W_TYPE_SIZE==64)
+#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_1_udiv(D,R,X,Y)
+#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
+#else
#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv(D,R,X,Y)
#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_4_udiv(Q,R,X,Y)
+#endif
#define _FP_NANFRAC_S ((_FP_QNANBIT_S << 1) - 1)
+
+#if (_FP_W_TYPE_SIZE==64)
+#define _FP_NANFRAC_D ((_FP_QNANBIT_D << 1) - 1)
+#define _FP_NANFRAC_Q ((_FP_QNANBIT_Q << 1) - 1), -1
+#else
#define _FP_NANFRAC_D ((_FP_QNANBIT_D << 1) - 1), -1
#define _FP_NANFRAC_Q ((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1
+#endif
+
#define _FP_NANSIGN_S 0
#define _FP_NANSIGN_D 0
#define _FP_NANSIGN_Q 0
@@ -64,6 +104,54 @@ typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
# endif
#endif
+/* Only provide exception support if we have hardware floating point using
+ floating point registers and we can execute the mtfsf instruction. This
+ would only be true if we are using the emulation routines for IEEE 128-bit
+ floating point on pre-ISA 3.0 machines without the IEEE 128-bit floating
+ point support. */
+
+#ifndef ___NO_FPRS__
+#define ISA_BIT(x) (1LL << (63 - x))
+
+/* Use the same bits of the FPSCR. */
+# define FP_EX_INVALID ISA_BIT(34)
+# define FP_EX_OVERFLOW ISA_BIT(35)
+# define FP_EX_UNDERFLOW ISA_BIT(36)
+# define FP_EX_DIVZERO ISA_BIT(37)
+# define FP_EX_INEXACT ISA_BIT(38)
+# define FP_EX_ALL (FP_EX_INVALID | FP_EX_OVERFLOW \
+ | FP_EX_UNDERFLOW | FP_EX_DIVZERO \
+ | FP_EX_INEXACT)
+
+void __sfp_handle_exceptions (int);
+
+# define FP_HANDLE_EXCEPTIONS \
+ do { \
+ if (__builtin_expect (_fex, 0)) \
+ __sfp_handle_exceptions (_fex); \
+ } while (0);
+/* A set bit indicates an exception is masked and a clear bit indicates it is
+ trapping. */
+# define FP_TRAPPING_EXCEPTIONS (~_fpscr & (FP_EX_ALL >> 22))
+
+# define FP_RND_NEAREST 0x0
+# define FP_RND_ZERO 0x1
+# define FP_RND_PINF 0x2
+# define FP_RND_MINF 0x3
+# define FP_RND_MASK 0x3
+
+# define _FP_DECL_EX \
+ unsigned long long _fpscr __attribute__ ((unused)) = FP_RND_NEAREST
+
+#define FP_INIT_ROUNDMODE \
+ do { \
+ __asm__ __volatile__ ("mtfsf 255, %0" \
+ : \
+ : "f" (_fpscr)); \
+ } while (0)
+
+# define FP_ROUNDMODE (_fpscr & FP_RND_MASK)
+#endif /* !__NO_FPRS__ */
/* Define ALIASNAME as a strong alias for NAME. */
# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
diff --git a/libgcc/config/rs6000/t-float128 b/libgcc/config/rs6000/t-float128
new file mode 100644
index 00000000000..82dab3639ea
--- /dev/null
+++ b/libgcc/config/rs6000/t-float128
@@ -0,0 +1,95 @@
+# Support for adding __float128 to the powerpc.
+
+# The standard 128-bit floating point support functions are TFmode. Most
+# PowerPC targets use a long double format that has a pair of doubles to give
+# you more precision, but no extra expoenent range. This long double format is
+# mostly compatible with the format used by the IBM XL compilers. Some of the
+# names used by the IBM double-double format use TF in them, so we rename
+# all of the functions provided for the new IEEE 128-bit support.
+#
+# We use the TF functions in soft-fp for 128-bit floating point support, using
+# sed to transform the names in the files from TF names to KF names.
+
+# Emulator functions from the soft-fp directory
+fp128_softfp_funcs = addkf3 subkf3 mulkf3 divkf3 negkf2 \
+ unordkf2 eqkf2 gekf2 lekf2 \
+ extendsfkf2 extenddfkf2 trunckfsf2 trunckfdf2 \
+ fixkfsi fixkfdi fixunskfsi fixunskfdi \
+ floatsikf floatdikf floatunsikf floatundikf
+
+fp128_softfp_src = $(addsuffix -sw.c,$(fp128_softfp_funcs))
+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)
+
+# New functions for software emulation
+fp128_ppc_funcs = floattikf floatuntikf fixkfti fixunskfti \
+ extendkftf2-sw trunctfkf2-sw \
+ sfp-exceptions
+
+fp128_ppc_src = $(addprefix $(srcdir)/config/rs6000/,$(addsuffix \
+ .c,$(fp128_ppc_funcs)))
+fp128_ppc_static_obj = $(addsuffix $(objext),$(fp128_ppc_funcs))
+fp128_ppc_shared_obj = $(addsuffix _s$(objext),$(fp128_ppc_funcs))
+fp128_ppc_obj = $(fp128_ppc_static_obj) $(fp128_ppc_shared_obj)
+
+# All functions
+fp128_funcs = $(fp128_softfp_funcs) $(fp128_ppc_funcs) \
+ $(fp128_hw_funcs) $(fp128_ifunc_funcs)
+
+fp128_src = $(fp128_softfp_src) $(fp128_ppc_src) \
+ $(fp128_hw_src) $(fp128_ifunc_src)
+
+fp128_obj = $(fp128_softfp_obj) $(fp128_ppc_obj) \
+ $(fp128_hw_obj) $(fp128_ifunc_obj)
+
+fp128_sed = $(srcdir)/config/rs6000/float128-sed$(fp128_sed_hw)
+fp128_dep = $(fp128_sed) $(srcdir)/config/rs6000/t-float128
+
+fp128_includes = $(srcdir)/soft-fp/double.h \
+ $(srcdir)/soft-fp/op-1.h \
+ $(srcdir)/soft-fp/op-4.h \
+ $(srcdir)/soft-fp/op-common.h \
+ $(srcdir)/soft-fp/single.h \
+ $(srcdir)/soft-fp/extended.h \
+ $(srcdir)/soft-fp/op-2.h \
+ $(srcdir)/soft-fp/op-8.h \
+ $(srcdir)/soft-fp/quad.h \
+ $(srcdir)/soft-fp/soft-fp.h
+
+# Build the emulator without ISA 3.0 hardware support.
+FP128_CFLAGS_SW = -Wno-type-limits -mvsx -mfloat128 \
+ -mno-float128-hardware \
+ -I$(srcdir)/soft-fp \
+ -I$(srcdir)/config/rs6000 \
+ $(FLOAT128_HW_INSNS)
+
+$(fp128_softfp_obj) : INTERNAL_CFLAGS += $(FP128_CFLAGS_SW)
+$(fp128_ppc_obj) : INTERNAL_CFLAGS += $(FP128_CFLAGS_SW)
+$(fp128_obj) : $(fp128_includes)
+$(fp128_obj) : $(srcdir)/config/rs6000/quad-float128.h
+
+$(fp128_softfp_src) : $(srcdir)/soft-fp/$(subst -sw,,$(subst kf,tf,$@)) $(fp128_dep)
+ @src="$(srcdir)/soft-fp/$(subst -sw,,$(subst kf,tf,$@))"; \
+ echo "Create $@"; \
+ (echo "/* file created from $$src */"; \
+ echo; \
+ sed -f $(fp128_sed) < $$src) > $@
+
+.PHONY: test clean-float128
+
+test:
+ @echo "fp128_src:"; \
+ for x in $(fp128_src); do echo " $$x"; done; \
+ echo; \
+ echo "fp128_obj:"; \
+ for x in $(fp128_obj); do echo " $$x"; done;
+
+clean-float128:
+ rm -rf $(fp128_softfp_src)
+ @$(MULTICLEAN) multi-clean DO=clean-float128
+
+# For now, only put it in the static library
+# LIB2ADD += $(fp128_src)
+
+LIB2ADD_ST += $(fp128_src)
diff --git a/libgcc/config/rs6000/t-float128-hw b/libgcc/config/rs6000/t-float128-hw
new file mode 100644
index 00000000000..161062f33c0
--- /dev/null
+++ b/libgcc/config/rs6000/t-float128-hw
@@ -0,0 +1,35 @@
+# Support for adding __float128 hardware support to the powerpc.
+# Tell the float128 functions that the ISA 3.0 hardware support can
+# be compiled it to be selected via IFUNC functions.
+
+FLOAT128_HW_INSNS = -DFLOAT128_HW_INSNS
+
+# New functions for hardware support
+fp128_hw_funcs = float128-hw
+fp128_hw_src = $(srcdir)/config/rs6000/float128-hw.c
+fp128_hw_static_obj = float128-hw$(objext)
+fp128_hw_shared_obj = float128-hw_s$(objext)
+fp128_hw_obj = $(fp128_hw_static_obj) $(fp128_hw_shared_obj)
+
+fp128_ifunc_funcs = float128-ifunc
+fp128_ifunc_src = $(srcdir)/config/rs6000/float128-ifunc.c
+fp128_ifunc_static_obj = float128-ifunc$(objext)
+fp128_ifunc_shared_obj = float128-ifunc_s$(objext)
+fp128_ifunc_obj = $(fp128_ifunc_static_obj) $(fp128_ifunc_shared_obj)
+
+# Add _sw suffix to names to allow ifunc support.
+fp128_sed_hw = -hw
+
+# Build the hardware support functions with appropriate hardware support
+FP128_CFLAGS_HW = -Wno-type-limits -mvsx -mfloat128 \
+ -mpower8-vector -mpower9-vector \
+ -mfloat128-hardware \
+ -I$(srcdir)/soft-fp \
+ -I$(srcdir)/config/rs6000 \
+ $(FLOAT128_HW_INSNS)
+
+$(fp128_hw_obj) : INTERNAL_CFLAGS += $(FP128_CFLAGS_HW)
+$(fp128_hw_obj) : $(srcdir)/config/rs6000/t-float128-hw
+
+$(fp128_ifunc_obj) : INTERNAL_CFLAGS += $(FP128_CFLAGS_SW)
+$(fp128_ifunc_obj) : $(srcdir)/config/rs6000/t-float128-hw
diff --git a/libgcc/config/rs6000/trunctfkf2-sw.c b/libgcc/config/rs6000/trunctfkf2-sw.c
new file mode 100644
index 00000000000..4d8ffe53dcf
--- /dev/null
+++ b/libgcc/config/rs6000/trunctfkf2-sw.c
@@ -0,0 +1,53 @@
+/* Software IEEE 128-bit floating-point emulation for PowerPC.
+
+ Copyright (C) 2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Michael Meissner (meissner@linux.vnet.ibm.com)
+ Code is based on the main soft-fp library written by:
+ Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ 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/>. */
+
+/* Convert IBM long double to IEEE 128-bit floating point. */
+
+#ifdef __FLOAT128_HARDWARE__
+#error "This module must not be compiled with IEEE 128-bit hardware support"
+#endif
+
+#include "soft-fp.h"
+#include "quad-float128.h"
+
+#ifndef FLOAT128_HW_INSNS
+#define __trunctfkf2_sw __trunctfkf2
+#endif
+
+__float128
+__trunctfkf2_sw (IBM128_TYPE value)
+{
+ __float128 ret;
+
+ CVT_IBM128_TO_FLOAT128 (ret, value);
+ return ret;
+}
diff --git a/libgcc/configure b/libgcc/configure
index 78708c7f407..de8c13c4ba3 100644
--- a/libgcc/configure
+++ b/libgcc/configure
@@ -4766,6 +4766,61 @@ esac
;;
esac
+case ${host} in
+powerpc*-*-linux*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the PowerPC compiler can do __float128" >&5
+$as_echo_n "checking whether the PowerPC compiler can do __float128... " >&6; }
+if test "${libgcc_cv_powerpc_float128+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#pragma GCC target ("vsx,float128")
+ __float128 add (__float128 *a) { return *a + *(a+1); }
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ libgcc_cv_powerpc_float128=yes
+else
+ libgcc_cv_powerpc_float128=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgcc_cv_powerpc_float128" >&5
+$as_echo "$libgcc_cv_powerpc_float128" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the PowerPC compiler can do hardware __float128" >&5
+$as_echo_n "checking whether the PowerPC compiler can do hardware __float128... " >&6; }
+if test "${libgcc_cv_powerpc_float128_hw+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#pragma GCC target ("cpu=power9,float128,float128-hardware")
+ #include <sys/auxv.h>
+ #ifndef AT_PLATFORM
+ #error "AT_PLATFORM is not defined"
+ #endif
+ __float128 add (__float128 a, __float128 b)
+ {
+ __float128 ret;
+ __asm__ ("xsaddqp %0,%1,%2" : "=v" (ret) : "v" (a), "v" (b));
+ return ret;
+ }
+ void *add_resolver (void) { return (void *) add; }
+ __float128 add_ifunc (__float128, __float128)
+ __attribute__ ((__ifunc__ ("add_resolver")));
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ libgcc_cv_powerpc_float128_hw=yes
+else
+ libgcc_cv_powerpc_float128_hw=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgcc_cv_powerpc_float128_hw" >&5
+$as_echo "$libgcc_cv_powerpc_float128_hw" >&6; }
+esac
+
# Collect host-machine-specific information.
. ${srcdir}/config.host
diff --git a/libgcc/configure.ac b/libgcc/configure.ac
index 9d831a76997..860a5f58100 100644
--- a/libgcc/configure.ac
+++ b/libgcc/configure.ac
@@ -373,6 +373,37 @@ esac
;;
esac
+case ${host} in
+powerpc*-*-linux*)
+ AC_CACHE_CHECK([whether the PowerPC compiler can do __float128],
+ [libgcc_cv_powerpc_float128],
+ [AC_COMPILE_IFELSE(
+ [#pragma GCC target ("vsx,float128")
+ __float128 add (__float128 *a) { return *a + *(a+1); }],
+ [libgcc_cv_powerpc_float128=yes],
+ [libgcc_cv_powerpc_float128=no])])
+
+ AC_CACHE_CHECK([whether the PowerPC compiler can do hardware __float128],
+ [libgcc_cv_powerpc_float128_hw],
+ [AC_COMPILE_IFELSE(
+ [#pragma GCC target ("cpu=power9,float128,float128-hardware")
+ #include <sys/auxv.h>
+ #ifndef AT_PLATFORM
+ #error "AT_PLATFORM is not defined"
+ #endif
+ __float128 add (__float128 a, __float128 b)
+ {
+ __float128 ret;
+ __asm__ ("xsaddqp %0,%1,%2" : "=v" (ret) : "v" (a), "v" (b));
+ return ret;
+ }
+ void *add_resolver (void) { return (void *) add; }
+ __float128 add_ifunc (__float128, __float128)
+ __attribute__ ((__ifunc__ ("add_resolver")));],
+ [libgcc_cv_powerpc_float128_hw=yes],
+ [libgcc_cv_powerpc_float128_hw=no])])
+esac
+
# Collect host-machine-specific information.
. ${srcdir}/config.host