Re: x86_64: floating-point environment (i.e. fenv.h). BUG.

2018-08-02 Thread Houder

On 2018-08-01 13:49, Houder wrote:

On 2018-08-01 13:00, Corinna Vinschen wrote:

On Aug  1 12:22, Houder wrote:

Hi Corinna,

Short version of my report (as there is more to say about the 
implementation

of
"fenv") in Cygwin; this time I restrict myself to a bug in fegetenv() 
).


(Note to myself: attach STC)

I am reporting a bug in fegetenv() in winsup/cygwin/fenv.cc. There is 
no

hurry
in repairing this bug, as "fenv" is hardly ever (never?) used by 
anyone.


fegetenv() should be modified as follows:

from:
  __asm__ volatile ("fnstenv %0" : "=m" (envp->_fpu) : );
  if (use_sse)
__asm__ volatile ("stmxcsr %0" : "=m" (envp->_sse_mxcsr) : );
  return 0

to:
// Henri: copying glibc ...
  __asm__ volatile ("fnstenv %0\n"
"fldenv %0" : "=m" (envp->_fpu) : );
  if (use_sse)
__asm__ volatile ("stmxcsr %0" : "=m" (envp->_sse_mxcsr) : );
  return 0;


Since you know how to fix things, please just send patches to
the cygwin-patches ML.


Ah ... Agreed. However, as I am not set up for building (anymore), this
will take some time ... (not even git is installed).

(yes, I did verify the above modification (and more), however I did 
that

 "locally" (basically, I included winsup/cygwin/fenv.cc in my  STC) ).


Corinna,

As requested by you, I made an attempt. See cygwin-patches.

Regards,

Henri

--
Problem reports:   http://cygwin.com/problems.html
FAQ:   http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info:  http://cygwin.com/ml/#unsubscribe-simple



Re: x86_64: floating-point environment (i.e. fenv.h). BUG.

2018-08-01 Thread Achim Gratz
Houder writes:
>> Since you know how to fix things, please just send patches to
>> the cygwin-patches ML.
>
> Ah ... Agreed. However, as I am not set up for building (anymore), this
> will take some time ... (not even git is installed).

Just make a unified diff of your changes…


Regards,
Achim.
-- 
+<[Q+ Matrix-12 WAVE#46+305 Neuron microQkb Andromeda XTk Blofeld]>+

Waldorf MIDI Implementation & additional documentation:
http://Synth.Stromeko.net/Downloads.html#WaldorfDocs

--
Problem reports:   http://cygwin.com/problems.html
FAQ:   http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info:  http://cygwin.com/ml/#unsubscribe-simple



Re: x86_64: floating-point environment (i.e. fenv.h). BUG.

2018-08-01 Thread Houder

On 2018-08-01 13:00, Corinna Vinschen wrote:

On Aug  1 12:22, Houder wrote:

Hi Corinna,

Short version of my report (as there is more to say about the 
implementation

of
"fenv") in Cygwin; this time I restrict myself to a bug in fegetenv() 
).


(Note to myself: attach STC)

I am reporting a bug in fegetenv() in winsup/cygwin/fenv.cc. There is 
no

hurry
in repairing this bug, as "fenv" is hardly ever (never?) used by 
anyone.


fegetenv() should be modified as follows:

from:
  __asm__ volatile ("fnstenv %0" : "=m" (envp->_fpu) : );
  if (use_sse)
__asm__ volatile ("stmxcsr %0" : "=m" (envp->_sse_mxcsr) : );
  return 0

to:
// Henri: copying glibc ...
  __asm__ volatile ("fnstenv %0\n"
"fldenv %0" : "=m" (envp->_fpu) : );
  if (use_sse)
__asm__ volatile ("stmxcsr %0" : "=m" (envp->_sse_mxcsr) : );
  return 0;


Since you know how to fix things, please just send patches to
the cygwin-patches ML.


Ah ... Agreed. However, as I am not set up for building (anymore), this
will take some time ... (not even git is installed).

(yes, I did verify the above modification (and more), however I did that
 "locally" (basically, I included winsup/cygwin/fenv.cc in my  STC) ).

Regards,

Henri

--
Problem reports:   http://cygwin.com/problems.html
FAQ:   http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info:  http://cygwin.com/ml/#unsubscribe-simple



Re: x86_64: floating-point environment (i.e. fenv.h). BUG.

2018-08-01 Thread Corinna Vinschen
On Aug  1 12:22, Houder wrote:
> Hi Corinna,
> 
> Short version of my report (as there is more to say about the implementation
> of
> "fenv") in Cygwin; this time I restrict myself to a bug in fegetenv() ).
> 
> (Note to myself: attach STC)
> 
> I am reporting a bug in fegetenv() in winsup/cygwin/fenv.cc. There is no
> hurry
> in repairing this bug, as "fenv" is hardly ever (never?) used by anyone.
> 
> fegetenv() should be modified as follows:
> 
> from:
>   __asm__ volatile ("fnstenv %0" : "=m" (envp->_fpu) : );
>   if (use_sse)
> __asm__ volatile ("stmxcsr %0" : "=m" (envp->_sse_mxcsr) : );
>   return 0
> 
> to:
> // Henri: copying glibc ...
>   __asm__ volatile ("fnstenv %0\n"
> "fldenv %0" : "=m" (envp->_fpu) : );
>   if (use_sse)
> __asm__ volatile ("stmxcsr %0" : "=m" (envp->_sse_mxcsr) : );
>   return 0;

Since you know how to fix things, please just send patches to
the cygwin-patches ML.


Thanks,
Corinna

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


signature.asc
Description: PGP signature


x86_64: floating-point environment (i.e. fenv.h). BUG.

2018-08-01 Thread Houder

Hi Corinna,

Short version of my report (as there is more to say about the 
implementation of

"fenv") in Cygwin; this time I restrict myself to a bug in fegetenv() ).

(Note to myself: attach STC)

I am reporting a bug in fegetenv() in winsup/cygwin/fenv.cc. There is no 
hurry

in repairing this bug, as "fenv" is hardly ever (never?) used by anyone.

fegetenv() should be modified as follows:

from:
  __asm__ volatile ("fnstenv %0" : "=m" (envp->_fpu) : );
  if (use_sse)
__asm__ volatile ("stmxcsr %0" : "=m" (envp->_sse_mxcsr) : );
  return 0

to:
// Henri: copying glibc ...
  __asm__ volatile ("fnstenv %0\n"
"fldenv %0" : "=m" (envp->_fpu) : );
  if (use_sse)
__asm__ volatile ("stmxcsr %0" : "=m" (envp->_sse_mxcsr) : );
  return 0;

Yes, you can verify my modification here:

https://sourceware.org/git/?p=glibc.git

(sysdeps/x86_64/fpu/fegetenv.c)

The fnstenv statement "copies" the state of the x87 FPU to memory, at 
the same

time MASKING all exceptions ...
However, masking the exceptions is NOT what we desire at this point. For 
this
reason fnstenv must be followed by fldenv, which copies "what has been 
copied

from the FPU" back to the FPU.

The stc is as follows:

 feenableexcept()
 ...
 fegetenv() // save state of fenv (the "control and status 
register")
 //fesetenv(FE_DFL_ENV) // set default environment: would mask all 
exceptions

 provoke exception
 fesetenv() // restore the previous state of fenv
Note: provoke exception, using
 - either feraiseexcept()
 - or double d = 1.0; long l = d + 0.4;

Using feraiseexcept() should trigger an exception; it does not.

Regards,

Henri// gcc -Wall -o STC-FENV STC-FENV.c
// Linux: gcc -Wall -o STC-FENV STC-FENV.c -lm

/*
 x86_64:
 This stc does not terminate w/ an exception if one is provoked using feraiseexcept(). This is due to a bug in
 fegetenv() in winsup/cygwin/fenv.cc.
 At first glance, this is weird, as using "double d = 1.0; long l = d + 0.4;" to provoke an exception, results
 in triggering the exception.
 Floating-point in the Intel processor may either use "SSE" or the x87 FPU. On x86_64, SSE is used (mostly?).
 In feraiseexcept() the exception is provoked using the x87 FPU ...
 However, in fegetenv(), as result of the bug, all exceptions will have been masked after calling fegetenv().
 WoW (x86):
 ... an entirely different story (x87 FPU and SSE behave differently when exceptions are enabled again after
 an exception has been provoked while exceptions WERE being masked; moreover the triggering of the exception
 is "delayed" (deferred) in case of the x87 FPU).
 */
/*
Program:
 feenableexcept()
 ...
 fegetenv() // save state of fenv (the "control and status register")
 //fesetenv(FE_DFL_ENV)	set default environment: would mask all exceptions
 provoke exception
 fesetenv() // restore the previous state of fenv
Note: provoke exception, using either feraiseexcept() or double d = 1.0; long l = d + 0.4;
 */

#if !defined __CYGWIN__
#define _GNU_SOURCE
#endif
#include 
#include 
#include 

const int xxx = 0x3d;

int main()
{
fenv_t fpenv;

if (feenableexcept(FE_ALL_EXCEPT) == -1) printf("\tfeenableexcept failed.\n");
printf("\tExceptions ENABLED!\n");

printf(">: fegetexcept() =  %2x enabled\n", fegetexcept() );
printf("0: fegetexcept() =  %2x mask\n", (~fegetexcept() & xxx) );

printf("Getenv() ...\n");
fegetenv();

#if 0
printf("Setenv(FE_DFL_ENV) ...\n"); fesetenv(FE_DFL_ENV); // duck
#else
printf("NO Setenv(FE_DFL_ENV) ...\n");
#endif
printf(">: fegetexcept() =  %2x enabled\n", fegetexcept() );
printf("1: fegetexcept() =  %2x mask\n", (~fegetexcept() & xxx) );

printf("Raise Exception!\n");
//double d = 1.0; long l = d + 0.4; l = l;
if (feraiseexcept(FE_INEXACT) == -1) printf("\tfeRAISErexcept() failed.\n");
printf("*: fetestexcept() = %2x status flags\n", fetestexcept(FE_ALL_EXCEPT) );
printf(">: fegetexcept() =  %2x enabled\n", fegetexcept() );
printf("2: fegetexcept() =  %2x mask\n", (~fegetexcept() & xxx) );

printf("Setenv() ...\n");
fesetenv();
printf("*: fetestexcept() = %2x status flags\n", fetestexcept(FE_ALL_EXCEPT) );
printf(">: fegetexcept() =  %2x enabled\n", fegetexcept() );
printf("3: fegetexcept() =  %2x mask\n", (~fegetexcept() & xxx) );
}

/* Results with the "generic" fenv.cc
Cygwin: ... using feraiseexcept()
64-@@ ./stc-fenv2 < Wrong! NO exception! ... Ditto x86 (NO exception!): wrong!
>: fegetexcept() =  3f enabled
0: fegetexcept() =   0 mask
Getenv() ...
NO Setenv(FE_DFL_ENV) ...
>: fegetexcept() =   0 enabled < Wrong! See above
1: fegetexcept() =  3d mask
Raise Exception!
*: fetestexcept() = 20 status flags
>: fegetexcept() =   0 enabled
2: fegetexcept() =  3d mask
Setenv() ...
*: fetestexcept() =  0 status flags
>: fegetexcept() =  3f enabled
3: fegetexcept() =   0 mask

64-@@ ./stc-fenv2
>: fegetexcept() =  3f enabled
0: fegetexcept() =   0 mask
Getenv() ...
Setenv(FE_DFL_ENV) ...
>: fegetexcept() =   0 enabled
1: fegetexcept() =  3d mask
Raise