1#include <fenv.h> 2#include <features.h> 3 4#if __HAVE_68881__ || __mcffpu__ 5 6static unsigned getsr() 7{ 8 unsigned v; 9 __asm__ __volatile__ ("fmove.l %%fpsr,%0" : "=dm"(v)); 10 return v; 11} 12 13static void setsr(unsigned v) 14{ 15 __asm__ __volatile__ ("fmove.l %0,%%fpsr" : : "dm"(v)); 16} 17 18static unsigned getcr() 19{ 20 unsigned v; 21 __asm__ __volatile__ ("fmove.l %%fpcr,%0" : "=dm"(v)); 22 return v; 23} 24 25static void setcr(unsigned v) 26{ 27 __asm__ __volatile__ ("fmove.l %0,%%fpcr" : : "dm"(v)); 28} 29 30int feclearexcept(int mask) 31{ 32 if (mask & ~FE_ALL_EXCEPT) return -1; 33 setsr(getsr() & ~mask); 34 return 0; 35} 36 37int feraiseexcept(int mask) 38{ 39 if (mask & ~FE_ALL_EXCEPT) return -1; 40 setsr(getsr() | mask); 41 return 0; 42} 43 44int fetestexcept(int mask) 45{ 46 return getsr() & mask; 47} 48 49int fegetround(void) 50{ 51 return getcr() & FE_UPWARD; 52} 53 54hidden int __fesetround(int r) 55{ 56 setcr((getcr() & ~FE_UPWARD) | r); 57 return 0; 58} 59 60int fegetenv(fenv_t *envp) 61{ 62 envp->__control_register = getcr(); 63 envp->__status_register = getsr(); 64 __asm__ __volatile__ ("fmove.l %%fpiar,%0" 65 : "=dm"(envp->__instruction_address)); 66 return 0; 67} 68 69int fesetenv(const fenv_t *envp) 70{ 71 static const fenv_t default_env = { 0 }; 72 if (envp == FE_DFL_ENV) 73 envp = &default_env; 74 setcr(envp->__control_register); 75 setsr(envp->__status_register); 76 __asm__ __volatile__ ("fmove.l %0,%%fpiar" 77 : : "dm"(envp->__instruction_address)); 78 return 0; 79} 80 81#else 82 83#include "../fenv.c" 84 85#endif 86