fesetenv doesn't set new fpu mode, because it's overwrited by current fpu mode:
fenv_t env = envp; <--- save new state to env localy in stack for fldenv
int _mxcsr;
asm ("fnstenv %0\n" <--- overwrites env by current state
"stmxcsr %1" : "=m" (&env), "=m" (&_mxcsr));
/_mxcsr = ((int)envp->unused0 << 16) | (int)envp->__unused1; // mxcsr low and high */
env.__unused0 = 0xffff;
env.__unused1 = 0xffff;
__asm volatile ("fldenv %0" : : "m" (env) <<<---- load current state (WHAT THE HECK)
commit added this bug:
https://sourceforge.net/p/mingw-w64/mingw-w64/ci/e98d8084dde3e3aba43736ee78dd7b35541df00b/
example:
Output of binary compiled by mingw :
0.333333343 hex: 3eaaaaab
0.333333313 hex: 3eaaaaaa
FPU control words: 37f, f7f
Output of binary compiled by linux gcc :
0.333333343 hex: 3eaaaaab
0.333333343 hex: 3eaaaaab
FPU control words: 37f, 37f
Last edit: Zidane 2016-05-25
Let me clarify.
In 2013 (the commit by Kai Tiez pointed above) apparently because of some bug hunting a code was introduced which affects FPU state. Particularly it could prevent a user code to set up rounding, etc.
This leads to incorrect computation which are seen only in the programs compiled with MinGW64. That is incorrect and is a bug in the compiler.
Particularly, the first comment in this thread provides a minimal program which demosntrated the effect. The program wants to set up rounding mode, but fsetenv() in MinGW64 prevents it from doing it.
The code from the commit needs to be revisited, and if it is really required, then it should be narrowed to a special case it was originally intended for.
Last edit: Eugene Sandulenko 2016-05-25
So it is broken strating with mingw-w64-v4x..
We have compiled and run the above source code using MinGW (GCC 6.1.0) and got the following:
0.333333343 hex: 3eaaaaab
0.333333343 hex: 3eaaaaab
FPU control words: 37f, 37f
We can assist with testing if needed.
Cheers.
may you get binary you compiled for me?
It is another project: https://sourceforge.net/projects/mingwbundle/
MSYS2 both GCC 6.1 and 6.2