svn commit: r329859 - in head: contrib/compiler-rt/lib/builtins include stand sys/arm/include sys/arm64/include sys/mips/include sys/powerpc/include sys/riscv/include sys/sparc64/include sys/sys sy...

Bruce Evans brde at optusnet.com.au
Fri Feb 23 16:48:40 UTC 2018


On Fri, 23 Feb 2018, Warner Losh wrote:

> On Thu, Feb 22, 2018 at 11:12 PM, Bruce Evans <brde at optusnet.com.au> wrote:
>
>> On Fri, 23 Feb 2018, Warner Losh wrote:
>* ...
>> Modified: head/sys/arm/include/_types.h
>>> ============================================================
>>> ==================
>>> --- head/sys/arm/include/_types.h       Fri Feb 23 04:04:18 2018
>>> (r329858)
>>> +++ head/sys/arm/include/_types.h       Fri Feb 23 04:04:25 2018
>>> (r329859)
>>> @@ -70,8 +70,10 @@ typedef      unsigned long long      __uint64_t;
>>>  */
>>> typedef __uint32_t      __clock_t;              /* clock()... */
>>> typedef __int32_t       __critical_t;
>>> +#ifndef _STANDALONE
>>> typedef double          __double_t;
>>> typedef float           __float_t;
>>> +#endif
>>> typedef __int32_t       __intfptr_t;
>>> typedef __int64_t       __intmax_t;
>>> typedef __int32_t       __intptr_t;
>>
>> __types.h headers exist to avoid ifdefs like this.  They only define types
>> in the implementation namespace.  Nothing except <math.h> should use
>> __double_t or __float_t directly.  There is only a problem if some option
>> like -fno-float turns off floating point completely, so that 'float' is
>> a syntax error.
>
> Right. Except, there's no longer a -fno-float option. Then again, these
> should almost certainly be in sys/_types instead because they are identical
> on every platform and will almost certainly never ever be anything other
> than what they are.
>
> For the boot loader, I spiked double and float definitions so that we don't
> touch floating point types at all. We do this in the Makefile by
> intentionally creating syntax errors. I don't think this is undefined
> behavior, I think it is well defined behavior: A syntax error is a syntax
> error. We're using a restricted set of C for the loader anyway. It's mostly
> to prevent accidental use of floating point.

It is more undefined than most undefined things.  E.g., C99 7.1.3p2 says:

        If the program ... defines a reserved identifier as a macro name,
        the behavior is undefined.

Even K&R support was much more careful.  E.g., to avoid defining away const,
it spelled const as __const and defined __const as nothing for K&R and as
const for C99 and later.  <sys/cdefs.h> still has ifdef tangles to support
this, but they are almost useless since other headers no longer use __const
and even <sys/cdefs.h> uses plain const in many places.  Also, the
defining away of __const is now under a very confusing condition
(_CC_SUPPORTS___INLINE).  The connection with __inline is that __inline is
gcc's pre-C99 spelling of inline.  gcc also has __const, which is a pre-C90
spelling of const.  The FreeBSD semantics for __const are tangled up with
the gcc semantics (FreeBSD wants to keep __const as itself and not define
it away for gcc with pre-C90 support).

<sys/cdefs.h> does define away const, etc under the even more arcane option
(_CC_SUPPORTS___INLINE && NO_ANSI_KEYWORDS.  (Hmm, NO_ANSI_KEYWORDS is
namespace pollution.)

You don't want these complications for float and double.

> If we ever support floats and such in the boot loader, I'll revert. This

Kernel programmers have no difficulty not using floats in kernel code.

I actually use doubles in tsc.c to do cperciva's statistics.  This is
much easier than using fixed point.  Compilers don't quite support it.
I have to remove -msoft-float and compile with gcc.  clang refuses
inline __builtin_sqrtl().

> helps us catch accidents like one of the lua files being compiled
> incorrectly, leading to stray references to float/double on arm which
> caused float stuff to be referenced and pulled in due to inlining. That's
> the real bug, and that's been fixed. Until we need float/double in the
> loader, I'll keep this in place to prevent a recurrence.

Floating point is even easier to use in boot code than in the kernel.
In tsc.c, I don't bother obtaining ownership of the FPU by the thread,
but just use it.  This works because there aren't really any threads
early in the boot.  Similarly in boot code.  The initialization is:

XX 	 * Since we want this calculation to be as accurate as possible, and
XX 	 * we cannot use the FPU at this point in the boot cycle, we resort to
XX 	 * fixed-point arithmetic, shifting everything as far left as we can
XX 	 * rely on being safe: The mean TSC is bounded by the maximum TSC, and

Above comment by cperciva.

XX 	/* Contrary to the comment, we can use the npx especially easily. */
XX 	__asm __volatile("clts; fninit");

This wasn't so easy in 1992 when on x86's the FPU might have been separate
or emulated.

Compilers might generate FPU use even if there is no explicit use of
floating point in the program, but this is normally turned off in boot
code and kernels using -msoft-float [-mno-sse -m-no-sse2 -mno-sse3 ...].
That should be enough.  Other errors are very easy to find since they
cause linkage failures like for my __builtin_sqrtl().  (gcc compiles
my FP with -msoft-float on i386, but then there are linkage errors for
the nonexistent soft-float support.  On amd64, -msoft-float is not
supported since it uses an incompatible ABI, so the error is detected
before link time.)

Bruce


More information about the svn-src-head mailing list