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 Workerstatic 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 Workerstatic 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 Workerstatic 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 Workerstatic 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 Workerint 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 Workerint 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 Workerint 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 Workerint 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 Workerhidden 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 Workerint 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 Workerint 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