mirror of git://sourceware.org/git/glibc.git
i386: Fix fmod/fmodf/remainder/remainderf for gcc-12
The __builtin_fmod{f} and __builtin_remainder{f} were added on gcc 13,
and the minimum supported gcc is 12. This patch adds a configure test
to check whether the compiler enables inlining for fmod/remainder, and
uses inline assembly if not.
Checked on i686-linux-gnu wih gcc-12.
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
This commit is contained in:
parent
83dd79dffb
commit
eb03df5404
|
|
@ -222,6 +222,9 @@
|
||||||
/* An integer used to scale the timeout of test programs. */
|
/* An integer used to scale the timeout of test programs. */
|
||||||
#define TIMEOUTFACTOR 1
|
#define TIMEOUTFACTOR 1
|
||||||
|
|
||||||
|
/* Define if __builtin_fmod/__builtin_remainder is inlined on x86. */
|
||||||
|
#undef HAVE_X86_INLINE_FMOD
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ __fmod (double x, double y)
|
||||||
&& !is_nan (hx)))
|
&& !is_nan (hx)))
|
||||||
return __math_invalid (x);
|
return __math_invalid (x);
|
||||||
|
|
||||||
return __builtin_fmod (x, y);
|
return fmod_inline (x, y);
|
||||||
}
|
}
|
||||||
strong_alias (__fmod, __ieee754_fmod)
|
strong_alias (__fmod, __ieee754_fmod)
|
||||||
libm_alias_finite (__ieee754_fmod, __fmod)
|
libm_alias_finite (__ieee754_fmod, __fmod)
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ __fmodf (float x, float y)
|
||||||
&& !is_nan (hx)))
|
&& !is_nan (hx)))
|
||||||
return __math_invalidf (x);
|
return __math_invalidf (x);
|
||||||
|
|
||||||
return __builtin_fmodf (x, y);
|
return fmodf_inline (x, y);
|
||||||
}
|
}
|
||||||
strong_alias (__fmodf, __ieee754_fmodf)
|
strong_alias (__fmodf, __ieee754_fmodf)
|
||||||
versioned_symbol (libm, __fmodf, fmodf, GLIBC_2_43);
|
versioned_symbol (libm, __fmodf, fmodf, GLIBC_2_43);
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ __remainder (double x, double y)
|
||||||
&& !is_nan (hx)))
|
&& !is_nan (hx)))
|
||||||
return __math_invalid (x);
|
return __math_invalid (x);
|
||||||
|
|
||||||
return __builtin_remainder (x, y);
|
return remainder_inline (x, y);
|
||||||
}
|
}
|
||||||
strong_alias (__remainder, __ieee754_remainder)
|
strong_alias (__remainder, __ieee754_remainder)
|
||||||
versioned_symbol (libm, __remainder, remainder, GLIBC_2_43);
|
versioned_symbol (libm, __remainder, remainder, GLIBC_2_43);
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ __remainderf (float x, float y)
|
||||||
&& !is_nan (hx)))
|
&& !is_nan (hx)))
|
||||||
return __math_invalidf (x);
|
return __math_invalidf (x);
|
||||||
|
|
||||||
return __builtin_remainderf (x, y);
|
return remainderf_inline (x, y);
|
||||||
}
|
}
|
||||||
strong_alias (__remainderf, __ieee754_remainderf)
|
strong_alias (__remainderf, __ieee754_remainderf)
|
||||||
versioned_symbol (libm, __remainderf, remainderf, GLIBC_2_43);
|
versioned_symbol (libm, __remainderf, remainderf, GLIBC_2_43);
|
||||||
|
|
|
||||||
|
|
@ -430,6 +430,54 @@ else
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
conftest_code="
|
||||||
|
double foo (double x, double y)
|
||||||
|
{
|
||||||
|
return __builtin_fmod (x, y);
|
||||||
|
}
|
||||||
|
"
|
||||||
|
|
||||||
|
cat > conftest.c <<EOF
|
||||||
|
$conftest_code
|
||||||
|
EOF
|
||||||
|
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if compiler inlines __builtin_fmod/__builtin_remainder" >&5
|
||||||
|
printf %s "checking if compiler inlines __builtin_fmod/__builtin_remainder... " >&6; }
|
||||||
|
if test ${libc_cv_cc_x86_inline_fmod+y}
|
||||||
|
then :
|
||||||
|
printf %s "(cached) " >&6
|
||||||
|
else case e in #(
|
||||||
|
e) if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $CFLAGS -fno-math-errno -S 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_fmod=no
|
||||||
|
if grep -E -q "fprem" conftest; then
|
||||||
|
libc_cv_cc_x86_inline_fmod=yes
|
||||||
|
fi
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
echo "failed to check if CC inlines fmod."
|
||||||
|
rm -f conftest*
|
||||||
|
exit 1
|
||||||
|
|
||||||
|
fi ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_cc_x86_inline_fmod" >&5
|
||||||
|
printf "%s\n" "$libc_cv_cc_x86_inline_fmod" >&6; }
|
||||||
|
rm -f conftest*
|
||||||
|
if test "$libc_cv_cc_x86_inline_fmod" = yes; then
|
||||||
|
printf "%s\n" "#define HAVE_X86_INLINE_FMOD 1" >>confdefs.h
|
||||||
|
|
||||||
|
else
|
||||||
|
printf "%s\n" "#define HAVE_X86_INLINE_FMOD 0" >>confdefs.h
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
if test "${libc_cv_cc_no_direct_extern_access}${libc_cv_test_cc_cflags_no_direct_extern_access}" = yes; then
|
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
|
libc_cv_protected_data=no
|
||||||
|
|
|
||||||
|
|
@ -240,6 +240,33 @@ else
|
||||||
AC_DEFINE(HAVE_X86_LIBGCC_CMP_RETURN_ATTR, 0)
|
AC_DEFINE(HAVE_X86_LIBGCC_CMP_RETURN_ATTR, 0)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
conftest_code="
|
||||||
|
double foo (double x, double y)
|
||||||
|
{
|
||||||
|
return __builtin_fmod (x, y);
|
||||||
|
}
|
||||||
|
"
|
||||||
|
dnl Check if CC inlines __builtin_fmod/__builtin_remainder
|
||||||
|
LIBC_TRY_CC_COMMAND([if compiler inlines __builtin_fmod/__builtin_remainder],
|
||||||
|
[$conftest_code],
|
||||||
|
[$CFLAGS -fno-math-errno -S],
|
||||||
|
libc_cv_cc_x86_inline_fmod,
|
||||||
|
[
|
||||||
|
libc_cv_cc_x86_inline_fmod=no
|
||||||
|
if grep -E -q "fprem" conftest; then
|
||||||
|
libc_cv_cc_x86_inline_fmod=yes
|
||||||
|
fi
|
||||||
|
],
|
||||||
|
[
|
||||||
|
echo "failed to check if CC inlines fmod."
|
||||||
|
rm -f conftest*
|
||||||
|
exit 1
|
||||||
|
])
|
||||||
|
if test "$libc_cv_cc_x86_inline_fmod" = yes; then
|
||||||
|
AC_DEFINE(HAVE_X86_INLINE_FMOD, 1)
|
||||||
|
else
|
||||||
|
AC_DEFINE(HAVE_X86_INLINE_FMOD, 0)
|
||||||
|
fi
|
||||||
|
|
||||||
dnl If the building compiler enables no direct external data access by
|
dnl If the building compiler enables no direct external data access by
|
||||||
dnl default, access to protected data in shared libraries from executables
|
dnl default, access to protected data in shared libraries from executables
|
||||||
|
|
|
||||||
|
|
@ -74,4 +74,84 @@ divss_inline_asm (float x, float y)
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static __always_inline double
|
||||||
|
fmod_inline (double x, double y)
|
||||||
|
{
|
||||||
|
#if HAVE_X86_INLINE_FMOD
|
||||||
|
return __builtin_fmod (x, y);
|
||||||
|
#else
|
||||||
|
double result;
|
||||||
|
asm ("1:\n"
|
||||||
|
"fprem\n"
|
||||||
|
"fnstsw %%ax\n"
|
||||||
|
"sahf\n"
|
||||||
|
"jp 1b\n"
|
||||||
|
: "=t" (result)
|
||||||
|
: "0" (x), "u" (y)
|
||||||
|
: "ax", "cc"
|
||||||
|
);
|
||||||
|
return result;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static __always_inline float
|
||||||
|
fmodf_inline (float x, float y)
|
||||||
|
{
|
||||||
|
#if HAVE_X86_INLINE_FMOD
|
||||||
|
return __builtin_fmodf (x, y);
|
||||||
|
#else
|
||||||
|
float result;
|
||||||
|
asm ("1:\n"
|
||||||
|
"fprem\n"
|
||||||
|
"fnstsw %%ax\n"
|
||||||
|
"sahf\n"
|
||||||
|
"jp 1b\n"
|
||||||
|
: "=t" (result)
|
||||||
|
: "0" (x), "u" (y)
|
||||||
|
: "ax", "cc"
|
||||||
|
);
|
||||||
|
return result;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static __always_inline double
|
||||||
|
remainder_inline (double x, double y)
|
||||||
|
{
|
||||||
|
#if HAVE_X86_INLINE_FMOD
|
||||||
|
return __builtin_remainder (x, y);
|
||||||
|
#else
|
||||||
|
double result;
|
||||||
|
asm ("1:\n"
|
||||||
|
"fprem1\n"
|
||||||
|
"fnstsw %%ax\n"
|
||||||
|
"sahf\n"
|
||||||
|
"jp 1b\n"
|
||||||
|
: "=t" (result)
|
||||||
|
: "0" (x), "u" (y)
|
||||||
|
: "ax", "cc"
|
||||||
|
);
|
||||||
|
return result;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static __always_inline float
|
||||||
|
remainderf_inline (float x, float y)
|
||||||
|
{
|
||||||
|
#if HAVE_X86_INLINE_FMOD
|
||||||
|
return __builtin_remainderf (x, y);
|
||||||
|
#else
|
||||||
|
float result;
|
||||||
|
asm ("1:\n"
|
||||||
|
"fprem1\n"
|
||||||
|
"fnstsw %%ax\n"
|
||||||
|
"sahf\n"
|
||||||
|
"jp 1b\n"
|
||||||
|
: "=t" (result)
|
||||||
|
: "0" (x), "u" (y)
|
||||||
|
: "ax", "cc"
|
||||||
|
);
|
||||||
|
return result;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue