Hi Kishan,

On 23/09/26 11:54 am, Kishan Parmar wrote:
> Hi All,
> 
> Below patch is bootstrapped and regtested on power64le-linux.
> 
> Thank you,
> Kishan
> 
> The rs6000 built-in infrastructure previously supported only a single
> gating predicate per built-in stanza.  This caused problems when a
> built-in required multiple conditions simultaneously.  For example,
> __builtin_vsx_xvtlsbb_all_ones requires both Power10 ISA support
> (-mcpu=power10) and VSX support (-mvsx), but was gated only on
> [power10], causing compiler crashes when compiled with -mcpu=power10
> -mno-vsx.
> 
> This patch extends the built-in infrastructure to support up to four
> comma-separated gating predicates in stanza headers, e.g.:
> 
>   [power10, vsx]
> 
> All predicates are combined with AND logic all must be satisfied for
> the built-in to be enabled. existing single-predicate stanzas are parsed
> as before.
> 
> The stanza keywords that hard-coded multi-predicate combinations
> (power6-64, power7-64, power8-vector, power9-64, power9-vector,
> power10-64, future-altivec, future-vsx) are removed and replaced by
> explicit comma-separated forms (e.g. [power9, vsx] instead of
> [power9-vector]).
> 
> The two new static helpers get_enable_string() and check_single_enable()
> consolidate all predicate-to-string and predicate-to-target-flag mapping
> that was previously duplicated across the two functions.
> 
> Note: only __builtin_vsx_xvtlsbb_all_ones and
> __builtin_vsx_xvtlsbb_all_zeros are moved to an explicit [power10, vsx]
> stanza in this patch.  Full rework of rs6000-builtins.def to use
> multi-predicate stanzas throughout is left for a follow-on patch.
> 
> This also fixes diagnostics for built-ins whose availability depends on
> both an ISA level and an additional feature.  For example,
> __builtin_dmsetdmrz previously reported only "-mdense-math":
> 
>   error: '__builtin_dmsetdmrz' requires the '-mdense-math' option
> 
> It now correctly reports both required predicates:
> 
>   error: '__builtin_dmsetdmrz' requires the '-mcpu=future' and
>   '-mdense-math' options
> 
> Similarly, MMA built-ins that require both Power10 ISA support and MMA
> support now report both missing requirements.  For example,
> __builtin_mma_xxsetaccz previously reported only "-mmma", while it now
> reports:
> 
>   error: '__builtin_mma_xxsetaccz' requires the '-mcpu=power10' and
>   '-mmma' options
> 
> This ensures diagnostics accurately reflect all gating predicates required
> by a built-in.
> 
> gcc/ChangeLog:
>       PR target/125389
>       * config/rs6000/rs6000-builtin.cc (get_enable_string): New static
>       helper. map a single bif_enable to its option-string representation.
>       (check_single_enable): New static helper. return true when a single
>       bif_enable predicate is satisfied by the current target.
>       (rs6000_invalid_builtin): Rewrite.  Loop over enables[]. track
>       ENB_M64 and ENB_IEEE128_HW separately for special diagnostic wording.
>       emit a single error naming every predicate the built-in requires.
>       (rs6000_builtin_is_supported): Rewrite.  Loop over enables[] calling
>       check_single_enable. return false on the first unsatisfied predicate.
>       * config/rs6000/rs6000-builtins.def: Update file-header comment to
>       document multi-predicate syntax.  Replace composite stanza keywords
>       with explicit comma-separated forms: [power6-64] -> [power6, m64],
>       [power7-64] -> [power7, m64], [power8-vector] -> [power8, vsx],
>       [power9-vector] -> [power9, vsx], [power9-64] -> [power9, m64],
>       [power10-64] -> [power10, m64], [future-altivec] -> [future, altivec],
>       [future-vsx] -> [future, vsx].  Move __builtin_vsx_xvtlsbb_all_ones
>       and __builtin_vsx_xvtlsbb_all_zeros from the [power10] stanza to a
>       new [power10, vsx] stanza.
>       * config/rs6000/rs6000-gen-builtins.cc: Update file-header comment
>       to document multi-predicate stanza syntax.
>       (enum bif_stanza): Remove stanzas BSTZ_P6_64, BSTZ_P7_64, BSTZ_P8V,
>       BSTZ_P9_64, BSTZ_P9V, BSTZ_P10_64, BSTZ_FUTURE_ALTIVEC,
>       BSTZ_FUTURE_VSX.  Add BSTZ_M64.
>       (MAXBIFPREDICATES): New macro. maximum predicates per stanza.
>       (curr_bif_num_predicates): New file-scope variable.
>       (curr_bif_predicates): New file-scope array.
>       (stanza_map): Remove composite entries. add "m64" -> BSTZ_M64.
>       (enable_string): Remove composite ENB_* entries. add ENB_M64.
>       (struct bifdata): Add fields num_predicates and predicates[].
>       (parse_bif_stanza_predicates): New function. parse comma-separated
>       predicates from a stanza header string.
>       (parse_bif_entry): Store num_predicates and predicates[] into bifdata.
>       (parse_bif_stanza): Call parse_bif_stanza_predicates instead of
>       stanza_name_to_stanza directly.
>       (write_decls): Emit ENB_M64. remove composite ENB_* values. emit
>       PPC_MAXBIFPREDICATES macro. change bifdata::enable field to
>       num_enables and enables[PPC_MAXBIFPREDICATES].
>       (write_bif_static_init): Emit num_enables and enables[] initializer
>       instead of single enable value.
> 
> gcc/testsuite/ChangeLog:
>       PR target/125389
>       * gcc.target/powerpc/pr96125.c:  Update expected error messages to
>       include the '-mcpu=power10' requirement for MMA built-ins.
> ---
>  gcc/config/rs6000/rs6000-builtin.cc        | 209 ++++++++++++---------
>  gcc/config/rs6000/rs6000-builtins.def      |  48 +++--
>  gcc/config/rs6000/rs6000-gen-builtins.cc   | 143 ++++++++++----
>  gcc/testsuite/gcc.target/powerpc/pr96125.c |   4 +-
>  4 files changed, 250 insertions(+), 154 deletions(-)
> 
> diff --git a/gcc/config/rs6000/rs6000-builtin.cc 
> b/gcc/config/rs6000/rs6000-builtin.cc
> index ad6f1fc09f4..9af2edca38c 100644
> --- a/gcc/config/rs6000/rs6000-builtin.cc
> +++ b/gcc/config/rs6000/rs6000-builtin.cc
> @@ -62,136 +62,75 @@ tree altivec_builtin_mask_for_load;
>  
>  /* **** General support functions **** */
>  
> -/* Raise an error message for a builtin function that is called without the
> -   appropriate target options being set.  */
> +/* Helper function to get the option string for a single enable predicate.  
> */
>  
> -void
> -rs6000_invalid_builtin (enum rs6000_gen_builtins fncode)
> +static const char *
> +get_enable_string (bif_enable enable)
>  {
> -  size_t j = (size_t) fncode;
> -  const char *name = rs6000_builtin_info[j].bifname;
> -
> -  switch (rs6000_builtin_info[j].enable)
> +  switch (enable)
>      {
>      case ENB_P5:
> -      error ("%qs requires the %qs option", name, "-mcpu=power5");
> -      break;
> +      return "-mcpu=power5";
>      case ENB_P6:
> -      error ("%qs requires the %qs option", name, "-mcpu=power6");
> -      break;
> -    case ENB_P6_64:
> -      error ("%qs requires the %qs option and either the %qs or %qs option",
> -          name, "-mcpu=power6", "-m64", "-mpowerpc64");
> -      break;
> +      return "-mcpu=power6";
>      case ENB_ALTIVEC:
> -      error ("%qs requires the %qs option", name, "-maltivec");
> -      break;
> +      return "-maltivec";
>      case ENB_CELL:
> -      error ("%qs requires the %qs option", name, "-mcpu=cell");
> -      break;
> +      return "-mcpu=cell";
>      case ENB_VSX:
> -      error ("%qs requires the %qs option", name, "-mvsx");
> -      break;
> +      return "-mvsx";
>      case ENB_P7:
> -      error ("%qs requires the %qs option", name, "-mcpu=power7");
> -      break;
> -    case ENB_P7_64:
> -      error ("%qs requires the %qs option and either the %qs or %qs option",
> -          name, "-mcpu=power7", "-m64", "-mpowerpc64");
> -      break;
> +      return "-mcpu=power7";
>      case ENB_P8:
> -      error ("%qs requires the %qs option", name, "-mcpu=power8");
> -      break;
> -    case ENB_P8V:
> -      error ("%qs requires the %qs and %qs options", name, "-mcpu=power8",
> -          "-mvsx");
> -      break;
> +      return "-mcpu=power8";
>      case ENB_P9:
> -      error ("%qs requires the %qs option", name, "-mcpu=power9");
> -      break;
> -    case ENB_P9_64:
> -      error ("%qs requires the %qs option and either the %qs or %qs option",
> -          name, "-mcpu=power9", "-m64", "-mpowerpc64");
> -      break;
> -    case ENB_P9V:
> -      error ("%qs requires the %qs and %qs options", name, "-mcpu=power9",
> -          "-mvsx");
> -      break;
> -    case ENB_IEEE128_HW:
> -      error ("%qs requires quad-precision floating-point arithmetic", name);
> -      break;
> +      return "-mcpu=power9";
>      case ENB_DFP:
> -      error ("%qs requires the %qs option", name, "-mhard-dfp");
> -      break;
> +      return "-mhard-dfp";
>      case ENB_CRYPTO:
> -      error ("%qs requires the %qs option", name, "-mcrypto");
> -      break;
> +      return "-mcrypto";
>      case ENB_HTM:
> -      error ("%qs requires the %qs option", name, "-mhtm");
> -      break;
> +      return "-mhtm";
>      case ENB_P10:
> -      error ("%qs requires the %qs option", name, "-mcpu=power10");
> -      break;
> -    case ENB_P10_64:
> -      error ("%qs requires the %qs option and either the %qs or %qs option",
> -          name, "-mcpu=power10", "-m64", "-mpowerpc64");
> -      break;
> +      return "-mcpu=power10";
>      case ENB_MMA:
> -      error ("%qs requires the %qs option", name, "-mmma");
> -      break;
> +      return "-mmma";
>      case ENB_FUTURE:
> -      error ("%qs requires the %qs option", name, "-mcpu=future");
> -      break;
> -    case ENB_FUTURE_ALTIVEC:
> -      error ("%qs requires the %qs and %qs options", name, "-mcpu=future",
> -          "-maltivec");
> -      break;
> -    case ENB_FUTURE_VSX:
> -      error ("%qs requires the %qs and %qs options", name, "-mcpu=future",
> -          "-mvsx");
> -      break;
> +      return "-mcpu=future";
>      case ENB_DM:
> -      error ("%qs requires the %qs option", name, "-mdense-math");
> -      break;
> +      return "-mdense-math";
>      default:
>      case ENB_ALWAYS:
> +    case ENB_M64:
> +    case ENB_IEEE128_HW:
>        gcc_unreachable ();
>      }
> +  gcc_unreachable ();
>  }
>  
> -/* Check whether a builtin function is supported in this target
> -   configuration.  */
> -bool
> -rs6000_builtin_is_supported (enum rs6000_gen_builtins fncode)
> +/* Helper function to check if a single enable predicate is satisfied.  */
> +
> +static bool
> +check_single_enable (bif_enable enable)
>  {
> -  switch (rs6000_builtin_info[(size_t) fncode].enable)
> +  switch (enable)
>      {
>      case ENB_ALWAYS:
>        return true;
> +    case ENB_M64:
> +      return TARGET_POWERPC64;
>      case ENB_P5:
>        return TARGET_POPCNTB;
>      case ENB_P6:
>        return TARGET_CMPB;
> -    case ENB_P6_64:
> -      return TARGET_CMPB && TARGET_POWERPC64;
>      case ENB_P7:
>        return TARGET_POPCNTD;
> -    case ENB_P7_64:
> -      return TARGET_POPCNTD && TARGET_POWERPC64;
>      case ENB_P8:
>        return TARGET_POWER8;
> -    case ENB_P8V:
> -      return TARGET_P8_VECTOR;
>      case ENB_P9:
>        return TARGET_MODULO;
> -    case ENB_P9_64:
> -      return TARGET_MODULO && TARGET_POWERPC64;
> -    case ENB_P9V:
> -      return TARGET_P9_VECTOR;
>      case ENB_P10:
>        return TARGET_POWER10;
> -    case ENB_P10_64:
> -      return TARGET_POWER10 && TARGET_POWERPC64;
>      case ENB_ALTIVEC:
>        return TARGET_ALTIVEC;
>      case ENB_VSX:
> @@ -210,10 +149,6 @@ rs6000_builtin_is_supported (enum rs6000_gen_builtins 
> fncode)
>        return TARGET_MMA;
>      case ENB_FUTURE:
>        return TARGET_FUTURE;
> -    case ENB_FUTURE_ALTIVEC:
> -      return TARGET_FUTURE && TARGET_ALTIVEC;
> -    case ENB_FUTURE_VSX:
> -      return TARGET_FUTURE && TARGET_VSX;
>      case ENB_DM:
>        return TARGET_DMF;
>      default:
> @@ -222,6 +157,92 @@ rs6000_builtin_is_supported (enum rs6000_gen_builtins 
> fncode)
>    gcc_unreachable ();
>  }
>  
> +/* Raise an error message for a builtin function that is called without the
> +   appropriate target options being set.  All predicates the builtin requires
> +   are reported so the user can see the full set at once.  */

Currently, rs6000_invalid_builtin() checks all required features without
checking whether they are already enabled by the user.

As a result, the error message may list options that the user has already
specified.

For example:

1. -mcpu=power10 -mno-vsx

Test case:

#include <altivec.h>

extern vector signed char abc;

int main()
{
  return __builtin_vsx_xvtlsbb_all_ones (abc);
}

The diagnostic reports both -mcpu=power10 and -mvsx, even though -mcpu=power10
is already specified.

2. -m64 -mcpu=power5

Test case:

unsigned long long test (unsigned long long a, unsigned long long b)
{
  return __builtin_cmpb (a, b);
}

The diagnostic reports -mcpu=power6 and either -m64 or -mpowerpc64, even though
-m64 is already specified.

> +
> +void
> +rs6000_invalid_builtin (enum rs6000_gen_builtins fncode)
> +{
> +  size_t j = (size_t) fncode;
> +  const char *name = rs6000_builtin_info[j].bifname;
> +  int num_enables = rs6000_builtin_info[j].num_enables;
> +
> +  if (num_enables == 1
> +      && rs6000_builtin_info[j].enables[0] == ENB_IEEE128_HW)
> +    {
> +      error ("%qs requires quad-precision floating-point arithmetic", name);
> +      return;
> +    }
> +
> +  /* Collect all predicates the builtin requires.  */
> +  const char *req[PPC_MAXBIFPREDICATES];
> +  int num_req = 0;
> +  bool has_m64 = false;
> +
> +  for (int i = 0; i < num_enables; i++)
> +    {
> +      bif_enable enb = rs6000_builtin_info[j].enables[i];
> +      if (enb == ENB_M64)
> +     has_m64 = true;
> +      else
> +     req[num_req++] = get_enable_string (enb);
> +    }
> +
> +  /* ENB_M64 has two equivalent spellings; append its wording last so
> +     that all plain option names come first in the message.  */
> +  if (has_m64)
> +    {
> +      if (num_req == 0)
> +     error ("%qs requires either the %qs or %qs option",
> +            name, "-m64", "-mpowerpc64");
> +      else if (num_req == 1)
> +     error ("%qs requires the %qs option and either the %qs or %qs option",
> +            name, req[0], "-m64", "-mpowerpc64");
> +      else if (num_req == 2)
> +     error ("%qs requires the %qs and %qs options"
> +            " and either the %qs or %qs option",
> +            name, req[0], req[1], "-m64", "-mpowerpc64");
> +      else if (num_req == 3)
> +     error ("%qs requires the %qs, %qs, and %qs options"
> +            " and either the %qs or %qs option",
> +            name, req[0], req[1], req[2], "-m64", "-mpowerpc64");
> +      return;
> +    }
> +
> +  /* Report all required options.  */
> +  if (num_req == 1)
> +    error ("%qs requires the %qs option", name, req[0]);
> +  else if (num_req == 2)
> +    error ("%qs requires the %qs and %qs options",
> +        name, req[0], req[1]);
> +  else if (num_req == 3)
> +    error ("%qs requires the %qs, %qs, and %qs options",
> +        name, req[0], req[1], req[2]);
> +  else if (num_req == 4)
> +    error ("%qs requires the %qs, %qs, %qs, and %qs options",
> +        name, req[0], req[1], req[2], req[3]);
> +}

Can we add an 'else gcc_unreachable ();' here to catch unexpected 'num_req'
values?

> +
> +/* Check whether a builtin function is supported in this target
> +   configuration.  For functions with multiple gating predicates,
> +   ALL predicates must be satisfied (AND logic).  */
> +
> +bool
> +rs6000_builtin_is_supported (enum rs6000_gen_builtins fncode)
> +{
> +  size_t j = (size_t) fncode;
> +  int num_enables = rs6000_builtin_info[j].num_enables;
> +
> +  for (int i = 0; i < num_enables; i++)
> +    {
> +      if (!check_single_enable (rs6000_builtin_info[j].enables[i]))
> +     return false;
> +    }
> +
> +  return true;
> +}
> +
>  /* Target hook for early folding of built-ins, shamelessly stolen
>     from ia64.cc.  */
>  
> diff --git a/gcc/config/rs6000/rs6000-builtins.def 
> b/gcc/config/rs6000/rs6000-builtins.def
> index 4b7d21cdb81..bbd8a2d4b79 100644
> --- a/gcc/config/rs6000/rs6000-builtins.def
> +++ b/gcc/config/rs6000/rs6000-builtins.def
> @@ -31,7 +31,15 @@
>  ;
>  ;     [power9]
>  ;
> -; The bracketed gating predicate is the only information allowed on
> +; Multiple gating predicates can be specified using comma-separated values.
> +; When multiple predicates are specified, ALL predicates must be satisfied
> +; (AND logic) for the built-in to be enabled.  For example:
> +;
> +;     [power10,vsx]
> +;
> +; This means the built-in requires both -mcpu=power10 AND -mvsx options.
> +;
> +; The bracketed gating predicate(s) are the only information allowed on
>  ; the stanza header line, other than whitespace.
>  ;
>  ; Following the stanza header are two lines for each function: the
> @@ -286,7 +294,7 @@
>  
>  
>  ; Power6 builtins requiring 64-bit GPRs (even with 32-bit addressing).
> -[power6-64]
> +[power6, m64]
>    const signed long __builtin_p6_cmpb (signed long, signed long);
>      CMPB cmpbdi3 {no32bit}
>  
> @@ -1861,7 +1869,7 @@
>  
>  
>  ; Power7 builtins requiring 64-bit GPRs (even with 32-bit addressing).
> -[power7-64]
> +[power7, m64]
>    const signed long long __builtin_divde (signed long long, signed long 
> long);
>      DIVDE dive_di {}
>  
> @@ -1871,7 +1879,7 @@
>  
>  
>  ; Power8 vector built-ins.
> -[power8-vector]
> +[power8, vsx]
>    const vsll __builtin_altivec_abs_v2di (vsll);
>      ABS_V2DI absv2di2 {}
>  
> @@ -2312,7 +2320,7 @@
>  
>  
>  ; Power9 vector builtins.
> -[power9-vector]
> +[power9, vsx]
>    const vss __builtin_altivec_convert_4f32_8f16 (vf, vf);
>      CONVERT_4F32_8F16 convert_4f32_8f16 {}
>  
> @@ -2659,7 +2667,7 @@
>    const signed int  __builtin_vsx_scalar_extract_exp (double);
>      VSEEDP xsxexpdp_si {}
>  
> -[power9-64]
> +[power9, m64]
>    void __builtin_altivec_xst_len_r (vsc, void *, long);
>      XST_LEN_R xst_len_r {}
>  
> @@ -3335,12 +3343,6 @@
>    const vuq __builtin_vsx_vmsumcud (vull, vull, vuq);
>      VMSUMCUD vmsumcud {}
>  
> -  const signed int __builtin_vsx_xvtlsbb_all_ones (vsc);
> -    XVTLSBB_ONES xvtlsbbo {}
> -
> -  const signed int __builtin_vsx_xvtlsbb_all_zeros (vsc);
> -    XVTLSBB_ZEROS xvtlsbbz {}
> -
>    const vf __builtin_vsx_vxxsplti32dx_v4sf (vf, const int<1>, float);
>      VXXSPLTI32DX_V4SF xxsplti32dx_v4sf {}
>  
> @@ -3442,7 +3444,16 @@
>      ZE_LXVRDX vsx_lxvrdx {lxvrze}
>  
>  
> -[power10-64]
> +; Power10 builtins that requires -mvsx.

Typo: change requires to require.

> +[power10, vsx]
> +  const signed int __builtin_vsx_xvtlsbb_all_ones (vsc);
> +    XVTLSBB_ONES xvtlsbbo {}
> +
> +  const signed int __builtin_vsx_xvtlsbb_all_zeros (vsc);
> +    XVTLSBB_ZEROS xvtlsbbz {}
> +
> +
> +[power10, m64]
>    const unsigned long long __builtin_cfuged (unsigned long long, \
>                                               unsigned long long);
>      CFUGED cfuged {}
> @@ -3463,8 +3474,8 @@
>                                              unsigned long long);
>      PEXTD pextd {}
>  
> -
> -[mma]
> +; Power10 built-ins that requires -mmma

Typo: change requires to require.

> +[power10, mma]
>    void __builtin_mma_assemble_acc (v512 *, vuc, vuc, vuc, vuc);
>      ASSEMBLE_ACC nothing {mma,mmaint}
>  
> @@ -3942,7 +3953,7 @@
>    void __builtin_vsx_stxvp (v256, unsigned long, const v256 *);
>      STXVP nothing {mma,pair}
>  
> -[future-vsx]
> +[future, vsx]
>    const vus __builtin_vsx_xvmulhuh (vus, vus);
>      XVMULHUH umulv8hi3_highpart {}
>  
> @@ -4071,7 +4082,7 @@
>    const vuc __builtin_galois_field_mult_xts (vuc, vuc);
>      XXGFMUL128XTS xxgfmul128xts {}
>  
> -[future-altivec]
> +[future, altivec]
>    const vus __builtin_altivec_uncompresshn (vuc, vui);
>      VUCMPRHN altivec_vucmprhn {}
>  
> @@ -4096,7 +4107,8 @@
>    const vf __builtin_altivec_unpack_int8_to_fp32 (vui, const int<2>);
>      VUPKINT8TOFP32 altivec_vupkint8tofp32 {}
>  
> -[dm]
> +; future built-ins that requires -mdense-math

Typo: change requires to require.

Thanks,
Jeevitha.

> +[future, dm]
>    void __builtin_dmsetdmrz (dmr1024 *);
>      DMSETDMRZ nothing {dm,dmint}
>  
> diff --git a/gcc/config/rs6000/rs6000-gen-builtins.cc 
> b/gcc/config/rs6000/rs6000-gen-builtins.cc
> index 08068ba78fd..c97c246df32 100644
> --- a/gcc/config/rs6000/rs6000-gen-builtins.cc
> +++ b/gcc/config/rs6000/rs6000-gen-builtins.cc
> @@ -39,7 +39,15 @@ along with GCC; see the file COPYING3.  If not see
>  
>       [power9]
>  
> -   The bracketed gating predicate is the only information allowed on
> +   Multiple gating predicates can be specified using comma-separated
> +   values.  When multiple predicates are specified, ALL predicates must
> +   be satisfied (AND logic) for the built-in to be enabled.  For example:
> +
> +     [power10,vsx]
> +
> +   This means the built-in requires both -mcpu=power10 AND -mvsx options.
> +
> +   The bracketed gating predicate(s) are the only information allowed on
>     the stanza header line, other than whitespace.
>  
>     Following the stanza header are two lines for each function: the
> @@ -215,34 +223,33 @@ enum void_status
>  enum bif_stanza
>  {
>   BSTZ_ALWAYS,
> + BSTZ_M64,
>   BSTZ_P5,
>   BSTZ_P6,
> - BSTZ_P6_64,
>   BSTZ_ALTIVEC,
>   BSTZ_CELL,
>   BSTZ_VSX,
>   BSTZ_P7,
> - BSTZ_P7_64,
>   BSTZ_P8,
> - BSTZ_P8V,
>   BSTZ_P9,
> - BSTZ_P9_64,
> - BSTZ_P9V,
>   BSTZ_IEEE128_HW,
>   BSTZ_DFP,
>   BSTZ_CRYPTO,
>   BSTZ_HTM,
>   BSTZ_P10,
> - BSTZ_P10_64,
>   BSTZ_MMA,
>   BSTZ_FUTURE,
> - BSTZ_FUTURE_ALTIVEC,
> - BSTZ_FUTURE_VSX,
>   BSTZ_DM,
>   NUMBIFSTANZAS
>  };
>  
> +/* Maximum number of predicates that can be specified for a single
> +   stanza.  */
> +#define MAXBIFPREDICATES 4
> +
>  static bif_stanza curr_bif_stanza;
> +static int curr_bif_num_predicates = 0;
> +static bif_stanza curr_bif_predicates[MAXBIFPREDICATES];
>  
>  struct stanza_entry
>  {
> @@ -253,58 +260,44 @@ struct stanza_entry
>  static stanza_entry stanza_map[NUMBIFSTANZAS] =
>    {
>      { "always",              BSTZ_ALWAYS     },
> +    { "m64",         BSTZ_M64        },
>      { "power5",              BSTZ_P5         },
>      { "power6",              BSTZ_P6         },
> -    { "power6-64",   BSTZ_P6_64      },
>      { "altivec",     BSTZ_ALTIVEC    },
>      { "cell",                BSTZ_CELL       },
>      { "vsx",         BSTZ_VSX        },
>      { "power7",              BSTZ_P7         },
> -    { "power7-64",   BSTZ_P7_64      },
>      { "power8",              BSTZ_P8         },
> -    { "power8-vector",       BSTZ_P8V        },
>      { "power9",              BSTZ_P9         },
> -    { "power9-64",   BSTZ_P9_64      },
> -    { "power9-vector",       BSTZ_P9V        },
>      { "ieee128-hw",  BSTZ_IEEE128_HW },
>      { "dfp",         BSTZ_DFP        },
>      { "crypto",              BSTZ_CRYPTO     },
>      { "htm",         BSTZ_HTM        },
>      { "power10",     BSTZ_P10        },
> -    { "power10-64",  BSTZ_P10_64     },
>      { "mma",         BSTZ_MMA        },
>      { "future",      BSTZ_FUTURE     },
> -    { "future-altivec", BSTZ_FUTURE_ALTIVEC },
> -    { "future-vsx",  BSTZ_FUTURE_VSX },
>      { "dm",          BSTZ_DM         }
>    };
>  
>  static const char *enable_string[NUMBIFSTANZAS] =
>    {
>      "ENB_ALWAYS",
> +    "ENB_M64",
>      "ENB_P5",
>      "ENB_P6",
> -    "ENB_P6_64",
>      "ENB_ALTIVEC",
>      "ENB_CELL",
>      "ENB_VSX",
>      "ENB_P7",
> -    "ENB_P7_64",
>      "ENB_P8",
> -    "ENB_P8V",
>      "ENB_P9",
> -    "ENB_P9_64",
> -    "ENB_P9V",
>      "ENB_IEEE128_HW",
>      "ENB_DFP",
>      "ENB_CRYPTO",
>      "ENB_HTM",
>      "ENB_P10",
> -    "ENB_P10_64",
>      "ENB_MMA",
>      "ENB_FUTURE",
> -    "ENB_FUTURE_ALTIVEC",
> -    "ENB_FUTURE_VSX",
>      "ENB_DM"
>    };
>  
> @@ -432,6 +425,8 @@ struct prototype
>  struct bifdata
>  {
>    int stanza;
> +  int num_predicates;
> +  int predicates[MAXBIFPREDICATES];
>    fnkinds kind;
>    prototype proto;
>    char *idname;
> @@ -837,6 +832,56 @@ stanza_name_to_stanza (const char *stanza_name)
>    return BSTZ_ALWAYS;
>  }
>  
> +/* Parse comma-separated gating predicates from a stanza header and populate
> +   the predicates array.  Each predicate is specified by a stanza name (e.g.,
> +   "power10", "vsx") that represents a gating condition that must be 
> satisfied
> +   for the built-in to be enabled.  Multiple predicates are combined with AND
> +   logic.  Returns the number of predicates parsed.  */
> +
> +static int
> +parse_bif_stanza_predicates (char *predicates_str, bif_stanza *predicates)
> +{
> +  int num_predicates = 0;
> +  char *predicate_name = predicates_str;
> +  char *comma_pos;
> +
> +  while (predicate_name && num_predicates < MAXBIFPREDICATES)
> +    {
> +      /* Find the next comma or end of string.  */
> +      comma_pos = strchr (predicate_name, ',');
> +      if (comma_pos)
> +     *comma_pos = '\0';
> +
> +      /* Trim leading and trailing whitespace from predicate name.  */
> +      while (*predicate_name == ' ' || *predicate_name == '\t')
> +     predicate_name++;
> +
> +      char *end = predicate_name + strlen (predicate_name) - 1;
> +      while (end > predicate_name && (*end == ' ' || *end == '\t'))
> +     {
> +       *end = '\0';
> +       end--;
> +     }
> +
> +      if (*predicate_name != '\0')
> +     {
> +       /* Convert predicate name (stanza name) to stanza enum.  */
> +       predicates[num_predicates] = stanza_name_to_stanza (predicate_name);
> +       num_predicates++;
> +     }
> +
> +      if (comma_pos)
> +     predicate_name = comma_pos + 1;
> +      else
> +     break;
> +    }
> +
> +  if (num_predicates >= MAXBIFPREDICATES && strchr (predicate_name, ','))
> +    fatal ("Too many predicates in stanza header.\n");
> +
> +  return num_predicates;
> +}
> +
>  /* Match one of the allowable base types.  Consumes one token unless the
>     token is "long", which must be paired with a second "long".  Optionally
>     consumes a following '*' token for pointers.  Return 1 for success,
> @@ -1831,6 +1876,9 @@ parse_bif_entry (void)
>  
>    curr_bif = num_bifs++;
>    bifs[curr_bif].stanza = curr_bif_stanza;
> +  bifs[curr_bif].num_predicates = curr_bif_num_predicates;
> +  for (int i = 0; i < curr_bif_num_predicates; i++)
> +    bifs[curr_bif].predicates[i] = curr_bif_predicates[i];
>  
>    /* Read the first token and see if it is a function modifier.  */
>    consume_whitespace ();
> @@ -1936,14 +1984,25 @@ parse_bif_stanza (void)
>      }
>    safe_inc_pos ();
>  
> -  const char *stanza_name = match_to_right_bracket ();
> -  if (!stanza_name)
> +  const char *stanza_name_const = match_to_right_bracket ();
> +  if (!stanza_name_const)
>      {
>        diag (pos, "no expression found in stanza header.\n");
>        return PC_PARSEFAIL;
>      }
>  
> -  curr_bif_stanza = stanza_name_to_stanza (stanza_name);
> +  /* Make a mutable copy since parse_bif_stanza_predicates modifies the
> +     string.  */
> +  char *stanza_name = strdup (stanza_name_const);
> +
> +  curr_bif_num_predicates = parse_bif_stanza_predicates (stanza_name,
> +                                                      curr_bif_predicates);
> +
> +  free (stanza_name);
> +
> +  /* Store the primary (first) stanza in curr_bif_stanza for
> +     backward compatibility.  */
> +  curr_bif_stanza = curr_bif_predicates[0];
>  
>    if (linebuf[pos] != ']')
>      {
> @@ -2270,37 +2329,32 @@ write_decls (void)
>  
>    fprintf (header_file, "enum bif_enable {\n");
>    fprintf (header_file, "  ENB_ALWAYS,\n");
> +  fprintf (header_file, "  ENB_M64,\n");
>    fprintf (header_file, "  ENB_P5,\n");
>    fprintf (header_file, "  ENB_P6,\n");
> -  fprintf (header_file, "  ENB_P6_64,\n");
>    fprintf (header_file, "  ENB_ALTIVEC,\n");
>    fprintf (header_file, "  ENB_CELL,\n");
>    fprintf (header_file, "  ENB_VSX,\n");
>    fprintf (header_file, "  ENB_P7,\n");
> -  fprintf (header_file, "  ENB_P7_64,\n");
>    fprintf (header_file, "  ENB_P8,\n");
> -  fprintf (header_file, "  ENB_P8V,\n");
>    fprintf (header_file, "  ENB_P9,\n");
> -  fprintf (header_file, "  ENB_P9_64,\n");
> -  fprintf (header_file, "  ENB_P9V,\n");
>    fprintf (header_file, "  ENB_IEEE128_HW,\n");
>    fprintf (header_file, "  ENB_DFP,\n");
>    fprintf (header_file, "  ENB_CRYPTO,\n");
>    fprintf (header_file, "  ENB_HTM,\n");
>    fprintf (header_file, "  ENB_P10,\n");
> -  fprintf (header_file, "  ENB_P10_64,\n");
>    fprintf (header_file, "  ENB_MMA,\n");
>    fprintf (header_file, "  ENB_FUTURE,\n");
> -  fprintf (header_file, "  ENB_FUTURE_ALTIVEC,\n");
> -  fprintf (header_file, "  ENB_FUTURE_VSX,\n");
>    fprintf (header_file, "  ENB_DM\n");
>    fprintf (header_file, "};\n\n");
>  
>    fprintf (header_file, "#define PPC_MAXRESTROPNDS 3\n");
> +  fprintf (header_file, "#define PPC_MAXBIFPREDICATES 4\n");
>    fprintf (header_file, "struct bifdata\n");
>    fprintf (header_file, "{\n");
>    fprintf (header_file, "  const char *bifname;\n");
> -  fprintf (header_file, "  bif_enable enable;\n");
> +  fprintf (header_file, "  int num_enables;\n");
> +  fprintf (header_file, "  bif_enable enables[PPC_MAXBIFPREDICATES];\n");
>    fprintf (header_file, "  insn_code icode;\n");
>    fprintf (header_file, "  int nargs;\n");
>    fprintf (header_file, "  int bifattrs;\n");
> @@ -2527,7 +2581,7 @@ write_bif_static_init (void)
>    fprintf (init_file, "bifdata rs6000_builtin_info[RS6000_BIF_MAX] =\n");
>    fprintf (init_file, "  {\n");
>    fprintf (init_file, "    { /* RS6000_BIF_NONE: */\n");
> -  fprintf (init_file, "      \"\", ENB_ALWAYS, CODE_FOR_nothing, 0,\n");
> +  fprintf (init_file, "      \"\", 0, {ENB_ALWAYS}, CODE_FOR_nothing, 0,\n");
>    fprintf (init_file, "      0, {0, 0, 0}, {RES_NONE, RES_NONE, 
> RES_NONE},\n");
>    fprintf (init_file, "      {0, 0, 0}, {0, 0, 0}, \"\", RS6000_BIF_NONE\n");
>    fprintf (init_file, "    },\n");
> @@ -2537,8 +2591,17 @@ write_bif_static_init (void)
>        fprintf (init_file, "    { /* RS6000_BIF_%s: */\n", bifp->idname);
>        fprintf (init_file, "      /* bifname */\t\"%s\",\n",
>              bifp->proto.bifname);
> -      fprintf (init_file, "      /* enable*/\t%s,\n",
> -            enable_string[bifp->stanza]);
> +      /* Output num_enables and enables array.  */
> +      fprintf (init_file, "      /* num_enables */\t%d,\n",
> +            bifp->num_predicates);
> +      fprintf (init_file, "      /* enables */\t{");
> +      for (int j = 0; j < bifp->num_predicates; j++)
> +     {
> +       if (j > 0)
> +         fprintf (init_file, ", ");
> +       fprintf (init_file, "%s", enable_string[bifp->predicates[j]]);
> +     }
> +      fprintf (init_file, "},\n");
>        fprintf (init_file, "      /* icode */\tCODE_FOR_%s,\n",
>              bifp->patname);
>        fprintf (init_file, "      /* nargs */\t%d,\n",
> diff --git a/gcc/testsuite/gcc.target/powerpc/pr96125.c 
> b/gcc/testsuite/gcc.target/powerpc/pr96125.c
> index a4bb0d55786..29711cac796 100644
> --- a/gcc/testsuite/gcc.target/powerpc/pr96125.c
> +++ b/gcc/testsuite/gcc.target/powerpc/pr96125.c
> @@ -15,7 +15,7 @@ void
>  test1 (__vector_quad *dst)
>  {
>    __vector_quad acc;
> -  __builtin_mma_xxsetaccz (&acc); /* { dg-error "'__builtin_mma_xxsetaccz' 
> requires the '-mmma' option" } */
> +  __builtin_mma_xxsetaccz (&acc); /* { dg-error "'__builtin_mma_xxsetaccz' 
> requires the '-mcpu=power10' and '-mmma' options" } */
>    *dst = acc;
>  }
>  
> @@ -41,7 +41,7 @@ void
>  test4 (__vector_quad *dst)
>  {
>    __vector_quad acc;
> -  __builtin_mma_xxmfacc (&acc); /* { dg-error "'__builtin_mma_xxmfacc' 
> requires the '-mmma' option" } */
> +  __builtin_mma_xxmfacc (&acc); /* { dg-error "'__builtin_mma_xxmfacc' 
> requires the '-mcpu=power10' and '-mmma' options" } */
>    *dst = acc;
>  }
>  

Reply via email to