===================================================================
@@ -16560,8 +16560,7 @@ init_float128_ieee (machine_mode mode)
set_optab_libfunc (lt_optab, mode, "__ltkf2");
set_optab_libfunc (le_optab, mode, "__lekf2");
set_optab_libfunc (unord_optab, mode, "__unordkf2");
- set_optab_libfunc (cmp_optab, mode, "__cmpokf2"); /* fcmpo */
- set_optab_libfunc (ucmp_optab, mode, "__cmpukf2"); /* fcmpu */
+ set_optab_libfunc (cmp_optab, mode, "__cmpukf2");
set_conv_libfunc (sext_optab, mode, SFmode, "__extendsfkf2");
set_conv_libfunc (sext_optab, mode, DFmode, "__extenddfkf2");
@@ -20569,12 +20568,11 @@ rs6000_generate_compare (rtx cmp, machin
instructions. */
else if (!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (mode))
{
- rtx and_reg = gen_reg_rtx (SImode);
rtx dest = gen_reg_rtx (SImode);
- rtx libfunc = optab_libfunc (ucmp_optab, mode);
+ rtx libfunc = NULL_RTX;
HOST_WIDE_INT mask_value = 0;
- /* Values that __cmpokf2/__cmpukf2 returns. */
+ /* Values that __cmpukf2 returns. */
#define PPC_CMP_UNORDERED 0x1 /* isnan (a) || isnan (b). */
#define PPC_CMP_EQUAL 0x2 /* a == b. */
#define PPC_CMP_GREATER_THEN 0x4 /* a > b. */
@@ -20582,84 +20580,83 @@ rs6000_generate_compare (rtx cmp, machin
switch (code)
{
+ /* Normal comparisons use __eqkf2, __gekf2, __lekf2. */
case EQ:
- mask_value = PPC_CMP_EQUAL;
- code = NE;
- break;
-
case NE:
- mask_value = PPC_CMP_EQUAL;
- code = EQ;
+ libfunc = optab_libfunc (eq_optab, mode);
break;
case GT:
- mask_value = PPC_CMP_GREATER_THEN;
- code = NE;
- break;
-
case GE:
- mask_value = PPC_CMP_GREATER_THEN | PPC_CMP_EQUAL;
- code = NE;
+ libfunc = optab_libfunc (ge_optab, mode);
break;
case LT:
- mask_value = PPC_CMP_LESS_THEN;
- code = NE;
- break;
-
case LE:
- mask_value = PPC_CMP_LESS_THEN | PPC_CMP_EQUAL;
- code = NE;
+ libfunc = optab_libfunc (le_optab, mode);
break;
case UNLE:
+ libfunc = optab_libfunc (cmp_optab, mode);
mask_value = PPC_CMP_GREATER_THEN;
code = EQ;
break;
+ /* IEEE comparisons that do not trap on NaN, call __cmpukf2 and
+ return 4 bits for LT, EQ, GT, and Unordered. */
case UNLT:
+ libfunc = optab_libfunc (cmp_optab, mode);
mask_value = PPC_CMP_GREATER_THEN | PPC_CMP_EQUAL;
code = EQ;
break;
case UNGE:
+ libfunc = optab_libfunc (cmp_optab, mode);
mask_value = PPC_CMP_LESS_THEN;
code = EQ;
break;
case UNGT:
+ libfunc = optab_libfunc (cmp_optab, mode);
mask_value = PPC_CMP_LESS_THEN | PPC_CMP_EQUAL;
code = EQ;
break;
case UNEQ:
+ libfunc = optab_libfunc (cmp_optab, mode);
mask_value = PPC_CMP_EQUAL | PPC_CMP_UNORDERED;
code = NE;
case LTGT:
+ libfunc = optab_libfunc (cmp_optab, mode);
mask_value = PPC_CMP_EQUAL | PPC_CMP_UNORDERED;
code = EQ;
break;
case UNORDERED:
- mask_value = PPC_CMP_UNORDERED;
- code = NE;
- break;
-
case ORDERED:
- mask_value = PPC_CMP_UNORDERED;
- code = EQ;
+ libfunc = optab_libfunc (unord_optab, mode);
+ code = (code == UNORDERED) ? NE : EQ;
break;
default:
gcc_unreachable ();
}
- gcc_assert (mask_value != 0);
- and_reg = emit_library_call_value (libfunc, and_reg, LCT_CONST, SImode, 2,
- op0, mode, op1, mode);
+ gcc_assert (libfunc != NULL_RTX);
+ dest = emit_library_call_value (libfunc, dest, LCT_CONST, SImode, 2,
+ op0, mode, op1, mode);
+
+ /* If this is an IEEE comparison, see if the particular bits that we are
+ interested are set. */
+ if (mask_value != 0)
+ {
+ rtx dest2 = gen_reg_rtx (SImode);
+
+ emit_insn (gen_andsi3 (dest2, dest, GEN_INT (mask_value)));
+ dest = dest2;
+ }
- emit_insn (gen_andsi3 (dest, and_reg, GEN_INT (mask_value)));
compare_result = gen_reg_rtx (CCmode);
comp_mode = CCmode;
===================================================================
@@ -1059,6 +1059,11 @@ powerpc*-*-linux*)
exit 1
;;
esac
+
+ if test $libgcc_cv_powerpc_float128 = yes; then
+ tmake_file="${tmake_file} rs6000/t-float128"
+ fi
+
extra_parts="$extra_parts ecrti.o ecrtn.o ncrti.o ncrtn.o"
md_unwind_header=rs6000/linux-unwind.h
;;
===================================================================
@@ -70,6 +70,8 @@ INSTALL_DATA = @INSTALL_DATA@
mkinstalldirs = $(SHELL) $(libgcc_topdir)/mkinstalldirs
INSTALL_PARTS = $(EXTRA_PARTS)
+EXTRA_CLEAN =
+
objext = .o
AR = @AR@
@@ -90,6 +92,7 @@ FLAGS_TO_PASS = \
"CFLAGS=$(CFLAGS)" \
"DESTDIR=$(DESTDIR)" \
"EXTRA_OFILES=$(EXTRA_OFILES)" \
+ "EXTRA_CLEAN=$(EXTRA_CLEAN)" \
"HDEFINES=$(HDEFINES)" \
"INSTALL=$(INSTALL)" \
"INSTALL_DATA=$(INSTALL_DATA)" \
@@ -128,7 +131,7 @@ installcheck:
clean:
-rm -f libgcc_tm.h libgcc.map
-rm -f libgcc_tm.stamp stmp-ldirs
- -rm -f *$(objext)
+ -rm -f *$(objext) $(EXTRA_CLEAN)
-rm -f *.dep
-rm -f *.a
-rm -f libunwind$(SHLIB_EXT)
===================================================================
@@ -373,6 +373,17 @@ 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])])
+esac
+
# Collect host-machine-specific information.
. ${srcdir}/config.host
===================================================================
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2015 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"
+
+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;
+
+ if (_fex & FP_EX_INVALID)
+ {
+ __asm__ __volatile__ ("fdiv %0, %0, %0"
+ :
+ : "f" (fp_zero));
+ }
+ if (_fex & FP_EX_DIVZERO)
+ {
+ __asm__ __volatile__ ("fdiv %0, %0, %1"
+ :
+ : "f" (fp_one), "f" (fp_zero));
+ }
+ if (_fex & FP_EX_OVERFLOW)
+ {
+ __asm__ __volatile__ ("fadd %0, %0, %0"
+ :
+ : "f" (fp_max));
+ }
+ if (_fex & FP_EX_UNDERFLOW)
+ {
+ __asm__ __volatile__ ("fmul %0, %0, %0"
+ :
+ : "f" (fp_min));
+ }
+ if (_fex & FP_EX_INEXACT)
+ {
+ __asm__ __volatile__ ("fsub %0, %0, %1"
+ :
+ : "f" (fp_max), "f" (fp_one));
+ }
+}
===================================================================
@@ -0,0 +1,50 @@
+/* Software floating-point emulation.
+ Convert a 128bit signed integer to IEEE quad
+ Copyright (C) 2015 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
===================================================================
@@ -0,0 +1,62 @@
+/* Software IEEE 128-bit floating-point emulation for PowerPC.
+ Copyright (C) 2014 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. */
+
+/* Force the use of the VSX instruction set. */
+#if defined(_ARCH_PPC) && (!defined(__VSX__) || !defined(__FLOAT128__))
+#pragma GCC target ("vsx,float128")
+#endif
+
+extern __ibm128 __extendkftf2 (__float128);
+
+__ibm128
+__extendkftf2 (__float128 value)
+{
+ double high, low;
+
+ high = (double) value;
+ if (__builtin_isnan (high) || __builtin_isinf (high))
+ low = 0.0;
+
+ else
+ {
+ double high_temp;
+
+ low = (double) (value - (__float128)high);
+ /* now renormalized the high/low into canonical IBM long double form. */
+ high_temp = high + low;
+ low = (high - high_temp) + low;
+ high = high_temp;
+ }
+
+ return __builtin_pack_longdouble (high, low);
+}
===================================================================
@@ -0,0 +1,70 @@
+/* Software IEEE 128-bit floating-point emulation for PowerPC.
+ Copyright (C) 2014 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. */
+
+/* Force the use of the VSX instruction set. */
+#if defined(_ARCH_PPC) && (!defined(__VSX__) || !defined(__FLOAT128__))
+#pragma GCC target ("vsx,float128")
+#else
+#if 0
+typedef long double __ibm128;
+typedef long double __float128;
+#endif
+#endif
+
+extern __float128 __trunctfkf2 (__ibm128);
+
+#ifdef __LITTLE_ENDIAN__
+#define HIGH_WORD 1
+#define LOW_WORD 0
+#else
+#define HIGH_WORD 0
+#define LOW_WORD 1
+#endif
+
+__float128
+__trunctfkf2 (__ibm128 value)
+{
+ double high = __builtin_unpack_longdouble (value, HIGH_WORD);
+ double low = __builtin_unpack_longdouble (value, LOW_WORD);
+
+ /* Handle the special cases of NAN and inifinity. */
+ if (__builtin_isnan (high) || __builtin_isinf (high))
+ return (__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. */
+ if (low == 0.0)
+ return (__float128) high;
+
+ return ((__float128)high) + ((__float128)low);
+}
===================================================================
@@ -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__
#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,46 @@ typedef int __gcc_CMPtype __attribute__
# endif
#endif
+#define ISA_BIT(x) (1 << (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)
/* Define ALIASNAME as a strong alias for NAME. */
# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
===================================================================
@@ -0,0 +1,50 @@
+/* Software floating-point emulation.
+ Convert IEEE quad to 128bit unsigned integer
+ Copyright (C) 2015 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
===================================================================
@@ -0,0 +1,50 @@
+/* Software floating-point emulation.
+ Convert IEEE quad to 128bit signed integer
+ Copyright (C) 2015 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
===================================================================
@@ -0,0 +1,101 @@
+/* Software IEEE 128-bit floating-point emulation for PowerPC.
+ Copyright (C) 2015 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:
+ Joseph Myers (joseph@codesourcery.com),
+ 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/>. */
+
+/* This function is called for the IEEE comparisons that specifically handle
+ NaNs. The normal comparisons use eqkf2, gekf2, lekf2, etc. */
+
+#include "soft-fp.h"
+#include "double.h"
+#include "single.h"
+#include "quad-float128.h"
+
+/* PowerPC condition register bits. */
+#define PPC_UNORDERED 0x1 /* isnan (a) || isnan (b). */
+#define PPC_EQUAL 0x2 /* a == b. */
+#define PPC_GREATER_THEN 0x4 /* a > b. */
+#define PPC_LESS_THEN 0x8 /* a < b. */
+
+/* Map FP_CMP_Q output to PowerPC condition register bits. */
+#define CMP_UNORDERED (-2) /* isnan (a) || isnan (b). */
+#define CMP_LESS_THEN (-1) /* a < b. */
+#define CMP_EQUAL 0 /* a == b. */
+#define CMP_GREATER_THEN 1 /* a < b. */
+#define CMP_INVALID 2 /* raise invalid exception. */
+
+#define CMP_LOW CMP_UNORDERED /* comparison low value. */
+#define CMP_HIGH CMP_INVALID /* comparison high value. */
+
+static const unsigned char ppc_cr_map[] = {
+ PPC_UNORDERED, /* -2: unordered. */
+ PPC_LESS_THEN, /* -1: a < b. */
+ PPC_EQUAL, /* 0: a == b. */
+ PPC_GREATER_THEN, /* 1: a > b. */
+ PPC_UNORDERED, /* 2: invalid. */
+};
+
+/* Compare two IEEE 128-bit floating point values and return the status. We
+ return the status as a 4-bit value that uses the same values as the PowerPC
+ condition code register. */
+
+CMPtype
+__cmpukf2 (TFtype a, TFtype b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q (A);
+ FP_DECL_Q (B);
+ CMPtype r, r2;
+
+ FP_INIT_EXCEPTIONS;
+ FP_UNPACK_RAW_Q (A, a);
+ FP_UNPACK_RAW_Q (B, b);
+
+ /* First do the unordered comparison. */
+ FP_CMP_UNORD_Q (r, A, B, 1);
+ if (r)
+ r2 = PPC_UNORDERED;
+
+ else
+ {
+ /* If the value is not unordered, do the normal comparison. */
+ FP_CMP_Q (r, A, B, 2, 2);
+ if (r == CMP_INVALID)
+ FP_SET_EXCEPTION (FP_EX_INVALID);
+
+ r2 = ((r < CMP_LOW || r > CMP_HIGH)
+ ? PPC_UNORDERED
+ : ppc_cr_map[r-CMP_LOW]);
+ }
+
+ FP_HANDLE_EXCEPTIONS;
+
+ return r2;
+}
===================================================================
@@ -0,0 +1,50 @@
+/* Software floating-point emulation.
+ Convert a 128bit unsigned integer to IEEE quad
+ Copyright (C) 2015 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
===================================================================
@@ -0,0 +1,87 @@
+/* Software floating-point emulation.
+ Definitions for IEEE Quad Precision on the PowerPC.
+ Copyright (C) 2015 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>
+
+/* 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
+
+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 CMPtype __cmpukf2 (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);
+
+#ifdef _ARCH_PPC64
+extern TItype_ppc __fixkfti (TFtype);
+extern UTItype_ppc __fixunskfti (TFtype);
+extern TFtype __floattikf (TItype_ppc);
+extern TFtype __floatuntikf (UTItype_ppc);
+#endif
===================================================================
@@ -0,0 +1,80 @@
+# 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 .c,$(fp128_softfp_funcs))
+fp128_softfp_static_obj = $(addsuffix $(objext),$(fp128_softfp_funcs))
+fp128_softfp_shared_obj = $(addsuffix _s$(objext),$(fp128_softfp_funcs))
+fp128_softfp_obj = $(fp128_softfp_static_obj) $(fp128_softfp_shared_obj)
+
+# New functions
+fp128_ppc_funcs = floattikf floatuntikf fixkfti fixunskfti \
+ extendkftf2 trunctfkf2 sfp-exceptions cmpukf2
+
+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_src = $(fp128_softfp_src) $(fp128_ppc_src)
+fp128_obj = $(fp128_softfp_obj) $(fp128_ppc_obj)
+fp128_sed = $(srcdir)/config/rs6000/float128-sed
+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
+
+EXTRA_CLEAN += $(fp128_softfp_src)
+
+FP128_CFLAGS = -Wno-type-limits -mvsx -mfloat128 \
+ -I$(srcdir)/soft-fp \
+ -I$(srcdir)/config/rs6000
+
+$(fp128_obj) : INTERNAL_CFLAGS += $(FP128_CFLAGS)
+$(fp128_obj) : $(fp128_includes)
+$(fp128_obj) : $(srcdir)/config/rs6000/quad-float128.h
+
+$(fp128_softfp_src) : $(srcdir)/soft-fp/$(subst kf,tf,$@) $(fp128_dep)
+ @src="$(srcdir)/soft-fp/$(subst kf,tf,$@)"; \
+ echo "Create $@"; \
+ (echo "/* file created from $$src */"; \
+ echo; \
+ sed -f $(fp128_sed) < $$src) > $@
+
+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;
+
+# For now, only put it in the static library
+# LIB2ADD += $(fp128_src)
+
+LIB2ADD_ST += $(fp128_src)
===================================================================
@@ -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
===================================================================
@@ -4766,6 +4766,29 @@ 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; }
+esac
+
# Collect host-machine-specific information.
. ${srcdir}/config.host