xref: /third_party/musl/src/fenv/m68k/fenv.c (revision 570af302)
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