From e94de06fd6077438539b2d7c18eb8fcb113bd9b6 Mon Sep 17 00:00:00 2001 From: Kito Cheng Date: Tue, 27 Oct 2020 14:38:07 +0800 Subject: [PATCH] RISC-V: Refine riscv_parse_arch_string - Generalize logic for translating arch to internal flags, this patch is infrastructure for supporing sub-extension parsing. gcc/ChangeLog * common/config/riscv/riscv-common.c (opt_var_ref_t): New. (riscv_ext_flag_table_t): New. (riscv_ext_flag_table): New. (riscv_parse_arch_string): Pass gcc_options* instead of &opts->x_target_flags only, and using riscv_arch_option_table to setup flags. (riscv_handle_option): Update argument for riscv_parse_arch_string. (riscv_expand_arch): Ditto. (riscv_expand_arch_from_cpu): Ditto. --- gcc/common/config/riscv/riscv-common.c | 84 ++++++++++++++++---------- 1 file changed, 51 insertions(+), 33 deletions(-) diff --git a/gcc/common/config/riscv/riscv-common.c b/gcc/common/config/riscv/riscv-common.c index 4b6bdf8685d..b84503a7742 100644 --- a/gcc/common/config/riscv/riscv-common.c +++ b/gcc/common/config/riscv/riscv-common.c @@ -618,44 +618,64 @@ riscv_arch_str (bool version_p) return std::string(); } +/* Type for pointer to member of gcc_options. */ +typedef int (gcc_options::*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; + int mask; +}; + +/* Mapping table between extension to internal flag. */ +static const riscv_ext_flag_table_t riscv_ext_flag_table[] = +{ + {"e", &gcc_options::x_target_flags, MASK_RVE}, + {"m", &gcc_options::x_target_flags, MASK_MUL}, + {"a", &gcc_options::x_target_flags, MASK_ATOMIC}, + {"f", &gcc_options::x_target_flags, MASK_HARD_FLOAT}, + {"d", &gcc_options::x_target_flags, MASK_DOUBLE_FLOAT}, + {"c", &gcc_options::x_target_flags, MASK_RVC}, + {NULL, NULL, 0} +}; + /* Parse a RISC-V ISA string into an option mask. Must clear or set all arch dependent mask bits, in case more than one -march string is passed. */ static void -riscv_parse_arch_string (const char *isa, int *flags, location_t loc) +riscv_parse_arch_string (const char *isa, + struct gcc_options *opts, + location_t loc) { riscv_subset_list *subset_list; subset_list = riscv_subset_list::parse (isa, loc); if (!subset_list) return; - if (subset_list->xlen () == 32) - *flags &= ~MASK_64BIT; - else if (subset_list->xlen () == 64) - *flags |= MASK_64BIT; - - *flags &= ~MASK_RVE; - if (subset_list->lookup ("e")) - *flags |= MASK_RVE; - - *flags &= ~MASK_MUL; - if (subset_list->lookup ("m")) - *flags |= MASK_MUL; - - *flags &= ~MASK_ATOMIC; - if (subset_list->lookup ("a")) - *flags |= MASK_ATOMIC; - - *flags &= ~(MASK_HARD_FLOAT | MASK_DOUBLE_FLOAT); - if (subset_list->lookup ("f")) - *flags |= MASK_HARD_FLOAT; - - if (subset_list->lookup ("d")) - *flags |= MASK_DOUBLE_FLOAT; - - *flags &= ~MASK_RVC; - if (subset_list->lookup ("c")) - *flags |= MASK_RVC; + 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; + + if (subset_list->xlen () == 32) + opts->x_target_flags &= ~MASK_64BIT; + else if (subset_list->xlen () == 64) + opts->x_target_flags |= MASK_64BIT; + + + for (arch_ext_flag_tab = &riscv_ext_flag_table[0]; + arch_ext_flag_tab->ext; + ++arch_ext_flag_tab) + { + if (subset_list->lookup (arch_ext_flag_tab->ext)) + opts->*arch_ext_flag_tab->var_ref |= arch_ext_flag_tab->mask; + } + } if (current_subset_list) delete current_subset_list; @@ -689,7 +709,7 @@ riscv_handle_option (struct gcc_options *opts, switch (decoded->opt_index) { case OPT_march_: - riscv_parse_arch_string (decoded->arg, &opts->x_target_flags, loc); + riscv_parse_arch_string (decoded->arg, opts, loc); return true; case OPT_mcpu_: @@ -710,9 +730,8 @@ riscv_expand_arch (int argc ATTRIBUTE_UNUSED, const char **argv) { gcc_assert (argc == 1); - int flags; location_t loc = UNKNOWN_LOCATION; - riscv_parse_arch_string (argv[0], &flags, loc); + 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()); @@ -760,9 +779,8 @@ riscv_expand_arch_from_cpu (int argc ATTRIBUTE_UNUSED, arch_str = cpu->arch; location_t loc = UNKNOWN_LOCATION; - int flags; - riscv_parse_arch_string (arch_str, &flags, loc); + riscv_parse_arch_string (arch_str, NULL, loc); const std::string arch = riscv_arch_str (false); return xasprintf ("-march=%s", arch.c_str()); } -- 2.30.2