Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 29 Apr 2014 07:48:55 +1000 (EST)
From:      Bruce Evans <brde@optusnet.com.au>
To:        John Baldwin <jhb@freebsd.org>
Cc:        svn-src-projects@freebsd.org, src-committers@freebsd.org, Mark Murray <markm@freebsd.org>
Subject:   Re: svn commit: r265045 - projects/random_number_generator/sys/dev/random
Message-ID:  <20140429064758.O1041@besplex.bde.org>
In-Reply-To: <2404556.5ed5qdM2Fl@ralph.baldwin.cx>
References:  <201404280751.s3S7p8Sg008554@svn.freebsd.org> <2404556.5ed5qdM2Fl@ralph.baldwin.cx>

next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, 28 Apr 2014, John Baldwin wrote:

> On Monday, April 28, 2014 07:51:08 AM Mark Murray wrote:
>> Author: markm
>> Date: Mon Apr 28 07:51:07 2014
>> New Revision: 265045
>> URL: http://svnweb.freebsd.org/changeset/base/265045
>>
>> Log:
>>   It turns out powerpc also doesn't have __uint128_t.
>>
>> Modified:
>>   projects/random_number_generator/sys/dev/random/uint128.h
>>
>> Modified: projects/random_number_generator/sys/dev/random/uint128.h
>> ============================================================================
>> == --- projects/random_number_generator/sys/dev/random/uint128.h	Mon Apr 28
>> 07:50:45 2014	(r265044) +++
>> projects/random_number_generator/sys/dev/random/uint128.h	Mon Apr 28
>> 07:51:07 2014	(r265045) @@ -34,7 +34,7 @@
>>   * Everyone knows you always need the __uint128_t types!
>>   */
>>
>> -#if !defined(__arm__) && !defined(__mips__) && !defined(__i386__) &&
>> !defined(__pc98__) +#if !defined(__arm__) && !defined(__mips__) &&
>> !defined(__i386__) && !defined(__pc98__) && !defined(__powerpc__) /* We do
>> have an inbuilt __uint128_t type */
>
> A better test would be to use
>
> #ifdef __SIZEOF_INT128__
>
> instead of listing architectures.  (Especially given it might be true on
> a given platform based on compiler options like -march.)  This is what
> Boost uses to detect a native 128-bit integer and works with both GCC and
> clang.

This is a bad name for an existence macro.  I grepped in cpp -E -dM
output and found nothing better.

Also, the existence of 128-bit integer types is a bug.  These types are
larger than [u[intmax_t.  But [u]intmax_t are specified to be the largest
integer types.  I thought that extended integer types might be allowed
to be larger, but they are not.  I now think extended integer types are
just not required to be supported in <stdint.h>.  But most of the rules
for integer types apply to extended integer types, and the rule that
[u]intmax_t is largest is important.

FreeBSD doesn't support [u]intmax_t == __[u]int128_t in <stdint.h>.
Compilers are bug for bug compatible with this.  They define
__INTMAX_WIDTH__ as only 8 on the same arches that they define
__SIZEOF_INT128__ as 16.
    (__SIZEOF_INT128__ is a bad name in other ways:
     - SIZEOF_FOO is gratuitously different to FOO_WIDTH
     - a value for __SIZEOF_INT128__ is not needed, unlike for
       __INTMAX_WIDTH__, since __int128_t has a fixed size in bits
       (128), so 128 must be a multiple of CHAR_BIT and the size of
       the type must be 128/CHAR_BIT.  Since POSIX requires CHAR_BIT
       to be 8, the size of the type must be 16.)

Things broken collaterally by having an integer type larger than
[u]intmax_t:
- preprocessor arithmetic.  It is specified to use [u]intmax_t.  Thus it
   is specified to work with any integer type.
- header and library support for integer types.  Even extended integer
   types are supposed to be printable by converting them to [u]intmax_t.
   Similarly for input using strto[u]imax().

Fixing this is not easy.  We can pretend that __[u]int128_t is not an
integer type.  This is the current fix.  Expanding [u]intmax_t to 128
bits (later to 256, 512, ... bits) would mainly cause massive bloat
in careful code that uses [u]intmax_t a lot.  It would also break any
ABIs that use [u]intmax_t.  There currently aren't many uses of it.
grepping for intmax_t in /usr/share/man shows mainly the standard APIs
like strtoimax() and imaxdiv(), and spam in nvlist man pages
     (a single uintmax_t in an example in an nvlist man page gets expamded
     to 564 instances.  That's without any cat pages.  The single man page
     is expamded to 141 using hard links.  The 141 hard links are then
     quadruplicated to 4 locales using symlinks.  Outside of this man page,
     there are only 415 lines matching intmax_t.  Somehow not a multiple of
     4.  It is 4*103 + 3.)
Apart from nvlist, nonstandard APIs like strtonum() and
dehumanize_number() are too broken as designed to even use [u]intmax_t,
so they break more automatically for large integer types.  The other
documented nonstandard uses of [u]intmax_t are in: sh(1), expr(1),
asprintf(3), *dprintf(3) and pidfile*(3) [silly -- PID_MAX fits in int18_t
and should remain below INT32_MAX].

Bruce



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