• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #define _GNU_SOURCE
2 #include <fenv.h>
3 #include <features.h>
4 
get_fpscr_f(void)5 static inline double get_fpscr_f(void)
6 {
7 	double d;
8 	__asm__ __volatile__("mffs %0" : "=d"(d));
9 	return d;
10 }
11 
get_fpscr(void)12 static inline long get_fpscr(void)
13 {
14 	return (union {double f; long i;}) {get_fpscr_f()}.i;
15 }
16 
set_fpscr_f(double fpscr)17 static inline void set_fpscr_f(double fpscr)
18 {
19 	__asm__ __volatile__("mtfsf 255, %0" : : "d"(fpscr));
20 }
21 
set_fpscr(long fpscr)22 static void set_fpscr(long fpscr)
23 {
24 	set_fpscr_f((union {long i; double f;}) {fpscr}.f);
25 }
26 
feclearexcept(int mask)27 int feclearexcept(int mask)
28 {
29 	mask &= FE_ALL_EXCEPT;
30 	if (mask & FE_INVALID) mask |= FE_ALL_INVALID;
31 	set_fpscr(get_fpscr() & ~mask);
32 	return 0;
33 }
34 
feraiseexcept(int mask)35 int feraiseexcept(int mask)
36 {
37 	mask &= FE_ALL_EXCEPT;
38 	if (mask & FE_INVALID) mask |= FE_INVALID_SOFTWARE;
39 	set_fpscr(get_fpscr() | mask);
40 	return 0;
41 }
42 
fetestexcept(int mask)43 int fetestexcept(int mask)
44 {
45 	return get_fpscr() & mask & FE_ALL_EXCEPT;
46 }
47 
fegetround(void)48 int fegetround(void)
49 {
50 	return get_fpscr() & 3;
51 }
52 
__fesetround(int r)53 hidden int __fesetround(int r)
54 {
55 	set_fpscr(get_fpscr() & ~3L | r);
56 	return 0;
57 }
58 
fegetenv(fenv_t * envp)59 int fegetenv(fenv_t *envp)
60 {
61 	*envp = get_fpscr_f();
62 	return 0;
63 }
64 
fesetenv(const fenv_t * envp)65 int fesetenv(const fenv_t *envp)
66 {
67 	set_fpscr_f(envp != FE_DFL_ENV ? *envp : 0);
68 	return 0;
69 }
70