i386/75862: fpsetsticky() incorrectly clears, instead of sets,
floating-point exception flags on IA-32
Bruce Evans
bde at zeta.org.au
Sun Jan 9 15:00:52 PST 2005
The following reply was made to PR i386/75862; it has been noted by GNATS.
From: Bruce Evans <bde at zeta.org.au>
To: "Nelson H. F. Beebe" <beebe at math.utah.edu>
Cc: freebsd-gnats-submit at freebsd.org, freebsd-i386 at freebsd.org
Subject: Re: i386/75862: fpsetsticky() incorrectly clears, instead of sets,
floating-point exception flags on IA-32
Date: Mon, 10 Jan 2005 09:50:12 +1100 (EST)
On Wed, 5 Jan 2005, Nelson H. F. Beebe wrote:
> >Description:
> The fpsetsticky() macro in <flloatingpoint.h>, e.g.,
> http://minnie.tuhs.org/FreeBSD-srctree/newsrc/i386/include/floatingpoint.h.html#fpgetsticky
> is defined like this:
> #define fpresetsticky(m) ((fp_except_t) __fpsetreg(0, FP_STKY_REG, (m), FP_STKY_OFF))
> #define fpsetsticky(m) fpresetsticky(m)
>
> That is wrong: fpresetsticky() CLEARS exception flags, and
> fpsetsticky() SETS them. The same API is present on HP-UX 10,
> OpenBSD 3.2 and NetBSD 1.6, and works correctly on all of them.
> It appears from the above URL that the error is long standing since
> it is still the current 5.3 sources.
Yes, it was wrong when first committed in FreeBSD-1 in 1993 and has never
been fixed. A thread in freebsd-standards has some relevant details:
%%%
On Tue, 20 Jan 2004, Bruce Evans wrote:
> On Mon, 19 Jan 2004, David Schultz wrote:
> > ...
> > By the way, the man pages refer to fpresetsticky(3), but not
> > fpsetsticky(3). The MI ieee.h header declares only fpsetsticky(),
> > but some architectures override these with equivalent macros for
> > both. If you have a good idea of how this is supposed to be, it
> > would be great if you could fix it.
>
> I once thought that fpresetsticky() was standard and fpsetsticky() was
> intentionally undocumented because it is nonstandard, but this seems
> to be backwards -- it is fpresetsticky() that is the mistake. Look
> them up on the web. There are more hits for fpsetsticky, and google
> even suggests I wanted fpsetsticky when I seach for fpresetsticky.
>
> The C99 interfaces should make these moot. It has equivalents to
> both, and also feraiseexcept().
>
> > Another option is to just implement the relevant parts of fenv.h.
> > They are fairly straightforward, and there's no sense in hiding
> > behind the brokenness of gcc's i386 backend forever.
%%%
David committed an implementation of fenv.h last June.
There is also a lot of bogusness in the arrangement of <floatingpoint.h>
and <ieeefp.h>. IIRC, the arrangement was sort of backwards
<floatingpoint.h> essentially now just includes <ieeefp.h>. Check
google or a Sun system for details of where things should be.
> >Fix:
> I found that this redefinition of fpsetsticky() solves the problem:
>
> #define fpsetsticky(e) ((fp_except)__fpsetreg(0x3f, FP_STKY_REG, (e), FP_STKY_OFF))
>
> With that change, I can now have a C99-style interface (sadly
> still lacking the BSD world) like this:
> #define feclearexcept(e) (void)fpsetsticky(~((fp_except)(e)))
> #define feraiseexcept(e) (void)fpsetsticky(fpgetsticky() | ((fp_except)(e)))
> #define fetestexcept(e) ((int)(fpgetsticky() & (fp_except)(e)))
But these have not been lacking in FreeBSD since last June. They are in
FreeBSD-5.3.
Bruce
More information about the freebsd-i386
mailing list