ardupilot/libraries/AP_Common/missing/fenv.h

75 lines
1.8 KiB
C
Raw Normal View History

#pragma once
#include_next <fenv.h>
#ifndef HAVE_FEENABLEEXCEPT
#if defined(__APPLE__) && defined(__MACH__)
// Public domain polyfill for feenableexcept on OS X
// http://www-personal.umich.edu/~williams/archive/computation/fe-handling-example.c
inline int feenableexcept(unsigned int excepts)
{
static fenv_t fenv;
unsigned int new_excepts = excepts & FE_ALL_EXCEPT;
// previous masks
unsigned int old_excepts;
if (fegetenv(&fenv)) {
return -1;
}
old_excepts = fenv.__control & FE_ALL_EXCEPT;
// unmask
fenv.__control &= ~new_excepts;
fenv.__mxcsr &= ~(new_excepts << 7);
return fesetenv(&fenv) ? -1 : old_excepts;
}
inline int fedisableexcept(unsigned int excepts)
{
static fenv_t fenv;
unsigned int new_excepts = excepts & FE_ALL_EXCEPT;
// all previous masks
unsigned int old_excepts;
if (fegetenv(&fenv)) {
return -1;
}
old_excepts = fenv.__control & FE_ALL_EXCEPT;
// mask
fenv.__control |= new_excepts;
fenv.__mxcsr |= new_excepts << 7;
return fesetenv(&fenv) ? -1 : old_excepts;
}
#else
inline int feenableexcept(unsigned int excepts)
{
#pragma STDC FENV_ACCESS ON
fexcept_t flags;
/* Save current exception flags. */
fegetexceptflag(&flags, FE_ALL_EXCEPT);
feclearexcept(FE_ALL_EXCEPT); /* clear all fp exception conditions */
return fesetexceptflag(&flags, excepts) != 0 ? -1 : flags; /* set new flags */
}
inline int fedisableexcept(unsigned int excepts)
{
#pragma STDC FENV_ACCESS ON
fexcept_t flags;
/* Save current exception flags. */
fegetexceptflag(&flags, FE_ALL_EXCEPT);
feclearexcept(FE_ALL_EXCEPT); /* clear all fp exception conditions */
return fesetexceptflag(&flags, ~excepts) != 0 ? -1 : flags; /* set new flags */
}
#endif
#endif