diff --git a/libc/utils/FPUtil/x86_64/FEnv.h b/libc/utils/FPUtil/x86_64/FEnv.h --- a/libc/utils/FPUtil/x86_64/FEnv.h +++ b/libc/utils/FPUtil/x86_64/FEnv.h @@ -48,6 +48,8 @@ static constexpr uint16_t Inexact = 0x20; }; +static constexpr uint16_t ExceptionSummaryStatusBit = 0x80; + // The exception control bits occupy six bits, one bit for each exception. // In the x87 control word, they occupy the first 6 bits. In the MXCSR // register, they occupy bits 7 to 12. @@ -194,6 +196,14 @@ (statusValue & internal::getMXCSR())); } +// This function returns a bitmap of which exceptions selected are enabled. +static inline int isEnabled(int excepts) { + uint16_t x87CW = internal::getX87ControlWord(); + return excepts & (~x87CW); + // The exceptions are enabled if the bit is zero (unmasked), + // so that is why the negation before the & operation. +} + static inline int raiseExcept(int excepts) { uint16_t statusValue = internal::getStatusValueForExcept(excepts); @@ -214,6 +224,9 @@ internal::X87State state; internal::getX87State(state); state.StatusWord |= internal::ExceptionFlags::Invalid; + if (isEnabled(internal::ExceptionFlags::Invalid)) { + state.StatusWord |= internal::ExceptionSummaryStatusBit; + } internal::writeX87State(state); internal::fwait(); } @@ -221,6 +234,9 @@ internal::X87State state; internal::getX87State(state); state.StatusWord |= internal::ExceptionFlags::DivByZero; + if (isEnabled(internal::ExceptionFlags::DivByZero)) { + state.StatusWord |= internal::ExceptionSummaryStatusBit; + } internal::writeX87State(state); internal::fwait(); } @@ -228,6 +244,9 @@ internal::X87State state; internal::getX87State(state); state.StatusWord |= internal::ExceptionFlags::Overflow; + if (isEnabled(internal::ExceptionFlags::Overflow)) { + state.StatusWord |= internal::ExceptionSummaryStatusBit; + } internal::writeX87State(state); internal::fwait(); } @@ -235,6 +254,9 @@ internal::X87State state; internal::getX87State(state); state.StatusWord |= internal::ExceptionFlags::Underflow; + if (isEnabled(internal::ExceptionFlags::Underflow)) { + state.StatusWord |= internal::ExceptionSummaryStatusBit; + } internal::writeX87State(state); internal::fwait(); } @@ -242,6 +264,9 @@ internal::X87State state; internal::getX87State(state); state.StatusWord |= internal::ExceptionFlags::Inexact; + if (isEnabled(internal::ExceptionFlags::Inexact)) { + state.StatusWord |= internal::ExceptionSummaryStatusBit; + } internal::writeX87State(state); internal::fwait(); }