On Thu, Sep 10, 2026 at 05:17:01AM -0500, Manjunath S Matti wrote:
> 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.
> 

This looks good to me.  I tried it doing builds with the long double
format set to IBM double double and IEEE 128-bit.  There are no
additional failures when long double is IEEE 128 bit.

I tried my own test to verify all of the floating point tests correctly
set all of the mantissa bits when doing conversions.

On PowerPC Little Endian, I did notice that one test
(gcc.dg/dfp/int128-4.c) fails.  You can check in the changes to the
master branch, and we can fix it later.  Thanks for doing this work.

-- 
Michael Meissner, IBM
PO Box 98, Ayer, Massachusetts, USA, 01432
email: [email protected]

Reply via email to