From c698be47ff8cfa337079fc14947056f867676591 Mon Sep 17 00:00:00 2001 From: Siva Chandra Reddy Date: Thu, 22 Jul 2021 22:05:34 +0000 Subject: [PATCH] [libc] Raise denormal exception if the libc defines __FE_DENORM. Reviewed By: michaelrj Differential Revision: https://reviews.llvm.org/D106604 --- libc/utils/FPUtil/x86_64/FEnvImpl.h | 48 ++++++++++++++----------------------- 1 file changed, 18 insertions(+), 30 deletions(-) diff --git a/libc/utils/FPUtil/x86_64/FEnvImpl.h b/libc/utils/FPUtil/x86_64/FEnvImpl.h index b67222b..fae74bb 100644 --- a/libc/utils/FPUtil/x86_64/FEnvImpl.h +++ b/libc/utils/FPUtil/x86_64/FEnvImpl.h @@ -251,41 +251,29 @@ static inline int raiseExcept(int excepts) { // ensure that the writes by the exception handler are maintained // when raising the next exception. - if (statusValue & internal::ExceptionFlags::Invalid) { + auto raiseHelper = [](uint16_t singleExceptFlag) { internal::X87StateDescriptor state; internal::getX87StateDescriptor(state); - state.StatusWord |= internal::ExceptionFlags::Invalid; - internal::writeX87StateDescriptor(state); - internal::fwait(); - } - if (statusValue & internal::ExceptionFlags::DivByZero) { - internal::X87StateDescriptor state; - internal::getX87StateDescriptor(state); - state.StatusWord |= internal::ExceptionFlags::DivByZero; - internal::writeX87StateDescriptor(state); - internal::fwait(); - } - if (statusValue & internal::ExceptionFlags::Overflow) { - internal::X87StateDescriptor state; - internal::getX87StateDescriptor(state); - state.StatusWord |= internal::ExceptionFlags::Overflow; - internal::writeX87StateDescriptor(state); - internal::fwait(); - } - if (statusValue & internal::ExceptionFlags::Underflow) { - internal::X87StateDescriptor state; - internal::getX87StateDescriptor(state); - state.StatusWord |= internal::ExceptionFlags::Underflow; - internal::writeX87StateDescriptor(state); - internal::fwait(); - } - if (statusValue & internal::ExceptionFlags::Inexact) { - internal::X87StateDescriptor state; - internal::getX87StateDescriptor(state); - state.StatusWord |= internal::ExceptionFlags::Inexact; + state.StatusWord |= singleExceptFlag; internal::writeX87StateDescriptor(state); internal::fwait(); + }; + + if (statusValue & internal::ExceptionFlags::Invalid) + raiseHelper(internal::ExceptionFlags::Invalid); + if (statusValue & internal::ExceptionFlags::DivByZero) + raiseHelper(internal::ExceptionFlags::DivByZero); + if (statusValue & internal::ExceptionFlags::Overflow) + raiseHelper(internal::ExceptionFlags::Overflow); + if (statusValue & internal::ExceptionFlags::Underflow) + raiseHelper(internal::ExceptionFlags::Underflow); + if (statusValue & internal::ExceptionFlags::Inexact) + raiseHelper(internal::ExceptionFlags::Inexact); +#ifdef __FE_DENORM + if (statusValue & internal::ExceptionFlags::Denormal) { + raiseHelper(internal::ExceptionFlags::Denormal); } +#endif // __FE_DENORM // There is no special synchronization scheme available to // raise SEE exceptions. So, we will ignore that for now. -- 2.7.4