This is the mail archive of the cygwin-patches mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH 1/1] Keep the denormal-operand exception masked; modify FE_ALL_EXCEPT accordingly.


Hi J.H.,

thanks for the patch.  Only problem, this patch is non-trivial
enough to require the BSD waiver per https://cygwin.com/contrib.html,
see the "Before you get started" section.  I add you to the
winsup/CONTRIBUTORS file then.  That ok with you?


Thanks,
Corinna


On Aug 15 12:59, J.H. van de Water wrote:
> By excluding the denormal-operand exception from FE_ALL_EXCEPT, it will not
> be possible anymore to UNmask this exception by means of the API defined by
> /usr/include/fenv.h
> 
> Note: terminology has changed since IEEE Std 854-1987; denormalized numbers
> are called subnormal numbers nowadays.
> 
> This modification has basically been motivated by the fact that it is also
> not possible on Linux to manipulate the denormal-operand exception by means
> of the interface as defined by /usr/include/fenv.h. This has been the state
> of affairs on Linux since 2001 (Andreas Jaeger).
> 
> The exceptions required by the standard (IEEE Std 754), in case they can be
> supported by the implementation, are:
> FE_INEXACT, FE_UNDERFLOW, FE_OVERFLOW, FE_DIVBYZERO and FE_INVALID.
> 
> Although it is allowed to define additional exceptions, there is no reason
> to support the "denormal-operand exception" in this case (fenv.h), because
> the subnormal numbers can be handled almost as fast the normalized numbers
> by the hardware of the x86/x86_64 architecture. Said differently, a reason
> to trap on the input of subnormal numbers does not exist. At least that is
> what William Kahan and others at Intel asserted around 2000.
> (that is William Kahan of the K-C-S draft, the precursor to the standard)
> 
> This commit modifies winsup/cygwin/include/fenv.h as follows:
>  - redefines FE_ALL_EXCEPT from 0x3f to 0x3d
>  - removes the definition for FE_DENORMAL
>  - introduces __FE_DENORM (0x2) (enum in Linux also uses __FE_DENORM)
>  - introduces FE_ALL_EXCEPT_X86 (0x3f), i.e. ALL x86/x86_64 FP exceptions
> ---
>  winsup/cygwin/fenv.cc        |  8 +++++---
>  winsup/cygwin/include/fenv.h | 14 ++++++++------
>  2 files changed, 13 insertions(+), 9 deletions(-)
> 
> diff --git a/winsup/cygwin/fenv.cc b/winsup/cygwin/fenv.cc
> index 066704b..0067da0 100644
> --- a/winsup/cygwin/fenv.cc
> +++ b/winsup/cygwin/fenv.cc
> @@ -417,7 +417,7 @@ fesetprec (int prec)
>  void
>  _feinitialise (void)
>  {
> -  unsigned int edx, eax, mxcsr;
> +  unsigned int edx, eax;
>  
>    /* Check for presence of SSE: invoke CPUID #1, check EDX bit 25.  */
>    eax = 1;
> @@ -431,11 +431,13 @@ _feinitialise (void)
>    /* The default cw value, 0x37f, is rounding mode zero.  The MXCSR has
>       no precision control, so the only thing to do is set the exception
>       mask bits.  */
> -  mxcsr = FE_ALL_EXCEPT << FE_SSE_EXCEPT_MASK_SHIFT;
> +
> +  /* initialize the MXCSR register: mask all exceptions */
> +  unsigned int mxcsr = __FE_ALL_EXCEPT_X86 << FE_SSE_EXCEPT_MASK_SHIFT;
>    if (use_sse)
>      __asm__ volatile ("ldmxcsr %0" :: "m" (mxcsr));
>  
> -  /* Setup unmasked environment.  */
> +  /* Setup unmasked environment, but leave __FE_DENORM masked.  */
>    feenableexcept (FE_ALL_EXCEPT);
>    fegetenv (&fe_nomask_env);
>  
> diff --git a/winsup/cygwin/include/fenv.h b/winsup/cygwin/include/fenv.h
> index 7ec5d4d..5fdbe5a 100644
> --- a/winsup/cygwin/include/fenv.h
> +++ b/winsup/cygwin/include/fenv.h
> @@ -87,16 +87,18 @@ typedef __uint32_t fexcept_t;
>  #define FE_OVERFLOW	(1 << 3)
>  #define FE_UNDERFLOW	(1 << 4)
>  
> -/*  This is not defined by Posix, but since x87 supports it we provide
> -   a definition according to the same naming scheme used above.  */
> -#define FE_DENORMAL	(1 << 1)
> -
>  /*  The <fenv.h> header shall define the following constant, which is
>     simply the bitwise-inclusive OR of all floating-point exception
>     constants defined above:  */
>  
> -#define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_INEXACT | FE_INVALID \
> -			| FE_OVERFLOW | FE_UNDERFLOW | FE_DENORMAL)
> +/* in agreement w/ Linux the subnormal exception will always be masked */
> +#define FE_ALL_EXCEPT \
> +  (FE_INEXACT | FE_UNDERFLOW | FE_OVERFLOW | FE_DIVBYZERO | FE_INVALID)
> +
> +#define __FE_DENORM	(1 << 1)
> +
> +/* mask (= 0x3f) to disable all exceptions at initialization */
> +#define __FE_ALL_EXCEPT_X86 (FE_ALL_EXCEPT | __FE_DENORM)
>  
>  /*  The <fenv.h> header shall define the following constants if and only
>     if the implementation supports getting and setting the represented
> -- 
> 2.7.5

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Maintainer                 cygwin AT cygwin DOT com
Red Hat

Attachment: signature.asc
Description: PGP signature


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]