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 <[email protected]>
* 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: [email protected], 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"