{
riscv_subset_t *s, *pre_s = NULL;
+ /* If the subset is added in order, then just add it at the tail. */
+ if (subset_list->tail != NULL
+ && riscv_compare_subsets (subset_list->tail->name, subset) < 0)
+ {
+ *current = subset_list->tail;
+ return false;
+ }
+
for (s = subset_list->head;
s != NULL;
pre_s = s, s = s->next)
break;
}
*current = pre_s;
+
return false;
}
-/* Add extension from ISA string to the last of the subset list. */
+/* Add the extension to the subset list. Search the
+ list first, and then find the right place to add. */
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;
-}
-
-/* Add the implicit extension to the subset list. Search the
- list first, and then find the right place to add. */
-
-static void
-riscv_add_implicit_subset (riscv_subset_list_t *subset_list,
- const char *subset,
- int major,
- int minor)
{
riscv_subset_t *current, *new;
new->next = subset_list->head;
subset_list->head = new;
}
-}
-/* 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
- directly, without searching.
+ if (new->next == NULL)
+ subset_list->tail = new;
+}
- Find the default versions for the extension before adding them to
+/* 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. */
return;
}
- if (!implicit)
- riscv_add_subset (rps->subset_list, subset,
- major_version, minor_version);
- else
- riscv_add_implicit_subset (rps->subset_list, subset,
- major_version, minor_version);
+ riscv_add_subset (rps->subset_list, subset,
+ major_version, minor_version);
}
/* Release subset list. */
Arguments:
`rps`: Hooks and status for parsing extensions.
- `march`: Full ISA string.
+ `arch`: Full ISA string.
`p`: Curent parsing position.
`major_version`: Parsed major version.
`minor_version`: Parsed minor version.
static const char *
riscv_parsing_subset_version (riscv_parse_subset_t *rps,
- const char *march,
+ const char *arch,
const char *p,
int *major_version,
int *minor_version,
else
{
rps->error_handler
- (_("-march=%s: expect number after `%dp'"),
- march, version);
+ (_("%s: expect number after `%dp'"),
+ arch, version);
return NULL;
}
}
Arguments:
`rps`: Hooks and status for parsing extensions.
- `march`: Full ISA string.
+ `arch`: Full ISA string.
`p`: Curent parsing position. */
static const char *
riscv_parse_std_ext (riscv_parse_subset_t *rps,
- const char *march,
+ const char *arch,
const char *p)
{
const char *all_std_exts = riscv_supported_std_ext ();
switch (*p)
{
case 'i':
- p = riscv_parsing_subset_version (rps, march, ++p,
+ p = riscv_parsing_subset_version (rps, arch, ++p,
&major_version,
&minor_version, true);
riscv_parse_add_subset (rps, "i",
break;
case 'e':
- p = riscv_parsing_subset_version (rps, march, ++p,
+ p = riscv_parsing_subset_version (rps, arch, ++p,
&major_version,
&minor_version, true);
riscv_parse_add_subset (rps, "e",
major_version,
minor_version, false);
- if (*rps->xlen > 32)
- {
- rps->error_handler
- (_("-march=%s: rv%de is not a valid base ISA"),
- march, *rps->xlen);
- return NULL;
- }
break;
case 'g':
- p = riscv_parsing_subset_version (rps, march, ++p,
+ p = riscv_parsing_subset_version (rps, arch, ++p,
&major_version,
&minor_version, true);
/* Expand g to imafd. */
default:
rps->error_handler
- (_("-march=%s: first ISA extension must be `e', `i' or `g'"),
- march);
+ (_("%s: first ISA extension must be `e', `i' or `g'"),
+ arch);
return NULL;
}
{
if (riscv_ext_order[(std_ext - 'a')] == 0)
rps->error_handler
- (_("-march=%s: unknown standard and prefixed ISA "
- "extension `%s'"), march, p);
+ (_("%s: unknown standard ISA extension `%c'"),
+ arch, std_ext);
else
rps->error_handler
- (_("-march=%s: standard ISA extension `%c' is not "
- "in canonical order"), march, std_ext);
+ (_("%s: standard ISA extension `%c' is not "
+ "in canonical order"), arch, std_ext);
return NULL;
}
std_exts++;
subset[0] = std_ext;
- p = riscv_parsing_subset_version (rps, march, ++p,
+ p = riscv_parsing_subset_version (rps, arch, ++p,
&major_version,
&minor_version, true);
riscv_parse_add_subset (rps, subset,
Arguments:
`rps`: Hooks and status for parsing extensions.
- `march`: Full ISA string.
+ `arch`: Full ISA string.
`p`: Curent parsing position. */
static const char *
riscv_parse_prefixed_ext (riscv_parse_subset_t *rps,
- const char *march,
+ const char *arch,
const char *p)
{
int major_version;
if (class == RV_ISA_CLASS_UNKNOWN)
{
rps->error_handler
- (_("-march=%s: unknown prefix class for the ISA extension `%s'"),
- march, p);
+ (_("%s: unknown prefix class for the ISA extension `%s'"),
+ arch, p);
return NULL;
}
;
end_of_version =
- riscv_parsing_subset_version (rps, march, q,
+ riscv_parsing_subset_version (rps, arch, q,
&major_version,
&minor_version, false);
*q = '\0';
&& !riscv_valid_prefixed_ext (subset))
{
rps->error_handler
- (_("-march=%s: unknown prefixed ISA extension `%s'"),
- march, subset);
+ (_("%s: unknown prefixed ISA extension `%s'"),
+ arch, subset);
free (subset);
return NULL;
}
if (!strcasecmp (last_name, subset))
{
rps->error_handler
- (_("-march=%s: duplicate prefixed ISA extension `%s'"),
- march, subset);
+ (_("%s: duplicate prefixed ISA extension `%s'"),
+ arch, subset);
free (subset);
return NULL;
}
if (riscv_compare_subsets (last_name, subset) > 0)
{
rps->error_handler
- (_("-march=%s: prefixed ISA extension `%s' is not in expected "
+ (_("%s: prefixed ISA extension `%s' is not in expected "
"order. It must come before `%s'"),
- march, subset, last_name);
+ arch, subset, last_name);
free (subset);
return NULL;
}
if (*p != '\0' && *p != '_')
{
rps->error_handler
- (_("-march=%s: prefixed ISA extension must separate with _"),
- march);
+ (_("%s: prefixed ISA extension must separate with _"),
+ arch);
return NULL;
}
}
}
}
+/* Check extensions conflicts. */
+
+static bool
+riscv_parse_check_conflicts (riscv_parse_subset_t *rps)
+{
+ riscv_subset_t *subset = NULL;
+ int xlen = *rps->xlen;
+ bool no_conflict = true;
+
+ if (riscv_lookup_subset (rps->subset_list, "e", &subset)
+ && xlen > 32)
+ {
+ rps->error_handler
+ (_("rv%d does not support the `e' extension"), xlen);
+ no_conflict = false;
+ }
+ if (riscv_lookup_subset (rps->subset_list, "q", &subset)
+ && xlen < 64)
+ {
+ rps->error_handler
+ (_("rv%d does not support the `q' extension"), xlen);
+ no_conflict = false;
+ }
+ if (riscv_lookup_subset (rps->subset_list, "e", &subset)
+ && riscv_lookup_subset (rps->subset_list, "f", &subset))
+ {
+ rps->error_handler
+ (_("rv32e does not support the `f' extension"));
+ no_conflict = false;
+ }
+ return no_conflict;
+}
+
/* Function for parsing ISA string.
Return Value:
riscv_parse_subset (riscv_parse_subset_t *rps,
const char *arch)
{
- riscv_subset_t *subset = NULL;
const char *p;
- bool no_conflict = true;
for (p = arch; *p != '\0'; p++)
{
if (ISUPPER (*p))
{
rps->error_handler
- (_("-march=%s: ISA string cannot contain uppercase letters"),
+ (_("%s: ISA string cannot contain uppercase letters"),
arch);
return false;
}
not issue this error when the ISA string is empty. */
if (strlen (arch))
rps->error_handler (
- _("-march=%s: ISA string must begin with rv32 or rv64"),
+ _("%s: ISA string must begin with rv32 or rv64"),
arch);
return false;
}
riscv_parse_add_implicit_subsets (rps);
/* Check the conflicts. */
- if (riscv_lookup_subset (rps->subset_list, "e", &subset)
- && riscv_lookup_subset (rps->subset_list, "f", &subset))
- {
- rps->error_handler
- (_("-march=%s: rv32e does not support the `f' extension"),
- arch);
- no_conflict = false;
- }
- if (riscv_lookup_subset (rps->subset_list, "q", &subset)
- && *rps->xlen < 64)
- {
- rps->error_handler
- (_("-march=%s: rv32 does not support the `q' extension"),
- arch);
- no_conflict = false;
- }
- return no_conflict;
+ return riscv_parse_check_conflicts (rps);
}
/* Return the number of digits for the input. */