diff --git a/config.h.in b/config.h.in index 8b4077f578..9fb369c640 100644 --- a/config.h.in +++ b/config.h.in @@ -308,4 +308,7 @@ /* Define if -mapxf is enabled by default on x86. */ #undef HAVE_X86_APX +/* Define if trunc is inlined on x86. */ +#undef HAVE_X86_INLINE_TRUNC + #endif diff --git a/sysdeps/x86/configure b/sysdeps/x86/configure index a021cdbcf5..2e95277f29 100644 --- a/sysdeps/x86/configure +++ b/sysdeps/x86/configure @@ -340,6 +340,58 @@ fi config_vars="$config_vars test-cc-cflags-no-direct-extern-access = $libc_cv_test_cc_cflags_no_direct_extern_access" +conftest_code=" +extern float truncf (float __x) __attribute__ ((__nothrow__,__const__)); + +float +tf (float x) +{ + return truncf (x); +} +" + +cat > conftest.c <&5 +printf %s "checking if -Os inlines trunc... " >&6; } +if test ${libc_cv_cc_x86_inline_trunc+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -S -Os -msse4.1 conftest.c -o conftest 1>&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 + (eval $ac_try) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } + then + +libc_cv_cc_x86_inline_trunc=no +if grep -E -q "roundss" conftest; then + libc_cv_cc_x86_inline_trunc=yes +fi + + else + +echo "failed to check if -Os inlines trunc." +rm -f conftest* +exit 1 + + fi ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_cc_x86_inline_trunc" >&5 +printf "%s\n" "$libc_cv_cc_x86_inline_trunc" >&6; } +rm -f conftest* +if test "$libc_cv_cc_x86_inline_trunc" = yes; then + printf "%s\n" "#define HAVE_X86_INLINE_TRUNC 1" >>confdefs.h + +else + printf "%s\n" "#define HAVE_X86_INLINE_TRUNC 0" >>confdefs.h + +fi + if test "${libc_cv_cc_no_direct_extern_access}${libc_cv_test_cc_cflags_no_direct_extern_access}" = yes; then libc_cv_protected_data=no fi diff --git a/sysdeps/x86/configure.ac b/sysdeps/x86/configure.ac index a87e2f6c41..f3888e6618 100644 --- a/sysdeps/x86/configure.ac +++ b/sysdeps/x86/configure.ac @@ -192,6 +192,37 @@ fi LIBC_CONFIG_VAR(test-cc-cflags-no-direct-extern-access, $libc_cv_test_cc_cflags_no_direct_extern_access) +conftest_code=" +extern float truncf (float __x) __attribute__ ((__nothrow__,__const__)); + +float +tf (float x) +{ + return truncf (x); +} +" +dnl Check if CC inlines trunc with -Os. +LIBC_TRY_CC_COMMAND([if -Os inlines trunc], + [$conftest_code], + [-S -Os -msse4.1], + libc_cv_cc_x86_inline_trunc, + [ +libc_cv_cc_x86_inline_trunc=no +if grep -E -q "roundss" conftest; then + libc_cv_cc_x86_inline_trunc=yes +fi +], +[ +echo "failed to check if -Os inlines trunc." +rm -f conftest* +exit 1 +]) +if test "$libc_cv_cc_x86_inline_trunc" = yes; then + AC_DEFINE(HAVE_X86_INLINE_TRUNC, 1) +else + AC_DEFINE(HAVE_X86_INLINE_TRUNC, 0) +fi + dnl If the building compiler enables no direct external data access by dnl default, access to protected data in shared libraries from executables dnl must be compiled with no direct external data access. If the testing diff --git a/sysdeps/x86/fpu/math_private.h b/sysdeps/x86/fpu/math_private.h index d30d580cea..bba085a578 100644 --- a/sysdeps/x86/fpu/math_private.h +++ b/sysdeps/x86/fpu/math_private.h @@ -33,27 +33,23 @@ __NTH (__ieee754_atan2l (long double y, long double x)) __extern_always_inline double __trunc (double x) { -#ifdef __AVX__ - asm ("vroundsd $11, %1, %1, %0" : "=v" (x) : "v" (x)); -#elif defined __SSE4_1__ - asm ("roundsd $11, %1, %0" : "=x" (x) : "x" (x)); +#if HAVE_X86_INLINE_TRUNC || !defined __SSE4_1__ + return trunc (x); #else - x = trunc (x); -#endif + asm ("%vroundsd $11, %d1, %0" : "=v" (x) : "v" (x)); return x; +#endif } __extern_always_inline float __truncf (float x) { -#ifdef __AVX__ - asm ("vroundss $11, %1, %1, %0" : "=v" (x) : "v" (x)); -#elif defined __SSE4_1__ - asm ("roundss $11, %1, %0" : "=x" (x) : "x" (x)); +#if HAVE_X86_INLINE_TRUNC || !defined __SSE4_1__ + return truncf (x); #else - x = truncf (x); -#endif + asm ("%vroundss $11, %d1, %0" : "=v" (x) : "v" (x)); return x; +#endif } #endif