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;
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_:
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());
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());
}