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"

Reply via email to