[libc-commits] [libc] 5041442 - [libc][math] Fix floating-point test support on x86_64 Apple machines

Dominic Chen via libc-commits libc-commits at lists.llvm.org
Wed Jul 12 00:38:53 PDT 2023


Author: Dominic Chen
Date: 2023-07-12T00:38:45-07:00
New Revision: 50414422ac155f75fa5d0b9174cfa97ed2b78f94

URL: https://github.com/llvm/llvm-project/commit/50414422ac155f75fa5d0b9174cfa97ed2b78f94
DIFF: https://github.com/llvm/llvm-project/commit/50414422ac155f75fa5d0b9174cfa97ed2b78f94.diff

LOG: [libc][math] Fix floating-point test support on x86_64 Apple machines

Provide platform-specific x87 FPU definitions and operations

Differential Revision: https://reviews.llvm.org/D153823

Added: 
    

Modified: 
    libc/src/__support/FPUtil/x86_64/FEnvImpl.h

Removed: 
    


################################################################################
diff  --git a/libc/src/__support/FPUtil/x86_64/FEnvImpl.h b/libc/src/__support/FPUtil/x86_64/FEnvImpl.h
index 5a496f631b011b..d6faed72e674e5 100644
--- a/libc/src/__support/FPUtil/x86_64/FEnvImpl.h
+++ b/libc/src/__support/FPUtil/x86_64/FEnvImpl.h
@@ -215,10 +215,12 @@ LIBC_INLINE int clear_except(int excepts) {
 }
 
 LIBC_INLINE int test_except(int excepts) {
-  uint16_t status_value = internal::get_status_value_for_except(excepts);
+  uint16_t status_word = internal::get_x87_status_word();
+  uint32_t mxcsr = internal::get_mxcsr();
   // Check both x87 status word and MXCSR.
+  uint16_t status_value = internal::get_status_value_for_except(excepts);
   return internal::exception_status_to_macro(
-      static_cast<uint16_t>(status_value & internal::get_mxcsr()));
+      static_cast<uint16_t>(status_value & (status_word | mxcsr)));
 }
 
 // Sets the exception flags but does not trigger the exception handler.
@@ -347,13 +349,20 @@ LIBC_INLINE int set_round(int mode) {
 
 namespace internal {
 
-#ifdef _WIN32
+#if defined(_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 control_word;
   uint32_t status_word;
 };
+#elif defined(__APPLE__)
+struct FPState {
+  uint16_t control_word;
+  uint16_t status_word;
+  uint32_t mxcsr;
+  uint8_t reserved[8];
+};
 #else
 struct FPState {
   X87StateDescriptor x87_status;
@@ -557,7 +566,14 @@ LIBC_INLINE int set_env(const fenv_t *envp) {
 #else
 LIBC_INLINE int get_env(fenv_t *envp) {
   internal::FPState *state = reinterpret_cast<internal::FPState *>(envp);
+#ifdef __APPLE__
+  internal::X87StateDescriptor x87_status;
+  internal::get_x87_state_descriptor(x87_status);
+  state->control_word = x87_status.control_word;
+  state->status_word = x87_status.status_word;
+#else
   internal::get_x87_state_descriptor(state->x87_status);
+#endif // __APPLE__
   state->mxcsr = internal::get_mxcsr();
   return 0;
 }
@@ -605,12 +621,18 @@ LIBC_INLINE int set_env(const fenv_t *envp) {
 
   // Copy the exception status flags from envp.
   x87_status.status_word &= ~uint16_t(0x3F);
+#ifdef __APPLE__
+  x87_status.status_word |= (fpstate->status_word & 0x3F);
+  // We can set the x87 control word as is as there no sensitive bits.
+  x87_status.control_word = fpstate->control_word;
+#else
   x87_status.status_word |= (fpstate->x87_status.status_word & 0x3F);
   // Copy other non-sensitive parts of the status word.
   for (int i = 0; i < 5; i++)
     x87_status._[i] = fpstate->x87_status._[i];
   // We can set the x87 control word as is as there no sensitive bits.
   x87_status.control_word = fpstate->x87_status.control_word;
+#endif // __APPLE__
   internal::write_x87_state_descriptor(x87_status);
 
   // We can write the MXCSR state as is as there are no sensitive bits.


        


More information about the libc-commits mailing list