@@ -215,10 +215,12 @@ LIBC_INLINE int clear_except(int excepts) {
215
215
}
216
216
217
217
LIBC_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 ();
219
220
// Check both x87 status word and MXCSR.
221
+ uint16_t status_value = internal::get_status_value_for_except (excepts);
220
222
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 )));
222
224
}
223
225
224
226
// Sets the exception flags but does not trigger the exception handler.
@@ -347,13 +349,20 @@ LIBC_INLINE int set_round(int mode) {
347
349
348
350
namespace internal {
349
351
350
- #ifdef _WIN32
352
+ #if defined( _WIN32)
351
353
// MSVC fenv.h defines a very simple representation of the floating point state
352
354
// which just consists of control and status words of the x87 unit.
353
355
struct FPState {
354
356
uint32_t control_word;
355
357
uint32_t status_word;
356
358
};
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
+ };
357
366
#else
358
367
struct FPState {
359
368
X87StateDescriptor x87_status;
@@ -557,7 +566,14 @@ LIBC_INLINE int set_env(const fenv_t *envp) {
557
566
#else
558
567
LIBC_INLINE int get_env (fenv_t *envp) {
559
568
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
560
575
internal::get_x87_state_descriptor (state->x87_status );
576
+ #endif // __APPLE__
561
577
state->mxcsr = internal::get_mxcsr ();
562
578
return 0 ;
563
579
}
@@ -605,12 +621,18 @@ LIBC_INLINE int set_env(const fenv_t *envp) {
605
621
606
622
// Copy the exception status flags from envp.
607
623
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
608
629
x87_status.status_word |= (fpstate->x87_status .status_word & 0x3F );
609
630
// Copy other non-sensitive parts of the status word.
610
631
for (int i = 0 ; i < 5 ; i++)
611
632
x87_status._ [i] = fpstate->x87_status ._ [i];
612
633
// We can set the x87 control word as is as there no sensitive bits.
613
634
x87_status.control_word = fpstate->x87_status .control_word ;
635
+ #endif // __APPLE__
614
636
internal::write_x87_state_descriptor (x87_status);
615
637
616
638
// We can write the MXCSR state as is as there are no sensitive bits.
0 commit comments