Jakub, Thanks for the helpful explanation!

I wanted to add some perspective on the ABI side.

Setting the abi_limb_mode to 2 * XLEN is primarily for compatibility
with existing ABI rules, where 2 * XLEN is passed via registers. For
the parts exceeding that, they become an array of 2 * XLEN bit
elements. This is a consideration for RV32 having Zilsd, and while
RV64 doesn't support it yet, it might in the future.

Jakub Jelinek <[email protected]> 於 2026年1月10日週六 上午6:09寫道:
>
> On Thu, Jan 08, 2026 at 08:50:35AM -0700, Jeffrey Law wrote:
> > > +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 (n <= 128 && TARGET_64BIT)
> > > +    info->limb_mode = TImode;
> > > +  else
> > > +    info->limb_mode = TARGET_64BIT ? DImode : SImode;
> > So I've never looked at how BitInt works, so if this is totally off-base
> > just say so ;-)
> >
> > It seems a bit odd to have the limb_mode by DImode for rv32 when we don't
> > have any DImode operations in rv32.  Though we allow TImode for rv64, so
> > perhaps we're just relying on widening capabilities in the expander
> > interfaces under the hood?
> >
> > It also seems a bit odd that for n > 128 and TARGET_64BIT that we select
> > DImode when we use TImode for sizes > 64, but <= 128.   Similarly for
> > !TARGET_64BIT we have SImode and DImode respectively.
>
> It depends on what the psABI says (if it says anything at all).
> What Kito posted is quite usual thing (except for the abi_limb_mode !=
> limb_mode && extended = true case which still needs to have a few spots
> in the generic handling tweaked (like for arm32).
>
> The above with that
> +  info->abi_limb_mode = info->limb_mode;
> +
> +  if (n > 64 && TARGET_64BIT)
> +    info->abi_limb_mode = TImode;
> +
> +  if (n > 32 && !TARGET_64BIT)
> +    info->abi_limb_mode = DImode;
> after it means that for TARGET_64BIT, up to _BitInt(128) those
> are passed and handled like char/short/int/long long/__int128 (or unsigned
> versions thereof) and for _BitInt(129) and above it is handled as
> structure containing array of __int128 elements for passing/alignment,
> but code emitted by compiler and libgcc handles it as array of long long
> elements.
> And similarly for !TARGET_64BIT ditto except the boundary is _BitInt(64)
> and instead of __int128 in the above it is long long and instead of long
> long elements int elements.
> So, it will use 2 words only for the _BitInt(65) to _BitInt(128)
> case (resp. _BitInt(33) to _BitInt(64)) and for larger stuff it will
> use initially straight line code, then loops working on word-sized elements.
>
>         Jakub
>

Reply via email to