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