This patch introduces support for RISC-V Profiles RV20 and RV22 [1], enabling developers to utilize these profiles through the -march option.
[1] https://github.com/riscv/riscv-profiles/releases/tag/v1.0 Version log: Using lowercase letters to present Profiles. Using '_' as divsor between Profiles and other RISC-V extension. Add descriptions in invoke.texi. Checking if there exist '_' between Profiles and additional extensions. Using std::string to avoid memory problems. gcc/ChangeLog: * common/config/riscv/riscv-common.cc (struct riscv_profiles): New struct. (riscv_subset_list::parse_profiles): New parser. (riscv_subset_list::parse_base_ext): Ditto. * config/riscv/riscv-subset.h: New def. * doc/invoke.texi: New option descriptions. gcc/testsuite/ChangeLog: * gcc.target/riscv/arch-49.c: New test. * gcc.target/riscv/arch-50.c: New test. * gcc.target/riscv/arch-51.c: New test. * gcc.target/riscv/arch-52.c: New test. --- gcc/common/config/riscv/riscv-common.cc | 85 ++++++++++++++++++- gcc/config/riscv/riscv-subset.h | 2 + gcc/doc/invoke.texi | 17 ++-- .../aarch64/sve/acle/general/attributes_7.c | 2 +- gcc/testsuite/gcc.target/riscv/arch-49.c | 5 ++ gcc/testsuite/gcc.target/riscv/arch-50.c | 12 +++ gcc/testsuite/gcc.target/riscv/arch-51.c | 12 +++ gcc/testsuite/gcc.target/riscv/arch-52.c | 6 ++ 8 files changed, 131 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/arch-49.c create mode 100644 gcc/testsuite/gcc.target/riscv/arch-50.c create mode 100644 gcc/testsuite/gcc.target/riscv/arch-51.c create mode 100644 gcc/testsuite/gcc.target/riscv/arch-52.c diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc index ca14eb96b2..0fa2e21f27 100644 --- a/gcc/common/config/riscv/riscv-common.cc +++ b/gcc/common/config/riscv/riscv-common.cc @@ -274,6 +274,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[] = { @@ -502,6 +508,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) \ @@ -1109,6 +1140,52 @@ 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. */ +std::string +riscv_subset_list::parse_profiles (const char *arch) +{ + /* Checking if input string contains a Profiles. + There are two cases use Profiles in -march option: + + 1. Only use Profiles in '-march' as input + 2. Mixed Profiles with other extensions + + Use '_' to split Profiles and other extension. */ + std::string p(arch); + const size_t p_len = p.size(); + + for (int i = 0; riscv_profiles_table[i].profile_name != nullptr; ++i) + { + const std::string& p_name = riscv_profiles_table[i].profile_name; + const std::string& p_str = riscv_profiles_table[i].profile_string; + size_t pos = p.find(p_name); + /* Find profile at the begin. */ + if (pos == 0 && pos + p_name.size() <= p_len) + { + size_t after_pos = pos + p_name.size(); + std::string after_part = p.substr(after_pos); + + /* If there're only profile, return the profile_string directly. */ + if (after_part[0] == '\0') + return p_str; + + /* If isn't '_' after profile, need to add it and mention the user. */ + if (after_part[0] != '_') + { + warning_at (m_loc, 0, "Should use \"%c\" to contact Profiles with other " + "extensions", '_'); + return p_str + "_" + after_part; + } + + /* Return 'profiles_additional' extensions. */ + return p_str + after_part; + } + } + /* Not found profile, return directly. */ + return p; +} + /* Parsing function for base extensions, rv[32|64][i|e|g] Return Value: @@ -1135,8 +1212,8 @@ riscv_subset_list::parse_base_ext (const char *p) } else { - error_at (m_loc, "%<-march=%s%>: ISA string must begin with rv32 or rv64", - m_arch); + error_at (m_loc, "%<-march=%s%>: ISA string must begin with rv32, rv64 " + "or Profiles", m_arch); return NULL; } @@ -1527,8 +1604,10 @@ riscv_subset_list::parse (const char *arch, location_t loc) return NULL; riscv_subset_list *subset_list = new riscv_subset_list (arch, loc); + const char *p = arch; - p = subset_list->parse_base_ext (p); + std::string a = subset_list->parse_profiles(p); + p = subset_list->parse_base_ext (a.c_str()); if (p == NULL) goto fail; diff --git a/gcc/config/riscv/riscv-subset.h b/gcc/config/riscv/riscv-subset.h index 559e708501..7b3fdaeb3e 100644 --- a/gcc/config/riscv/riscv-subset.h +++ b/gcc/config/riscv/riscv-subset.h @@ -82,6 +82,8 @@ private: const char *parse_single_multiletter_ext (const char *, const char *, const char *, bool); + std::string parse_profiles (const char*); + void handle_implied_ext (const char *); bool check_implied_ext (); void handle_combine_ext (); diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index f31d504f99..a0f1a93056 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -1268,7 +1268,7 @@ See RS/6000 and PowerPC Options. -mfence-tso -mno-fence-tso -mdiv -mno-div -misa-spec=@var{ISA-spec-string} --march=@var{ISA-string} +-march=@var{ISA-string|Profiles|Profiles_ISA-string} -mtune=@var{processor-string} -mpreferred-stack-boundary=@var{num} -msmall-data-limit=@var{N-bytes} @@ -31115,11 +31115,16 @@ The default is @option{-misa-spec=20191213} unless GCC has been configured with @option{--with-isa-spec=} specifying a different default version. @opindex march -@item -march=@var{ISA-string} -Generate code for given RISC-V ISA (e.g.@: @samp{rv64im}). ISA strings must be -lower-case. Examples include @samp{rv64i}, @samp{rv32g}, @samp{rv32e}, and -@samp{rv32imaf}. Additionally, a special value @option{help} -(@option{-march=help}) is accepted to list all supported extensions. +@item -march=@var{ISA-string|Profiles|Profile_ISA-string} +Generate code for given RISC-V ISA or Profiles or a combination of them +(e.g.@: @samp{rv64im} @samp{rvi20u64} @samp{rvi20u64_zbb}). ISA strings and +Profiles must be lower-case. Examples include @samp{rv64i}, @samp{rv32g}, +@samp{rv32e}, @samp{rv32imaf}, @samp{rva22u64} and @samp{rva23u64}. +To combine Profiles and optional RISC-V ISA extention, the profile should start +at the beginning of the option, then use underline connect ISA-string (e.g.@: +@samp{rvi20u64_zca_zcb} @samp{rva23u64_zacas}). Additionally, a special value +@option{help} (@option{-march=help}) is accepted to list all supported +extensions. The syntax of the ISA string is defined as follows: diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/attributes_7.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/attributes_7.c index 7df9aaf45c..682a8edbe2 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/attributes_7.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/attributes_7.c @@ -182,7 +182,7 @@ g (int c) diff = fb - fb; sb = fb; // { dg-error {invalid conversion} "" { target c++ } } - // { dg-warning {incompatible pointer type} "c" { target c xfail c } .-1 } + // { rning {incompatible pointer type} "c" { target c xfail c } .-1 } fb = sb; // { dg-error {invalid conversion} "" { target c++ } } // { dg-warning {incompatible pointer type} "c" { target c xfail c } .-1 } diff --git a/gcc/testsuite/gcc.target/riscv/arch-49.c b/gcc/testsuite/gcc.target/riscv/arch-49.c new file mode 100644 index 0000000000..6b86ae9fb3 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/arch-49.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-50.c b/gcc/testsuite/gcc.target/riscv/arch-50.c new file mode 100644 index 0000000000..072180d4f1 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/arch-50.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-51.c b/gcc/testsuite/gcc.target/riscv/arch-51.c new file mode 100644 index 0000000000..5af983cbca --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/arch-51.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 --git a/gcc/testsuite/gcc.target/riscv/arch-52.c b/gcc/testsuite/gcc.target/riscv/arch-52.c new file mode 100644 index 0000000000..da6aea8fd9 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/arch-52.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rva22u64v -mabi=lp64" } */ +/* { dg-warning "*Should use \"_\" to contact Profiles with other extensions" } */ +int +foo () +{} -- 2.43.0