Define a new riscv_ext_info_t struct to aggregate all ISA extension fields (name, version, flags, implied extensions, bitmask and extra flags) generated from riscv-ext.def.
Also adjust riscv_ext_flag_table_t and riscv_implied_info_t to make it able to not hold extension name, this part will refactor in later patchs. gcc/ChangeLog: * common/config/riscv/riscv-common.cc (riscv_ext_info_t): New struct. (opt_var_ref_t): Adjust order. (cl_opt_var_ref_t): Ditto. (riscv_ext_flag_table_t): Adjust order, and add a new construct that not hold the extension name. (riscv_version_t): New struct. (riscv_implied_info_t): Adjust order, and add a new construct that not hold the extension name. (apply_extra_extension_flags): New function. (riscv_ext_infos): New. (riscv_implied_info): Adjust. * config/riscv/riscv-opts.h (EXT_FLAG_MACRO): New macro. (BITMASK_NOT_YET_ALLOCATED): New macro. --- gcc/common/config/riscv/riscv-common.cc | 191 ++++++++++++++++++++++-- gcc/config/riscv/riscv-opts.h | 8 + 2 files changed, 185 insertions(+), 14 deletions(-) diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc index 5a091e3987b1..72d5d8181d16 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,11 +42,62 @@ 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_ext_flag_table_t +{ + riscv_ext_flag_table_t (const char *ext, opt_var_ref_t var_ref, + cl_opt_var_ref_t cl_var_ref, int mask) + : ext (ext), var_ref (var_ref), cl_var_ref (cl_var_ref), mask (mask) + {} + riscv_ext_flag_table_t (opt_var_ref_t var_ref, + cl_opt_var_ref_t cl_var_ref, int mask) + : ext (nullptr), var_ref (var_ref), cl_var_ref (cl_var_ref), mask (mask) + {} + + const char *ext; + 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 *implied_ext, + riscv_implied_predicator_t predicator + = nullptr) + : ext (nullptr), implied_ext (implied_ext), predicator (predicator) + {} + constexpr riscv_implied_info_t (const char *ext, const char *implied_ext, riscv_implied_predicator_t predicator = nullptr) @@ -53,7 +105,7 @@ struct riscv_implied_info_t bool match (const riscv_subset_list *subset_list, const char *ext_name) const { - if (strcmp (ext_name, ext) != 0) + if (ext_name && strcmp (ext_name, ext) != 0) return false; if (predicator && !predicator (subset_list)) @@ -73,6 +125,111 @@ struct riscv_implied_info_t riscv_implied_predicator_t predicator; }; +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; + + 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 +}; + /* Implied ISA info, must end with NULL sentinel. */ static const riscv_implied_info_t riscv_implied_info[] = { @@ -261,7 +418,7 @@ static const riscv_implied_info_t riscv_implied_info[] = {"xsfvcp", "zve32x"}, - {NULL, NULL} + {NULL, NULL, NULL} }; /* This structure holds version information for specific ISA version. */ @@ -1620,18 +1777,6 @@ 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} @@ -1822,6 +1967,24 @@ static const riscv_ext_flag_table_t riscv_ext_flag_table[] = {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_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 (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; diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h index fc3963c96bc5..0f3bca5bb7c7 100644 --- a/gcc/config/riscv/riscv-opts.h +++ b/gcc/config/riscv/riscv-opts.h @@ -164,4 +164,12 @@ enum riscv_tls_type { #define GPR2VR_COST_UNPROVIDED -1 +/* Extra extension flags, used for carry extra info for a RISC-V extension. */ +enum +{ + EXT_FLAG_MACRO = 1 << 0, +}; + +#define BITMASK_NOT_YET_ALLOCATED -1 + #endif /* ! GCC_RISCV_OPTS_H */ -- 2.34.1