mirror of
https://gitlab.com/embeddable-common-lisp/ecl.git
synced 2026-01-25 05:51:55 -08:00
Merge branch 'fpe-without-sigfpe' into 'develop'
Fix floating point exceptions for systems without working feenableexcept See merge request embeddable-common-lisp/ecl!177
This commit is contained in:
commit
9cf6e774a4
17 changed files with 202 additions and 84 deletions
47
src/aclocal.m4
vendored
47
src/aclocal.m4
vendored
|
|
@ -939,6 +939,53 @@ if test $ECL_WORKING_ENVIRON = yes ; then
|
|||
fi
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl --------------------------------------------------------------
|
||||
dnl Check if we have feenableexcept and the hardware generates
|
||||
dnl floating point exceptions.
|
||||
dnl
|
||||
AC_DEFUN(ECL_FLOATING_POINT_EXCEPTIONS,[
|
||||
if test "${with_fpe}" = "yes" ; then
|
||||
AC_MSG_CHECKING(for working feenableexcept)
|
||||
saved_libs="${LIBS}"
|
||||
LIBS="-lm"
|
||||
AC_RUN_IFELSE([AC_LANG_SOURCE([[
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <fenv.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
const int traps = FE_DIVBYZERO | FE_OVERFLOW;
|
||||
|
||||
void fpe_handler(int code) {
|
||||
if (code == SIGFPE)
|
||||
exit(0);
|
||||
}
|
||||
|
||||
double raises_fpe(double x) {
|
||||
return x / 0.0;
|
||||
}
|
||||
|
||||
int main() {
|
||||
signal(SIGFPE, fpe_handler);
|
||||
feclearexcept(traps);
|
||||
feenableexcept(traps);
|
||||
raises_fpe(1.0);
|
||||
return 1;
|
||||
}
|
||||
]])],
|
||||
[AC_DEFINE([HAVE_FEENABLEEXCEPT], [], [feenableexcept works])
|
||||
AC_MSG_RESULT(yes)],
|
||||
[AC_MSG_RESULT(no)],
|
||||
[AC_MSG_RESULT(only checking if feenableexcept is present due to cross compilation)
|
||||
AC_CHECK_DECL([feenableexcept],
|
||||
[AC_DEFINE(HAVE_FEENABLEEXCEPT,[],[feenableexcept is declared])],
|
||||
[],
|
||||
[#include <fenv.h>])])
|
||||
LIBS="${saved_libs}"
|
||||
fi])
|
||||
|
||||
dnl ----------------------------------------------------------------------
|
||||
dnl Configure libatomic-ops
|
||||
dnl
|
||||
|
|
|
|||
|
|
@ -22,6 +22,9 @@ ecl_def_string_array(feature_names,static,const) = {
|
|||
ecl_def_string_array_elt("PACKAGE-LOCAL-NICKNAMES"),
|
||||
#ifdef ECL_IEEE_FP
|
||||
ecl_def_string_array_elt("IEEE-FLOATING-POINT"),
|
||||
#endif
|
||||
#if !defined(ECL_IEEE_FP) || !defined(ECL_AVOID_FPE_H)
|
||||
ecl_def_string_array_elt("FLOATING-POINT-EXCEPTIONS"),
|
||||
#endif
|
||||
ecl_def_string_array_elt("COMMON-LISP"),
|
||||
ecl_def_string_array_elt("ANSI-CL"),
|
||||
|
|
|
|||
|
|
@ -13,8 +13,6 @@
|
|||
*
|
||||
*/
|
||||
|
||||
/* for ECL_MATHERR_* */
|
||||
#define ECL_INCLUDE_MATH_H
|
||||
#include <ecl/ecl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
|
|
|||
|
|
@ -23,26 +23,38 @@
|
|||
#include <ecl/impl/math_fenv.h>
|
||||
|
||||
#if defined(ECL_IEEE_FP)
|
||||
# if defined(HAVE_FEENABLEEXCEPT)
|
||||
# if defined(ECL_AVOID_FPE_H)
|
||||
/*
|
||||
* We don't check for floating point exceptions
|
||||
*/
|
||||
# define DO_DETECT_FPE(f)
|
||||
# define DO_DETECT_FPE2(f1,f2)
|
||||
# elif defined(HAVE_FEENABLEEXCEPT)
|
||||
/*
|
||||
* We are using IEEE arithmetics and can rely on FPE exceptions
|
||||
* to be raised when invalid operations are performed.
|
||||
*/
|
||||
# define DO_DETECT_FPE(f) ecl_detect_fpe()
|
||||
# define DO_DETECT_FPE2(f1,f2) DO_DETECT_FPE(f1)
|
||||
# else
|
||||
/*
|
||||
* Floating point exceptions are disabled
|
||||
* We need explicit checks for floating point exception bits being set
|
||||
*/
|
||||
# define DO_DETECT_FPE(f)
|
||||
# define DO_DETECT_FPE(f) do { \
|
||||
int status = fetestexcept(ecl_process_env()->trap_fpe_bits); \
|
||||
unlikely_if (status) ecl_deliver_fpe(status); \
|
||||
} while (0)
|
||||
# define DO_DETECT_FPE2(f1,f2) DO_DETECT_FPE(f1)
|
||||
# endif
|
||||
#else
|
||||
/*
|
||||
* We do not want IEEE NaNs and infinities
|
||||
*/
|
||||
# define DO_DETECT_FPE(f) do { \
|
||||
unlikely_if (isnan(f)) ecl_deliver_fpe(FE_INVALID); \
|
||||
unlikely_if (!isfinite(f)) ecl_deliver_fpe(FE_OVERFLOW); \
|
||||
# define DO_DETECT_FPE(f) do { \
|
||||
unlikely_if (isnan(f)) ecl_deliver_fpe(FE_INVALID); \
|
||||
unlikely_if (!isfinite(f)) ecl_deliver_fpe(FE_OVERFLOW); \
|
||||
} while (0)
|
||||
# define DO_DETECT_FPE2(f1,f2) DO_DETECT_FPE(f1); DO_DETECT_FPE(f2)
|
||||
#endif
|
||||
|
||||
#if !ECL_CAN_INLINE
|
||||
|
|
@ -618,8 +630,7 @@ si_complex_float(cl_object r, cl_object i)
|
|||
}
|
||||
|
||||
cl_object ecl_make_csfloat(float _Complex x) {
|
||||
DO_DETECT_FPE(crealf(x));
|
||||
DO_DETECT_FPE(cimagf(x));
|
||||
DO_DETECT_FPE2(crealf(x), cimagf(x));
|
||||
|
||||
cl_object c = ecl_alloc_object(t_csfloat);
|
||||
ecl_csfloat(c) = x;
|
||||
|
|
@ -627,8 +638,7 @@ cl_object ecl_make_csfloat(float _Complex x) {
|
|||
}
|
||||
|
||||
cl_object ecl_make_cdfloat(double _Complex x) {
|
||||
DO_DETECT_FPE(creal(x));
|
||||
DO_DETECT_FPE(cimag(x));
|
||||
DO_DETECT_FPE2(creal(x), cimag(x));
|
||||
|
||||
cl_object c = ecl_alloc_object(t_cdfloat);
|
||||
ecl_cdfloat(c) = x;
|
||||
|
|
@ -636,8 +646,7 @@ cl_object ecl_make_cdfloat(double _Complex x) {
|
|||
}
|
||||
|
||||
cl_object ecl_make_clfloat(long double _Complex x) {
|
||||
DO_DETECT_FPE(creall(x));
|
||||
DO_DETECT_FPE(cimagl(x));
|
||||
DO_DETECT_FPE2(creall(x), cimagl(x));
|
||||
|
||||
cl_object c = ecl_alloc_object(t_clfloat);
|
||||
ecl_clfloat(c) = x;
|
||||
|
|
|
|||
|
|
@ -24,27 +24,23 @@ cl_object
|
|||
ecl_atan2(cl_object y, cl_object x)
|
||||
{
|
||||
cl_object output;
|
||||
ECL_MATHERR_CLEAR;
|
||||
{
|
||||
int tx = ecl_t_of(x);
|
||||
int ty = ecl_t_of(y);
|
||||
if (tx < ty)
|
||||
tx = ty;
|
||||
if (tx == t_longfloat) {
|
||||
long double d = atan2l(ecl_to_long_double(y), ecl_to_long_double(x));
|
||||
output = ecl_make_long_float(d);
|
||||
int tx = ecl_t_of(x);
|
||||
int ty = ecl_t_of(y);
|
||||
if (tx < ty)
|
||||
tx = ty;
|
||||
if (tx == t_longfloat) {
|
||||
long double d = atan2l(ecl_to_long_double(y), ecl_to_long_double(x));
|
||||
output = ecl_make_long_float(d);
|
||||
} else {
|
||||
double dx = ecl_to_double(x);
|
||||
double dy = ecl_to_double(y);
|
||||
double dz = atan2(dy, dx);
|
||||
if (tx == t_doublefloat) {
|
||||
output = ecl_make_double_float(dz);
|
||||
} else {
|
||||
double dx = ecl_to_double(x);
|
||||
double dy = ecl_to_double(y);
|
||||
double dz = atan2(dy, dx);
|
||||
if (tx == t_doublefloat) {
|
||||
output = ecl_make_double_float(dz);
|
||||
} else {
|
||||
output = ecl_make_single_float(dz);
|
||||
}
|
||||
output = ecl_make_single_float(dz);
|
||||
}
|
||||
}
|
||||
ECL_MATHERR_TEST;
|
||||
return output;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -100,7 +100,6 @@ ecl_expt_generic(cl_object x, cl_object y) {
|
|||
if (minusp) {
|
||||
y = ecl_negate(y);
|
||||
}
|
||||
ECL_MATHERR_CLEAR;
|
||||
do {
|
||||
/* INV: ecl_integer_divide outputs an integer */
|
||||
if (!ecl_evenp(y)) {
|
||||
|
|
@ -113,7 +112,6 @@ ecl_expt_generic(cl_object x, cl_object y) {
|
|||
}
|
||||
x = ecl_times(x, x);
|
||||
} while (1);
|
||||
ECL_MATHERR_TEST;
|
||||
}
|
||||
|
||||
static cl_object
|
||||
|
|
|
|||
94
src/configure
vendored
94
src/configure
vendored
|
|
@ -741,6 +741,7 @@ infodir
|
|||
docdir
|
||||
oldincludedir
|
||||
includedir
|
||||
runstatedir
|
||||
localstatedir
|
||||
sharedstatedir
|
||||
sysconfdir
|
||||
|
|
@ -866,6 +867,7 @@ datadir='${datarootdir}'
|
|||
sysconfdir='${prefix}/etc'
|
||||
sharedstatedir='${prefix}/com'
|
||||
localstatedir='${prefix}/var'
|
||||
runstatedir='${localstatedir}/run'
|
||||
includedir='${prefix}/include'
|
||||
oldincludedir='/usr/include'
|
||||
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
|
||||
|
|
@ -1118,6 +1120,15 @@ do
|
|||
| -silent | --silent | --silen | --sile | --sil)
|
||||
silent=yes ;;
|
||||
|
||||
-runstatedir | --runstatedir | --runstatedi | --runstated \
|
||||
| --runstate | --runstat | --runsta | --runst | --runs \
|
||||
| --run | --ru | --r)
|
||||
ac_prev=runstatedir ;;
|
||||
-runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
|
||||
| --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
|
||||
| --run=* | --ru=* | --r=*)
|
||||
runstatedir=$ac_optarg ;;
|
||||
|
||||
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
|
||||
ac_prev=sbindir ;;
|
||||
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
|
||||
|
|
@ -1255,7 +1266,7 @@ fi
|
|||
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
|
||||
datadir sysconfdir sharedstatedir localstatedir includedir \
|
||||
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
|
||||
libdir localedir mandir
|
||||
libdir localedir mandir runstatedir
|
||||
do
|
||||
eval ac_val=\$$ac_var
|
||||
# Remove trailing slashes.
|
||||
|
|
@ -1408,6 +1419,7 @@ Fine tuning of the installation directories:
|
|||
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
|
||||
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
|
||||
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
|
||||
--runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
|
||||
--libdir=DIR object code libraries [EPREFIX/lib]
|
||||
--includedir=DIR C header files [PREFIX/include]
|
||||
--oldincludedir=DIR C header files for non-gcc [/usr/include]
|
||||
|
|
@ -1525,7 +1537,7 @@ Optional Packages:
|
|||
--with-signed-zero={yes|no}
|
||||
allow for IEEE signed zeros (default=YES).
|
||||
--with-ieee-fp={yes|no} full IEEE floating point system, including denormals
|
||||
(default=YES). Implies signed-zero and fpe
|
||||
(default=YES). Implies signed-zero
|
||||
--with-sse={yes|no|auto}
|
||||
implement SSE intrinsics in ECL (default=NO). Only
|
||||
works when supported by the compiler
|
||||
|
|
@ -6499,7 +6511,6 @@ ECL_VERSION_NUMBER=$(($PACKAGE_MAJOR * 10000 + $PACKAGE_MINOR * 100 + $PACKAGE_L
|
|||
|
||||
if test "${with_ieee_fp}" = yes; then
|
||||
with_signed_zero="yes"
|
||||
with_fpe="yes"
|
||||
|
||||
$as_echo "#define ECL_IEEE_FP /**/" >>confdefs.h
|
||||
|
||||
|
|
@ -8996,6 +9007,8 @@ main ()
|
|||
if (*(data + i) != *(data3 + i))
|
||||
return 14;
|
||||
close (fd);
|
||||
free (data);
|
||||
free (data3);
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
|
|
@ -9443,17 +9456,6 @@ _ACEOF
|
|||
fi
|
||||
done
|
||||
|
||||
ac_fn_c_check_decl "$LINENO" "feenableexcept" "ac_cv_have_decl_feenableexcept" "#include <fenv.h>
|
||||
"
|
||||
if test "x$ac_cv_have_decl_feenableexcept" = xyes; then :
|
||||
|
||||
$as_echo "#define HAVE_FEENABLEEXCEPT /**/" >>confdefs.h
|
||||
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: feenableexcept not declared: disabling floating point exceptions" >&5
|
||||
$as_echo "$as_me: WARNING: feenableexcept not declared: disabling floating point exceptions" >&2;}
|
||||
fi
|
||||
|
||||
|
||||
for ac_func in expf powf logf sqrtf cosf sinf tanf sinhf coshf tanhf \
|
||||
floorf ceilf fabsf frexpf ldexpf log1p log1pf log1pl \
|
||||
|
|
@ -9537,6 +9539,70 @@ fi
|
|||
|
||||
|
||||
|
||||
if test "${with_fpe}" = "yes" ; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working feenableexcept" >&5
|
||||
$as_echo_n "checking for working feenableexcept... " >&6; }
|
||||
saved_libs="${LIBS}"
|
||||
LIBS="-lm"
|
||||
if test "$cross_compiling" = yes; then :
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: only checking if feenableexcept is present due to cross compilation" >&5
|
||||
$as_echo "only checking if feenableexcept is present due to cross compilation" >&6; }
|
||||
ac_fn_c_check_decl "$LINENO" "feenableexcept" "ac_cv_have_decl_feenableexcept" "#include <fenv.h>
|
||||
"
|
||||
if test "x$ac_cv_have_decl_feenableexcept" = xyes; then :
|
||||
|
||||
$as_echo "#define HAVE_FEENABLEEXCEPT /**/" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
else
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <fenv.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
const int traps = FE_DIVBYZERO | FE_OVERFLOW;
|
||||
|
||||
void fpe_handler(int code) {
|
||||
if (code == SIGFPE)
|
||||
exit(0);
|
||||
}
|
||||
|
||||
double raises_fpe(double x) {
|
||||
return x / 0.0;
|
||||
}
|
||||
|
||||
int main() {
|
||||
signal(SIGFPE, fpe_handler);
|
||||
feclearexcept(traps);
|
||||
feenableexcept(traps);
|
||||
raises_fpe(1.0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
_ACEOF
|
||||
if ac_fn_c_try_run "$LINENO"; then :
|
||||
|
||||
$as_echo "#define HAVE_FEENABLEEXCEPT /**/" >>confdefs.h
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
|
||||
conftest.$ac_objext conftest.beam conftest.$ac_ext
|
||||
fi
|
||||
|
||||
LIBS="${saved_libs}"
|
||||
fi
|
||||
|
||||
|
||||
|
||||
if test ${with_cxx} = "no" ; then
|
||||
ECL_CC=${CC}
|
||||
|
|
|
|||
|
|
@ -215,7 +215,7 @@ AC_ARG_WITH(signed-zero,
|
|||
AC_ARG_WITH(ieee-fp,
|
||||
AS_HELP_STRING( [--with-ieee-fp={yes|no}],
|
||||
[full IEEE floating point system, including denormals (default=YES).]
|
||||
[Implies signed-zero and fpe]),
|
||||
[Implies signed-zero]),
|
||||
[], [with_ieee_fp="yes"])
|
||||
|
||||
AC_ARG_WITH(sse,
|
||||
|
|
@ -633,7 +633,6 @@ dnl ----------------------------------------------------------------------
|
|||
dnl Deactivate floating point exceptions if asked to
|
||||
if test "${with_ieee_fp}" = yes; then
|
||||
with_signed_zero="yes"
|
||||
with_fpe="yes"
|
||||
AC_DEFINE([ECL_IEEE_FP], [], [ECL_IEEE_FP])
|
||||
fi
|
||||
if test "${with_fpe}" != yes; then
|
||||
|
|
@ -738,10 +737,6 @@ dnl !!! end autoscan
|
|||
AC_CHECK_FUNCS( [nanosleep alarm times select setenv putenv] \
|
||||
[lstat mkstemp sigprocmask isatty tzset] \
|
||||
[gettimeofday getrusage system] )
|
||||
AC_CHECK_DECL([feenableexcept],
|
||||
[AC_DEFINE(HAVE_FEENABLEEXCEPT,[],[feenableexcept is available])],
|
||||
[AC_MSG_WARN(feenableexcept not declared: disabling floating point exceptions)],
|
||||
[#include <fenv.h>])
|
||||
|
||||
AC_CHECK_FUNCS( [expf powf logf sqrtf cosf sinf tanf sinhf coshf tanhf] \
|
||||
[floorf ceilf fabsf frexpf ldexpf log1p log1pf log1pl] \
|
||||
|
|
@ -756,6 +751,8 @@ AC_CHECK_HEADER( [sys/mman.h],
|
|||
|
||||
ECL_POSIX_ENVIRON
|
||||
|
||||
ECL_FLOATING_POINT_EXCEPTIONS
|
||||
|
||||
dnl =====================================================================
|
||||
dnl Checks for system services
|
||||
|
||||
|
|
|
|||
|
|
@ -55,17 +55,20 @@ ratios all complex numbers are pairs of numbers.
|
|||
@subsection Floating point exceptions
|
||||
ECL supports two ways of dealing with special floating point values,
|
||||
such as Not a Number (NaN), infinity or denormalized floats, which can
|
||||
occur in floating point computations. Either a condition is signaled
|
||||
or the value is silently used as it is. There are multiple options
|
||||
occur in floating point computations. Either a condition is signaled or
|
||||
the value is silently used as it is. There are multiple options
|
||||
controlling which behaviour is selected: If ECL is built with the
|
||||
@code{--with-ieee-fp=no} configure option, then a condition is
|
||||
signaled for every infinity or NaN encountered. If not, the behaviour
|
||||
can be controlled by @code{ext:trap-fpe}. By default, a condition is
|
||||
signaled for invalid operation, division by zero and floating point
|
||||
overflows. If the @code{ECL_OPT_TRAP_SIGFPE} option is false, no
|
||||
conditions are signaled by default (Note that in this case, if you
|
||||
enable trapping of floating point exceptions with @code{ext:trap-fpe},
|
||||
then you have to install your own signal handler).
|
||||
@code{--without-ieee-fp} configure option, then a condition is signaled
|
||||
for every infinity or NaN encountered. If not, floating point exceptions
|
||||
can be disabled at build time using the @code{--without-fpe} configure
|
||||
option. Otherwise, if both @code{--with-ieee-fp} and @code{--with-fpe}
|
||||
options are on, by default, a condition is signaled for invalid
|
||||
operation, division by zero and floating point overflows. This can be
|
||||
changed at runtime by using @code{ext:trap-fpe}. If the
|
||||
@code{ECL_OPT_TRAP_SIGFPE} boot option is false, no conditions are
|
||||
signaled by default (Note that in this case, if you enable trapping of
|
||||
floating point exceptions with @code{ext:trap-fpe}, then you have to
|
||||
install your own signal handler).
|
||||
|
||||
@lspindex ext:trap-fpe
|
||||
@defun ext:trap-fpe condition flag
|
||||
|
|
@ -91,6 +94,10 @@ floating point exception for the conditions passed in @var{condition}.
|
|||
@var{condition} can be either a symbol denoting a single condition,
|
||||
@code{t} for all conditions that are enabled by default or a value
|
||||
obtained from an earlier call to @code{ext:trap-fpe} with @code{last}.
|
||||
|
||||
@subsubheading See also
|
||||
@code{ECL_WITH_LISP_FPE}
|
||||
|
||||
@end defun
|
||||
|
||||
@node Numbers - Random-States
|
||||
|
|
|
|||
|
|
@ -263,4 +263,8 @@ will output
|
|||
@verbatim
|
||||
inf 0
|
||||
@end verbatim
|
||||
|
||||
@subsubheading See also
|
||||
@code{ext:trap-fpe}
|
||||
|
||||
@end defmac
|
||||
|
|
|
|||
|
|
@ -303,7 +303,7 @@
|
|||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#undef HAVE_FCNTL_H
|
||||
|
||||
/* feenableexcept is available */
|
||||
/* feenableexcept works */
|
||||
#undef HAVE_FEENABLEEXCEPT
|
||||
|
||||
/* Define to 1 if you have the <fenv.h> header file. */
|
||||
|
|
|
|||
|
|
@ -63,9 +63,7 @@ typedef cl_object (*math_one_arg_fn)(cl_object);
|
|||
cl_object ecl_##name(cl_object arg) \
|
||||
{ \
|
||||
cl_object out; \
|
||||
ECL_MATHERR_CLEAR; \
|
||||
out = ecl_##name##_ne(arg); \
|
||||
ECL_MATHERR_TEST; \
|
||||
return out; \
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -87,17 +87,4 @@
|
|||
# define ECL_WITH_LISP_FPE_END } while (0)
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_FENV_H) && !defined(HAVE_FEENABLEEXCEPT) && !defined(ECL_AVOID_FPE_H)
|
||||
# define ECL_USED_EXCEPTIONS (FE_DIVBYZERO|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW)
|
||||
# define ECL_MATHERR_CLEAR feclearexcept(FE_ALL_EXCEPT)
|
||||
# define ECL_MATHERR_TEST do { \
|
||||
int bits = fetestexcept(ECL_USED_EXCEPTIONS); \
|
||||
unlikely_if (bits) ecl_deliver_fpe(bits); } while(0)
|
||||
#else
|
||||
# define ECL_MATHERR_CLEAR
|
||||
# define ECL_MATHERR_TEST
|
||||
#endif
|
||||
|
||||
extern void ecl_deliver_fpe(int flags);
|
||||
|
||||
#endif /* !ECL_MATH_FENV_H */
|
||||
|
|
|
|||
|
|
@ -1238,6 +1238,7 @@
|
|||
;;;
|
||||
;;; On some platforms (without feenableexcept) compiling code with
|
||||
;;; constants being infinity cause fpe-exception.
|
||||
#+ieee-floating-point
|
||||
(test cmp.0056.artificial-fpe
|
||||
(finishes
|
||||
(funcall (compile nil
|
||||
|
|
|
|||
|
|
@ -224,9 +224,13 @@
|
|||
;; exp, sqrt, log and log1p
|
||||
(finishes (mapc (lambda (cf) (exp cf)) all-cfloats) "exp1")
|
||||
(finishes (mapc (lambda (cf) (sqrt cf)) all-cfloats) "sqrt")
|
||||
(finishes (mapc (lambda (cf) (if (zerop cf)
|
||||
(signals division-by-zero (log cf))
|
||||
(log cf)))
|
||||
(finishes (mapc (lambda (cf)
|
||||
#+floating-point-exceptions
|
||||
(if (zerop cf)
|
||||
(signals division-by-zero (log cf))
|
||||
(log cf))
|
||||
#-floating-point-exceptions
|
||||
(log cf))
|
||||
all-cfloats) "log1")
|
||||
(finishes (mapc (lambda (cf) (si:log1p cf)) all-cfloats) "log1p")
|
||||
;; log operations on floats should give corresponding cfloat type
|
||||
|
|
|
|||
|
|
@ -332,6 +332,7 @@ Common Lisp type contagion rules."
|
|||
|
||||
;;; ... but we don't, therefore everything throws arithmetic errors.
|
||||
|
||||
#+floating-point-exceptions
|
||||
(test ieee-fp.0010.NaN-floor/ceiling/truncate/round/mod/rem
|
||||
(loop :for function :in '(floor ceiling truncate round
|
||||
ffloor fceiling ftruncate fround
|
||||
|
|
@ -347,6 +348,7 @@ Common Lisp type contagion rules."
|
|||
(for-all-number-subtypes (x float 0)
|
||||
(signals arithmetic-error (funcall function x x)))))
|
||||
|
||||
#+floating-point-exceptions
|
||||
(test ieee-fp.0011.infinity-floor/ceiling/truncate/round
|
||||
(loop :for function :in '(floor ceiling truncate round
|
||||
ffloor fceiling ftruncate fround
|
||||
|
|
|
|||
|
|
@ -191,10 +191,11 @@
|
|||
;;; Date: 2016-12-21
|
||||
;;; Description:
|
||||
;;;
|
||||
;;; `sleep' sues `ECL_WITHOUT_FPE_BEGIN' which didn't restore fpe
|
||||
;;; `sleep' uses `ECL_WITHOUT_FPE_BEGIN' which didn't restore fpe
|
||||
;;; correctly.
|
||||
;;;
|
||||
;;; Bug: https://gitlab.com/embeddable-common-lisp/ecl/issues/317
|
||||
#+floating-point-exceptions
|
||||
(test mix.0013.sleep-without-fpe
|
||||
(sleep 0.1)
|
||||
(let ((a 1.0)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue