From 082139830afb428628657a7520659a01ae00b852 Mon Sep 17 00:00:00 2001 From: Michael Meissner Date: Fri, 7 Oct 2016 18:58:10 +0000 Subject: [PATCH] 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 * 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_truncdi2): Likewise. (fixuns_trunc2): Likewise. (floatdi2): Likewise. (floatuns2): Likewise. (neg2, FLOAT128 iterator): Likewise. (abs2, FLOAT128 iterator): Likewise. (ieee_128bit_negative_zero): Likewise. (ieee_128bit_vsx_neg2): Likewise. (ieee_128bit_vsx_neg2_internal): Likewise. (ieee_128bit_vsx_abs2): Likewise. (ieee_128bit_vsx_abs2_internal): Likewise. (ieee_128bit_vsx_nabs2): Likewise. (ieee_128bit_vsx_nabs2_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 * 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 --- gcc/ChangeLog | 74 ++++++++ gcc/config/rs6000/linux64.h | 6 + gcc/config/rs6000/rs6000-c.c | 12 +- gcc/config/rs6000/rs6000-cpus.def | 4 +- gcc/config/rs6000/rs6000.c | 195 +++++++++++++++------ gcc/config/rs6000/rs6000.h | 18 +- gcc/config/rs6000/rs6000.md | 53 +++--- gcc/config/rs6000/rs6000.opt | 10 +- gcc/testsuite/ChangeLog | 8 + gcc/testsuite/gcc.target/powerpc/float128-mix.c | 10 +- gcc/testsuite/gcc.target/powerpc/float128-type-1.c | 28 +++ gcc/testsuite/gcc.target/powerpc/float128-type-2.c | 31 ++++ 12 files changed, 355 insertions(+), 94 deletions(-) create mode 100644 gcc/testsuite/gcc.target/powerpc/float128-type-1.c create mode 100644 gcc/testsuite/gcc.target/powerpc/float128-type-2.c 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 + + * 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_truncdi2): Likewise. + (fixuns_trunc2): Likewise. + (floatdi2): Likewise. + (floatuns2): Likewise. + (neg2, FLOAT128 iterator): Likewise. + (abs2, FLOAT128 iterator): Likewise. + (ieee_128bit_negative_zero): Likewise. + (ieee_128bit_vsx_neg2): Likewise. + (ieee_128bit_vsx_neg2_internal): Likewise. + (ieee_128bit_vsx_abs2): Likewise. + (ieee_128bit_vsx_abs2_internal): Likewise. + (ieee_128bit_vsx_nabs2): Likewise. + (ieee_128bit_vsx_nabs2_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 * 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_truncdi2" [(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_trunc2" [(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 "floatdi2" [(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 "floatuns2" [(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 == 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 == 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)" + "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (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)" + "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW + && FLOAT128_IEEE_P (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 + + * 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 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" } } */ -- 2.7.4