Index: gcc/configure.ac
===================================================================
--- gcc/configure.ac	(revision 256120)
+++ gcc/configure.ac	(working copy)
@@ -5885,6 +5885,30 @@ if test x$gcc_cv_target_ldbl128 = xyes; 
 	    [Define if TFmode long double should be the default])
 fi
 
+# Check if TFmode long double target should use the IBM extended double or IEEE
+# 128-bit floating point formats if long doubles are 128-bits long.  The long
+# double type can only be switched on powerpc64 bit Linux systems where VSX is
+# supported.  Other PowerPC systems do not build the IEEE 128-bit emulator in
+# liggcc.
+AC_ARG_WITH([long-double-format],
+  [AS_HELP_STRING([--with-long-double-format={ieee,ibm}]
+		  [Specify whether PowerPC long double uses IEEE or IBM format])],[
+case "$target:$with_cpu:$with_long_double_format" in
+  powerpc*-*-linux*:power[789]:ieee | powerpc*-*-linux*:power[1-9][0-9]+:ieee | \
+  powerpc*-*-linux*:power[789]:ibm | powerpc*-*-linux*:power[1-9][0-9]+:ibm | \
+  powerpc64le-*-linux*:*:ieee | powerpc64le-*-linux*:*:ibm)
+    ;;
+  powerpc*-*-linux*:power[789]:* | powerpc*-*-linux*:power[1-9][0-9]+:* | \
+  powerpc64le-*-linux*:*:*)
+    AC_MSG_ERROR([--with-long-double-format argument should be ibm or ieee])
+    ;;
+  *)
+    AC_MSG_ERROR([Configure option --with-long-double-format is only supported \
+for PowerPC VSX Linux systems])
+    ;;
+esac],
+  [])
+
 # Check if the target LIBC supports exporting the AT_PLATFORM and AT_HWCAP
 # values in the TCB.  Currently, only GLIBC 2.23 and later support this.
 gcc_cv_libc_provides_hwcap_in_tcb=no
Index: gcc/configure
===================================================================
--- gcc/configure	(revision 256120)
+++ gcc/configure	(working copy)
@@ -945,6 +945,7 @@ enable_linker_build_id
 enable_libssp
 enable_default_ssp
 with_long_double_128
+with_long_double_format
 with_gc
 with_system_zlib
 enable_maintainer_mode
@@ -1738,6 +1739,9 @@ Optional Packages:
   --with-glibc-version=M.N
                           assume GCC used with glibc version M.N or later
   --with-long-double-128  use 128-bit long double by default
+  --with-long-double-format={ieee,ibm}
+		  Specify whether PowerPC long double uses IEEE or IBM format
+
   --with-gc={page,zone}   this option is not supported anymore. It used to
                           choose the garbage collection mechanism to use with
                           the compiler
@@ -18442,7 +18446,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 18445 "configure"
+#line 18449 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -18548,7 +18552,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 18551 "configure"
+#line 18555 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -29185,6 +29189,32 @@ $as_echo "#define TARGET_DEFAULT_LONG_DO
 
 fi
 
+# Check if TFmode long double target should use the IBM extended double or IEEE
+# 128-bit floating point formats if long doubles are 128-bits long.  The long
+# double type can only be switched on powerpc64 bit Linux systems where VSX is
+# supported.  Other PowerPC systems do not build the IEEE 128-bit emulator in
+# liggcc.
+
+# Check whether --with-long-double-format was given.
+if test "${with_long_double_format+set}" = set; then :
+  withval=$with_long_double_format;
+case "$target:$with_cpu:$with_long_double_format" in
+  powerpc*-*-linux*:power789:ieee | powerpc*-*-linux*:power1-90-9+:ieee | \
+  powerpc*-*-linux*:power789:ibm | powerpc*-*-linux*:power1-90-9+:ibm | \
+  powerpc64le-*-linux*:*:ieee | powerpc64le-*-linux*:*:ibm)
+    ;;
+  powerpc*-*-linux*:power789:* | powerpc*-*-linux*:power1-90-9+:* | \
+  powerpc64le-*-linux*:*:*)
+    as_fn_error "--with-long-double-format argument should be ibm or ieee" "$LINENO" 5
+    ;;
+  *)
+    as_fn_error "Configure option --with-long-double-format is only supported \
+for PowerPC VSX Linux systems" "$LINENO" 5
+    ;;
+esac
+fi
+
+
 # Check if the target LIBC supports exporting the AT_PLATFORM and AT_HWCAP
 # values in the TCB.  Currently, only GLIBC 2.23 and later support this.
 gcc_cv_libc_provides_hwcap_in_tcb=no
Index: gcc/config.gcc
===================================================================
--- gcc/config.gcc	(revision 256120)
+++ gcc/config.gcc	(working copy)
@@ -4392,6 +4392,24 @@ case "${target}" in
 			exit 1
 		    fi
 		fi
+
+		# Set up the default long double format.  Only enable the
+		# IEEE/IBM multilibs if the user explicitly set the long double
+		# format and did not do --disable-multilib.
+		if test x$with_long_double_format = xieee; then
+		    tm_defines="${tm_defines} TARGET_IEEEQUAD_DEFAULT=1"
+		    if test x$enable_multilib = xyes; then
+			tm_defines="${tm_defines} TARGET_IEEEQUAD_MULTILIB=1"
+			tmake_file="${tmake_file} rs6000/t-ldouble"
+		    fi
+
+		elif test x$with_long_double_format = xibm; then
+		    tm_defines="${tm_defines} TARGET_IEEEQUAD_DEFAULT=0"
+		    if test x$enable_multilib = xyes; then
+			tm_defines="${tm_defines} TARGET_IEEEQUAD_MULTILIB=1"
+			tmake_file="${tmake_file} rs6000/t-ldouble"
+		    fi
+		fi
 		;;
 
 	s390*-*-*)
Index: gcc/config/rs6000/rs6000.h
===================================================================
--- gcc/config/rs6000/rs6000.h	(revision 256120)
+++ gcc/config/rs6000/rs6000.h	(working copy)
@@ -437,11 +437,13 @@ extern const char *host_detect_local_cpu
    Similarly IFmode is the IBM long double format even if the default is IEEE
    128-bit.  Don't allow IFmode if -msoft-float.  */
 #define FLOAT128_IEEE_P(MODE)						\
-  ((TARGET_IEEEQUAD && ((MODE) == TFmode || (MODE) == TCmode))		\
+  ((TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128				\
+    && ((MODE) == TFmode || (MODE) == TCmode))				\
    || ((MODE) == KFmode) || ((MODE) == KCmode))
 
 #define FLOAT128_IBM_P(MODE)						\
-  ((!TARGET_IEEEQUAD && ((MODE) == TFmode || (MODE) == TCmode))		\
+  ((!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128				\
+    && ((MODE) == TFmode || (MODE) == TCmode))				\
    || (TARGET_HARD_FLOAT && ((MODE) == IFmode || (MODE) == ICmode)))
 
 /* Helper macros to say whether a 128-bit floating point type can go in a
@@ -562,6 +564,12 @@ extern int rs6000_vector_align[];
 #define TARGET_ALTIVEC_ABI rs6000_altivec_abi
 #define TARGET_LDBRX (TARGET_POPCNTD || rs6000_cpu == PROCESSOR_CELL)
 
+/* Define as 1 if we support multilibs for switching long double between IEEE
+   128-bit floating point and IBM extended double.  */
+#ifndef TARGET_IEEEQUAD_MULTILIB
+#define TARGET_IEEEQUAD_MULTILIB 0
+#endif
+
 /* ISA 2.01 allowed FCFID to be done in 32-bit, previously it was 64-bit only.
    Enable 32-bit fcfid's on any of the switches for newer ISA machines or
    XILINX.  */
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 256120)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -4600,11 +4600,15 @@ rs6000_option_override_internal (bool gl
      systems will also set long double to be IEEE 128-bit.  AIX and Darwin
      explicitly redefine TARGET_IEEEQUAD and TARGET_IEEEQUAD_DEFAULT to 0, so
      those systems will not pick up this default.  Warn if the user changes the
-     default unless -Wno-psabi.  */
+     default unless either the user used the -Wno-psabi option, or the compiler
+     was built to enable multilibs to switch between the two long double
+     types.  */
   if (!global_options_set.x_rs6000_ieeequad)
     rs6000_ieeequad = TARGET_IEEEQUAD_DEFAULT;
 
-  else if (rs6000_ieeequad != TARGET_IEEEQUAD_DEFAULT && TARGET_LONG_DOUBLE_128)
+  else if (!TARGET_IEEEQUAD_MULTILIB
+	   && rs6000_ieeequad != TARGET_IEEEQUAD_DEFAULT
+	   && TARGET_LONG_DOUBLE_128)
     {
       static bool warned_change_long_double;
       if (!warned_change_long_double)
@@ -11424,7 +11428,9 @@ rs6000_must_pass_in_stack (machine_mode 
 static inline bool
 is_complex_IBM_long_double (machine_mode mode)
 {
-  return mode == ICmode || (!TARGET_IEEEQUAD && mode == TCmode);
+  return mode == ICmode || (!TARGET_IEEEQUAD
+			    && TARGET_LONG_DOUBLE_128
+			    && mode == TCmode);
 }
 
 /* Whether ABI_V4 passes MODE args to a function in floating point
Index: gcc/config/rs6000/rs6000-c.c
===================================================================
--- gcc/config/rs6000/rs6000-c.c	(revision 256120)
+++ gcc/config/rs6000/rs6000-c.c	(working copy)
@@ -708,7 +708,18 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfi
       builtin_define ("__LONGDOUBLE128");
 
       if (TARGET_IEEEQUAD)
-	builtin_define ("__LONG_DOUBLE_IEEE128__");
+	{
+	  /* Older versions of GLIBC used __attribute__((__KC__)) to create the
+	     IEEE 128-bit floating point complex type for C++ (which does not
+	     support _Float128 _Complex).  If the default for long double is
+	     IEEE 128-bit mode, the library would need to use
+	     __attribute__((__TC__)) instead.  Defining __KF__ and __KC__
+	     is a stop-gap to build with the older libraries, until we
+	     get an updated library.  */
+	  builtin_define ("__LONG_DOUBLE_IEEE128__");
+	  builtin_define ("__KF__=__TF__");
+	  builtin_define ("__KC__=__TC__");
+	}
       else
 	builtin_define ("__LONG_DOUBLE_IBM128__");
     }
Index: gcc/config/rs6000/linux64.h
===================================================================
--- gcc/config/rs6000/linux64.h	(revision 256120)
+++ gcc/config/rs6000/linux64.h	(working copy)
@@ -245,11 +245,23 @@ extern int dot_symbols;
 #define DYNAMIC_LINKER_PREFIX	""
 #endif
 
+#if TARGET_IEEEQUAD_MULTILIB
+#if TARGET_IEEEQUAD_DEFAULT
+#define MULTILIB_DEFAULTS_IEEE , "mabi=ieeelongdouble"
+
+#else	/* TARGET_IEEEQUAD_DEFAULT.  */
+#define MULTILIB_DEFAULTS_IEEE , "mabi=ibmlongdouble"
+#endif	/* TARGET_IEEEQUAD_DEFAULT.  */
+
+#else	/* TARGET_IEEEQUAD_MULTILIB.  */
+#define MULTILIB_DEFAULTS_IEEE
+#endif	/* TARGET_IEEEQUAD_MULTILIB.  */
+
 #undef	MULTILIB_DEFAULTS
 #if DEFAULT_ARCH64_P
-#define MULTILIB_DEFAULTS { "m64" }
+#define MULTILIB_DEFAULTS { "m64" MULTILIB_DEFAULTS_IEEE }
 #else
-#define MULTILIB_DEFAULTS { "m32" }
+#define MULTILIB_DEFAULTS { "m32" MULTILIB_DEFAULTS_IEEE }
 #endif
 
 /* Split stack is only supported for 64 bit, and requires glibc >= 2.18.  */
Index: gcc/config/rs6000/t-ldouble
===================================================================
--- gcc/config/rs6000/t-ldouble	(revision 0)
+++ gcc/config/rs6000/t-ldouble	(revision 0)
@@ -0,0 +1,24 @@
+# Copyright (C) 2017 Free Software Foundation, Inc.
+#
+# This file is part of GCC.
+#
+# GCC is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GCC is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+# Enable building IEEE 128-bit floating point multilibs on a system that
+# defaults to IBM extended double floating point.
+MULTILIB_OPTIONS        += mabi=ibmlongdouble/mabi=ieeelongdouble
+MULTILIB_DIRNAMES       += ibm128 ieee128
+MULTILIB_OSDIRNAMES     += mabi.ibmlongdouble=../lib64 mabi.ieeelongdouble=../ieee64 ../lib64
+
Index: libgcc/config/rs6000/quad-float128.h
===================================================================
--- libgcc/config/rs6000/quad-float128.h	(revision 256120)
+++ libgcc/config/rs6000/quad-float128.h	(working copy)
@@ -51,12 +51,7 @@ typedef __complex float TCtype __attribu
 
 #include <quad.h>
 
-#ifdef __LONG_DOUBLE_IEEE128__
-#define IBM128_TYPE		__ibm128
-
-#else
-#define IBM128_TYPE		long double
-#endif
+#define IBM128_TYPE	__ibm128
 
 /* 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,
@@ -185,7 +180,7 @@ union ibm128_union {
 #define CVT_FLOAT128_TO_IBM128(RESULT, VALUE)				\
 {									\
   double __high, __low;							\
-  __float128 __value = (VALUE);						\
+  TFtype __value = (VALUE);						\
   union ibm128_union u;							\
 									\
   __high = (double) __value;						\
@@ -196,7 +191,7 @@ union ibm128_union {
     {									\
       double __high_temp;						\
 									\
-      __low = (double) (__value - (__float128) __high);			\
+      __low = (double) (__value - (TFtype) __high);			\
       /* Renormalize low/high and move them into canonical IBM long	\
 	 double form.  */						\
       __high_temp = __high + __low;					\
@@ -220,13 +215,13 @@ union ibm128_union {
 									\
   /* Handle the special cases of NAN and infinity.  */			\
   if (__builtin_isnan (__high) || __builtin_isinf (__high))		\
-    RESULT = (__float128) __high;					\
+    RESULT = (TFtype) __high;						\
 									\
   /* If low is 0.0, there no need to do the add.  In addition,		\
      avoiding the add produces the correct sign if high is -0.0.  */	\
   else if (__low == 0.0)						\
-    RESULT = (__float128) __high;					\
+    RESULT = (TFtype) __high;						\
 									\
   else									\
-    RESULT = ((__float128) __high) + ((__float128) __low);		\
+    RESULT = ((TFtype) __high) + ((TFtype) __low);			\
 }
Index: libgcc/config/rs6000/ibm-ldouble.c
===================================================================
--- libgcc/config/rs6000/ibm-ldouble.c	(revision 256120)
+++ libgcc/config/rs6000/ibm-ldouble.c	(working copy)
@@ -56,6 +56,15 @@ see the files COPYING3 and COPYING.RUNTI
 
 #define nonfinite(a) unlikely (! isless (fabs (a), inf ()))
 
+/* If we have __float128/_Float128, use __ibm128 instead of long double.  On
+   other systems, use long double, because __ibm128 might not have been
+   created.  */
+#ifdef __FLOAT128__
+#define IBM128_TYPE __ibm128
+#else
+#define IBM128_TYPE long double
+#endif
+
 /* Define ALIASNAME as a strong alias for NAME.  */
 # define strong_alias(name, aliasname) _strong_alias(name, aliasname)
 # define _strong_alias(name, aliasname) \
@@ -65,10 +74,10 @@ see the files COPYING3 and COPYING.RUNTI
    but GCC currently generates poor code when a union is used to turn
    a long double into a pair of doubles.  */
 
-long double __gcc_qadd (double, double, double, double);
-long double __gcc_qsub (double, double, double, double);
-long double __gcc_qmul (double, double, double, double);
-long double __gcc_qdiv (double, double, double, double);
+IBM128_TYPE __gcc_qadd (double, double, double, double);
+IBM128_TYPE __gcc_qsub (double, double, double, double);
+IBM128_TYPE __gcc_qmul (double, double, double, double);
+IBM128_TYPE __gcc_qdiv (double, double, double, double);
 
 #if defined __ELF__ && defined SHARED \
     && (defined __powerpc64__ || !(defined __linux__ || defined __gnu_hurd__))
@@ -88,17 +97,17 @@ __asm__ (".symver __gcc_qadd,_xlqadd@GCC
 	 ".symver .__gcc_qdiv,._xlqdiv@GCC_3.4");
 #endif
 
-/* Combine two 'double' values into one 'long double' and return the result.  */
-static inline long double
+/* Combine two 'double' values into one 'IBM128_TYPE' and return the result.  */
+static inline IBM128_TYPE
 pack_ldouble (double dh, double dl)
 {
-#if defined (__LONG_DOUBLE_128__) \
+#if defined (__LONG_DOUBLE_128__) && defined (__LONG_DOUBLE_IBM128__)	\
     && !(defined (_SOFT_FLOAT) || defined (__NO_FPRS__))
   return __builtin_pack_longdouble (dh, dl);
 #else
   union
   {
-    long double ldval;
+    IBM128_TYPE ldval;
     double dval[2];
   } x;
   x.dval[0] = dh;
@@ -107,8 +116,8 @@ pack_ldouble (double dh, double dl)
 #endif
 }
 
-/* Add two 'long double' values and return the result.	*/
-long double
+/* Add two 'IBM128_TYPE' values and return the result.	*/
+IBM128_TYPE
 __gcc_qadd (double a, double aa, double c, double cc)
 {
   double xh, xl, z, q, zz;
@@ -147,7 +156,7 @@ __gcc_qadd (double a, double aa, double 
   return pack_ldouble (xh, xl);
 }
 
-long double
+IBM128_TYPE
 __gcc_qsub (double a, double b, double c, double d)
 {
   return __gcc_qadd (a, b, -c, -d);
@@ -157,7 +166,7 @@ __gcc_qsub (double a, double b, double c
 static double fmsub (double, double, double);
 #endif
 
-long double
+IBM128_TYPE
 __gcc_qmul (double a, double b, double c, double d)
 {
   double xh, xl, t, tau, u, v, w;
@@ -181,7 +190,7 @@ __gcc_qmul (double a, double b, double c
   tau += v + w;	    /* Add in other second-order terms.	 */
   u = t + tau;
 
-  /* Construct long double result.  */
+  /* Construct IBM128_TYPE result.  */
   if (nonfinite (u))
     return u;
   xh = u;
@@ -189,7 +198,7 @@ __gcc_qmul (double a, double b, double c
   return pack_ldouble (xh, xl);
 }
 
-long double
+IBM128_TYPE
 __gcc_qdiv (double a, double b, double c, double d)
 {
   double xh, xl, s, sigma, t, tau, u, v, w;
@@ -226,7 +235,7 @@ __gcc_qdiv (double a, double b, double c
   tau = ((v-sigma)+w)/c;   /* Correction to t.  */
   u = t + tau;
 
-  /* Construct long double result.  */
+  /* Construct IBM128_TYPE result.  */
   if (nonfinite (u))
     return u;
   xh = u;
@@ -236,32 +245,32 @@ __gcc_qdiv (double a, double b, double c
 
 #if defined (_SOFT_DOUBLE) && defined (__LONG_DOUBLE_128__)
 
-long double __gcc_qneg (double, double);
+IBM128_TYPE __gcc_qneg (double, double);
 int __gcc_qeq (double, double, double, double);
 int __gcc_qne (double, double, double, double);
 int __gcc_qge (double, double, double, double);
 int __gcc_qle (double, double, double, double);
-long double __gcc_stoq (float);
-long double __gcc_dtoq (double);
+IBM128_TYPE __gcc_stoq (float);
+IBM128_TYPE __gcc_dtoq (double);
 float __gcc_qtos (double, double);
 double __gcc_qtod (double, double);
 int __gcc_qtoi (double, double);
 unsigned int __gcc_qtou (double, double);
-long double __gcc_itoq (int);
-long double __gcc_utoq (unsigned int);
+IBM128_TYPE __gcc_itoq (int);
+IBM128_TYPE __gcc_utoq (unsigned int);
 
 extern int __eqdf2 (double, double);
 extern int __ledf2 (double, double);
 extern int __gedf2 (double, double);
 
-/* Negate 'long double' value and return the result.	*/
-long double
+/* Negate 'IBM128_TYPE' value and return the result.	*/
+IBM128_TYPE
 __gcc_qneg (double a, double aa)
 {
   return pack_ldouble (-a, -aa);
 }
 
-/* Compare two 'long double' values for equality.  */
+/* Compare two 'IBM128_TYPE' values for equality.  */
 int
 __gcc_qeq (double a, double aa, double c, double cc)
 {
@@ -272,7 +281,7 @@ __gcc_qeq (double a, double aa, double c
 
 strong_alias (__gcc_qeq, __gcc_qne);
 
-/* Compare two 'long double' values for less than or equal.  */
+/* Compare two 'IBM128_TYPE' values for less than or equal.  */
 int
 __gcc_qle (double a, double aa, double c, double cc)
 {
@@ -283,7 +292,7 @@ __gcc_qle (double a, double aa, double c
 
 strong_alias (__gcc_qle, __gcc_qlt);
 
-/* Compare two 'long double' values for greater than or equal.  */
+/* Compare two 'IBM128_TYPE' values for greater than or equal.  */
 int
 __gcc_qge (double a, double aa, double c, double cc)
 {
@@ -294,35 +303,35 @@ __gcc_qge (double a, double aa, double c
 
 strong_alias (__gcc_qge, __gcc_qgt);
 
-/* Convert single to long double.  */
-long double
+/* Convert single to IBM128_TYPE.  */
+IBM128_TYPE
 __gcc_stoq (float a)
 {
   return pack_ldouble ((double) a, 0.0);
 }
 
-/* Convert double to long double.  */
-long double
+/* Convert double to IBM128_TYPE.  */
+IBM128_TYPE
 __gcc_dtoq (double a)
 {
   return pack_ldouble (a, 0.0);
 }
 
-/* Convert long double to single.  */
+/* Convert IBM128_TYPE to single.  */
 float
 __gcc_qtos (double a, double aa __attribute__ ((__unused__)))
 {
   return (float) a;
 }
 
-/* Convert long double to double.  */
+/* Convert IBM128_TYPE to double.  */
 double
 __gcc_qtod (double a, double aa __attribute__ ((__unused__)))
 {
   return a;
 }
 
-/* Convert long double to int.  */
+/* Convert IBM128_TYPE to int.  */
 int
 __gcc_qtoi (double a, double aa)
 {
@@ -330,7 +339,7 @@ __gcc_qtoi (double a, double aa)
   return (int) z;
 }
 
-/* Convert long double to unsigned int.  */
+/* Convert IBM128_TYPE to unsigned int.  */
 unsigned int
 __gcc_qtou (double a, double aa)
 {
@@ -338,15 +347,15 @@ __gcc_qtou (double a, double aa)
   return (unsigned int) z;
 }
 
-/* Convert int to long double.  */
-long double
+/* Convert int to IBM128_TYPE.  */
+IBM128_TYPE
 __gcc_itoq (int a)
 {
   return __gcc_dtoq ((double) a);
 }
 
-/* Convert unsigned int to long double.  */
-long double
+/* Convert unsigned int to IBM128_TYPE.  */
+IBM128_TYPE
 __gcc_utoq (unsigned int a)
 {
   return __gcc_dtoq ((double) a);
@@ -361,7 +370,7 @@ int __gcc_qunord (double, double, double
 extern int __eqdf2 (double, double);
 extern int __unorddf2 (double, double);
 
-/* Compare two 'long double' values for unordered.  */
+/* Compare two 'IBM128_TYPE' values for unordered.  */
 int
 __gcc_qunord (double a, double aa, double c, double cc)
 {
@@ -389,7 +398,7 @@ fmsub (double a, double b, double c)
     FP_DECL_Q(V);
     FP_DECL_D(R);
     double r;
-    long double u, x, y, z;
+    IBM128_TYPE u, x, y, z;
 
     FP_INIT_ROUNDMODE;
     FP_UNPACK_RAW_D (A, a);
Index: libgcc/config/rs6000/_mulkc3.c
===================================================================
--- libgcc/config/rs6000/_mulkc3.c	(revision 256120)
+++ libgcc/config/rs6000/_mulkc3.c	(working copy)
@@ -23,11 +23,11 @@ see the files COPYING3 and COPYING.RUNTI
 
 /* This is a temporary specialization of code from libgcc/libgcc2.c.  */
 
-typedef float KFtype __attribute__ ((mode (KF)));
-typedef __complex float KCtype __attribute__ ((mode (KC)));
+#include "soft-fp.h"
+#include "quad-float128.h"
 
-#define COPYSIGN(x,y) __builtin_copysignq (x, y)
-#define INFINITY __builtin_infq ()
+#define COPYSIGN(x,y) __builtin_copysignf128 (x, y)
+#define INFINITY __builtin_inff128 ()
 #define isnan __builtin_isnan
 #define isinf __builtin_isinf
 
@@ -35,13 +35,11 @@ typedef __complex float KCtype __attribu
 #define __mulkc3 __mulkc3_sw
 #endif
 
-extern KCtype __mulkc3 (KFtype, KFtype, KFtype, KFtype);
-
-KCtype
-__mulkc3 (KFtype a, KFtype b, KFtype c, KFtype d)
+TCtype
+__mulkc3 (TFtype a, TFtype b, TFtype c, TFtype d)
 {
-  KFtype ac, bd, ad, bc, x, y;
-  KCtype res;
+  TFtype ac, bd, ad, bc, x, y;
+  TCtype res;
 
   ac = a * c;
   bd = b * d;
Index: libgcc/config/rs6000/_divkc3.c
===================================================================
--- libgcc/config/rs6000/_divkc3.c	(revision 256120)
+++ libgcc/config/rs6000/_divkc3.c	(working copy)
@@ -23,12 +23,12 @@ see the files COPYING3 and COPYING.RUNTI
 
 /* This is a temporary specialization of code from libgcc/libgcc2.c.  */
 
-typedef float KFtype __attribute__ ((mode (KF)));
-typedef __complex float KCtype __attribute__ ((mode (KC)));
+#include "soft-fp.h"
+#include "quad-float128.h"
 
-#define COPYSIGN(x,y) __builtin_copysignq (x, y)
-#define INFINITY __builtin_infq ()
-#define FABS __builtin_fabsq
+#define COPYSIGN(x,y) __builtin_copysignf128 (x, y)
+#define INFINITY __builtin_inff128 ()
+#define FABS __builtin_fabsf128
 #define isnan __builtin_isnan
 #define isinf __builtin_isinf
 #define isfinite __builtin_isfinite
@@ -37,13 +37,11 @@ typedef __complex float KCtype __attribu
 #define __divkc3 __divkc3_sw
 #endif
 
-extern KCtype __divkc3 (KFtype, KFtype, KFtype, KFtype);
-
-KCtype
-__divkc3 (KFtype a, KFtype b, KFtype c, KFtype d)
+TCtype
+__divkc3 (TFtype a, TFtype b, TFtype c, TFtype d)
 {
-  KFtype denom, ratio, x, y;
-  KCtype res;
+  TFtype denom, ratio, x, y;
+  TCtype res;
 
   /* ??? We can get better behavior from logarithmic scaling instead of
      the division.  But that would mean starting to link libgcc against
Index: libgcc/config/rs6000/extendkftf2-sw.c
===================================================================
--- libgcc/config/rs6000/extendkftf2-sw.c	(revision 256120)
+++ libgcc/config/rs6000/extendkftf2-sw.c	(working copy)
@@ -44,7 +44,7 @@
 #endif
 
 IBM128_TYPE
-__extendkftf2_sw (__float128 value)
+__extendkftf2_sw (TFtype value)
 {
   IBM128_TYPE ret;
 
Index: libgcc/config/rs6000/trunctfkf2-sw.c
===================================================================
--- libgcc/config/rs6000/trunctfkf2-sw.c	(revision 256120)
+++ libgcc/config/rs6000/trunctfkf2-sw.c	(working copy)
@@ -43,10 +43,10 @@
 #define __trunctfkf2_sw __trunctfkf2
 #endif
 
-__float128
+TFtype
 __trunctfkf2_sw (IBM128_TYPE value)
 {
-  __float128 ret;
+  TFtype ret;
 
   CVT_IBM128_TO_FLOAT128 (ret, value);
   return ret;
