From: Nadav Har'El <[email protected]>
Committer: Nadav Har'El <[email protected]>
Branch: master
Implement feenableexcept() and friends
Implement the functions feenableexcept(), fedisableexcept() and
fegetexcept(), non-standard glibc functions which allows controlling
which FPU events generate a floating point exception.
Signed-off-by: Nadav Har'El <[email protected]>
Message-Id: <[email protected]>
---
diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -849,6 +849,7 @@ objects += arch/$(arch)/interrupt.o
objects += arch/$(arch)/pci.o
objects += arch/$(arch)/msi.o
objects += arch/$(arch)/power.o
+objects += arch/$(arch)/feexcept.o
$(out)/arch/x64/string-ssse3.o: CXXFLAGS += -mssse3
diff --git a/arch/aarch64/feexcept.cc b/arch/aarch64/feexcept.cc
--- a/arch/aarch64/feexcept.cc
+++ b/arch/aarch64/feexcept.cc
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2017 ScyllaDB, Ltd.
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+#include <osv/types.h>
+#include <osv/stubbing.hh>
+#include <fenv.h>
+// Note that musl's fenv.h does not define feenableexcept and friends, so
+// we need to 'extern "C"' them here, as no header file does this.
+
+extern "C"
+int feenableexcept(int mask)
+{
+ WARN_STUBBED();
+ // The feenableexcept says it returns -1 on failure.
+ return -1;
+}
+
+extern "C"
+int fedisableexcept(int mask)
+{
+ WARN_STUBBED();
+ return -1;
+}
+
+extern "C"
+int fegetexcept()
+{
+ WARN_STUBBED();
+ return -1;
+}
diff --git a/arch/x64/feexcept.cc b/arch/x64/feexcept.cc
--- a/arch/x64/feexcept.cc
+++ b/arch/x64/feexcept.cc
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2017 ScyllaDB, Ltd.
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+#include <osv/types.h>
+#include <fenv.h>
+
+int feenableexcept(int mask)
+{
+ // The feenableexcept() manual page suggests that -1 should be returned
+ // on failure, and theoretically this could include the case that
invalid
+ // bits are passed in mask. But in practice, the Linux implementation
+ // simply ignores invalid bits, and never returns -1.
+ mask &= FE_ALL_EXCEPT;
+
+ // Update the the x87 control word. Note that:
+ // 1. We need to leave the other bits (non-exception related)
unchanged.
+ // 2. A 1 bit means disable exception (opposite of our "mask")
+ // 3. This function is supposed to only enable exceptions.
+ u16 cw;
+ asm volatile("fstcw %0" : "=m"(cw));
+ // Save the previous set of enabled exceptions, for returning later.
+ int ret = (~cw) & FE_ALL_EXCEPT;
+ cw &= ~mask;
+ asm volatile("fldcw %0" : : "m"(cw));
+
+ // Also update the SSE control and status register (here the relevant
+ // bits start at bit 7).
+ u32 csr;
+ asm volatile("stmxcsr %0" : "=m"(csr));
+ csr &= ~(mask << 7);
+ asm volatile("ldmxcsr %0" : : "m"(csr));
+
+ return ret;
+}
+
+int fedisableexcept(int mask)
+{
+ mask &= FE_ALL_EXCEPT;
+
+ u16 cw;
+ asm volatile("fstcw %0" : "=m"(cw));
+ int ret = (~cw) & FE_ALL_EXCEPT;
+ cw |= mask;
+ asm volatile("fldcw %0" : : "m"(cw));
+
+ u32 csr;
+ asm volatile("stmxcsr %0" : "=m"(csr));
+ csr |= mask << 7;
+ asm volatile("ldmxcsr %0" : : "m"(csr));
+
+ return ret;
+}
+
+int fegetexcept()
+{
+ u16 cw;
+ asm volatile("fstcw %0" : "=m"(cw));
+ return (~cw) & FE_ALL_EXCEPT;
+}
--
You received this message because you are subscribed to the Google Groups "OSv
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.