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

Houder houder@xs4all.nl
Fri Aug 3 09:27:00 GMT 2018


On 2018-08-03 09:36, Corinna Vinschen wrote:
> Hi J.H.,
> 
> Pushed with tweaks.  The string in __asm__ statements works a

Bah! Must be the heat! I did a compare (sdiff), but missed it. You
are correct: the '\n' is required.

> bit different and I made a slight change to the commit message.

No problem! (you could have gone even further; your command of the
English language is far better than mine).

> 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.

Basically, it was Anton Lavrentiev (Cygwin ML, July 9 2018) who got
me interested.

I created my little STC:

feenableexcept()
fegetenv(&fpenv)
fegetenv(FE_DFL_ENV) // to be switched on and off
operation to provoke exception
fesetenv(&fpenv)

I could not make "head or tail" of what was happening; especially
when I expected to see the exception triggered.

On WoW, but also on x86_64.

The standard (and manual page) that describe "fenv" is a disaster.
(too me far too abstract).

That is why I started comparing Cywgin with glibc. Comparing the
implementation by Dave Korn (Cygwin, some 8 years ago), and that
by Andreas Jaeger (glibc).

Only then, I started studying the manuals written by Intel. But
only as far as was required to get a grasp of what was going on.

First "code-wise", next to understand the behaviour of my STC.

Meaning, my focus of interest have been:

fe{en,dis}ableexcept
fe{get,set)env

and after the repair of fegetenv(), _feinitialise(), as Dave Korn
defines FE_ALL_EXCEPT different from Andreas Jaeger.
(in my test environment I used Jaeger's definition, which required
  a slight modification of _feinitialise() )

ONLY after the above was "out of the way", I moved my attention to
WoW: why did exceptions get triggered here, while they were NOT on
x86_64 ?????

I discovered a difference in behaviour between the x87 FPU and SSE.

When an exception is masked, a "default action" is carried out when
an exception occurs. At the same time the associated status flag is
set.
(the manual speaks about a "reasonable" default action, an action
  that is "sufficient" most of the times)

When the exception is enabled again, SSE is not bothered. However
the next _FPU_ statement will notice the status flag set, and will
set the "Exception Summary Bit" (in the FPU's status register).

The next FPU statement after will trigger the exception! (Yes, the
triggering of the exception is "delayed", deferred).

You can read all this in Intel's manuals. Bottom-line, if the FPU
is used, and exceptions are enabled again, one must _first_ clear
all exceptions (again, not needed on SSE).

Returning to your question ...

 From "a logical point of view", Korn's implementation is more or
less the same as Jaeger's implementation.

Why is there "a preference for the x87 FPU" on WoW, I cannot tell.

Why does "using double d = 1.0; long l = d + 0.4" on WoW result
in code that is executed on the x87 FPU ????? (and why does the
reverse occur on x86_64)? (Yes, that is my hypothesis!)

I cannot tell.

Perhaps it is gcc ... I did not investigate any further.

Regards,

Henri



More information about the Cygwin-patches mailing list