cvs commit: src/sys/i386/include _types.h

Bruce Evans brde at
Fri Mar 7 02:57:16 UTC 2008

On Wed, 5 Mar 2008, David Schultz wrote:

> On Wed, Mar 05, 2008, Colin Percival wrote:
>> Bruce Evans wrote:
>>>   Modified files:
>>>     sys/i386/include     _types.h
>>>   Log:
>>>   Change float_t and double_t to long double on i386.
>> Doesn't this have a rather severe performance impact on any code which
>> uses double_t?
> Yes, if the code is compiled with -msse2. Otherwise, doubles get
> fed to the i387 anyway.

Not even then.  Doubles get fed to the i387 anyway in many cases (in
most cases I think).  One exception is double to int conversion --
this uses SSE2 so as to avoid a slow mode switch (cvtsd2si always
rounds towards 0, while the default i386 mode rounds to nearest;
otherwise it would be the SSE code that is slower).  Adds of doubles
normally go through the i387 (I've never seen an exception to this).

> Technically Bruce's change isn't wrong without changing the
> default precision, it's just rather pointless.

It isn't pointless, since the default is only the default.  Changing
it using fpsetprec() has been supported in FreeBSD since 1993, and
before that it required 2 lines of asm.  My change gives double_t
a chance of working right when the default is changed at runtime.
While such changes are not really supported, there is no need to
force them to be broken.

> (Why tell programs
> to store variables in a wider format if you're just going to
> evaluate them in a narrower format anyway?)

After fpsetprec(FP_PE):
(1) the evaluation is not in a narrower format.
(2) I use double_t when I hope that the variable will stay in a register
     and not cost a store
(3) when I store to a double, it is obviously narrower on i386, and the
     compiler is tricked into doing the store correctly without using
     something like STRICT_ASSIGN().  STRICT_ASSIGN() uses a volatile
     hack which makes it potentially slower than an ordinary assignment,
     and currently doesn't support this mode.

Irrespective of fpsetprec(FP_PE):
(1)' - (3)' for float_t vs float precision.  float_t just needs to be
     double for this.  Using long double costs little and is technically
     half required even with the default precision, since the range is
     almost that of a long double.  (The different range affects at least
     overflow exceptions.)
(3)'' I can write code that is more portable and don't need to pessimize
     all uses of STRICT_ALIGN() on doubles by supporting full long double
     precision everywhere.  Code that supports extra precision (either
     by a runtime switch or a change in the default) can use double_t and
     code that doesn't care or doesn't understand the complications can
     keep using plain double.

> So I guess I agree
> that if we're going to go down this path, we ought to just bite
> the bullet and change npx.h and contrib/gcc/config/i386/freebsd.h
> to use 64-bit precision by default on i386.

I hope to do that in a non-revolutionary way.


More information about the cvs-src mailing list