From ah@alvman.Haakh.de  Fri May 17 00:01:13 2002
Return-Path: <ah@alvman.Haakh.de>
Received: from alvman.Haakh.de (p50816A36.dip.t-dialin.net [80.129.106.54])
	by hub.freebsd.org (Postfix) with ESMTP id 98DBC37B400
	for <FreeBSD-gnats-submit@freebsd.org>; Fri, 17 May 2002 00:01:12 -0700 (PDT)
Received: from alvman.Haakh.de (localhost [127.0.0.1])
	by alvman.Haakh.de (8.12.3/8.11.6) with ESMTP id g4H71BNi000805
	for <FreeBSD-gnats-submit@freebsd.org>; Fri, 17 May 2002 09:01:12 +0200 (CEST)
	(envelope-from ah@alvman.Haakh.de)
Received: (from ah@localhost)
	by alvman.Haakh.de (8.12.3/8.12.3/Submit) id g4H71BVv000804;
	Fri, 17 May 2002 09:01:11 +0200 (CEST)
Message-Id: <200205170701.g4H71BVv000804@alvman.Haakh.de>
Date: Fri, 17 May 2002 09:01:11 +0200 (CEST)
From: Andreas Haakh <ah@alvman.Haakh.de>
Reply-To: Andreas Haakh <ah@alvman.Haakh.de>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: fpgetmask, fpsetmask yield strange results
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         38170
>Category:       kern
>Synopsis:       fpgetmask, fpsetmask yield strange results
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri May 17 00:10:01 PDT 2002
>Closed-Date:    Sat Jun 29 17:57:32 PDT 2002
>Last-Modified:  Sat Jun 29 17:57:32 PDT 2002
>Originator:     Andreas Haakh
>Release:        FreeBSD 4.6-RC i386
>Organization:
Ingenieurbro fr Baustatik
>Environment:
System: FreeBSD alvman.Haakh.de 4.6-RC FreeBSD 4.6-RC #0: Fri May 17 07:18:23 CEST 2002 root@alvman.Haakh.de:/usr/obj/usr/src/sys/ALVMAN i386 i686-class CPU

>Description:
	I tried to modify the default fp_exception-mask. The results from fpgetmask and fpsetmask (and probably some other fp[sg]et-routines) are buggy.

>How-To-Repeat:
	The following codeexample shows this strange behaviour:

#include <stdio.h>
#include <ieeefp.h>

int main (void) {

    fp_except_t except, res;

    res=fpgetmask();

    printf ("fp_except from fpgetmask: \t0x%02x!\n", res);

    except = FP_X_INV|FP_X_DZ|FP_X_OFL|FP_X_STK;

    printf ("attempt to set fp_except to: \t0x%02x!\n", except);

    res=fpsetmask(except);

    printf ("fp_except from fpsetmask: \t0x%02x!\n", res);

    res=fpgetmask();

    printf ("fp_except from fpgetmask: \t0x%02x!\n", res);

    res=fpsetmask(except);

    printf ("retry to set fp_except to:\t0x%02x!\n", except);

    res=fpsetmask(except);

    printf ("fp_except from fpsetmask: \t0x%02x!\n", res);

    res=fpgetmask();

    printf ("fp_except from fpgetmask: \t0x%02x!\n", res);

    exit (except);

}

	The results from this prog are:


fp_except from fpgetmask: 	0x00!
attempt to set fp_except to: 	0x4d!
fp_except from fpsetmask: 	0x3f!
fp_except from fpgetmask: 	0x0d!
retry to set fp_except to:	0x4d!
fp_except from fpsetmask: 	0x32!
fp_except from fpgetmask: 	0x0d!


>Fix:
	correct the inline functions and/or macros in <machine/floatingpoint.h>
	I have not enough knowledge to do it myself...


>Release-Note:
>Audit-Trail:

From: Bruce Evans <bde@zeta.org.au>
To: Andreas Haakh <ah@alvman.Haakh.de>
Cc: FreeBSD-gnats-submit@FreeBSD.ORG
Subject: Re: kern/38170: fpgetmask, fpsetmask yield strange results
Date: Sun, 2 Jun 2002 03:54:07 +1000 (EST)

 On Fri, 17 May 2002, Andreas Haakh wrote:
 
 > >Description:
 > 	I tried to modify the default fp_exception-mask. The results from fpgetmask and fpsetmask (and probably some other fp[sg]et-routines) are buggy.
 
 fpsetmask() is fixed in -current.  The complement of the mask (ANDed with
 the mask bitfield) was being returned.  The other routines seem to be OK.
 
 > >How-To-Repeat:
 > 	The following codeexample shows this strange behaviour:
 >
 > #include <stdio.h>
 > #include <ieeefp.h>
 >
 > int main (void) {
 >
 >     fp_except_t except, res;
 >
 >     res=fpgetmask();
 >
 >     printf ("fp_except from fpgetmask: \t0x%02x!\n", res);
 >
 >     except = FP_X_INV|FP_X_DZ|FP_X_OFL|FP_X_STK;
 
 Note that FP_X_STK is output-only.  Attempts to set it are ignored by
 fpsetmask(), and fpgetmask() returns whatever the hardware gives for
 attempts to set it in other initializations that don't mask it.  It
 is documented as "reserved" in at least the i486 manual, so strictly
 it should not be set unconditionally, but the kernel just tries to
 write 0 to it.  I wish that this bit controlled stack exceptions
 independently of invalid operand exceptions, so that SIGFPEs could
 be generated for the programming error of stack overflow without
 generating them for invalid operands which might not even be an error
 in programs that generate NaNs intentionally.
 
 Bruce
 

From: "Andreas Haakh" <ah@haakh.de>
To: "Bruce Evans" <bde@zeta.org.au>
Cc: <FreeBSD-gnats-submit@FreeBSD.ORG>
Subject: Re: kern/38170: fpgetmask, fpsetmask yield strange results
Date: Wed, 12 Jun 2002 10:54:01 +0200

 ----- Original Message -----
 From: "Bruce Evans" <bde@zeta.org.au>
 To: "Andreas Haakh" <ah@alvman.Haakh.de>
 Cc: <FreeBSD-gnats-submit@FreeBSD.ORG>
 Sent: Saturday, June 01, 2002 7:54 PM
 Subject: Re: kern/38170: fpgetmask, fpsetmask yield strange results
 
 
 > On Fri, 17 May 2002, Andreas Haakh wrote:
 >
 > > >Description:
 > > I tried to modify the default fp_exception-mask. The results from
 fpgetmask and fpsetmask (and probably some other fp[sg]et-routines) are
 buggy.
 >
 > fpsetmask() is fixed in -current.  The complement of the mask (ANDed with
 > the mask bitfield) was being returned.  The other routines seem to be OK.
 >
 > > >How-To-Repeat:
 > > The following codeexample shows this strange behaviour:
 > >
 > > #include <stdio.h>
 > > #include <ieeefp.h>
 > >
 > > int main (void) {
 > >
 > >     fp_except_t except, res;
 > >
 > >     res=fpgetmask();
 > >
 > >     printf ("fp_except from fpgetmask: \t0x%02x!\n", res);
 > >
 > >     except = FP_X_INV|FP_X_DZ|FP_X_OFL|FP_X_STK;
 >
 > Note that FP_X_STK is output-only.  Attempts to set it are ignored by
 > fpsetmask(), and fpgetmask() returns whatever the hardware gives for
 > attempts to set it in other initializations that don't mask it.  It
 > is documented as "reserved" in at least the i486 manual, so strictly
 > it should not be set unconditionally, but the kernel just tries to
 > write 0 to it.  I wish that this bit controlled stack exceptions
 > independently of invalid operand exceptions, so that SIGFPEs could
 > be generated for the programming error of stack overflow without
 > generating them for invalid operands which might not even be an error
 > in programs that generate NaNs intentionally.
 >
 
 Is it already MFC'd or when will this happen?
 
 There should be a note in fpsetask(3) that FP_X_STK is reserved...
 
 Andreas
 

From: Bruce Evans <bde@zeta.org.au>
To: Andreas Haakh <ah@haakh.de>
Cc: FreeBSD-gnats-submit@FreeBSD.ORG
Subject: Re: kern/38170: fpgetmask, fpsetmask yield strange results
Date: Thu, 13 Jun 2002 12:57:19 +1000 (EST)

 On Wed, 12 Jun 2002, Andreas Haakh wrote:
 
 > From: "Bruce Evans" <bde@zeta.org.au>
 > > fpsetmask() is fixed in -current.  The complement of the mask (ANDed with
 > > the mask bitfield) was being returned.  The other routines seem to be OK.
 >
 > Is it already MFC'd or when will this happen?
 
 MFC scheduled after 4 weeks.
 
 > There should be a note in fpsetask(3) that FP_X_STK is reserved...
 
 It's read-only, but very unportable.  Most of <floatingpoint.h> and
 <ieeefp.h> hould be undocumented and replaced by the C99 feset*().
 There is nothing standard to replace fp{get,set}mask() since setting
 masks is unportable, so FreeBSD will need unportable extensions.
 
 Bruce
 

From: "Andreas Haakh" <ah@Haakh.de>
To: "Bruce Evans" <bde@zeta.org.au>
Cc: <FreeBSD-gnats-submit@FreeBSD.ORG>
Subject: Re: kern/38170: fpgetmask, fpsetmask yield strange results
Date: Thu, 20 Jun 2002 17:32:44 +0200

 Hi,
 
 today I installed floatingpoint.h from HEAD and now the functions
 fp[sg]etmask yield the desired results.
 
 The reason, why I found the bug is, that somewhere in the past the default
 setting for npxcw was silently changed.
 
 Investigating the sources revealed, that
 http://www.freebsd.org/cgi/query-pr.cgi?pr=17984 changed the default
 floating point precision to 53 bits and masked _ALL_ exceptions in
 /sys/i386/include/npx.h! There was no note in UPDATING and this change
 caused quite some trouble.
 
 Since this PR we have
 #define	__INITIAL_NPXCW__	0x127F
 
 I think it would be better to have the initial value set to
 #define __INITIAL_NPXCW__ 0x1272
 which would force a trap on
 FP_X_INV, FP_X_DZ and FP_X_OFL.
 This is a better behaviour for floatingpoint exceptions if you don't catch
 them at all and complies with the sample code in fpsetmask(3). This manpage
 should also describe the default settings.
 
 Whoever wants to prevent floating point exceptions should check and/or reset
 the sticky flags if needed and for those programs its not a big deal to set
 the exception mask to the desired value.
 
 The current setting silently ignores them and give strange (wrong!!!)
 results.
 
 If you don't agree to change the initial npxcw to my proposed value, it
 would be nice to have either a kernel configuration option or a
 sysctl-variable holding the initial npxcw for new processes..
 
 Andreas
 
 ----- Original Message -----
 From: "Andreas Haakh" <ah@haakh.de>
 To: "Bruce Evans" <bde@zeta.org.au>
 Cc: <FreeBSD-gnats-submit@FreeBSD.ORG>
 Sent: Wednesday, June 12, 2002 10:54 AM
 Subject: Re: kern/38170: fpgetmask, fpsetmask yield strange results
 
 
 >
 > ----- Original Message -----
 > From: "Bruce Evans" <bde@zeta.org.au>
 > To: "Andreas Haakh" <ah@alvman.Haakh.de>
 > Cc: <FreeBSD-gnats-submit@FreeBSD.ORG>
 > Sent: Saturday, June 01, 2002 7:54 PM
 > Subject: Re: kern/38170: fpgetmask, fpsetmask yield strange results
 >
 >
 > > On Fri, 17 May 2002, Andreas Haakh wrote:
 > >
 > > > >Description:
 > > > I tried to modify the default fp_exception-mask. The results from
 > fpgetmask and fpsetmask (and probably some other fp[sg]et-routines) are
 > buggy.
 > >
 > > fpsetmask() is fixed in -current.  The complement of the mask (ANDed
 with
 > > the mask bitfield) was being returned.  The other routines seem to be
 OK.
 > >
 > > > >How-To-Repeat:
 > > > The following codeexample shows this strange behaviour:
 > > >
 > > > #include <stdio.h>
 > > > #include <ieeefp.h>
 > > >
 > > > int main (void) {
 > > >
 > > >     fp_except_t except, res;
 > > >
 > > >     res=fpgetmask();
 > > >
 > > >     printf ("fp_except from fpgetmask: \t0x%02x!\n", res);
 > > >
 > > >     except = FP_X_INV|FP_X_DZ|FP_X_OFL|FP_X_STK;
 > >
 > > Note that FP_X_STK is output-only.  Attempts to set it are ignored by
 > > fpsetmask(), and fpgetmask() returns whatever the hardware gives for
 > > attempts to set it in other initializations that don't mask it.  It
 > > is documented as "reserved" in at least the i486 manual, so strictly
 > > it should not be set unconditionally, but the kernel just tries to
 > > write 0 to it.  I wish that this bit controlled stack exceptions
 > > independently of invalid operand exceptions, so that SIGFPEs could
 > > be generated for the programming error of stack overflow without
 > > generating them for invalid operands which might not even be an error
 > > in programs that generate NaNs intentionally.
 > >
 >
 > Is it already MFC'd or when will this happen?
 >
 > There should be a note in fpsetask(3) that FP_X_STK is reserved...
 >
 > Andreas
 >
 

From: Bruce Evans <bde@zeta.org.au>
To: Andreas Haakh <ah@haakh.de>
Cc: FreeBSD-gnats-submit@FreeBSD.ORG
Subject: Re: kern/38170: fpgetmask, fpsetmask yield strange results
Date: Sun, 23 Jun 2002 00:40:47 +1000 (EST)

 On Thu, 20 Jun 2002, Andreas Haakh wrote:
 
 > The reason, why I found the bug is, that somewhere in the past the default
 > setting for npxcw was silently changed.
 >
 > Investigating the sources revealed, that
 > http://www.freebsd.org/cgi/query-pr.cgi?pr=17984 changed the default
 > floating point precision to 53 bits and masked _ALL_ exceptions in
 > /sys/i386/include/npx.h! There was no note in UPDATING and this change
 > caused quite some trouble.
 
 I opposed this change for many years because I think not masking the
 exceptions is a better default, at least with the old C standard (C90)
 which doesn't specify any usable exception handling, but eventually gave
 up.
 
 > Since this PR we have
 > #define	__INITIAL_NPXCW__	0x127F
 >
 > I think it would be better to have the initial value set to
 > #define __INITIAL_NPXCW__ 0x1272
 > which would force a trap on
 > FP_X_INV, FP_X_DZ and FP_X_OFL.
 > This is a better behaviour for floatingpoint exceptions if you don't catch
 > them at all and complies with the sample code in fpsetmask(3). This manpage
 > should also describe the default settings.
 
 It's too late to change this back now :-).  The change was made over
 2 years ago just before FreeBSD-4 was released.  The C standard (C99)
 finally specified usuable (but optional) exception handling just a few
 months before that.  I believe that POSIX.1-2001 (which came out about
 18 months later) makes the usable exception handling non-optional and
 requires either all exceptions to be masked by default, or all math
 functions to break the C standard by delivering SIGFPEs when they
 raise a floating point exception.  This is all rather complicated and
 not really supported yet.
 
 > Whoever wants to prevent floating point exceptions should check and/or reset
 > the sticky flags if needed and for those programs its not a big deal to set
 > the exception mask to the desired value.
 
 This argument can easily be inverted to "Whoever doesn't want ..." :-).
 
 > The current setting silently ignores them and give strange (wrong!!!)
 > results.
 
 In theory you are supposed to get a NaN or Inf result, and check for this
 or the exception flags at appropriate times.  I prefer to get an exception
 because programs that actually do the checks can easily set the exception
 mask.
 
 > If you don't agree to change the initial npxcw to my proposed value, it
 > would be nice to have either a kernel configuration option or a
 > sysctl-variable holding the initial npxcw for new processes..
 
 I think it's too late for any of this now.
 
 Bruce
 
State-Changed-From-To: open->closed 
State-Changed-By: bde 
State-Changed-When: Sat Jun 29 17:55:25 PDT 2002 
State-Changed-Why:  
Fixed in rev.1.12 (-current) and rev.1.10.2.1 (RELENG_4) of the i386 
floatingpoint.h. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=38170 
>Unformatted:
