+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.
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;
#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
\f
/* Processor table. */
&& (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;
|| (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;
__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");
}
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;
return 0;
return RS6000_STARTING_FRAME_OFFSET;
}
+\f
+
+/* 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
+
\f
struct gcc_target targetm = TARGET_INITIALIZER;