[libc-commits] [libc] dd8b93a - [libc] Fix x86_64 fenv implementation for windows
Siva Chandra Reddy via libc-commits
libc-commits at lists.llvm.org
Tue Jul 27 13:53:10 PDT 2021
Author: Siva Chandra Reddy
Date: 2021-07-27T20:53:01Z
New Revision: dd8b93a9e76bc5e3c8fc521fcb06c779371211d3
URL: https://github.com/llvm/llvm-project/commit/dd8b93a9e76bc5e3c8fc521fcb06c779371211d3
DIFF: https://github.com/llvm/llvm-project/commit/dd8b93a9e76bc5e3c8fc521fcb06c779371211d3.diff
LOG: [libc] Fix x86_64 fenv implementation for windows
All fenv functions are also enabled for windows. Since two tests,
enabled_exceptions_test and feholdexcept_test are still failing on
windows, they have been disabled.
Reviewed By: aeubanks
Differential Revision: https://reviews.llvm.org/D106808
Added:
Modified:
libc/config/windows/entrypoints.txt
libc/test/src/fenv/CMakeLists.txt
libc/utils/FPUtil/x86_64/FEnvImpl.h
Removed:
################################################################################
diff --git a/libc/config/windows/entrypoints.txt b/libc/config/windows/entrypoints.txt
index 20a59a0184635..38892340e915a 100644
--- a/libc/config/windows/entrypoints.txt
+++ b/libc/config/windows/entrypoints.txt
@@ -41,6 +41,19 @@ set(TARGET_LIBC_ENTRYPOINTS
)
set(TARGET_LIBM_ENTRYPOINTS
+ # fenv.h entrypoints
+ libc.src.fenv.feclearexcept
+ libc.src.fenv.fegetenv
+ libc.src.fenv.fegetexceptflag
+ libc.src.fenv.fegetround
+ libc.src.fenv.feholdexcept
+ libc.src.fenv.fesetenv
+ libc.src.fenv.fesetexceptflag
+ libc.src.fenv.fesetround
+ libc.src.fenv.feraiseexcept
+ libc.src.fenv.fetestexcept
+ libc.src.fenv.feupdateenv
+
# math.h entrypoints
libc.src.math.copysign
libc.src.math.copysignf
diff --git a/libc/test/src/fenv/CMakeLists.txt b/libc/test/src/fenv/CMakeLists.txt
index 88d9663ae472d..9ff2c189bab87 100644
--- a/libc/test/src/fenv/CMakeLists.txt
+++ b/libc/test/src/fenv/CMakeLists.txt
@@ -71,9 +71,11 @@ add_libc_unittest(
libc.utils.FPUtil.fputil
)
-if (NOT LLVM_USE_SANITIZER)
+if (NOT (LLVM_USE_SANITIZER OR (${LIBC_TARGET_OS} STREQUAL "windows")))
# Sanitizers don't like SIGFPE. So, we will run the
# tests which raise SIGFPE only in non-sanitizer builds.
+ # The tests are also disabled for Windows as they fail currently.
+ # TODO: Investigate and fix the windows failures and enable them for Windows.
add_fp_unittest(
enabled_exceptions_test
SUITE
diff --git a/libc/utils/FPUtil/x86_64/FEnvImpl.h b/libc/utils/FPUtil/x86_64/FEnvImpl.h
index fae74bb5da9bc..b3e5fc58a2e0d 100644
--- a/libc/utils/FPUtil/x86_64/FEnvImpl.h
+++ b/libc/utils/FPUtil/x86_64/FEnvImpl.h
@@ -91,22 +91,9 @@ struct X87StateDescriptor {
uint16_t StatusWord;
uint16_t Unused2;
// TODO: Elaborate the remaining 20 bytes as required.
-#if !(defined(_WIN32))
uint32_t _[5];
-#endif
};
-struct FPState {
- X87StateDescriptor X87Status;
-#if !(defined(_WIN32))
- uint32_t MXCSR;
-#endif
-};
-
-static_assert(
- sizeof(fenv_t) == sizeof(FPState),
- "Internal floating point state does not match the public fenv_t type.");
-
static inline uint16_t getX87ControlWord() {
uint16_t w;
__asm__ __volatile__("fnstcw %0" : "=m"(w)::);
@@ -338,7 +325,48 @@ static inline int setRound(int mode) {
return 0;
}
-#if !(defined(_WIN32))
+namespace internal {
+
+#ifdef _WIN32
+// MSVC fenv.h defines a very simple representation of the floating point state
+// which just consists of control and status words of the x87 unit.
+struct FPState {
+ uint32_t ControlWord;
+ uint32_t StatusWord;
+};
+#else
+struct FPState {
+ X87StateDescriptor X87Status;
+ uint32_t MXCSR;
+};
+#endif // _WIN32
+
+} // namespace internal
+
+static_assert(
+ sizeof(fenv_t) == sizeof(internal::FPState),
+ "Internal floating point state does not match the public fenv_t type.");
+
+#ifdef _WIN32
+static inline int getEnv(fenv_t *envp) {
+ internal::FPState *state = reinterpret_cast<internal::FPState *>(envp);
+ internal::X87StateDescriptor X87Status;
+ internal::getX87StateDescriptor(X87Status);
+ state->ControlWord = X87Status.ControlWord;
+ state->StatusWord = X87Status.StatusWord;
+ return 0;
+}
+
+static inline int setEnv(const fenv_t *envp) {
+ const internal::FPState *state =
+ reinterpret_cast<const internal::FPState *>(envp);
+ internal::X87StateDescriptor X87Status;
+ X87Status.ControlWord = state->ControlWord;
+ X87Status.StatusWord = state->StatusWord;
+ internal::writeX87StateDescriptor(X87Status);
+ return 0;
+}
+#else
static inline int getEnv(fenv_t *envp) {
internal::FPState *state = reinterpret_cast<internal::FPState *>(envp);
internal::getX87StateDescriptor(state->X87Status);
More information about the libc-commits
mailing list