@@ -215,10 +215,12 @@ LIBC_INLINE int clear_except(int excepts) {
215215}
216216
217217LIBC_INLINE int test_except (int excepts) {
218- uint16_t status_value = internal::get_status_value_for_except (excepts);
218+ uint16_t status_word = internal::get_x87_status_word ();
219+ uint32_t mxcsr = internal::get_mxcsr ();
219220 // Check both x87 status word and MXCSR.
221+ uint16_t status_value = internal::get_status_value_for_except (excepts);
220222 return internal::exception_status_to_macro (
221- static_cast <uint16_t >(status_value & internal::get_mxcsr ( )));
223+ static_cast <uint16_t >(status_value & (status_word | mxcsr )));
222224}
223225
224226// Sets the exception flags but does not trigger the exception handler.
@@ -347,13 +349,20 @@ LIBC_INLINE int set_round(int mode) {
347349
348350namespace internal {
349351
350- #ifdef _WIN32
352+ #if defined( _WIN32)
351353// MSVC fenv.h defines a very simple representation of the floating point state
352354// which just consists of control and status words of the x87 unit.
353355struct FPState {
354356 uint32_t control_word;
355357 uint32_t status_word;
356358};
359+ #elif defined(__APPLE__)
360+ struct FPState {
361+ uint16_t control_word;
362+ uint16_t status_word;
363+ uint32_t mxcsr;
364+ uint8_t reserved[8 ];
365+ };
357366#else
358367struct FPState {
359368 X87StateDescriptor x87_status;
@@ -557,7 +566,14 @@ LIBC_INLINE int set_env(const fenv_t *envp) {
557566#else
558567LIBC_INLINE int get_env (fenv_t *envp) {
559568 internal::FPState *state = reinterpret_cast <internal::FPState *>(envp);
569+ #ifdef __APPLE__
570+ internal::X87StateDescriptor x87_status;
571+ internal::get_x87_state_descriptor (x87_status);
572+ state->control_word = x87_status.control_word ;
573+ state->status_word = x87_status.status_word ;
574+ #else
560575 internal::get_x87_state_descriptor (state->x87_status );
576+ #endif // __APPLE__
561577 state->mxcsr = internal::get_mxcsr ();
562578 return 0 ;
563579}
@@ -605,12 +621,18 @@ LIBC_INLINE int set_env(const fenv_t *envp) {
605621
606622 // Copy the exception status flags from envp.
607623 x87_status.status_word &= ~uint16_t (0x3F );
624+ #ifdef __APPLE__
625+ x87_status.status_word |= (fpstate->status_word & 0x3F );
626+ // We can set the x87 control word as is as there no sensitive bits.
627+ x87_status.control_word = fpstate->control_word ;
628+ #else
608629 x87_status.status_word |= (fpstate->x87_status .status_word & 0x3F );
609630 // Copy other non-sensitive parts of the status word.
610631 for (int i = 0 ; i < 5 ; i++)
611632 x87_status._ [i] = fpstate->x87_status ._ [i];
612633 // We can set the x87 control word as is as there no sensitive bits.
613634 x87_status.control_word = fpstate->x87_status .control_word ;
635+ #endif // __APPLE__
614636 internal::write_x87_state_descriptor (x87_status);
615637
616638 // We can write the MXCSR state as is as there are no sensitive bits.
0 commit comments