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
This commit is contained in:
parent
9d67f13e6a
commit
c765c8cb73
4 changed files with 103 additions and 31 deletions
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
@ -38726,6 +38761,40 @@ rs6000_starting_frame_offset (void)
|
|||
return 0;
|
||||
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;
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue