RISC-V: Add i-ext as the implicit extension when e-ext is set.
authorNelson Chu <nelson.chu@sifive.com>
Mon, 12 Apr 2021 08:58:47 +0000 (16:58 +0800)
committerNelson Chu <nelson.chu@sifive.com>
Mon, 12 Apr 2021 09:51:07 +0000 (17:51 +0800)
The linker does not care the default versions of the extensions, since
it does not have the default ISA spec setting.  Therefore, linker won't
insert the implicit extensions for the input objects.  But we used to
insert the i-ext as the explicit extension, even if the e-ext is set.
This causes linker to report "cannot find default versions of the ISA
extension `i'" errors when linking the input objects with e-ext.

This patch fixes the above linker problem, and also remove the confused
riscv_ext_dont_care_version function.  Unless these "dont care" extensions
are set in the input architecture explicitly, otherwise we always insert
them as the implicit ones.  Afterwards, let riscv_arch_str1 surpress them
not to output to the architecture string if their versions are
RISCV_UNKNOWN_VERSION.

bfd/
    * elfxx-riscv.c (riscv_ext_dont_care_version): Removed.
    (riscv_parse_add_subset): Always add the implicit extensions, even if
    their versions are RISCV_UNKNOWN_VERSION.
    (riscv_parse_std_ext): Delay to add i-ext as the implicit extension
    in the riscv_parse_add_implicit_subsets.  Besides, add g-ext as the
    implicit extension after it has been expanded.
    (riscv_parse_add_implicit_subsets): Updated.

bfd/ChangeLog
bfd/elfxx-riscv.c

index 266ebf3b572bbdc594acc34bc8c9f626cd4eb0c5..58a862c0ea57afc0f8fff246209e87d6e40923bd 100644 (file)
@@ -1,3 +1,13 @@
+2021-04-12  Nelson Chu  <nelson.chu@sifive.com>
+
+       * elfxx-riscv.c (riscv_ext_dont_care_version): Removed.
+       (riscv_parse_add_subset): Always add the implicit extensions, even if
+       their versions are RISCV_UNKNOWN_VERSION.
+       (riscv_parse_std_ext): Delay to add i-ext as the implicit extension
+       in the riscv_parse_add_implicit_subsets.  Besides, add g-ext as the
+       implicit extension after it has been expanded.
+       (riscv_parse_add_implicit_subsets): Updated.
+
 2021-04-12  Nelson Chu  <nelson.chu@sifive.com>
 
        * elfxx-riscv.c (riscv_std_z_ext_strtab): Moved forward.
index a8613d86bc468e89817f7467a3c5e1470fef04d2..ef55d8384eb01dac797bcd6ea1cb6d7716fcb619 100644 (file)
@@ -1310,21 +1310,6 @@ riscv_add_implicit_subset (riscv_subset_list_t *subset_list,
     }
 }
 
-/* These extensions are added to the subset list for special purposes,
-   with the explicit versions or the RISCV_UNKNOWN_VERSION versions.
-   Therefore, we won't output them to the output ISA string in the
-   riscv_arch_str1, if the versions are unknown.  */
-
-static bool
-riscv_ext_dont_care_version (const char *subset)
-{
-  if (strcmp (subset, "g") == 0
-      || strcmp (subset, "zicsr") == 0
-      || strcmp (subset, "zifencei") == 0)
-    return true;
-  return false;
-}
-
 /* We have to add all extensions from ISA string first, and then start to
    add their implicit extensions.  The extensions from ISA string must be
    set in order, so we can add them to the last of the subset list
@@ -1349,15 +1334,11 @@ riscv_parse_add_subset (riscv_parse_subset_t *rps,
       && rps->get_default_version != NULL)
     rps->get_default_version (subset, &major_version, &minor_version);
 
-  if (!riscv_ext_dont_care_version (subset)
+  /* We don't care the versions of the implicit extensions.  */
+  if (!implicit
       && (major_version == RISCV_UNKNOWN_VERSION
          || minor_version == RISCV_UNKNOWN_VERSION))
     {
-      /* We only add the implicit extension if it is supported in the
-        chosen ISA spec.  */
-      if (implicit)
-       return;
-
       if (subset[0] == 'x')
        rps->error_handler
          (_("x ISA extension `%s' must be set with the versions"),
@@ -1518,11 +1499,6 @@ riscv_parse_std_ext (riscv_parse_subset_t *rps,
        riscv_parse_add_subset (rps, "e",
                                major_version,
                                minor_version, false);
-       /* i-ext must be enabled.  */
-       riscv_parse_add_subset (rps, "i",
-                               RISCV_UNKNOWN_VERSION,
-                               RISCV_UNKNOWN_VERSION, false);
-
        if (*rps->xlen > 32)
          {
            rps->error_handler
@@ -1536,13 +1512,8 @@ riscv_parse_std_ext (riscv_parse_subset_t *rps,
        p = riscv_parsing_subset_version (rps, march, ++p,
                                          &major_version,
                                          &minor_version, true);
-       /* i-ext must be enabled.  */
+       /* Expand g to imafd.  */
        riscv_parse_add_subset (rps, "i",
-                               RISCV_UNKNOWN_VERSION,
-                               RISCV_UNKNOWN_VERSION, false);
-       /* g-ext is used to add the implicit extensions, but will
-          not be output to the ISA string.  */
-       riscv_parse_add_subset (rps, "g",
                                major_version,
                                minor_version, false);
        for ( ; *std_exts != 'q'; std_exts++)
@@ -1552,6 +1523,10 @@ riscv_parse_std_ext (riscv_parse_subset_t *rps,
                                    RISCV_UNKNOWN_VERSION,
                                    RISCV_UNKNOWN_VERSION, false);
          }
+       /* Add g as an implicit extension.  */
+       riscv_parse_add_subset (rps, "g",
+                               RISCV_UNKNOWN_VERSION,
+                               RISCV_UNKNOWN_VERSION, true);
        break;
 
       default:
@@ -1726,8 +1701,13 @@ riscv_parse_add_implicit_subsets (riscv_parse_subset_t *rps)
 {
   riscv_subset_t *subset = NULL;
 
+  if (riscv_lookup_subset (rps->subset_list, "e", &subset))
+    riscv_parse_add_subset (rps, "i",
+                           RISCV_UNKNOWN_VERSION,
+                           RISCV_UNKNOWN_VERSION, true);
+
   /* Add the zicsr and zifencei only when the i's version less than 2.1.  */
-  if ((riscv_lookup_subset (rps->subset_list, "i", &subset))
+  if (riscv_lookup_subset (rps->subset_list, "i", &subset)
       && (subset->major_version < 2
          || (subset->major_version == 2
              && subset->minor_version < 1)))
@@ -1740,7 +1720,7 @@ riscv_parse_add_implicit_subsets (riscv_parse_subset_t *rps)
                              RISCV_UNKNOWN_VERSION, true);
     }
 
-  if ((riscv_lookup_subset (rps->subset_list, "q", &subset)))
+  if (riscv_lookup_subset (rps->subset_list, "q", &subset))
     {
       riscv_parse_add_subset (rps, "d",
                              RISCV_UNKNOWN_VERSION,
@@ -1752,7 +1732,7 @@ riscv_parse_add_implicit_subsets (riscv_parse_subset_t *rps)
                              RISCV_UNKNOWN_VERSION,
                              RISCV_UNKNOWN_VERSION, true);
     }
-  else if ((riscv_lookup_subset (rps->subset_list, "d", &subset)))
+  else if (riscv_lookup_subset (rps->subset_list, "d", &subset))
     {
       riscv_parse_add_subset (rps, "f",
                              RISCV_UNKNOWN_VERSION,
@@ -1761,12 +1741,12 @@ riscv_parse_add_implicit_subsets (riscv_parse_subset_t *rps)
                              RISCV_UNKNOWN_VERSION,
                              RISCV_UNKNOWN_VERSION, true);
     }
-  else if ((riscv_lookup_subset (rps->subset_list, "f", &subset)))
+  else if (riscv_lookup_subset (rps->subset_list, "f", &subset))
     riscv_parse_add_subset (rps, "zicsr",
                            RISCV_UNKNOWN_VERSION,
                            RISCV_UNKNOWN_VERSION, true);
 
-  if ((riscv_lookup_subset (rps->subset_list, "g", &subset)))
+  if (riscv_lookup_subset (rps->subset_list, "g", &subset))
     {
       riscv_parse_add_subset (rps, "zicsr",
                              RISCV_UNKNOWN_VERSION,