diff options
Diffstat (limited to 'gcc/common/config/riscv/riscv-common.cc')
-rw-r--r-- | gcc/common/config/riscv/riscv-common.cc | 1152 |
1 files changed, 435 insertions, 717 deletions
diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc index 145a0f2..82037a3 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); + +/* 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; - {NULL, NULL} + 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 @@ -274,226 +262,67 @@ struct riscv_ext_version int minor_version; }; -/* All standard extensions defined in all supported ISA spec. */ -static const struct riscv_ext_version riscv_ext_version_table[] = +struct riscv_profiles { - /* 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}, - - {"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}, - - {"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}, - - {"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} + const char *profile_name; + const char *profile_string; }; -/* 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}, +/* 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"}, + + /* 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", "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_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", "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"}, + + /* 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, ISA_SPEC_CLASS_NONE, 0, 0} + {NULL, NULL} }; static const riscv_cpu_info riscv_cpu_tables[] = @@ -551,7 +380,7 @@ riscv_subset_t::riscv_subset_t () 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) { } @@ -729,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. */ @@ -863,24 +689,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. */ @@ -1103,6 +924,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: @@ -1129,7 +996,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", + 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; } @@ -1238,25 +1106,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. */ @@ -1277,14 +1128,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; } } @@ -1295,27 +1145,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; @@ -1325,11 +1173,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); } } } @@ -1340,6 +1186,34 @@ riscv_subset_list::check_conflict_ext () if (lookup ("zcf") && m_xlen == 64) 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, @@ -1521,8 +1395,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; @@ -1614,89 +1490,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 ("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. @@ -1713,106 +1515,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 ("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; @@ -1839,23 +1575,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); + } } } } @@ -1866,37 +1606,14 @@ 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 &[ext_name, 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; - } + 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. @@ -1951,20 +1668,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); } } } @@ -2019,7 +1734,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_: @@ -2036,15 +1752,18 @@ 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); + /* 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 ""; } @@ -2518,16 +2237,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"); |