diff options
author | Michael Meissner <meissner@linux.ibm.com> | 2018-06-06 21:11:15 +0000 |
---|---|---|
committer | Michael Meissner <meissner@gcc.gnu.org> | 2018-06-06 21:11:15 +0000 |
commit | c765c8cb73b0bb91e9f0401ab6567b6218b910e5 (patch) | |
tree | 275dcfb6667d7feb398c5115a168ec6bb4c1016b | |
parent | 9d67f13e6afe013a65c1e910bf8fdda976dcd1ad (diff) | |
download | gcc-c765c8cb73b0bb91e9f0401ab6567b6218b910e5.zip gcc-c765c8cb73b0bb91e9f0401ab6567b6218b910e5.tar.gz gcc-c765c8cb73b0bb91e9f0401ab6567b6218b910e5.tar.bz2 |
re PR target/85657 (Make __ibm128 a separate type, even if long double uses the IBM double-double format)
[gcc]
2018-06-06 Michael Meissner <meissner@linux.ibm.com>
* config/rs6000/rs6000.c (rs6000_passes_ieee128): New boolean to
track if we pass or return IEEE 128-bit floating point.
(ieee128_mangling_gcc_8_1): New boolean to say whether to generate
C++ mangling that is compatible with GCC 8.1.
(TARGET_ASM_GLOBALIZE_DECL_NAME): Override target hook.
(init_cumulative_args): Note if we pass or return IEEE 128-bit
floating point types.
(rs6000_function_arg_advance_1): Likewise.
(rs6000_mangle_type): Optionally generate mangled names that match
what GCC 8.1 generated for IEEE 128-bit floating point types.
(rs6000_globalize_decl_name): If we have an external function that
passes or returns IEEE 128-bit types, generate a weak reference
from the mangled name used in GCC 8.1 to the current mangled
name.
[gcc]
2018-06-05 Michael Meissner <meissner@linux.ibm.com>
* config/rs6000/rs6000.c (rs6000_init_builtins): Make __ibm128 use
the long double type if long double is IBM extended double. Make
__float128 use the long double type if long double is IEEE 128-bit.
[gcc/testsuite]
2018-06-05 Michael Meissner <meissner@linux.ibm.com>
PR target/85657
* g++.dg/pr85657.C: Only test whether __ibm128 and long double can
be used in templates. Don't check for them in overloaded functions.
From-SVN: r261246
-rw-r--r-- | gcc/ChangeLog | 20 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 81 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/pr85657.C | 27 |
4 files changed, 103 insertions, 31 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bf56e89..f82ccb3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,23 @@ +2018-06-05 Michael Meissner <meissner@linux.ibm.com> + + * config/rs6000/rs6000.c (rs6000_passes_ieee128): New boolean to + track if we pass or return IEEE 128-bit floating point. + (ieee128_mangling_gcc_8_1): New boolean to say whether to generate + C++ mangling that is compatible with GCC 8.1. + (TARGET_ASM_GLOBALIZE_DECL_NAME): Override target hook. + (init_cumulative_args): Note if we pass or return IEEE 128-bit + floating point types. + (rs6000_function_arg_advance_1): Likewise. + (rs6000_mangle_type): Optionally generate mangled names that match + what GCC 8.1 generated for IEEE 128-bit floating point types. + (rs6000_globalize_decl_name): If we have an external function that + passes or returns IEEE 128-bit types, generate a weak reference + from the mangled name used in GCC 8.1 to the current mangled + name. + (rs6000_init_builtins): Make __ibm128 use the long double type if + long double is IBM extended double. Make __float128 use the long + double type if long double is IEEE 128-bit. + 2018-06-06 Jim Wilson <jimw@sifive.com> * config/riscv/riscv.c (enum riscv_privilege_levels): New. diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index c5c9821..bbee6cb 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -200,6 +200,17 @@ int dot_symbols; of this machine mode. */ scalar_int_mode rs6000_pmode; +/* Note whether IEEE 128-bit floating point was passed or returned, either as + the __float128/_Float128 explicit type, or when long double is IEEE 128-bit + floating point. We changed the default C++ mangling for these types and we + may want to generate a weak alias of the old mangling (U10__float128) to the + new mangling (u9__ieee128). */ +static bool rs6000_passes_ieee128; + +/* Generate the manged name (i.e. U10__float128) used in GCC 8.1, and not the + name used in current releases (i.e. u9__ieee128). */ +static bool ieee128_mangling_gcc_8_1; + /* Width in bits of a pointer. */ unsigned rs6000_pointer_size; @@ -1973,6 +1984,11 @@ static const struct attribute_spec rs6000_attribute_table[] = #undef TARGET_STARTING_FRAME_OFFSET #define TARGET_STARTING_FRAME_OFFSET rs6000_starting_frame_offset + +#if TARGET_ELF && RS6000_WEAK +#undef TARGET_ASM_GLOBALIZE_DECL_NAME +#define TARGET_ASM_GLOBALIZE_DECL_NAME rs6000_globalize_decl_name +#endif /* Processor table. */ @@ -11108,6 +11124,12 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, && (TYPE_MAIN_VARIANT (return_type) == long_double_type_node)))) rs6000_passes_long_double = true; + + /* Note if we passed or return a IEEE 128-bit type. We changed + the mangling for these types, and we may need to make an alias + with the old mangling. */ + if (FLOAT128_IEEE_P (return_mode)) + rs6000_passes_ieee128 = true; } if (ALTIVEC_OR_VSX_VECTOR_MODE (return_mode)) rs6000_passes_vector = true; @@ -11559,6 +11581,12 @@ rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, machine_mode mode, || (type != NULL && TYPE_MAIN_VARIANT (type) == long_double_type_node))) rs6000_passes_long_double = true; + + /* Note if we passed or return a IEEE 128-bit type. We changed the + mangling for these types, and we may need to make an alias with + the old mangling. */ + if (FLOAT128_IEEE_P (mode)) + rs6000_passes_ieee128 = true; } if (named && ALTIVEC_OR_VSX_VECTOR_MODE (mode)) rs6000_passes_vector = true; @@ -16355,14 +16383,21 @@ rs6000_init_builtins (void) __ieee128. */ if (TARGET_FLOAT128_TYPE) { - ibm128_float_type_node = make_node (REAL_TYPE); - TYPE_PRECISION (ibm128_float_type_node) = 128; - SET_TYPE_MODE (ibm128_float_type_node, IFmode); - layout_type (ibm128_float_type_node); + if (TARGET_IEEEQUAD || !TARGET_LONG_DOUBLE_128) + { + ibm128_float_type_node = make_node (REAL_TYPE); + TYPE_PRECISION (ibm128_float_type_node) = 128; + SET_TYPE_MODE (ibm128_float_type_node, IFmode); + layout_type (ibm128_float_type_node); + } + else + ibm128_float_type_node = long_double_type_node; + lang_hooks.types.register_builtin_type (ibm128_float_type_node, "__ibm128"); - ieee128_float_type_node = float128_type_node; + ieee128_float_type_node + = TARGET_IEEEQUAD ? long_double_type_node : float128_type_node; lang_hooks.types.register_builtin_type (ieee128_float_type_node, "__ieee128"); } @@ -32117,7 +32152,7 @@ rs6000_mangle_type (const_tree type) if (SCALAR_FLOAT_TYPE_P (type) && FLOAT128_IBM_P (TYPE_MODE (type))) return "g"; if (SCALAR_FLOAT_TYPE_P (type) && FLOAT128_IEEE_P (TYPE_MODE (type))) - return "u9__ieee128"; + return ieee128_mangling_gcc_8_1 ? "U10__float128" : "u9__ieee128"; /* For all other types, use the default mangling. */ return NULL; @@ -38727,6 +38762,40 @@ rs6000_starting_frame_offset (void) return RS6000_STARTING_FRAME_OFFSET; } + +/* Create an alias for a mangled name where we have changed the mangling (in + GCC 8.1, we used U10__float128, and now we use u9__ieee128). This is called + via the target hook TARGET_ASM_GLOBALIZE_DECL_NAME. */ + +#if TARGET_ELF && RS6000_WEAK +static void +rs6000_globalize_decl_name (FILE * stream, tree decl) +{ + const char *name = XSTR (XEXP (DECL_RTL (decl), 0), 0); + + targetm.asm_out.globalize_label (stream, name); + + if (rs6000_passes_ieee128 && name[0] == '_' && name[1] == 'Z') + { + tree save_asm_name = DECL_ASSEMBLER_NAME (decl); + const char *old_name; + + ieee128_mangling_gcc_8_1 = true; + lang_hooks.set_decl_assembler_name (decl); + old_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); + SET_DECL_ASSEMBLER_NAME (decl, save_asm_name); + ieee128_mangling_gcc_8_1 = false; + + if (strcmp (name, old_name) != 0) + { + fprintf (stream, "\t.weak %s\n", old_name); + fprintf (stream, "\t.set %s,%s\n", old_name, name); + } + } +} +#endif + + struct gcc_target targetm = TARGET_INITIALIZER; #include "gt-rs6000.h" diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index aa24adf..04d7628 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2018-06-06 Michael Meissner <meissner@linux.ibm.com> + + PR target/85657 + * g++.dg/pr85657.C: Only test whether __ibm128 and long double can + be used in templates. Don't check for them in overloaded functions. + 2018-06-06 Jim Wilson <jimw@sifive.com> * gcc.target/riscv/interrupt-5.c (sub3): Add new test. diff --git a/gcc/testsuite/g++.dg/pr85657.C b/gcc/testsuite/g++.dg/pr85657.C index 6b81bc2..e62b62a 100644 --- a/gcc/testsuite/g++.dg/pr85657.C +++ b/gcc/testsuite/g++.dg/pr85657.C @@ -3,8 +3,8 @@ // { dg-options "-mvsx -mfloat128 -O2 -mabi=ibmlongdouble -Wno-psabi" } // PR 85657 -// Check that __ibm128 and long double are represented as different types, even -// if long double is currently using the same representation as __ibm128. +// Check that __ibm128 and long double can be used in the same template, +// even if long double uses the IBM extended double representation. template <class __T> inline bool iszero (__T __val) @@ -18,30 +18,7 @@ use_template (void) long double ld = 0.0; __ibm128 ibm = 0.0; -#ifdef _ARCH_PWR7 __asm__ (" # %x0, %x1" : "+d" (ld), "+d" (ibm)); -#endif return iszero (ld) + iszero (ibm); } - -class foo { -public: - foo () {} - ~foo () {} - inline bool iszero (long double ld) { return ld == 0.0; } - inline bool iszero (__ibm128 i128) { return i128 == 0.0; } -} st; - -int -use_class (void) -{ - long double ld = 0.0; - __ibm128 ibm = 0.0; - -#ifdef _ARCH_PWR7 - __asm__ (" # %x0, %x1" : "+d" (ld), "+d" (ibm)); -#endif - - return st.iszero (ld) + st.iszero (ibm); -} |