Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 9 Jan 2005 23:00:51 GMT
From:      Bruce Evans <bde@zeta.org.au>
To:        freebsd-i386@FreeBSD.org
Subject:   Re: i386/75862: fpsetsticky() incorrectly clears, instead of sets, floating-point exception flags on IA-32
Message-ID:  <200501092300.j09N0pHm041112@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR i386/75862; it has been noted by GNATS.

From: Bruce Evans <bde@zeta.org.au>
To: "Nelson H. F. Beebe" <beebe@math.utah.edu>
Cc: freebsd-gnats-submit@freebsd.org, freebsd-i386@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



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