From e601909a3287bf541c6a7d82214bb387d2c76d82 Mon Sep 17 00:00:00 2001 From: Nelson Chu Date: Wed, 7 Apr 2021 12:50:19 +0800 Subject: [PATCH] RISC-V: Support to parse the multi-letter prefix in the architecture string. The original discussion is as follows, https://github.com/riscv/riscv-isa-manual/issues/637 I never considered the prefixes may have multiple letters, like zxm. But the ISA spec has been updated for a long time that I haven't noticed. This patch rewrites the part of architecture parser to support parsing the multi-letter prefixes. Besides, I also improve the parser to report errors in details. One of the most obvious improvement is - Do not parse the prefixed extensions according to the orders in the parse_config. If we do so, then we used to get "unexpected ISA string at end" errors, but the message is a little bit hard to know what is happening. I Remove the confused message, and let riscv_parse_prefixed_ext to report the details. bfd/ * elfxx-riscv.c (riscv_std_z_ext_strtab): Moved forward. (riscv_std_s_ext_strtab): Likewise. (riscv_std_h_ext_strtab): Likewise. (riscv_std_zxm_ext_strtab): Added for the zxm prefix. (enum riscv_prefix_ext_class): Moved forward and renamed from riscv_isa_ext_class. Reorder them according to the parsing order, since the enum values are used to check the orders in the riscv_compare_subsets. (struct riscv_parse_prefix_config): Moved forward and renamed from riscv_parse_config_t. Also removed the ext_valid_p field, the related functions are replaced by riscv_valid_prefixed_ext. (parse_config): Moved forward and updated. The more letters of the prefix string, the more forward it must be defined. Otherwise, we will get the wrong mapping when using strncmp in riscv_get_prefix_class. (riscv_get_prefix_class): Moved forward. Support to parse the multi-letter prefix, like zxm. (riscv_known_prefixed_ext): New function, check if the prefixed extension is supported according to the right riscv_std_*_ext_strtab. (riscv_valid_prefixed_ext): New function, used to replace the riscv_ext_*_valid_p functions. (riscv_init_ext_order): Do not set the values for prefix keywords since they may have multiple letters for now. (riscv_compare_subsets): Set the order values of prefix keywords to negative numbers according to the riscv_prefix_ext_class. (riscv_parse_std_ext): Call riscv_get_prefix_class to see if we have parsed the prefixed extensions. (riscv_parse_prefixed_ext): Updated and removed the parameter config. Report error when the prefix is unknown. (riscv_parse_subset): Do not parse the prefixed extensions according to the orders in the parse_config. Remove the confused message and let riscv_parse_prefixed_ext to report the details. * elfxx-riscv.h (enum riscv_isa_ext_class): Moved to elfxx-riscv.c. (riscv_get_prefix_class): Removed to static. gas/ * testsuite/gas/riscv/march-fail-order-x-std.d: Renamed from march-fail-porder-x-std.d. * testsuite/gas/riscv/march-fail-order-z-std.d: Renamed from march-fail-porder-z-std.d. * testsuite/gas/riscv/march-fail-order-x-z.d: Renamed from march-fail-porder-x-z.d. * testsuite/gas/riscv/march-fail-order-zx-std.l: Added to replace march-fail-porder.l. * testsuite/gas/riscv/march-fail-order-x-z.l: Likewise. * testsuite/gas/riscv/march-fail-order-x.l: Updated. * testsuite/gas/riscv/march-fail-order-z.l: Likewise. * testsuite/gas/riscv/march-fail-single-prefix-h.d: Renamed from march-fail-single-char-h.d. * testsuite/gas/riscv/march-fail-single-prefix-s.d: Renamed from march-fail-single-char-s.d. * testsuite/gas/riscv/march-fail-single-prefix-x.d: Renamed from march-fail-single-char-x.d. * testsuite/gas/riscv/march-fail-single-prefix-z.d: Renamed from march-fail-single-char-z.d. * testsuite/gas/riscv/march-fail-single-prefix-zmx.d: Added. * testsuite/gas/riscv/march-fail-single-prefix.l: Added to replace march-fail-single-prefix.l. * testsuite/gas/riscv/march-fail-unknown-zxm.d: Added. * testsuite/gas/riscv/march-fail-unknown-std.l: Updated. * testsuite/gas/riscv/march-fail-unknown.l: Likewise. --- bfd/ChangeLog | 36 ++ bfd/elfxx-riscv.c | 395 +++++++++--------- bfd/elfxx-riscv.h | 13 - gas/ChangeLog | 28 ++ ...order-x-std.d => march-fail-order-x-std.d} | 2 +- ...il-porder-x-z.d => march-fail-order-x-z.d} | 2 +- .../gas/riscv/march-fail-order-x-z.l | 2 + gas/testsuite/gas/riscv/march-fail-order-x.l | 2 +- ...order-z-std.d => march-fail-order-z-std.d} | 2 +- gas/testsuite/gas/riscv/march-fail-order-z.l | 2 +- .../gas/riscv/march-fail-order-zx-std.l | 2 + gas/testsuite/gas/riscv/march-fail-porder.l | 2 - .../gas/riscv/march-fail-single-char-h.d | 3 - .../gas/riscv/march-fail-single-char-s.d | 3 - .../gas/riscv/march-fail-single-char-x.d | 3 - .../gas/riscv/march-fail-single-char-z.d | 3 - .../gas/riscv/march-fail-single-char.l | 2 - .../gas/riscv/march-fail-single-prefix-h.d | 3 + .../gas/riscv/march-fail-single-prefix-s.d | 3 + .../gas/riscv/march-fail-single-prefix-x.d | 3 + .../gas/riscv/march-fail-single-prefix-z.d | 3 + .../gas/riscv/march-fail-single-prefix-zxm.d | 3 + .../gas/riscv/march-fail-single-prefix.l | 2 + .../gas/riscv/march-fail-unknown-std.l | 2 +- .../gas/riscv/march-fail-unknown-zxm.d | 3 + gas/testsuite/gas/riscv/march-fail-unknown.l | 2 +- 26 files changed, 291 insertions(+), 235 deletions(-) rename gas/testsuite/gas/riscv/{march-fail-porder-x-std.d => march-fail-order-x-std.d} (54%) rename gas/testsuite/gas/riscv/{march-fail-porder-x-z.d => march-fail-order-x-z.d} (58%) create mode 100644 gas/testsuite/gas/riscv/march-fail-order-x-z.l rename gas/testsuite/gas/riscv/{march-fail-porder-z-std.d => march-fail-order-z-std.d} (54%) create mode 100644 gas/testsuite/gas/riscv/march-fail-order-zx-std.l delete mode 100644 gas/testsuite/gas/riscv/march-fail-porder.l delete mode 100644 gas/testsuite/gas/riscv/march-fail-single-char-h.d delete mode 100644 gas/testsuite/gas/riscv/march-fail-single-char-s.d delete mode 100644 gas/testsuite/gas/riscv/march-fail-single-char-x.d delete mode 100644 gas/testsuite/gas/riscv/march-fail-single-char-z.d delete mode 100644 gas/testsuite/gas/riscv/march-fail-single-char.l create mode 100644 gas/testsuite/gas/riscv/march-fail-single-prefix-h.d create mode 100644 gas/testsuite/gas/riscv/march-fail-single-prefix-s.d create mode 100644 gas/testsuite/gas/riscv/march-fail-single-prefix-x.d create mode 100644 gas/testsuite/gas/riscv/march-fail-single-prefix-z.d create mode 100644 gas/testsuite/gas/riscv/march-fail-single-prefix-zxm.d create mode 100644 gas/testsuite/gas/riscv/march-fail-single-prefix.l create mode 100644 gas/testsuite/gas/riscv/march-fail-unknown-zxm.d diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 6d1880a62ea..266ebf3b572 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,39 @@ +2021-04-12 Nelson Chu + + * elfxx-riscv.c (riscv_std_z_ext_strtab): Moved forward. + (riscv_std_s_ext_strtab): Likewise. + (riscv_std_h_ext_strtab): Likewise. + (riscv_std_zxm_ext_strtab): Added for the zxm prefix. + (enum riscv_prefix_ext_class): Moved forward and renamed from + riscv_isa_ext_class. Reorder them according to the parsing order, + since the enum values are used to check the orders in the + riscv_compare_subsets. + (struct riscv_parse_prefix_config): Moved forward and renamed from + riscv_parse_config_t. Also removed the ext_valid_p field, the + related functions are replaced by riscv_valid_prefixed_ext. + (parse_config): Moved forward and updated. The more letters of the + prefix string, the more forward it must be defined. Otherwise, we + will get the wrong mapping when using strncmp in riscv_get_prefix_class. + (riscv_get_prefix_class): Moved forward. Support to parse the + multi-letter prefix, like zxm. + (riscv_known_prefixed_ext): New function, check if the prefixed + extension is supported according to the right riscv_std_*_ext_strtab. + (riscv_valid_prefixed_ext): New function, used to replace the + riscv_ext_*_valid_p functions. + (riscv_init_ext_order): Do not set the values for prefix keywords + since they may have multiple letters for now. + (riscv_compare_subsets): Set the order values of prefix keywords + to negative numbers according to the riscv_prefix_ext_class. + (riscv_parse_std_ext): Call riscv_get_prefix_class to see if we + have parsed the prefixed extensions. + (riscv_parse_prefixed_ext): Updated and removed the parameter config. + Report error when the prefix is unknown. + (riscv_parse_subset): Do not parse the prefixed extensions according + to the orders in the parse_config. Remove the confused message and + let riscv_parse_prefixed_ext to report the details. + * elfxx-riscv.h (enum riscv_isa_ext_class): Moved to elfxx-riscv.c. + (riscv_get_prefix_class): Removed to static. + 2021-04-08 Mike Frysinger * configure.ac (ACX_BUGURL): Use https://. diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c index f6a2509d521..a8613d86bc4 100644 --- a/bfd/elfxx-riscv.c +++ b/bfd/elfxx-riscv.c @@ -1028,16 +1028,167 @@ riscv_elf_add_sub_reloc (bfd *abfd, #define RISCV_UNKNOWN_VERSION -1 -/* Array is used to compare the orders of all extensions quickly. +/* Lists of prefixed class extensions that binutils should know about. + Whether or not a particular entry is in these lists will dictate if + gas/ld will accept its presence in the architecture string. + + Please add the extensions to the lists in lower case. However, keep + these subsets in alphabetical order in these tables is recommended, + although there is no impact on the current implementation. */ + +static const char * const riscv_std_z_ext_strtab[] = +{ + "zba", "zbb", "zbc", "zicsr", "zifencei", "zihintpause", NULL +}; + +static const char * const riscv_std_s_ext_strtab[] = +{ + NULL +}; + +static const char * const riscv_std_h_ext_strtab[] = +{ + NULL +}; + +static const char * const riscv_std_zxm_ext_strtab[] = +{ + NULL +}; + +/* ISA extension prefixed name class. Must define them in parsing order. */ +enum riscv_prefix_ext_class +{ + RV_ISA_CLASS_Z = 1, + RV_ISA_CLASS_S, + RV_ISA_CLASS_H, + RV_ISA_CLASS_ZXM, + RV_ISA_CLASS_X, + RV_ISA_CLASS_UNKNOWN +}; + +/* Record the strings of the prefixed extensions, and their corresponding + classes. The more letters of the prefix string, the more forward it must + be defined. Otherwise, the riscv_get_prefix_class will map it to the + wrong classes. */ +struct riscv_parse_prefix_config +{ + /* Class of the extension. */ + enum riscv_prefix_ext_class class; + + /* Prefix string for error printing and internal parser usage. */ + const char *prefix; +}; +static const struct riscv_parse_prefix_config parse_config[] = +{ + {RV_ISA_CLASS_ZXM, "zxm"}, + {RV_ISA_CLASS_Z, "z"}, + {RV_ISA_CLASS_S, "s"}, + {RV_ISA_CLASS_H, "h"}, + {RV_ISA_CLASS_X, "x"}, + {RV_ISA_CLASS_UNKNOWN, NULL} +}; + +/* Get the prefixed name class for the extensions, the class also + means the order of the prefixed extensions. */ + +static enum riscv_prefix_ext_class +riscv_get_prefix_class (const char *arch) +{ + int i = 0; + while (parse_config[i].class != RV_ISA_CLASS_UNKNOWN) + { + if (strncmp (arch, parse_config[i].prefix, + strlen (parse_config[i].prefix)) == 0) + return parse_config[i].class; + i++; + } + return RV_ISA_CLASS_UNKNOWN; +} + +/* Check KNOWN_EXTS to see if the EXT is supported. */ + +static bool +riscv_known_prefixed_ext (const char *ext, + const char *const *known_exts) +{ + size_t i; + for (i = 0; known_exts[i]; ++i) + if (strcmp (ext, known_exts[i]) == 0) + return true; + return false; +} - Zero value: Preserved keyword. - Negative value: Prefixed keyword (s, h, x, z). - Positive value: Standard extension. */ +/* Check whether the prefixed extension is valid or not. Return + true if valid, otehrwise return false. */ + +static bool +riscv_valid_prefixed_ext (const char *ext) +{ + enum riscv_prefix_ext_class class = riscv_get_prefix_class (ext); + switch (class) + { + case RV_ISA_CLASS_Z: + return riscv_known_prefixed_ext (ext, riscv_std_z_ext_strtab); + case RV_ISA_CLASS_ZXM: + return riscv_known_prefixed_ext (ext, riscv_std_zxm_ext_strtab); + case RV_ISA_CLASS_S: + return riscv_known_prefixed_ext (ext, riscv_std_s_ext_strtab); + case RV_ISA_CLASS_H: + return riscv_known_prefixed_ext (ext, riscv_std_h_ext_strtab); + case RV_ISA_CLASS_X: + /* Only the single x is invalid. */ + if (strcmp (ext, "x") != 0) + return true; + default: + break; + } + return false; +} + +/* Array is used to compare the orders of standard extensions quickly. */ static int riscv_ext_order[26] = {0}; +/* Init the riscv_ext_order array. */ + +static void +riscv_init_ext_order (void) +{ + static bool inited = false; + const char *std_base_exts = "eig"; + const char *std_remain_exts = riscv_supported_std_ext (); + const char *ext; + int order; + + if (inited) + return; + + /* The orders of all standard extensions are positive. */ + order = 1; + + /* Init the standard base extensions first. */ + for (ext = std_base_exts; *ext; ext++) + riscv_ext_order[(*ext - 'a')] = order++; + + /* Init the standard remaining extensions. */ + for (ext = std_remain_exts; *ext; ext++) + riscv_ext_order[(*ext - 'a')] = order++; + + /* Some of the prefixed keyword are not single letter, so we set + their prefixed orders in the riscv_compare_subsets directly, + not through the riscv_ext_order. */ + + inited = true; +} + /* Similar to the strcmp. It returns an integer less than, equal to, or greater than zero if `subset2` is found, respectively, to be less - than, to match, or be greater than `subset1`. */ + than, to match, or be greater than `subset1`. + + The order values, + Zero: Preserved keywords. + Positive number: Standard extensions. + Negative number: Prefixed keywords. */ int riscv_compare_subsets (const char *subset1, const char *subset2) @@ -1049,10 +1200,19 @@ riscv_compare_subsets (const char *subset1, const char *subset2) if (order1 > 0 && order2 > 0) return order1 - order2; - if (order1 == order2 && order1 < 0) + /* Set the prefixed orders to negative numbers. */ + enum riscv_prefix_ext_class class1 = riscv_get_prefix_class (subset1); + enum riscv_prefix_ext_class class2 = riscv_get_prefix_class (subset2); + + if (class1 != RV_ISA_CLASS_UNKNOWN) + order1 = - (int) class1; + if (class2 != RV_ISA_CLASS_UNKNOWN) + order2 = - (int) class2; + + if (order1 == order2) { /* Compare the standard addition z extensions. */ - if (*subset1 == 'z') + if (class1 == RV_ISA_CLASS_Z) { order1 = riscv_ext_order[(*++subset1 - 'a')]; order2 = riscv_ext_order[(*++subset2 - 'a')]; @@ -1403,7 +1563,9 @@ riscv_parse_std_ext (riscv_parse_subset_t *rps, while (p != NULL && *p != '\0') { - if (*p == 'x' || *p == 's' || *p == 'h' || *p == 'z') + /* Stop when we parsed the known prefix class. */ + enum riscv_prefix_ext_class class = riscv_get_prefix_class (p); + if (class != RV_ISA_CLASS_UNKNOWN) break; if (*p == '_') @@ -1419,10 +1581,10 @@ riscv_parse_std_ext (riscv_parse_subset_t *rps, if (std_ext != *std_exts) { - if (strchr (all_std_exts, std_ext) == NULL) + if (riscv_ext_order[(std_ext - 'a')] == 0) rps->error_handler - (_("-march=%s: unknown standard ISA extension `%c'"), - march, std_ext); + (_("-march=%s: unknown standard and prefixed ISA " + "extension `%s'"), march, p); else rps->error_handler (_("-march=%s: standard ISA extension `%c' is not " @@ -1443,38 +1605,6 @@ riscv_parse_std_ext (riscv_parse_subset_t *rps, return p; } -/* Classify ARCH into one of riscv_isa_ext_class_t. */ - -riscv_isa_ext_class_t -riscv_get_prefix_class (const char *arch) -{ - switch (*arch) - { - case 's': return RV_ISA_CLASS_S; - case 'h': return RV_ISA_CLASS_H; - case 'x': return RV_ISA_CLASS_X; - case 'z': return RV_ISA_CLASS_Z; - default: return RV_ISA_CLASS_UNKNOWN; - } -} - -/* Structure describing parameters to use when parsing a particular - riscv_isa_ext_class_t. One of these should be provided for each - possible class, except RV_ISA_CLASS_UNKNOWN. */ -typedef struct riscv_parse_config -{ - /* Class of the extension. */ - riscv_isa_ext_class_t class; - - /* Prefix string for error printing and internal parser usage. */ - const char *prefix; - - /* Predicate which is used for checking whether this is a "known" - extension. For 'x', it always returns true since they are by - definition non-standard and cannot be known. */ - bool (*ext_valid_p) (const char *); -} riscv_parse_config_t; - /* Parsing function for prefixed extensions. Return Value: @@ -1490,13 +1620,12 @@ typedef struct riscv_parse_config static const char * riscv_parse_prefixed_ext (riscv_parse_subset_t *rps, const char *march, - const char *p, - const riscv_parse_config_t *config) + const char *p) { int major_version; int minor_version; const char *last_name; - riscv_isa_ext_class_t class; + enum riscv_prefix_ext_class class; while (*p) { @@ -1506,12 +1635,14 @@ riscv_parse_prefixed_ext (riscv_parse_subset_t *rps, continue; } - /* Assert that the current extension specifier matches our parsing - class. */ class = riscv_get_prefix_class (p); - if (class != config->class - || class == RV_ISA_CLASS_UNKNOWN) - break; + if (class == RV_ISA_CLASS_UNKNOWN) + { + rps->error_handler + (_("-march=%s: unknown prefix class for the ISA extension `%s'"), + march, p); + return NULL; + } char *subset = xstrdup (p); char *q = subset; @@ -1532,18 +1663,18 @@ riscv_parse_prefixed_ext (riscv_parse_subset_t *rps, return NULL; } - /* Check that the prefix extension is known. + /* Check if the prefix extension is known. 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 'h', it must be known from a list and cannot simply be 'h'. For 'z', it must be known from a list and cannot simply be 'z'. */ /* Check that the extension name is well-formed. */ - if (!config->ext_valid_p (subset)) + if (!riscv_valid_prefixed_ext (subset)) { rps->error_handler - (_("-march=%s: unknown %s ISA extension `%s'"), - march, config->prefix, subset); + (_("-march=%s: unknown prefixed ISA extension `%s'"), + march, subset); free (subset); return NULL; } @@ -1553,19 +1684,19 @@ riscv_parse_prefixed_ext (riscv_parse_subset_t *rps, if (!strcasecmp (last_name, subset)) { rps->error_handler - (_("-march=%s: duplicate %s ISA extension `%s'"), - march, config->prefix, subset); + (_("-march=%s: duplicate prefixed ISA extension `%s'"), + march, subset); free (subset); return NULL; } - /* Check that the extension is in alphabetical order. */ + /* Check that the extension is in expected order. */ if (riscv_compare_subsets (last_name, subset) > 0) { rps->error_handler - (_("-march=%s: %s ISA extension `%s' is not in alphabetical " + (_("-march=%s: prefixed ISA extension `%s' is not in expected " "order. It must come before `%s'"), - march, config->prefix, subset, last_name); + march, subset, last_name); free (subset); return NULL; } @@ -1579,8 +1710,8 @@ riscv_parse_prefixed_ext (riscv_parse_subset_t *rps, if (*p != '\0' && *p != '_') { rps->error_handler - (_("-march=%s: %s ISA extension must separate with _"), - march, config->prefix); + (_("-march=%s: prefixed ISA extension must separate with _"), + march); return NULL; } } @@ -1588,132 +1719,6 @@ riscv_parse_prefixed_ext (riscv_parse_subset_t *rps, return p; } -/* Lists of prefixed class extensions that binutils should know about. - Whether or not a particular entry is in these lists will dictate if - gas/ld will accept its presence in the architecture string. - - Please add the extensions to the lists in lower case. However, keep - these subsets in alphabetical order in these tables is recommended, - although there is no impact on the current implementation. */ - -static const char * const riscv_std_z_ext_strtab[] = -{ - "zba", "zbb", "zbc", "zicsr", "zifencei", "zihintpause", NULL -}; - -static const char * const riscv_std_s_ext_strtab[] = -{ - NULL -}; - -static const char * const riscv_std_h_ext_strtab[] = -{ - NULL -}; - -/* For the extension `ext`, search through the list of known extensions - `known_exts` for a match, and return TRUE if found. */ - -static bool -riscv_multi_letter_ext_valid_p (const char *ext, - const char *const *known_exts) -{ - size_t i; - - for (i = 0; known_exts[i]; ++i) - if (!strcmp (ext, known_exts[i])) - return true; - - return false; -} - -/* Predicator function for x-prefixed extensions. - Anything goes, except the literal 'x'. */ - -static bool -riscv_ext_x_valid_p (const char *arg) -{ - if (!strcasecmp (arg, "x")) - return false; - - return true; -} - -/* Predicator functions for z-prefixed extensions. - Only known z-extensions are permitted. */ - -static bool -riscv_ext_z_valid_p (const char *arg) -{ - return riscv_multi_letter_ext_valid_p (arg, riscv_std_z_ext_strtab); -} - -/* Predicator function for 's' prefixed extensions. - Only known s-extensions are permitted. */ - -static bool -riscv_ext_s_valid_p (const char *arg) -{ - return riscv_multi_letter_ext_valid_p (arg, riscv_std_s_ext_strtab); -} - -/* Predicator function for 'h' prefixed extensions. - Only known h-extensions are permitted. */ - -static bool -riscv_ext_h_valid_p (const char *arg) -{ - return riscv_multi_letter_ext_valid_p (arg, riscv_std_h_ext_strtab); -} - -/* Parsing order of the prefixed extensions that is specified by - the ISA spec. */ -static const riscv_parse_config_t parse_config[] = -{ - {RV_ISA_CLASS_S, "s", riscv_ext_s_valid_p}, - {RV_ISA_CLASS_H, "h", riscv_ext_h_valid_p}, - {RV_ISA_CLASS_Z, "z", riscv_ext_z_valid_p}, - {RV_ISA_CLASS_X, "x", riscv_ext_x_valid_p}, - {RV_ISA_CLASS_UNKNOWN, NULL, NULL} -}; - -/* Init the riscv_ext_order array. */ - -static void -riscv_init_ext_order (void) -{ - static bool inited = false; - const char *std_base_exts = "eig"; - const char *std_remain_exts = riscv_supported_std_ext (); - const char *ext; - unsigned int i; - int order; - - if (inited) - return; - - /* The orders of all standard extensions are positive. */ - order = 1; - - /* Init the standard base extensions first. */ - for (ext = std_base_exts; *ext; ext++) - riscv_ext_order[(*ext - 'a')] = order++; - - /* Init the standard remaining extensions. */ - for (ext = std_remain_exts; *ext; ext++) - riscv_ext_order[(*ext - 'a')] = order++; - - /* Init the order for prefixed keywords. The orders are negative. */ - order = -1; - for (i = 0; parse_config[i].class != RV_ISA_CLASS_UNKNOWN; i++) - { - ext = parse_config[i].prefix; - riscv_ext_order[(*ext - 'a')] = order--; - } - - inited = true; -} - /* Add the implicit extensions. */ static void @@ -1787,7 +1792,6 @@ riscv_parse_subset (riscv_parse_subset_t *rps, { riscv_subset_t *subset = NULL; const char *p; - size_t i; bool no_conflict = true; for (p = arch; *p != '\0'; p++) @@ -1837,19 +1841,12 @@ riscv_parse_subset (riscv_parse_subset_t *rps, return false; /* Parse the different classes of extensions in the specified order. */ - for (i = 0; i < ARRAY_SIZE (parse_config); ++i) + while (*p != '\0') { - p = riscv_parse_prefixed_ext (rps, arch, p, &parse_config[i]); + p = riscv_parse_prefixed_ext (rps, arch, p); if (p == NULL) - return false; - } - - if (*p != '\0') - { - rps->error_handler (_("-march=%s: unexpected ISA string at end: %s"), - arch, p); - return false; + return false; } /* Finally add implicit extensions according to the current diff --git a/bfd/elfxx-riscv.h b/bfd/elfxx-riscv.h index 10b78ee4916..2955b753fca 100644 --- a/bfd/elfxx-riscv.h +++ b/bfd/elfxx-riscv.h @@ -90,19 +90,6 @@ riscv_arch_str (unsigned, const riscv_subset_list_t *); extern size_t riscv_estimate_digit (unsigned); -/* ISA extension prefixed name class. */ -typedef enum riscv_isa_ext_class -{ - RV_ISA_CLASS_S, - RV_ISA_CLASS_H, - RV_ISA_CLASS_Z, - RV_ISA_CLASS_X, - RV_ISA_CLASS_UNKNOWN -} riscv_isa_ext_class_t; - -riscv_isa_ext_class_t -riscv_get_prefix_class (const char *); - extern int riscv_compare_subsets (const char *, const char *); diff --git a/gas/ChangeLog b/gas/ChangeLog index 13e427284ec..15e4c071929 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,31 @@ +2021-04-12 Nelson Chu + + * testsuite/gas/riscv/march-fail-order-x-std.d: Renamed from + march-fail-porder-x-std.d. + * testsuite/gas/riscv/march-fail-order-z-std.d: Renamed from + march-fail-porder-z-std.d. + * testsuite/gas/riscv/march-fail-order-x-z.d: Renamed from + march-fail-porder-x-z.d. + * testsuite/gas/riscv/march-fail-order-zx-std.l: Added to replace + march-fail-porder.l. + * testsuite/gas/riscv/march-fail-order-x-z.l: Likewise. + * testsuite/gas/riscv/march-fail-order-x.l: Updated. + * testsuite/gas/riscv/march-fail-order-z.l: Likewise. + * testsuite/gas/riscv/march-fail-single-prefix-h.d: Renamed from + march-fail-single-char-h.d. + * testsuite/gas/riscv/march-fail-single-prefix-s.d: Renamed from + march-fail-single-char-s.d. + * testsuite/gas/riscv/march-fail-single-prefix-x.d: Renamed from + march-fail-single-char-x.d. + * testsuite/gas/riscv/march-fail-single-prefix-z.d: Renamed from + march-fail-single-char-z.d. + * testsuite/gas/riscv/march-fail-single-prefix-zmx.d: Added. + * testsuite/gas/riscv/march-fail-single-prefix.l: Added to replace + march-fail-single-prefix.l. + * testsuite/gas/riscv/march-fail-unknown-zxm.d: Added. + * testsuite/gas/riscv/march-fail-unknown-std.l: Updated. + * testsuite/gas/riscv/march-fail-unknown.l: Likewise. + 2021-04-09 Tejas Belagod * config/tc-aarch64.c (warn_unpredictable_ldst): Clean-up diagnostic messages diff --git a/gas/testsuite/gas/riscv/march-fail-porder-x-std.d b/gas/testsuite/gas/riscv/march-fail-order-x-std.d similarity index 54% rename from gas/testsuite/gas/riscv/march-fail-porder-x-std.d rename to gas/testsuite/gas/riscv/march-fail-order-x-std.d index 2bef073464d..4762f3dd95c 100644 --- a/gas/testsuite/gas/riscv/march-fail-porder-x-std.d +++ b/gas/testsuite/gas/riscv/march-fail-order-x-std.d @@ -1,3 +1,3 @@ #as: -march=rv32i_xargle2p0_mafd #source: empty.s -#error_output: march-fail-porder.l +#error_output: march-fail-order-zx-std.l diff --git a/gas/testsuite/gas/riscv/march-fail-porder-x-z.d b/gas/testsuite/gas/riscv/march-fail-order-x-z.d similarity index 58% rename from gas/testsuite/gas/riscv/march-fail-porder-x-z.d rename to gas/testsuite/gas/riscv/march-fail-order-x-z.d index 094180ddd08..7245e68e0ea 100644 --- a/gas/testsuite/gas/riscv/march-fail-porder-x-z.d +++ b/gas/testsuite/gas/riscv/march-fail-order-x-z.d @@ -1,3 +1,3 @@ #as: -march=rv32i_xargle2p0_zicsr2p0 #source: empty.s -#error_output: march-fail-porder.l +#error_output: march-fail-order-x-z.l diff --git a/gas/testsuite/gas/riscv/march-fail-order-x-z.l b/gas/testsuite/gas/riscv/march-fail-order-x-z.l new file mode 100644 index 00000000000..53ea8201187 --- /dev/null +++ b/gas/testsuite/gas/riscv/march-fail-order-x-z.l @@ -0,0 +1,2 @@ +.*Assembler messages: +.*Error: .*prefixed ISA extension `zicsr' is not in expected order. It must come before `xargle' diff --git a/gas/testsuite/gas/riscv/march-fail-order-x.l b/gas/testsuite/gas/riscv/march-fail-order-x.l index 025db146867..cfb118528df 100644 --- a/gas/testsuite/gas/riscv/march-fail-order-x.l +++ b/gas/testsuite/gas/riscv/march-fail-order-x.l @@ -1,2 +1,2 @@ .*Assembler messages: -.*Error: .*x ISA extension `xargle' is not in alphabetical order. It must come before `xbargle' +.*Error: .*prefixed ISA extension `xargle' is not in expected order. It must come before `xbargle' diff --git a/gas/testsuite/gas/riscv/march-fail-porder-z-std.d b/gas/testsuite/gas/riscv/march-fail-order-z-std.d similarity index 54% rename from gas/testsuite/gas/riscv/march-fail-porder-z-std.d rename to gas/testsuite/gas/riscv/march-fail-order-z-std.d index 1fa1a159f3a..42526de3621 100644 --- a/gas/testsuite/gas/riscv/march-fail-porder-z-std.d +++ b/gas/testsuite/gas/riscv/march-fail-order-z-std.d @@ -1,3 +1,3 @@ #as: -march=rv32i_zicsr2p0_mafd #source: empty.s -#error_output: march-fail-porder.l +#error_output: march-fail-order-zx-std.l diff --git a/gas/testsuite/gas/riscv/march-fail-order-z.l b/gas/testsuite/gas/riscv/march-fail-order-z.l index a98c53a279d..468c412051f 100644 --- a/gas/testsuite/gas/riscv/march-fail-order-z.l +++ b/gas/testsuite/gas/riscv/march-fail-order-z.l @@ -1,2 +1,2 @@ .*Assembler messages: -.*Error: .*z ISA extension `zicsr' is not in alphabetical order. It must come before `zifencei' +.*Error: .*prefixed ISA extension `zicsr' is not in expected order. It must come before `zifencei' diff --git a/gas/testsuite/gas/riscv/march-fail-order-zx-std.l b/gas/testsuite/gas/riscv/march-fail-order-zx-std.l new file mode 100644 index 00000000000..4f6b98c592e --- /dev/null +++ b/gas/testsuite/gas/riscv/march-fail-order-zx-std.l @@ -0,0 +1,2 @@ +.*Assembler messages: +.*Error: .*unknown prefix class for the ISA extension `mafd' diff --git a/gas/testsuite/gas/riscv/march-fail-porder.l b/gas/testsuite/gas/riscv/march-fail-porder.l deleted file mode 100644 index c5496eab499..00000000000 --- a/gas/testsuite/gas/riscv/march-fail-porder.l +++ /dev/null @@ -1,2 +0,0 @@ -.*Assembler messages: -.*Error: .*unexpected ISA string at end:.* diff --git a/gas/testsuite/gas/riscv/march-fail-single-char-h.d b/gas/testsuite/gas/riscv/march-fail-single-char-h.d deleted file mode 100644 index 7fca9576bf3..00000000000 --- a/gas/testsuite/gas/riscv/march-fail-single-char-h.d +++ /dev/null @@ -1,3 +0,0 @@ -#as: -march=rv32ih -#source: empty.s -#error_output: march-fail-single-char.l diff --git a/gas/testsuite/gas/riscv/march-fail-single-char-s.d b/gas/testsuite/gas/riscv/march-fail-single-char-s.d deleted file mode 100644 index b3aace9122b..00000000000 --- a/gas/testsuite/gas/riscv/march-fail-single-char-s.d +++ /dev/null @@ -1,3 +0,0 @@ -#as: -march=rv32is -#source: empty.s -#error_output: march-fail-single-char.l diff --git a/gas/testsuite/gas/riscv/march-fail-single-char-x.d b/gas/testsuite/gas/riscv/march-fail-single-char-x.d deleted file mode 100644 index 585608cb82e..00000000000 --- a/gas/testsuite/gas/riscv/march-fail-single-char-x.d +++ /dev/null @@ -1,3 +0,0 @@ -#as: -march=rv32ix -#source: empty.s -#error_output: march-fail-single-char.l diff --git a/gas/testsuite/gas/riscv/march-fail-single-char-z.d b/gas/testsuite/gas/riscv/march-fail-single-char-z.d deleted file mode 100644 index daf96d2124d..00000000000 --- a/gas/testsuite/gas/riscv/march-fail-single-char-z.d +++ /dev/null @@ -1,3 +0,0 @@ -#as: -march=rv32iz -#source: empty.s -#error_output: march-fail-single-char.l diff --git a/gas/testsuite/gas/riscv/march-fail-single-char.l b/gas/testsuite/gas/riscv/march-fail-single-char.l deleted file mode 100644 index 435d0b23a4f..00000000000 --- a/gas/testsuite/gas/riscv/march-fail-single-char.l +++ /dev/null @@ -1,2 +0,0 @@ -.*Assembler messages: -.*Error: .*unknown (s|h|z|x) ISA extension `(s|h|z|x)' diff --git a/gas/testsuite/gas/riscv/march-fail-single-prefix-h.d b/gas/testsuite/gas/riscv/march-fail-single-prefix-h.d new file mode 100644 index 00000000000..eb101bd7135 --- /dev/null +++ b/gas/testsuite/gas/riscv/march-fail-single-prefix-h.d @@ -0,0 +1,3 @@ +#as: -march=rv32ih +#source: empty.s +#error_output: march-fail-single-prefix.l diff --git a/gas/testsuite/gas/riscv/march-fail-single-prefix-s.d b/gas/testsuite/gas/riscv/march-fail-single-prefix-s.d new file mode 100644 index 00000000000..8b6b0d0f34d --- /dev/null +++ b/gas/testsuite/gas/riscv/march-fail-single-prefix-s.d @@ -0,0 +1,3 @@ +#as: -march=rv32is +#source: empty.s +#error_output: march-fail-single-prefix.l diff --git a/gas/testsuite/gas/riscv/march-fail-single-prefix-x.d b/gas/testsuite/gas/riscv/march-fail-single-prefix-x.d new file mode 100644 index 00000000000..9e87801c95c --- /dev/null +++ b/gas/testsuite/gas/riscv/march-fail-single-prefix-x.d @@ -0,0 +1,3 @@ +#as: -march=rv32ix +#source: empty.s +#error_output: march-fail-single-prefix.l diff --git a/gas/testsuite/gas/riscv/march-fail-single-prefix-z.d b/gas/testsuite/gas/riscv/march-fail-single-prefix-z.d new file mode 100644 index 00000000000..4ae26926230 --- /dev/null +++ b/gas/testsuite/gas/riscv/march-fail-single-prefix-z.d @@ -0,0 +1,3 @@ +#as: -march=rv32iz +#source: empty.s +#error_output: march-fail-single-prefix.l diff --git a/gas/testsuite/gas/riscv/march-fail-single-prefix-zxm.d b/gas/testsuite/gas/riscv/march-fail-single-prefix-zxm.d new file mode 100644 index 00000000000..bdf6f86784a --- /dev/null +++ b/gas/testsuite/gas/riscv/march-fail-single-prefix-zxm.d @@ -0,0 +1,3 @@ +#as: -march=rv32izxm +#source: empty.s +#error_output: march-fail-single-prefix.l diff --git a/gas/testsuite/gas/riscv/march-fail-single-prefix.l b/gas/testsuite/gas/riscv/march-fail-single-prefix.l new file mode 100644 index 00000000000..13942ed6664 --- /dev/null +++ b/gas/testsuite/gas/riscv/march-fail-single-prefix.l @@ -0,0 +1,2 @@ +.*Assembler messages: +.*Error: .*unknown prefixed ISA extension `(s|h|z|x|zxm)' diff --git a/gas/testsuite/gas/riscv/march-fail-unknown-std.l b/gas/testsuite/gas/riscv/march-fail-unknown-std.l index 75cdda38942..0e9add79056 100644 --- a/gas/testsuite/gas/riscv/march-fail-unknown-std.l +++ b/gas/testsuite/gas/riscv/march-fail-unknown-std.l @@ -1,2 +1,2 @@ .*Assembler messages: -.*Error: .*unknown standard ISA extension `[^eimafdqiglcbjtpvn]' +.*Error: .*unknown standard and prefixed ISA extension `y' diff --git a/gas/testsuite/gas/riscv/march-fail-unknown-zxm.d b/gas/testsuite/gas/riscv/march-fail-unknown-zxm.d new file mode 100644 index 00000000000..b3d46032ea5 --- /dev/null +++ b/gas/testsuite/gas/riscv/march-fail-unknown-zxm.d @@ -0,0 +1,3 @@ +#as: -march=rv32izxmfoo2p0 +#source: empty.s +#error_output: march-fail-unknown.l diff --git a/gas/testsuite/gas/riscv/march-fail-unknown.l b/gas/testsuite/gas/riscv/march-fail-unknown.l index 874b8d461ba..0cc8096fed4 100644 --- a/gas/testsuite/gas/riscv/march-fail-unknown.l +++ b/gas/testsuite/gas/riscv/march-fail-unknown.l @@ -1,2 +1,2 @@ .*Assembler messages: -.*Error: .*unknown (s|h|z) ISA extension `(s|h|z)foo' +.*Error: .*unknown prefixed ISA extension `(s|h|z|zxm)foo' -- 2.30.2