86 lines
1.4 KiB
C
86 lines
1.4 KiB
C
#include <fenv.h>
|
|
#include <features.h>
|
|
|
|
#if __HAVE_68881__ || __mcffpu__
|
|
|
|
static unsigned getsr()
|
|
{
|
|
unsigned v;
|
|
__asm__ __volatile__ ("fmove.l %%fpsr,%0" : "=dm"(v));
|
|
return v;
|
|
}
|
|
|
|
static void setsr(unsigned v)
|
|
{
|
|
__asm__ __volatile__ ("fmove.l %0,%%fpsr" : : "dm"(v));
|
|
}
|
|
|
|
static unsigned getcr()
|
|
{
|
|
unsigned v;
|
|
__asm__ __volatile__ ("fmove.l %%fpcr,%0" : "=dm"(v));
|
|
return v;
|
|
}
|
|
|
|
static void setcr(unsigned v)
|
|
{
|
|
__asm__ __volatile__ ("fmove.l %0,%%fpcr" : : "dm"(v));
|
|
}
|
|
|
|
int feclearexcept(int mask)
|
|
{
|
|
if (mask & ~FE_ALL_EXCEPT) return -1;
|
|
setsr(getsr() & ~mask);
|
|
return 0;
|
|
}
|
|
|
|
int feraiseexcept(int mask)
|
|
{
|
|
if (mask & ~FE_ALL_EXCEPT) return -1;
|
|
setsr(getsr() | mask);
|
|
return 0;
|
|
}
|
|
|
|
int fetestexcept(int mask)
|
|
{
|
|
return getsr() & mask;
|
|
}
|
|
|
|
int fegetround(void)
|
|
{
|
|
return getcr() & FE_UPWARD;
|
|
}
|
|
|
|
hidden int __fesetround(int r)
|
|
{
|
|
setcr((getcr() & ~FE_UPWARD) | r);
|
|
return 0;
|
|
}
|
|
|
|
int fegetenv(fenv_t *envp)
|
|
{
|
|
envp->__control_register = getcr();
|
|
envp->__status_register = getsr();
|
|
__asm__ __volatile__ ("fmove.l %%fpiar,%0"
|
|
: "=dm"(envp->__instruction_address));
|
|
return 0;
|
|
}
|
|
|
|
int fesetenv(const fenv_t *envp)
|
|
{
|
|
static const fenv_t default_env = { 0 };
|
|
if (envp == FE_DFL_ENV)
|
|
envp = &default_env;
|
|
setcr(envp->__control_register);
|
|
setsr(envp->__status_register);
|
|
__asm__ __volatile__ ("fmove.l %0,%%fpiar"
|
|
: : "dm"(envp->__instruction_address));
|
|
return 0;
|
|
}
|
|
|
|
#else
|
|
|
|
#include "../fenv.c"
|
|
|
|
#endif
|