diff mbox series

[committed] RISC-V: Refine riscv_parse_arch_string

Message ID 20201027081557.125620-1-kito.cheng@sifive.com
State New
Headers show
Series [committed] RISC-V: Refine riscv_parse_arch_string | expand

Commit Message

Kito Cheng Oct. 27, 2020, 8:15 a.m. UTC
- 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 mbox series

Patch

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