diff options
Diffstat (limited to 'gcc/common/config/riscv/riscv-common.cc')
-rw-r--r-- | gcc/common/config/riscv/riscv-common.cc | 1241 |
1 files changed, 441 insertions, 800 deletions
diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc index e06cd5f..d24fca6 100644 --- a/gcc/common/config/riscv/riscv-common.cc +++ b/gcc/common/config/riscv/riscv-common.cc @@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see #include <sstream> #include <vector> +#include <unordered_map> #include <queue> #define INCLUDE_STRING @@ -41,229 +42,216 @@ along with GCC; see the file COPYING3. If not see #define TARGET_DEFAULT_TARGET_FLAGS (MASK_BIG_ENDIAN) #endif +/* Type for pointer to member of gcc_options and cl_target_option. */ +typedef int (gcc_options::*opt_var_ref_t); +typedef int (cl_target_option::*cl_opt_var_ref_t); + +/* Types for recording extension to internal flag. */ +struct riscv_extra_ext_flag_table_t +{ + const char *ext; + opt_var_ref_t var_ref; + cl_opt_var_ref_t cl_var_ref; + int mask; +}; + +/* Types for recording extension to internal flag. */ +struct riscv_ext_flag_table_t +{ + opt_var_ref_t var_ref; + cl_opt_var_ref_t cl_var_ref; + int mask; + + void clean (gcc_options *opts) const { opts->*var_ref &= ~mask; } + + void set (gcc_options *opts) const { opts->*var_ref |= mask; } + + bool check (cl_target_option *opts) const + { + return (opts->*cl_var_ref & mask); + } +}; + +/* Type for hold RISC-V extension version. */ +struct riscv_version_t +{ + riscv_version_t (int major_version, int minor_version, + enum riscv_isa_spec_class isa_spec_class + = ISA_SPEC_CLASS_NONE) + : major_version (major_version), minor_version (minor_version), + isa_spec_class (isa_spec_class) + {} + int major_version; + int minor_version; + enum riscv_isa_spec_class isa_spec_class; +}; + typedef bool (*riscv_implied_predicator_t) (const riscv_subset_list *); /* Type for implied ISA info. */ struct riscv_implied_info_t { - constexpr riscv_implied_info_t (const char *ext, const char *implied_ext, + constexpr riscv_implied_info_t (const char *implied_ext, riscv_implied_predicator_t predicator = nullptr) - : ext (ext), implied_ext (implied_ext), predicator (predicator){}; + : implied_ext (implied_ext), predicator (predicator) + {} - bool match (const riscv_subset_list *subset_list, const char *ext_name) const + bool match (const riscv_subset_list *subset_list) const { - if (strcmp (ext_name, ext) != 0) - return false; - if (predicator && !predicator (subset_list)) return false; return true; } - bool match (const riscv_subset_list *subset_list, - const riscv_subset_t *subset) const - { - return match (subset_list, subset->name.c_str()); - } - - const char *ext; const char *implied_ext; riscv_implied_predicator_t predicator; }; -/* Implied ISA info, must end with NULL sentinel. */ -static const riscv_implied_info_t riscv_implied_info[] = -{ - {"m", "zmmul"}, - - {"d", "f"}, - {"f", "zicsr"}, - {"d", "zicsr"}, - - {"a", "zaamo"}, - {"a", "zalrsc"}, - - {"c", "zca"}, - {"c", "zcf", - [] (const riscv_subset_list *subset_list) -> bool - { - return subset_list->xlen () == 32 && subset_list->lookup ("f"); - }}, - {"c", "zcd", - [] (const riscv_subset_list *subset_list) -> bool - { - return subset_list->lookup ("d"); - }}, - - {"zabha", "zaamo"}, - {"zacas", "zaamo"}, - {"zawrs", "zalrsc"}, - - {"zcmop", "zca"}, - - {"b", "zba"}, - {"b", "zbb"}, - {"b", "zbs"}, - - {"zdinx", "zfinx"}, - {"zfinx", "zicsr"}, - {"zdinx", "zicsr"}, - - {"zicfiss", "zicsr"}, - {"zicfiss", "zimop"}, - {"zicfilp", "zicsr"}, - - {"zk", "zkn"}, - {"zk", "zkr"}, - {"zk", "zkt"}, - {"zkn", "zbkb"}, - {"zkn", "zbkc"}, - {"zkn", "zbkx"}, - {"zkn", "zkne"}, - {"zkn", "zknd"}, - {"zkn", "zknh"}, - {"zks", "zbkb"}, - {"zks", "zbkc"}, - {"zks", "zbkx"}, - {"zks", "zksed"}, - {"zks", "zksh"}, - - {"v", "zvl128b"}, - {"v", "zve64d"}, - - {"zve32f", "f"}, - {"zve64f", "f"}, - {"zve64d", "d"}, - - {"zve32x", "zicsr"}, - {"zve32x", "zvl32b"}, - {"zve32f", "zve32x"}, - {"zve32f", "zvl32b"}, - - {"zve64x", "zve32x"}, - {"zve64x", "zvl64b"}, - {"zve64f", "zve32f"}, - {"zve64f", "zve64x"}, - {"zve64f", "zvl64b"}, - {"zve64d", "zve64f"}, - {"zve64d", "zvl64b"}, - - {"zvl64b", "zvl32b"}, - {"zvl128b", "zvl64b"}, - {"zvl256b", "zvl128b"}, - {"zvl512b", "zvl256b"}, - {"zvl1024b", "zvl512b"}, - {"zvl2048b", "zvl1024b"}, - {"zvl4096b", "zvl2048b"}, - {"zvl8192b", "zvl4096b"}, - {"zvl16384b", "zvl8192b"}, - {"zvl32768b", "zvl16384b"}, - {"zvl65536b", "zvl32768b"}, - - {"zvkn", "zvkned"}, - {"zvkn", "zvknhb"}, - {"zvkn", "zvkb"}, - {"zvkn", "zvkt"}, - {"zvknc", "zvkn"}, - {"zvknc", "zvbc"}, - {"zvkng", "zvkn"}, - {"zvkng", "zvkg"}, - {"zvks", "zvksed"}, - {"zvks", "zvksh"}, - {"zvks", "zvkb"}, - {"zvks", "zvkt"}, - {"zvksc", "zvks"}, - {"zvksc", "zvbc"}, - {"zvksg", "zvks"}, - {"zvksg", "zvkg"}, - {"zvbb", "zvkb"}, - {"zvbc", "zve64x"}, - {"zvkb", "zve32x"}, - {"zvkg", "zve32x"}, - {"zvkned", "zve32x"}, - {"zvknha", "zve32x"}, - {"zvknhb", "zve64x"}, - {"zvksed", "zve32x"}, - {"zvksh", "zve32x"}, - - {"zfbfmin", "zfhmin"}, - {"zfh", "zfhmin"}, - {"zfhmin", "f"}, - - {"zfa", "f"}, - - {"zvfbfmin", "zve32f"}, - {"zvfbfwma", "zvfbfmin"}, - {"zvfbfwma", "zfbfmin"}, - {"zvfhmin", "zve32f"}, - {"zvfh", "zve32f"}, - {"zvfh", "zfhmin"}, - - {"zhinx", "zhinxmin"}, - {"zhinxmin", "zfinx"}, - - {"zce", "zca"}, - {"zce", "zcb"}, - {"zce", "zcmp"}, - {"zce", "zcmt"}, - {"zcf", "zca"}, - {"zcd", "zca"}, - {"zcb", "zca"}, - {"zcmp", "zca"}, - {"zcmt", "zca"}, - {"zcmt", "zicsr"}, - {"zce", "zcf", - [] (const riscv_subset_list *subset_list) -> bool - { - return subset_list->xlen () == 32 && subset_list->lookup ("f"); - }}, - {"zca", "c", - [] (const riscv_subset_list *subset_list) -> bool - { - /* For RV32 Zca implies C for one of these combinations of - extensions: Zca, F_Zca_Zcf and FD_Zca_Zcf_Zcd. */ - if (subset_list->xlen () == 32) - { - if (subset_list->lookup ("d")) - return subset_list->lookup ("zcf") && subset_list->lookup ("zcd"); - - if (subset_list->lookup ("f")) - return subset_list->lookup ("zcf"); - - return true; - } - - /* For RV64 Zca implies C for one of these combinations of - extensions: Zca and FD_Zca_Zcd (Zcf is not available - for RV64). */ - if (subset_list->xlen () == 64) - { - if (subset_list->lookup ("d")) - return subset_list->lookup ("zcd"); - - return true; - } - - /* Do nothing for future RV128 specification. Behaviour - for this case is not yet well defined. */ - return false; - }}, - - {"smaia", "ssaia"}, - {"smstateen", "ssstateen"}, - {"smepmp", "zicsr"}, - {"ssaia", "zicsr"}, - {"sscofpmf", "zicsr"}, - {"ssstateen", "zicsr"}, - {"sstc", "zicsr"}, - - {"xsfvcp", "zve32x"}, +static void +apply_extra_extension_flags (const char *ext, + std::vector<riscv_ext_flag_table_t> &flag_table); - {NULL, NULL} +/* Class for hold the extension info. */ +class riscv_ext_info_t +{ +public: + riscv_ext_info_t (const char *ext, + const std::vector<riscv_implied_info_t> &implied_exts, + const std::vector<riscv_version_t> &supported_versions, + const std::vector<riscv_ext_flag_table_t> &flag_table, + int bitmask_group_id, int bitmask_group_bit_pos, + unsigned extra_extension_flags) + : m_ext (ext), m_implied_exts (implied_exts), + m_supported_versions (supported_versions), m_flag_table (flag_table), + m_bitmask_group_id (bitmask_group_id), + m_bitmask_group_bit_pos (bitmask_group_bit_pos), + m_extra_extension_flags (extra_extension_flags) + { + apply_extra_extension_flags (ext, m_flag_table); + } + + /* Return true if any change. */ + bool apply_implied_ext (riscv_subset_list *subset_list) const; + + const std::vector<riscv_implied_info_t> implied_exts () const + { + return m_implied_exts; + } + + bool need_combine_p () const + { + return m_extra_extension_flags & EXT_FLAG_MACRO; + } + + riscv_version_t default_version () const + { + if (m_supported_versions.size () == 1) + { + return *m_supported_versions.begin (); + } + + for (const riscv_version_t &ver : m_supported_versions) + { + if (ver.isa_spec_class == riscv_isa_spec + || ver.isa_spec_class == ISA_SPEC_CLASS_NONE) + return ver; + } + gcc_unreachable (); + } + + void clean_opts (gcc_options *opts) const + { + for (auto &flag : m_flag_table) + flag.clean (opts); + } + + void set_opts (gcc_options *opts) const + { + for (auto &flag : m_flag_table) + flag.set (opts); + } + + bool check_opts (cl_target_option *opts) const + { + bool result = true; + for (auto &flag : m_flag_table) + result = result && flag.check (opts); + return result; + } + + const std::vector<riscv_version_t> &supported_versions () const + { + return m_supported_versions; + } + +private: + const char *m_ext; + std::vector<riscv_implied_info_t> m_implied_exts; + std::vector<riscv_version_t> m_supported_versions; + std::vector<riscv_ext_flag_table_t> m_flag_table; + int m_bitmask_group_id; + int m_bitmask_group_bit_pos; + unsigned m_extra_extension_flags; }; +static const std::unordered_map<std::string, riscv_ext_info_t> riscv_ext_infos + = { +#define DEFINE_RISCV_EXT(NAME, UPPERCAE_NAME, FULL_NAME, DESC, URL, DEP_EXTS, \ + SUPPORTED_VERSIONS, FLAG_GROUP, BITMASK_GROUP_ID, \ + BITMASK_BIT_POSITION, EXTRA_EXTENSION_FLAGS) \ + {std::string (#NAME), \ + riscv_ext_info_t (#NAME, std::vector<riscv_implied_info_t> DEP_EXTS, \ + std::vector<riscv_version_t> SUPPORTED_VERSIONS, \ + std::vector<riscv_ext_flag_table_t> ( \ + {{&gcc_options::x_riscv_##FLAG_GROUP##_subext, \ + &cl_target_option::x_riscv_##FLAG_GROUP##_subext, \ + MASK_##UPPERCAE_NAME}}), \ + BITMASK_GROUP_ID, BITMASK_BIT_POSITION, \ + EXTRA_EXTENSION_FLAGS)}, +#include "../../../config/riscv/riscv-ext.def" +#undef DEFINE_RISCV_EXT +}; + +static const riscv_ext_info_t & +get_riscv_ext_info (const char * ext) +{ + auto itr = riscv_ext_infos.find (ext); + if (itr == riscv_ext_infos.end ()) + { + gcc_unreachable (); + } + return itr->second; +} + +/* Return true if any change. */ +bool +riscv_ext_info_t::apply_implied_ext (riscv_subset_list *subset_list) const +{ + bool any_change = false; + for (const riscv_implied_info_t &implied_info : m_implied_exts) + { + /* Skip if implied extension already present. */ + if (subset_list->lookup (implied_info.implied_ext)) + continue; + + any_change = true; + if (!implied_info.match (subset_list)) + continue; + + /* Version of implied extension will get from current ISA spec + version. */ + subset_list->add (implied_info.implied_ext, true); + + /* Recursively add implied extension by implied_info->implied_ext. */ + const riscv_ext_info_t &implied_ext_info + = get_riscv_ext_info (implied_info.implied_ext); + implied_ext_info.apply_implied_ext (subset_list); + } + return any_change; +} + /* This structure holds version information for specific ISA version. */ struct riscv_ext_version @@ -280,234 +268,6 @@ struct riscv_profiles const char *profile_string; }; -/* All standard extensions defined in all supported ISA spec. */ -static const struct riscv_ext_version riscv_ext_version_table[] = -{ - /* name, ISA spec, major version, minor_version. */ - {"e", ISA_SPEC_CLASS_20191213, 2, 0}, - {"e", ISA_SPEC_CLASS_20190608, 2, 0}, - {"e", ISA_SPEC_CLASS_2P2, 2, 0}, - - {"i", ISA_SPEC_CLASS_20191213, 2, 1}, - {"i", ISA_SPEC_CLASS_20190608, 2, 1}, - {"i", ISA_SPEC_CLASS_2P2, 2, 0}, - - {"m", ISA_SPEC_CLASS_20191213, 2, 0}, - {"m", ISA_SPEC_CLASS_20190608, 2, 0}, - {"m", ISA_SPEC_CLASS_2P2, 2, 0}, - - {"a", ISA_SPEC_CLASS_20191213, 2, 1}, - {"a", ISA_SPEC_CLASS_20190608, 2, 0}, - {"a", ISA_SPEC_CLASS_2P2, 2, 0}, - - {"f", ISA_SPEC_CLASS_20191213, 2, 2}, - {"f", ISA_SPEC_CLASS_20190608, 2, 2}, - {"f", ISA_SPEC_CLASS_2P2, 2, 0}, - - {"d", ISA_SPEC_CLASS_20191213, 2, 2}, - {"d", ISA_SPEC_CLASS_20190608, 2, 2}, - {"d", ISA_SPEC_CLASS_2P2, 2, 0}, - - {"c", ISA_SPEC_CLASS_20191213, 2, 0}, - {"c", ISA_SPEC_CLASS_20190608, 2, 0}, - {"c", ISA_SPEC_CLASS_2P2, 2, 0}, - - {"b", ISA_SPEC_CLASS_NONE, 1, 0}, - - {"h", ISA_SPEC_CLASS_NONE, 1, 0}, - - {"v", ISA_SPEC_CLASS_NONE, 1, 0}, - - {"zicsr", ISA_SPEC_CLASS_20191213, 2, 0}, - {"zicsr", ISA_SPEC_CLASS_20190608, 2, 0}, - - {"zifencei", ISA_SPEC_CLASS_20191213, 2, 0}, - {"zifencei", ISA_SPEC_CLASS_20190608, 2, 0}, - - {"zicond", ISA_SPEC_CLASS_NONE, 1, 0}, - - {"za64rs", ISA_SPEC_CLASS_NONE, 1, 0}, - {"za128rs", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zawrs", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zaamo", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zalrsc", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zabha", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zacas", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zama16b", ISA_SPEC_CLASS_NONE, 1, 0}, - - {"zba", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zbb", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zbc", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zbs", ISA_SPEC_CLASS_NONE, 1, 0}, - - {"zfinx", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zdinx", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zhinx", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zhinxmin", ISA_SPEC_CLASS_NONE, 1, 0}, - - {"zbkb", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zbkc", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zbkx", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zkne", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zknd", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zknh", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zkr", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zksed", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zksh", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zkt", ISA_SPEC_CLASS_NONE, 1, 0}, - - {"zihintntl", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zihintpause", ISA_SPEC_CLASS_NONE, 2, 0}, - - {"zicboz",ISA_SPEC_CLASS_NONE, 1, 0}, - {"zicbom",ISA_SPEC_CLASS_NONE, 1, 0}, - {"zicbop",ISA_SPEC_CLASS_NONE, 1, 0}, - {"zic64b", ISA_SPEC_CLASS_NONE, 1, 0}, - {"ziccamoa", ISA_SPEC_CLASS_NONE, 1, 0}, - {"ziccif", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zicclsm", ISA_SPEC_CLASS_NONE, 1, 0}, - {"ziccrse", ISA_SPEC_CLASS_NONE, 1, 0}, - - {"zicfiss", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zicfilp", ISA_SPEC_CLASS_NONE, 1, 0}, - - {"zimop", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zcmop", ISA_SPEC_CLASS_NONE, 1, 0}, - - {"zicntr", ISA_SPEC_CLASS_NONE, 2, 0}, - {"zihpm", ISA_SPEC_CLASS_NONE, 2, 0}, - - {"zk", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zkn", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zks", ISA_SPEC_CLASS_NONE, 1, 0}, - - {"ztso", ISA_SPEC_CLASS_NONE, 1, 0}, - - {"zve32x", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zve32f", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zve64x", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zve64f", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zve64d", ISA_SPEC_CLASS_NONE, 1, 0}, - - {"zvbb", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zvbc", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zvkb", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zvkg", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zvkned", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zvknha", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zvknhb", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zvksed", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zvksh", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zvkn", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zvknc", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zvkng", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zvks", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zvksc", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zvksg", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zvkt", ISA_SPEC_CLASS_NONE, 1, 0}, - - {"zvl32b", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zvl64b", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zvl128b", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zvl256b", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zvl512b", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zvl1024b", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zvl2048b", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zvl4096b", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zvl8192b", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zvl16384b", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zvl32768b", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zvl65536b", ISA_SPEC_CLASS_NONE, 1, 0}, - - {"zfbfmin", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zfh", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zfhmin", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zvfbfmin", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zvfbfwma", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zvfhmin", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zvfh", ISA_SPEC_CLASS_NONE, 1, 0}, - - {"zfa", ISA_SPEC_CLASS_NONE, 1, 0}, - - {"zmmul", ISA_SPEC_CLASS_NONE, 1, 0}, - - {"zca", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zcb", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zce", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zcf", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zcd", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zcmp", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zcmt", ISA_SPEC_CLASS_NONE, 1, 0}, - - {"sdtrig", ISA_SPEC_CLASS_NONE, 1, 0}, - - {"smaia", ISA_SPEC_CLASS_NONE, 1, 0}, - {"smepmp", ISA_SPEC_CLASS_NONE, 1, 0}, - {"smstateen", ISA_SPEC_CLASS_NONE, 1, 0}, - - {"ssaia", ISA_SPEC_CLASS_NONE, 1, 0}, - {"sscofpmf", ISA_SPEC_CLASS_NONE, 1, 0}, - {"ssstateen", ISA_SPEC_CLASS_NONE, 1, 0}, - {"sstc", ISA_SPEC_CLASS_NONE, 1, 0}, - {"ssstrict", ISA_SPEC_CLASS_NONE, 1, 0}, - - {"svade", ISA_SPEC_CLASS_NONE, 1, 0}, - {"svadu", ISA_SPEC_CLASS_NONE, 1, 0}, - {"svinval", ISA_SPEC_CLASS_NONE, 1, 0}, - {"svnapot", ISA_SPEC_CLASS_NONE, 1, 0}, - {"svpbmt", ISA_SPEC_CLASS_NONE, 1, 0}, - {"svvptc", ISA_SPEC_CLASS_NONE, 1, 0}, - - {"xcvmac", ISA_SPEC_CLASS_NONE, 1, 0}, - {"xcvalu", ISA_SPEC_CLASS_NONE, 1, 0}, - {"xcvelw", ISA_SPEC_CLASS_NONE, 1, 0}, - {"xcvsimd", ISA_SPEC_CLASS_NONE, 1, 0}, - {"xcvbi", ISA_SPEC_CLASS_NONE, 1, 0}, - - {"xtheadba", ISA_SPEC_CLASS_NONE, 1, 0}, - {"xtheadbb", ISA_SPEC_CLASS_NONE, 1, 0}, - {"xtheadbs", ISA_SPEC_CLASS_NONE, 1, 0}, - {"xtheadcmo", ISA_SPEC_CLASS_NONE, 1, 0}, - {"xtheadcondmov", ISA_SPEC_CLASS_NONE, 1, 0}, - {"xtheadfmemidx", ISA_SPEC_CLASS_NONE, 1, 0}, - {"xtheadfmv", ISA_SPEC_CLASS_NONE, 1, 0}, - {"xtheadint", ISA_SPEC_CLASS_NONE, 1, 0}, - {"xtheadmac", ISA_SPEC_CLASS_NONE, 1, 0}, - {"xtheadmemidx", ISA_SPEC_CLASS_NONE, 1, 0}, - {"xtheadmempair", ISA_SPEC_CLASS_NONE, 1, 0}, - {"xtheadsync", ISA_SPEC_CLASS_NONE, 1, 0}, - {"xtheadvector", ISA_SPEC_CLASS_NONE, 1, 0}, - - {"xventanacondops", ISA_SPEC_CLASS_NONE, 1, 0}, - - {"xsfvcp", ISA_SPEC_CLASS_NONE, 1, 0}, - {"xsfcease", ISA_SPEC_CLASS_NONE, 1, 0}, - {"xsfvqmaccqoq", ISA_SPEC_CLASS_NONE, 1, 0}, - {"xsfvqmaccdod", ISA_SPEC_CLASS_NONE, 1, 0}, - {"xsfvfnrclipxfqf", ISA_SPEC_CLASS_NONE, 1, 0}, - - /* Terminate the list. */ - {NULL, ISA_SPEC_CLASS_NONE, 0, 0} -}; - -/* Combine extensions defined in this table */ -static const struct riscv_ext_version riscv_combine_info[] = -{ - {"a", ISA_SPEC_CLASS_20191213, 2, 1}, - {"b", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zk", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zkn", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zks", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zvkn", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zvknc", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zvkng", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zvks", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zvksc", ISA_SPEC_CLASS_NONE, 1, 0}, - {"zvksg", ISA_SPEC_CLASS_NONE, 1, 0}, - /* Terminate the list. */ - {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[] = { @@ -530,20 +290,36 @@ static const riscv_profiles riscv_profiles_table[] = /* RVA23 contains all mandatory base ISA for RVA22U64 and the new extension 'v,zihintntl,zvfhmin,zvbb,zvkt,zicond,zimop,zcmop,zfa,zawrs' as mandatory extensions. */ - {"rva23u64", "rv64imafdcv_zicsr_zicntr_zihpm_ziccif_ziccrse_ziccamoa" + {"rva23u64", "rv64imafdcbv_zicsr_zicntr_zihpm_ziccif_ziccrse_ziccamoa" "_zicclsm_zic64b_za64rs_zihintpause_zba_zbb_zbs_zicbom_zicbop" "_zicboz_zfhmin_zkt_zvfhmin_zvbb_zvkt_zihintntl_zicond_zimop_zcmop_zcb" - "_zfa_zawrs"}, + "_zfa_zawrs_supm"}, + + /* RVA23S contains all mandatory base ISA for RVA23U64 and the privileged + extensions as mandatory extensions. */ + {"rva23s64", "rv64imafdcbv_zicsr_zicntr_zihpm_ziccif_ziccrse_ziccamoa" + "_zicclsm_zic64b_za64rs_zihintpause_zba_zbb_zbs_zicbom_zicbop" + "_zicboz_zfhmin_zkt_zvfhmin_zvbb_zvkt_zihintntl_zicond_zimop_zcmop_zcb" + "_zfa_zawrs_svbare_svade_ssccptr_sstvecd_sstvala_sscounterenw_svpbmt" + "_svinval_svnapot_sstc_sscofpmf_ssnpm_ssu64xl_sha_supm" + }, /* RVB23 contains all mandatory base ISA for RVA22U64 and the new extension 'zihintntl,zicond,zimop,zcmop,zfa,zawrs' as mandatory extensions. */ - {"rvb23u64", "rv64imafdc_zicsr_zicntr_zihpm_ziccif_ziccrse_ziccamoa" + {"rvb23u64", "rv64imafdcb_zicsr_zicntr_zihpm_ziccif_ziccrse_ziccamoa" "_zicclsm_zic64b_za64rs_zihintpause_zba_zbb_zbs_zicbom_zicbop" "_zicboz_zfhmin_zkt_zihintntl_zicond_zimop_zcmop_zcb" "_zfa_zawrs"}, - /* Currently we do not define S/M mode Profiles in gcc part. */ + /* RVB23S contains all mandatory base ISA for RVB23U64 and the privileged + extensions as mandatory extensions. */ + {"rvb23s64", "rv64imafdcb_zicsr_zicntr_zihpm_ziccif_ziccrse_ziccamoa" + "_zicclsm_zic64b_za64rs_zihintpause_zba_zbb_zbs_zicbom_zicbop" + "_zicboz_zfhmin_zkt_zvfhmin_zvbb_zvkt_zihintntl_zicond_zimop_zcmop_zcb" + "_zfa_zawrs_svbare_svade_ssccptr_sstvecd_sstvala_sscounterenw_svpbmt" + "_svinval_svnapot_sstc_sscofpmf_ssu64xl_supm" + }, /* Terminate the list. */ {NULL, NULL} @@ -602,9 +378,9 @@ riscv_subset_t::riscv_subset_t () { } -riscv_subset_list::riscv_subset_list (const char *arch, location_t loc) +riscv_subset_list::riscv_subset_list (const char *arch, location_t *loc) : m_arch (arch), m_loc (loc), m_head (NULL), m_tail (NULL), m_xlen (0), - m_subset_num (0) + m_subset_num (0), m_allow_adding_dup (false) { } @@ -782,11 +558,8 @@ subset_cmp (const std::string &a, const std::string &b) static bool standard_extensions_p (const char *ext) { - const riscv_ext_version *ext_ver; - for (ext_ver = &riscv_ext_version_table[0]; ext_ver->name != NULL; ++ext_ver) - if (strcmp (ext, ext_ver->name) == 0) - return true; - return false; + auto itr = riscv_ext_infos.find (ext); + return itr != riscv_ext_infos.end (); } /* Add new subset to list. */ @@ -811,47 +584,49 @@ riscv_subset_list::add (const char *subset, int major_version, else { /* The extension is already in the list. */ - if (!m_allow_adding_dup - || ext->major_version != major_version - || ext->minor_version != minor_version) - error_at ( - m_loc, - "%<-march=%s%>: extension %qs appear more than one time", - m_arch, - subset); + if (m_loc + && (!m_allow_adding_dup + || ext->major_version != major_version + || ext->minor_version != minor_version)) + error_at (*m_loc, "%<-march=%s%>: extension %qs appear more " + "than one time", m_arch, subset); } return; } else if (strlen (subset) == 1 && !standard_extensions_p (subset)) { - error_at (m_loc, - "%<-march=%s%>: extension %qs is unsupported standard single " - "letter extension", - m_arch, subset); + if (m_loc) + error_at (*m_loc, + "%<-march=%s%>: extension %qs is unsupported standard " + "single letter extension", + m_arch, subset); return; } else if (subset[0] == 'z' && !standard_extensions_p (subset)) { - error_at (m_loc, - "%<-march=%s%>: extension %qs starts with 'z' but is " - "unsupported standard extension", - m_arch, subset); + if (m_loc) + error_at (*m_loc, + "%<-march=%s%>: extension %qs starts with 'z' but is " + "unsupported standard extension", + m_arch, subset); return; } else if (subset[0] == 's' && !standard_extensions_p (subset)) { - error_at (m_loc, - "%<-march=%s%>: extension %qs starts with 's' but is " - "unsupported standard supervisor extension", - m_arch, subset); + if (m_loc) + error_at (*m_loc, + "%<-march=%s%>: extension %qs starts with 's' but is " + "unsupported standard supervisor extension", + m_arch, subset); return; } else if (subset[0] == 'x' && !standard_extensions_p (subset)) { - error_at (m_loc, - "%<-march=%s%>: extension %qs starts with 'x' but is " - "unsupported non-standard extension", - m_arch, subset); + if (m_loc) + error_at (*m_loc, + "%<-march=%s%>: extension %qs starts with 'x' but is " + "unsupported non-standard extension", + m_arch, subset); return; } @@ -916,24 +691,19 @@ get_default_version (const char *ext, unsigned int *major_version, unsigned int *minor_version) { - const riscv_ext_version *ext_ver; - for (ext_ver = &riscv_ext_version_table[0]; - ext_ver->name != NULL; - ++ext_ver) - if (strcmp (ext, ext_ver->name) == 0) - { - if ((ext_ver->isa_spec_class == riscv_isa_spec) || - (ext_ver->isa_spec_class == ISA_SPEC_CLASS_NONE)) - { - *major_version = ext_ver->major_version; - *minor_version = ext_ver->minor_version; - return; - } - } + auto itr = riscv_ext_infos.find (ext); + if (itr == riscv_ext_infos.end ()) + { + /* Not found version info. */ + *major_version = 0; + *minor_version = 0; + return; + } - /* Not found version info. */ - *major_version = 0; - *minor_version = 0; + riscv_version_t ver = itr->second.default_version (); + /* Get the version info from riscv_ext_infos. */ + *major_version = ver.major_version; + *minor_version = ver.minor_version; } /* Add new subset to list, but using default version from ISA spec version. */ @@ -1118,15 +888,17 @@ riscv_subset_list::parsing_subset_version (const char *ext, { if (!ISDIGIT (*(p+1))) { - error_at (m_loc, "%<-march=%s%>: expect number " - "after %<%dp%>", m_arch, version); + if (m_loc) + error_at (*m_loc, "%<-march=%s%>: expect number " + "after %<%dp%>", m_arch, version); return NULL; } if (!major_p) { - error_at (m_loc, "%<-march=%s%>: for %<%s%dp%dp?%>, version " - "number with more than 2 level is not supported", - m_arch, ext, major, version); + if (m_loc) + error_at (*m_loc, "%<-march=%s%>: for %<%s%dp%dp?%>, " + "version number with more than 2 level is not " + "supported", m_arch, ext, major, version); return NULL; } major = version; @@ -1189,8 +961,9 @@ riscv_subset_list::parse_profiles (const char *arch) /* 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", '_'); + if (m_loc) + warning_at (*m_loc, 0, "Should use \"%c\" to contact Profiles " + "with other extensions", '_'); return p_str + "_" + after_part; } @@ -1228,8 +1001,10 @@ riscv_subset_list::parse_base_ext (const char *p) } else { - error_at (m_loc, "%<-march=%s%>: ISA string must begin with rv32, rv64 " - "or Profiles", m_arch); + if (m_loc) + error_at (*m_loc, "%<-march=%s%>: ISA string must begin with rv32, " + "rv64, a supported RVA profile or refer to a supported CPU", + m_arch); return NULL; } @@ -1252,8 +1027,9 @@ riscv_subset_list::parse_base_ext (const char *p) if (m_xlen > 64) { - error_at (m_loc, "%<-march=%s%>: rv%de is not a valid base ISA", - m_arch, m_xlen); + if (m_loc) + error_at (*m_loc, "%<-march=%s%>: rv%de is not a valid base ISA", + m_arch, m_xlen); return NULL; } break; @@ -1264,8 +1040,9 @@ riscv_subset_list::parse_base_ext (const char *p) /* std_ext_p= */ true, &explicit_version_p); if (major_version != 0 || minor_version != 0) { - warning_at (m_loc, 0, "version of %<g%> will be omitted, please " - "specify version for individual extension"); + if (m_loc) + warning_at (*m_loc, 0, "version of %<g%> will be omitted, please " + "specify version for individual extension"); } /* We have special rule for G, we disallow rv32gm2p but allow rv32g_zicsr @@ -1283,8 +1060,9 @@ riscv_subset_list::parse_base_ext (const char *p) break; default: - error_at (m_loc, "%<-march=%s%>: first ISA subset must be %<e%>, " - "%<i%> or %<g%>", m_arch); + if (m_loc) + error_at (*m_loc, "%<-march=%s%>: first ISA subset must be %<e%>, " + "%<i%> or %<g%>", m_arch); return NULL; } return p; @@ -1305,10 +1083,9 @@ riscv_subset_list::parse_single_std_ext (const char *p, bool exact_single_p) { if (*p == 'x' || *p == 's' || *p == 'z') { - error_at (m_loc, - "%<-march=%s%>: Not single-letter extension. " - "%<%c%>", - m_arch, *p); + if (m_loc) + error_at (*m_loc, "%<-march=%s%>: Not single-letter extension. %<%c%>", + m_arch, *p); return nullptr; } @@ -1337,25 +1114,8 @@ riscv_subset_list::parse_single_std_ext (const char *p, bool exact_single_p) void riscv_subset_list::handle_implied_ext (const char *ext) { - const riscv_implied_info_t *implied_info; - for (implied_info = &riscv_implied_info[0]; - implied_info->ext; - ++implied_info) - { - if (!implied_info->match (this, ext)) - continue; - - /* Skip if implied extension already present. */ - if (lookup (implied_info->implied_ext)) - continue; - - /* Version of implied extension will get from current ISA spec - version. */ - add (implied_info->implied_ext, true); - - /* Recursively add implied extension by implied_info->implied_ext. */ - handle_implied_ext (implied_info->implied_ext); - } + const riscv_ext_info_t &ext_info = get_riscv_ext_info (ext); + ext_info.apply_implied_ext (this); /* For RISC-V ISA version 2.2 or earlier version, zicsr and zifence is included in the base ISA. */ @@ -1376,14 +1136,13 @@ riscv_subset_list::check_implied_ext () riscv_subset_t *itr; for (itr = m_head; itr != NULL; itr = itr->next) { - const riscv_implied_info_t *implied_info; - for (implied_info = &riscv_implied_info[0]; implied_info->ext; - ++implied_info) + auto &ext = *itr; + auto &ext_info = get_riscv_ext_info (ext.name.c_str ()); + for (auto &implied_ext : ext_info.implied_exts ()) { - if (!implied_info->match (this, itr)) + if (!implied_ext.match (this)) continue; - - if (!lookup (implied_info->implied_ext)) + if (lookup (implied_ext.implied_ext) == NULL) return false; } } @@ -1394,27 +1153,25 @@ riscv_subset_list::check_implied_ext () void riscv_subset_list::handle_combine_ext () { - const riscv_ext_version *combine_info; - const riscv_implied_info_t *implied_info; - bool is_combined = false; - - for (combine_info = &riscv_combine_info[0]; combine_info->name; - ++combine_info) + for (const auto &pair : riscv_ext_infos) { - /* Skip if combine extensions are present */ - if (lookup (combine_info->name)) + const std::string &ext_name = pair.first; + auto &ext_info = pair.second; + bool is_combined = true; + /* Skip if this extension don't need to combine. */ + if (!ext_info.need_combine_p ()) + continue; + /* Skip if combine extensions are present. */ + if (lookup (ext_name.c_str ())) continue; - /* Find all extensions of the combine extension */ - for (implied_info = &riscv_implied_info[0]; implied_info->ext; - ++implied_info) + /* Check all implied extensions is present. */ + for (const auto &implied_ext : ext_info.implied_exts ()) { - if (!implied_info->match (this, combine_info->name)) + if (!implied_ext.match (this)) continue; - if (lookup (implied_info->implied_ext)) - is_combined = true; - else + if (!lookup (implied_ext.implied_ext)) { is_combined = false; break; @@ -1424,11 +1181,9 @@ riscv_subset_list::handle_combine_ext () /* Add combine extensions */ if (is_combined) { - if (lookup (combine_info->name) == NULL) - { - add (combine_info->name, combine_info->major_version, - combine_info->minor_version, false, true); - } + riscv_version_t ver = ext_info.default_version(); + add (ext_name.c_str (), ver.major_version, + ver.minor_version, false, true); } } } @@ -1436,26 +1191,58 @@ riscv_subset_list::handle_combine_ext () void riscv_subset_list::check_conflict_ext () { + if (!m_loc) + return; + if (lookup ("zcf") && m_xlen == 64) - error_at (m_loc, "%<-march=%s%>: zcf extension supports in rv32 only", + error_at (*m_loc, "%<-march=%s%>: zcf extension supports in rv32 only", + m_arch); + + if (lookup ("zilsd") && m_xlen == 64) + error_at (*m_loc, "%<-march=%s%>: zilsd extension supports in rv32 only", + m_arch); + + if (lookup ("zclsd") && m_xlen == 64) + error_at (*m_loc, "%<-march=%s%>: zclsd extension supports in rv32 only", + m_arch); + + if (lookup ("ssnpm") && m_xlen == 32) + error_at (*m_loc, "%<-march=%s%>: ssnpm extension supports in rv64 only", + m_arch); + + if (lookup ("smnpm") && m_xlen == 32) + error_at (*m_loc, "%<-march=%s%>: smnpm extension supports in rv64 only", + m_arch); + + if (lookup ("smmpm") && m_xlen == 32) + error_at (*m_loc, "%<-march=%s%>: smmpm extension supports in rv64 only", + m_arch); + + if (lookup ("sspm") && m_xlen == 32) + error_at (*m_loc, "%<-march=%s%>: sspm extension supports in rv64 only", + m_arch); + + if (lookup ("supm") && m_xlen == 32) + error_at (*m_loc, "%<-march=%s%>: supm extension supports in rv64 only", m_arch); if (lookup ("zfinx") && lookup ("f")) - error_at (m_loc, + error_at (*m_loc, "%<-march=%s%>: z*inx conflicts with floating-point " "extensions", m_arch); /* 'H' hypervisor extension requires base ISA with 32 registers. */ if (lookup ("e") && lookup ("h")) - error_at (m_loc, "%<-march=%s%>: h extension requires i extension", m_arch); + error_at (*m_loc, "%<-march=%s%>: h extension requires i extension", + m_arch); if (lookup ("zcd")) { if (lookup ("zcmt")) - error_at (m_loc, "%<-march=%s%>: zcd conflicts with zcmt", m_arch); + error_at (*m_loc, "%<-march=%s%>: zcd conflicts with zcmt", m_arch); if (lookup ("zcmp")) - error_at (m_loc, "%<-march=%s%>: zcd conflicts with zcmp", m_arch); + error_at (*m_loc, "%<-march=%s%>: zcd conflicts with zcmp", m_arch); } if ((lookup ("v") || lookup ("zve32x") @@ -1463,9 +1250,9 @@ riscv_subset_list::check_conflict_ext () || lookup ("zve64f") || lookup ("zve64d") || lookup ("zvl32b") || lookup ("zvl64b") || lookup ("zvl128b") || lookup ("zvfh")) - && lookup ("xtheadvector")) - error_at (m_loc, "%<-march=%s%>: xtheadvector conflicts with vector " - "extension or its sub-extensions", m_arch); + && lookup ("xtheadvector")) + error_at (*m_loc, "%<-march=%s%>: xtheadvector conflicts with vector " + "extension or its sub-extensions", m_arch); } /* Parsing function for multi-letter extensions. @@ -1561,8 +1348,9 @@ riscv_subset_list::parse_single_multiletter_ext (const char *p, if (strlen (subset) == 1) { - error_at (m_loc, "%<-march=%s%>: name of %s must be more than 1 letter", - m_arch, ext_type_str); + if (m_loc) + error_at (*m_loc, "%<-march=%s%>: name of %s must be more " + "than 1 letter", m_arch, ext_type_str); free (subset); return NULL; } @@ -1573,8 +1361,9 @@ riscv_subset_list::parse_single_multiletter_ext (const char *p, if (*p != '\0' && *p != '_') { - error_at (m_loc, "%<-march=%s%>: %s must separate with %<_%>", - m_arch, ext_type_str); + if (m_loc) + error_at (*m_loc, "%<-march=%s%>: %s must separate with %<_%>", + m_arch, ext_type_str); return NULL; } @@ -1611,10 +1400,12 @@ riscv_subset_list::parse_single_ext (const char *p, bool exact_single_p) } } -/* Parsing arch string to subset list, return NULL if parsing failed. */ +/* Parsing arch string to subset list, return NULL if parsing failed. + If LOC is nonnull, report diagnostics against location *LOC, otherwise + remain silent. */ riscv_subset_list * -riscv_subset_list::parse (const char *arch, location_t loc) +riscv_subset_list::parse (const char *arch, location_t *loc) { if (riscv_subset_list::parse_failed) return NULL; @@ -1637,8 +1428,9 @@ riscv_subset_list::parse (const char *arch, location_t loc) case 'e': case 'i': case 'g': - error_at (loc, "%<-march=%s%>: i, e or g must be the first extension", - arch); + if (loc) + error_at (*loc, "%<-march=%s%>: i, e or g must be " + "the first extension", arch); goto fail; default: p = subset_list->parse_single_ext (p, /*exact_single_p=*/ false); @@ -1673,7 +1465,7 @@ riscv_subset_list::clone () const } void -riscv_subset_list::set_loc (location_t loc) +riscv_subset_list::set_loc (location_t *loc) { m_loc = loc; } @@ -1715,90 +1507,15 @@ riscv_arch_str (bool version_p) return std::string(); } -/* Type for pointer to member of gcc_options and cl_target_option. */ -typedef int (gcc_options::*opt_var_ref_t); -typedef int (cl_target_option::*cl_opt_var_ref_t); - -/* Types for recording extension to internal flag. */ -struct riscv_ext_flag_table_t { - const char *ext; - opt_var_ref_t var_ref; - cl_opt_var_ref_t cl_var_ref; - int mask; -}; - #define RISCV_EXT_FLAG_ENTRY(NAME, VAR, MASK) \ {NAME, &gcc_options::VAR, &cl_target_option::VAR, MASK} -/* Mapping table between extension to internal flag. */ -static const riscv_ext_flag_table_t riscv_ext_flag_table[] = -{ - RISCV_EXT_FLAG_ENTRY ("e", x_target_flags, MASK_RVE), - RISCV_EXT_FLAG_ENTRY ("m", x_target_flags, MASK_MUL), - RISCV_EXT_FLAG_ENTRY ("a", x_target_flags, MASK_ATOMIC), - RISCV_EXT_FLAG_ENTRY ("f", x_target_flags, MASK_HARD_FLOAT), - RISCV_EXT_FLAG_ENTRY ("d", x_target_flags, MASK_DOUBLE_FLOAT), - RISCV_EXT_FLAG_ENTRY ("c", x_target_flags, MASK_RVC), - RISCV_EXT_FLAG_ENTRY ("v", x_target_flags, MASK_FULL_V), - RISCV_EXT_FLAG_ENTRY ("v", x_target_flags, MASK_VECTOR), - - RISCV_EXT_FLAG_ENTRY ("zicsr", x_riscv_zi_subext, MASK_ZICSR), - RISCV_EXT_FLAG_ENTRY ("zifencei", x_riscv_zi_subext, MASK_ZIFENCEI), - RISCV_EXT_FLAG_ENTRY ("zicond", x_riscv_zi_subext, MASK_ZICOND), - - RISCV_EXT_FLAG_ENTRY ("za64rs", x_riscv_za_subext, MASK_ZA64RS), - RISCV_EXT_FLAG_ENTRY ("za128rs", x_riscv_za_subext, MASK_ZA128RS), - RISCV_EXT_FLAG_ENTRY ("zawrs", x_riscv_za_subext, MASK_ZAWRS), - RISCV_EXT_FLAG_ENTRY ("zaamo", x_riscv_za_subext, MASK_ZAAMO), - RISCV_EXT_FLAG_ENTRY ("zalrsc", x_riscv_za_subext, MASK_ZALRSC), - RISCV_EXT_FLAG_ENTRY ("zabha", x_riscv_za_subext, MASK_ZABHA), - RISCV_EXT_FLAG_ENTRY ("zacas", x_riscv_za_subext, MASK_ZACAS), - RISCV_EXT_FLAG_ENTRY ("zama16b", x_riscv_za_subext, MASK_ZAMA16B), - - RISCV_EXT_FLAG_ENTRY ("zba", x_riscv_zb_subext, MASK_ZBA), - RISCV_EXT_FLAG_ENTRY ("zbb", x_riscv_zb_subext, MASK_ZBB), - RISCV_EXT_FLAG_ENTRY ("zbc", x_riscv_zb_subext, MASK_ZBC), - RISCV_EXT_FLAG_ENTRY ("zbs", x_riscv_zb_subext, MASK_ZBS), - - RISCV_EXT_FLAG_ENTRY ("zfinx", x_riscv_zinx_subext, MASK_ZFINX), - RISCV_EXT_FLAG_ENTRY ("zdinx", x_riscv_zinx_subext, MASK_ZDINX), - RISCV_EXT_FLAG_ENTRY ("zhinx", x_riscv_zinx_subext, MASK_ZHINX), - RISCV_EXT_FLAG_ENTRY ("zhinxmin", x_riscv_zinx_subext, MASK_ZHINXMIN), - - RISCV_EXT_FLAG_ENTRY ("zbkb", x_riscv_zk_subext, MASK_ZBKB), - RISCV_EXT_FLAG_ENTRY ("zbkc", x_riscv_zk_subext, MASK_ZBKC), - RISCV_EXT_FLAG_ENTRY ("zbkx", x_riscv_zk_subext, MASK_ZBKX), - RISCV_EXT_FLAG_ENTRY ("zknd", x_riscv_zk_subext, MASK_ZKND), - RISCV_EXT_FLAG_ENTRY ("zkne", x_riscv_zk_subext, MASK_ZKNE), - RISCV_EXT_FLAG_ENTRY ("zknh", x_riscv_zk_subext, MASK_ZKNH), - RISCV_EXT_FLAG_ENTRY ("zkr", x_riscv_zk_subext, MASK_ZKR), - RISCV_EXT_FLAG_ENTRY ("zksed", x_riscv_zk_subext, MASK_ZKSED), - RISCV_EXT_FLAG_ENTRY ("zksh", x_riscv_zk_subext, MASK_ZKSH), - RISCV_EXT_FLAG_ENTRY ("zkt", x_riscv_zk_subext, MASK_ZKT), - - RISCV_EXT_FLAG_ENTRY ("zihintntl", x_riscv_zi_subext, MASK_ZIHINTNTL), - RISCV_EXT_FLAG_ENTRY ("zihintpause", x_riscv_zi_subext, MASK_ZIHINTPAUSE), - RISCV_EXT_FLAG_ENTRY ("ziccamoa", x_riscv_zi_subext, MASK_ZICCAMOA), - RISCV_EXT_FLAG_ENTRY ("ziccif", x_riscv_zi_subext, MASK_ZICCIF), - RISCV_EXT_FLAG_ENTRY ("zicclsm", x_riscv_zi_subext, MASK_ZICCLSM), - RISCV_EXT_FLAG_ENTRY ("ziccrse", x_riscv_zi_subext, MASK_ZICCRSE), - - RISCV_EXT_FLAG_ENTRY ("zicboz", x_riscv_zicmo_subext, MASK_ZICBOZ), - RISCV_EXT_FLAG_ENTRY ("zicbom", x_riscv_zicmo_subext, MASK_ZICBOM), - RISCV_EXT_FLAG_ENTRY ("zicbop", x_riscv_zicmo_subext, MASK_ZICBOP), - RISCV_EXT_FLAG_ENTRY ("zic64b", x_riscv_zicmo_subext, MASK_ZIC64B), - - RISCV_EXT_FLAG_ENTRY ("zicfiss", x_riscv_zi_subext, MASK_ZICFISS), - RISCV_EXT_FLAG_ENTRY ("zicfilp", x_riscv_zi_subext, MASK_ZICFILP), - - RISCV_EXT_FLAG_ENTRY ("zimop", x_riscv_mop_subext, MASK_ZIMOP), - RISCV_EXT_FLAG_ENTRY ("zcmop", x_riscv_mop_subext, MASK_ZCMOP), - - RISCV_EXT_FLAG_ENTRY ("zve32x", x_target_flags, MASK_VECTOR), - RISCV_EXT_FLAG_ENTRY ("zve32f", x_target_flags, MASK_VECTOR), - RISCV_EXT_FLAG_ENTRY ("zve64x", x_target_flags, MASK_VECTOR), - RISCV_EXT_FLAG_ENTRY ("zve64f", x_target_flags, MASK_VECTOR), - RISCV_EXT_FLAG_ENTRY ("zve64d", x_target_flags, MASK_VECTOR), +/* Mapping table between extension to internal flag, + this table is not needed to add manually unless there is speical rule. */ +static const riscv_extra_ext_flag_table_t riscv_extra_ext_flag_table[] = +{ + RISCV_EXT_FLAG_ENTRY ("zve32x", x_riscv_isa_flags, MASK_VECTOR), + RISCV_EXT_FLAG_ENTRY ("v", x_riscv_isa_flags, MASK_FULL_V), /* We don't need to put complete ELEN/ELEN_FP info here, due to the implication relation of vector extension. @@ -1815,108 +1532,40 @@ static const riscv_ext_flag_table_t riscv_ext_flag_table[] = RISCV_EXT_FLAG_ENTRY ("zvfhmin", x_riscv_vector_elen_flags, MASK_VECTOR_ELEN_FP_16), RISCV_EXT_FLAG_ENTRY ("zvfh", x_riscv_vector_elen_flags, MASK_VECTOR_ELEN_FP_16), - RISCV_EXT_FLAG_ENTRY ("zvbb", x_riscv_zvb_subext, MASK_ZVBB), - RISCV_EXT_FLAG_ENTRY ("zvbc", x_riscv_zvb_subext, MASK_ZVBC), - RISCV_EXT_FLAG_ENTRY ("zvkb", x_riscv_zvb_subext, MASK_ZVKB), - RISCV_EXT_FLAG_ENTRY ("zvkg", x_riscv_zvk_subext, MASK_ZVKG), - RISCV_EXT_FLAG_ENTRY ("zvkned", x_riscv_zvk_subext, MASK_ZVKNED), - RISCV_EXT_FLAG_ENTRY ("zvknha", x_riscv_zvk_subext, MASK_ZVKNHA), - RISCV_EXT_FLAG_ENTRY ("zvknhb", x_riscv_zvk_subext, MASK_ZVKNHB), - RISCV_EXT_FLAG_ENTRY ("zvksed", x_riscv_zvk_subext, MASK_ZVKSED), - RISCV_EXT_FLAG_ENTRY ("zvksh", x_riscv_zvk_subext, MASK_ZVKSH), - RISCV_EXT_FLAG_ENTRY ("zvkn", x_riscv_zvk_subext, MASK_ZVKN), - RISCV_EXT_FLAG_ENTRY ("zvknc", x_riscv_zvk_subext, MASK_ZVKNC), - RISCV_EXT_FLAG_ENTRY ("zvkng", x_riscv_zvk_subext, MASK_ZVKNG), - RISCV_EXT_FLAG_ENTRY ("zvks", x_riscv_zvk_subext, MASK_ZVKS), - RISCV_EXT_FLAG_ENTRY ("zvksc", x_riscv_zvk_subext, MASK_ZVKSC), - RISCV_EXT_FLAG_ENTRY ("zvksg", x_riscv_zvk_subext, MASK_ZVKSG), - RISCV_EXT_FLAG_ENTRY ("zvkt", x_riscv_zvk_subext, MASK_ZVKT), - - RISCV_EXT_FLAG_ENTRY ("zvl32b", x_riscv_zvl_flags, MASK_ZVL32B), - RISCV_EXT_FLAG_ENTRY ("zvl64b", x_riscv_zvl_flags, MASK_ZVL64B), - RISCV_EXT_FLAG_ENTRY ("zvl128b", x_riscv_zvl_flags, MASK_ZVL128B), - RISCV_EXT_FLAG_ENTRY ("zvl256b", x_riscv_zvl_flags, MASK_ZVL256B), - RISCV_EXT_FLAG_ENTRY ("zvl512b", x_riscv_zvl_flags, MASK_ZVL512B), - RISCV_EXT_FLAG_ENTRY ("zvl1024b", x_riscv_zvl_flags, MASK_ZVL1024B), - RISCV_EXT_FLAG_ENTRY ("zvl2048b", x_riscv_zvl_flags, MASK_ZVL2048B), - RISCV_EXT_FLAG_ENTRY ("zvl4096b", x_riscv_zvl_flags, MASK_ZVL4096B), - RISCV_EXT_FLAG_ENTRY ("zvl8192b", x_riscv_zvl_flags, MASK_ZVL8192B), - RISCV_EXT_FLAG_ENTRY ("zvl16384b", x_riscv_zvl_flags, MASK_ZVL16384B), - RISCV_EXT_FLAG_ENTRY ("zvl32768b", x_riscv_zvl_flags, MASK_ZVL32768B), - RISCV_EXT_FLAG_ENTRY ("zvl65536b", x_riscv_zvl_flags, MASK_ZVL65536B), - - RISCV_EXT_FLAG_ENTRY ("zfbfmin", x_riscv_zf_subext, MASK_ZFBFMIN), - RISCV_EXT_FLAG_ENTRY ("zfhmin", x_riscv_zf_subext, MASK_ZFHMIN), - RISCV_EXT_FLAG_ENTRY ("zfh", x_riscv_zf_subext, MASK_ZFH), - RISCV_EXT_FLAG_ENTRY ("zvfbfmin", x_riscv_zf_subext, MASK_ZVFBFMIN), - RISCV_EXT_FLAG_ENTRY ("zvfbfwma", x_riscv_zf_subext, MASK_ZVFBFWMA), - RISCV_EXT_FLAG_ENTRY ("zvfhmin", x_riscv_zf_subext, MASK_ZVFHMIN), - RISCV_EXT_FLAG_ENTRY ("zvfh", x_riscv_zf_subext, MASK_ZVFH), - - RISCV_EXT_FLAG_ENTRY ("zfa", x_riscv_zfa_subext, MASK_ZFA), - - RISCV_EXT_FLAG_ENTRY ("zmmul", x_riscv_zm_subext, MASK_ZMMUL), - - /* Code-size reduction extensions. */ - RISCV_EXT_FLAG_ENTRY ("zca", x_riscv_zc_subext, MASK_ZCA), - RISCV_EXT_FLAG_ENTRY ("zcb", x_riscv_zc_subext, MASK_ZCB), - RISCV_EXT_FLAG_ENTRY ("zce", x_riscv_zc_subext, MASK_ZCE), - RISCV_EXT_FLAG_ENTRY ("zcf", x_riscv_zc_subext, MASK_ZCF), - RISCV_EXT_FLAG_ENTRY ("zcd", x_riscv_zc_subext, MASK_ZCD), - RISCV_EXT_FLAG_ENTRY ("zcmp", x_riscv_zc_subext, MASK_ZCMP), - RISCV_EXT_FLAG_ENTRY ("zcmt", x_riscv_zc_subext, MASK_ZCMT), - - RISCV_EXT_FLAG_ENTRY ("svade", x_riscv_sv_subext, MASK_SVADE), - RISCV_EXT_FLAG_ENTRY ("svadu", x_riscv_sv_subext, MASK_SVADU), - RISCV_EXT_FLAG_ENTRY ("svinval", x_riscv_sv_subext, MASK_SVINVAL), - RISCV_EXT_FLAG_ENTRY ("svnapot", x_riscv_sv_subext, MASK_SVNAPOT), - RISCV_EXT_FLAG_ENTRY ("svvptc", x_riscv_sv_subext, MASK_SVVPTC), - - RISCV_EXT_FLAG_ENTRY ("ztso", x_riscv_ztso_subext, MASK_ZTSO), - - RISCV_EXT_FLAG_ENTRY ("xcvmac", x_riscv_xcv_subext, MASK_XCVMAC), - RISCV_EXT_FLAG_ENTRY ("xcvalu", x_riscv_xcv_subext, MASK_XCVALU), - RISCV_EXT_FLAG_ENTRY ("xcvelw", x_riscv_xcv_subext, MASK_XCVELW), - RISCV_EXT_FLAG_ENTRY ("xcvsimd", x_riscv_xcv_subext, MASK_XCVSIMD), - RISCV_EXT_FLAG_ENTRY ("xcvbi", x_riscv_xcv_subext, MASK_XCVBI), - - RISCV_EXT_FLAG_ENTRY ("xtheadba", x_riscv_xthead_subext, MASK_XTHEADBA), - RISCV_EXT_FLAG_ENTRY ("xtheadbb", x_riscv_xthead_subext, MASK_XTHEADBB), - RISCV_EXT_FLAG_ENTRY ("xtheadbs", x_riscv_xthead_subext, MASK_XTHEADBS), - RISCV_EXT_FLAG_ENTRY ("xtheadcmo", x_riscv_xthead_subext, MASK_XTHEADCMO), - RISCV_EXT_FLAG_ENTRY ("xtheadcondmov", x_riscv_xthead_subext, MASK_XTHEADCONDMOV), - RISCV_EXT_FLAG_ENTRY ("xtheadfmemidx", x_riscv_xthead_subext, MASK_XTHEADFMEMIDX), - RISCV_EXT_FLAG_ENTRY ("xtheadfmv", x_riscv_xthead_subext, MASK_XTHEADFMV), - RISCV_EXT_FLAG_ENTRY ("xtheadint", x_riscv_xthead_subext, MASK_XTHEADINT), - RISCV_EXT_FLAG_ENTRY ("xtheadmac", x_riscv_xthead_subext, MASK_XTHEADMAC), - RISCV_EXT_FLAG_ENTRY ("xtheadmemidx", x_riscv_xthead_subext, MASK_XTHEADMEMIDX), - RISCV_EXT_FLAG_ENTRY ("xtheadmempair", x_riscv_xthead_subext, MASK_XTHEADMEMPAIR), - RISCV_EXT_FLAG_ENTRY ("xtheadsync", x_riscv_xthead_subext, MASK_XTHEADSYNC), - RISCV_EXT_FLAG_ENTRY ("xtheadvector", x_riscv_xthead_subext, MASK_XTHEADVECTOR), RISCV_EXT_FLAG_ENTRY ("xtheadvector", x_riscv_vector_elen_flags, MASK_VECTOR_ELEN_32), RISCV_EXT_FLAG_ENTRY ("xtheadvector", x_riscv_vector_elen_flags, MASK_VECTOR_ELEN_64), RISCV_EXT_FLAG_ENTRY ("xtheadvector", x_riscv_vector_elen_flags, MASK_VECTOR_ELEN_FP_32), RISCV_EXT_FLAG_ENTRY ("xtheadvector", x_riscv_vector_elen_flags, MASK_VECTOR_ELEN_FP_64), RISCV_EXT_FLAG_ENTRY ("xtheadvector", x_riscv_vector_elen_flags, MASK_VECTOR_ELEN_FP_16), - RISCV_EXT_FLAG_ENTRY ("xtheadvector", x_riscv_zvl_flags, MASK_ZVL32B), - RISCV_EXT_FLAG_ENTRY ("xtheadvector", x_riscv_zvl_flags, MASK_ZVL64B), - RISCV_EXT_FLAG_ENTRY ("xtheadvector", x_riscv_zvl_flags, MASK_ZVL128B), - RISCV_EXT_FLAG_ENTRY ("xtheadvector", x_riscv_zf_subext, MASK_ZVFHMIN), - RISCV_EXT_FLAG_ENTRY ("xtheadvector", x_riscv_zf_subext, MASK_ZVFH), - RISCV_EXT_FLAG_ENTRY ("xtheadvector", x_target_flags, MASK_FULL_V), - RISCV_EXT_FLAG_ENTRY ("xtheadvector", x_target_flags, MASK_VECTOR), - - RISCV_EXT_FLAG_ENTRY ("xventanacondops", x_riscv_xventana_subext, MASK_XVENTANACONDOPS), - - RISCV_EXT_FLAG_ENTRY ("xsfvcp", x_riscv_sifive_subext, MASK_XSFVCP), - RISCV_EXT_FLAG_ENTRY ("xsfcease", x_riscv_sifive_subext, MASK_XSFCEASE), - RISCV_EXT_FLAG_ENTRY ("xsfvqmaccqoq", x_riscv_sifive_subext, MASK_XSFVQMACCQOQ), - RISCV_EXT_FLAG_ENTRY ("xsfvqmaccdod", x_riscv_sifive_subext, MASK_XSFVQMACCDOD), - RISCV_EXT_FLAG_ENTRY ("xsfvfnrclipxfqf", x_riscv_sifive_subext, MASK_XSFVFNRCLIPXFQF), + RISCV_EXT_FLAG_ENTRY ("xtheadvector", x_riscv_zvl_subext, MASK_ZVL32B), + RISCV_EXT_FLAG_ENTRY ("xtheadvector", x_riscv_zvl_subext, MASK_ZVL64B), + RISCV_EXT_FLAG_ENTRY ("xtheadvector", x_riscv_zvl_subext, MASK_ZVL128B), + RISCV_EXT_FLAG_ENTRY ("xtheadvector", x_riscv_zvf_subext, MASK_ZVFHMIN), + RISCV_EXT_FLAG_ENTRY ("xtheadvector", x_riscv_zvf_subext, MASK_ZVFH), + RISCV_EXT_FLAG_ENTRY ("xtheadvector", x_riscv_isa_flags, MASK_FULL_V), + RISCV_EXT_FLAG_ENTRY ("xtheadvector", x_riscv_isa_flags, MASK_VECTOR), {NULL, NULL, NULL, 0} }; +/* Add extra extension flags into FLAG_TABLE for EXT. */ +static void +apply_extra_extension_flags (const char *ext, + std::vector<riscv_ext_flag_table_t> &flag_table) +{ + const riscv_extra_ext_flag_table_t *arch_ext_flag_tab; + for (arch_ext_flag_tab = &riscv_extra_ext_flag_table[0]; + arch_ext_flag_tab->ext; ++arch_ext_flag_tab) + { + if (strcmp (arch_ext_flag_tab->ext, ext) == 0) + { + flag_table.push_back ({arch_ext_flag_tab->var_ref, + arch_ext_flag_tab->cl_var_ref, + arch_ext_flag_tab->mask}); + } + } +} + /* Types for recording extension to RISC-V C-API bitmask. */ struct riscv_ext_bitmask_table_t { const char *ext; @@ -1943,23 +1592,27 @@ riscv_set_arch_by_subset_list (riscv_subset_list *subset_list, { if (opts) { - const riscv_ext_flag_table_t *arch_ext_flag_tab; /* Clean up target flags before we set. */ - for (arch_ext_flag_tab = &riscv_ext_flag_table[0]; arch_ext_flag_tab->ext; - ++arch_ext_flag_tab) - opts->*arch_ext_flag_tab->var_ref &= ~arch_ext_flag_tab->mask; + for (const auto &pair : riscv_ext_infos) + { + auto &ext_info = pair.second; + ext_info.clean_opts (opts); + } if (subset_list->xlen () == 32) - opts->x_target_flags &= ~MASK_64BIT; + opts->x_riscv_isa_flags &= ~MASK_64BIT; else if (subset_list->xlen () == 64) - opts->x_target_flags |= MASK_64BIT; + opts->x_riscv_isa_flags |= MASK_64BIT; - for (arch_ext_flag_tab = &riscv_ext_flag_table[0]; - arch_ext_flag_tab->ext; - ++arch_ext_flag_tab) + for (const auto &pair : riscv_ext_infos) { - if (subset_list->lookup (arch_ext_flag_tab->ext)) - opts->*arch_ext_flag_tab->var_ref |= arch_ext_flag_tab->mask; + const std::string &ext_name = pair.first; + auto &ext_info = pair.second; + if (subset_list->lookup (ext_name.c_str ())) + { + /* Set the extension flag. */ + ext_info.set_opts (opts); + } } } } @@ -1970,37 +1623,15 @@ bool riscv_ext_is_subset (struct cl_target_option *opts, struct cl_target_option *subset) { - const riscv_ext_flag_table_t *arch_ext_flag_tab; - for (arch_ext_flag_tab = &riscv_ext_flag_table[0]; - arch_ext_flag_tab->ext; - ++arch_ext_flag_tab) + for (const auto &riscv_ext_info : riscv_ext_infos) { - if (subset->*arch_ext_flag_tab->cl_var_ref & arch_ext_flag_tab->mask) - { - if (!(opts->*arch_ext_flag_tab->cl_var_ref & arch_ext_flag_tab->mask)) - return false; - } + const auto &ext_info = riscv_ext_info.second; + if (!ext_info.check_opts (opts) && ext_info.check_opts (subset)) + return false; } return true; } -/* Return the mask of ISA extension in x_target_flags of gcc_options. */ - -int -riscv_x_target_flags_isa_mask (void) -{ - int mask = 0; - const riscv_ext_flag_table_t *arch_ext_flag_tab; - for (arch_ext_flag_tab = &riscv_ext_flag_table[0]; - arch_ext_flag_tab->ext; - ++arch_ext_flag_tab) - { - if (arch_ext_flag_tab->var_ref == &gcc_options::x_target_flags) - mask |= arch_ext_flag_tab->mask; - } - return mask; -} - /* Get the minimal feature bits in Linux hwprobe of the given ISA string. Used for generating Function Multi-Versioning (FMV) dispatcher for RISC-V. @@ -2008,12 +1639,15 @@ riscv_x_target_flags_isa_mask (void) The minimal feature bits refer to using the earliest extension that appeared in the Linux hwprobe to support the specified ISA string. This ensures that older kernels, which may lack certain implied extensions, can still run the - FMV dispatcher correctly. */ + FMV dispatcher correctly. + + If LOC is nonnull, report any diagnostics against *LOC, otherwise remain + silent. */ bool riscv_minimal_hwprobe_feature_bits (const char *isa, struct riscv_feature_bits *res, - location_t loc) + location_t *loc) { riscv_subset_list *subset_list; subset_list = riscv_subset_list::parse (isa, loc); @@ -2055,20 +1689,18 @@ riscv_minimal_hwprobe_feature_bits (const char *isa, search_q.pop (); /* Iterate through the implied extension table. */ - const riscv_implied_info_t *implied_info; - for (implied_info = &riscv_implied_info[0]; - implied_info->ext; - ++implied_info) + auto &ext_info = get_riscv_ext_info (search_ext); + for (const auto &implied_ext : ext_info.implied_exts ()) { /* When the search extension matches the implied extension and the implied extension has not been visited, mark the implied extension in the implied_exts set and push it into the queue. */ - if (implied_info->match (subset_list, search_ext) - && implied_exts.count (implied_info->implied_ext) == 0) + if (implied_ext.match (subset_list) + && implied_exts.count (implied_ext.implied_ext) == 0) { - implied_exts.insert (implied_info->implied_ext); - search_q.push (implied_info->implied_ext); + implied_exts.insert (implied_ext.implied_ext); + search_q.push (implied_ext.implied_ext); } } } @@ -2085,7 +1717,7 @@ riscv_parse_arch_string (const char *isa, location_t loc) { riscv_subset_list *subset_list; - subset_list = riscv_subset_list::parse (isa, loc); + subset_list = riscv_subset_list::parse (isa, &loc); if (!subset_list) return; @@ -2123,7 +1755,8 @@ riscv_handle_option (struct gcc_options *opts, switch (decoded->opt_index) { case OPT_march_: - riscv_parse_arch_string (decoded->arg, opts, loc); + if (riscv_find_cpu (decoded->arg) == NULL) + riscv_parse_arch_string (decoded->arg, opts, loc); return true; case OPT_mcpu_: @@ -2140,15 +1773,23 @@ riscv_handle_option (struct gcc_options *opts, /* Expand arch string with implied extensions. */ const char * -riscv_expand_arch (int argc ATTRIBUTE_UNUSED, +riscv_expand_arch (int argc, const char **argv) { gcc_assert (argc == 1); location_t loc = UNKNOWN_LOCATION; - riscv_parse_arch_string (argv[0], NULL, loc); + + /* Filter out -march=unset, it will expand from -mcpu later. */ + if (strcmp (argv[0], "unset") == 0) + return ""; + + /* Try to interpret the arch as CPU first. */ + const char *arch_str = riscv_expand_arch_from_cpu (argc, argv); + if (!strlen (arch_str)) + riscv_parse_arch_string (argv[0], NULL, loc); const std::string arch = riscv_arch_str (false); - if (arch.length()) - return xasprintf ("-march=%s", arch.c_str()); + if (arch.length ()) + return xasprintf ("-march=%s", arch.c_str ()); else return ""; } @@ -2283,7 +1924,8 @@ riscv_multi_lib_info_t::parse ( } multi_lib_info->subset_list = - riscv_subset_list::parse (multi_lib_info->arch_str.c_str (), input_location); + riscv_subset_list::parse (multi_lib_info->arch_str.c_str (), + &input_location); return true; } @@ -2472,7 +2114,7 @@ riscv_compute_multilib ( return multilib_dir; subset_list = riscv_subset_list::parse (riscv_current_arch_str.c_str (), - input_location); + &input_location); /* Failed to parse -march, fallback to using what gcc use. */ if (subset_list == NULL) @@ -2622,16 +2264,15 @@ riscv_arch_help (int, const char **) } }; std::map<std::string, std::set<unsigned>, extension_comparator> all_exts; - for (const riscv_ext_version &ext : riscv_ext_version_table) + for (const auto &[ext_name, ext_info] : riscv_ext_infos) { - if (!ext.name) - break; - if (ext.name[0] == 'g') - continue; - unsigned version_value = (ext.major_version * RISCV_MAJOR_VERSION_BASE) - + (ext.minor_version - * RISCV_MINOR_VERSION_BASE); - all_exts[ext.name].insert(version_value); + for (auto &supported_version : ext_info.supported_versions ()) + { + unsigned version_value + = (supported_version.major_version * RISCV_MAJOR_VERSION_BASE) + + (supported_version.minor_version * RISCV_MINOR_VERSION_BASE); + all_exts[ext_name].insert (version_value); + } } printf("All available -march extensions for RISC-V:\n"); |