<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body style="overflow-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;">Hi Tsukasa,<div><br></div><div>Indeed this idea is from Clang.</div><div>Let me see if I can have another implementation based on your suggestions.</div><div>Thanks for your quick reply :).</div><div><br><div>
<div dir="auto" style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; overflow-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><div>Best,</div><div><br></div><div>Hau Hsu</div><div>Software Engineer</div><div>hau.hsu@sifive.com</div><div><br></div></div><br class="Apple-interchange-newline"><br class="Apple-interchange-newline">
</div>
<div><br><blockquote type="cite"><div>Tsukasa OI <research_trasio@irq.a4lg.com> 於 2024年1月30日 下午4:43 寫道:</div><br class="Apple-interchange-newline"><div><div>Hi Hau,<br><br>I'm not yet ready to come back to Binutils development (because I<br>haven't finished writing my research paper) but I'd like to comment.<br><br>While your idea seems great at first glance, I would never like to see<br>"help" handling in the riscv_parse_subset function because many other<br>functions call it (some calls this function with an argument retrieved<br>from an assembly / object file and your design seems vulnerable from<br>adversarial files e.g. when disassembling files with unknown origin).<br><br>Besides that, I think that's not a bad idea (quite rare to see in the<br>GNU toolchain, though).<br><br>IMHO, the right place to put "help" handling (at least, its entry point)<br>is the md_parse_option function in gas/config/tc-riscv.c.  Exiting<br>successfully from here is rare but at least cris and kvx does so for<br>help-like options.<br><br>Thanks,<br>Tsukasa<br><br>On 2024/01/30 15:36, Hau Hsu wrote:<br><blockquote type="cite">Use --march=help to print all supported extensions and versions.<br><br>This patch assumes that the supported extensions with the same versions<br>are listed together.<br><br>For example<br>static struct riscv_supported_ext riscv_supported_std_ext[] =<br>{<br>  ...<br>  {"i",         ISA_SPEC_CLASS_20191213,        2, 1, 0 },<br>  {"i",         ISA_SPEC_CLASS_20190608,        2, 1, 0 },<br>  {"i",         ISA_SPEC_CLASS_2P2,             2, 0, 0 },<br>  ...<br>};<br><br>For "i" extension, 2.1.0 with different spec class are listed together.<br>This patch records the previous printed extension and version.  If the<br>current extension and version are the same as the previous one, skip<br>printing.<br><br>Here is part of the output of `as -march=help`:<br><br>All available -march extensions for RISC-V:<br>        e                                       1.9<br>        i                                       2.1, 2.0<br>        m                                       2.0<br>        a                                       2.1, 2.0<br>        f                                       2.2, 2.0<br>        d                                       2.2, 2.0<br>        q                                       2.2, 2.0<br>        c                                       2.0<br>        v                                       1.0<br>        h                                       1.0<br>        zicbom                                  1.0<br>        zicbop                                  1.0<br><br>Signed-off-by: Hau Hsu <hau.hsu@sifive.com><br>---<br> bfd/ChangeLog     |  9 ++++++<br> bfd/elfxx-riscv.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++<br> 2 files changed, 81 insertions(+)<br><br>diff --git a/bfd/ChangeLog b/bfd/ChangeLog<br>index 97d0c585a56..0807a2e0bcb 100644<br>--- a/bfd/ChangeLog<br>+++ b/bfd/ChangeLog<br>@@ -1,3 +1,12 @@<br>+2024-01-17 Hau Hsu  <hau.hsu@sifive.com><br>+<br>+<span class="Apple-tab-span" style="white-space:pre">    </span>* elfxx-riscv.c (riscv_parse_subset): Parse 'help' keyword to print<br>+<span class="Apple-tab-span" style="white-space:pre">      </span>  available extension and versions.<br>+<span class="Apple-tab-span" style="white-space:pre"> </span>(riscv_print_extensions): New function.<br>+<span class="Apple-tab-span" style="white-space:pre">  </span>(riscv_same_extension_version): New function.<br>+<span class="Apple-tab-span" style="white-space:pre">    </span>(riscv_same_extension_diff_version): New function.<br>+<span class="Apple-tab-span" style="white-space:pre">       </span>(riscv_valid_ext): New function.<br>+<br> 2024-01-15  Nick Clifton  <nickc@redhat.com><br><br> <span class="Apple-tab-span" style="white-space:pre">     </span>* 2.42 branch point.<br>diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c<br>index 9a121b47121..bb394a589b1 100644<br>--- a/bfd/elfxx-riscv.c<br>+++ b/bfd/elfxx-riscv.c<br>@@ -2051,6 +2051,71 @@ riscv_set_default_arch (riscv_parse_subset_t *rps)<br>     }<br> }<br><br>+static<br>+bool riscv_same_extension_version(<br>+  const struct riscv_supported_ext* ext1,<br>+  const struct riscv_supported_ext* ext2)<br>+{<br>+  return (strcmp(ext1->name, ext2->name) == 0<br>+          && ext1->major_version == ext2->major_version<br>+          && ext1->minor_version == ext2->minor_version);<br>+}<br>+<br>+static<br>+bool riscv_same_extension_diff_version(<br>+  const struct riscv_supported_ext* ext1,<br>+  const struct riscv_supported_ext* ext2)<br>+{<br>+  return (strcmp(ext1->name, ext2->name) == 0<br>+          && !(ext1->major_version == ext2->major_version<br>+               && ext1->minor_version == ext2->minor_version));<br>+}<br>+<br>+static<br>+bool riscv_valid_ext(const struct riscv_supported_ext *ext)<br>+{<br>+  return (ext->isa_spec_class != ISA_SPEC_CLASS_NONE<br>+          && ext->major_version != RISCV_UNKNOWN_VERSION<br>+          && ext->minor_version != RISCV_UNKNOWN_VERSION);<br>+}<br>+<br>+static<br>+void riscv_print_extensions(void)<br>+{<br>+  /* Record the previous pritned extension.<br>+     Print the current one if they are not the same.  */<br>+  const struct riscv_supported_ext *cur = NULL, *prev = NULL;<br>+<br>+  int i, j;<br>+  printf ("All available -march extensions for RISC-V:");<br>+  for (i = 0; riscv_all_supported_ext[i] != NULL; i++)<br>+    {<br>+      const struct riscv_supported_ext *exts = riscv_all_supported_ext[i];<br>+      prev = NULL;<br>+      for (j = 0; exts[j].name != NULL; j++)<br>+        {<br>+          cur = &exts[j];<br>+          if (!riscv_valid_ext (cur))<br>+            continue;<br>+<br>+          if (prev && riscv_same_extension_version (prev, cur))<br>+            continue;<br>+<br>+          if (!prev || !riscv_same_extension_diff_version (prev, cur))<br>+            {<br>+              printf("\n\t%-40s%d.%d", cur->name, cur->major_version, cur->minor_version);<br>+              prev = &exts[j];<br>+            }<br>+          else<br>+            {<br>+              printf(", %d.%d", cur->major_version, cur->minor_version);<br>+              prev = &exts[j];<br>+            }<br>+        }<br>+    }<br>+  printf ("\n");<br>+}<br>+<br> /* Function for parsing ISA string.<br><br>    Return Value:<br>@@ -2089,6 +2154,13 @@ riscv_parse_subset (riscv_parse_subset_t *rps,<br>     }<br><br>   p = arch;<br>+  /* List all avaiable archs. */<br>+  if (strcmp (p, "help") == 0)<br>+    {<br>+      riscv_print_extensions();<br>+      exit (EXIT_SUCCESS);<br>+    }<br>+<br>   if (startswith (p, "rv32"))<br>     {<br>       *rps->xlen = 32;<br></blockquote></div></div></blockquote></div><br></div></body></html>