Skip to content

Commit 5041442

Browse files
author
Dominic Chen
committed
[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
1 parent 3a75551 commit 5041442

File tree

1 file changed

+25
-3
lines changed

1 file changed

+25
-3
lines changed

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

+25-3
Original file line numberDiff line numberDiff line change
@@ -215,10 +215,12 @@ LIBC_INLINE int clear_except(int excepts) {
215215
}
216216

217217
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();
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

348350
namespace 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.
353355
struct 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
358367
struct FPState {
359368
X87StateDescriptor x87_status;
@@ -557,7 +566,14 @@ LIBC_INLINE int set_env(const fenv_t *envp) {
557566
#else
558567
LIBC_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

Comments
 (0)