This patch breaks up the previous patch. It renames the boolean, and eliminates the switch.
This is patch #1 of 3. It generates a weak reference for the mangled name generated in GCC 8.1 to point to the new name that will be in future releases (i.e. U10__float128 -> u9__ieee128). Patch #2 will make __ibm128 use the long double type if long double is IBM extended double, and __float128 use the long double type if long double is IEEE 128-bit. The rationale here is to allow templates where one call uses long double and the other call uses __ibm128 (PR 85075). The GLIBC ran into this issue. As I mentioned before because __ibm128 and long double are the same type, you can't have explicit overloads with the two types. The test g++.dg/pr85657.C contains both template use and explicit constructors. It fails right now. I will modify the test to remove the explicit constructors, since that won't work given they are the same type. Patch #3 will update the previous patch for __builtin_{,un}pack_ibm128 to deal with the __ibm128 using TFmode in the current default case, and IFmode when the long double default has changed. I tested this on a little endian power8 system running Linux. There were no regressions. Can I install this in the trunk and eventually back port it to GCC 8.2? 2018-06-05 Michael Meissner <meiss...@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. -- Michael Meissner, IBM IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA email: meiss...@linux.ibm.com, phone: +1 (978) 899-4797
Index: gcc/config/rs6000/rs6000.c =================================================================== --- gcc/config/rs6000/rs6000.c (revision 261170) +++ gcc/config/rs6000/rs6000.c (working copy) @@ -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 rs600 #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 *c && (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 (CUMULATIV || (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; @@ -32117,7 +32145,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 +38755,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"