Hi,
Jakub, thanks for floatbitinttf-ibm128.c and fixtfbitint-ibm128.c and
the follow-up fix.
The changes have been bootstrapped and regression tested on
powerpc64le-linux and powerpc64-linux (m64/m32).
Changes from V2:
* Addressed review comments from Jakub.
* Removed stale code in rs6000_promote_function_mode.
* _BitInt <-> IBM double double (__ibm128): Modified files
floatbitinttf-ibm128.c and fixtfbitint-ibm128.c, provided by Jakub.
* Additional testcase bitint-bitint-to-ibm128.c and
bitint-ibm128-to-bitint.c, provided by Jakub.
Changes from V1:
* The major change being limb mode now DImode on 64-bit PowerPC and
SImode on 32-bit PowerPC.
* Padding bits above the precision in the most significant limb are
unspecified(bitint_ext_undef). So the same rule describes ppc64le,
ppc64 big-endian and ppc32.
* Additional powerpc specific test cases.
This patch implements the powerpc64le/ppc64/ppc32 target hook and
libgcc runtime support needed for GCC's existing C23 _BitInt
front-end/middle-end machinery to work on rs6000. Previously
TARGET_C_BITINT_TYPE_INFO was unimplemented on this target, so
_BitInt was entirely unsupported.
rs6000_bitint_type_info selects the limb mode by precision: QImode,
HImode or SImode for n <= 8, 16 or 32 respectively, and above that the
widest integer that fits in one general purpose register,
i.e. DImode on 64-bit PowerPC and SImode on 32-bit PowerPC.
The ABI limb mode always equals the internal limb mode, so a _BitInt
wider than one limb is an array of limbs, ordered least to most
significant on little-endian and most to least significant on
big-endian, exactly like any other multi-word integer. Padding bits
above the precision in the most significant limb are unspecified
(bitint_ext_undef). Neither property is conditional on endianness, so
the same rule describes ppc64le, ppc64 big-endian and ppc32.
Large _BitInt -- more than 16 bytes under ELFv2, more than 8 bytes
otherwise -- is passed and returned by reference, as aggregates of
those sizes already are. The threshold is computed in one place,
rs6000_bitint_large_p, so that rs6000_return_in_memory and
rs6000_pass_by_reference cannot drift apart. Both use BITINT_TYPE_P
rather than a TREE_CODE test, so that C2Y bit-precise enums backed by
_BitInt are handled identically to plain _BitInt.
rs6000_function_value excludes BITINT_TYPE from the generic sub-word
integer promotion, so that the mode used for a _BitInt return value
agrees with the one the middle end computes for the type.
13 powerpc execution tests covering alignment, size, argument and
return passing (including the by-reference threshold and the
transition around 128 bits), arithmetic, bitwise and shift operations,
comparisons, conversions, byte layout, struct layout and varargs
Tested on powerpc64le-linux and powerpc64-linux (big endian, both
multilibs). One known failure remains on big endian:
gcc.dg/torture/bitint-16.c fails its -O2 execution test with -m32.
2026-08-19 Manjunath Matti <[email protected]>
gcc/ChangeLog:
PR target/117584
* config/rs6000/rs6000-call.cc (rs6000_bitint_large_p): New
function.
(rs6000_return_in_memory): Return large _BitInt values, and enums
backed by _BitInt, via a hidden pointer.
(rs6000_pass_by_reference): Pass large _BitInt values, and enums
backed by _BitInt, by reference.
* config/rs6000/rs6000.cc (TARGET_C_BITINT_TYPE_INFO): Define.
(init_float128_ibm): Set bitinttofp_optab and bitintfromfp_optab
libfuncs to __floatbitinttf and __fixtfbitint.
(init_float128_ieee): Set bitinttofp_optab and bitintfromfp_optab
libfuncs to __floatbitintkf and __fixkfbitint.
(rs6000_function_value): Exclude BITINT_TYPE from sub-word integer
return value promotion.
(rs6000_bitint_type_info): New function.
libgcc/ChangeLog:
PR target/117584
* config/rs6000/float128-sed: Add __floatbitinttf/__floatbitintkf
and __fixtfbitint/__fixkfbitint substitution rules.
* config/rs6000/float128-sed-hw: Likewise.
* config/rs6000/libgcc-glibc.ver (GCC_17.0.0): New version node
inheriting GCC_4.2.0; export __floatbitintkf, __fixkfbitint,
__floatbitinttf, __fixtfbitint, __floatbitintsf, __fixsfbitint,
__floatbitintdf and __fixdfbitint.
* config/rs6000/t-float128 (fp128_softfp_funcs): Add floatbitintkf
and fixkfbitint.
(rs6000_bitint_bin_funcs, rs6000_bitint_bin_src): New; add to
LIB2ADD unconditionally.
(rs6000_bitint_dec_funcs, rs6000_bitint_dec_src): New; add to
LIB2ADD_ST when decimal float is enabled.
* config/rs6000/t-linux (ibm128_bitint_funcs, ibm128_bitint_src):
New; add to LIB2ADD.
(ibm128_bitint_objs, IBM128_BITINT_CFLAGS): New.
* config/rs6000/floatbitinttf-ibm128.c: New file.
* config/rs6000/fixtfbitint-ibm128.c: New file.
gcc/testsuite/ChangeLog:
PR target/117584
* gcc.target/powerpc/bitint-abi-call.c: New test.
* gcc.target/powerpc/bitint-alignments-powerpc.c: New test.
* gcc.target/powerpc/bitint-args-powerpc.c: New test.
* gcc.target/powerpc/bitint-arith-powerpc.c: New test.
* gcc.target/powerpc/bitint-bitint-to-ibm128.c: New test.
* gcc.target/powerpc/bitint-bitwise-powerpc.c: New test.
* gcc.target/powerpc/bitint-compare-powerpc.c: New test.
* gcc.target/powerpc/bitint-conversions-powerpc.c: New test.
* gcc.target/powerpc/bitint-endian-powerpc.c: New test.
* gcc.target/powerpc/bitint-ibm128-to-bitint.c: New test.
* gcc.target/powerpc/bitint-sizes-powerpc.c: New test.
* gcc.target/powerpc/bitint-struct-layout.c: New test.
* gcc.target/powerpc/bitint-varargs.c: New test.