On Thu, 14 Dec 2023, Jakub Jelinek wrote:

> Hi!
> 
> Given what I saw in the aarch64/arm psABIs for BITINT_TYPE, as I said
> earlier I'm afraid we need to differentiate between the limb mode/precision
> specified in the psABIs (what is used to decide how it is actually passed,
> aligned or what size it has) vs. what limb mode/precision should be used
> during bitint lowering and in the libgcc bitint APIs.
> While in the x86_64 psABI a limb is 64-bit, which is perfect for both,
> that is a wordsize which we can perform operations natively in,
> e.g. aarch64 wants 128-bit limbs for alignment/sizing purposes, but
> on the bitint lowering side I believe it would result in terribly bad code
> and on the libgcc side wouldn't work at all (because it relies there on
> longlong.h support).
> 
> So, the following patch makes it possible for aarch64 to use TImode
> as abi_limb_mode for _BitInt(129) and larger, while using DImode as
> limb_mode.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

Thanks,
Richard.

> 2023-12-14  Jakub Jelinek  <ja...@redhat.com>
> 
>       * target.h (struct bitint_info): Add abi_limb_mode member, adjust
>       comment.
>       * target.def (bitint_type_info): Mention abi_limb_mode instead of
>       limb_mode.
>       * varasm.cc (output_constant): Use abi_limb_mode rather than
>       limb_mode.
>       * stor-layout.cc (finish_bitfield_representative): Likewise.  Assert
>       that if precision is smaller or equal to abi_limb_mode precision or
>       if info.big_endian is different from WORDS_BIG_ENDIAN, info.limb_mode
>       must be the same as info.abi_limb_mode.
>       (layout_type): Use abi_limb_mode rather than limb_mode.
>       * gimple-fold.cc (clear_padding_bitint_needs_padding_p): Likewise.
>       (clear_padding_type): Likewise.
>       * config/i386/i386.cc (ix86_bitint_type_info): Also set
>       info->abi_limb_mode.
>       * doc/tm.texi: Regenerated.
> 
> --- gcc/target.h.jj   2023-09-06 17:28:24.228977486 +0200
> +++ gcc/target.h      2023-12-14 14:26:48.490047206 +0100
> @@ -69,15 +69,23 @@ union cumulative_args_t { void *p; };
>  #endif /* !CHECKING_P */
>  
>  /* Target properties of _BitInt(N) type.  _BitInt(N) is to be represented
> -   as series of limb_mode CEIL (N, GET_MODE_PRECISION (limb_mode)) limbs,
> -   ordered from least significant to most significant if !big_endian,
> +   as series of abi_limb_mode CEIL (N, GET_MODE_PRECISION (abi_limb_mode))
> +   limbs, ordered from least significant to most significant if !big_endian,
>     otherwise from most significant to least significant.  If extended is
>     false, the bits above or equal to N are undefined when stored in a 
> register
>     or memory, otherwise they are zero or sign extended depending on if
> -   it is unsigned _BitInt(N) or _BitInt(N) / signed _BitInt(N).  */
> +   it is unsigned _BitInt(N) or _BitInt(N) / signed _BitInt(N).
> +   limb_mode is either the same as abi_limb_mode, or some narrower mode
> +   in which _BitInt lowering should actually perform operations in and
> +   what libgcc _BitInt helpers should use.
> +   E.g. abi_limb_mode could be TImode which is something some processor
> +   specific ABI would specify to use, but it would be desirable to handle
> +   it as an array of DImode instead for efficiency.
> +   Note, abi_limb_mode can be different from limb_mode only if big_endian
> +   matches WORDS_BIG_ENDIAN.  */
>  
>  struct bitint_info {
> -  machine_mode limb_mode;
> +  machine_mode abi_limb_mode, limb_mode;
>    bool big_endian;
>    bool extended;
>  };
> --- gcc/target.def.jj 2023-12-08 08:28:23.644171016 +0100
> +++ gcc/target.def    2023-12-14 14:27:25.239537794 +0100
> @@ -6357,8 +6357,8 @@ DEFHOOK
>  (bitint_type_info,
>   "This target hook returns true if @code{_BitInt(@var{N})} is supported 
> and\n\
>  provides details on it.  @code{_BitInt(@var{N})} is to be represented as\n\
> -series of @code{info->limb_mode}\n\
> -@code{CEIL (@var{N}, GET_MODE_PRECISION (info->limb_mode))} limbs,\n\
> +series of @code{info->abi_limb_mode}\n\
> +@code{CEIL (@var{N}, GET_MODE_PRECISION (info->abi_limb_mode))} limbs,\n\
>  ordered from least significant to most significant if\n\
>  @code{!info->big_endian}, otherwise from most significant to least\n\
>  significant.  If @code{info->extended} is false, the bits above or equal 
> to\n\
> --- gcc/varasm.cc.jj  2023-12-01 08:10:44.504299177 +0100
> +++ gcc/varasm.cc     2023-12-14 14:55:45.821971713 +0100
> @@ -5315,7 +5315,8 @@ output_constant (tree exp, unsigned HOST
>         tree type = TREE_TYPE (exp);
>         bool ok = targetm.c.bitint_type_info (TYPE_PRECISION (type), &info);
>         gcc_assert (ok);
> -       scalar_int_mode limb_mode = as_a <scalar_int_mode> (info.limb_mode);
> +       scalar_int_mode limb_mode
> +         = as_a <scalar_int_mode> (info.abi_limb_mode);
>         if (TYPE_PRECISION (type) <= GET_MODE_PRECISION (limb_mode))
>           {
>             cst = expand_expr (exp, NULL_RTX, VOIDmode, EXPAND_INITIALIZER);
> --- gcc/stor-layout.cc.jj     2023-10-08 16:37:31.780273377 +0200
> +++ gcc/stor-layout.cc        2023-12-14 14:59:27.147904721 +0100
> @@ -2154,7 +2154,8 @@ finish_bitfield_representative (tree rep
>         unsigned prec = TYPE_PRECISION (TREE_TYPE (field));
>         bool ok = targetm.c.bitint_type_info (prec, &info);
>         gcc_assert (ok);
> -       scalar_int_mode limb_mode = as_a <scalar_int_mode> (info.limb_mode);
> +       scalar_int_mode limb_mode
> +         = as_a <scalar_int_mode> (info.abi_limb_mode);
>         unsigned lprec = GET_MODE_PRECISION (limb_mode);
>         if (prec > lprec)
>           {
> @@ -2416,16 +2417,20 @@ layout_type (tree type)
>       int cnt;
>       bool ok = targetm.c.bitint_type_info (TYPE_PRECISION (type), &info);
>       gcc_assert (ok);
> -     scalar_int_mode limb_mode = as_a <scalar_int_mode> (info.limb_mode);
> +     scalar_int_mode limb_mode
> +       = as_a <scalar_int_mode> (info.abi_limb_mode);
>       if (TYPE_PRECISION (type) <= GET_MODE_PRECISION (limb_mode))
>         {
>           SET_TYPE_MODE (type, limb_mode);
> +         gcc_assert (info.abi_limb_mode == info.limb_mode);
>           cnt = 1;
>         }
>       else
>         {
>           SET_TYPE_MODE (type, BLKmode);
>           cnt = CEIL (TYPE_PRECISION (type), GET_MODE_PRECISION (limb_mode));
> +         gcc_assert (info.abi_limb_mode == info.limb_mode
> +                     || !info.big_endian == !WORDS_BIG_ENDIAN);
>         }
>       TYPE_SIZE (type) = bitsize_int (cnt * GET_MODE_BITSIZE (limb_mode));
>       TYPE_SIZE_UNIT (type) = size_int (cnt * GET_MODE_SIZE (limb_mode));
> --- gcc/gimple-fold.cc.jj     2023-11-30 20:43:32.273640149 +0100
> +++ gcc/gimple-fold.cc        2023-12-14 14:52:13.363915817 +0100
> @@ -4604,7 +4604,7 @@ clear_padding_bitint_needs_padding_p (tr
>    gcc_assert (ok);
>    if (info.extended)
>      return false;
> -  scalar_int_mode limb_mode = as_a <scalar_int_mode> (info.limb_mode);
> +  scalar_int_mode limb_mode = as_a <scalar_int_mode> (info.abi_limb_mode);
>    if (TYPE_PRECISION (type) < GET_MODE_PRECISION (limb_mode))
>      return true;
>    else if (TYPE_PRECISION (type) == GET_MODE_PRECISION (limb_mode))
> @@ -4881,7 +4881,8 @@ clear_padding_type (clear_padding_struct
>       struct bitint_info info;
>       bool ok = targetm.c.bitint_type_info (TYPE_PRECISION (type), &info);
>       gcc_assert (ok);
> -     scalar_int_mode limb_mode = as_a <scalar_int_mode> (info.limb_mode);
> +     scalar_int_mode limb_mode
> +       = as_a <scalar_int_mode> (info.abi_limb_mode);
>       if (TYPE_PRECISION (type) <= GET_MODE_PRECISION (limb_mode))
>         {
>           gcc_assert ((size_t) sz <= clear_padding_unit);
> --- gcc/config/i386/i386.cc.jj        2023-12-13 11:34:05.836511498 +0100
> +++ gcc/config/i386/i386.cc   2023-12-14 14:28:34.074583610 +0100
> @@ -25679,6 +25679,7 @@ ix86_bitint_type_info (int n, struct bit
>      info->limb_mode = SImode;
>    else
>      info->limb_mode = DImode;
> +  info->abi_limb_mode = info->limb_mode;
>    info->big_endian = false;
>    info->extended = false;
>    return true;
> --- gcc/doc/tm.texi.jj        2023-12-08 08:28:23.520172768 +0100
> +++ gcc/doc/tm.texi   2023-12-14 14:58:12.643937150 +0100
> @@ -1032,8 +1032,8 @@ applied.
>  @deftypefn {Target Hook} bool TARGET_C_BITINT_TYPE_INFO (int @var{n}, struct 
> bitint_info *@var{info})
>  This target hook returns true if @code{_BitInt(@var{N})} is supported and
>  provides details on it.  @code{_BitInt(@var{N})} is to be represented as
> -series of @code{info->limb_mode}
> -@code{CEIL (@var{N}, GET_MODE_PRECISION (info->limb_mode))} limbs,
> +series of @code{info->abi_limb_mode}
> +@code{CEIL (@var{N}, GET_MODE_PRECISION (info->abi_limb_mode))} limbs,
>  ordered from least significant to most significant if
>  @code{!info->big_endian}, otherwise from most significant to least
>  significant.  If @code{info->extended} is false, the bits above or equal to
> 
>       Jakub
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)

Reply via email to