diff mbox series

[v4] RISC-V: Supports Profiles in '-march' option.

Message ID 20240820045354.1911861-1-jiawei@iscas.ac.cn
State New
Headers show
Series [v4] RISC-V: Supports Profiles in '-march' option. | expand

Commit Message

Jiawei Aug. 20, 2024, 4:53 a.m. UTC
Supports RISC-V profiles[1] in -march option.

Default input set the profile before other formal extensions.

V2: Fixes some format errors and adds code comments for parse function
Thanks for Jeff Law's review and comments.

V3: Update testcases and profiles extensions support.Remove S/M mode Profiles. 
Thanks for Christoph Müllner,Palmer Dabbelt's  review and comments.

V4: Fix format issue, adjust test name.

[1]https://github.com/riscv/riscv-profiles/blob/main/profiles.adoc

gcc/ChangeLog:

	* common/config/riscv/riscv-common.cc (struct riscv_profiles):
	* New struct.
	(riscv_subset_list::parse_profiles): New function.
	(riscv_subset_list::parse_base_ext): New process.
	* config/riscv/riscv-subset.h: New protype.

gcc/testsuite/ChangeLog:

	* gcc.target/riscv/arch-44.c: New test.
	* gcc.target/riscv/arch-45.c: New test.
	* gcc.target/riscv/arch-46.c: New test.

---
 gcc/common/config/riscv/riscv-common.cc  | 75 +++++++++++++++++++++++-
 gcc/config/riscv/riscv-subset.h          |  2 +
 gcc/testsuite/gcc.target/riscv/arch-44.c |  5 ++
 gcc/testsuite/gcc.target/riscv/arch-45.c | 12 ++++
 gcc/testsuite/gcc.target/riscv/arch-46.c | 12 ++++
 5 files changed, 105 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/arch-44.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/arch-45.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/arch-46.c

Comments

Palmer Dabbelt Aug. 20, 2024, 7:23 p.m. UTC | #1
On Mon, 19 Aug 2024 21:53:54 PDT (-0700), jiawei@iscas.ac.cn wrote:
> Supports RISC-V profiles[1] in -march option.
>
> Default input set the profile before other formal extensions.
>
> V2: Fixes some format errors and adds code comments for parse function
> Thanks for Jeff Law's review and comments.
>
> V3: Update testcases and profiles extensions support.Remove S/M mode Profiles.
> Thanks for Christoph Müllner,Palmer Dabbelt's  review and comments.
>
> V4: Fix format issue, adjust test name.
>
> [1]https://github.com/riscv/riscv-profiles/blob/main/profiles.adoc
>
> gcc/ChangeLog:
>
> 	* common/config/riscv/riscv-common.cc (struct riscv_profiles):
> 	* New struct.
> 	(riscv_subset_list::parse_profiles): New function.
> 	(riscv_subset_list::parse_base_ext): New process.
> 	* config/riscv/riscv-subset.h: New protype.
>
> gcc/testsuite/ChangeLog:
>
> 	* gcc.target/riscv/arch-44.c: New test.
> 	* gcc.target/riscv/arch-45.c: New test.
> 	* gcc.target/riscv/arch-46.c: New test.
>
> ---
>  gcc/common/config/riscv/riscv-common.cc  | 75 +++++++++++++++++++++++-
>  gcc/config/riscv/riscv-subset.h          |  2 +
>  gcc/testsuite/gcc.target/riscv/arch-44.c |  5 ++
>  gcc/testsuite/gcc.target/riscv/arch-45.c | 12 ++++
>  gcc/testsuite/gcc.target/riscv/arch-46.c | 12 ++++
>  5 files changed, 105 insertions(+), 1 deletion(-)
>  create mode 100644 gcc/testsuite/gcc.target/riscv/arch-44.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/arch-45.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/arch-46.c
>
> diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc
> index 62c6e1dab1f..0bad4426971 100644
> --- a/gcc/common/config/riscv/riscv-common.cc
> +++ b/gcc/common/config/riscv/riscv-common.cc
> @@ -234,6 +234,12 @@ struct riscv_ext_version
>    int minor_version;
>  };
>
> +struct riscv_profiles
> +{
> +  const char *profile_name;
> +  const char *profile_string;
> +};
> +
>  /* All standard extensions defined in all supported ISA spec.  */
>  static const struct riscv_ext_version riscv_ext_version_table[] =
>  {
> @@ -449,6 +455,31 @@ static const struct riscv_ext_version riscv_combine_info[] =
>    {NULL, ISA_SPEC_CLASS_NONE, 0, 0}
>  };
>
> +/* This table records the mapping form RISC-V Profiles into march string.  */
> +static const riscv_profiles riscv_profiles_table[] =
> +{
> +  /* RVI20U only contains the base extension 'i' as mandatory extension.  */
> +  {"RVI20U64", "rv64i"},
> +  {"RVI20U32", "rv32i"},
> +
> +  /* RVA20U contains the 'i,m,a,f,d,c,zicsr,zicntr,ziccif,ziccrse,ziccamoa,
> +     zicclsm,za128rs' as mandatory extensions.  */
> +  {"RVA20U64", "rv64imafdc_zicsr_zicntr_ziccif_ziccrse_ziccamoa"
> +   "_zicclsm_za128rs"},
> +
> +  /* RVA22U contains the 'i,m,a,f,d,c,zicsr,zihintpause,zba,zbb,zbs,zicntr,
> +     zihpm,ziccif,ziccrse,ziccamoa, zicclsm,zic64b,za64rs,zicbom,zicbop,zicboz,

Except at least the Spacemit stuff that claims RVA22 doesn't actually 
have Zicclsm, at least assuming the "supports" in there means "doesn't 
trap" (we could just say "supports" includes traps, and thus Zicclsm 
means nothing).

I'd argue we should just punt on the profiles until we figure out what 
they're actually going to be.  The pre-23 profiles were all minor 
releases anyway, so it's not like we should be losing much there 
(as they're not meant for software).  At least if we wait we don't end 
up committing to this whole "profiles don't mean anything" spot we're 
in, like we did for the other spec flavors.

Though now that I'm writing that it actually just sounds kind of silly 
to keep hoping that we're going to get any meaningful compatibility 
rules enforced by the RISC-V foundation.  There's really just no 
incentive for that to happen, as we keep bailing out vendors who ship 
broken systems and thus there's no pushback from their members.

So maybe the right answer here is to just break users and tell them to 
go complain to someone else?  At least that way everyone will be upset, 
maybe that'll be enough to get things to change?

> +     zfhmin,zkt' as mandatory extensions.  */
> +  {"RVA22U64", "rv64imafdc_zicsr_zicntr_ziccif_ziccrse_ziccamoa"
> +   "_zicclsm_zic64b_za64rs_zihintpause_zba_zbb_zbs_zicbom_zicbop"
> +   "_zicboz_zfhmin_zkt"},
> +
> +  /* Currently we do not define S/M mode Profiles in gcc part.  */
> +
> +  /* Terminate the list.  */
> +  {NULL, NULL}
> +};
> +
>  static const riscv_cpu_info riscv_cpu_tables[] =
>  {
>  #define RISCV_CORE(CORE_NAME, ARCH, TUNE) \
> @@ -1056,6 +1087,46 @@ riscv_subset_list::parsing_subset_version (const char *ext,
>    return p;
>  }
>
> +/* Parsing RISC-V Profiles in -march string.
> +   Return string with mandatory extensions of Profiles.  */
> +const char *
> +riscv_subset_list::parse_profiles (const char *p)
> +{
> +  /* Checking if input string contains a Profiles.
> +     There are two cases use Profiles in -march option:
> +
> +     1. Only use Profiles as -march input
> +     2. Mixed Profiles with other extensions
> +
> +     Use '+' to split Profiles and other extension.  */
> +  for (int i = 0; riscv_profiles_table[i].profile_name != NULL; ++i)
> +    {
> +      const char *match = strstr (p, riscv_profiles_table[i].profile_name);
> +      const char *plus_ext = strchr (p, '+');
> +      /* Find profile at the begin.  */
> +      if (match != NULL && match == p)
> +	{
> +	  /* If there's no '+' sign, return the profile_string directly.  */
> +	  if (!plus_ext)
> +	    return riscv_profiles_table[i].profile_string;
> +	  /* If there's a '+' sign, need to add profiles with other ext.  */
> +	  else
> +	  {
> +	    size_t arch_len = strlen (riscv_profiles_table[i].profile_string)
> +		  + strlen (plus_ext);
> +	    /* Reset the input string with Profiles mandatory extensions,
> +	       end with '_' to connect other additional extensions.  */
> +	    char *result = new char[arch_len + 2];
> +	    strcpy (result, riscv_profiles_table[i].profile_string);
> +	    strcat (result, "_");
> +	    strcat (result, plus_ext + 1); /* skip the '+'.  */
> +	    return result;
> +	  }
> +	}
> +    }
> +  return p;
> +}
> +
>  /* Parsing function for base extensions, rv[32|64][i|e|g]
>
>     Return Value:
> @@ -1070,6 +1141,8 @@ riscv_subset_list::parse_base_ext (const char *p)
>    unsigned minor_version = 0;
>    bool explicit_version_p = false;
>
> +  p = parse_profiles(p);
> +
>    if (startswith (p, "rv32"))
>      {
>        m_xlen = 32;
> @@ -1082,7 +1155,7 @@ riscv_subset_list::parse_base_ext (const char *p)
>      }
>    else
>      {
> -      error_at (m_loc, "%<-march=%s%>: ISA string must begin with rv32 or rv64",
> +      error_at (m_loc, "%<-march=%s%>: ISA string must begin with rv32, rv64 or Profile",
>  		m_arch);
>        return NULL;
>      }
> diff --git a/gcc/config/riscv/riscv-subset.h b/gcc/config/riscv/riscv-subset.h
> index dace4de6575..98fd9877f74 100644
> --- a/gcc/config/riscv/riscv-subset.h
> +++ b/gcc/config/riscv/riscv-subset.h
> @@ -80,6 +80,8 @@ private:
>    const char *parse_single_multiletter_ext (const char *, const char *,
>  					    const char *, bool);
>
> +  const char *parse_profiles (const char*);
> +
>    void handle_implied_ext (const char *);
>    bool check_implied_ext ();
>    void handle_combine_ext ();
> diff --git a/gcc/testsuite/gcc.target/riscv/arch-44.c b/gcc/testsuite/gcc.target/riscv/arch-44.c
> new file mode 100644
> index 00000000000..41190bc5939
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/arch-44.c
> @@ -0,0 +1,5 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=RVI20U64 -mabi=lp64" } */
> +int
> +foo ()
> +{}
> diff --git a/gcc/testsuite/gcc.target/riscv/arch-45.c b/gcc/testsuite/gcc.target/riscv/arch-45.c
> new file mode 100644
> index 00000000000..273c6abf60d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/arch-45.c
> @@ -0,0 +1,12 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=RVI20U64+mafdc -mabi=lp64d" } */
> +#if !(defined __riscv_mul) || \
> +    !(defined __riscv_atomic) || \
> +    !(defined __riscv_flen) || \
> +    !(defined __riscv_div) || \
> +    !(defined __riscv_compressed)
> +#error "Feature macros not defined"
> +#endif
> +int
> +foo ()
> +{}
> diff --git a/gcc/testsuite/gcc.target/riscv/arch-46.c b/gcc/testsuite/gcc.target/riscv/arch-46.c
> new file mode 100644
> index 00000000000..1ebf50d3755
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/arch-46.c
> @@ -0,0 +1,12 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=RVA20U64 -mabi=lp64d" } */
> +#if !(defined __riscv_mul) || \
> +    !(defined __riscv_atomic) || \
> +    !(defined __riscv_flen) || \
> +    !(defined __riscv_div) || \
> +    !(defined __riscv_compressed)
> +#error "Feature macros not defined"
> +#endif
> +int
> +foo ()
> +{}
Jiawei Aug. 21, 2024, 6:18 a.m. UTC | #2
在 2024/8/21 3:23, Palmer Dabbelt 写道:
> On Mon, 19 Aug 2024 21:53:54 PDT (-0700), jiawei@iscas.ac.cn wrote:
>> Supports RISC-V profiles[1] in -march option.
>>
>> Default input set the profile before other formal extensions.
>>
>> V2: Fixes some format errors and adds code comments for parse function
>> Thanks for Jeff Law's review and comments.
>>
>> V3: Update testcases and profiles extensions support.Remove S/M mode 
>> Profiles.
>> Thanks for Christoph Müllner,Palmer Dabbelt's  review and comments.
>>
>> V4: Fix format issue, adjust test name.
>>
>> [1]https://github.com/riscv/riscv-profiles/blob/main/profiles.adoc
>>
>> gcc/ChangeLog:
>>
>>     * common/config/riscv/riscv-common.cc (struct riscv_profiles):
>>     * New struct.
>>     (riscv_subset_list::parse_profiles): New function.
>>     (riscv_subset_list::parse_base_ext): New process.
>>     * config/riscv/riscv-subset.h: New protype.
>>
>> gcc/testsuite/ChangeLog:
>>
>>     * gcc.target/riscv/arch-44.c: New test.
>>     * gcc.target/riscv/arch-45.c: New test.
>>     * gcc.target/riscv/arch-46.c: New test.
>>
>> ---
>>  gcc/common/config/riscv/riscv-common.cc  | 75 +++++++++++++++++++++++-
>>  gcc/config/riscv/riscv-subset.h          |  2 +
>>  gcc/testsuite/gcc.target/riscv/arch-44.c |  5 ++
>>  gcc/testsuite/gcc.target/riscv/arch-45.c | 12 ++++
>>  gcc/testsuite/gcc.target/riscv/arch-46.c | 12 ++++
>>  5 files changed, 105 insertions(+), 1 deletion(-)
>>  create mode 100644 gcc/testsuite/gcc.target/riscv/arch-44.c
>>  create mode 100644 gcc/testsuite/gcc.target/riscv/arch-45.c
>>  create mode 100644 gcc/testsuite/gcc.target/riscv/arch-46.c
>>
>> diff --git a/gcc/common/config/riscv/riscv-common.cc 
>> b/gcc/common/config/riscv/riscv-common.cc
>> index 62c6e1dab1f..0bad4426971 100644
>> --- a/gcc/common/config/riscv/riscv-common.cc
>> +++ b/gcc/common/config/riscv/riscv-common.cc
>> @@ -234,6 +234,12 @@ struct riscv_ext_version
>>    int minor_version;
>>  };
>>
>> +struct riscv_profiles
>> +{
>> +  const char *profile_name;
>> +  const char *profile_string;
>> +};
>> +
>>  /* All standard extensions defined in all supported ISA spec. */
>>  static const struct riscv_ext_version riscv_ext_version_table[] =
>>  {
>> @@ -449,6 +455,31 @@ static const struct riscv_ext_version 
>> riscv_combine_info[] =
>>    {NULL, ISA_SPEC_CLASS_NONE, 0, 0}
>>  };
>>
>> +/* This table records the mapping form RISC-V Profiles into march 
>> string.  */
>> +static const riscv_profiles riscv_profiles_table[] =
>> +{
>> +  /* RVI20U only contains the base extension 'i' as mandatory 
>> extension.  */
>> +  {"RVI20U64", "rv64i"},
>> +  {"RVI20U32", "rv32i"},
>> +
>> +  /* RVA20U contains the 
>> 'i,m,a,f,d,c,zicsr,zicntr,ziccif,ziccrse,ziccamoa,
>> +     zicclsm,za128rs' as mandatory extensions.  */
>> +  {"RVA20U64", "rv64imafdc_zicsr_zicntr_ziccif_ziccrse_ziccamoa"
>> +   "_zicclsm_za128rs"},
>> +
>> +  /* RVA22U contains the 
>> 'i,m,a,f,d,c,zicsr,zihintpause,zba,zbb,zbs,zicntr,
>> +     zihpm,ziccif,ziccrse,ziccamoa, 
>> zicclsm,zic64b,za64rs,zicbom,zicbop,zicboz,
>
> Except at least the Spacemit stuff that claims RVA22 doesn't actually 
> have Zicclsm, at least assuming the "supports" in there means "doesn't 
> trap" (we could just say "supports" includes traps, and thus Zicclsm 
> means nothing).
>
> I'd argue we should just punt on the profiles until we figure out what 
> they're actually going to be.  The pre-23 profiles were all minor 
> releases anyway, so it's not like we should be losing much there (as 
> they're not meant for software).  At least if we wait we don't end up 
> committing to this whole "profiles don't mean anything" spot we're in, 
> like we did for the other spec flavors.
>
> Though now that I'm writing that it actually just sounds kind of silly 
> to keep hoping that we're going to get any meaningful compatibility 
> rules enforced by the RISC-V foundation.  There's really just no 
> incentive for that to happen, as we keep bailing out vendors who ship 
> broken systems and thus there's no pushback from their members.
>
> So maybe the right answer here is to just break users and tell them to 
> go complain to someone else?  At least that way everyone will be 
> upset, maybe that'll be enough to get things to change?

Okay, let's continue to wait for the RVA/B23 forzen.

>
>> +     zfhmin,zkt' as mandatory extensions.  */
>> +  {"RVA22U64", "rv64imafdc_zicsr_zicntr_ziccif_ziccrse_ziccamoa"
>> + "_zicclsm_zic64b_za64rs_zihintpause_zba_zbb_zbs_zicbom_zicbop"
>> +   "_zicboz_zfhmin_zkt"},
>> +
>> +  /* Currently we do not define S/M mode Profiles in gcc part. */
>> +
>> +  /* Terminate the list.  */
>> +  {NULL, NULL}
>> +};
>> +
>>  static const riscv_cpu_info riscv_cpu_tables[] =
>>  {
>>  #define RISCV_CORE(CORE_NAME, ARCH, TUNE) \
>> @@ -1056,6 +1087,46 @@ riscv_subset_list::parsing_subset_version 
>> (const char *ext,
>>    return p;
>>  }
>>
>> +/* Parsing RISC-V Profiles in -march string.
>> +   Return string with mandatory extensions of Profiles.  */
>> +const char *
>> +riscv_subset_list::parse_profiles (const char *p)
>> +{
>> +  /* Checking if input string contains a Profiles.
>> +     There are two cases use Profiles in -march option:
>> +
>> +     1. Only use Profiles as -march input
>> +     2. Mixed Profiles with other extensions
>> +
>> +     Use '+' to split Profiles and other extension.  */
>> +  for (int i = 0; riscv_profiles_table[i].profile_name != NULL; ++i)
>> +    {
>> +      const char *match = strstr (p, 
>> riscv_profiles_table[i].profile_name);
>> +      const char *plus_ext = strchr (p, '+');
>> +      /* Find profile at the begin.  */
>> +      if (match != NULL && match == p)
>> +    {
>> +      /* If there's no '+' sign, return the profile_string 
>> directly.  */
>> +      if (!plus_ext)
>> +        return riscv_profiles_table[i].profile_string;
>> +      /* If there's a '+' sign, need to add profiles with other 
>> ext.  */
>> +      else
>> +      {
>> +        size_t arch_len = strlen 
>> (riscv_profiles_table[i].profile_string)
>> +          + strlen (plus_ext);
>> +        /* Reset the input string with Profiles mandatory extensions,
>> +           end with '_' to connect other additional extensions.  */
>> +        char *result = new char[arch_len + 2];
>> +        strcpy (result, riscv_profiles_table[i].profile_string);
>> +        strcat (result, "_");
>> +        strcat (result, plus_ext + 1); /* skip the '+'.  */
>> +        return result;
>> +      }
>> +    }
>> +    }
>> +  return p;
>> +}
>> +
>>  /* Parsing function for base extensions, rv[32|64][i|e|g]
>>
>>     Return Value:
>> @@ -1070,6 +1141,8 @@ riscv_subset_list::parse_base_ext (const char *p)
>>    unsigned minor_version = 0;
>>    bool explicit_version_p = false;
>>
>> +  p = parse_profiles(p);
>> +
>>    if (startswith (p, "rv32"))
>>      {
>>        m_xlen = 32;
>> @@ -1082,7 +1155,7 @@ riscv_subset_list::parse_base_ext (const char *p)
>>      }
>>    else
>>      {
>> -      error_at (m_loc, "%<-march=%s%>: ISA string must begin with 
>> rv32 or rv64",
>> +      error_at (m_loc, "%<-march=%s%>: ISA string must begin with 
>> rv32, rv64 or Profile",
>>          m_arch);
>>        return NULL;
>>      }
>> diff --git a/gcc/config/riscv/riscv-subset.h 
>> b/gcc/config/riscv/riscv-subset.h
>> index dace4de6575..98fd9877f74 100644
>> --- a/gcc/config/riscv/riscv-subset.h
>> +++ b/gcc/config/riscv/riscv-subset.h
>> @@ -80,6 +80,8 @@ private:
>>    const char *parse_single_multiletter_ext (const char *, const char *,
>>                          const char *, bool);
>>
>> +  const char *parse_profiles (const char*);
>> +
>>    void handle_implied_ext (const char *);
>>    bool check_implied_ext ();
>>    void handle_combine_ext ();
>> diff --git a/gcc/testsuite/gcc.target/riscv/arch-44.c 
>> b/gcc/testsuite/gcc.target/riscv/arch-44.c
>> new file mode 100644
>> index 00000000000..41190bc5939
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/riscv/arch-44.c
>> @@ -0,0 +1,5 @@
>> +/* { dg-do compile } */
>> +/* { dg-options "-march=RVI20U64 -mabi=lp64" } */
>> +int
>> +foo ()
>> +{}
>> diff --git a/gcc/testsuite/gcc.target/riscv/arch-45.c 
>> b/gcc/testsuite/gcc.target/riscv/arch-45.c
>> new file mode 100644
>> index 00000000000..273c6abf60d
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/riscv/arch-45.c
>> @@ -0,0 +1,12 @@
>> +/* { dg-do compile } */
>> +/* { dg-options "-march=RVI20U64+mafdc -mabi=lp64d" } */
>> +#if !(defined __riscv_mul) || \
>> +    !(defined __riscv_atomic) || \
>> +    !(defined __riscv_flen) || \
>> +    !(defined __riscv_div) || \
>> +    !(defined __riscv_compressed)
>> +#error "Feature macros not defined"
>> +#endif
>> +int
>> +foo ()
>> +{}
>> diff --git a/gcc/testsuite/gcc.target/riscv/arch-46.c 
>> b/gcc/testsuite/gcc.target/riscv/arch-46.c
>> new file mode 100644
>> index 00000000000..1ebf50d3755
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/riscv/arch-46.c
>> @@ -0,0 +1,12 @@
>> +/* { dg-do compile } */
>> +/* { dg-options "-march=RVA20U64 -mabi=lp64d" } */
>> +#if !(defined __riscv_mul) || \
>> +    !(defined __riscv_atomic) || \
>> +    !(defined __riscv_flen) || \
>> +    !(defined __riscv_div) || \
>> +    !(defined __riscv_compressed)
>> +#error "Feature macros not defined"
>> +#endif
>> +int
>> +foo ()
>> +{}
Palmer Dabbelt Sept. 3, 2024, 10:49 p.m. UTC | #3
On Tue, 20 Aug 2024 23:18:36 PDT (-0700), jiawei@iscas.ac.cn wrote:
>
> 在 2024/8/21 3:23, Palmer Dabbelt 写道:
>> On Mon, 19 Aug 2024 21:53:54 PDT (-0700), jiawei@iscas.ac.cn wrote:
>>> Supports RISC-V profiles[1] in -march option.
>>>
>>> Default input set the profile before other formal extensions.
>>>
>>> V2: Fixes some format errors and adds code comments for parse function
>>> Thanks for Jeff Law's review and comments.
>>>
>>> V3: Update testcases and profiles extensions support.Remove S/M mode
>>> Profiles.
>>> Thanks for Christoph Müllner,Palmer Dabbelt's  review and comments.
>>>
>>> V4: Fix format issue, adjust test name.
>>>
>>> [1]https://github.com/riscv/riscv-profiles/blob/main/profiles.adoc
>>>
>>> gcc/ChangeLog:
>>>
>>>     * common/config/riscv/riscv-common.cc (struct riscv_profiles):
>>>     * New struct.
>>>     (riscv_subset_list::parse_profiles): New function.
>>>     (riscv_subset_list::parse_base_ext): New process.
>>>     * config/riscv/riscv-subset.h: New protype.
>>>
>>> gcc/testsuite/ChangeLog:
>>>
>>>     * gcc.target/riscv/arch-44.c: New test.
>>>     * gcc.target/riscv/arch-45.c: New test.
>>>     * gcc.target/riscv/arch-46.c: New test.
>>>
>>> ---
>>>  gcc/common/config/riscv/riscv-common.cc  | 75 +++++++++++++++++++++++-
>>>  gcc/config/riscv/riscv-subset.h          |  2 +
>>>  gcc/testsuite/gcc.target/riscv/arch-44.c |  5 ++
>>>  gcc/testsuite/gcc.target/riscv/arch-45.c | 12 ++++
>>>  gcc/testsuite/gcc.target/riscv/arch-46.c | 12 ++++
>>>  5 files changed, 105 insertions(+), 1 deletion(-)
>>>  create mode 100644 gcc/testsuite/gcc.target/riscv/arch-44.c
>>>  create mode 100644 gcc/testsuite/gcc.target/riscv/arch-45.c
>>>  create mode 100644 gcc/testsuite/gcc.target/riscv/arch-46.c
>>>
>>> diff --git a/gcc/common/config/riscv/riscv-common.cc
>>> b/gcc/common/config/riscv/riscv-common.cc
>>> index 62c6e1dab1f..0bad4426971 100644
>>> --- a/gcc/common/config/riscv/riscv-common.cc
>>> +++ b/gcc/common/config/riscv/riscv-common.cc
>>> @@ -234,6 +234,12 @@ struct riscv_ext_version
>>>    int minor_version;
>>>  };
>>>
>>> +struct riscv_profiles
>>> +{
>>> +  const char *profile_name;
>>> +  const char *profile_string;
>>> +};
>>> +
>>>  /* All standard extensions defined in all supported ISA spec. */
>>>  static const struct riscv_ext_version riscv_ext_version_table[] =
>>>  {
>>> @@ -449,6 +455,31 @@ static const struct riscv_ext_version
>>> riscv_combine_info[] =
>>>    {NULL, ISA_SPEC_CLASS_NONE, 0, 0}
>>>  };
>>>
>>> +/* This table records the mapping form RISC-V Profiles into march
>>> string.  */
>>> +static const riscv_profiles riscv_profiles_table[] =
>>> +{
>>> +  /* RVI20U only contains the base extension 'i' as mandatory
>>> extension.  */
>>> +  {"RVI20U64", "rv64i"},
>>> +  {"RVI20U32", "rv32i"},
>>> +
>>> +  /* RVA20U contains the
>>> 'i,m,a,f,d,c,zicsr,zicntr,ziccif,ziccrse,ziccamoa,
>>> +     zicclsm,za128rs' as mandatory extensions.  */
>>> +  {"RVA20U64", "rv64imafdc_zicsr_zicntr_ziccif_ziccrse_ziccamoa"
>>> +   "_zicclsm_za128rs"},
>>> +
>>> +  /* RVA22U contains the
>>> 'i,m,a,f,d,c,zicsr,zihintpause,zba,zbb,zbs,zicntr,
>>> +     zihpm,ziccif,ziccrse,ziccamoa,
>>> zicclsm,zic64b,za64rs,zicbom,zicbop,zicboz,
>>
>> Except at least the Spacemit stuff that claims RVA22 doesn't actually
>> have Zicclsm, at least assuming the "supports" in there means "doesn't
>> trap" (we could just say "supports" includes traps, and thus Zicclsm
>> means nothing).
>>
>> I'd argue we should just punt on the profiles until we figure out what
>> they're actually going to be.  The pre-23 profiles were all minor
>> releases anyway, so it's not like we should be losing much there (as
>> they're not meant for software).  At least if we wait we don't end up
>> committing to this whole "profiles don't mean anything" spot we're in,
>> like we did for the other spec flavors.
>>
>> Though now that I'm writing that it actually just sounds kind of silly
>> to keep hoping that we're going to get any meaningful compatibility
>> rules enforced by the RISC-V foundation.  There's really just no
>> incentive for that to happen, as we keep bailing out vendors who ship
>> broken systems and thus there's no pushback from their members.
>>
>> So maybe the right answer here is to just break users and tell them to
>> go complain to someone else?  At least that way everyone will be
>> upset, maybe that'll be enough to get things to change?
>
> Okay, let's continue to wait for the RVA/B23 forzen.

I actually don't think that's going to change anything.  The problem 
here is really enforcing the compatibility rules, and I don't see how
another round of profiles is going to change that.  We're already 
starting to see the backpedalling start again with the A/B and the 
renaming, there's been so many rounds of this it's getting pretty 
predictable.

It's really more a political thing than a technical thing, and with the 
hardware vendors being in charge of things at the RISC-V foundation 
there's just no incentive to enforce compatibility.  That'd just lead to 
them needing to re-spin broken chips.  I don't see how that changes 
until we get enough successful RISC-V based products that the 
fragmentation gets expensive, but that's going to take a while.

IMO we should just give up on getting compatibility rules from the 
RISC-V foundation and just build our own.  That's basically what we've 
done in Linux land and it's working great -- it doesn't really change 
the fundamentals, it just cuts out a bunch of word games about what the 
specs mean.

So essentially just have a "-march=gnu2024" type argument, and define 
that to mean everything that's shipped in 2024 that's interesting for 
binary-compatible distributions.

>>> +     zfhmin,zkt' as mandatory extensions.  */
>>> +  {"RVA22U64", "rv64imafdc_zicsr_zicntr_ziccif_ziccrse_ziccamoa"
>>> + "_zicclsm_zic64b_za64rs_zihintpause_zba_zbb_zbs_zicbom_zicbop"
>>> +   "_zicboz_zfhmin_zkt"},
>>> +
>>> +  /* Currently we do not define S/M mode Profiles in gcc part. */
>>> +
>>> +  /* Terminate the list.  */
>>> +  {NULL, NULL}
>>> +};
>>> +
>>>  static const riscv_cpu_info riscv_cpu_tables[] =
>>>  {
>>>  #define RISCV_CORE(CORE_NAME, ARCH, TUNE) \
>>> @@ -1056,6 +1087,46 @@ riscv_subset_list::parsing_subset_version
>>> (const char *ext,
>>>    return p;
>>>  }
>>>
>>> +/* Parsing RISC-V Profiles in -march string.
>>> +   Return string with mandatory extensions of Profiles.  */
>>> +const char *
>>> +riscv_subset_list::parse_profiles (const char *p)
>>> +{
>>> +  /* Checking if input string contains a Profiles.
>>> +     There are two cases use Profiles in -march option:
>>> +
>>> +     1. Only use Profiles as -march input
>>> +     2. Mixed Profiles with other extensions
>>> +
>>> +     Use '+' to split Profiles and other extension.  */
>>> +  for (int i = 0; riscv_profiles_table[i].profile_name != NULL; ++i)
>>> +    {
>>> +      const char *match = strstr (p,
>>> riscv_profiles_table[i].profile_name);
>>> +      const char *plus_ext = strchr (p, '+');
>>> +      /* Find profile at the begin.  */
>>> +      if (match != NULL && match == p)
>>> +    {
>>> +      /* If there's no '+' sign, return the profile_string
>>> directly.  */
>>> +      if (!plus_ext)
>>> +        return riscv_profiles_table[i].profile_string;
>>> +      /* If there's a '+' sign, need to add profiles with other
>>> ext.  */
>>> +      else
>>> +      {
>>> +        size_t arch_len = strlen
>>> (riscv_profiles_table[i].profile_string)
>>> +          + strlen (plus_ext);
>>> +        /* Reset the input string with Profiles mandatory extensions,
>>> +           end with '_' to connect other additional extensions.  */
>>> +        char *result = new char[arch_len + 2];
>>> +        strcpy (result, riscv_profiles_table[i].profile_string);
>>> +        strcat (result, "_");
>>> +        strcat (result, plus_ext + 1); /* skip the '+'.  */
>>> +        return result;
>>> +      }
>>> +    }
>>> +    }
>>> +  return p;
>>> +}
>>> +
>>>  /* Parsing function for base extensions, rv[32|64][i|e|g]
>>>
>>>     Return Value:
>>> @@ -1070,6 +1141,8 @@ riscv_subset_list::parse_base_ext (const char *p)
>>>    unsigned minor_version = 0;
>>>    bool explicit_version_p = false;
>>>
>>> +  p = parse_profiles(p);
>>> +
>>>    if (startswith (p, "rv32"))
>>>      {
>>>        m_xlen = 32;
>>> @@ -1082,7 +1155,7 @@ riscv_subset_list::parse_base_ext (const char *p)
>>>      }
>>>    else
>>>      {
>>> -      error_at (m_loc, "%<-march=%s%>: ISA string must begin with
>>> rv32 or rv64",
>>> +      error_at (m_loc, "%<-march=%s%>: ISA string must begin with
>>> rv32, rv64 or Profile",
>>>          m_arch);
>>>        return NULL;
>>>      }
>>> diff --git a/gcc/config/riscv/riscv-subset.h
>>> b/gcc/config/riscv/riscv-subset.h
>>> index dace4de6575..98fd9877f74 100644
>>> --- a/gcc/config/riscv/riscv-subset.h
>>> +++ b/gcc/config/riscv/riscv-subset.h
>>> @@ -80,6 +80,8 @@ private:
>>>    const char *parse_single_multiletter_ext (const char *, const char *,
>>>                          const char *, bool);
>>>
>>> +  const char *parse_profiles (const char*);
>>> +
>>>    void handle_implied_ext (const char *);
>>>    bool check_implied_ext ();
>>>    void handle_combine_ext ();
>>> diff --git a/gcc/testsuite/gcc.target/riscv/arch-44.c
>>> b/gcc/testsuite/gcc.target/riscv/arch-44.c
>>> new file mode 100644
>>> index 00000000000..41190bc5939
>>> --- /dev/null
>>> +++ b/gcc/testsuite/gcc.target/riscv/arch-44.c
>>> @@ -0,0 +1,5 @@
>>> +/* { dg-do compile } */
>>> +/* { dg-options "-march=RVI20U64 -mabi=lp64" } */
>>> +int
>>> +foo ()
>>> +{}
>>> diff --git a/gcc/testsuite/gcc.target/riscv/arch-45.c
>>> b/gcc/testsuite/gcc.target/riscv/arch-45.c
>>> new file mode 100644
>>> index 00000000000..273c6abf60d
>>> --- /dev/null
>>> +++ b/gcc/testsuite/gcc.target/riscv/arch-45.c
>>> @@ -0,0 +1,12 @@
>>> +/* { dg-do compile } */
>>> +/* { dg-options "-march=RVI20U64+mafdc -mabi=lp64d" } */
>>> +#if !(defined __riscv_mul) || \
>>> +    !(defined __riscv_atomic) || \
>>> +    !(defined __riscv_flen) || \
>>> +    !(defined __riscv_div) || \
>>> +    !(defined __riscv_compressed)
>>> +#error "Feature macros not defined"
>>> +#endif
>>> +int
>>> +foo ()
>>> +{}
>>> diff --git a/gcc/testsuite/gcc.target/riscv/arch-46.c
>>> b/gcc/testsuite/gcc.target/riscv/arch-46.c
>>> new file mode 100644
>>> index 00000000000..1ebf50d3755
>>> --- /dev/null
>>> +++ b/gcc/testsuite/gcc.target/riscv/arch-46.c
>>> @@ -0,0 +1,12 @@
>>> +/* { dg-do compile } */
>>> +/* { dg-options "-march=RVA20U64 -mabi=lp64d" } */
>>> +#if !(defined __riscv_mul) || \
>>> +    !(defined __riscv_atomic) || \
>>> +    !(defined __riscv_flen) || \
>>> +    !(defined __riscv_div) || \
>>> +    !(defined __riscv_compressed)
>>> +#error "Feature macros not defined"
>>> +#endif
>>> +int
>>> +foo ()
>>> +{}
Kito Cheng Sept. 4, 2024, 1:05 a.m. UTC | #4
I don't see there is conflict if we want to support both gnu2024 and
RVI profiles?
also I am not sure what the usage scenarios for the gnu2024 and how we
defined that?


On Wed, Sep 4, 2024 at 6:49 AM Palmer Dabbelt <palmer@rivosinc.com> wrote:
>
> On Tue, 20 Aug 2024 23:18:36 PDT (-0700), jiawei@iscas.ac.cn wrote:
> >
> > 在 2024/8/21 3:23, Palmer Dabbelt 写道:
> >> On Mon, 19 Aug 2024 21:53:54 PDT (-0700), jiawei@iscas.ac.cn wrote:
> >>> Supports RISC-V profiles[1] in -march option.
> >>>
> >>> Default input set the profile before other formal extensions.
> >>>
> >>> V2: Fixes some format errors and adds code comments for parse function
> >>> Thanks for Jeff Law's review and comments.
> >>>
> >>> V3: Update testcases and profiles extensions support.Remove S/M mode
> >>> Profiles.
> >>> Thanks for Christoph Müllner,Palmer Dabbelt's  review and comments.
> >>>
> >>> V4: Fix format issue, adjust test name.
> >>>
> >>> [1]https://github.com/riscv/riscv-profiles/blob/main/profiles.adoc
> >>>
> >>> gcc/ChangeLog:
> >>>
> >>>     * common/config/riscv/riscv-common.cc (struct riscv_profiles):
> >>>     * New struct.
> >>>     (riscv_subset_list::parse_profiles): New function.
> >>>     (riscv_subset_list::parse_base_ext): New process.
> >>>     * config/riscv/riscv-subset.h: New protype.
> >>>
> >>> gcc/testsuite/ChangeLog:
> >>>
> >>>     * gcc.target/riscv/arch-44.c: New test.
> >>>     * gcc.target/riscv/arch-45.c: New test.
> >>>     * gcc.target/riscv/arch-46.c: New test.
> >>>
> >>> ---
> >>>  gcc/common/config/riscv/riscv-common.cc  | 75 +++++++++++++++++++++++-
> >>>  gcc/config/riscv/riscv-subset.h          |  2 +
> >>>  gcc/testsuite/gcc.target/riscv/arch-44.c |  5 ++
> >>>  gcc/testsuite/gcc.target/riscv/arch-45.c | 12 ++++
> >>>  gcc/testsuite/gcc.target/riscv/arch-46.c | 12 ++++
> >>>  5 files changed, 105 insertions(+), 1 deletion(-)
> >>>  create mode 100644 gcc/testsuite/gcc.target/riscv/arch-44.c
> >>>  create mode 100644 gcc/testsuite/gcc.target/riscv/arch-45.c
> >>>  create mode 100644 gcc/testsuite/gcc.target/riscv/arch-46.c
> >>>
> >>> diff --git a/gcc/common/config/riscv/riscv-common.cc
> >>> b/gcc/common/config/riscv/riscv-common.cc
> >>> index 62c6e1dab1f..0bad4426971 100644
> >>> --- a/gcc/common/config/riscv/riscv-common.cc
> >>> +++ b/gcc/common/config/riscv/riscv-common.cc
> >>> @@ -234,6 +234,12 @@ struct riscv_ext_version
> >>>    int minor_version;
> >>>  };
> >>>
> >>> +struct riscv_profiles
> >>> +{
> >>> +  const char *profile_name;
> >>> +  const char *profile_string;
> >>> +};
> >>> +
> >>>  /* All standard extensions defined in all supported ISA spec. */
> >>>  static const struct riscv_ext_version riscv_ext_version_table[] =
> >>>  {
> >>> @@ -449,6 +455,31 @@ static const struct riscv_ext_version
> >>> riscv_combine_info[] =
> >>>    {NULL, ISA_SPEC_CLASS_NONE, 0, 0}
> >>>  };
> >>>
> >>> +/* This table records the mapping form RISC-V Profiles into march
> >>> string.  */
> >>> +static const riscv_profiles riscv_profiles_table[] =
> >>> +{
> >>> +  /* RVI20U only contains the base extension 'i' as mandatory
> >>> extension.  */
> >>> +  {"RVI20U64", "rv64i"},
> >>> +  {"RVI20U32", "rv32i"},
> >>> +
> >>> +  /* RVA20U contains the
> >>> 'i,m,a,f,d,c,zicsr,zicntr,ziccif,ziccrse,ziccamoa,
> >>> +     zicclsm,za128rs' as mandatory extensions.  */
> >>> +  {"RVA20U64", "rv64imafdc_zicsr_zicntr_ziccif_ziccrse_ziccamoa"
> >>> +   "_zicclsm_za128rs"},
> >>> +
> >>> +  /* RVA22U contains the
> >>> 'i,m,a,f,d,c,zicsr,zihintpause,zba,zbb,zbs,zicntr,
> >>> +     zihpm,ziccif,ziccrse,ziccamoa,
> >>> zicclsm,zic64b,za64rs,zicbom,zicbop,zicboz,
> >>
> >> Except at least the Spacemit stuff that claims RVA22 doesn't actually
> >> have Zicclsm, at least assuming the "supports" in there means "doesn't
> >> trap" (we could just say "supports" includes traps, and thus Zicclsm
> >> means nothing).
> >>
> >> I'd argue we should just punt on the profiles until we figure out what
> >> they're actually going to be.  The pre-23 profiles were all minor
> >> releases anyway, so it's not like we should be losing much there (as
> >> they're not meant for software).  At least if we wait we don't end up
> >> committing to this whole "profiles don't mean anything" spot we're in,
> >> like we did for the other spec flavors.
> >>
> >> Though now that I'm writing that it actually just sounds kind of silly
> >> to keep hoping that we're going to get any meaningful compatibility
> >> rules enforced by the RISC-V foundation.  There's really just no
> >> incentive for that to happen, as we keep bailing out vendors who ship
> >> broken systems and thus there's no pushback from their members.
> >>
> >> So maybe the right answer here is to just break users and tell them to
> >> go complain to someone else?  At least that way everyone will be
> >> upset, maybe that'll be enough to get things to change?
> >
> > Okay, let's continue to wait for the RVA/B23 forzen.
>
> I actually don't think that's going to change anything.  The problem
> here is really enforcing the compatibility rules, and I don't see how
> another round of profiles is going to change that.  We're already
> starting to see the backpedalling start again with the A/B and the
> renaming, there's been so many rounds of this it's getting pretty
> predictable.
>
> It's really more a political thing than a technical thing, and with the
> hardware vendors being in charge of things at the RISC-V foundation
> there's just no incentive to enforce compatibility.  That'd just lead to
> them needing to re-spin broken chips.  I don't see how that changes
> until we get enough successful RISC-V based products that the
> fragmentation gets expensive, but that's going to take a while.
>
> IMO we should just give up on getting compatibility rules from the
> RISC-V foundation and just build our own.  That's basically what we've
> done in Linux land and it's working great -- it doesn't really change
> the fundamentals, it just cuts out a bunch of word games about what the
> specs mean.
>
> So essentially just have a "-march=gnu2024" type argument, and define
> that to mean everything that's shipped in 2024 that's interesting for
> binary-compatible distributions.
>
> >>> +     zfhmin,zkt' as mandatory extensions.  */
> >>> +  {"RVA22U64", "rv64imafdc_zicsr_zicntr_ziccif_ziccrse_ziccamoa"
> >>> + "_zicclsm_zic64b_za64rs_zihintpause_zba_zbb_zbs_zicbom_zicbop"
> >>> +   "_zicboz_zfhmin_zkt"},
> >>> +
> >>> +  /* Currently we do not define S/M mode Profiles in gcc part. */
> >>> +
> >>> +  /* Terminate the list.  */
> >>> +  {NULL, NULL}
> >>> +};
> >>> +
> >>>  static const riscv_cpu_info riscv_cpu_tables[] =
> >>>  {
> >>>  #define RISCV_CORE(CORE_NAME, ARCH, TUNE) \
> >>> @@ -1056,6 +1087,46 @@ riscv_subset_list::parsing_subset_version
> >>> (const char *ext,
> >>>    return p;
> >>>  }
> >>>
> >>> +/* Parsing RISC-V Profiles in -march string.
> >>> +   Return string with mandatory extensions of Profiles.  */
> >>> +const char *
> >>> +riscv_subset_list::parse_profiles (const char *p)
> >>> +{
> >>> +  /* Checking if input string contains a Profiles.
> >>> +     There are two cases use Profiles in -march option:
> >>> +
> >>> +     1. Only use Profiles as -march input
> >>> +     2. Mixed Profiles with other extensions
> >>> +
> >>> +     Use '+' to split Profiles and other extension.  */
> >>> +  for (int i = 0; riscv_profiles_table[i].profile_name != NULL; ++i)
> >>> +    {
> >>> +      const char *match = strstr (p,
> >>> riscv_profiles_table[i].profile_name);
> >>> +      const char *plus_ext = strchr (p, '+');
> >>> +      /* Find profile at the begin.  */
> >>> +      if (match != NULL && match == p)
> >>> +    {
> >>> +      /* If there's no '+' sign, return the profile_string
> >>> directly.  */
> >>> +      if (!plus_ext)
> >>> +        return riscv_profiles_table[i].profile_string;
> >>> +      /* If there's a '+' sign, need to add profiles with other
> >>> ext.  */
> >>> +      else
> >>> +      {
> >>> +        size_t arch_len = strlen
> >>> (riscv_profiles_table[i].profile_string)
> >>> +          + strlen (plus_ext);
> >>> +        /* Reset the input string with Profiles mandatory extensions,
> >>> +           end with '_' to connect other additional extensions.  */
> >>> +        char *result = new char[arch_len + 2];
> >>> +        strcpy (result, riscv_profiles_table[i].profile_string);
> >>> +        strcat (result, "_");
> >>> +        strcat (result, plus_ext + 1); /* skip the '+'.  */
> >>> +        return result;
> >>> +      }
> >>> +    }
> >>> +    }
> >>> +  return p;
> >>> +}
> >>> +
> >>>  /* Parsing function for base extensions, rv[32|64][i|e|g]
> >>>
> >>>     Return Value:
> >>> @@ -1070,6 +1141,8 @@ riscv_subset_list::parse_base_ext (const char *p)
> >>>    unsigned minor_version = 0;
> >>>    bool explicit_version_p = false;
> >>>
> >>> +  p = parse_profiles(p);
> >>> +
> >>>    if (startswith (p, "rv32"))
> >>>      {
> >>>        m_xlen = 32;
> >>> @@ -1082,7 +1155,7 @@ riscv_subset_list::parse_base_ext (const char *p)
> >>>      }
> >>>    else
> >>>      {
> >>> -      error_at (m_loc, "%<-march=%s%>: ISA string must begin with
> >>> rv32 or rv64",
> >>> +      error_at (m_loc, "%<-march=%s%>: ISA string must begin with
> >>> rv32, rv64 or Profile",
> >>>          m_arch);
> >>>        return NULL;
> >>>      }
> >>> diff --git a/gcc/config/riscv/riscv-subset.h
> >>> b/gcc/config/riscv/riscv-subset.h
> >>> index dace4de6575..98fd9877f74 100644
> >>> --- a/gcc/config/riscv/riscv-subset.h
> >>> +++ b/gcc/config/riscv/riscv-subset.h
> >>> @@ -80,6 +80,8 @@ private:
> >>>    const char *parse_single_multiletter_ext (const char *, const char *,
> >>>                          const char *, bool);
> >>>
> >>> +  const char *parse_profiles (const char*);
> >>> +
> >>>    void handle_implied_ext (const char *);
> >>>    bool check_implied_ext ();
> >>>    void handle_combine_ext ();
> >>> diff --git a/gcc/testsuite/gcc.target/riscv/arch-44.c
> >>> b/gcc/testsuite/gcc.target/riscv/arch-44.c
> >>> new file mode 100644
> >>> index 00000000000..41190bc5939
> >>> --- /dev/null
> >>> +++ b/gcc/testsuite/gcc.target/riscv/arch-44.c
> >>> @@ -0,0 +1,5 @@
> >>> +/* { dg-do compile } */
> >>> +/* { dg-options "-march=RVI20U64 -mabi=lp64" } */
> >>> +int
> >>> +foo ()
> >>> +{}
> >>> diff --git a/gcc/testsuite/gcc.target/riscv/arch-45.c
> >>> b/gcc/testsuite/gcc.target/riscv/arch-45.c
> >>> new file mode 100644
> >>> index 00000000000..273c6abf60d
> >>> --- /dev/null
> >>> +++ b/gcc/testsuite/gcc.target/riscv/arch-45.c
> >>> @@ -0,0 +1,12 @@
> >>> +/* { dg-do compile } */
> >>> +/* { dg-options "-march=RVI20U64+mafdc -mabi=lp64d" } */
> >>> +#if !(defined __riscv_mul) || \
> >>> +    !(defined __riscv_atomic) || \
> >>> +    !(defined __riscv_flen) || \
> >>> +    !(defined __riscv_div) || \
> >>> +    !(defined __riscv_compressed)
> >>> +#error "Feature macros not defined"
> >>> +#endif
> >>> +int
> >>> +foo ()
> >>> +{}
> >>> diff --git a/gcc/testsuite/gcc.target/riscv/arch-46.c
> >>> b/gcc/testsuite/gcc.target/riscv/arch-46.c
> >>> new file mode 100644
> >>> index 00000000000..1ebf50d3755
> >>> --- /dev/null
> >>> +++ b/gcc/testsuite/gcc.target/riscv/arch-46.c
> >>> @@ -0,0 +1,12 @@
> >>> +/* { dg-do compile } */
> >>> +/* { dg-options "-march=RVA20U64 -mabi=lp64d" } */
> >>> +#if !(defined __riscv_mul) || \
> >>> +    !(defined __riscv_atomic) || \
> >>> +    !(defined __riscv_flen) || \
> >>> +    !(defined __riscv_div) || \
> >>> +    !(defined __riscv_compressed)
> >>> +#error "Feature macros not defined"
> >>> +#endif
> >>> +int
> >>> +foo ()
> >>> +{}
Andrew Waterman Sept. 4, 2024, 1:07 a.m. UTC | #5
As is normally the case when it comes to matters of RISC-V
International, Palmer is taking the least-charitable interpretation
and then adding a generous dollop of falsehoods.  The RVA23U64 profile
is set to be ratified soon, and that's our intended target for apps
processors.


On Tue, Sep 3, 2024 at 3:50 PM Palmer Dabbelt <palmer@rivosinc.com> wrote:
>
> On Tue, 20 Aug 2024 23:18:36 PDT (-0700), jiawei@iscas.ac.cn wrote:
> >
> > 在 2024/8/21 3:23, Palmer Dabbelt 写道:
> >> On Mon, 19 Aug 2024 21:53:54 PDT (-0700), jiawei@iscas.ac.cn wrote:
> >>> Supports RISC-V profiles[1] in -march option.
> >>>
> >>> Default input set the profile before other formal extensions.
> >>>
> >>> V2: Fixes some format errors and adds code comments for parse function
> >>> Thanks for Jeff Law's review and comments.
> >>>
> >>> V3: Update testcases and profiles extensions support.Remove S/M mode
> >>> Profiles.
> >>> Thanks for Christoph Müllner,Palmer Dabbelt's  review and comments.
> >>>
> >>> V4: Fix format issue, adjust test name.
> >>>
> >>> [1]https://github.com/riscv/riscv-profiles/blob/main/profiles.adoc
> >>>
> >>> gcc/ChangeLog:
> >>>
> >>>     * common/config/riscv/riscv-common.cc (struct riscv_profiles):
> >>>     * New struct.
> >>>     (riscv_subset_list::parse_profiles): New function.
> >>>     (riscv_subset_list::parse_base_ext): New process.
> >>>     * config/riscv/riscv-subset.h: New protype.
> >>>
> >>> gcc/testsuite/ChangeLog:
> >>>
> >>>     * gcc.target/riscv/arch-44.c: New test.
> >>>     * gcc.target/riscv/arch-45.c: New test.
> >>>     * gcc.target/riscv/arch-46.c: New test.
> >>>
> >>> ---
> >>>  gcc/common/config/riscv/riscv-common.cc  | 75 +++++++++++++++++++++++-
> >>>  gcc/config/riscv/riscv-subset.h          |  2 +
> >>>  gcc/testsuite/gcc.target/riscv/arch-44.c |  5 ++
> >>>  gcc/testsuite/gcc.target/riscv/arch-45.c | 12 ++++
> >>>  gcc/testsuite/gcc.target/riscv/arch-46.c | 12 ++++
> >>>  5 files changed, 105 insertions(+), 1 deletion(-)
> >>>  create mode 100644 gcc/testsuite/gcc.target/riscv/arch-44.c
> >>>  create mode 100644 gcc/testsuite/gcc.target/riscv/arch-45.c
> >>>  create mode 100644 gcc/testsuite/gcc.target/riscv/arch-46.c
> >>>
> >>> diff --git a/gcc/common/config/riscv/riscv-common.cc
> >>> b/gcc/common/config/riscv/riscv-common.cc
> >>> index 62c6e1dab1f..0bad4426971 100644
> >>> --- a/gcc/common/config/riscv/riscv-common.cc
> >>> +++ b/gcc/common/config/riscv/riscv-common.cc
> >>> @@ -234,6 +234,12 @@ struct riscv_ext_version
> >>>    int minor_version;
> >>>  };
> >>>
> >>> +struct riscv_profiles
> >>> +{
> >>> +  const char *profile_name;
> >>> +  const char *profile_string;
> >>> +};
> >>> +
> >>>  /* All standard extensions defined in all supported ISA spec. */
> >>>  static const struct riscv_ext_version riscv_ext_version_table[] =
> >>>  {
> >>> @@ -449,6 +455,31 @@ static const struct riscv_ext_version
> >>> riscv_combine_info[] =
> >>>    {NULL, ISA_SPEC_CLASS_NONE, 0, 0}
> >>>  };
> >>>
> >>> +/* This table records the mapping form RISC-V Profiles into march
> >>> string.  */
> >>> +static const riscv_profiles riscv_profiles_table[] =
> >>> +{
> >>> +  /* RVI20U only contains the base extension 'i' as mandatory
> >>> extension.  */
> >>> +  {"RVI20U64", "rv64i"},
> >>> +  {"RVI20U32", "rv32i"},
> >>> +
> >>> +  /* RVA20U contains the
> >>> 'i,m,a,f,d,c,zicsr,zicntr,ziccif,ziccrse,ziccamoa,
> >>> +     zicclsm,za128rs' as mandatory extensions.  */
> >>> +  {"RVA20U64", "rv64imafdc_zicsr_zicntr_ziccif_ziccrse_ziccamoa"
> >>> +   "_zicclsm_za128rs"},
> >>> +
> >>> +  /* RVA22U contains the
> >>> 'i,m,a,f,d,c,zicsr,zihintpause,zba,zbb,zbs,zicntr,
> >>> +     zihpm,ziccif,ziccrse,ziccamoa,
> >>> zicclsm,zic64b,za64rs,zicbom,zicbop,zicboz,
> >>
> >> Except at least the Spacemit stuff that claims RVA22 doesn't actually
> >> have Zicclsm, at least assuming the "supports" in there means "doesn't
> >> trap" (we could just say "supports" includes traps, and thus Zicclsm
> >> means nothing).
> >>
> >> I'd argue we should just punt on the profiles until we figure out what
> >> they're actually going to be.  The pre-23 profiles were all minor
> >> releases anyway, so it's not like we should be losing much there (as
> >> they're not meant for software).  At least if we wait we don't end up
> >> committing to this whole "profiles don't mean anything" spot we're in,
> >> like we did for the other spec flavors.
> >>
> >> Though now that I'm writing that it actually just sounds kind of silly
> >> to keep hoping that we're going to get any meaningful compatibility
> >> rules enforced by the RISC-V foundation.  There's really just no
> >> incentive for that to happen, as we keep bailing out vendors who ship
> >> broken systems and thus there's no pushback from their members.
> >>
> >> So maybe the right answer here is to just break users and tell them to
> >> go complain to someone else?  At least that way everyone will be
> >> upset, maybe that'll be enough to get things to change?
> >
> > Okay, let's continue to wait for the RVA/B23 forzen.
>
> I actually don't think that's going to change anything.  The problem
> here is really enforcing the compatibility rules, and I don't see how
> another round of profiles is going to change that.  We're already
> starting to see the backpedalling start again with the A/B and the
> renaming, there's been so many rounds of this it's getting pretty
> predictable.
>
> It's really more a political thing than a technical thing, and with the
> hardware vendors being in charge of things at the RISC-V foundation
> there's just no incentive to enforce compatibility.  That'd just lead to
> them needing to re-spin broken chips.  I don't see how that changes
> until we get enough successful RISC-V based products that the
> fragmentation gets expensive, but that's going to take a while.
>
> IMO we should just give up on getting compatibility rules from the
> RISC-V foundation and just build our own.  That's basically what we've
> done in Linux land and it's working great -- it doesn't really change
> the fundamentals, it just cuts out a bunch of word games about what the
> specs mean.
>
> So essentially just have a "-march=gnu2024" type argument, and define
> that to mean everything that's shipped in 2024 that's interesting for
> binary-compatible distributions.
>
> >>> +     zfhmin,zkt' as mandatory extensions.  */
> >>> +  {"RVA22U64", "rv64imafdc_zicsr_zicntr_ziccif_ziccrse_ziccamoa"
> >>> + "_zicclsm_zic64b_za64rs_zihintpause_zba_zbb_zbs_zicbom_zicbop"
> >>> +   "_zicboz_zfhmin_zkt"},
> >>> +
> >>> +  /* Currently we do not define S/M mode Profiles in gcc part. */
> >>> +
> >>> +  /* Terminate the list.  */
> >>> +  {NULL, NULL}
> >>> +};
> >>> +
> >>>  static const riscv_cpu_info riscv_cpu_tables[] =
> >>>  {
> >>>  #define RISCV_CORE(CORE_NAME, ARCH, TUNE) \
> >>> @@ -1056,6 +1087,46 @@ riscv_subset_list::parsing_subset_version
> >>> (const char *ext,
> >>>    return p;
> >>>  }
> >>>
> >>> +/* Parsing RISC-V Profiles in -march string.
> >>> +   Return string with mandatory extensions of Profiles.  */
> >>> +const char *
> >>> +riscv_subset_list::parse_profiles (const char *p)
> >>> +{
> >>> +  /* Checking if input string contains a Profiles.
> >>> +     There are two cases use Profiles in -march option:
> >>> +
> >>> +     1. Only use Profiles as -march input
> >>> +     2. Mixed Profiles with other extensions
> >>> +
> >>> +     Use '+' to split Profiles and other extension.  */
> >>> +  for (int i = 0; riscv_profiles_table[i].profile_name != NULL; ++i)
> >>> +    {
> >>> +      const char *match = strstr (p,
> >>> riscv_profiles_table[i].profile_name);
> >>> +      const char *plus_ext = strchr (p, '+');
> >>> +      /* Find profile at the begin.  */
> >>> +      if (match != NULL && match == p)
> >>> +    {
> >>> +      /* If there's no '+' sign, return the profile_string
> >>> directly.  */
> >>> +      if (!plus_ext)
> >>> +        return riscv_profiles_table[i].profile_string;
> >>> +      /* If there's a '+' sign, need to add profiles with other
> >>> ext.  */
> >>> +      else
> >>> +      {
> >>> +        size_t arch_len = strlen
> >>> (riscv_profiles_table[i].profile_string)
> >>> +          + strlen (plus_ext);
> >>> +        /* Reset the input string with Profiles mandatory extensions,
> >>> +           end with '_' to connect other additional extensions.  */
> >>> +        char *result = new char[arch_len + 2];
> >>> +        strcpy (result, riscv_profiles_table[i].profile_string);
> >>> +        strcat (result, "_");
> >>> +        strcat (result, plus_ext + 1); /* skip the '+'.  */
> >>> +        return result;
> >>> +      }
> >>> +    }
> >>> +    }
> >>> +  return p;
> >>> +}
> >>> +
> >>>  /* Parsing function for base extensions, rv[32|64][i|e|g]
> >>>
> >>>     Return Value:
> >>> @@ -1070,6 +1141,8 @@ riscv_subset_list::parse_base_ext (const char *p)
> >>>    unsigned minor_version = 0;
> >>>    bool explicit_version_p = false;
> >>>
> >>> +  p = parse_profiles(p);
> >>> +
> >>>    if (startswith (p, "rv32"))
> >>>      {
> >>>        m_xlen = 32;
> >>> @@ -1082,7 +1155,7 @@ riscv_subset_list::parse_base_ext (const char *p)
> >>>      }
> >>>    else
> >>>      {
> >>> -      error_at (m_loc, "%<-march=%s%>: ISA string must begin with
> >>> rv32 or rv64",
> >>> +      error_at (m_loc, "%<-march=%s%>: ISA string must begin with
> >>> rv32, rv64 or Profile",
> >>>          m_arch);
> >>>        return NULL;
> >>>      }
> >>> diff --git a/gcc/config/riscv/riscv-subset.h
> >>> b/gcc/config/riscv/riscv-subset.h
> >>> index dace4de6575..98fd9877f74 100644
> >>> --- a/gcc/config/riscv/riscv-subset.h
> >>> +++ b/gcc/config/riscv/riscv-subset.h
> >>> @@ -80,6 +80,8 @@ private:
> >>>    const char *parse_single_multiletter_ext (const char *, const char *,
> >>>                          const char *, bool);
> >>>
> >>> +  const char *parse_profiles (const char*);
> >>> +
> >>>    void handle_implied_ext (const char *);
> >>>    bool check_implied_ext ();
> >>>    void handle_combine_ext ();
> >>> diff --git a/gcc/testsuite/gcc.target/riscv/arch-44.c
> >>> b/gcc/testsuite/gcc.target/riscv/arch-44.c
> >>> new file mode 100644
> >>> index 00000000000..41190bc5939
> >>> --- /dev/null
> >>> +++ b/gcc/testsuite/gcc.target/riscv/arch-44.c
> >>> @@ -0,0 +1,5 @@
> >>> +/* { dg-do compile } */
> >>> +/* { dg-options "-march=RVI20U64 -mabi=lp64" } */
> >>> +int
> >>> +foo ()
> >>> +{}
> >>> diff --git a/gcc/testsuite/gcc.target/riscv/arch-45.c
> >>> b/gcc/testsuite/gcc.target/riscv/arch-45.c
> >>> new file mode 100644
> >>> index 00000000000..273c6abf60d
> >>> --- /dev/null
> >>> +++ b/gcc/testsuite/gcc.target/riscv/arch-45.c
> >>> @@ -0,0 +1,12 @@
> >>> +/* { dg-do compile } */
> >>> +/* { dg-options "-march=RVI20U64+mafdc -mabi=lp64d" } */
> >>> +#if !(defined __riscv_mul) || \
> >>> +    !(defined __riscv_atomic) || \
> >>> +    !(defined __riscv_flen) || \
> >>> +    !(defined __riscv_div) || \
> >>> +    !(defined __riscv_compressed)
> >>> +#error "Feature macros not defined"
> >>> +#endif
> >>> +int
> >>> +foo ()
> >>> +{}
> >>> diff --git a/gcc/testsuite/gcc.target/riscv/arch-46.c
> >>> b/gcc/testsuite/gcc.target/riscv/arch-46.c
> >>> new file mode 100644
> >>> index 00000000000..1ebf50d3755
> >>> --- /dev/null
> >>> +++ b/gcc/testsuite/gcc.target/riscv/arch-46.c
> >>> @@ -0,0 +1,12 @@
> >>> +/* { dg-do compile } */
> >>> +/* { dg-options "-march=RVA20U64 -mabi=lp64d" } */
> >>> +#if !(defined __riscv_mul) || \
> >>> +    !(defined __riscv_atomic) || \
> >>> +    !(defined __riscv_flen) || \
> >>> +    !(defined __riscv_div) || \
> >>> +    !(defined __riscv_compressed)
> >>> +#error "Feature macros not defined"
> >>> +#endif
> >>> +int
> >>> +foo ()
> >>> +{}
Palmer Dabbelt Sept. 4, 2024, 1:23 a.m. UTC | #6
On Tue, 03 Sep 2024 18:05:42 PDT (-0700), Kito Cheng wrote:
> I don't see there is conflict if we want to support both gnu2024 and
> RVI profiles?

Ya, they'd just be two different things aimed at solving the same set of 
problems.  I'm just tired of users coming and complaining that stuff is 
broken because of this weak compatibility stance.  If we skip the 
profiles we get to define a stronger compatibility stance.

> also I am not sure what the usage scenarios for the gnu2024 and how we
> defined that?

It'd essentially targeted at binary-compatible distros.  It'd let us 
just write down exactly what we're targeting, so everyone's on the same 
page about what's supported (as opposed to needing to just track down 
all the incompatibilities themselves).

I'd just define it as being compatible with a specific list of chips, 
which we define by discussing it on the mailing lists.  Then it's just a 
matter of deciding which chips that is, but so far there's been a pretty 
clear split on the "interesting for binary compatible distros" side of 
things.  Maybe there's some grey areas at some point, but at least we 
can 

The advantage is that it just side-steps all these word games about what 
compatibility means.

> On Wed, Sep 4, 2024 at 6:49 AM Palmer Dabbelt <palmer@rivosinc.com> wrote:
>>
>> On Tue, 20 Aug 2024 23:18:36 PDT (-0700), jiawei@iscas.ac.cn wrote:
>> >
>> > 在 2024/8/21 3:23, Palmer Dabbelt 写道:
>> >> On Mon, 19 Aug 2024 21:53:54 PDT (-0700), jiawei@iscas.ac.cn wrote:
>> >>> Supports RISC-V profiles[1] in -march option.
>> >>>
>> >>> Default input set the profile before other formal extensions.
>> >>>
>> >>> V2: Fixes some format errors and adds code comments for parse function
>> >>> Thanks for Jeff Law's review and comments.
>> >>>
>> >>> V3: Update testcases and profiles extensions support.Remove S/M mode
>> >>> Profiles.
>> >>> Thanks for Christoph Müllner,Palmer Dabbelt's  review and comments.
>> >>>
>> >>> V4: Fix format issue, adjust test name.
>> >>>
>> >>> [1]https://github.com/riscv/riscv-profiles/blob/main/profiles.adoc
>> >>>
>> >>> gcc/ChangeLog:
>> >>>
>> >>>     * common/config/riscv/riscv-common.cc (struct riscv_profiles):
>> >>>     * New struct.
>> >>>     (riscv_subset_list::parse_profiles): New function.
>> >>>     (riscv_subset_list::parse_base_ext): New process.
>> >>>     * config/riscv/riscv-subset.h: New protype.
>> >>>
>> >>> gcc/testsuite/ChangeLog:
>> >>>
>> >>>     * gcc.target/riscv/arch-44.c: New test.
>> >>>     * gcc.target/riscv/arch-45.c: New test.
>> >>>     * gcc.target/riscv/arch-46.c: New test.
>> >>>
>> >>> ---
>> >>>  gcc/common/config/riscv/riscv-common.cc  | 75 +++++++++++++++++++++++-
>> >>>  gcc/config/riscv/riscv-subset.h          |  2 +
>> >>>  gcc/testsuite/gcc.target/riscv/arch-44.c |  5 ++
>> >>>  gcc/testsuite/gcc.target/riscv/arch-45.c | 12 ++++
>> >>>  gcc/testsuite/gcc.target/riscv/arch-46.c | 12 ++++
>> >>>  5 files changed, 105 insertions(+), 1 deletion(-)
>> >>>  create mode 100644 gcc/testsuite/gcc.target/riscv/arch-44.c
>> >>>  create mode 100644 gcc/testsuite/gcc.target/riscv/arch-45.c
>> >>>  create mode 100644 gcc/testsuite/gcc.target/riscv/arch-46.c
>> >>>
>> >>> diff --git a/gcc/common/config/riscv/riscv-common.cc
>> >>> b/gcc/common/config/riscv/riscv-common.cc
>> >>> index 62c6e1dab1f..0bad4426971 100644
>> >>> --- a/gcc/common/config/riscv/riscv-common.cc
>> >>> +++ b/gcc/common/config/riscv/riscv-common.cc
>> >>> @@ -234,6 +234,12 @@ struct riscv_ext_version
>> >>>    int minor_version;
>> >>>  };
>> >>>
>> >>> +struct riscv_profiles
>> >>> +{
>> >>> +  const char *profile_name;
>> >>> +  const char *profile_string;
>> >>> +};
>> >>> +
>> >>>  /* All standard extensions defined in all supported ISA spec. */
>> >>>  static const struct riscv_ext_version riscv_ext_version_table[] =
>> >>>  {
>> >>> @@ -449,6 +455,31 @@ static const struct riscv_ext_version
>> >>> riscv_combine_info[] =
>> >>>    {NULL, ISA_SPEC_CLASS_NONE, 0, 0}
>> >>>  };
>> >>>
>> >>> +/* This table records the mapping form RISC-V Profiles into march
>> >>> string.  */
>> >>> +static const riscv_profiles riscv_profiles_table[] =
>> >>> +{
>> >>> +  /* RVI20U only contains the base extension 'i' as mandatory
>> >>> extension.  */
>> >>> +  {"RVI20U64", "rv64i"},
>> >>> +  {"RVI20U32", "rv32i"},
>> >>> +
>> >>> +  /* RVA20U contains the
>> >>> 'i,m,a,f,d,c,zicsr,zicntr,ziccif,ziccrse,ziccamoa,
>> >>> +     zicclsm,za128rs' as mandatory extensions.  */
>> >>> +  {"RVA20U64", "rv64imafdc_zicsr_zicntr_ziccif_ziccrse_ziccamoa"
>> >>> +   "_zicclsm_za128rs"},
>> >>> +
>> >>> +  /* RVA22U contains the
>> >>> 'i,m,a,f,d,c,zicsr,zihintpause,zba,zbb,zbs,zicntr,
>> >>> +     zihpm,ziccif,ziccrse,ziccamoa,
>> >>> zicclsm,zic64b,za64rs,zicbom,zicbop,zicboz,
>> >>
>> >> Except at least the Spacemit stuff that claims RVA22 doesn't actually
>> >> have Zicclsm, at least assuming the "supports" in there means "doesn't
>> >> trap" (we could just say "supports" includes traps, and thus Zicclsm
>> >> means nothing).
>> >>
>> >> I'd argue we should just punt on the profiles until we figure out what
>> >> they're actually going to be.  The pre-23 profiles were all minor
>> >> releases anyway, so it's not like we should be losing much there (as
>> >> they're not meant for software).  At least if we wait we don't end up
>> >> committing to this whole "profiles don't mean anything" spot we're in,
>> >> like we did for the other spec flavors.
>> >>
>> >> Though now that I'm writing that it actually just sounds kind of silly
>> >> to keep hoping that we're going to get any meaningful compatibility
>> >> rules enforced by the RISC-V foundation.  There's really just no
>> >> incentive for that to happen, as we keep bailing out vendors who ship
>> >> broken systems and thus there's no pushback from their members.
>> >>
>> >> So maybe the right answer here is to just break users and tell them to
>> >> go complain to someone else?  At least that way everyone will be
>> >> upset, maybe that'll be enough to get things to change?
>> >
>> > Okay, let's continue to wait for the RVA/B23 forzen.
>>
>> I actually don't think that's going to change anything.  The problem
>> here is really enforcing the compatibility rules, and I don't see how
>> another round of profiles is going to change that.  We're already
>> starting to see the backpedalling start again with the A/B and the
>> renaming, there's been so many rounds of this it's getting pretty
>> predictable.
>>
>> It's really more a political thing than a technical thing, and with the
>> hardware vendors being in charge of things at the RISC-V foundation
>> there's just no incentive to enforce compatibility.  That'd just lead to
>> them needing to re-spin broken chips.  I don't see how that changes
>> until we get enough successful RISC-V based products that the
>> fragmentation gets expensive, but that's going to take a while.
>>
>> IMO we should just give up on getting compatibility rules from the
>> RISC-V foundation and just build our own.  That's basically what we've
>> done in Linux land and it's working great -- it doesn't really change
>> the fundamentals, it just cuts out a bunch of word games about what the
>> specs mean.
>>
>> So essentially just have a "-march=gnu2024" type argument, and define
>> that to mean everything that's shipped in 2024 that's interesting for
>> binary-compatible distributions.
>>
>> >>> +     zfhmin,zkt' as mandatory extensions.  */
>> >>> +  {"RVA22U64", "rv64imafdc_zicsr_zicntr_ziccif_ziccrse_ziccamoa"
>> >>> + "_zicclsm_zic64b_za64rs_zihintpause_zba_zbb_zbs_zicbom_zicbop"
>> >>> +   "_zicboz_zfhmin_zkt"},
>> >>> +
>> >>> +  /* Currently we do not define S/M mode Profiles in gcc part. */
>> >>> +
>> >>> +  /* Terminate the list.  */
>> >>> +  {NULL, NULL}
>> >>> +};
>> >>> +
>> >>>  static const riscv_cpu_info riscv_cpu_tables[] =
>> >>>  {
>> >>>  #define RISCV_CORE(CORE_NAME, ARCH, TUNE) \
>> >>> @@ -1056,6 +1087,46 @@ riscv_subset_list::parsing_subset_version
>> >>> (const char *ext,
>> >>>    return p;
>> >>>  }
>> >>>
>> >>> +/* Parsing RISC-V Profiles in -march string.
>> >>> +   Return string with mandatory extensions of Profiles.  */
>> >>> +const char *
>> >>> +riscv_subset_list::parse_profiles (const char *p)
>> >>> +{
>> >>> +  /* Checking if input string contains a Profiles.
>> >>> +     There are two cases use Profiles in -march option:
>> >>> +
>> >>> +     1. Only use Profiles as -march input
>> >>> +     2. Mixed Profiles with other extensions
>> >>> +
>> >>> +     Use '+' to split Profiles and other extension.  */
>> >>> +  for (int i = 0; riscv_profiles_table[i].profile_name != NULL; ++i)
>> >>> +    {
>> >>> +      const char *match = strstr (p,
>> >>> riscv_profiles_table[i].profile_name);
>> >>> +      const char *plus_ext = strchr (p, '+');
>> >>> +      /* Find profile at the begin.  */
>> >>> +      if (match != NULL && match == p)
>> >>> +    {
>> >>> +      /* If there's no '+' sign, return the profile_string
>> >>> directly.  */
>> >>> +      if (!plus_ext)
>> >>> +        return riscv_profiles_table[i].profile_string;
>> >>> +      /* If there's a '+' sign, need to add profiles with other
>> >>> ext.  */
>> >>> +      else
>> >>> +      {
>> >>> +        size_t arch_len = strlen
>> >>> (riscv_profiles_table[i].profile_string)
>> >>> +          + strlen (plus_ext);
>> >>> +        /* Reset the input string with Profiles mandatory extensions,
>> >>> +           end with '_' to connect other additional extensions.  */
>> >>> +        char *result = new char[arch_len + 2];
>> >>> +        strcpy (result, riscv_profiles_table[i].profile_string);
>> >>> +        strcat (result, "_");
>> >>> +        strcat (result, plus_ext + 1); /* skip the '+'.  */
>> >>> +        return result;
>> >>> +      }
>> >>> +    }
>> >>> +    }
>> >>> +  return p;
>> >>> +}
>> >>> +
>> >>>  /* Parsing function for base extensions, rv[32|64][i|e|g]
>> >>>
>> >>>     Return Value:
>> >>> @@ -1070,6 +1141,8 @@ riscv_subset_list::parse_base_ext (const char *p)
>> >>>    unsigned minor_version = 0;
>> >>>    bool explicit_version_p = false;
>> >>>
>> >>> +  p = parse_profiles(p);
>> >>> +
>> >>>    if (startswith (p, "rv32"))
>> >>>      {
>> >>>        m_xlen = 32;
>> >>> @@ -1082,7 +1155,7 @@ riscv_subset_list::parse_base_ext (const char *p)
>> >>>      }
>> >>>    else
>> >>>      {
>> >>> -      error_at (m_loc, "%<-march=%s%>: ISA string must begin with
>> >>> rv32 or rv64",
>> >>> +      error_at (m_loc, "%<-march=%s%>: ISA string must begin with
>> >>> rv32, rv64 or Profile",
>> >>>          m_arch);
>> >>>        return NULL;
>> >>>      }
>> >>> diff --git a/gcc/config/riscv/riscv-subset.h
>> >>> b/gcc/config/riscv/riscv-subset.h
>> >>> index dace4de6575..98fd9877f74 100644
>> >>> --- a/gcc/config/riscv/riscv-subset.h
>> >>> +++ b/gcc/config/riscv/riscv-subset.h
>> >>> @@ -80,6 +80,8 @@ private:
>> >>>    const char *parse_single_multiletter_ext (const char *, const char *,
>> >>>                          const char *, bool);
>> >>>
>> >>> +  const char *parse_profiles (const char*);
>> >>> +
>> >>>    void handle_implied_ext (const char *);
>> >>>    bool check_implied_ext ();
>> >>>    void handle_combine_ext ();
>> >>> diff --git a/gcc/testsuite/gcc.target/riscv/arch-44.c
>> >>> b/gcc/testsuite/gcc.target/riscv/arch-44.c
>> >>> new file mode 100644
>> >>> index 00000000000..41190bc5939
>> >>> --- /dev/null
>> >>> +++ b/gcc/testsuite/gcc.target/riscv/arch-44.c
>> >>> @@ -0,0 +1,5 @@
>> >>> +/* { dg-do compile } */
>> >>> +/* { dg-options "-march=RVI20U64 -mabi=lp64" } */
>> >>> +int
>> >>> +foo ()
>> >>> +{}
>> >>> diff --git a/gcc/testsuite/gcc.target/riscv/arch-45.c
>> >>> b/gcc/testsuite/gcc.target/riscv/arch-45.c
>> >>> new file mode 100644
>> >>> index 00000000000..273c6abf60d
>> >>> --- /dev/null
>> >>> +++ b/gcc/testsuite/gcc.target/riscv/arch-45.c
>> >>> @@ -0,0 +1,12 @@
>> >>> +/* { dg-do compile } */
>> >>> +/* { dg-options "-march=RVI20U64+mafdc -mabi=lp64d" } */
>> >>> +#if !(defined __riscv_mul) || \
>> >>> +    !(defined __riscv_atomic) || \
>> >>> +    !(defined __riscv_flen) || \
>> >>> +    !(defined __riscv_div) || \
>> >>> +    !(defined __riscv_compressed)
>> >>> +#error "Feature macros not defined"
>> >>> +#endif
>> >>> +int
>> >>> +foo ()
>> >>> +{}
>> >>> diff --git a/gcc/testsuite/gcc.target/riscv/arch-46.c
>> >>> b/gcc/testsuite/gcc.target/riscv/arch-46.c
>> >>> new file mode 100644
>> >>> index 00000000000..1ebf50d3755
>> >>> --- /dev/null
>> >>> +++ b/gcc/testsuite/gcc.target/riscv/arch-46.c
>> >>> @@ -0,0 +1,12 @@
>> >>> +/* { dg-do compile } */
>> >>> +/* { dg-options "-march=RVA20U64 -mabi=lp64d" } */
>> >>> +#if !(defined __riscv_mul) || \
>> >>> +    !(defined __riscv_atomic) || \
>> >>> +    !(defined __riscv_flen) || \
>> >>> +    !(defined __riscv_div) || \
>> >>> +    !(defined __riscv_compressed)
>> >>> +#error "Feature macros not defined"
>> >>> +#endif
>> >>> +int
>> >>> +foo ()
>> >>> +{}
diff mbox series

Patch

diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc
index 62c6e1dab1f..0bad4426971 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -234,6 +234,12 @@  struct riscv_ext_version
   int minor_version;
 };
 
+struct riscv_profiles
+{
+  const char *profile_name;
+  const char *profile_string;
+};
+
 /* All standard extensions defined in all supported ISA spec.  */
 static const struct riscv_ext_version riscv_ext_version_table[] =
 {
@@ -449,6 +455,31 @@  static const struct riscv_ext_version riscv_combine_info[] =
   {NULL, ISA_SPEC_CLASS_NONE, 0, 0}
 };
 
+/* This table records the mapping form RISC-V Profiles into march string.  */
+static const riscv_profiles riscv_profiles_table[] =
+{
+  /* RVI20U only contains the base extension 'i' as mandatory extension.  */
+  {"RVI20U64", "rv64i"},
+  {"RVI20U32", "rv32i"},
+
+  /* RVA20U contains the 'i,m,a,f,d,c,zicsr,zicntr,ziccif,ziccrse,ziccamoa,
+     zicclsm,za128rs' as mandatory extensions.  */
+  {"RVA20U64", "rv64imafdc_zicsr_zicntr_ziccif_ziccrse_ziccamoa"
+   "_zicclsm_za128rs"},
+
+  /* RVA22U contains the 'i,m,a,f,d,c,zicsr,zihintpause,zba,zbb,zbs,zicntr,
+     zihpm,ziccif,ziccrse,ziccamoa, zicclsm,zic64b,za64rs,zicbom,zicbop,zicboz,
+     zfhmin,zkt' as mandatory extensions.  */
+  {"RVA22U64", "rv64imafdc_zicsr_zicntr_ziccif_ziccrse_ziccamoa"
+   "_zicclsm_zic64b_za64rs_zihintpause_zba_zbb_zbs_zicbom_zicbop"
+   "_zicboz_zfhmin_zkt"},
+
+  /* Currently we do not define S/M mode Profiles in gcc part.  */
+
+  /* Terminate the list.  */
+  {NULL, NULL}
+};
+
 static const riscv_cpu_info riscv_cpu_tables[] =
 {
 #define RISCV_CORE(CORE_NAME, ARCH, TUNE) \
@@ -1056,6 +1087,46 @@  riscv_subset_list::parsing_subset_version (const char *ext,
   return p;
 }
 
+/* Parsing RISC-V Profiles in -march string.
+   Return string with mandatory extensions of Profiles.  */
+const char *
+riscv_subset_list::parse_profiles (const char *p)
+{
+  /* Checking if input string contains a Profiles.
+     There are two cases use Profiles in -march option:
+
+     1. Only use Profiles as -march input
+     2. Mixed Profiles with other extensions
+
+     Use '+' to split Profiles and other extension.  */
+  for (int i = 0; riscv_profiles_table[i].profile_name != NULL; ++i)
+    {
+      const char *match = strstr (p, riscv_profiles_table[i].profile_name);
+      const char *plus_ext = strchr (p, '+');
+      /* Find profile at the begin.  */
+      if (match != NULL && match == p)
+	{
+	  /* If there's no '+' sign, return the profile_string directly.  */
+	  if (!plus_ext)
+	    return riscv_profiles_table[i].profile_string;
+	  /* If there's a '+' sign, need to add profiles with other ext.  */
+	  else
+	  {
+	    size_t arch_len = strlen (riscv_profiles_table[i].profile_string)
+		  + strlen (plus_ext);
+	    /* Reset the input string with Profiles mandatory extensions,
+	       end with '_' to connect other additional extensions.  */
+	    char *result = new char[arch_len + 2];
+	    strcpy (result, riscv_profiles_table[i].profile_string);
+	    strcat (result, "_");
+	    strcat (result, plus_ext + 1); /* skip the '+'.  */
+	    return result;
+	  }
+	}
+    }
+  return p;
+}
+
 /* Parsing function for base extensions, rv[32|64][i|e|g]
 
    Return Value:
@@ -1070,6 +1141,8 @@  riscv_subset_list::parse_base_ext (const char *p)
   unsigned minor_version = 0;
   bool explicit_version_p = false;
 
+  p = parse_profiles(p);
+
   if (startswith (p, "rv32"))
     {
       m_xlen = 32;
@@ -1082,7 +1155,7 @@  riscv_subset_list::parse_base_ext (const char *p)
     }
   else
     {
-      error_at (m_loc, "%<-march=%s%>: ISA string must begin with rv32 or rv64",
+      error_at (m_loc, "%<-march=%s%>: ISA string must begin with rv32, rv64 or Profile",
 		m_arch);
       return NULL;
     }
diff --git a/gcc/config/riscv/riscv-subset.h b/gcc/config/riscv/riscv-subset.h
index dace4de6575..98fd9877f74 100644
--- a/gcc/config/riscv/riscv-subset.h
+++ b/gcc/config/riscv/riscv-subset.h
@@ -80,6 +80,8 @@  private:
   const char *parse_single_multiletter_ext (const char *, const char *,
 					    const char *, bool);
 
+  const char *parse_profiles (const char*);
+
   void handle_implied_ext (const char *);
   bool check_implied_ext ();
   void handle_combine_ext ();
diff --git a/gcc/testsuite/gcc.target/riscv/arch-44.c b/gcc/testsuite/gcc.target/riscv/arch-44.c
new file mode 100644
index 00000000000..41190bc5939
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/arch-44.c
@@ -0,0 +1,5 @@ 
+/* { dg-do compile } */
+/* { dg-options "-march=RVI20U64 -mabi=lp64" } */
+int
+foo ()
+{}
diff --git a/gcc/testsuite/gcc.target/riscv/arch-45.c b/gcc/testsuite/gcc.target/riscv/arch-45.c
new file mode 100644
index 00000000000..273c6abf60d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/arch-45.c
@@ -0,0 +1,12 @@ 
+/* { dg-do compile } */
+/* { dg-options "-march=RVI20U64+mafdc -mabi=lp64d" } */
+#if !(defined __riscv_mul) || \
+    !(defined __riscv_atomic) || \
+    !(defined __riscv_flen) || \
+    !(defined __riscv_div) || \
+    !(defined __riscv_compressed)
+#error "Feature macros not defined"
+#endif
+int
+foo ()
+{}
diff --git a/gcc/testsuite/gcc.target/riscv/arch-46.c b/gcc/testsuite/gcc.target/riscv/arch-46.c
new file mode 100644
index 00000000000..1ebf50d3755
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/arch-46.c
@@ -0,0 +1,12 @@ 
+/* { dg-do compile } */
+/* { dg-options "-march=RVA20U64 -mabi=lp64d" } */
+#if !(defined __riscv_mul) || \
+    !(defined __riscv_atomic) || \
+    !(defined __riscv_flen) || \
+    !(defined __riscv_div) || \
+    !(defined __riscv_compressed)
+#error "Feature macros not defined"
+#endif
+int
+foo ()
+{}