aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMichael Meissner <meissner@linux.vnet.ibm.com>2016-10-07 18:58:10 +0000
committerMichael Meissner <meissner@gcc.gnu.org>2016-10-07 18:58:10 +0000
commit082139830afb428628657a7520659a01ae00b852 (patch)
tree06618651cecee32e28ec0288e0bdba5a7c6527ad /gcc
parentbd845c14b7aa666b5f7d453fa928551506df0ffa (diff)
downloadgcc-082139830afb428628657a7520659a01ae00b852.zip
gcc-082139830afb428628657a7520659a01ae00b852.tar.gz
gcc-082139830afb428628657a7520659a01ae00b852.tar.bz2
rs6000-c.c (rs6000_cpu_cpp_builtins): Split -mfloat128 into -mfloat128-type that enables the IEEE 128-bit floating...
[gcc] 2016-10-06 Michael Meissner <meissner@linux.vnet.ibm.com> * config/rs6000/rs6000-c.c (rs6000_cpu_cpp_builtins): Split -mfloat128 into -mfloat128-type that enables the IEEE 128-bit floating point type infrastructre, and -mfloat128 that enables the keyword. Define __FLOAT128__ if -mfloat128, and __FLOAT128_TYPE__ if -mfloat128-type. Define __ibm128 to be long double by default. * config/rs6000/rs6000.c (rs6000_debug_reg_global): Print whether the IEEE 128-bit floating point type infrastructure should automatically be enabled. (rs6000_init_hard_regno_mode_ok): Switch to use -mfloat128-type instead of -mfloat128 to enable KFmode. (rs6000_option_override_internal): Split the option -mfloat128 into -mfloat128-type and -mfloat128. On Linux PowerPC 64-bit systems, automatically set -mfloat128-type, but don't enable it on other operating systems. Move setting the long double size and IEEE quad support before the IEEE 128-bit floating point changes. (rs6000_init_builtins): Do not create a unique type for __ibm128 if long double is IBM extended double, instead rely on __ibm128 being defined as 'long double'. If -mfloat128-type and not -mfloat128, create the KFmode type with an undocumented __ieee128 keyword. (rs6000_init_libfuncs): Use -mfloat128-type instead of -mfloat128 for tests about the types, but keep tests for -mfloat128 to enable the keyword support. (rs6000_complex_function_value): Likewise. (rs6000_scalar_mode_supported_p): Likewise. (rs6000_floatn_mode): Likewise. (rs6000_c_mode_for_suffix): Likewise. (rs6000_opt_masks): Add -mfloat128-type. * config/rs6000/rs6000-cpus.def (POWERPC_MASKS): Add support for -mfloat128-type being split from -mfloat128. Add -mfloat128-hardware, which was missing. * config/rs6000/rs6000.opt (-mfloat128): Split -mfloat128 into -mfloat128 and -mfloat128-type: (-mfloat128-type): Likewise. * config/rs6000/linux64.h (TARGET_FLOAT128_ENABLE_TYPE): Define so that 64-bit Linux systems with enable -mfloat128-type by default on VSX systems. * config/rs6000/rs6000.h (TARGET_FLOAT128_ENABLE_TYPE): Likewise. (FLOAT128_VECTOR_P): Switch IEEE 128-bit floating points to use -mfloat128-type instead of -mfloat128. (FLOAT128_2REG_P): Likewise. (MASK_FLOAT128_TYPE): Likewise. (ALTIVEC_ARG_MAX_RETURN): Likewise. (RS6000_BTM_FLOAT128): Likewise. (TARGET_FLOAT128): Poison old identifiers. (OPTION_MASK_FLOAT128): Likewise. (MASK_FLOAT128): Likewise. * config/rs6000/rs6000.md (FP): Likewise. (FLOAT128): Likewise. (fix_trunc<mode>di2): Likewise. (fixuns_trunc<IEEE128:mode><SDI:mode>2): Likewise. (floatdi<mode>2): Likewise. (floatuns<SDI:mode><IEEE128:mode>2): Likewise. (neg<mode>2, FLOAT128 iterator): Likewise. (abs<mode>2, FLOAT128 iterator): Likewise. (ieee_128bit_negative_zero): Likewise. (ieee_128bit_vsx_neg<mode>2): Likewise. (ieee_128bit_vsx_neg<mode>2_internal): Likewise. (ieee_128bit_vsx_abs<mode>2): Likewise. (ieee_128bit_vsx_abs<mode>2_internal): Likewise. (ieee_128bit_vsx_nabs<mode>2): Likewise. (ieee_128bit_vsx_nabs<mode>2_internal): Likewise. (extendiftf2): Likewise. (extendifkf2): Likewise. (extendtfkf2): Likewise. (trunciftf2): Likewise. (truncifkf2): Likewise. (trunckftf2): Likewise. (trunctfif2): Likewise. (extendkftf2): Likewise. (trunctfkf2): Likewise. [gcc/testsuite] 2016-10-06 Michael Meissner <meissner@linux.vnet.ibm.com> * gcc.target/powerpc/float128-type-1.c: New test to check that PowerPC 64-bit Linux enables -mfloat128-type by default. * gcc.target/powerpc/float128-type-2.c: Likewise. * gcc.target/powerpc/float128-mix.c: Change error message to reflect that __ibm128 is now #define'ed to be long double. From-SVN: r240872
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog74
-rw-r--r--gcc/config/rs6000/linux64.h6
-rw-r--r--gcc/config/rs6000/rs6000-c.c12
-rw-r--r--gcc/config/rs6000/rs6000-cpus.def4
-rw-r--r--gcc/config/rs6000/rs6000.c195
-rw-r--r--gcc/config/rs6000/rs6000.h18
-rw-r--r--gcc/config/rs6000/rs6000.md53
-rw-r--r--gcc/config/rs6000/rs6000.opt10
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/gcc.target/powerpc/float128-mix.c10
-rw-r--r--gcc/testsuite/gcc.target/powerpc/float128-type-1.c28
-rw-r--r--gcc/testsuite/gcc.target/powerpc/float128-type-2.c31
12 files changed, 355 insertions, 94 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fe68253..8c873c3 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,77 @@
+2016-10-06 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ * config/rs6000/rs6000-c.c (rs6000_cpu_cpp_builtins): Split
+ -mfloat128 into -mfloat128-type that enables the IEEE 128-bit
+ floating point type infrastructre, and -mfloat128 that enables the
+ keyword. Define __FLOAT128__ if -mfloat128, and __FLOAT128_TYPE__
+ if -mfloat128-type. Define __ibm128 to be long double by default.
+ * config/rs6000/rs6000.c (rs6000_debug_reg_global): Print whether
+ the IEEE 128-bit floating point type infrastructure should
+ automatically be enabled.
+ (rs6000_init_hard_regno_mode_ok): Switch to use -mfloat128-type
+ instead of -mfloat128 to enable KFmode.
+ (rs6000_option_override_internal): Split the option -mfloat128
+ into -mfloat128-type and -mfloat128. On Linux PowerPC 64-bit
+ systems, automatically set -mfloat128-type, but don't enable it on
+ other operating systems. Move setting the long double size and
+ IEEE quad support before the IEEE 128-bit floating point changes.
+ (rs6000_init_builtins): Do not create a unique type for __ibm128
+ if long double is IBM extended double, instead rely on __ibm128
+ being defined as 'long double'. If -mfloat128-type and not
+ -mfloat128, create the KFmode type with an undocumented __ieee128
+ keyword.
+ (rs6000_init_libfuncs): Use -mfloat128-type instead of
+ -mfloat128 for tests about the types, but keep tests for
+ -mfloat128 to enable the keyword support.
+ (rs6000_complex_function_value): Likewise.
+ (rs6000_scalar_mode_supported_p): Likewise.
+ (rs6000_floatn_mode): Likewise.
+ (rs6000_c_mode_for_suffix): Likewise.
+ (rs6000_opt_masks): Add -mfloat128-type.
+ * config/rs6000/rs6000-cpus.def (POWERPC_MASKS): Add support for
+ -mfloat128-type being split from -mfloat128. Add
+ -mfloat128-hardware, which was missing.
+ * config/rs6000/rs6000.opt (-mfloat128): Split -mfloat128 into
+ -mfloat128 and -mfloat128-type:
+ (-mfloat128-type): Likewise.
+ * config/rs6000/linux64.h (TARGET_FLOAT128_ENABLE_TYPE): Define so
+ that 64-bit Linux systems with enable -mfloat128-type by default
+ on VSX systems.
+ * config/rs6000/rs6000.h (TARGET_FLOAT128_ENABLE_TYPE): Likewise.
+ (FLOAT128_VECTOR_P): Switch IEEE 128-bit floating points to use
+ -mfloat128-type instead of -mfloat128.
+ (FLOAT128_2REG_P): Likewise.
+ (MASK_FLOAT128_TYPE): Likewise.
+ (ALTIVEC_ARG_MAX_RETURN): Likewise.
+ (RS6000_BTM_FLOAT128): Likewise.
+ (TARGET_FLOAT128): Poison old identifiers.
+ (OPTION_MASK_FLOAT128): Likewise.
+ (MASK_FLOAT128): Likewise.
+ * config/rs6000/rs6000.md (FP): Likewise.
+ (FLOAT128): Likewise.
+ (fix_trunc<mode>di2): Likewise.
+ (fixuns_trunc<IEEE128:mode><SDI:mode>2): Likewise.
+ (floatdi<mode>2): Likewise.
+ (floatuns<SDI:mode><IEEE128:mode>2): Likewise.
+ (neg<mode>2, FLOAT128 iterator): Likewise.
+ (abs<mode>2, FLOAT128 iterator): Likewise.
+ (ieee_128bit_negative_zero): Likewise.
+ (ieee_128bit_vsx_neg<mode>2): Likewise.
+ (ieee_128bit_vsx_neg<mode>2_internal): Likewise.
+ (ieee_128bit_vsx_abs<mode>2): Likewise.
+ (ieee_128bit_vsx_abs<mode>2_internal): Likewise.
+ (ieee_128bit_vsx_nabs<mode>2): Likewise.
+ (ieee_128bit_vsx_nabs<mode>2_internal): Likewise.
+ (extendiftf2): Likewise.
+ (extendifkf2): Likewise.
+ (extendtfkf2): Likewise.
+ (trunciftf2): Likewise.
+ (truncifkf2): Likewise.
+ (trunckftf2): Likewise.
+ (trunctfif2): Likewise.
+ (extendkftf2): Likewise.
+ (trunctfkf2): Likewise.
+
2016-10-07 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* simplify-rtx.c (simplify_immed_subreg): Zero-initialize tmp array
diff --git a/gcc/config/rs6000/linux64.h b/gcc/config/rs6000/linux64.h
index e86b5d5..0101ec0 100644
--- a/gcc/config/rs6000/linux64.h
+++ b/gcc/config/rs6000/linux64.h
@@ -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
diff --git a/gcc/config/rs6000/rs6000-c.c b/gcc/config/rs6000/rs6000-c.c
index 8dfb53f..c98a54f 100644
--- a/gcc/config/rs6000/rs6000-c.c
+++ b/gcc/config/rs6000/rs6000-c.c
@@ -425,10 +425,20 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfile)
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 && FLOAT128_IBM_P (TFmode))
+ builtin_define ("__ibm128=long double");
+
+ /* We needed to create a keyword if -mfloat128-type was used but not -mfloat,
+ so we used __ieee128. If -mfloat128 was used, create a #define back to
+ the real keyword in case somebody used it. */
+ if (TARGET_FLOAT128_KEYWORD)
+ builtin_define ("__ieee128=__float128");
if (TARGET_EXTRA_BUILTINS && cpp_get_options (pfile)->lang != CLK_ASM)
{
diff --git a/gcc/config/rs6000/rs6000-cpus.def b/gcc/config/rs6000/rs6000-cpus.def
index 401088f..e1786b2 100644
--- a/gcc/config/rs6000/rs6000-cpus.def
+++ b/gcc/config/rs6000/rs6000-cpus.def
@@ -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 \
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index e7e551d..49da4b6 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -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 global_init_p)
/* 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 global_init_p)
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 global_init_p)
}
}
- /* __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 ((rs6000_isa_flags_explicit & OPTION_MASK_FLOAT128) != 0)
- error ("-mfloat128 requires VSX support");
+ 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 (TARGET_FLOAT128_KEYWORD)
+ {
+ if ((rs6000_isa_flags_explicit & OPTION_MASK_FLOAT128_KEYWORD) != 0)
+ error ("-mfloat128 requires VSX support");
+
+ 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 | OPTION_MASK_FLOAT128_HW);
+ 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 global_init_p)
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 global_init_p)
}
}
- 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,55 @@ 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)
+ {
+ ieee128_float_type_node = float128_type_node;
+ lang_hooks.types.register_builtin_type (ieee128_float_type_node,
+ "__float128");
+ }
+
+ else if (TARGET_FLOAT128_TYPE)
{
- /* 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 = 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);
+
+ /* If we are not exporting the __float128/_Float128 keywords, we need a
+ keyword to get the types created. Use __ieee128 as the dummy
+ keyword. */
+ 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 +18400,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 +33509,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 +36481,7 @@ rs6000_complex_function_value (machine_mode mode)
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 +36888,7 @@ rs6000_scalar_mode_supported_p (machine_mode mode)
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 +36927,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 +36951,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 +36967,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 +37068,8 @@ static struct rs6000_opt_mask const rs6000_opt_masks[] =
{ "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 },
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 446d388..ad58193 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -363,6 +363,10 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
#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 (int argc, const char **argv);
/* 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[RS6000_CONSTRAINT_MAX];
: (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[RS6000_BTI_MAX];
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
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index a9fabc1..e432a5a 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -376,8 +376,8 @@
(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 @@
(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_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 "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 "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 "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 @@
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 @@
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 "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 @@
[(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 @@
[(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 @@
[(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 @@
[(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 @@
(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 @@
(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_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 "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 "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 "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 "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 "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 "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_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 "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"
diff --git a/gcc/config/rs6000/rs6000.opt b/gcc/config/rs6000/rs6000.opt
index c79a439..3e0717d 100644
--- a/gcc/config/rs6000/rs6000.opt
+++ b/gcc/config/rs6000/rs6000.opt
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index a0fedff..0aa90ee 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,11 @@
+2016-10-06 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ * gcc.target/powerpc/float128-type-1.c: New test to check that
+ PowerPC 64-bit Linux enables -mfloat128-type by default.
+ * gcc.target/powerpc/float128-type-2.c: Likewise.
+ * gcc.target/powerpc/float128-mix.c: Change error message to
+ reflect that __ibm128 is now #define'ed to be long double.
+
2016-10-07 Steven G. Kargl <kargl@gcc.gnu.org>
PR fortran/77406
diff --git a/gcc/testsuite/gcc.target/powerpc/float128-mix.c b/gcc/testsuite/gcc.target/powerpc/float128-mix.c
index 23cb9d5..d0cac202 100644
--- a/gcc/testsuite/gcc.target/powerpc/float128-mix.c
+++ b/gcc/testsuite/gcc.target/powerpc/float128-mix.c
@@ -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" "" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/float128-type-1.c b/gcc/testsuite/gcc.target/powerpc/float128-type-1.c
new file mode 100644
index 0000000..a8326bd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/float128-type-1.c
@@ -0,0 +1,28 @@
+/* { 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" } */
+
+/* This test tests whether -mfloat128-type (which enables the underlying IEEE
+ 128-bit floating point) is enabled by default on VSX Linux 64-bit systems,
+ even if the keywords __float128 and _Float128 (-mfloat128) are not enabled
+ via the -mfloat128 switch. Test that power8 generates a call to the
+ __addkf3 emulation function. */
+
+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" } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/float128-type-2.c b/gcc/testsuite/gcc.target/powerpc/float128-type-2.c
new file mode 100644
index 0000000..c5d6e35
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/float128-type-2.c
@@ -0,0 +1,31 @@
+/* { 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" } */
+
+/* This test tests whether -mfloat128-type (which enables the underlying IEEE
+ 128-bit floating point) is enabled by default on VSX Linux 64-bit systems,
+ even if the keywords __float128 and _Float128 (-mfloat128) are not enabled
+ via the -mfloat128 switch. Test that power9 generates the xsaddqp
+ instruction. */
+
+/* The effective target powerpc_float128_hw_ok is not used, 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" } } */