Index: gcc/config/rs6000/rs6000-c.c
===================================================================
--- gcc/config/rs6000/rs6000-c.c	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/config/rs6000)	(revision 240680)
+++ gcc/config/rs6000/rs6000-c.c	(.../gcc/config/rs6000)	(working copy)
@@ -425,10 +425,19 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfi
     builtin_define ("__RSQRTE__");
   if (TARGET_FRSQRTES)
     builtin_define ("__RSQRTEF__");
-  if (TARGET_FLOAT128)
+  if (TARGET_FLOAT128_KEYWORD)
     builtin_define ("__FLOAT128__");
+  if (TARGET_FLOAT128_TYPE)
+    builtin_define ("__FLOAT128_TYPE__");
   if (TARGET_FLOAT128_HW)
     builtin_define ("__FLOAT128_HARDWARE__");
+  if (TARGET_LONG_DOUBLE_128)
+    {
+      if (FLOAT128_IBM_P (TFmode))
+	builtin_define ("__ibm128=long double");
+      else if (TARGET_FLOAT128_KEYWORD && FLOAT128_IEEE_P (TFmode))
+	builtin_define ("__float128=long double");
+    }
 
   if (TARGET_EXTRA_BUILTINS && cpp_get_options (pfile)->lang != CLK_ASM)
     {
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/config/rs6000)	(revision 240680)
+++ gcc/config/rs6000/rs6000.c	(.../gcc/config/rs6000)	(working copy)
@@ -2718,6 +2718,9 @@ rs6000_debug_reg_global (void)
   fprintf (stderr, DEBUG_FMT_D, "Number of rs6000 builtins",
 	   (int)RS6000_BUILTIN_COUNT);
 
+  fprintf (stderr, DEBUG_FMT_D, "Enable float128 on VSX",
+	   (int)TARGET_FLOAT128_ENABLE_TYPE);
+
   if (TARGET_VSX)
     fprintf (stderr, DEBUG_FMT_D, "VSX easy 64-bit scalar element",
 	     (int)VECTOR_ELEMENT_SCALAR_64BIT);
@@ -2956,7 +2959,7 @@ rs6000_init_hard_regno_mode_ok (bool glo
 
   /* KF mode (IEEE 128-bit in VSX registers).  We do not have arithmetic, so
      only set the memory modes.  Include TFmode if -mabi=ieeelongdouble.  */
-  if (TARGET_FLOAT128)
+  if (TARGET_FLOAT128_TYPE)
     {
       rs6000_vector_mem[KFmode] = VECTOR_VSX;
       rs6000_vector_align[KFmode] = 128;
@@ -3162,7 +3165,7 @@ rs6000_init_hard_regno_mode_ok (bool glo
   if (TARGET_LFIWZX)
     rs6000_constraints[RS6000_CONSTRAINT_wz] = FLOAT_REGS;	/* DImode  */
 
-  if (TARGET_FLOAT128)
+  if (TARGET_FLOAT128_TYPE)
     {
       rs6000_constraints[RS6000_CONSTRAINT_wq] = VSX_REGS;	/* KFmode  */
       if (FLOAT128_IEEE_P (TFmode))
@@ -3701,7 +3704,7 @@ rs6000_builtin_mask_calculate (void)
 	  | ((TARGET_DFP)		    ? RS6000_BTM_DFP	   : 0)
 	  | ((TARGET_HARD_FLOAT)	    ? RS6000_BTM_HARD_FLOAT : 0)
 	  | ((TARGET_LONG_DOUBLE_128)	    ? RS6000_BTM_LDBL128   : 0)
-	  | ((TARGET_FLOAT128)		    ? RS6000_BTM_FLOAT128  : 0));
+	  | ((TARGET_FLOAT128_TYPE)	    ? RS6000_BTM_FLOAT128  : 0));
 }
 
 /* Implement TARGET_MD_ASM_ADJUST.  All asm statements are considered
@@ -4405,28 +4408,96 @@ rs6000_option_override_internal (bool gl
 	}
     }
 
-  /* __float128 requires VSX support.  */
-  if (TARGET_FLOAT128 && !TARGET_VSX)
+  /* Set long double size before the IEEE 128-bit tests.  */
+  if (!global_options_set.x_rs6000_long_double_type_size)
+    {
+      if (main_target_opt != NULL
+	  && (main_target_opt->x_rs6000_long_double_type_size
+	      != RS6000_DEFAULT_LONG_DOUBLE_SIZE))
+	error ("target attribute or pragma changes long double size");
+      else
+	rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
+    }
+
+  /* Set -mabi=ieeelongdouble on some old targets.  Note, AIX and Darwin
+     explicitly redefine TARGET_IEEEQUAD to 0, so those systems will not
+     pick up this default.  */
+#if !defined (POWERPC_LINUX) && !defined (POWERPC_FREEBSD)
+  if (!global_options_set.x_rs6000_ieeequad)
+    rs6000_ieeequad = 1;
+#endif
+
+  /* Enable the default support for IEEE 128-bit floating point on Linux VSX
+     sytems, but don't enable the __float128 keyword.  */
+  if (TARGET_VSX && TARGET_LONG_DOUBLE_128
+      && (TARGET_FLOAT128_ENABLE_TYPE || TARGET_IEEEQUAD)
+      && ((rs6000_isa_flags_explicit & OPTION_MASK_FLOAT128_TYPE) == 0))
+    rs6000_isa_flags |= OPTION_MASK_FLOAT128_TYPE;
+
+  /* IEEE 128-bit floating point requires VSX support.  */
+  if (!TARGET_VSX)
     {
-      if ((rs6000_isa_flags_explicit & OPTION_MASK_FLOAT128) != 0)
-	error ("-mfloat128 requires VSX support");
+      if (TARGET_FLOAT128_KEYWORD)
+	{
+	  if ((rs6000_isa_flags_explicit & OPTION_MASK_FLOAT128_KEYWORD) != 0)
+	    error ("-mfloat128 requires VSX support");
 
-      rs6000_isa_flags &= ~(OPTION_MASK_FLOAT128 | OPTION_MASK_FLOAT128_HW);
+	  rs6000_isa_flags &= ~(OPTION_MASK_FLOAT128_TYPE
+				| OPTION_MASK_FLOAT128_KEYWORD
+				| OPTION_MASK_FLOAT128_HW);
+	}
+
+      else if (TARGET_FLOAT128_TYPE)
+	{
+	  if ((rs6000_isa_flags_explicit & OPTION_MASK_FLOAT128_TYPE) != 0)
+	    error ("-mfloat128-type requires VSX support");
+
+	  rs6000_isa_flags &= ~(OPTION_MASK_FLOAT128_TYPE
+				| OPTION_MASK_FLOAT128_KEYWORD
+				| OPTION_MASK_FLOAT128_HW);
+	}
     }
 
-  /* If we have -mfloat128 and full ISA 3.0 support, enable -mfloat128-hardware
-     by default.  */
-  if (TARGET_FLOAT128 && !TARGET_FLOAT128_HW
-      && (rs6000_isa_flags & ISA_3_0_MASKS_IEEE) == ISA_3_0_MASKS_IEEE
-      && !(rs6000_isa_flags_explicit & OPTION_MASK_FLOAT128_HW))
+  /* -mfloat128 and -mfloat128-hardware internally require the underlying IEEE
+      128-bit floating point support to be enabled.  */
+  if (!TARGET_FLOAT128_TYPE)
     {
-      rs6000_isa_flags |= OPTION_MASK_FLOAT128_HW;
-      if ((rs6000_isa_flags & OPTION_MASK_FLOAT128) != 0)
-	rs6000_isa_flags_explicit |= OPTION_MASK_FLOAT128_HW;
+      if (TARGET_FLOAT128_KEYWORD)
+	{
+	  if ((rs6000_isa_flags_explicit & OPTION_MASK_FLOAT128_KEYWORD) != 0)
+	    {
+	      error ("-mfloat128 requires -mfloat128-type");
+	      rs6000_isa_flags &= ~(OPTION_MASK_FLOAT128_TYPE
+				    | OPTION_MASK_FLOAT128_KEYWORD
+				    | OPTION_MASK_FLOAT128_HW);
+	    }
+	  else
+	    rs6000_isa_flags |= OPTION_MASK_FLOAT128_TYPE;
+	}
+
+      if (TARGET_FLOAT128_HW)
+	{
+	  if ((rs6000_isa_flags_explicit & OPTION_MASK_FLOAT128_HW) != 0)
+	    {
+	      error ("-mfloat128-hardware requires -mfloat128-type");
+	      rs6000_isa_flags &= ~OPTION_MASK_FLOAT128_HW;
+	    }
+	  else
+	    rs6000_isa_flags &= ~(OPTION_MASK_FLOAT128_TYPE
+				  | OPTION_MASK_FLOAT128_KEYWORD
+				  | OPTION_MASK_FLOAT128_HW);
+	}
     }
 
-  /* IEEE 128-bit floating point hardware instructions imply enabling
-     __float128.  */
+  /* If we have -mfloat128-type and full ISA 3.0 support, enable
+     -mfloat128-hardware by default.  However, don't enable the __float128
+     keyword.  If the user explicitly turned on -mfloat128-hardware, enable the
+     -mfloat128 option as well if it was not already set.  */
+  if (TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
+      && (rs6000_isa_flags & ISA_3_0_MASKS_IEEE) == ISA_3_0_MASKS_IEEE
+      && !(rs6000_isa_flags_explicit & OPTION_MASK_FLOAT128_HW))
+    rs6000_isa_flags |= OPTION_MASK_FLOAT128_HW;
+
   if (TARGET_FLOAT128_HW
       && (rs6000_isa_flags & ISA_3_0_MASKS_IEEE) != ISA_3_0_MASKS_IEEE)
     {
@@ -4436,9 +4507,10 @@ rs6000_option_override_internal (bool gl
       rs6000_isa_flags &= ~OPTION_MASK_FLOAT128_HW;
     }
 
-  if (TARGET_FLOAT128_HW
-      && (rs6000_isa_flags_explicit & OPTION_MASK_FLOAT128) == 0)
-    rs6000_isa_flags |= OPTION_MASK_FLOAT128;
+  if (TARGET_FLOAT128_HW && !TARGET_FLOAT128_KEYWORD
+      && (rs6000_isa_flags_explicit & OPTION_MASK_FLOAT128_HW) != 0
+      && (rs6000_isa_flags_explicit & OPTION_MASK_FLOAT128_KEYWORD) == 0)
+    rs6000_isa_flags |= OPTION_MASK_FLOAT128_KEYWORD;
 
   /* Print the options after updating the defaults.  */
   if (TARGET_DEBUG_REG || TARGET_DEBUG_TARGET)
@@ -4501,28 +4573,14 @@ rs6000_option_override_internal (bool gl
 	}
     }
 
-  if (!global_options_set.x_rs6000_long_double_type_size)
-    {
-      if (main_target_opt != NULL
-	  && (main_target_opt->x_rs6000_long_double_type_size
-	      != RS6000_DEFAULT_LONG_DOUBLE_SIZE))
-	error ("target attribute or pragma changes long double size");
-      else
-	rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
-    }
-
-#if !defined (POWERPC_LINUX) && !defined (POWERPC_FREEBSD)
-  if (!global_options_set.x_rs6000_ieeequad)
-    rs6000_ieeequad = 1;
-#endif
-
   /* Disable VSX and Altivec silently if the user switched cpus to power7 in a
      target attribute or pragma which automatically enables both options,
      unless the altivec ABI was set.  This is set by default for 64-bit, but
      not for 32-bit.  */
   if (main_target_opt != NULL && !main_target_opt->x_rs6000_altivec_abi)
     rs6000_isa_flags &= ~((OPTION_MASK_VSX | OPTION_MASK_ALTIVEC
-			   | OPTION_MASK_FLOAT128)
+			   | OPTION_MASK_FLOAT128_TYPE
+			   | OPTION_MASK_FLOAT128_KEYWORD)
 			  & ~rs6000_isa_flags_explicit);
 
   /* Enable Altivec ABI for AIX -maltivec.  */
@@ -16505,29 +16563,53 @@ rs6000_init_builtins (void)
      IFmode is the IBM extended 128-bit format that is a pair of doubles.
      TFmode will be either IEEE 128-bit floating point or the IBM double-double
      format that uses a pair of doubles, depending on the switches and
-     defaults.  */
-  if (TARGET_FLOAT128)
+     defaults.
+
+     We do not enable the actual __float128 keyword unless the user explicitly
+     asks for it, because the library support is not yet complete.
+
+     If we don't support for either 128-bit IBM double double or IEEE 128-bit
+     floating point, we need make sure the type is non-zero or else self-test
+     fails during bootstrap.
+
+     We don't register a built-in type for __ibm128 or __float128 if the type
+     is the same as long double.  Instead we add a #define for __ibm128 or
+     __float128 in rs6000_cpu_cpp_builtins to long double.  */
+  if (TARGET_IEEEQUAD || !TARGET_LONG_DOUBLE_128)
     {
       ibm128_float_type_node = make_node (REAL_TYPE);
       TYPE_PRECISION (ibm128_float_type_node) = 128;
       layout_type (ibm128_float_type_node);
       SET_TYPE_MODE (ibm128_float_type_node, IFmode);
 
-      ieee128_float_type_node = float128_type_node;
-
-      lang_hooks.types.register_builtin_type (ieee128_float_type_node,
-					      "__float128");
-
       lang_hooks.types.register_builtin_type (ibm128_float_type_node,
 					      "__ibm128");
     }
   else
+    ibm128_float_type_node = long_double_type_node;
+
+  if (TARGET_FLOAT128_KEYWORD)
     {
-      /* All types must be nonzero, or self-test barfs during bootstrap.  */
-      ieee128_float_type_node = long_double_type_node;
-      ibm128_float_type_node = long_double_type_node;
+      ieee128_float_type_node = float128_type_node;
+      if (!FLOAT128_IEEE_P (TFmode))
+	lang_hooks.types.register_builtin_type (ieee128_float_type_node,
+						"__float128");
     }
 
+  else if (TARGET_FLOAT128_TYPE)
+    {
+      ieee128_float_type_node = make_node (REAL_TYPE);
+      TYPE_PRECISION (ibm128_float_type_node) = 128;
+      layout_type (ieee128_float_type_node);
+      SET_TYPE_MODE (ieee128_float_type_node, KFmode);
+
+      lang_hooks.types.register_builtin_type (ieee128_float_type_node,
+					      "__ieee128");
+    }
+
+  else
+    ieee128_float_type_node = long_double_type_node;
+
   /* Initialize the modes for builtin_function_type, mapping a machine mode to
      tree type node.  */
   builtin_mode_to_type[QImode][0] = integer_type_node;
@@ -18316,7 +18398,7 @@ static void
 rs6000_init_libfuncs (void)
 {
   /* __float128 support.  */
-  if (TARGET_FLOAT128)
+  if (TARGET_FLOAT128_TYPE)
     {
       init_float128_ibm (IFmode);
       init_float128_ieee (KFmode);
@@ -33425,7 +33507,7 @@ rs6000_mangle_type (const_tree type)
   /* Use a unique name for __float128 rather than trying to use "e" or "g". Use
      "g" for IBM extended double, no matter whether it is long double (using
      -mabi=ibmlongdouble) or the distinct __ibm128 type.  */
-  if (TARGET_FLOAT128)
+  if (TARGET_FLOAT128_TYPE)
     {
       if (type == ieee128_float_type_node)
 	return "U10__float128";
@@ -36397,7 +36479,7 @@ rs6000_complex_function_value (machine_m
   machine_mode inner = GET_MODE_INNER (mode);
   unsigned int inner_bytes = GET_MODE_UNIT_SIZE (mode);
 
-  if (TARGET_FLOAT128
+  if (TARGET_FLOAT128_TYPE
       && (mode == KCmode
 	  || (mode == TCmode && TARGET_IEEEQUAD)))
     regno = ALTIVEC_ARG_RETURN;
@@ -36804,7 +36886,7 @@ rs6000_scalar_mode_supported_p (machine_
 
   if (DECIMAL_FLOAT_MODE_P (mode))
     return default_decimal_float_supported_p ();
-  else if (TARGET_FLOAT128 && (mode == KFmode || mode == IFmode))
+  else if (TARGET_FLOAT128_TYPE && (mode == KFmode || mode == IFmode))
     return true;
   else
     return default_scalar_mode_supported_p (mode);
@@ -36843,7 +36925,7 @@ rs6000_floatn_mode (int n, bool extended
 	  return DFmode;
 
 	case 64:
-	  if (TARGET_FLOAT128)
+	  if (TARGET_FLOAT128_KEYWORD)
 	    return (FLOAT128_IEEE_P (TFmode)) ? TFmode : KFmode;
 	  else
 	    return VOIDmode;
@@ -36867,7 +36949,7 @@ rs6000_floatn_mode (int n, bool extended
 	  return DFmode;
 
 	case 128:
-	  if (TARGET_FLOAT128)
+	  if (TARGET_FLOAT128_KEYWORD)
 	    return (FLOAT128_IEEE_P (TFmode)) ? TFmode : KFmode;
 	  else
 	    return VOIDmode;
@@ -36883,7 +36965,7 @@ rs6000_floatn_mode (int n, bool extended
 static machine_mode
 rs6000_c_mode_for_suffix (char suffix)
 {
-  if (TARGET_FLOAT128)
+  if (TARGET_FLOAT128_TYPE)
     {
       if (suffix == 'q' || suffix == 'Q')
 	return (FLOAT128_IEEE_P (TFmode)) ? TFmode : KFmode;
@@ -36984,7 +37066,8 @@ static struct rs6000_opt_mask const rs60
   { "dlmzb",			OPTION_MASK_DLMZB,		false, true  },
   { "efficient-unaligned-vsx",	OPTION_MASK_EFFICIENT_UNALIGNED_VSX,
 								false, true  },
-  { "float128",			OPTION_MASK_FLOAT128,		false, false },
+  { "float128",			OPTION_MASK_FLOAT128_KEYWORD,	false, false },
+  { "float128-type",		OPTION_MASK_FLOAT128_TYPE,	false, false },
   { "float128-hardware",	OPTION_MASK_FLOAT128_HW,	false, false },
   { "fprnd",			OPTION_MASK_FPRND,		false, true  },
   { "hard-dfp",			OPTION_MASK_DFP,		false, true  },
Index: gcc/config/rs6000/rs6000-cpus.def
===================================================================
--- gcc/config/rs6000/rs6000-cpus.def	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/config/rs6000)	(revision 240680)
+++ gcc/config/rs6000/rs6000-cpus.def	(.../gcc/config/rs6000)	(working copy)
@@ -103,7 +103,9 @@
 				 | OPTION_MASK_DIRECT_MOVE		\
 				 | OPTION_MASK_DLMZB			\
 				 | OPTION_MASK_EFFICIENT_UNALIGNED_VSX	\
-				 | OPTION_MASK_FLOAT128			\
+				 | OPTION_MASK_FLOAT128_HW		\
+				 | OPTION_MASK_FLOAT128_KEYWORD		\
+				 | OPTION_MASK_FLOAT128_TYPE		\
 				 | OPTION_MASK_FPRND			\
 				 | OPTION_MASK_HTM			\
 				 | OPTION_MASK_ISEL			\
Index: gcc/config/rs6000/rs6000.opt
===================================================================
--- gcc/config/rs6000/rs6000.opt	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/config/rs6000)	(revision 240680)
+++ gcc/config/rs6000/rs6000.opt	(.../gcc/config/rs6000)	(working copy)
@@ -645,8 +645,16 @@ mmodulo
 Target Undocumented Report Mask(MODULO) Var(rs6000_isa_flags)
 Generate the integer modulo instructions.
 
+; We want to enable the internal support for the IEEE 128-bit floating point
+; type without necessarily enabling the __float128 keyword.  This is to allow
+; Boost and other libraries that know about __float128 to work until the
+; official library support is finished.
+mfloat128-type
+Target Undocumented Mask(FLOAT128_TYPE) Var(rs6000_isa_flags)
+Allow the IEEE 128-bit types without requiring the __float128 keyword.
+
 mfloat128
-Target Report Mask(FLOAT128) Var(rs6000_isa_flags)
+Target Report Mask(FLOAT128_KEYWORD) Var(rs6000_isa_flags)
 Enable IEEE 128-bit floating point via the __float128 keyword.
 
 mfloat128-hardware
Index: gcc/config/rs6000/linux64.h
===================================================================
--- gcc/config/rs6000/linux64.h	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/config/rs6000)	(revision 240680)
+++ gcc/config/rs6000/linux64.h	(.../gcc/config/rs6000)	(working copy)
@@ -634,3 +634,9 @@ extern int dot_symbols;
   || (TARGET_GLIBC_MAJOR == 2 && TARGET_GLIBC_MINOR >= 19)
 #define RS6000_GLIBC_ATOMIC_FENV 1
 #endif
+
+/* The IEEE 128-bit emulator is only built on Linux systems.  Flag that we
+   should enable the type handling for KFmode on VSX systems even if we are not
+   enabling the __float128 keyword.  */
+#undef	TARGET_FLOAT128_ENABLE_TYPE
+#define TARGET_FLOAT128_ENABLE_TYPE 1
Index: gcc/config/rs6000/rs6000.h
===================================================================
--- gcc/config/rs6000/rs6000.h	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/config/rs6000)	(revision 240680)
+++ gcc/config/rs6000/rs6000.h	(.../gcc/config/rs6000)	(working copy)
@@ -363,6 +363,10 @@ extern const char *host_detect_local_cpu
 #define SET_TARGET_LINK_STACK(X) do { } while (0)
 #endif
 
+#ifndef TARGET_FLOAT128_ENABLE_TYPE
+#define TARGET_FLOAT128_ENABLE_TYPE 0
+#endif
+
 /* Return 1 for a symbol ref for a thread-local storage symbol.  */
 #define RS6000_SYMBOL_REF_TLS_P(RTX) \
   (GET_CODE (RTX) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (RTX) != 0)
@@ -449,12 +453,12 @@ extern const char *host_detect_local_cpu
 
 /* Helper macros to say whether a 128-bit floating point type can go in a
    single vector register, or whether it needs paired scalar values.  */
-#define FLOAT128_VECTOR_P(MODE) (TARGET_FLOAT128 && FLOAT128_IEEE_P (MODE))
+#define FLOAT128_VECTOR_P(MODE) (TARGET_FLOAT128_TYPE && FLOAT128_IEEE_P (MODE))
 
 #define FLOAT128_2REG_P(MODE)						\
   (FLOAT128_IBM_P (MODE)						\
    || ((MODE) == TDmode)						\
-   || (!TARGET_FLOAT128 && FLOAT128_IEEE_P (MODE)))
+   || (!TARGET_FLOAT128_TYPE && FLOAT128_IEEE_P (MODE)))
 
 /* Return true for floating point that does not use a vector register.  */
 #define SCALAR_FLOAT_MODE_NOT_VECTOR_P(MODE)				\
@@ -637,7 +641,7 @@ extern int rs6000_vector_align[];
 #define MASK_DIRECT_MOVE		OPTION_MASK_DIRECT_MOVE
 #define MASK_DLMZB			OPTION_MASK_DLMZB
 #define MASK_EABI			OPTION_MASK_EABI
-#define MASK_FLOAT128			OPTION_MASK_FLOAT128
+#define MASK_FLOAT128_TYPE		OPTION_MASK_FLOAT128_TYPE
 #define MASK_FPRND			OPTION_MASK_FPRND
 #define MASK_P8_FUSION			OPTION_MASK_P8_FUSION
 #define MASK_HARD_FLOAT			OPTION_MASK_HARD_FLOAT
@@ -1821,7 +1825,7 @@ extern enum reg_class rs6000_constraints
 			   : (FP_ARG_RETURN + AGGR_ARG_NUM_REG - 1))
 #define ALTIVEC_ARG_MAX_RETURN (DEFAULT_ABI != ABI_ELFv2		\
 				? (ALTIVEC_ARG_RETURN			\
-				   + (TARGET_FLOAT128 ? 1 : 0))		\
+				   + (TARGET_FLOAT128_TYPE ? 1 : 0))	\
 			        : (ALTIVEC_ARG_RETURN + AGGR_ARG_NUM_REG - 1))
 
 /* Flags for the call/call_value rtl operations set up by function_arg */
@@ -2728,7 +2732,7 @@ extern int frame_pointer_needed;
 #define RS6000_BTM_HARD_FLOAT	MASK_SOFT_FLOAT	/* Hardware floating point.  */
 #define RS6000_BTM_LDBL128	MASK_MULTIPLE	/* 128-bit long double.  */
 #define RS6000_BTM_64BIT	MASK_64BIT	/* 64-bit addressing.  */
-#define RS6000_BTM_FLOAT128	MASK_FLOAT128	/* IEEE 128-bit float.  */
+#define RS6000_BTM_FLOAT128	MASK_FLOAT128_TYPE /* IEEE 128-bit float.  */
 
 #define RS6000_BTM_COMMON	(RS6000_BTM_ALTIVEC			\
 				 | RS6000_BTM_VSX			\
@@ -2914,3 +2918,7 @@ extern GTY(()) tree rs6000_builtin_types
 extern GTY(()) tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT];
 
 #define TARGET_SUPPORTS_WIDE_INT 1
+
+#if (GCC_VERSION >= 3000)
+#pragma GCC poison TARGET_FLOAT128 OPTION_MASK_FLOAT128 MASK_FLOAT128
+#endif
Index: gcc/config/rs6000/rs6000.md
===================================================================
--- gcc/config/rs6000/rs6000.md	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/config/rs6000)	(revision 240680)
+++ gcc/config/rs6000/rs6000.md	(.../gcc/config/rs6000)	(working copy)
@@ -376,8 +376,8 @@ (define_mode_iterator FP [
   (TF "TARGET_HARD_FLOAT
    && (TARGET_FPRS || TARGET_E500_DOUBLE)
    && TARGET_LONG_DOUBLE_128")
-  (IF "TARGET_FLOAT128")
-  (KF "TARGET_FLOAT128")
+  (IF "TARGET_LONG_DOUBLE_128")
+  (KF "TARGET_FLOAT128_TYPE")
   (DD "TARGET_DFP")
   (TD "TARGET_DFP")])
 
@@ -506,8 +506,8 @@ (define_mode_iterator IEEE128 [(KF "FLOA
 			       (TF "FLOAT128_IEEE_P (TFmode)")])
 
 ; Iterator for 128-bit floating point
-(define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128")
-				(IF "TARGET_FLOAT128")
+(define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
+				(IF "TARGET_FLOAT128_TYPE")
 				(TF "TARGET_LONG_DOUBLE_128")])
 
 ; Iterator for signbit on 64-bit machines with direct move
@@ -7298,7 +7298,7 @@ (define_insn_and_split "*fix_trunc<mode>
 (define_expand "fix_trunc<mode>di2"
   [(set (match_operand:DI 0 "gpc_reg_operand" "")
 	(fix:DI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
-  "TARGET_FLOAT128"
+  "TARGET_FLOAT128_TYPE"
 {
   rs6000_expand_float128_convert (operands[0], operands[1], false);
   DONE;
@@ -7307,7 +7307,7 @@ (define_expand "fix_trunc<mode>di2"
 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
 	(unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
-  "TARGET_FLOAT128"
+  "TARGET_FLOAT128_TYPE"
 {
   rs6000_expand_float128_convert (operands[0], operands[1], true);
   DONE;
@@ -7316,7 +7316,7 @@ (define_expand "fixuns_trunc<IEEE128:mod
 (define_expand "floatdi<mode>2"
   [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
 	(float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
-  "TARGET_FLOAT128"
+  "TARGET_FLOAT128_TYPE"
 {
   rs6000_expand_float128_convert (operands[0], operands[1], false);
   DONE;
@@ -7325,7 +7325,7 @@ (define_expand "floatdi<mode>2"
 (define_expand "floatuns<SDI:mode><IEEE128:mode>2"
   [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
 	(unsigned_float:IEEE128 (match_operand:SDI 1 "gpc_reg_operand" "")))]
-  "TARGET_FLOAT128"
+  "TARGET_FLOAT128_TYPE"
 {
   rs6000_expand_float128_convert (operands[0], operands[1], true);
   DONE;
@@ -7351,7 +7351,7 @@ (define_expand "neg<mode>2"
 	  else
 	    gcc_unreachable ();
 	}
-      else if (TARGET_FLOAT128)
+      else if (TARGET_FLOAT128_TYPE)
 	{
 	  if (<MODE>mode == TFmode)
 	    emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
@@ -7411,7 +7411,7 @@ (define_expand "abs<mode>2"
 	    FAIL;
 	  DONE;
 	}
-      else if (TARGET_FLOAT128)
+      else if (TARGET_FLOAT128_TYPE)
 	{
 	  if (<MODE>mode == TFmode)
 	    emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
@@ -7471,7 +7471,7 @@ (define_expand "abs<mode>2_internal"
 
 (define_expand "ieee_128bit_negative_zero"
   [(set (match_operand:V16QI 0 "register_operand" "") (match_dup 1))]
-  "TARGET_FLOAT128"
+  "TARGET_FLOAT128_TYPE"
 {
   rtvec v = rtvec_alloc (16);
   int i, high;
@@ -7498,7 +7498,7 @@ (define_insn_and_split "ieee_128bit_vsx_
   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
 	(neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
    (clobber (match_scratch:V16QI 2 "=v"))]
-  "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
+  "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
   "#"
   "&& 1"
   [(parallel [(set (match_dup 0)
@@ -7518,7 +7518,7 @@ (define_insn "*ieee_128bit_vsx_neg<mode>
   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
 	(neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
    (use (match_operand:V16QI 2 "register_operand" "v"))]
-  "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
+  "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
   "xxlxor %x0,%x1,%x2"
   [(set_attr "type" "veclogical")])
 
@@ -7527,7 +7527,7 @@ (define_insn_and_split "ieee_128bit_vsx_
   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
 	(abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
    (clobber (match_scratch:V16QI 2 "=v"))]
-  "TARGET_FLOAT128 && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
+  "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
   "#"
   "&& 1"
   [(parallel [(set (match_dup 0)
@@ -7547,7 +7547,7 @@ (define_insn "*ieee_128bit_vsx_abs<mode>
   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
 	(abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
    (use (match_operand:V16QI 2 "register_operand" "v"))]
-  "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
+  "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
   "xxlandc %x0,%x1,%x2"
   [(set_attr "type" "veclogical")])
 
@@ -7558,7 +7558,8 @@ (define_insn_and_split "*ieee_128bit_vsx
 	 (abs:IEEE128
 	  (match_operand:IEEE128 1 "register_operand" "wa"))))
    (clobber (match_scratch:V16QI 2 "=v"))]
-  "TARGET_FLOAT128 && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
+  "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
+   && FLOAT128_IEEE_P (<MODE>mode)"
   "#"
   "&& 1"
   [(parallel [(set (match_dup 0)
@@ -7580,7 +7581,7 @@ (define_insn "*ieee_128bit_vsx_nabs<mode
 	 (abs:IEEE128
 	  (match_operand:IEEE128 1 "register_operand" "wa"))))
    (use (match_operand:V16QI 2 "register_operand" "v"))]
-  "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
+  "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
   "xxlor %x0,%x1,%x2"
   [(set_attr "type" "veclogical")])
 
@@ -7590,7 +7591,7 @@ (define_insn "*ieee_128bit_vsx_nabs<mode
 (define_expand "extendiftf2"
   [(set (match_operand:TF 0 "gpc_reg_operand" "")
 	(float_extend:TF (match_operand:IF 1 "gpc_reg_operand" "")))]
-  "TARGET_FLOAT128"
+  "TARGET_FLOAT128_TYPE"
 {
   rs6000_expand_float128_convert (operands[0], operands[1], false);
   DONE;
@@ -7599,7 +7600,7 @@ (define_expand "extendiftf2"
 (define_expand "extendifkf2"
   [(set (match_operand:KF 0 "gpc_reg_operand" "")
 	(float_extend:KF (match_operand:IF 1 "gpc_reg_operand" "")))]
-  "TARGET_FLOAT128"
+  "TARGET_FLOAT128_TYPE"
 {
   rs6000_expand_float128_convert (operands[0], operands[1], false);
   DONE;
@@ -7608,7 +7609,7 @@ (define_expand "extendifkf2"
 (define_expand "extendtfkf2"
   [(set (match_operand:KF 0 "gpc_reg_operand" "")
 	(float_extend:KF (match_operand:TF 1 "gpc_reg_operand" "")))]
-  "TARGET_FLOAT128"
+  "TARGET_FLOAT128_TYPE"
 {
   rs6000_expand_float128_convert (operands[0], operands[1], false);
   DONE;
@@ -7617,7 +7618,7 @@ (define_expand "extendtfkf2"
 (define_expand "trunciftf2"
   [(set (match_operand:IF 0 "gpc_reg_operand" "")
 	(float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
-  "TARGET_FLOAT128"
+  "TARGET_FLOAT128_TYPE"
 {
   rs6000_expand_float128_convert (operands[0], operands[1], false);
   DONE;
@@ -7626,7 +7627,7 @@ (define_expand "trunciftf2"
 (define_expand "truncifkf2"
   [(set (match_operand:IF 0 "gpc_reg_operand" "")
 	(float_truncate:IF (match_operand:KF 1 "gpc_reg_operand" "")))]
-  "TARGET_FLOAT128"
+  "TARGET_FLOAT128_TYPE"
 {
   rs6000_expand_float128_convert (operands[0], operands[1], false);
   DONE;
@@ -7635,7 +7636,7 @@ (define_expand "truncifkf2"
 (define_expand "trunckftf2"
   [(set (match_operand:TF 0 "gpc_reg_operand" "")
 	(float_truncate:TF (match_operand:KF 1 "gpc_reg_operand" "")))]
-  "TARGET_FLOAT128"
+  "TARGET_FLOAT128_TYPE"
 {
   rs6000_expand_float128_convert (operands[0], operands[1], false);
   DONE;
@@ -7644,7 +7645,7 @@ (define_expand "trunckftf2"
 (define_expand "trunctfif2"
   [(set (match_operand:IF 0 "gpc_reg_operand" "")
 	(float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
-  "TARGET_FLOAT128"
+  "TARGET_FLOAT128_TYPE"
 {
   rs6000_expand_float128_convert (operands[0], operands[1], false);
   DONE;
@@ -13724,7 +13725,7 @@ (define_insn "extend<SFDF:mode><IEEE128:
 (define_insn_and_split "extendkftf2"
   [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
 	(float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
-  "TARGET_FLOAT128 && TARGET_IEEEQUAD"
+  "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
   "@
    #
    xxlor %x0,%x1,%x1"
@@ -13740,7 +13741,7 @@ (define_insn_and_split "extendkftf2"
 (define_insn_and_split "trunctfkf2"
   [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
 	(float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
-  "TARGET_FLOAT128 && TARGET_IEEEQUAD"
+  "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
   "@
    #
    xxlor %x0,%x1,%x1"
Index: gcc/testsuite/gcc.target/powerpc/float128-mix.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/float128-mix.c	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/testsuite/gcc.target/powerpc)	(revision 240680)
+++ gcc/testsuite/gcc.target/powerpc/float128-mix.c	(.../gcc/testsuite/gcc.target/powerpc)	(working copy)
@@ -4,13 +4,13 @@
 /* { dg-options "-O2 -mcpu=power7 -mfloat128" } */
 
 
-/* Test to make sure that __float128 and __ibm128 cannot be combined together.  */
-__float128 add (__float128 a, __ibm128 b)
+/* Test to make sure that __float128 and long double cannot be combined together.  */
+__float128 add (__float128 a, long double b)
 {
-  return a+b;	/* { dg-error "__float128 and __ibm128 cannot be used in the same expression" "" } */
+  return a+b;	/* { dg-error "__float128 and long double cannot be used in the same expression" "" } */
 }
 
-__ibm128 sub (__ibm128 a, __float128 b)
+__ibm128 sub (long double a, __float128 b)
 {
-  return a-b;	/* { dg-error "__float128 and __ibm128 cannot be used in the same expression" "" } */
+  return a-b;	/* { dg-error "__float128 and long double cannot be used in the same expression" "" } */
 }
Index: gcc/testsuite/gcc.target/powerpc/float128-type-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/float128-type-1.c	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/testsuite/gcc.target/powerpc)	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/float128-type-1.c	(.../gcc/testsuite/gcc.target/powerpc)	(revision 240728)
@@ -0,0 +1,24 @@
+/* { dg-do compile { target { powerpc64*-*-linux* && lp64 } } } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
+/* { dg-options "-mcpu=power8 -O2" } */
+
+/* -mfloat128-type is enabled by default on VSX Linux 64-bit systems.  */
+
+typedef double          __attribute__((__mode__(__KF__))) f128_t;
+typedef _Complex double __attribute__((__mode__(__KC__))) f128c_t;
+
+f128_t
+add_scalar (f128_t a, f128_t b)
+{
+  return a+b;
+}
+
+
+f128c_t
+add_complex (f128c_t a, f128c_t b)
+{
+  return a+b;
+}
+
+/* { dg-final { scan-assembler "bl __addkf3" } } */
Index: gcc/testsuite/gcc.target/powerpc/float128-type-2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/float128-type-2.c	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/testsuite/gcc.target/powerpc)	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/float128-type-2.c	(.../gcc/testsuite/gcc.target/powerpc)	(revision 240728)
@@ -0,0 +1,26 @@
+/* { dg-do compile { target { powerpc64-*-linux* && lp64 } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-options "-mcpu=power9 -O2" } */
+
+/* -mfloat128-type is enabled by default on VSX Linux 64-bit systems.  */
+/* Note, do not use effective target powerpc_float128_hw_ok, as that
+   will pass -mfloat128.  */
+
+typedef double          __attribute__((__mode__(__KF__))) f128_t;
+typedef _Complex double __attribute__((__mode__(__KC__))) f128c_t;
+
+f128_t
+add_scalar (f128_t a, f128_t b)
+{
+  return a+b;
+}
+
+
+f128c_t
+add_complex (f128c_t a, f128c_t b)
+{
+  return a+b;
+}
+
+/* { dg-final { scan-assembler "xsaddqp" } } */
