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. */
|
||||
#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)))
|
||||
return __math_invalid (x);
|
||||
|
||||
return __builtin_fmod (x, y);
|
||||
return fmod_inline (x, y);
|
||||
}
|
||||
strong_alias (__fmod, __ieee754_fmod)
|
||||
libm_alias_finite (__ieee754_fmod, __fmod)
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ __fmodf (float x, float y)
|
|||
&& !is_nan (hx)))
|
||||
return __math_invalidf (x);
|
||||
|
||||
return __builtin_fmodf (x, y);
|
||||
return fmodf_inline (x, y);
|
||||
}
|
||||
strong_alias (__fmodf, __ieee754_fmodf)
|
||||
versioned_symbol (libm, __fmodf, fmodf, GLIBC_2_43);
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ __remainder (double x, double y)
|
|||
&& !is_nan (hx)))
|
||||
return __math_invalid (x);
|
||||
|
||||
return __builtin_remainder (x, y);
|
||||
return remainder_inline (x, y);
|
||||
}
|
||||
strong_alias (__remainder, __ieee754_remainder)
|
||||
versioned_symbol (libm, __remainder, remainder, GLIBC_2_43);
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ __remainderf (float x, float y)
|
|||
&& !is_nan (hx)))
|
||||
return __math_invalidf (x);
|
||||
|
||||
return __builtin_remainderf (x, y);
|
||||
return remainderf_inline (x, y);
|
||||
}
|
||||
strong_alias (__remainderf, __ieee754_remainderf)
|
||||
versioned_symbol (libm, __remainderf, remainderf, GLIBC_2_43);
|
||||
|
|
|
|||
|
|
@ -430,6 +430,54 @@ else
|
|||
|
||||
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
|
||||
libc_cv_protected_data=no
|
||||
|
|
|
|||
|
|
@ -240,6 +240,33 @@ else
|
|||
AC_DEFINE(HAVE_X86_LIBGCC_CMP_RETURN_ATTR, 0)
|
||||
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 default, access to protected data in shared libraries from executables
|
||||
|
|
|
|||
|
|
@ -74,4 +74,84 @@ divss_inline_asm (float x, float y)
|
|||
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
|
||||
|
|
|
|||
Loading…
Reference in New Issue