If we want an offical API in C2y we would need to submit a proposal relatively soon.
Martin Am Dienstag, dem 07.07.2026 um 05:51 +0200 schrieb Martin Uecker: > Am Montag, dem 06.07.2026 um 19:23 +0200 schrieb Jakub Jelinek: > > On Mon, Jul 06, 2026 at 05:09:53PM +0200, Martin Uecker wrote: > > > The design looks very reasonable to me, but I have two > > > comments/questions: > > > > > > Do we need the full generality, i.e. support for LE, BE and > > > any limb type or could we simply fix this to whatever corresponds > > > to the ABI? Maybe I am missing something obvious. > > > > Hardcoding some limb type to some _BitInt limb type (but which one, > > on many architectures we have two, the ABI one which influences > > size/alignment decision and another one, often smaller width > > but sometimes the same, which is used in most of the operations) > > would simplify it a little bit, but would be a nightmare for C library > > writers or users which want to write similar APIs in their libraries. > > > As I wrote, at least for the libc built with older compiler which doesn't > > support this (which is something that needs to be supported for at least > > a few years), my plan was that one would compile these intrinsics/macros > > into assembly and use in the library. But the library better should be > > able to choose what limb it wants to use and use it on all architectures, > > rather than dealing with on aarch64 I need 128-bit limb type, on x86_64 > > 64-bit limb type, on i686 32-bit limb type, ... > > I would have assumed they might want to anyway use the same limb type > that is also used by the ABI for _BitInt for large N. Then one would > need to expose this type to the user somehow (__BITINT_LIMB_T__). > But Joseph also gave an argument why libraries might want to pick another > type, so I guess it is better to allow a choice. > > > > > Now, one could hardcode some limb type for all users, say > > unsigned long, but I wasn't sure that is the right choice for all the > > C libraries and all users. I'd say the most usual choices will be likely > > unsinged long, unsigned int and unsigned long long, but already that that > > point the intrinsic needs to support all the cases the posted patch handles, > > namely when the user chosen limb has smaller width than the _BitInt internal > > limb type (but right now the _BitInt internal limb type width has to be > > divisible by the user chosen limb width in that case), or same width, or > > larger width (the posted patch requires double the width in that case). > > I intentionally chose not to support bit-precise integers in the > > type-generic macro, don't think splitting some _BitInt(n) for runtime n > > into an array of _BitInt(17) or array of _BitInt(925) is useful or > > worth the effort. > > > > Regarding endianity, sure, we could hardcode say little-endian ordering, > > or always match the architecture endianity, but that again makes the > > C library maintainance harder for little gain on the compiler side. > > > > > In general for libraries (or user code) there is the issue > > > that different systems may support a different number of bits, > > > and once a library is compiled with one compiler could break > > > (or have limitations) for code using another. This may become > > > a bigger concern when we want to introduce standard library > > > functionality using _BitInt. So I wonder whether these > > > builtins could be made to work for an arbitrary number > > > of bits exceeding what the current limit for GCC is. > > > > There are psABIs which specify the size/alignment/passing/returning of > > _BitInt(N), and GCC chose to support _BitInt only on architectures > > where this is specified or where GCC is a de-factor psABI for the arch. > > For both the __builtin_va_arg_bitint va_arg side, and > > __builtin_bitint_*pack (or __builtin_va_arg_bitint __builtin_bitint_unpack > > side) the emitted code uses (matching the psABIs), something like > > if (n <= 8) > > load using _BitInt(8) (but with alias set matching anything or any > > _BitInt) > > else if (n <= 16) > > load using _BitInt(16) (but with alias set matching anything or any > > _BitInt) > > else if (n <= 32) > > load using _BitInt(32) (but with alias set matching anything or any > > _BitInt) > > ... > > else > > load or handle using VLA of the ABI and/or internal limb types with > > alias set matching anything or any _BitInt > > so the first few n values are handled as special cases and rest handles the > > larger ones of arbitrary sizes. And what GCC emits in that case can handle > > any BITINT_MAXWIDTH, doesn't stop at 65535, will happily handle even the > > clang BITINT_MAXWIDTH it has on the 2 or 3 architectures (rest have I think > > still 128 and don't follow psABI or follow it by accident). > > Of course unless clang chooses to follow psABI for N <= 65535 and for some > > larger ones chooses some completely different ABI. I'm not aware of that > > though, who would bother with something like that. All that e.g. GCC > > supports internally is some small width special cases and then anything > > larger being treated usually as a struct with a single array member of > > the ABI limb type. > > That makes sense, so there is no arbitrary limit and - assuming no one > switches to some new ABI for large N - no compatibility risks. > > > Martin
