public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v2] RISC-V: Add --march=help
@ 2024-01-30  6:36 Hau Hsu
  2024-01-30  8:43 ` Tsukasa OI
  0 siblings, 1 reply; 3+ messages in thread
From: Hau Hsu @ 2024-01-30  6:36 UTC (permalink / raw)
  To: binutils, kito.cheng, hau.hsu

Use --march=help to print all supported extensions and versions.

This patch assumes that the supported extensions with the same versions
are listed together.

For example
static struct riscv_supported_ext riscv_supported_std_ext[] =
{
  ...
  {"i",         ISA_SPEC_CLASS_20191213,        2, 1, 0 },
  {"i",         ISA_SPEC_CLASS_20190608,        2, 1, 0 },
  {"i",         ISA_SPEC_CLASS_2P2,             2, 0, 0 },
  ...
};

For "i" extension, 2.1.0 with different spec class are listed together.
This patch records the previous printed extension and version.  If the
current extension and version are the same as the previous one, skip
printing.

Here is part of the output of `as -march=help`:

All available -march extensions for RISC-V:
        e                                       1.9
        i                                       2.1, 2.0
        m                                       2.0
        a                                       2.1, 2.0
        f                                       2.2, 2.0
        d                                       2.2, 2.0
        q                                       2.2, 2.0
        c                                       2.0
        v                                       1.0
        h                                       1.0
        zicbom                                  1.0
        zicbop                                  1.0

Signed-off-by: Hau Hsu <hau.hsu@sifive.com>
---
 bfd/ChangeLog     |  9 ++++++
 bfd/elfxx-riscv.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 81 insertions(+)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 97d0c585a56..0807a2e0bcb 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,12 @@
+2024-01-17 Hau Hsu  <hau.hsu@sifive.com>
+
+	* elfxx-riscv.c (riscv_parse_subset): Parse 'help' keyword to print
+	  available extension and versions.
+	(riscv_print_extensions): New function.
+	(riscv_same_extension_version): New function.
+	(riscv_same_extension_diff_version): New function.
+	(riscv_valid_ext): New function.
+
 2024-01-15  Nick Clifton  <nickc@redhat.com>
 
 	* 2.42 branch point.
diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index 9a121b47121..bb394a589b1 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -2051,6 +2051,71 @@ riscv_set_default_arch (riscv_parse_subset_t *rps)
     }
 }
 
+static
+bool riscv_same_extension_version(
+  const struct riscv_supported_ext* ext1,
+  const struct riscv_supported_ext* ext2)
+{
+  return (strcmp(ext1->name, ext2->name) == 0
+          && ext1->major_version == ext2->major_version
+          && ext1->minor_version == ext2->minor_version);
+}
+
+static
+bool riscv_same_extension_diff_version(
+  const struct riscv_supported_ext* ext1,
+  const struct riscv_supported_ext* ext2)
+{
+  return (strcmp(ext1->name, ext2->name) == 0
+          && !(ext1->major_version == ext2->major_version
+               && ext1->minor_version == ext2->minor_version));
+}
+
+static
+bool riscv_valid_ext(const struct riscv_supported_ext *ext)
+{
+  return (ext->isa_spec_class != ISA_SPEC_CLASS_NONE
+          && ext->major_version != RISCV_UNKNOWN_VERSION
+          && ext->minor_version != RISCV_UNKNOWN_VERSION);
+}
+
+static
+void riscv_print_extensions(void)
+{
+  /* Record the previous pritned extension.
+     Print the current one if they are not the same.  */
+  const struct riscv_supported_ext *cur = NULL, *prev = NULL;
+
+  int i, j;
+  printf ("All available -march extensions for RISC-V:");
+  for (i = 0; riscv_all_supported_ext[i] != NULL; i++)
+    {
+      const struct riscv_supported_ext *exts = riscv_all_supported_ext[i];
+      prev = NULL;
+      for (j = 0; exts[j].name != NULL; j++)
+        {
+          cur = &exts[j];
+          if (!riscv_valid_ext (cur))
+            continue;
+
+          if (prev && riscv_same_extension_version (prev, cur))
+            continue;
+
+          if (!prev || !riscv_same_extension_diff_version (prev, cur))
+            {
+              printf("\n\t%-40s%d.%d", cur->name, cur->major_version, cur->minor_version);
+              prev = &exts[j];
+            }
+          else
+            {
+              printf(", %d.%d", cur->major_version, cur->minor_version);
+              prev = &exts[j];
+            }
+        }
+    }
+  printf ("\n");
+}
+
 /* Function for parsing ISA string.
 
    Return Value:
@@ -2089,6 +2154,13 @@ riscv_parse_subset (riscv_parse_subset_t *rps,
     }
 
   p = arch;
+  /* List all avaiable archs. */
+  if (strcmp (p, "help") == 0)
+    {
+      riscv_print_extensions();
+      exit (EXIT_SUCCESS);
+    }
+
   if (startswith (p, "rv32"))
     {
       *rps->xlen = 32;
-- 
2.37.1


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH v2] RISC-V: Add --march=help
  2024-01-30  6:36 [PATCH v2] RISC-V: Add --march=help Hau Hsu
@ 2024-01-30  8:43 ` Tsukasa OI
  2024-01-30 12:32   ` Hau Hsu
  0 siblings, 1 reply; 3+ messages in thread
From: Tsukasa OI @ 2024-01-30  8:43 UTC (permalink / raw)
  To: Hau Hsu, Binutils

Hi Hau,

I'm not yet ready to come back to Binutils development (because I
haven't finished writing my research paper) but I'd like to comment.

While your idea seems great at first glance, I would never like to see
"help" handling in the riscv_parse_subset function because many other
functions call it (some calls this function with an argument retrieved
from an assembly / object file and your design seems vulnerable from
adversarial files e.g. when disassembling files with unknown origin).

Besides that, I think that's not a bad idea (quite rare to see in the
GNU toolchain, though).

IMHO, the right place to put "help" handling (at least, its entry point)
is the md_parse_option function in gas/config/tc-riscv.c.  Exiting
successfully from here is rare but at least cris and kvx does so for
help-like options.

Thanks,
Tsukasa

On 2024/01/30 15:36, Hau Hsu wrote:
> Use --march=help to print all supported extensions and versions.
> 
> This patch assumes that the supported extensions with the same versions
> are listed together.
> 
> For example
> static struct riscv_supported_ext riscv_supported_std_ext[] =
> {
>   ...
>   {"i",         ISA_SPEC_CLASS_20191213,        2, 1, 0 },
>   {"i",         ISA_SPEC_CLASS_20190608,        2, 1, 0 },
>   {"i",         ISA_SPEC_CLASS_2P2,             2, 0, 0 },
>   ...
> };
> 
> For "i" extension, 2.1.0 with different spec class are listed together.
> This patch records the previous printed extension and version.  If the
> current extension and version are the same as the previous one, skip
> printing.
> 
> Here is part of the output of `as -march=help`:
> 
> All available -march extensions for RISC-V:
>         e                                       1.9
>         i                                       2.1, 2.0
>         m                                       2.0
>         a                                       2.1, 2.0
>         f                                       2.2, 2.0
>         d                                       2.2, 2.0
>         q                                       2.2, 2.0
>         c                                       2.0
>         v                                       1.0
>         h                                       1.0
>         zicbom                                  1.0
>         zicbop                                  1.0
> 
> Signed-off-by: Hau Hsu <hau.hsu@sifive.com>
> ---
>  bfd/ChangeLog     |  9 ++++++
>  bfd/elfxx-riscv.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 81 insertions(+)
> 
> diff --git a/bfd/ChangeLog b/bfd/ChangeLog
> index 97d0c585a56..0807a2e0bcb 100644
> --- a/bfd/ChangeLog
> +++ b/bfd/ChangeLog
> @@ -1,3 +1,12 @@
> +2024-01-17 Hau Hsu  <hau.hsu@sifive.com>
> +
> +	* elfxx-riscv.c (riscv_parse_subset): Parse 'help' keyword to print
> +	  available extension and versions.
> +	(riscv_print_extensions): New function.
> +	(riscv_same_extension_version): New function.
> +	(riscv_same_extension_diff_version): New function.
> +	(riscv_valid_ext): New function.
> +
>  2024-01-15  Nick Clifton  <nickc@redhat.com>
>  
>  	* 2.42 branch point.
> diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
> index 9a121b47121..bb394a589b1 100644
> --- a/bfd/elfxx-riscv.c
> +++ b/bfd/elfxx-riscv.c
> @@ -2051,6 +2051,71 @@ riscv_set_default_arch (riscv_parse_subset_t *rps)
>      }
>  }
>  
> +static
> +bool riscv_same_extension_version(
> +  const struct riscv_supported_ext* ext1,
> +  const struct riscv_supported_ext* ext2)
> +{
> +  return (strcmp(ext1->name, ext2->name) == 0
> +          && ext1->major_version == ext2->major_version
> +          && ext1->minor_version == ext2->minor_version);
> +}
> +
> +static
> +bool riscv_same_extension_diff_version(
> +  const struct riscv_supported_ext* ext1,
> +  const struct riscv_supported_ext* ext2)
> +{
> +  return (strcmp(ext1->name, ext2->name) == 0
> +          && !(ext1->major_version == ext2->major_version
> +               && ext1->minor_version == ext2->minor_version));
> +}
> +
> +static
> +bool riscv_valid_ext(const struct riscv_supported_ext *ext)
> +{
> +  return (ext->isa_spec_class != ISA_SPEC_CLASS_NONE
> +          && ext->major_version != RISCV_UNKNOWN_VERSION
> +          && ext->minor_version != RISCV_UNKNOWN_VERSION);
> +}
> +
> +static
> +void riscv_print_extensions(void)
> +{
> +  /* Record the previous pritned extension.
> +     Print the current one if they are not the same.  */
> +  const struct riscv_supported_ext *cur = NULL, *prev = NULL;
> +
> +  int i, j;
> +  printf ("All available -march extensions for RISC-V:");
> +  for (i = 0; riscv_all_supported_ext[i] != NULL; i++)
> +    {
> +      const struct riscv_supported_ext *exts = riscv_all_supported_ext[i];
> +      prev = NULL;
> +      for (j = 0; exts[j].name != NULL; j++)
> +        {
> +          cur = &exts[j];
> +          if (!riscv_valid_ext (cur))
> +            continue;
> +
> +          if (prev && riscv_same_extension_version (prev, cur))
> +            continue;
> +
> +          if (!prev || !riscv_same_extension_diff_version (prev, cur))
> +            {
> +              printf("\n\t%-40s%d.%d", cur->name, cur->major_version, cur->minor_version);
> +              prev = &exts[j];
> +            }
> +          else
> +            {
> +              printf(", %d.%d", cur->major_version, cur->minor_version);
> +              prev = &exts[j];
> +            }
> +        }
> +    }
> +  printf ("\n");
> +}
> +
>  /* Function for parsing ISA string.
>  
>     Return Value:
> @@ -2089,6 +2154,13 @@ riscv_parse_subset (riscv_parse_subset_t *rps,
>      }
>  
>    p = arch;
> +  /* List all avaiable archs. */
> +  if (strcmp (p, "help") == 0)
> +    {
> +      riscv_print_extensions();
> +      exit (EXIT_SUCCESS);
> +    }
> +
>    if (startswith (p, "rv32"))
>      {
>        *rps->xlen = 32;

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH v2] RISC-V: Add --march=help
  2024-01-30  8:43 ` Tsukasa OI
@ 2024-01-30 12:32   ` Hau Hsu
  0 siblings, 0 replies; 3+ messages in thread
From: Hau Hsu @ 2024-01-30 12:32 UTC (permalink / raw)
  To: Tsukasa OI; +Cc: Binutils

[-- Attachment #1: Type: text/plain, Size: 6487 bytes --]

Hi Tsukasa,

Indeed this idea is from Clang.
Let me see if I can have another implementation based on your suggestions.
Thanks for your quick reply :).

Best,

Hau Hsu
Software Engineer
hau.hsu@sifive.com




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


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2024-01-30 12:32 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-01-30  6:36 [PATCH v2] RISC-V: Add --march=help Hau Hsu
2024-01-30  8:43 ` Tsukasa OI
2024-01-30 12:32   ` Hau Hsu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).