On Thu, Nov 06, 2025 at 10:49:01PM +0800, Kito Cheng wrote:
> This patch implements _BitInt support for RISC-V target by defining the
> type layout and ABI requirements. The limb mode selection is based on
> the bit width, using appropriate integer modes from QImode to TImode.
> The implementation also adds the necessary libgcc version symbols for
> _BitInt runtime support functions.
>
> gcc/ChangeLog:
>
> PR target/117581
> * config/riscv/riscv.cc (riscv_bitint_type_info): New function.
> (TARGET_C_BITINT_TYPE_INFO): Define.
> --- a/gcc/config/riscv/riscv.cc
> +++ b/gcc/config/riscv/riscv.cc
> @@ -14654,6 +14654,35 @@ riscv_c_mode_for_floating_type (enum tree_index ti)
> return default_mode_for_floating_type (ti);
> }
>
> +/* Implement TARGET_C_BITINT_TYPE_INFO.
> + Return true if _BitInt(N) is supported and fill its details into *INFO.
> */
> +bool
> +riscv_bitint_type_info (int n, struct bitint_info *info)
> +{
> + if (n <= 8)
> + info->limb_mode = QImode;
> + else if (n <= 16)
> + info->limb_mode = HImode;
> + else if (n <= 32)
> + info->limb_mode = SImode;
> + else if (n <= 64)
> + info->limb_mode = DImode;
> + else
> + {
> + if (TARGET_64BIT)
> + info->limb_mode = TImode;
> + else
> + info->limb_mode = DImode;
> + }
> +
> + info->abi_limb_mode = info->limb_mode;
I'm really surprised if this works at all, certainly it looks very
problematic. E.g. libgcc2.c __mulbitint* needs umul_ppmm in that case
which will multiply 2 128-bit numbers and produce 256-bit one (split into
two 128-bit numbers), similarly division etc.
It is fine if your psABI (does it have _BitInt support?) says that the limbs
should be 128-bit for 64-bit RISCV and 64-bit for 32-bit RISCV.
So, the abi_limb_mode choice is reasonable.
But unless the CPU is truly 128-bit and supports all basic arithmetics on
128-bit types in hw etc., the limb_mode choice looks bad.
You really don't want the compiler emitted code to be handling 128-bit limbs
at a time (or for 32-bit target 64-bit limbs at a time), it is much better
to handle 64-bit limbs at a time or 32-bit limbs for 32-bit target.
Not to mention libgcc.
So, for info->limb_mode I think you want instead something like
aarch64 does, which is:
if (n <= 8)
info->limb_mode = QImode;
else if (n <= 16)
info->limb_mode = HImode;
else if (n <= 32)
info->limb_mode = SImode;
else if (n <= 64)
info->limb_mode = DImode;
else if (n <= 128)
info->limb_mode = TImode;
else
info->limb_mode = DImode;
if (n > 128)
info->abi_limb_mode = TImode;
else
info->abi_limb_mode = info->limb_mode;
And correspondingly for !TARGET_64BIT, so:
if (n <= 8)
info->limb_mode = QImode;
else if (n <= 16)
info->limb_mode = HImode;
else if (n <= 32)
info->limb_mode = SImode;
else if (n <= 64)
info->limb_mode = DImode;
else if (n <= 128 && TARGET_64BIT)
info->limb_mode = TImode;
else if (TARGET_64BIT)
info->limb_mode = DImode;
else
info->limb_mode = SImode;
if (TARGET_64BIT && n > 128)
info->abi_limb_mode = TImode;
else if (!TARGET_64BIT && n > 64)
info->abi_limb_mode = DImode;
else
info->abi_limb_mode = info->limb_mode;
> + info->big_endian = TARGET_BIG_ENDIAN;
> + info->extended = true;
Though, because you've chosen info->extended (is it what
RISCV psABI requires), there is further complication.
I'm afraid the generic code right now will not take care of doing an
extension into the most significant 64 (or for !TARGET_64BIT 32)
bits of _BitInts like _BitInt(1025). LoongArch chose to use info->extended
but its psABI says that it only extends the last half-limb, and s390x as
another arch with info->extended has abi_limb_mode == limb_mode always
(uses 64-bit limbs rather than 128-bit limbs in the psABI).
BTW, when you choose info->extended, you should edit
gcc/testsuite/gcc.dg/bitintext.h
and add the extension support in there.
Jakub