Re: x86_64: floating-point environment (i.e. fenv.h). BUG.
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.
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.
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.
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.
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