[PATCH] Cygwin: fegetenv() in winsup/cygwin/fenv.cc should not disable exceptions!

Houder houder@xs4all.nl
Sun Aug 5 06:26:00 GMT 2018


On 2018-08-03 14:00, Houder wrote:
> On 2018-08-03 12:39, Corinna Vinschen wrote:
>> On Aug  3 11:27, Houder wrote:
>>> On 2018-08-03 09:36, Corinna Vinschen wrote:
> [snip]
> 
>>> > In terms of x86_64, do we have to change the fenv stuff completely
>>> > to use only SSE opcodes?  Does that make sense at all?
>>> 
>>> Ho! I have to disappoint you here! I am not an expert at all.
>> 
>> Thanks all the same for your detailed description.  A quick search in
>> glibc shows that x86_64 FP exceptions in fact work somewhat different 
>> in
>> that it additionally reads and writes from the SSE control register,
>> e.g. sysdeps/x86_64/fpu/fesetenv.c:
>> 
>>     __asm__ ("fnstenv %0\n"
>>            "stmxcsr %1" : "=m" (*&temp), "=m" (*&temp.__mxcsr));
>>     [...]
>>       __asm__ ("fldenv %0\n"
>>            "ldmxcsr %1" : : "m" (temp), "m" (temp.__mxcsr));
> 
> ? ... uhm, this also happens in Korn's implementation (Cygwin). Only
> Dave Korn verifies if SSE is present (does the machine have SSE?).
> 
> Both implementations both manage SSE and x87 FPU simultaneously.
> 
> For instance fetestexcept(), i.e. show me the status flags, return
> 
>     status flag in SSE | status flag in x87 FPU
> (bit-wise "OR" of both "status registers")
> 
> Both Korn and Jaeger try to hide that there are in fact two devices
> that do "floating-point".
> 
> Can gcc generate code for both devices at the same time? Possibly!
> 
> Did it in case of my _tiny_ STC? ("double d = 1.0; long l = d + 0.4")
> 
> No (as far as I tell).
> 
> On Linux and Cygwin 64-bits, the SSE was used. On WoW the x87 FPU was
> used.
> 
> As far as I tell, it is neither the machine nor "fenv" that devices
> to switch from x87 FPU to SSE ...
> 
> Why gcc prefers x87 FPU in case of WoW, I cannot tell (Yes, I a bit
> outspoken here; though that is my hypothesis).

As a last note on this topic:

My hypothesis was correct.

By default gcc "uses" the x87 FPU on WoW (32-bits) and SSE on x86_64.

It is NOT even possible to force gcc to use SSE on WoW (32-bits):

@@ gcc -Wall -mfpmath=sse -o STC-FENV STC-FENV.c
cc1: warning: SSE instruction set disabled, using 387 arithmetics

It is however possible to instruct gcc to use the x87 FPU on x86_64,
... resulting in an exception where one is not expected (on x86_64):

64-@@ gcc -Wall -mfpmath=387 -o stc-last stc-last.c
64-@@ ./stc-last
INITIALIZING !!!!!
Initializing fe_dfl_env
Initializing fe_nomask_env
         Exception created! <==== exceptions STILL DISabled
obj->_fpu._fpu_cw    = ffff037f
obj->_fpu._fpu_sw    = ffff0004 <=== "zero-divide" flag set!
obj->_fpu._fpu_tagw  = ffffffff
obj->_fpu._fpu_ipoff = 40186f
obj->_fpu._fpu_ipsel = 0  obj->_fpu._fpu_opcde = 0
obj->_fpu._fpu_dpoff = ffffcc10
obj->_fpu._fpu_dpsel = ffff0000
obj->_sse_mxcsr      = 1f80
         Exceptions ENABLED!
Floating point exception (core dumped) <=== Whao!

(when SSE is used, an exception is not triggered in this case)

Regards,
Henri



More information about the Cygwin-patches mailing list