Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 31 Oct 2002 19:59:21 +1100 (EST)
From:      Bruce Evans <bde@zeta.org.au>
To:        "M. Warner Losh" <imp@bsdimp.com>
Cc:        rittle@labs.mot.com, <rittle@latour.rsch.comm.mot.com>, <current@FreeBSD.ORG>, <dschultz@uclink.Berkeley.EDU>
Subject:   Re: Lack of real long double support
Message-ID:  <20021031192610.W8632-100000@gamplex.bde.org>
In-Reply-To: <20021030.162239.52163953.imp@bsdimp.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, 30 Oct 2002, M. Warner Losh wrote:

> In message: <20021030215500.E5692-100000@gamplex.bde.org>
>             Bruce Evans <bde@zeta.org.au> writes:
> : The reasons are the same as they used to be: incomplete language support
> : and incomplete library support.  Language support is being completed but
> : is far from here yet.  See the paper referenced in Loren's reply for more
> : details than anyone should want to know.
>
> OK.  I'll have to go back and find that reference.  I'd really like to
> change the __INITIAL_NPXCW__ from 0x127f to 0x137f in npx.h.  I think
> that we can get the library support in place over time, as this
> already is a bullet item in the standards todo list web page.  The gcc
> 3.2 compiler does a decent, but not perfect, job of dealing with the
> floating point stuff.

Er, it does the same very imperfect job that it did in when it first
implemented long doubles.

> : C99 encourages having a behaviour that is known at compile time and
> : telling applications about it in FLT_EVAL_METHOD (this can be set to
> : -1 == indeterminable, but that would not be very useful although it
> : is the only correct setting now).  The compiler should implement the
> : system implementor's choice or enforce its own choice.  gcc doesn't
> : really understand this this.  gcc-3.2 thinks that it implementing
> : method 0 (no extension of precision) but the npx hardware is nothing
> : like that.
>
> I don't understand this completely.  ARe you saying that gcc is doing
> something worng?

Yes.  It doesn't attempt to implement C99 stuff and depends on a fuzzy
reading of C90 to conform to C90.  Example of gcc-3.2's schizophrenia
with precision:

%%%
$ cat z.c
double x = 1.0F / 3.0F;
float y = 1.0F;
float z = 3.0F;
double u;

int
main()
{
	u = y / z;
	printf("x = %.17g\n", x);
	printf("u = %.17g\n", u);
	return (x == u ? 0 : 1);
}
$ cc -o z z.c
$ ./z
x = 0.3333333432674408
u = 0.33333333333333331
%%%

Evaluation at compile time is different that at runtime because gcc
thinks that float operations are performed in float precision and
performs them at that precision at compile time.  But float operations
at runtime are actually performed in the ambient precision due to
white lies like the following in i386.md:

%%%
(define_expand "divsf3"
  [(set (match_operand:SF 0 "register_operand" "")
	(div:SF (match_operand:SF 1 "register_operand" "")
		(match_operand:SF 2 "nonimmediate_operand" "")))]
  "TARGET_80387 || TARGET_SSE_MATH"
  "")
%%%

(This says that the result of dividing a single-precision float by a
single precision float is a single-precision float, but the result is
actually an ambient-precision float.)

The above example is for float precision.  The FreeBSD default basically
insulates users from surprises due to precision when everything is a long
double.

> BTW, NetBSD is kinda schizophrenic about this:

It just supports a lot of cases.

> /*
>  * The i387 defaults to Intel extended precision mode and round to nearest,
>  * with all exceptions masked.
>  */
> #define __INITIAL_NPXCW__       0x037f
> /* NetBSD uses IEEE double precision. */
> #define __NetBSD_NPXCW__        0x127f
> /* FreeBSD leaves some exceptions unmasked as well. */
> #define __FreeBSD_NPXCW__       0x1272

This is the FreeBSD[1-3] default.

> /* iBCS2 goes a bit further and leaves the underflow exception unmasked. */
> #define __iBCS2_NPXCW__         0x0262

FreeBSD and NetBSD are both derived from 386BSD which had this.  I added
the 0x1000 bit in case 386BSD ever got run with a 287.

> /* Linux just uses the default control word. */
> #define __Linux_NPXCW__         0x037f
> /* SVR4 uses the same control word as iBCS2. */
> #define __SVR4_NPXCW__          0x0262
>
> So their float.h values are correct only for Linux binaries and
> emulation.  Also, it looks like FreeBSD_NPXCW is incorrect, since we

Linux binaries are just differently incorrect :-).

> have:
> #define	__INITIAL_NPXCW__	0x127F
>
> And there's a comment:
>  * 64-bit precision often gives bad results with high level languages
>  * because it makes the results of calculations depend on whether
>  * intermediate values are stored in memory or in FPU registers.
> which seems like a compiler issue, not an OS issue to me.

Indeed it is mostly a language issue, so this is not a very good place to
decide the setting.  You would not be wrong to set it in crt0 if you removed
it in the kernel (just set the hardware default in the kernel).  But the
library can still override any unwanted defaults.

Bruce


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




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