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