mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-19 17:18:24 +08:00
RISC-V: Improve the version parsing for arch string.
Keep the riscv_add_subset to do the same thing, and use a new function, riscv_parse_add_subset, to cover most of the things when parsing, including find the default versions for extensions, and check whether the versions are valid. The version 0p0 should be an invalid version, that is the mistake I made before. This patch clarify the version rules as follows, * We accept any version of extensions set by users, except 0p0. * The non-standard x extensions must be set with versions in arch string. * If user don't set the versions, or set 0p0 for the extensions, then try to find the supported versions according to the chosen ISA spec. Otherwise, report errors rather than output 0p0 for them. Besides, we use as_bad rather than as_fatal to report more errors for assembler. bfd/ * elfxx-riscv.c (riscv_lookup_subset): Moved to front. (riscv_add_subset): Likewise. (riscv_release_subset_list): Likewise. (riscv_parse_add_subset): New function. Find and check the versions before adding them by riscv_add_subset. (riscv_parsing_subset_version): Remove use_default_version and change the version type from unsigned to int. Set the versions to RISCV_UNKNOWN_VERSION if we can not find them in the arch string. (riscv_parse_std_ext): Updated. (riscv_parse_prefixed_ext): Updated. Since we use as_bad rather than as_fatal to report more errors, return NULL string if the parsed end_of_version is NULL, too. (riscv_parse_subset): Use a new boolean, no_conflict, to report more errors when we have more than one ISA conflicts. * elfxx-riscv.h (RISCV_DONT_CARE_VERSION): Changed to RISCV_UNKNOWN_VERSION. (riscv_lookup_subset_version): Removed. (riscv_parse_subset_t): Updated. gas/ * config/tc-riscv.c (riscv_get_default_ext_version): Change the version type from unsigned to int. (riscv_set_arch): Use as_bad rather than as_fatal to report more errors. * testsuite/gas/riscv/attribute-02.d: Updated since x must be set with versions. * testsuite/gas/riscv/attribute-03.d: Likewise. * testsuite/gas/riscv/march-ok-two-nse.d: Likewise. * testsuite/gas/riscv/attribute-09.d: zicsr wasn't supported in the spec 2.2, so choose the newer spec. * testsuite/gas/riscv/march-fail-base-01.l: Updated since as_bad. * testsuite/gas/riscv/march-fail-base-02.l: Likewise. * testsuite/gas/riscv/march-fail-order-std.l: Likewise. * testsuite/gas/riscv/march-fail-order-x.l: Likewise. * testsuite/gas/riscv/march-fail-order-z.l: Likewise. * testsuite/gas/riscv/march-fail-porder.l: Likewise. * testsuite/gas/riscv/march-fail-rv32ef.l: Likewise. * testsuite/gas/riscv/march-fail-rv32id.l: Likewise. * testsuite/gas/riscv/march-fail-rv32iq.l: Likewise. * testsuite/gas/riscv/march-fail-rv64iq.l: Likewise. * testsuite/gas/riscv/march-fail-single-char.l: Likewise. * testsuite/gas/riscv/march-fail-unknown-std.l: Likewise. * testsuite/gas/riscv/march-fail-unknown.l: Likewise. * testsuite/gas/riscv/march-fail-uppercase.l: Likewise. * testsuite/gas/riscv/march-fail-version.l: Likewise. * testsuite/gas/riscv/march-fail-isa-spec.d: Likewise. * testsuite/gas/riscv/march-fail-isa-spec.l: Likewise. include/ * opcode/riscv.h (riscv_ext_version): Change the version type from unsigned to int.
This commit is contained in:
@ -1,3 +1,25 @@
|
|||||||
|
2020-12-01 Nelson Chu <nelson.chu@sifive.com>
|
||||||
|
|
||||||
|
* elfxx-riscv.c (riscv_lookup_subset): Moved to front.
|
||||||
|
(riscv_add_subset): Likewise.
|
||||||
|
(riscv_release_subset_list): Likewise.
|
||||||
|
(riscv_parse_add_subset): New function. Find and check the
|
||||||
|
versions before adding them by riscv_add_subset.
|
||||||
|
(riscv_parsing_subset_version): Remove use_default_version
|
||||||
|
and change the version type from unsigned to int. Set the
|
||||||
|
versions to RISCV_UNKNOWN_VERSION if we can not find them
|
||||||
|
in the arch string.
|
||||||
|
(riscv_parse_std_ext): Updated.
|
||||||
|
(riscv_parse_prefixed_ext): Updated. Since we use as_bad
|
||||||
|
rather than as_fatal to report more errors, return NULL
|
||||||
|
string if the parsed end_of_version is NULL, too.
|
||||||
|
(riscv_parse_subset): Use a new boolean, no_conflict, to
|
||||||
|
report more errors when we have more than one ISA conflicts.
|
||||||
|
* elfxx-riscv.h (RISCV_DONT_CARE_VERSION): Changed to
|
||||||
|
RISCV_UNKNOWN_VERSION.
|
||||||
|
(riscv_lookup_subset_version): Removed.
|
||||||
|
(riscv_parse_subset_t): Updated.
|
||||||
|
|
||||||
2020-12-01 Nelson Chu <nelson.chu@sifive.com>
|
2020-12-01 Nelson Chu <nelson.chu@sifive.com>
|
||||||
|
|
||||||
* elfxx-riscv.c (riscv_parse_std_ext): Stop parsing standard
|
* elfxx-riscv.c (riscv_parse_std_ext): Stop parsing standard
|
||||||
|
@ -1025,6 +1025,96 @@ riscv_elf_add_sub_reloc (bfd *abfd,
|
|||||||
return bfd_reloc_ok;
|
return bfd_reloc_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Find subset in list, return NULL if not found. */
|
||||||
|
|
||||||
|
riscv_subset_t *
|
||||||
|
riscv_lookup_subset (const riscv_subset_list_t *subset_list,
|
||||||
|
const char *subset)
|
||||||
|
{
|
||||||
|
riscv_subset_t *s;
|
||||||
|
|
||||||
|
for (s = subset_list->head; s != NULL; s = s->next)
|
||||||
|
if (strcasecmp (s->name, subset) == 0)
|
||||||
|
return s;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add extension to the subset list. */
|
||||||
|
|
||||||
|
void
|
||||||
|
riscv_add_subset (riscv_subset_list_t *subset_list,
|
||||||
|
const char *subset,
|
||||||
|
int major,
|
||||||
|
int minor)
|
||||||
|
{
|
||||||
|
riscv_subset_t *s = xmalloc (sizeof *s);
|
||||||
|
|
||||||
|
if (subset_list->head == NULL)
|
||||||
|
subset_list->head = s;
|
||||||
|
|
||||||
|
s->name = xstrdup (subset);
|
||||||
|
s->major_version = major;
|
||||||
|
s->minor_version = minor;
|
||||||
|
s->next = NULL;
|
||||||
|
|
||||||
|
if (subset_list->tail != NULL)
|
||||||
|
subset_list->tail->next = s;
|
||||||
|
subset_list->tail = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find the default versions for the extension before adding them to
|
||||||
|
the subset list, if their versions are RISCV_UNKNOWN_VERSION.
|
||||||
|
Afterwards, report errors if we can not find their default versions. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
riscv_parse_add_subset (riscv_parse_subset_t *rps,
|
||||||
|
const char *subset,
|
||||||
|
int major,
|
||||||
|
int minor)
|
||||||
|
{
|
||||||
|
int major_version = major;
|
||||||
|
int minor_version = minor;
|
||||||
|
|
||||||
|
if ((major_version == RISCV_UNKNOWN_VERSION
|
||||||
|
|| minor_version == RISCV_UNKNOWN_VERSION)
|
||||||
|
&& rps->get_default_version != NULL)
|
||||||
|
rps->get_default_version (subset, &major_version, &minor_version);
|
||||||
|
|
||||||
|
if (major_version == RISCV_UNKNOWN_VERSION
|
||||||
|
|| minor_version == RISCV_UNKNOWN_VERSION)
|
||||||
|
{
|
||||||
|
if (subset[0] == 'x')
|
||||||
|
rps->error_handler
|
||||||
|
(_("x ISA extension `%s' must be set with the versions"),
|
||||||
|
subset);
|
||||||
|
else
|
||||||
|
rps->error_handler
|
||||||
|
(_("cannot find default versions of the ISA extension `%s'"),
|
||||||
|
subset);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
riscv_add_subset (rps->subset_list, subset,
|
||||||
|
major_version, minor_version);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release subset list. */
|
||||||
|
|
||||||
|
void
|
||||||
|
riscv_release_subset_list (riscv_subset_list_t *subset_list)
|
||||||
|
{
|
||||||
|
while (subset_list->head != NULL)
|
||||||
|
{
|
||||||
|
riscv_subset_t *next = subset_list->head->next;
|
||||||
|
free ((void *)subset_list->head->name);
|
||||||
|
free (subset_list->head);
|
||||||
|
subset_list->head = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
subset_list->tail = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Parsing extension version.
|
/* Parsing extension version.
|
||||||
|
|
||||||
Return Value:
|
Return Value:
|
||||||
@ -1034,25 +1124,20 @@ riscv_elf_add_sub_reloc (bfd *abfd,
|
|||||||
`rps`: Hooks and status for parsing extensions.
|
`rps`: Hooks and status for parsing extensions.
|
||||||
`march`: Full arch string.
|
`march`: Full arch string.
|
||||||
`p`: Curent parsing position.
|
`p`: Curent parsing position.
|
||||||
`major_version`: Parsing result of major version, using
|
`major_version`: Parsed major version.
|
||||||
default_major_version if version is not present in arch string.
|
`minor_version`: Parsed minor version.
|
||||||
`minor_version`: Parsing result of minor version, set to 0 if version is
|
`std_ext_p`: True if parsing standard extension. */
|
||||||
not present in arch string, but set to `default_minor_version` if
|
|
||||||
`major_version` using default_major_version.
|
|
||||||
`std_ext_p`: True if parsing std extension.
|
|
||||||
`use_default_version`: Set it to True if we need the default version. */
|
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
riscv_parsing_subset_version (riscv_parse_subset_t *rps,
|
riscv_parsing_subset_version (riscv_parse_subset_t *rps,
|
||||||
const char *march,
|
const char *march,
|
||||||
const char *p,
|
const char *p,
|
||||||
unsigned *major_version,
|
int *major_version,
|
||||||
unsigned *minor_version,
|
int *minor_version,
|
||||||
bfd_boolean std_ext_p,
|
bfd_boolean std_ext_p)
|
||||||
bfd_boolean *use_default_version)
|
|
||||||
{
|
{
|
||||||
bfd_boolean major_p = TRUE;
|
bfd_boolean major_p = TRUE;
|
||||||
unsigned version = 0;
|
int version = 0;
|
||||||
char np;
|
char np;
|
||||||
|
|
||||||
*major_version = 0;
|
*major_version = 0;
|
||||||
@ -1096,11 +1181,13 @@ riscv_parsing_subset_version (riscv_parse_subset_t *rps,
|
|||||||
else
|
else
|
||||||
*minor_version = version;
|
*minor_version = version;
|
||||||
|
|
||||||
/* We can not find any version in string, need to parse default version. */
|
/* We can not find any version in string. */
|
||||||
if (use_default_version != NULL
|
if (*major_version == 0 && *minor_version == 0)
|
||||||
&& *major_version == 0
|
{
|
||||||
&& *minor_version == 0)
|
*major_version = RISCV_UNKNOWN_VERSION;
|
||||||
*use_default_version = TRUE;
|
*minor_version = RISCV_UNKNOWN_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1130,9 +1217,8 @@ riscv_parse_std_ext (riscv_parse_subset_t *rps,
|
|||||||
{
|
{
|
||||||
const char *all_std_exts = riscv_supported_std_ext ();
|
const char *all_std_exts = riscv_supported_std_ext ();
|
||||||
const char *std_exts = all_std_exts;
|
const char *std_exts = all_std_exts;
|
||||||
unsigned major_version = 0;
|
int major_version;
|
||||||
unsigned minor_version = 0;
|
int minor_version;
|
||||||
bfd_boolean use_default_version = FALSE;
|
|
||||||
char subset[2] = {0, 0};
|
char subset[2] = {0, 0};
|
||||||
|
|
||||||
/* First letter must start with i, e or g. */
|
/* First letter must start with i, e or g. */
|
||||||
@ -1141,42 +1227,23 @@ riscv_parse_std_ext (riscv_parse_subset_t *rps,
|
|||||||
case 'i':
|
case 'i':
|
||||||
p = riscv_parsing_subset_version (rps, march, ++p,
|
p = riscv_parsing_subset_version (rps, march, ++p,
|
||||||
&major_version,
|
&major_version,
|
||||||
&minor_version, TRUE,
|
&minor_version, TRUE);
|
||||||
&use_default_version);
|
riscv_parse_add_subset (rps, "i",
|
||||||
/* Find the default version if needed. */
|
major_version,
|
||||||
if (use_default_version
|
minor_version);
|
||||||
&& rps->get_default_version != NULL)
|
|
||||||
rps->get_default_version ("i",
|
|
||||||
&major_version,
|
|
||||||
&minor_version);
|
|
||||||
riscv_add_subset (rps->subset_list, "i",
|
|
||||||
major_version,
|
|
||||||
minor_version);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'e':
|
case 'e':
|
||||||
p = riscv_parsing_subset_version (rps, march, ++p,
|
p = riscv_parsing_subset_version (rps, march, ++p,
|
||||||
&major_version,
|
&major_version,
|
||||||
&minor_version, TRUE,
|
&minor_version, TRUE);
|
||||||
&use_default_version);
|
riscv_parse_add_subset (rps, "e",
|
||||||
/* Find the default version if needed. */
|
major_version,
|
||||||
if (use_default_version
|
minor_version);
|
||||||
&& rps->get_default_version != NULL)
|
|
||||||
rps->get_default_version ("e",
|
|
||||||
&major_version,
|
|
||||||
&minor_version);
|
|
||||||
riscv_add_subset (rps->subset_list, "e",
|
|
||||||
major_version,
|
|
||||||
minor_version);
|
|
||||||
|
|
||||||
/* i-ext must be enabled. */
|
/* i-ext must be enabled. */
|
||||||
if (rps->get_default_version != NULL)
|
riscv_parse_add_subset (rps, "i",
|
||||||
rps->get_default_version ("i",
|
RISCV_UNKNOWN_VERSION,
|
||||||
&major_version,
|
RISCV_UNKNOWN_VERSION);
|
||||||
&minor_version);
|
|
||||||
riscv_add_subset (rps->subset_list, "i",
|
|
||||||
major_version,
|
|
||||||
minor_version);
|
|
||||||
|
|
||||||
if (*rps->xlen > 32)
|
if (*rps->xlen > 32)
|
||||||
{
|
{
|
||||||
@ -1192,27 +1259,17 @@ riscv_parse_std_ext (riscv_parse_subset_t *rps,
|
|||||||
skip the setting if user set a version to it. */
|
skip the setting if user set a version to it. */
|
||||||
p = riscv_parsing_subset_version (rps, march, ++p,
|
p = riscv_parsing_subset_version (rps, march, ++p,
|
||||||
&major_version,
|
&major_version,
|
||||||
&minor_version, TRUE,
|
&minor_version, TRUE);
|
||||||
&use_default_version);
|
|
||||||
/* i-ext must be enabled. */
|
/* i-ext must be enabled. */
|
||||||
if (rps->get_default_version != NULL)
|
riscv_parse_add_subset (rps, "i",
|
||||||
rps->get_default_version ("i",
|
RISCV_UNKNOWN_VERSION,
|
||||||
&major_version,
|
RISCV_UNKNOWN_VERSION);
|
||||||
&minor_version);
|
|
||||||
riscv_add_subset (rps->subset_list, "i",
|
|
||||||
major_version,
|
|
||||||
minor_version);
|
|
||||||
|
|
||||||
for ( ; *std_exts != 'q'; std_exts++)
|
for ( ; *std_exts != 'q'; std_exts++)
|
||||||
{
|
{
|
||||||
subset[0] = *std_exts;
|
subset[0] = *std_exts;
|
||||||
if (rps->get_default_version != NULL)
|
riscv_parse_add_subset (rps, subset,
|
||||||
rps->get_default_version (subset,
|
RISCV_UNKNOWN_VERSION,
|
||||||
&major_version,
|
RISCV_UNKNOWN_VERSION);
|
||||||
&minor_version);
|
|
||||||
riscv_add_subset (rps->subset_list, subset,
|
|
||||||
major_version,
|
|
||||||
minor_version);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1253,21 +1310,13 @@ riscv_parse_std_ext (riscv_parse_subset_t *rps,
|
|||||||
}
|
}
|
||||||
|
|
||||||
std_exts++;
|
std_exts++;
|
||||||
use_default_version = FALSE;
|
|
||||||
subset[0] = std_ext;
|
subset[0] = std_ext;
|
||||||
p = riscv_parsing_subset_version (rps, march, ++p,
|
p = riscv_parsing_subset_version (rps, march, ++p,
|
||||||
&major_version,
|
&major_version,
|
||||||
&minor_version, TRUE,
|
&minor_version, TRUE);
|
||||||
&use_default_version);
|
riscv_parse_add_subset (rps, subset,
|
||||||
/* Find the default version if needed. */
|
major_version,
|
||||||
if (use_default_version
|
minor_version);
|
||||||
&& rps->get_default_version != NULL)
|
|
||||||
rps->get_default_version (subset,
|
|
||||||
&major_version,
|
|
||||||
&minor_version);
|
|
||||||
riscv_add_subset (rps->subset_list, subset,
|
|
||||||
major_version,
|
|
||||||
minor_version);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
@ -1324,11 +1373,10 @@ riscv_parse_prefixed_ext (riscv_parse_subset_t *rps,
|
|||||||
const char *p,
|
const char *p,
|
||||||
const riscv_parse_config_t *config)
|
const riscv_parse_config_t *config)
|
||||||
{
|
{
|
||||||
unsigned major_version = 0;
|
int major_version;
|
||||||
unsigned minor_version = 0;
|
int minor_version;
|
||||||
const char *last_name;
|
const char *last_name;
|
||||||
riscv_isa_ext_class_t class;
|
riscv_isa_ext_class_t class;
|
||||||
bfd_boolean use_default_version;
|
|
||||||
|
|
||||||
while (*p)
|
while (*p)
|
||||||
{
|
{
|
||||||
@ -1352,14 +1400,18 @@ riscv_parse_prefixed_ext (riscv_parse_subset_t *rps,
|
|||||||
while (*++q != '\0' && *q != '_' && !ISDIGIT (*q))
|
while (*++q != '\0' && *q != '_' && !ISDIGIT (*q))
|
||||||
;
|
;
|
||||||
|
|
||||||
use_default_version = FALSE;
|
|
||||||
end_of_version =
|
end_of_version =
|
||||||
riscv_parsing_subset_version (rps, march, q,
|
riscv_parsing_subset_version (rps, march, q,
|
||||||
&major_version,
|
&major_version,
|
||||||
&minor_version, FALSE,
|
&minor_version, FALSE);
|
||||||
&use_default_version);
|
|
||||||
*q = '\0';
|
*q = '\0';
|
||||||
|
|
||||||
|
if (end_of_version == NULL)
|
||||||
|
{
|
||||||
|
free (subset);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check that the prefix extension is known.
|
/* Check that the prefix extension is known.
|
||||||
For 'x', anything goes but it cannot simply be 'x'.
|
For 'x', anything goes but it cannot simply be 'x'.
|
||||||
For 's', it must be known from a list and cannot simply be 's'.
|
For 's', it must be known from a list and cannot simply be 's'.
|
||||||
@ -1399,16 +1451,9 @@ riscv_parse_prefixed_ext (riscv_parse_subset_t *rps,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find the default version if needed. */
|
riscv_parse_add_subset (rps, subset,
|
||||||
if (use_default_version
|
major_version,
|
||||||
&& rps->get_default_version != NULL)
|
minor_version);
|
||||||
rps->get_default_version (subset,
|
|
||||||
&major_version,
|
|
||||||
&minor_version);
|
|
||||||
riscv_add_subset (rps->subset_list, subset,
|
|
||||||
major_version,
|
|
||||||
minor_version);
|
|
||||||
|
|
||||||
free (subset);
|
free (subset);
|
||||||
p += end_of_version - subset;
|
p += end_of_version - subset;
|
||||||
|
|
||||||
@ -1529,6 +1574,7 @@ riscv_parse_subset (riscv_parse_subset_t *rps,
|
|||||||
{
|
{
|
||||||
const char *p;
|
const char *p;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
bfd_boolean no_conflict = TRUE;
|
||||||
|
|
||||||
for (p = arch; *p != '\0'; p++)
|
for (p = arch; *p != '\0'; p++)
|
||||||
{
|
{
|
||||||
@ -1595,7 +1641,7 @@ riscv_parse_subset (riscv_parse_subset_t *rps,
|
|||||||
rps->error_handler
|
rps->error_handler
|
||||||
(_("-march=%s: rv32e does not support the `f' extension"),
|
(_("-march=%s: rv32e does not support the `f' extension"),
|
||||||
arch);
|
arch);
|
||||||
return FALSE;
|
no_conflict = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (riscv_lookup_subset (rps->subset_list, "q") && *rps->xlen < 64)
|
if (riscv_lookup_subset (rps->subset_list, "q") && *rps->xlen < 64)
|
||||||
@ -1603,7 +1649,7 @@ riscv_parse_subset (riscv_parse_subset_t *rps,
|
|||||||
rps->error_handler
|
rps->error_handler
|
||||||
(_("-march=%s: rv32 does not support the `q' extension"),
|
(_("-march=%s: rv32 does not support the `q' extension"),
|
||||||
arch);
|
arch);
|
||||||
return FALSE;
|
no_conflict = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (riscv_lookup_subset (rps->subset_list, "d")
|
if (riscv_lookup_subset (rps->subset_list, "d")
|
||||||
@ -1612,7 +1658,7 @@ riscv_parse_subset (riscv_parse_subset_t *rps,
|
|||||||
rps->error_handler
|
rps->error_handler
|
||||||
(_("-march=%s: `d' extension requires `f' extension"),
|
(_("-march=%s: `d' extension requires `f' extension"),
|
||||||
arch);
|
arch);
|
||||||
return FALSE;
|
no_conflict = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (riscv_lookup_subset (rps->subset_list, "q")
|
if (riscv_lookup_subset (rps->subset_list, "q")
|
||||||
@ -1621,88 +1667,10 @@ riscv_parse_subset (riscv_parse_subset_t *rps,
|
|||||||
rps->error_handler
|
rps->error_handler
|
||||||
(_("-march=%s: `q' extension requires `d' extension"),
|
(_("-march=%s: `q' extension requires `d' extension"),
|
||||||
arch);
|
arch);
|
||||||
return FALSE;
|
no_conflict = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return no_conflict;
|
||||||
}
|
|
||||||
|
|
||||||
/* Add new subset to list. */
|
|
||||||
|
|
||||||
void
|
|
||||||
riscv_add_subset (riscv_subset_list_t *subset_list,
|
|
||||||
const char *subset,
|
|
||||||
int major,
|
|
||||||
int minor)
|
|
||||||
{
|
|
||||||
riscv_subset_t *s = xmalloc (sizeof *s);
|
|
||||||
|
|
||||||
if (subset_list->head == NULL)
|
|
||||||
subset_list->head = s;
|
|
||||||
|
|
||||||
s->name = xstrdup (subset);
|
|
||||||
s->major_version = major;
|
|
||||||
s->minor_version = minor;
|
|
||||||
s->next = NULL;
|
|
||||||
|
|
||||||
if (subset_list->tail != NULL)
|
|
||||||
subset_list->tail->next = s;
|
|
||||||
|
|
||||||
subset_list->tail = s;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find subset in list without version checking, return NULL if not found. */
|
|
||||||
|
|
||||||
riscv_subset_t *
|
|
||||||
riscv_lookup_subset (const riscv_subset_list_t *subset_list,
|
|
||||||
const char *subset)
|
|
||||||
{
|
|
||||||
return riscv_lookup_subset_version
|
|
||||||
(subset_list, subset,
|
|
||||||
RISCV_DONT_CARE_VERSION,
|
|
||||||
RISCV_DONT_CARE_VERSION);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find subset in list with version checking, return NULL if not found. */
|
|
||||||
|
|
||||||
riscv_subset_t *
|
|
||||||
riscv_lookup_subset_version (const riscv_subset_list_t *subset_list,
|
|
||||||
const char *subset,
|
|
||||||
int major, int minor)
|
|
||||||
{
|
|
||||||
riscv_subset_t *s;
|
|
||||||
|
|
||||||
for (s = subset_list->head; s != NULL; s = s->next)
|
|
||||||
if (strcasecmp (s->name, subset) == 0)
|
|
||||||
{
|
|
||||||
if ((major != RISCV_DONT_CARE_VERSION)
|
|
||||||
&& (s->major_version != major))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if ((minor != RISCV_DONT_CARE_VERSION)
|
|
||||||
&& (s->minor_version != minor))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Release subset list. */
|
|
||||||
|
|
||||||
void
|
|
||||||
riscv_release_subset_list (riscv_subset_list_t *subset_list)
|
|
||||||
{
|
|
||||||
while (subset_list->head != NULL)
|
|
||||||
{
|
|
||||||
riscv_subset_t *next = subset_list->head->next;
|
|
||||||
free ((void *)subset_list->head->name);
|
|
||||||
free (subset_list->head);
|
|
||||||
subset_list->head = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
subset_list->tail = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the number of digits for the input. */
|
/* Return the number of digits for the input. */
|
||||||
|
@ -33,7 +33,7 @@ riscv_reloc_type_lookup (bfd *, bfd_reloc_code_real_type);
|
|||||||
extern reloc_howto_type *
|
extern reloc_howto_type *
|
||||||
riscv_elf_rtype_to_howto (bfd *, unsigned int r_type);
|
riscv_elf_rtype_to_howto (bfd *, unsigned int r_type);
|
||||||
|
|
||||||
#define RISCV_DONT_CARE_VERSION -1
|
#define RISCV_UNKNOWN_VERSION -1
|
||||||
|
|
||||||
/* The information of architecture attribute. */
|
/* The information of architecture attribute. */
|
||||||
struct riscv_subset_t
|
struct riscv_subset_t
|
||||||
@ -64,11 +64,6 @@ extern riscv_subset_t *
|
|||||||
riscv_lookup_subset (const riscv_subset_list_t *,
|
riscv_lookup_subset (const riscv_subset_list_t *,
|
||||||
const char *);
|
const char *);
|
||||||
|
|
||||||
extern riscv_subset_t *
|
|
||||||
riscv_lookup_subset_version (const riscv_subset_list_t *,
|
|
||||||
const char *,
|
|
||||||
int, int);
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
riscv_subset_list_t *subset_list;
|
riscv_subset_list_t *subset_list;
|
||||||
@ -76,8 +71,8 @@ typedef struct
|
|||||||
...) ATTRIBUTE_PRINTF_1;
|
...) ATTRIBUTE_PRINTF_1;
|
||||||
unsigned *xlen;
|
unsigned *xlen;
|
||||||
void (*get_default_version) (const char *,
|
void (*get_default_version) (const char *,
|
||||||
unsigned int *,
|
int *,
|
||||||
unsigned int *);
|
int *);
|
||||||
} riscv_parse_subset_t;
|
} riscv_parse_subset_t;
|
||||||
|
|
||||||
extern bfd_boolean
|
extern bfd_boolean
|
||||||
|
@ -1,3 +1,33 @@
|
|||||||
|
2020-12-01 Nelson Chu <nelson.chu@sifive.com>
|
||||||
|
|
||||||
|
* config/tc-riscv.c (riscv_get_default_ext_version):
|
||||||
|
Change the version type from unsigned to int.
|
||||||
|
(riscv_set_arch): Use as_bad rather than as_fatal to
|
||||||
|
report more errors.
|
||||||
|
* testsuite/gas/riscv/attribute-02.d: Updated since x must be
|
||||||
|
set with versions.
|
||||||
|
* testsuite/gas/riscv/attribute-03.d: Likewise.
|
||||||
|
* testsuite/gas/riscv/march-ok-two-nse.d: Likewise.
|
||||||
|
* testsuite/gas/riscv/attribute-09.d: zicsr wasn't supported
|
||||||
|
in the spec 2.2, so choose the newer spec.
|
||||||
|
* testsuite/gas/riscv/march-fail-base-01.l: Updated since as_bad.
|
||||||
|
* testsuite/gas/riscv/march-fail-base-02.l: Likewise.
|
||||||
|
* testsuite/gas/riscv/march-fail-order-std.l: Likewise.
|
||||||
|
* testsuite/gas/riscv/march-fail-order-x.l: Likewise.
|
||||||
|
* testsuite/gas/riscv/march-fail-order-z.l: Likewise.
|
||||||
|
* testsuite/gas/riscv/march-fail-porder.l: Likewise.
|
||||||
|
* testsuite/gas/riscv/march-fail-rv32ef.l: Likewise.
|
||||||
|
* testsuite/gas/riscv/march-fail-rv32id.l: Likewise.
|
||||||
|
* testsuite/gas/riscv/march-fail-rv32iq.l: Likewise.
|
||||||
|
* testsuite/gas/riscv/march-fail-rv64iq.l: Likewise.
|
||||||
|
* testsuite/gas/riscv/march-fail-single-char.l: Likewise.
|
||||||
|
* testsuite/gas/riscv/march-fail-unknown-std.l: Likewise.
|
||||||
|
* testsuite/gas/riscv/march-fail-unknown.l: Likewise.
|
||||||
|
* testsuite/gas/riscv/march-fail-uppercase.l: Likewise.
|
||||||
|
* testsuite/gas/riscv/march-fail-version.l: Likewise.
|
||||||
|
* testsuite/gas/riscv/march-fail-isa-spec.d: Likewise.
|
||||||
|
* testsuite/gas/riscv/march-fail-isa-spec.l: Likewise.
|
||||||
|
|
||||||
2020-12-01 Nelson Chu <nelson.chu@sifive.com>
|
2020-12-01 Nelson Chu <nelson.chu@sifive.com>
|
||||||
|
|
||||||
* testsuite/gas/riscv/march-fail-order-z.d: New testcase, check
|
* testsuite/gas/riscv/march-fail-order-z.d: New testcase, check
|
||||||
|
@ -275,28 +275,25 @@ init_ext_version_hash (const struct riscv_ext_version *table)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
riscv_get_default_ext_version (const char *name,
|
riscv_get_default_ext_version (const char *name,
|
||||||
unsigned int *major_version,
|
int *major_version,
|
||||||
unsigned int *minor_version)
|
int *minor_version)
|
||||||
{
|
{
|
||||||
struct riscv_ext_version *ext;
|
struct riscv_ext_version *ext;
|
||||||
|
|
||||||
*major_version = 0;
|
|
||||||
*minor_version = 0;
|
|
||||||
|
|
||||||
if (name == NULL || default_isa_spec == ISA_SPEC_CLASS_NONE)
|
if (name == NULL || default_isa_spec == ISA_SPEC_CLASS_NONE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ext = (struct riscv_ext_version *) str_hash_find (ext_version_hash, name);
|
ext = (struct riscv_ext_version *) str_hash_find (ext_version_hash, name);
|
||||||
while (ext
|
while (ext
|
||||||
&& ext->name
|
&& ext->name
|
||||||
&& strcmp (ext->name, name) == 0)
|
&& strcmp (ext->name, name) == 0)
|
||||||
{
|
{
|
||||||
if (ext->isa_spec_class == default_isa_spec)
|
if (ext->isa_spec_class == default_isa_spec)
|
||||||
{
|
{
|
||||||
*major_version = ext->major_version;
|
*major_version = ext->major_version;
|
||||||
*minor_version = ext->minor_version;
|
*minor_version = ext->minor_version;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ext++;
|
ext++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -308,7 +305,7 @@ riscv_set_arch (const char *s)
|
|||||||
{
|
{
|
||||||
riscv_parse_subset_t rps;
|
riscv_parse_subset_t rps;
|
||||||
rps.subset_list = &riscv_subsets;
|
rps.subset_list = &riscv_subsets;
|
||||||
rps.error_handler = as_fatal;
|
rps.error_handler = as_bad;
|
||||||
rps.xlen = &xlen;
|
rps.xlen = &xlen;
|
||||||
rps.get_default_version = riscv_get_default_ext_version;
|
rps.get_default_version = riscv_get_default_ext_version;
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#as: -march=rv32gxargle -march-attr -misa-spec=2.2
|
#as: -march=rv32gxargle2p0 -march-attr -misa-spec=2.2
|
||||||
#readelf: -A
|
#readelf: -A
|
||||||
#source: empty.s
|
#source: empty.s
|
||||||
Attribute Section: riscv
|
Attribute Section: riscv
|
||||||
File Attributes
|
File Attributes
|
||||||
Tag_RISCV_arch: "rv32i2p0_m2p0_a2p0_f2p0_d2p0_xargle0p0"
|
Tag_RISCV_arch: "rv32i2p0_m2p0_a2p0_f2p0_d2p0_xargle2p0"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#as: -march=rv32gxargle_xfoo -march-attr -misa-spec=2.2
|
#as: -march=rv32gxargle2p0_xfoo3p0 -march-attr -misa-spec=2.2
|
||||||
#readelf: -A
|
#readelf: -A
|
||||||
#source: empty.s
|
#source: empty.s
|
||||||
Attribute Section: riscv
|
Attribute Section: riscv
|
||||||
File Attributes
|
File Attributes
|
||||||
Tag_RISCV_arch: "rv32i2p0_m2p0_a2p0_f2p0_d2p0_xargle0p0_xfoo0p0"
|
Tag_RISCV_arch: "rv32i2p0_m2p0_a2p0_f2p0_d2p0_xargle2p0_xfoo3p0"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#as: -march-attr -march=rv32i2p1m_zicsr -misa-spec=2.2
|
#as: -march-attr -march=rv32i2p2m_zicsr -misa-spec=20191213
|
||||||
#readelf: -A
|
#readelf: -A
|
||||||
#source: empty.s
|
#source: empty.s
|
||||||
Attribute Section: riscv
|
Attribute Section: riscv
|
||||||
File Attributes
|
File Attributes
|
||||||
Tag_RISCV_arch: "rv32i2p1_m2p0_zicsr0p0"
|
Tag_RISCV_arch: "rv32i2p2_m2p0_zicsr2p0"
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
.*Assembler messages:
|
.*Assembler messages:
|
||||||
.*Fatal error: .*first ISA extension must be `e', `i' or `g'
|
.*Error: .*first ISA extension must be `e', `i' or `g'
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
.*Assembler messages:
|
.*Assembler messages:
|
||||||
.*Fatal error: .*rv64e is not a valid base ISA
|
.*Error: .*rv64e is not a valid base ISA
|
||||||
|
3
gas/testsuite/gas/riscv/march-fail-isa-spec.d
Normal file
3
gas/testsuite/gas/riscv/march-fail-isa-spec.d
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#as: -march=rv32iln_zicsr_xargle_xbargle -misa-spec=20191213
|
||||||
|
#source: empty.s
|
||||||
|
#error_output: march-fail-isa-spec.l
|
5
gas/testsuite/gas/riscv/march-fail-isa-spec.l
Normal file
5
gas/testsuite/gas/riscv/march-fail-isa-spec.l
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
.*Assembler messages:
|
||||||
|
.*Error: cannot find default versions of the ISA extension `l'
|
||||||
|
.*Error: cannot find default versions of the ISA extension `n'
|
||||||
|
.*Error: x ISA extension `xargle' must be set with the versions
|
||||||
|
.*Error: x ISA extension `xbargle' must be set with the versions
|
@ -1,2 +1,2 @@
|
|||||||
.*Assembler messages:
|
.*Assembler messages:
|
||||||
.*Fatal error: .*standard ISA extension `m' is not in canonical order
|
.*Error: .*standard ISA extension `m' is not in canonical order
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
.*Assembler messages:
|
.*Assembler messages:
|
||||||
.*Fatal error: .*x ISA extension `xargle' is not in alphabetical order. It must come before `xbargle'
|
.*Error: .*x ISA extension `xargle' is not in alphabetical order. It must come before `xbargle'
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
.*Assembler messages:
|
.*Assembler messages:
|
||||||
.*Fatal error: .*z ISA extension `zicsr' is not in alphabetical order. It must come before `zifencei'
|
.*Error: .*z ISA extension `zicsr' is not in alphabetical order. It must come before `zifencei'
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
.*Assembler messages:
|
.*Assembler messages:
|
||||||
.*Fatal error: .*unexpected ISA string at end:.*
|
.*Error: .*unexpected ISA string at end:.*
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
.*Assembler messages:
|
.*Assembler messages:
|
||||||
.*Fatal error: .*rv32e does not support the `f' extension
|
.*Error: .*rv32e does not support the `f' extension
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
.*Assembler messages:
|
.*Assembler messages:
|
||||||
.*Fatal error: .*`d' extension requires `f' extension
|
.*Error: .*`d' extension requires `f' extension
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
.*Assembler messages:
|
.*Assembler messages:
|
||||||
.*Fatal error: .*rv32 does not support the `q' extension
|
.*Error: .*rv32 does not support the `q' extension
|
||||||
|
.*Error: .*`q' extension requires `d' extension
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
.*Assembler messages:
|
.*Assembler messages:
|
||||||
.*Fatal error: .*`q' extension requires `d' extension
|
.*Error: .*`q' extension requires `d' extension
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
.*Assembler messages:
|
.*Assembler messages:
|
||||||
.*Fatal error: .*unknown (s|h|z|x) ISA extension `(s|h|z|x)'
|
.*Error: .*unknown (s|h|z|x) ISA extension `(s|h|z|x)'
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
.*Assembler messages:
|
.*Assembler messages:
|
||||||
.*Fatal error: .*unknown standard ISA extension `[^eimafdqiglcbjtpvn]'
|
.*Error: .*unknown standard ISA extension `[^eimafdqiglcbjtpvn]'
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
.*Assembler messages:
|
.*Assembler messages:
|
||||||
.*Fatal error: .*unknown (s|h|z) ISA extension `(s|h|z)foo'
|
.*Error: .*unknown (s|h|z) ISA extension `(s|h|z)foo'
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
.*Assembler messages:
|
.*Assembler messages:
|
||||||
.*Fatal error: .*ISA string cannot contain uppercase letters
|
.*Error: .*ISA string cannot contain uppercase letters
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
.*Assembler messages:
|
.*Assembler messages:
|
||||||
.*Fatal error: .*expect number after `2p'
|
.*Error: cannot find default versions of the ISA extension `p'
|
||||||
|
.*Error: .*expect number after `2p'
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#as: -march=rv32imafd_xargle_xbargle
|
#as: -march=rv32imafd_xargle2p0_xbargle3p0
|
||||||
#objdump: -dr
|
#objdump: -dr
|
||||||
#source: empty.s
|
#source: empty.s
|
||||||
|
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
2020-12-01 Nelson Chu <nelson.chu@sifive.com>
|
||||||
|
|
||||||
|
* opcode/riscv.h (riscv_ext_version):
|
||||||
|
Change the version type from unsigned to int.
|
||||||
|
|
||||||
2020-11-23 Nick Alcock <nick.alcock@oracle.com>
|
2020-11-23 Nick Alcock <nick.alcock@oracle.com>
|
||||||
|
|
||||||
* ctf-api.h: Style nit: remove () on function names in comments.
|
* ctf-api.h: Style nit: remove () on function names in comments.
|
||||||
|
@ -360,8 +360,8 @@ struct riscv_ext_version
|
|||||||
{
|
{
|
||||||
const char *name;
|
const char *name;
|
||||||
enum riscv_isa_spec_class isa_spec_class;
|
enum riscv_isa_spec_class isa_spec_class;
|
||||||
unsigned int major_version;
|
int major_version;
|
||||||
unsigned int minor_version;
|
int minor_version;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* All RISC-V CSR belong to one of these classes. */
|
/* All RISC-V CSR belong to one of these classes. */
|
||||||
|
Reference in New Issue
Block a user