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