[binutils-gdb] RISC-V: Allow to add numbers in the prefixed extension names.
Nelson Chu
nelsonc1225@sourceware.org
Tue Sep 28 11:39:33 GMT 2021
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=69a61890cb94746e5a564776081c3cefa8fca408
commit 69a61890cb94746e5a564776081c3cefa8fca408
Author: Nelson Chu <nelson.chu@sifive.com>
Date: Tue Sep 28 16:47:23 2021 +0800
RISC-V: Allow to add numbers in the prefixed extension names.
We need to allow adding numbers in the prefixed extension names, since
the zve<32,64><d,f,x> extensions are included in the forzen rvv v1.0 spec
recently. But there are two restrictions as follows,
* The extension name ends with <number>p is invalid, since this may
be confused with extension with <number>.0 version. We report errors
for this case.
Invalid format: [z|h|s|zvm|x][0-9a-z]+[0-9]+p
* The extension name ends with numbers is valid, but the numbers will
be parsed as major version, so try to avoid naming extensions like this.
bfd/
* elfxx-riscv.c (riscv_recognized_prefixed_ext): Renamed from
riscv_valid_prefixed_ext/
(riscv_parsing_subset_version): The extensions end with <number>p
is forbidden, we already report the detailed errors in the
riscv_parse_prefixed_ext, so clean the code and unused parameters.
(riscv_parse_std_ext): Updated.
(riscv_parse_prefixed_ext): Rewrite the parser to allow numbers
in the prefixed extension names.
gas/
* testsuite/gas/riscv/march-fail-invalid-x-01.d: New testcases.
* testsuite/gas/riscv/march-fail-invalid-x-02.d: Likewise.
* testsuite/gas/riscv/march-fail-invalid-z-01.d: Likewise.
* testsuite/gas/riscv/march-fail-invalid-z-02.d: Likewise.
* testsuite/gas/riscv/march-fail-invalid.l: Likewise.
* testsuite/gas/riscv/march-fail-version-x.d: Removed.
* testsuite/gas/riscv/march-fail-version-z.d: Likewise.
* testsuite/gas/riscv/march-fail-version.l: Likewise.
Diff:
---
bfd/elfxx-riscv.c | 82 ++++++++++++-----------
gas/testsuite/gas/riscv/march-fail-invalid-x-01.d | 3 +
gas/testsuite/gas/riscv/march-fail-invalid-x-02.d | 3 +
gas/testsuite/gas/riscv/march-fail-invalid-z-01.d | 3 +
gas/testsuite/gas/riscv/march-fail-invalid-z-02.d | 3 +
gas/testsuite/gas/riscv/march-fail-invalid.l | 2 +
gas/testsuite/gas/riscv/march-fail-version-x.d | 3 -
gas/testsuite/gas/riscv/march-fail-version-z.d | 3 -
gas/testsuite/gas/riscv/march-fail-version.l | 3 -
9 files changed, 58 insertions(+), 47 deletions(-)
diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index b467bceb919..c3d019c03a6 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -1236,11 +1236,11 @@ riscv_known_prefixed_ext (const char *ext,
return false;
}
-/* Check whether the prefixed extension is valid or not. Return
- true if valid, otehrwise return false. */
+/* Check whether the prefixed extension is recognized or not. Return
+ true if recognized, otehrwise return false. */
static bool
-riscv_valid_prefixed_ext (const char *ext)
+riscv_recognized_prefixed_ext (const char *ext)
{
enum riscv_prefix_ext_class class = riscv_get_prefix_class (ext);
switch (class)
@@ -1254,7 +1254,7 @@ riscv_valid_prefixed_ext (const char *ext)
case RV_ISA_CLASS_H:
return riscv_known_prefixed_ext (ext, riscv_supported_std_h_ext);
case RV_ISA_CLASS_X:
- /* Only the single x is invalid. */
+ /* Only the single x is unrecognized. */
if (strcmp (ext, "x") != 0)
return true;
default:
@@ -1515,20 +1515,14 @@ riscv_release_subset_list (riscv_subset_list_t *subset_list)
Points to the end of version
Arguments:
- `rps`: Hooks and status for parsing extensions.
- `arch`: Full ISA string.
`p`: Curent parsing position.
`major_version`: Parsed major version.
- `minor_version`: Parsed minor version.
- `std_ext_p`: True if parsing standard extension. */
+ `minor_version`: Parsed minor version. */
static const char *
-riscv_parsing_subset_version (riscv_parse_subset_t *rps,
- const char *arch,
- const char *p,
+riscv_parsing_subset_version (const char *p,
int *major_version,
- int *minor_version,
- bool std_ext_p)
+ int *minor_version)
{
bool major_p = true;
int version = 0;
@@ -1545,19 +1539,9 @@ riscv_parsing_subset_version (riscv_parse_subset_t *rps,
if (!ISDIGIT (np))
{
/* Might be beginning of `p` extension. */
- if (std_ext_p)
- {
- *major_version = version;
- *minor_version = 0;
- return p;
- }
- else
- {
- rps->error_handler
- (_("%s: expect number after `%dp'"),
- arch, version);
- return NULL;
- }
+ *major_version = version;
+ *minor_version = 0;
+ return p;
}
*major_version = version;
@@ -1648,7 +1632,7 @@ riscv_parse_std_ext (riscv_parse_subset_t *rps,
return NULL;
}
- p = riscv_parsing_subset_version (rps, arch, ++p, &major, &minor, true);
+ p = riscv_parsing_subset_version (++p, &major, &minor);
/* Added g as an implicit extension. */
if (subset[0] == 'g')
{
@@ -1703,29 +1687,51 @@ riscv_parse_prefixed_ext (riscv_parse_subset_t *rps,
char *q = subset;
const char *end_of_version;
- while (*++q != '\0' && *q != '_' && !ISDIGIT (*q))
+ /* Extract the whole prefixed extension by '_'. */
+ while (*++q != '\0' && *q != '_')
;
+ /* Look forward to the first letter which is not <major>p<minor>. */
+ bool find_any_version = false;
+ bool find_minor_version = false;
+ while (1)
+ {
+ q--;
+ if (ISDIGIT (*q))
+ find_any_version = true;
+ else if (find_any_version
+ && !find_minor_version
+ && *q == 'p'
+ && ISDIGIT (*(q - 1)))
+ find_minor_version = true;
+ else
+ break;
+ }
+ q++;
+
+ /* Check if the end of extension is 'p' or not. If yes, then
+ the second letter from the end cannot be number. */
+ if (*(q - 1) == 'p' && ISDIGIT (*(q - 2)))
+ {
+ *q = '\0';
+ rps->error_handler
+ (_("%s: invalid prefixed ISA extension `%s' ends with <number>p"),
+ arch, subset);
+ free (subset);
+ return NULL;
+ }
end_of_version =
- riscv_parsing_subset_version (rps, arch, q,
- &major_version,
- &minor_version, false);
+ riscv_parsing_subset_version (q, &major_version, &minor_version);
*q = '\0';
-
if (end_of_version == NULL)
{
free (subset);
return NULL;
}
- /* Check if the prefix extension is known.
- For 'x', anything goes but it cannot simply be 'x'.
- For other prefixed extensions, it must be known from a list
- and cannot simply be the prefixed name. */
-
/* Check that the extension name is well-formed. */
if (rps->check_unknown_prefixed_ext
- && !riscv_valid_prefixed_ext (subset))
+ && !riscv_recognized_prefixed_ext (subset))
{
rps->error_handler
(_("%s: unknown prefixed ISA extension `%s'"),
diff --git a/gas/testsuite/gas/riscv/march-fail-invalid-x-01.d b/gas/testsuite/gas/riscv/march-fail-invalid-x-01.d
new file mode 100644
index 00000000000..929cfac7a74
--- /dev/null
+++ b/gas/testsuite/gas/riscv/march-fail-invalid-x-01.d
@@ -0,0 +1,3 @@
+#as: -march=rv32i_zicsr2p0_xargle2p
+#source: empty.s
+#error_output: march-fail-invalid.l
diff --git a/gas/testsuite/gas/riscv/march-fail-invalid-x-02.d b/gas/testsuite/gas/riscv/march-fail-invalid-x-02.d
new file mode 100644
index 00000000000..d85f16a42fa
--- /dev/null
+++ b/gas/testsuite/gas/riscv/march-fail-invalid-x-02.d
@@ -0,0 +1,3 @@
+#as: -march=rv32i_zicsr2p0_xargle2p3p0
+#source: empty.s
+#error_output: march-fail-invalid.l
diff --git a/gas/testsuite/gas/riscv/march-fail-invalid-z-01.d b/gas/testsuite/gas/riscv/march-fail-invalid-z-01.d
new file mode 100644
index 00000000000..5ecc72aa312
--- /dev/null
+++ b/gas/testsuite/gas/riscv/march-fail-invalid-z-01.d
@@ -0,0 +1,3 @@
+#as: -march=rv32i_zicsr2p
+#source: empty.s
+#error_output: march-fail-invalid.l
diff --git a/gas/testsuite/gas/riscv/march-fail-invalid-z-02.d b/gas/testsuite/gas/riscv/march-fail-invalid-z-02.d
new file mode 100644
index 00000000000..38e8def0eb6
--- /dev/null
+++ b/gas/testsuite/gas/riscv/march-fail-invalid-z-02.d
@@ -0,0 +1,3 @@
+#as: -march=rv32i_zicsr2p4p0
+#source: empty.s
+#error_output: march-fail-invalid.l
diff --git a/gas/testsuite/gas/riscv/march-fail-invalid.l b/gas/testsuite/gas/riscv/march-fail-invalid.l
new file mode 100644
index 00000000000..804c3617f6f
--- /dev/null
+++ b/gas/testsuite/gas/riscv/march-fail-invalid.l
@@ -0,0 +1,2 @@
+.*Assembler messages:
+.*Error: .*invalid prefixed ISA extension `[0-9a-z]+' ends with <number>p
diff --git a/gas/testsuite/gas/riscv/march-fail-version-x.d b/gas/testsuite/gas/riscv/march-fail-version-x.d
deleted file mode 100644
index 8e140e3d5f3..00000000000
--- a/gas/testsuite/gas/riscv/march-fail-version-x.d
+++ /dev/null
@@ -1,3 +0,0 @@
-#as: -march=rv32i2p_zicsr2p0_xargle2p
-#source: empty.s
-#error_output: march-fail-version.l
diff --git a/gas/testsuite/gas/riscv/march-fail-version-z.d b/gas/testsuite/gas/riscv/march-fail-version-z.d
deleted file mode 100644
index 73ca5794bfe..00000000000
--- a/gas/testsuite/gas/riscv/march-fail-version-z.d
+++ /dev/null
@@ -1,3 +0,0 @@
-#as: -march=rv32i2p_zicsr2p
-#source: empty.s
-#error_output: march-fail-version.l
diff --git a/gas/testsuite/gas/riscv/march-fail-version.l b/gas/testsuite/gas/riscv/march-fail-version.l
deleted file mode 100644
index c7f8a4d5487..00000000000
--- a/gas/testsuite/gas/riscv/march-fail-version.l
+++ /dev/null
@@ -1,3 +0,0 @@
-.*Assembler messages:
-.*Error: cannot find default versions of the ISA extension `p'
-.*Error: .*expect number after `2p'
More information about the Binutils-cvs
mailing list