/* Define if you want runtime assertions enabled. This is a cheap check. */
#undef ENABLE_RUNTIME_CHECKING
+/* Define to enable evaluating float expressions with double precision in
+ standards-compatible mode on s390 targets. */
+#undef ENABLE_S390_EXCESS_FLOAT_PRECISION
+
/* Define if you want all operations on trees (the basic data structure of the
front ends) to be checked for dynamic type safety at runtime. This is
moderately expensive. */
return NULL;
}
-/* Implement TARGET_C_EXCESS_PRECISION.
+#if ENABLE_S390_EXCESS_FLOAT_PRECISION == 1
+/* Implement TARGET_C_EXCESS_PRECISION to maintain historic behavior with older
+ glibc versions
- FIXME: For historical reasons, float_t and double_t are typedef'ed to
+ For historical reasons, float_t and double_t had been typedef'ed to
double on s390, causing operations on float_t to operate in a higher
precision than is necessary. However, it is not the case that SFmode
operations have implicit excess precision, and we generate more optimal
code if we let the compiler know no implicit extra precision is added.
- That means when we are compiling with -fexcess-precision=fast, the value
- we set for FLT_EVAL_METHOD will be out of line with the actual precision of
- float_t (though they would be correct for -fexcess-precision=standard).
+ With a glibc with that "historic" definition, configure will enable this hook
+ to set FLT_EVAL_METHOD to 1 for -fexcess-precision=standard (e.g., as implied
+ by -std=cXY). That means when we are compiling with -fexcess-precision=fast,
+ the value we set for FLT_EVAL_METHOD will be out of line with the actual
+ precision of float_t.
- A complete fix would modify glibc to remove the unnecessary typedef
- of float_t to double. */
+ Newer versions of glibc will be modified to derive the definition of float_t
+ from FLT_EVAL_METHOD on s390x, as on many other architectures. There,
+ configure will disable this hook by default, so that we defer to the default
+ of FLT_EVAL_METHOD_PROMOTE_TO_FLOAT and a resulting typedef of float_t to
+ float. Note that in that scenario, float_t and FLT_EVAL_METHOD will be in
+ line independent of -fexcess-precision. */
static enum flt_eval_method
s390_excess_precision (enum excess_precision_type type)
}
return FLT_EVAL_METHOD_UNPREDICTABLE;
}
+#endif
/* Implement the TARGET_ASAN_SHADOW_OFFSET hook. */
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
+#if ENABLE_S390_EXCESS_FLOAT_PRECISION == 1
+/* This hook is only needed to maintain the historic behavior with glibc
+ versions that typedef float_t to double. */
#undef TARGET_C_EXCESS_PRECISION
#define TARGET_C_EXCESS_PRECISION s390_excess_precision
+#endif
#undef TARGET_SCHED_ADJUST_PRIORITY
#define TARGET_SCHED_ADJUST_PRIORITY s390_adjust_priority
with_diagnostics_urls
enable_default_pie
enable_cet
+enable_s390_excess_float_precision
'
ac_precious_vars='build_alias
host_alias
disable libquadmath support for Fortran
--enable-default-pie enable Position Independent Executable as default
--enable-cet enable Intel CET in host libraries [default=auto]
+ --enable-s390-excess-float-precision
+ on s390 targets, evaluate float with double
+ precision when in standards-conforming mode
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 19183 "configure"
+#line 19187 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 19289 "configure"
+#line 19293 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_pushpopstate_support" >&5
$as_echo "$ld_pushpopstate_support" >&6; }
+# On s390, float_t has historically been statically defined as double for no
+# good reason. To comply with the C standard in the light of this definition,
+# gcc has evaluated float expressions in double precision when in
+# standards-compatible mode or when given -fexcess-precision=standard. To enable
+# a smooth transition towards the new model used by most architectures, where
+# gcc describes its behavior via the macro __FLT_EVAL_METHOD__ and glibc derives
+# float_t from that, this behavior can be configured with
+# --enable-s390-excess-float-precision. When given as enabled, that flag selects
+# the old model. When omitted, native builds will derive the flag from the
+# behavior of glibc. When glibc clamps float_t to double, gcc follows the old
+# model. In any other case, it defaults to the new model.
+# Check whether --enable-s390-excess-float-precision was given.
+if test "${enable_s390_excess_float_precision+set}" = set; then :
+ enableval=$enable_s390_excess_float_precision;
+else
+ enable_s390_excess_float_precision=auto
+fi
+
+
+case $target in
+ s390*-linux*)
+ if test "$target" = "$host" -a "$host" = "$build" -a \
+ x"$enable_s390_excess_float_precision" = xauto; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for glibc clamping float_t to double" >&5
+$as_echo_n "checking for glibc clamping float_t to double... " >&6; }
+if ${gcc_cv_float_t_clamped_to_double+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run test program while cross compiling
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#define __FLT_EVAL_METHOD__ 0
+#include <math.h>
+int main() {
+ return !(sizeof(float_t) == sizeof(double));
+}
+_ACEOF
+if ac_fn_cxx_try_run "$LINENO"; then :
+ gcc_cv_float_t_clamped_to_double=yes
+else
+ gcc_cv_float_t_clamped_to_double=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_float_t_clamped_to_double" >&5
+$as_echo "$gcc_cv_float_t_clamped_to_double" >&6; }
+ if test x"$gcc_cv_float_t_clamped_to_double" = xyes; then
+ enable_s390_excess_float_precision=yes
+ fi
+ fi
+
+
+ if test x"$enable_s390_excess_float_precision" = xyes; then
+
+$as_echo "#define ENABLE_S390_EXCESS_FLOAT_PRECISION 1" >>confdefs.h
+
+ fi
+ ;;
+esac
+
# Configure the subdirectories
# AC_CONFIG_SUBDIRS($subdirs)
fi
AC_MSG_RESULT($ld_pushpopstate_support)
+# On s390, float_t has historically been statically defined as double for no
+# good reason. To comply with the C standard in the light of this definition,
+# gcc has evaluated float expressions in double precision when in
+# standards-compatible mode or when given -fexcess-precision=standard. To enable
+# a smooth transition towards the new model used by most architectures, where
+# gcc describes its behavior via the macro __FLT_EVAL_METHOD__ and glibc derives
+# float_t from that, this behavior can be configured with
+# --enable-s390-excess-float-precision. When given as enabled, that flag selects
+# the old model. When omitted, native builds will derive the flag from the
+# behavior of glibc. When glibc clamps float_t to double, gcc follows the old
+# model. In any other case, it defaults to the new model.
+AC_ARG_ENABLE(s390-excess-float-precision,
+ [AS_HELP_STRING([--enable-s390-excess-float-precision],
+ [on s390 targets, evaluate float with double precision
+ when in standards-conforming mode])],
+ [],[enable_s390_excess_float_precision=auto])
+
+case $target in
+ s390*-linux*)
+ if test "$target" = "$host" -a "$host" = "$build" -a \
+ x"$enable_s390_excess_float_precision" = xauto; then
+ AC_CACHE_CHECK([for glibc clamping float_t to double],
+ gcc_cv_float_t_clamped_to_double,
+ [AC_RUN_IFELSE([AC_LANG_SOURCE([
+#define __FLT_EVAL_METHOD__ 0
+#include <math.h>
+int main() {
+ return !(sizeof(float_t) == sizeof(double));
+}])],
+ [gcc_cv_float_t_clamped_to_double=yes],
+ [gcc_cv_float_t_clamped_to_double=no])])
+ if test x"$gcc_cv_float_t_clamped_to_double" = xyes; then
+ enable_s390_excess_float_precision=yes
+ fi
+ fi
+
+ GCC_TARGET_TEMPLATE(ENABLE_S390_EXCESS_FLOAT_PRECISION)
+ if test x"$enable_s390_excess_float_precision" = xyes; then
+ AC_DEFINE(ENABLE_S390_EXCESS_FLOAT_PRECISION, 1,
+[Define to enable evaluating float expressions with double precision in
+standards-compatible mode on s390 targets.])
+ fi
+ ;;
+esac
+
# Configure the subdirectories
# AC_CONFIG_SUBDIRS($subdirs)
The option is disabled by default. It is enabled on RISC-V/ELF (bare-metal)
target if target binutils supported.
+
+@item --enable-s390-excess-float-precision
+@itemx --disable-s390-excess-float-precision
+On s390(x) targets, enable treatment of float expressions with double precision
+when in standards-compliant mode (e.g., when @code{--std=c99} or
+@code{-fexcess-precision=standard} are given).
+
+For a native build, the option's default is derived from glibc's behavior. When
+glibc clamps float_t to double, gcc follows and enables the option. In all other
+cases, it defaults to off.
@end table
@subheading Cross-Compiler-Specific Options