fenv.c raw

   1  #include <fenv.h>
   2  #include <features.h>
   3  
   4  #if __HAVE_68881__ || __mcffpu__
   5  
   6  static unsigned getsr()
   7  {
   8  	unsigned v;
   9  	__asm__ __volatile__ ("fmove.l %%fpsr,%0" : "=dm"(v));
  10  	return v;
  11  }
  12  
  13  static void setsr(unsigned v)
  14  {
  15  	__asm__ __volatile__ ("fmove.l %0,%%fpsr" : : "dm"(v));
  16  }
  17  
  18  static unsigned getcr()
  19  {
  20  	unsigned v;
  21  	__asm__ __volatile__ ("fmove.l %%fpcr,%0" : "=dm"(v));
  22  	return v;
  23  }
  24  
  25  static void setcr(unsigned v)
  26  {
  27  	__asm__ __volatile__ ("fmove.l %0,%%fpcr" : : "dm"(v));
  28  }
  29  
  30  int feclearexcept(int mask)
  31  {
  32  	if (mask & ~FE_ALL_EXCEPT) return -1;
  33  	setsr(getsr() & ~mask);
  34  	return 0;
  35  }
  36  
  37  int feraiseexcept(int mask)
  38  {
  39  	if (mask & ~FE_ALL_EXCEPT) return -1;
  40  	setsr(getsr() | mask);
  41  	return 0;
  42  }
  43  
  44  int fetestexcept(int mask)
  45  {
  46  	return getsr() & mask;
  47  }
  48  
  49  int fegetround(void)
  50  {
  51  	return getcr() & FE_UPWARD;
  52  }
  53  
  54  hidden int __fesetround(int r)
  55  {
  56  	setcr((getcr() & ~FE_UPWARD) | r);
  57  	return 0;
  58  }
  59  
  60  int 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  
  69  int 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