From c9f279910113d6a10cb64d81aba2c1af9f3c228c Mon Sep 17 00:00:00 2001 From: Nelson Chu Date: Thu, 16 Sep 2021 14:36:54 +0800 Subject: [PATCH] RISC-V: Merged extension string tables and their version tables into one. There are two main reasons for this patch, * In the past we had two extension tables, one is used to record all supported extensions in bfd/elfxx-riscv.c, another is used to get the default extension versions in gas/config/tc-riscv.c. It is hard to maintain lots of tables in different files, but in fact we can merge them into just one table. Therefore, we now define many riscv_supported_std* tables, which record names and versions for all supported extensions. We not only use these tables to initialize the riscv_ext_order, but also use them to get the default versions of extensions, and decide if the extensions should be enbaled by default. * We add a new filed `default_enable' for the riscv_supported_std* tables, to decide if the extension should be enabled by default. For now if the `default_enable' field of the extension is set to EXT_DEFAULT, then we should enable the extension when the -march and elf architecture attributes are not set. In the future, I suppose the `default_enable' can be set to lots of EXT_, each vendor can decide to open which extensions, when the target triple of vendor is chosen. The elf/linux regression tests of riscv-gnu-toolchain are passed. bfd/ * elfnn-riscv.c (cpu-riscv.h): Removed sine it is included in bfd/elfxx-riscv.h. (riscv_merge_std_ext): Updated since the field of rpe is changed. * elfxx-riscv.c (cpu-riscv.h): Removed. (riscv_implicit_subsets): Added implicit extensions for g. (struct riscv_supported_ext): Used to be riscv_ext_version. Moved from gas/config/tc-riscv.c, and added new field `default_enable' to decide if the extension should be enabled by default. (EXT_DEFAULT): Defined for `default_enable' field. (riscv_supported_std_ext): It used to return the supported standard architecture string, but now we move ext_version_table from gas/config/tc-riscv.c to here, and rename it to riscv_supported_std_ext. Currently we not only use the table to initialize riscv_ext_order, but also get the default versions of extensions, and decide if the extensions should be enbaled by default. (riscv_supported_std_z_ext): Likewise, but is used for z* extensions. (riscv_supported_std_s_ext): Likewise, but is used for s* extensions. (riscv_supported_std_h_ext): Likewise, but is used for h* extensions. (riscv_supported_std_zxm_ext): Likewise, but is used for zxm* extensions. (riscv_all_supported_ext): Includes all supported extension tables. (riscv_known_prefixed_ext): Updated. (riscv_valid_prefixed_ext): Updated. (riscv_init_ext_order): Init the riscv_ext_order table according to riscv_supported_std_ext. (riscv_get_default_ext_version): Moved from gas/config/tc-riscv.c. Get the versions of extensions from riscv_supported_std* tables. (riscv_parse_add_subset): Updated. (riscv_parse_std_ext): Updated. (riscv_set_default_arch): Set the default subset list according to the default_enable field of riscv_supported_*ext tables. (riscv_parse_subset): If the input ARCH is NULL, then we call riscv_set_default_arch to set the default subset list. * elfxx-riscv.h (cpu-riscv.h): Included. (riscv_parse_subset_t): Removed get_default_version field, and added isa_spec field to replace it. (extern riscv_supported_std_ext): Removed. gas/ * (bfd/cpu-riscv.h): Removed. (struct riscv_ext_version): Renamed and moved to bfd/elfxx-riscv.c. (ext_version_table): Likewise. (riscv_get_default_ext_version): Likewise. (ext_version_hash): Removed. (init_ext_version_hash): Removed. (riscv_set_arch): Updated since the field of rps is changed. Besides, report error when the architecture string is empty. (riscv_after_parse_args): Updated. --- bfd/elfnn-riscv.c | 7 +- bfd/elfxx-riscv.c | 350 +++++++++++++++++++++++++++--------------- bfd/elfxx-riscv.h | 8 +- gas/config/tc-riscv.c | 126 +-------------- 4 files changed, 235 insertions(+), 256 deletions(-) diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c index a10384cd4d3..2e8df72fa2a 100644 --- a/bfd/elfnn-riscv.c +++ b/bfd/elfnn-riscv.c @@ -32,7 +32,6 @@ #include "elf/riscv.h" #include "opcode/riscv.h" #include "objalloc.h" -#include "cpu-riscv.h" #include #ifndef CHAR_BIT @@ -3443,7 +3442,7 @@ riscv_merge_std_ext (bfd *ibfd, struct riscv_subset_t **pin, struct riscv_subset_t **pout) { - const char *standard_exts = riscv_supported_std_ext (); + const char *standard_exts = "mafdqlcbjtpvn"; const char *p; struct riscv_subset_t *in = *pin; struct riscv_subset_t *out = *pout; @@ -3587,13 +3586,13 @@ riscv_merge_arch_attr_info (bfd *ibfd, char *in_arch, char *out_arch) rpe_in.subset_list = &in_subsets; rpe_in.error_handler = _bfd_error_handler; rpe_in.xlen = &xlen_in; - rpe_in.get_default_version = NULL; + rpe_in.isa_spec = ISA_SPEC_CLASS_NONE; rpe_in.check_unknown_prefixed_ext = false; rpe_out.subset_list = &out_subsets; rpe_out.error_handler = _bfd_error_handler; rpe_out.xlen = &xlen_out; - rpe_out.get_default_version = NULL; + rpe_out.isa_spec = ISA_SPEC_CLASS_NONE; rpe_out.check_unknown_prefixed_ext = false; if (in_arch == NULL && out_arch == NULL) diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c index ddcf872d63c..b467bceb919 100644 --- a/bfd/elfxx-riscv.c +++ b/bfd/elfxx-riscv.c @@ -29,7 +29,6 @@ #include "libiberty.h" #include "elfxx-riscv.h" #include "safe-ctype.h" -#include "cpu-riscv.h" #define MINUS_ONE ((bfd_vma)0 - 1) @@ -1066,6 +1065,11 @@ static struct riscv_implicit_subset riscv_implicit_subsets[] = {"e", "i", check_implicit_always}, {"i", "zicsr", check_implicit_for_i}, {"i", "zifencei", check_implicit_for_i}, + {"g", "i", check_implicit_always}, + {"g", "m", check_implicit_always}, + {"g", "a", check_implicit_always}, + {"g", "f", check_implicit_always}, + {"g", "d", check_implicit_always}, {"g", "zicsr", check_implicit_always}, {"g", "zifencei", check_implicit_always}, {"q", "d", check_implicit_always}, @@ -1074,31 +1078,98 @@ static struct riscv_implicit_subset riscv_implicit_subsets[] = {NULL, NULL, NULL} }; -/* 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. +/* For default_enable field, decide if the extension should + be enbaled by default. */ - 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. */ +#define EXT_DEFAULT 0x1 -static const char * const riscv_std_z_ext_strtab[] = +/* List all extensions that binutils should know about. */ + +struct riscv_supported_ext { - "zba", "zbb", "zbc", "zicsr", "zifencei", "zihintpause", NULL + const char *name; + enum riscv_spec_class isa_spec_class; + int major_version; + int minor_version; + unsigned long default_enable; }; -static const char * const riscv_std_s_ext_strtab[] = +/* The standard extensions must be added in canonical order. */ + +static struct riscv_supported_ext riscv_supported_std_ext[] = { - NULL + {"e", ISA_SPEC_CLASS_20191213, 1, 9, 0 }, + {"e", ISA_SPEC_CLASS_20190608, 1, 9, 0 }, + {"e", ISA_SPEC_CLASS_2P2, 1, 9, 0 }, + {"i", ISA_SPEC_CLASS_20191213, 2, 1, 0 }, + {"i", ISA_SPEC_CLASS_20190608, 2, 1, 0 }, + {"i", ISA_SPEC_CLASS_2P2, 2, 0, 0 }, + /* The g is a special case which we don't want to output it, + but still need it when adding implicit extensions. */ + {"g", ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, EXT_DEFAULT }, + {"m", ISA_SPEC_CLASS_20191213, 2, 0, 0 }, + {"m", ISA_SPEC_CLASS_20190608, 2, 0, 0 }, + {"m", ISA_SPEC_CLASS_2P2, 2, 0, 0 }, + {"a", ISA_SPEC_CLASS_20191213, 2, 1, 0 }, + {"a", ISA_SPEC_CLASS_20190608, 2, 0, 0 }, + {"a", ISA_SPEC_CLASS_2P2, 2, 0, 0 }, + {"f", ISA_SPEC_CLASS_20191213, 2, 2, 0 }, + {"f", ISA_SPEC_CLASS_20190608, 2, 2, 0 }, + {"f", ISA_SPEC_CLASS_2P2, 2, 0, 0 }, + {"d", ISA_SPEC_CLASS_20191213, 2, 2, 0 }, + {"d", ISA_SPEC_CLASS_20190608, 2, 2, 0 }, + {"d", ISA_SPEC_CLASS_2P2, 2, 0, 0 }, + {"q", ISA_SPEC_CLASS_20191213, 2, 2, 0 }, + {"q", ISA_SPEC_CLASS_20190608, 2, 2, 0 }, + {"q", ISA_SPEC_CLASS_2P2, 2, 0, 0 }, + {"l", ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 }, + {"c", ISA_SPEC_CLASS_20191213, 2, 0, 0 }, + {"c", ISA_SPEC_CLASS_20190608, 2, 0, 0 }, + {"c", ISA_SPEC_CLASS_2P2, 2, 0, 0 }, + {"b", ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 }, + {"j", ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 }, + {"t", ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 }, + {"p", ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 }, + {"v", ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 }, + {"n", ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 }, + {NULL, 0, 0, 0, 0} }; -static const char * const riscv_std_h_ext_strtab[] = +static struct riscv_supported_ext riscv_supported_std_z_ext[] = { - NULL + {"zicsr", ISA_SPEC_CLASS_20191213, 2, 0, 0 }, + {"zicsr", ISA_SPEC_CLASS_20190608, 2, 0, 0 }, + {"zifencei", ISA_SPEC_CLASS_20191213, 2, 0, 0 }, + {"zifencei", ISA_SPEC_CLASS_20190608, 2, 0, 0 }, + {"zihintpause", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, + {"zbb", ISA_SPEC_CLASS_DRAFT, 0, 93, 0 }, + {"zba", ISA_SPEC_CLASS_DRAFT, 0, 93, 0 }, + {"zbc", ISA_SPEC_CLASS_DRAFT, 0, 93, 0 }, + {NULL, 0, 0, 0, 0} }; -static const char * const riscv_std_zxm_ext_strtab[] = +static struct riscv_supported_ext riscv_supported_std_s_ext[] = { + {NULL, 0, 0, 0, 0} +}; + +static struct riscv_supported_ext riscv_supported_std_h_ext[] = +{ + {NULL, 0, 0, 0, 0} +}; + +static struct riscv_supported_ext riscv_supported_std_zxm_ext[] = +{ + {NULL, 0, 0, 0, 0} +}; + +const struct riscv_supported_ext *riscv_all_supported_ext[] = +{ + riscv_supported_std_ext, + riscv_supported_std_z_ext, + riscv_supported_std_s_ext, + riscv_supported_std_h_ext, + riscv_supported_std_zxm_ext, NULL }; @@ -1156,11 +1227,11 @@ riscv_get_prefix_class (const char *arch) static bool riscv_known_prefixed_ext (const char *ext, - const char *const *known_exts) + struct riscv_supported_ext *known_exts) { size_t i; - for (i = 0; known_exts[i]; ++i) - if (strcmp (ext, known_exts[i]) == 0) + for (i = 0; known_exts[i].name != NULL; ++i) + if (strcmp (ext, known_exts[i].name) == 0) return true; return false; } @@ -1175,13 +1246,13 @@ riscv_valid_prefixed_ext (const char *ext) switch (class) { case RV_ISA_CLASS_Z: - return riscv_known_prefixed_ext (ext, riscv_std_z_ext_strtab); + return riscv_known_prefixed_ext (ext, riscv_supported_std_z_ext); case RV_ISA_CLASS_ZXM: - return riscv_known_prefixed_ext (ext, riscv_std_zxm_ext_strtab); + return riscv_known_prefixed_ext (ext, riscv_supported_std_zxm_ext); case RV_ISA_CLASS_S: - return riscv_known_prefixed_ext (ext, riscv_std_s_ext_strtab); + return riscv_known_prefixed_ext (ext, riscv_supported_std_s_ext); case RV_ISA_CLASS_H: - return riscv_known_prefixed_ext (ext, riscv_std_h_ext_strtab); + return riscv_known_prefixed_ext (ext, riscv_supported_std_h_ext); case RV_ISA_CLASS_X: /* Only the single x is invalid. */ if (strcmp (ext, "x") != 0) @@ -1201,24 +1272,22 @@ 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; + int 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++; + int i = 0; + while (riscv_supported_std_ext[i].name != NULL) + { + const char *ext = riscv_supported_std_ext[i].name; + riscv_ext_order[(*ext - 'a')] = order++; + i++; + while (riscv_supported_std_ext[i].name + && strcmp (ext, riscv_supported_std_ext[i].name) == 0) + i++; + } /* Some of the prefixed keyword are not single letter, so we set their prefixed orders in the riscv_compare_subsets directly, @@ -1345,6 +1414,46 @@ riscv_add_subset (riscv_subset_list_t *subset_list, subset_list->tail = new; } +/* Get the default versions from the riscv_supported_*ext tables. */ + +static void +riscv_get_default_ext_version (enum riscv_spec_class default_isa_spec, + const char *name, + int *major_version, + int *minor_version) +{ + if (name == NULL || default_isa_spec == ISA_SPEC_CLASS_NONE) + return; + + struct riscv_supported_ext *table = NULL; + enum riscv_prefix_ext_class class = riscv_get_prefix_class (name); + switch (class) + { + case RV_ISA_CLASS_ZXM: table = riscv_supported_std_zxm_ext; break; + case RV_ISA_CLASS_Z: table = riscv_supported_std_z_ext; break; + case RV_ISA_CLASS_S: table = riscv_supported_std_s_ext; break; + case RV_ISA_CLASS_H: table = riscv_supported_std_h_ext; break; + case RV_ISA_CLASS_X: + break; + default: + table = riscv_supported_std_ext; + } + + int i = 0; + while (table != NULL && table[i].name != NULL) + { + if (strcmp (table[i].name, name) == 0 + && (table[i].isa_spec_class == ISA_SPEC_CLASS_DRAFT + || table[i].isa_spec_class == default_isa_spec)) + { + *major_version = table[i].major_version; + *minor_version = table[i].minor_version; + return; + } + i++; + } +} + /* 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. */ @@ -1359,10 +1468,10 @@ riscv_parse_add_subset (riscv_parse_subset_t *rps, int major_version = major; int minor_version = minor; - if ((major_version == RISCV_UNKNOWN_VERSION + 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); + riscv_get_default_ext_version (rps->isa_spec, subset, + &major_version, &minor_version); /* We don't care the versions of the implicit extensions. */ if (!implicit @@ -1476,15 +1585,6 @@ riscv_parsing_subset_version (riscv_parse_subset_t *rps, return p; } -/* Return string which contain all supported standard extensions in - canonical order. */ - -const char * -riscv_supported_std_ext (void) -{ - return "mafdqlcbjtpvn"; -} - /* Parsing function for standard extensions. Return Value: @@ -1500,59 +1600,13 @@ riscv_parse_std_ext (riscv_parse_subset_t *rps, const char *arch, const char *p) { - const char *all_std_exts = riscv_supported_std_ext (); - const char *std_exts = all_std_exts; - int major_version; - int minor_version; - char subset[2] = {0, 0}; - /* First letter must start with i, e or g. */ - switch (*p) + if (*p != 'e' && *p != 'i' && *p != 'g') { - case 'i': - p = riscv_parsing_subset_version (rps, arch, ++p, - &major_version, - &minor_version, true); - riscv_parse_add_subset (rps, "i", - major_version, - minor_version, false); - break; - - case 'e': - p = riscv_parsing_subset_version (rps, arch, ++p, - &major_version, - &minor_version, true); - riscv_parse_add_subset (rps, "e", - major_version, - minor_version, false); - break; - - case 'g': - p = riscv_parsing_subset_version (rps, arch, ++p, - &major_version, - &minor_version, true); - /* Expand g to imafd. */ - riscv_parse_add_subset (rps, "i", - RISCV_UNKNOWN_VERSION, - RISCV_UNKNOWN_VERSION, false); - for ( ; *std_exts != 'q'; std_exts++) - { - subset[0] = *std_exts; - riscv_parse_add_subset (rps, subset, - RISCV_UNKNOWN_VERSION, - RISCV_UNKNOWN_VERSION, false); - } - /* Add g as an implicit extension. */ - riscv_parse_add_subset (rps, "g", - RISCV_UNKNOWN_VERSION, - RISCV_UNKNOWN_VERSION, true); - break; - - default: - rps->error_handler - (_("%s: first ISA extension must be `e', `i' or `g'"), - arch); - return NULL; + rps->error_handler + (_("%s: first ISA extension must be `e', `i' or `g'"), + arch); + return NULL; } while (p != NULL && *p != '\0') @@ -1568,32 +1622,41 @@ riscv_parse_std_ext (riscv_parse_subset_t *rps, continue; } - /* Checking canonical order. */ - char std_ext = *p; - while (*std_exts && std_ext != *std_exts) - std_exts++; + bool implicit = false; + int major = RISCV_UNKNOWN_VERSION; + int minor = RISCV_UNKNOWN_VERSION; + char subset[2] = {0, 0}; - if (std_ext != *std_exts) + subset[0] = *p; + + /* Check if the standard extension is supported. */ + if (riscv_ext_order[(subset[0] - 'a')] == 0) { - if (riscv_ext_order[(std_ext - 'a')] == 0) - rps->error_handler - (_("%s: unknown standard ISA extension `%c'"), - arch, std_ext); - else - rps->error_handler - (_("%s: standard ISA extension `%c' is not " - "in canonical order"), arch, std_ext); + rps->error_handler + (_("%s: unknown standard ISA extension `%c'"), + arch, subset[0]); return NULL; } - std_exts++; - subset[0] = std_ext; - p = riscv_parsing_subset_version (rps, arch, ++p, - &major_version, - &minor_version, true); - riscv_parse_add_subset (rps, subset, - major_version, - minor_version, false); + /* Checking canonical order. */ + if (rps->subset_list->tail != NULL + && riscv_compare_subsets (rps->subset_list->tail->name, subset) > 0) + { + rps->error_handler + (_("%s: standard ISA extension `%c' is not " + "in canonical order"), arch, subset[0]); + return NULL; + } + + p = riscv_parsing_subset_version (rps, arch, ++p, &major, &minor, true); + /* Added g as an implicit extension. */ + if (subset[0] == 'g') + { + implicit = true; + major = RISCV_UNKNOWN_VERSION; + minor = RISCV_UNKNOWN_VERSION; + } + riscv_parse_add_subset (rps, subset, major, minor, implicit); } return p; @@ -1761,6 +1824,30 @@ riscv_parse_check_conflicts (riscv_parse_subset_t *rps) return no_conflict; } +/* Set the default subset list according to the default_enable field + of riscv_supported_*ext tables. */ + +static void +riscv_set_default_arch (riscv_parse_subset_t *rps) +{ + unsigned long enable = EXT_DEFAULT; + int i, j; + for (i = 0; riscv_all_supported_ext[i] != NULL; i++) + { + const struct riscv_supported_ext *table = riscv_all_supported_ext[i]; + for (j = 0; table[j].name != NULL; j++) + { + bool implicit = false; + if (strcmp (table[j].name, "g") == 0) + implicit = true; + if (table[j].default_enable & enable) + riscv_parse_add_subset (rps, table[j].name, + RISCV_UNKNOWN_VERSION, + RISCV_UNKNOWN_VERSION, implicit); + } + } +} + /* Function for parsing ISA string. Return Value: @@ -1776,6 +1863,17 @@ riscv_parse_subset (riscv_parse_subset_t *rps, { const char *p; + /* Init the riscv_ext_order array to compare the order of extensions + quickly. */ + riscv_init_ext_order (); + + if (arch == NULL) + { + riscv_set_default_arch (rps); + riscv_parse_add_implicit_subsets (rps); + return riscv_parse_check_conflicts (rps); + } + for (p = arch; *p != '\0'; p++) { if (ISUPPER (*p)) @@ -1800,11 +1898,13 @@ riscv_parse_subset (riscv_parse_subset_t *rps, } else { - /* ISA string shouldn't be NULL or empty here. However, - it might be empty only when we failed to merge the ISA - string in the riscv_merge_attributes. We have already - issued the correct error message in another side, so do - not issue this error when the ISA string is empty. */ + /* ISA string shouldn't be NULL or empty here. For linker, + it might be empty when we failed to merge the ISA string + in the riscv_merge_attributes. For assembler, we might + give an empty string by .attribute arch, "" or -march=. + However, We have already issued the correct error message + in another side, so do not issue this error when the ISA + string is empty. */ if (strlen (arch)) rps->error_handler ( _("%s: ISA string must begin with rv32 or rv64"), @@ -1812,10 +1912,6 @@ riscv_parse_subset (riscv_parse_subset_t *rps, return false; } - /* Init the riscv_ext_order array to compare the order of extensions - quickly. */ - riscv_init_ext_order (); - /* Parsing standard extension. */ p = riscv_parse_std_ext (rps, arch, p); diff --git a/bfd/elfxx-riscv.h b/bfd/elfxx-riscv.h index 6a2501b7be8..e691a97ecda 100644 --- a/bfd/elfxx-riscv.h +++ b/bfd/elfxx-riscv.h @@ -23,6 +23,7 @@ #include "elf/common.h" #include "elf/internal.h" #include "opcode/riscv.h" +#include "cpu-riscv.h" #define RISCV_UNKNOWN_VERSION -1 @@ -71,9 +72,7 @@ typedef struct void (*error_handler) (const char *, ...) ATTRIBUTE_PRINTF_1; unsigned *xlen; - void (*get_default_version) (const char *, - int *, - int *); + enum riscv_spec_class isa_spec; bool check_unknown_prefixed_ext; } riscv_parse_subset_t; @@ -81,9 +80,6 @@ extern bool riscv_parse_subset (riscv_parse_subset_t *, const char *); -extern const char * -riscv_supported_std_ext (void); - extern void riscv_release_subset_list (riscv_subset_list_t *); diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c index 1dbc4d85b86..e7b733a4e6d 100644 --- a/gas/config/tc-riscv.c +++ b/gas/config/tc-riscv.c @@ -29,7 +29,6 @@ #include "dwarf2dbg.h" #include "dw2gencfi.h" -#include "bfd/cpu-riscv.h" #include "bfd/elfxx-riscv.h" #include "elf/riscv.h" #include "opcode/riscv.h" @@ -88,65 +87,6 @@ struct riscv_csr_extra struct riscv_csr_extra *next; }; -/* All standard/Z* extensions defined in all supported ISA spec. */ -struct riscv_ext_version -{ - const char *name; - enum riscv_spec_class isa_spec_class; - int major_version; - int minor_version; -}; - -static const struct riscv_ext_version ext_version_table[] = -{ - {"e", ISA_SPEC_CLASS_20191213, 1, 9}, - {"e", ISA_SPEC_CLASS_20190608, 1, 9}, - {"e", ISA_SPEC_CLASS_2P2, 1, 9}, - - {"i", ISA_SPEC_CLASS_20191213, 2, 1}, - {"i", ISA_SPEC_CLASS_20190608, 2, 1}, - {"i", ISA_SPEC_CLASS_2P2, 2, 0}, - - {"m", ISA_SPEC_CLASS_20191213, 2, 0}, - {"m", ISA_SPEC_CLASS_20190608, 2, 0}, - {"m", ISA_SPEC_CLASS_2P2, 2, 0}, - - {"a", ISA_SPEC_CLASS_20191213, 2, 1}, - {"a", ISA_SPEC_CLASS_20190608, 2, 0}, - {"a", ISA_SPEC_CLASS_2P2, 2, 0}, - - {"f", ISA_SPEC_CLASS_20191213, 2, 2}, - {"f", ISA_SPEC_CLASS_20190608, 2, 2}, - {"f", ISA_SPEC_CLASS_2P2, 2, 0}, - - {"d", ISA_SPEC_CLASS_20191213, 2, 2}, - {"d", ISA_SPEC_CLASS_20190608, 2, 2}, - {"d", ISA_SPEC_CLASS_2P2, 2, 0}, - - {"q", ISA_SPEC_CLASS_20191213, 2, 2}, - {"q", ISA_SPEC_CLASS_20190608, 2, 2}, - {"q", ISA_SPEC_CLASS_2P2, 2, 0}, - - {"c", ISA_SPEC_CLASS_20191213, 2, 0}, - {"c", ISA_SPEC_CLASS_20190608, 2, 0}, - {"c", ISA_SPEC_CLASS_2P2, 2, 0}, - - {"zicsr", ISA_SPEC_CLASS_20191213, 2, 0}, - {"zicsr", ISA_SPEC_CLASS_20190608, 2, 0}, - - {"zifencei", ISA_SPEC_CLASS_20191213, 2, 0}, - {"zifencei", ISA_SPEC_CLASS_20190608, 2, 0}, - - {"zihintpause", ISA_SPEC_CLASS_DRAFT, 1, 0}, - - {"zbb", ISA_SPEC_CLASS_DRAFT, 0, 93}, - {"zba", ISA_SPEC_CLASS_DRAFT, 0, 93}, - {"zbc", ISA_SPEC_CLASS_DRAFT, 0, 93}, - - /* Terminate the list. */ - {NULL, 0, 0, 0} -}; - #ifndef DEFAULT_ARCH #define DEFAULT_ARCH "riscv64" #endif @@ -349,57 +289,6 @@ riscv_multi_subset_supports (enum riscv_insn_class insn_class) } } -/* Handle of the extension with version hash table. */ -static htab_t ext_version_hash = NULL; - -static htab_t -init_ext_version_hash (void) -{ - const struct riscv_ext_version *table = ext_version_table; - htab_t hash = str_htab_create (); - int i = 0; - - while (table[i].name) - { - const char *name = table[i].name; - if (str_hash_insert (hash, name, &table[i], 0) != NULL) - as_fatal (_("internal: duplicate %s"), name); - - i++; - while (table[i].name - && strcmp (table[i].name, name) == 0) - i++; - } - - return hash; -} - -static void -riscv_get_default_ext_version (const char *name, - int *major_version, - int *minor_version) -{ - struct riscv_ext_version *ext; - - if (name == NULL || default_isa_spec == ISA_SPEC_CLASS_NONE) - return; - - ext = (struct riscv_ext_version *) str_hash_find (ext_version_hash, name); - while (ext - && ext->name - && strcmp (ext->name, name) == 0) - { - if (ext->isa_spec_class == ISA_SPEC_CLASS_DRAFT - || ext->isa_spec_class == default_isa_spec) - { - *major_version = ext->major_version; - *minor_version = ext->minor_version; - return; - } - ext++; - } -} - /* Set which ISA and extensions are available. */ static void @@ -409,11 +298,15 @@ riscv_set_arch (const char *s) rps.subset_list = &riscv_subsets; rps.error_handler = as_bad; rps.xlen = &xlen; - rps.get_default_version = riscv_get_default_ext_version; + rps.isa_spec = default_isa_spec; rps.check_unknown_prefixed_ext = true; - if (s == NULL) - return; + if (s != NULL && strcmp (s, "") == 0) + { + as_bad (_("the architecture string of -march and elf architecture " + "attributes cannot be empty")); + return; + } riscv_release_subset_list (&riscv_subsets); riscv_parse_subset (&rps, s); @@ -3137,11 +3030,6 @@ riscv_after_parse_args (void) else as_bad ("unknown default architecture `%s'", default_arch); } - if (default_arch_with_ext == NULL) - default_arch_with_ext = xlen == 64 ? "rv64g" : "rv32g"; - - /* Initialize the hash table for extensions with default version. */ - ext_version_hash = init_ext_version_hash (); /* Set default specs. */ if (default_isa_spec == ISA_SPEC_CLASS_NONE)