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>