+2014-11-03 Joseph Myers <joseph@codesourcery.com>
+
+ * configure.ac (TARGET_GLIBC_MAJOR, TARGET_GLIBC_MINOR): Define
+ macros.
+ * configure, config.h.in: Regenerate.
+ * config/rs6000/linux.h [TARGET_GLIBC_MAJOR > 2 ||
+ (TARGET_GLIBC_MAJOR == 2 && TARGET_GLIBC_MINOR >= 19)]
+ (RS6000_GLIBC_ATOMIC_FENV): New macro.
+ * config/rs6000/linux64.h [TARGET_GLIBC_MAJOR > 2 ||
+ (TARGET_GLIBC_MAJOR == 2 && TARGET_GLIBC_MINOR >= 19)]
+ (RS6000_GLIBC_ATOMIC_FENV): New macro.
+ * config/rs6000/rs6000.c (atomic_hold_decl, atomic_clear_decl)
+ (atomic_update_decl): New static variables.
+ (rs6000_atomic_assign_expand_fenv) [RS6000_GLIBC_ATOMIC_FENV]:
+ Generate calls to __atomic_feholdexcept, __atomic_feclearexcept
+ and __atomic_feupdateenv for soft-float and no-FPRs.
+
2014-11-03 Richard Biener <rguenther@suse.de>
* match.pd: Add two abs patterns. Announce tree_expr_nonnegative_p.
#undef HAVE_WORKING_VFORK
#endif
-/* Define if isl is in use. */
-#ifndef USED_FOR_TARGET
-#undef HAVE_isl
-#endif
/* Define if cloog is in use. */
#ifndef USED_FOR_TARGET
#undef HAVE_cloog
#endif
+
+/* Define if isl is in use. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_isl
+#endif
+
+
/* Define if F_SETLKW supported by fcntl. */
#ifndef USED_FOR_TARGET
#undef HOST_HAS_F_SETLKW
/* Define if your target C library provides the `dl_iterate_phdr' function. */
#undef TARGET_DL_ITERATE_PHDR
+/* GNU C Library major version number used on the target, or 0. */
+#ifndef USED_FOR_TARGET
+#undef TARGET_GLIBC_MAJOR
+#endif
+
+
+/* GNU C Library minor version number used on the target, or 0. */
+#ifndef USED_FOR_TARGET
+#undef TARGET_GLIBC_MINOR
+#endif
+
+
/* Define if your target C library provides stack protector support */
#ifndef USED_FOR_TARGET
#undef TARGET_LIBC_PROVIDES_SSP
#undef TARGET_FLOAT_EXCEPTIONS_ROUNDING_SUPPORTED_P
#define TARGET_FLOAT_EXCEPTIONS_ROUNDING_SUPPORTED_P \
rs6000_linux_float_exceptions_rounding_supported_p
+
+/* Support for TARGET_ATOMIC_ASSIGN_EXPAND_FENV without FPRs depends
+ on glibc 2.19 or greater. */
+#if TARGET_GLIBC_MAJOR > 2 \
+ || (TARGET_GLIBC_MAJOR == 2 && TARGET_GLIBC_MINOR >= 19)
+#define RS6000_GLIBC_ATOMIC_FENV 1
+#endif
#undef TARGET_FLOAT_EXCEPTIONS_ROUNDING_SUPPORTED_P
#define TARGET_FLOAT_EXCEPTIONS_ROUNDING_SUPPORTED_P \
rs6000_linux_float_exceptions_rounding_supported_p
+
+/* Support for TARGET_ATOMIC_ASSIGN_EXPAND_FENV without FPRs depends
+ on glibc 2.19 or greater. */
+#if TARGET_GLIBC_MAJOR > 2 \
+ || (TARGET_GLIBC_MAJOR == 2 && TARGET_GLIBC_MINOR >= 19)
+#define RS6000_GLIBC_ATOMIC_FENV 1
+#endif
return new pass_analyze_swaps (ctxt);
}
+/* Function declarations for rs6000_atomic_assign_expand_fenv. */
+static tree atomic_hold_decl, atomic_clear_decl, atomic_update_decl;
+
/* Implement TARGET_ATOMIC_ASSIGN_EXPAND_FENV hook. */
static void
rs6000_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
{
if (!TARGET_HARD_FLOAT || !TARGET_FPRS)
- return;
+ {
+#ifdef RS6000_GLIBC_ATOMIC_FENV
+ if (atomic_hold_decl == NULL_TREE)
+ {
+ atomic_hold_decl
+ = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
+ get_identifier ("__atomic_feholdexcept"),
+ build_function_type_list (void_type_node,
+ double_ptr_type_node,
+ NULL_TREE));
+ TREE_PUBLIC (atomic_hold_decl) = 1;
+ DECL_EXTERNAL (atomic_hold_decl) = 1;
+ }
+
+ if (atomic_clear_decl == NULL_TREE)
+ {
+ atomic_clear_decl
+ = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
+ get_identifier ("__atomic_feclearexcept"),
+ build_function_type_list (void_type_node,
+ NULL_TREE));
+ TREE_PUBLIC (atomic_clear_decl) = 1;
+ DECL_EXTERNAL (atomic_clear_decl) = 1;
+ }
+
+ tree const_double = build_qualified_type (double_type_node,
+ TYPE_QUAL_CONST);
+ tree const_double_ptr = build_pointer_type (const_double);
+ if (atomic_update_decl == NULL_TREE)
+ {
+ atomic_update_decl
+ = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
+ get_identifier ("__atomic_feupdateenv"),
+ build_function_type_list (void_type_node,
+ const_double_ptr,
+ NULL_TREE));
+ TREE_PUBLIC (atomic_update_decl) = 1;
+ DECL_EXTERNAL (atomic_update_decl) = 1;
+ }
+
+ tree fenv_var = create_tmp_var (double_type_node, NULL);
+ mark_addressable (fenv_var);
+ tree fenv_addr = build1 (ADDR_EXPR, double_ptr_type_node, fenv_var);
+
+ *hold = build_call_expr (atomic_hold_decl, 1, fenv_addr);
+ *clear = build_call_expr (atomic_clear_decl, 0);
+ *update = build_call_expr (atomic_update_decl, 1,
+ fold_convert (const_double_ptr, fenv_addr));
+#endif
+ return;
+ }
tree mffs = rs6000_builtin_decls[RS6000_BUILTIN_MFFS];
tree mtfsf = rs6000_builtin_decls[RS6000_BUILTIN_MTFSF];
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibc_version_major.$glibc_version_minor" >&5
$as_echo "$glibc_version_major.$glibc_version_minor" >&6; }
+cat >>confdefs.h <<_ACEOF
+#define TARGET_GLIBC_MAJOR $glibc_version_major
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define TARGET_GLIBC_MINOR $glibc_version_minor
+_ACEOF
+
+
# Check whether --enable-gnu-unique-object was given.
if test "${enable_gnu_unique_object+set}" = set; then :
enableval=$enable_gnu_unique_object; case $enable_gnu_unique_object in
glibc_version_minor=`echo "$glibc_version_minor_define" | sed -e 's/.*__GLIBC_MINOR__[ ]*//'`
fi]])
AC_MSG_RESULT([$glibc_version_major.$glibc_version_minor])
+AC_DEFINE_UNQUOTED([TARGET_GLIBC_MAJOR], [$glibc_version_major],
+[GNU C Library major version number used on the target, or 0.])
+AC_DEFINE_UNQUOTED([TARGET_GLIBC_MINOR], [$glibc_version_minor],
+[GNU C Library minor version number used on the target, or 0.])
AC_ARG_ENABLE(gnu-unique-object,
[AS_HELP_STRING([--enable-gnu-unique-object],