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,13 @@ (statusValue & internal::getMXCSR())); } +static inline int isEnabled(int excepts) { + uint16_t x87CW = internal::getX87ControlWord(); + return excepts & (~x87CW); + // since we want each bit where excepts is 1 and x87CW is 0 + // (since 0 means enabled) I just and excepts and the inverse of the CW state. +} + static inline int raiseExcept(int excepts) { uint16_t statusValue = internal::getStatusValueForExcept(excepts); @@ -214,6 +223,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 +233,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 +243,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 +253,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 +263,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(); }