Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 10 Jan 2005 09:50:12 +1100 (EST)
From:      Bruce Evans <bde@zeta.org.au>
To:        "Nelson H. F. Beebe" <beebe@math.utah.edu>
Cc:        freebsd-i386@freebsd.org
Subject:   Re: i386/75862: fpsetsticky() incorrectly clears, instead of sets, floating-point exception flags on IA-32
Message-ID:  <20050110094425.G30197@delplex.bde.org>
In-Reply-To: <200501051801.j05I1Xtc040919@www.freebsd.org>
References:  <200501051801.j05I1Xtc040919@www.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20050110094425.G30197>