summaryrefslogtreecommitdiff
path: root/src/fenv
diff options
context:
space:
mode:
authorBobby Bingham <koorogi@koorogi.info>2016-04-30 19:18:17 -0500
committerRich Felker <dalias@aerifal.cx>2016-05-08 22:57:40 -0400
commitc0ede9e4046a0882d83ae4b45c7dfac86fb7c15d (patch)
tree02956e3cc93a50bcc9c946fbc2bbffb883e72f2f /src/fenv
parent6bc7d9c411c3a32cfa9d239b73fffb2ba66dd9ff (diff)
downloadmusl-c0ede9e4046a0882d83ae4b45c7dfac86fb7c15d.tar.gz
add powerpc64 port
Diffstat (limited to 'src/fenv')
-rw-r--r--src/fenv/powerpc64/fenv.c68
1 files changed, 68 insertions, 0 deletions
diff --git a/src/fenv/powerpc64/fenv.c b/src/fenv/powerpc64/fenv.c
new file mode 100644
index 00000000..739420b7
--- /dev/null
+++ b/src/fenv/powerpc64/fenv.c
@@ -0,0 +1,68 @@
+#define _GNU_SOURCE
+#include <fenv.h>
+
+static inline double get_fpscr_f(void)
+{
+ double d;
+ __asm__ __volatile__("mffs %0" : "=d"(d));
+ return d;
+}
+
+static inline long get_fpscr(void)
+{
+ return (union {double f; long i;}) {get_fpscr_f()}.i;
+}
+
+static inline void set_fpscr_f(double fpscr)
+{
+ __asm__ __volatile__("mtfsf 255, %0" : : "d"(fpscr));
+}
+
+static void set_fpscr(long fpscr)
+{
+ set_fpscr_f((union {long i; double f;}) {fpscr}.f);
+}
+
+int feclearexcept(int mask)
+{
+ mask &= FE_ALL_EXCEPT;
+ if (mask & FE_INVALID) mask |= FE_ALL_INVALID;
+ set_fpscr(get_fpscr() & ~mask);
+ return 0;
+}
+
+int feraiseexcept(int mask)
+{
+ mask &= FE_ALL_EXCEPT;
+ if (mask & FE_INVALID) mask |= FE_INVALID_SOFTWARE;
+ set_fpscr(get_fpscr() | mask);
+ return 0;
+}
+
+int fetestexcept(int mask)
+{
+ return get_fpscr() & mask & FE_ALL_EXCEPT;
+}
+
+int fegetround(void)
+{
+ return get_fpscr() & 3;
+}
+
+int __fesetround(int r)
+{
+ set_fpscr(get_fpscr() & ~3L | r);
+ return 0;
+}
+
+int fegetenv(fenv_t *envp)
+{
+ *envp = get_fpscr_f();
+ return 0;
+}
+
+int fesetenv(const fenv_t *envp)
+{
+ set_fpscr_f(envp != FE_DFL_ENV ? *envp : 0);
+ return 0;
+}