From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pl1-x641.google.com (mail-pl1-x641.google.com [IPv6:2607:f8b0:4864:20::641]) by sourceware.org (Postfix) with ESMTPS id 3E63E385BF81 for ; Sat, 18 Apr 2020 11:08:19 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 3E63E385BF81 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=sifive.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=nelson.chu@sifive.com Received: by mail-pl1-x641.google.com with SMTP id h11so1975292plr.11 for ; Sat, 18 Apr 2020 04:08:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=BxYV5mrKLPnnFJxopzSgZv7LapA8yNM/ACnfyhw3D90=; b=KRFy7Ek+OUBGKQN4ySjyFExmMZBqOfBjEy8p9wk2tnHEwORNcYxOnxRdYm722Wb7C6 gKU5t6zsvIlpFNxkVq0KT0J2jepN3/+sgKKM9Q5mp9Ht+tgsofGCgyCWi9K/nhENUsqE UpdfYr0JA2l3fktH0jKzaMxEgX8B70BspAtxggvaQ0JnBuBwoS4ZWfzG9OqJCkSDyDjJ gxSN+kfnNoBOTWmFZTl6ZH6I9UN5ceWCPTTAzJ3bTAXdZoQk7yrnzZrb3o3QnDfz42Sp qrOkSCH2Z2s1jPVdjuKso2tC+EPtmhSM+m+e3x8TAq9StMAHdeqz7rtaf/hrvCqDGp74 j/Rg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=BxYV5mrKLPnnFJxopzSgZv7LapA8yNM/ACnfyhw3D90=; b=UWGbMIIB57K1kVKZwtzCQ4N8ZGoFTiPZYGDJLjR0Ssr4sA26rCDMrKsuiTQAGWDtZu MHpQjuHHJRvUj+iQ7S+kWMjrBu+eUT5cRGmbeyoNVGyZ+KDkB2cVL80o8hvymgkUbHfu w8QVntwQE6eFjWQ7ZgCzZkw1Sn8Mh8102LeweQR/p6Qltyixvyhc5T1fJUX95mHcJYDh O2sfERPMAfbd7lfojs/lazwvmV+NagmGNqmceNgAmQlL2e0681KeTBY05Ua+6F5HqS3t mewjBoj2Q5thhBBRkmKdyb5FcQ690rVrHoZwEikVUfuHhZ1vh0iKx62v79hwqKkaGrZV H8hw== X-Gm-Message-State: AGi0PuZ/lka6HC78zKZ0sPl6O5rSjWM8YfyobzutxpDjYdmGNDyQ1s1x ZBshBu4EqejhAZdNe0mg99A/Fw== X-Google-Smtp-Source: APiQypJZYeTOadrjMTEgQmRyY+6wdc15hLCAcmmmZiQCTz2rOvX9/I1YcoLkN0HC3q6UBG9u9BaIvA== X-Received: by 2002:a17:902:b60d:: with SMTP id b13mr8123994pls.324.1587208097138; Sat, 18 Apr 2020 04:08:17 -0700 (PDT) Received: from gamma05.internal.sifive.com ([64.62.193.194]) by smtp.gmail.com with ESMTPSA id fy21sm8008313pjb.25.2020.04.18.04.08.16 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 18 Apr 2020 04:08:16 -0700 (PDT) From: Nelson Chu To: binutils@sourceware.org, gdb-patches@sourceware.org Cc: andrew.burgess@embecosm.com, andrew@sifive.com, asb@lowrisc.org, kito.cheng@sifive.com, maxim.blinov@embecosm.com, jimw@sifive.com Subject: [PATCH 3/7] RISC-V: Support new GAS options and configure options to set ISA versions. Date: Sat, 18 Apr 2020 04:07:51 -0700 Message-Id: <1587208075-2462-4-git-send-email-nelson.chu@sifive.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1587208075-2462-1-git-send-email-nelson.chu@sifive.com> References: <1587208075-2462-1-git-send-email-nelson.chu@sifive.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-21.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_BARRACUDACENTRAL, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 18 Apr 2020 11:08:24 -0000 For now, we can only use the GAS option -march and ELF arch attribute to set the versions for ISA extensions. It seems not so friendly for user. Therefore, we support new GAS options and configure options to make it easiler for user. New Assembler Options, * -misa-spec = [2p0|2p1|2p2|20190608|20191213] You can simply choose the ISA spec by this option, and then assembler will set the version for the standard extensions if you don’t set in the ELF arch attributes or -march option. * -mriscv-isa-version = The syntax of is same as -march option, but without rv32 or rv64 prefix. There are two reasons that you may need this option, 1. Some versions of extensions defined in the ISA spec are not matched to the toolchain’s implementation. For example, V-ext is defined to version 0.7 in ISA spec, but we only have implementations for 0.8 and 0.9. Therefore, you have to use this option to choose the correct version for V-ext. 2. You want to update the version for the specific standard extensions if the version are not set in the ELF arch attributes and -march option. New Default Configure Options, * --with-arch = The syntax of is same as -march option. Assembler will check this if -march option and ELF arch attributes aren’t set. * --with-isa-spec = [2p0|2p1|2p2|20190608|20191213] The syntax is same as -misa-spec option. Assembler will check this if -misa-spec option isn’t set. * --with-riscv-isa-version = The syntax of is same as -mriscv-isa-version option. Assembler will check this if -mriscv-isa-version option isn’t set. The Priority of these options, * ELF arch attributes > Assembler options > Default configure options * For GAS options, -march > -mriscv-isa-version > -misa-spec * For configure options, --with-arch > --with-riscv-isa-version > --with-isa-spec gas/ * config/tc-riscv.c (DEFAULT_ARCH_WITH_EXT, DEFAULT_ISA_SPEC, DEFAULT_RISCV_ISA_VERSION): Default configure option settings. You can set them by new configure options --with-arch, --with-isa-spec and --with-riscv-isa-version. (default_arch_with_ext, default_isa_spec, default_riscv_isa_version): const char strings which are used to set the ISA extensions. You can use gas options -march (or ELF build attributes), and new gas options -misa-spec and -mriscv-isa-version to set them, respectively. If the gas options and attributes are not set, then assembler will check the default configure option settings. (ext_version_hash): The hash table used to handle the extensions with versions. (init_ext_version_hash): Initialize the ext_version_hash according to riscv_ext_version_table. (riscv_get_default_ext_version): The callback function of riscv_parse_subset_t. According to the choosed ISA spec, get the default version for the specific extension. (riscv_set_arch): Add new bfd_boolean parameter update_version. The update_version is TRUE means we just want to update the version according to default_riscv_isa_version, so don't call the riscv_release_subset_list to reset the subset list. Pass two new arguments to riscv_parse_subset, one is update_version mentioned above, the other is the default_isa_spec. We use the default_isa_spec to choose the default version for the extensions. (enum options, struct option md_longopts): Add new gas options, -misa-spec and -mriscv-isa-version. (md_parse_option): Handle the above new gas options. (riscv_after_parse_args): Call init_ext_version_hash to initialize the ext_version_hash, and then always call riscv_set_arch twice to set and update the architecture with versions according to default_arch_with_ext and default_riscv_isa_version. (s_riscv_attribute): Same as riscv_after_parse_args, we need to call riscv_set_arch twice. * testsuite/gas/riscv/attribute-01.d: Add -misa-spec=2p2. Set 0p0 as default version for x extensions. * testsuite/gas/riscv/attribute-02.d: Likewise. * testsuite/gas/riscv/attribute-03.d: Likewise. * testsuite/gas/riscv/attribute-04.d: Likewise. * testsuite/gas/riscv/attribute-05.d: Likewise. * testsuite/gas/riscv/attribute-06.d: Likewise. * testsuite/gas/riscv/attribute-07.d: Likewise. * testsuite/gas/riscv/attribute-08.d: Likewise. * testsuite/gas/riscv/attribute-09.d: New testcase. For i-ext, we already set the version 1p9 in elf attribute, so -misa-spec and -mriscv-isa-version don't update the version to 2p0 and 2p1. For f-ext, we don't set the version to it, so use the default version 2p0 according to the ISA spec 2p2. For v-ext, the default version is 0p7 according to ISA spec 2p2, but we use -mriscv-isa-version to update it to 0p9. For a-ext, it isn't enabled by -march or elf attribute, so we don't update it's version even if -mriscv-isa-version is set. As for the zicsr extension, it is defined in the lastest ISA spec rather than 2p2, so set it's version to 0p0. * testsuite/gas/riscv/attribute-09.s: Likewise. * testsuite/gas/riscv/attribute-10.d: New testcase. The version of zicsr is 2p0 according to ISA spec 20191213. * testsuite/gas/riscv/attribute-11.d: New testcase. We can also update the z* extension by -mriscv-isa-version. * configure.ac: Add new configure options, --with-arch, --with-isa-spec and --with-riscv-isa-version. * configure: Regenerated. * config.in: Regenerated. bfd/ * elfxx-riscv.h (struct riscv_subset_t): Add new bfd_boolean field use_default_version, which is used to record whether the default version is used for the extension. (struct riscv_parse_subset_t): Add new callback function get_default_version. It is used to find the default version for the specific extension. (riscv_add_subset, riscv_parse_subset): Update function declaration. * elfxx-riscv.c (riscv_parsing_subset_version): Remove the parameters default_major_version and default_minor_version. Add new bfd_boolean parameter *use_default_version. Set it to TRUE if we need to call the callback rps->get_default_version to find the default version. (riscv_update_subset_version): Only update the version of existin standard extensions and their Z* sub extensions, if -mriscv-isa-version or --with-riscv-isa-version are set, and the default version are used. (riscv_add_subset): New parameter use_default_version. Record whether the default version is used. riscv_update_subset_version only update the version of extensions if the default versions are used. (riscv_parse_subset): Add two parameters isa_spec_name and update_version. Pass them to riscv_parse_std_ext and riscv_parse_prefixed_ext. The string set by -mriscv-isa-version or --with-riscv-isa-version doesn't have to start with rv32/rv64, so skip the checking if update_version is TRUE. (riscv_parse_std_ext): If update_version is TRUE, then we just call riscv_update_subset_version to update the default version. Otherwise, Call rps->get_default_version if we fail to find the default version in riscv_parsing_subset_version, and then call riscv_add_subset to add the subset into subset list. (riscv_parse_prefixed_ext): Same as the riscv_parse_std_ext. (riscv_std_z_ext_strtab): Support Zicsr extensions. * elfnn-riscv.c (riscv_merge_std_ext, riscv_merge_multi_letter_ext): Updated. Pass update_version as FALSE to riscv_add_subset, the update_version is only needed for assembler, not linker. (riscv_merge_arch_attr_info): The callback function get_default_version is only needed for assembler, so set it to NULL in linker. Also, Pass isa_spec_name as NULL and update_version as FALSE to riscv_parse_subset. include/ * opcode/riscv.h (struct riscv_ext_version): New structure holds version information for the specific ISA. opcodes/ * riscv-opc.c (riscv_ext_version_table): The table used to store all information about the supported spec and the corresponding ISA versions. Currently, only Zicsr is supported to verify the correctness of Z sub extension settings. Others will be supported in the future patches. --- bfd/elfnn-riscv.c | 24 ++- bfd/elfxx-riscv.c | 350 ++++++++++++++++++++++++--------- bfd/elfxx-riscv.h | 12 +- gas/config.in | 9 + gas/config/tc-riscv.c | 128 +++++++++++- gas/configure | 53 ++++- gas/configure.ac | 35 +++- gas/testsuite/gas/riscv/attribute-01.d | 2 +- gas/testsuite/gas/riscv/attribute-02.d | 4 +- gas/testsuite/gas/riscv/attribute-03.d | 4 +- gas/testsuite/gas/riscv/attribute-04.d | 2 +- gas/testsuite/gas/riscv/attribute-05.d | 2 +- gas/testsuite/gas/riscv/attribute-06.d | 2 +- gas/testsuite/gas/riscv/attribute-07.d | 2 +- gas/testsuite/gas/riscv/attribute-08.d | 2 +- gas/testsuite/gas/riscv/attribute-09.d | 6 + gas/testsuite/gas/riscv/attribute-09.s | 1 + gas/testsuite/gas/riscv/attribute-10.d | 6 + gas/testsuite/gas/riscv/attribute-11.d | 6 + include/opcode/riscv.h | 11 ++ opcodes/riscv-opc.c | 53 +++++ 21 files changed, 585 insertions(+), 129 deletions(-) create mode 100644 gas/testsuite/gas/riscv/attribute-09.d create mode 100644 gas/testsuite/gas/riscv/attribute-09.s create mode 100644 gas/testsuite/gas/riscv/attribute-10.d create mode 100644 gas/testsuite/gas/riscv/attribute-11.d diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c index 8fcb106..4ca49e0 100644 --- a/bfd/elfnn-riscv.c +++ b/bfd/elfnn-riscv.c @@ -2802,7 +2802,7 @@ riscv_merge_std_ext (bfd *ibfd, if (!riscv_i_or_e_p (ibfd, out_arch, out)) return FALSE; - if (in->name[0] != out->name[0]) + if (strcasecmp (in->name, out->name) != 0) { /* TODO: We might allow merge 'i' with 'e'. */ _bfd_error_handler @@ -2818,8 +2818,8 @@ riscv_merge_std_ext (bfd *ibfd, return FALSE; } else - riscv_add_subset (&merged_subsets, - in->name, in->major_version, in->minor_version); + riscv_add_subset (&merged_subsets, in->name, in->major_version, + in->minor_version, FALSE); in = in->next; out = out->next; @@ -2848,7 +2848,7 @@ riscv_merge_std_ext (bfd *ibfd, struct riscv_subset_t *merged = find_in ? find_in : find_out; riscv_add_subset (&merged_subsets, merged->name, - merged->major_version, merged->minor_version); + merged->major_version, merged->minor_version, FALSE); } /* Skip all standard extensions. */ @@ -2917,14 +2917,14 @@ riscv_merge_multi_letter_ext (bfd *ibfd, { /* `in' comes before `out', append `in' and increment. */ riscv_add_subset (&merged_subsets, in->name, in->major_version, - in->minor_version); + in->minor_version, FALSE); in = in->next; } else if (cmp > 0) { /* `out' comes before `in', append `out' and increment. */ riscv_add_subset (&merged_subsets, out->name, out->major_version, - out->minor_version); + out->minor_version, FALSE); out = out->next; } else @@ -2938,7 +2938,7 @@ riscv_merge_multi_letter_ext (bfd *ibfd, } riscv_add_subset (&merged_subsets, out->name, out->major_version, - out->minor_version); + out->minor_version, FALSE); out = out->next; in = in->next; } @@ -2952,7 +2952,7 @@ riscv_merge_multi_letter_ext (bfd *ibfd, while (tail) { riscv_add_subset (&merged_subsets, tail->name, tail->major_version, - tail->minor_version); + tail->minor_version, FALSE); tail = tail->next; } } @@ -2975,13 +2975,17 @@ riscv_merge_arch_attr_info (bfd *ibfd, char *in_arch, char *out_arch) riscv_parse_subset_t rpe_in; riscv_parse_subset_t rpe_out; + /* Only assembler needs to check the default version of ISA, so just set + the rpe_in.get_default_version and rpe_out.get_default_version to NULL. */ 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_out.subset_list = &out_subsets; rpe_out.error_handler = _bfd_error_handler; rpe_out.xlen = &xlen_out; + rpe_out.get_default_version = NULL; if (in_arch == NULL && out_arch == NULL) return NULL; @@ -2993,10 +2997,10 @@ riscv_merge_arch_attr_info (bfd *ibfd, char *in_arch, char *out_arch) return in_arch; /* Parse subset from arch string. */ - if (!riscv_parse_subset (&rpe_in, in_arch)) + if (!riscv_parse_subset (&rpe_in, in_arch, NULL, FALSE)) return NULL; - if (!riscv_parse_subset (&rpe_out, out_arch)) + if (!riscv_parse_subset (&rpe_out, out_arch, NULL, FALSE)) return NULL; /* Checking XLEN. */ diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c index b15fdee..3a6aaf3 100644 --- a/bfd/elfxx-riscv.c +++ b/bfd/elfxx-riscv.c @@ -1025,9 +1025,8 @@ riscv_elf_add_sub_reloc (bfd *abfd, `minor_version`: Parsing result of minor version, set to 0 if version is not present in arch string, but set to `default_minor_version` if `major_version` using default_major_version. - `default_major_version`: Default major version. - `default_minor_version`: Default minor version. - `std_ext_p`: True if parsing std extension. */ + `std_ext_p`: True if parsing std extension. + `use_default_version`: Set it to True if we need the default version. */ static const char * riscv_parsing_subset_version (riscv_parse_subset_t *rps, @@ -1035,17 +1034,16 @@ riscv_parsing_subset_version (riscv_parse_subset_t *rps, const char *p, unsigned *major_version, unsigned *minor_version, - unsigned default_major_version, - unsigned default_minor_version, - bfd_boolean std_ext_p) + bfd_boolean std_ext_p, + bfd_boolean *use_default_version) { bfd_boolean major_p = TRUE; unsigned version = 0; - unsigned major = 0; - unsigned minor = 0; char np; - for (;*p; ++p) + *major_version = 0; + *minor_version = 0; + for (; *p; ++p) { if (*p == 'p') { @@ -1057,7 +1055,6 @@ riscv_parsing_subset_version (riscv_parse_subset_t *rps, if (std_ext_p) { *major_version = version; - *minor_version = 0; return p; } else @@ -1068,7 +1065,7 @@ riscv_parsing_subset_version (riscv_parse_subset_t *rps, } } - major = version; + *major_version = version; major_p = FALSE; version = 0; } @@ -1079,21 +1076,15 @@ riscv_parsing_subset_version (riscv_parse_subset_t *rps, } if (major_p) - major = version; + *major_version = version; else - minor = version; + *minor_version = version; - if (major == 0 && minor == 0) - { - /* We don't found any version string, use default version. */ - *major_version = default_major_version; - *minor_version = default_minor_version; - } - else - { - *major_version = major; - *minor_version = minor; - } + /* We can not find any version in string, need to parse default version. */ + if (use_default_version != NULL + && *major_version == 0 + && *minor_version == 0) + *use_default_version = TRUE; return p; } @@ -1106,6 +1097,41 @@ riscv_supported_std_ext (void) return "mafdqlcbjtpvn"; } +/* Update the version of standard extensions and their Z* sub extensions + if -mriscv-isa-version is set. */ + +static bfd_boolean +riscv_update_subset_version (riscv_parse_subset_t *rps, + const char *ext_with_version, + char *ext, + unsigned major_version, + unsigned minor_version, + bfd_boolean use_default_version) +{ + riscv_subset_t *subset = riscv_lookup_subset (rps->subset_list, ext);; + + /* The extension doesn't exist, so just return. */ + if (subset == NULL) + return TRUE; + + /* This means we can not find the version in the string. */ + if (use_default_version) + { + rps->error_handler ("-mriscv-isa-version=%s: unexpected version " + "setting for subset `%s'", ext_with_version, ext); + return FALSE; + } + + /* We only update the extension which use the default version. */ + if (subset->use_default_version) + { + subset->major_version = major_version; + subset->minor_version = minor_version; + } + + return TRUE; +} + /* Parsing function for standard extensions. Return Value: @@ -1114,46 +1140,95 @@ riscv_supported_std_ext (void) Arguments: `rps`: Hooks and status for parsing subset. `march`: Full arch string. - `p`: Curent parsing position. */ + `p`: Curent parsing position. + `isa_spec_name`: The ISA spec name. We set the default ISA versions + according to it. + `update_version`: True if the -mriscv-isa-version is set, and we need + to update the version for the existing extensions. */ static const char * riscv_parse_std_ext (riscv_parse_subset_t *rps, - const char *march, const char *p) + const char *march, + const char *p, + const char *isa_spec_name, + bfd_boolean update_version) { const char *all_std_exts = riscv_supported_std_ext (); const char *std_exts = all_std_exts; - unsigned major_version = 0; unsigned minor_version = 0; char std_ext = '\0'; + bfd_boolean use_default_version = FALSE; /* First letter must start with i, e or g. */ switch (*p) { case 'i': - p++; - p = riscv_parsing_subset_version ( - rps, - march, - p, &major_version, &minor_version, - /* default_major_version= */ 2, - /* default_minor_version= */ 0, - /* std_ext_p= */TRUE); - riscv_add_subset (rps->subset_list, "i", major_version, minor_version); + p = riscv_parsing_subset_version (rps, + march, + ++p, + &major_version, + &minor_version, + /* std_ext_p= */TRUE, + &use_default_version); + + /* Update the version for exsiting extension. */ + if (update_version) + { + if (!riscv_update_subset_version (rps, march, "i", + major_version, + minor_version, + use_default_version)) + return NULL; + break; + } + + /* Find the default version if needed. */ + if (use_default_version) + rps->get_default_version ("i", + isa_spec_name, + &major_version, + &minor_version); + riscv_add_subset (rps->subset_list, "i", major_version, minor_version, + use_default_version); break; case 'e': - p++; - p = riscv_parsing_subset_version ( - rps, - march, - p, &major_version, &minor_version, - /* default_major_version= */ 1, - /* default_minor_version= */ 9, - /* std_ext_p= */TRUE); - - riscv_add_subset (rps->subset_list, "e", major_version, minor_version); - riscv_add_subset (rps->subset_list, "i", 2, 0); + p = riscv_parsing_subset_version (rps, + march, + ++p, + &major_version, + &minor_version, + /* std_ext_p= */TRUE, + &use_default_version); + + /* Update the version for exsiting extension. */ + if (update_version) + { + if (!riscv_update_subset_version (rps, march, "e", + major_version, + minor_version, + use_default_version)) + return NULL; + break; + } + + /* Find the default version if needed. */ + if (use_default_version) + rps->get_default_version ("e", + isa_spec_name, + &major_version, + &minor_version); + riscv_add_subset (rps->subset_list, "e", major_version, minor_version, + use_default_version); + + /* i-ext must be enabled. */ + rps->get_default_version ("i", + isa_spec_name, + &major_version, + &minor_version); + riscv_add_subset (rps->subset_list, "i", major_version, minor_version, + TRUE); if (*rps->xlen > 32) { @@ -1161,35 +1236,58 @@ riscv_parse_std_ext (riscv_parse_subset_t *rps, march, *rps->xlen); return NULL; } - break; case 'g': - p++; - p = riscv_parsing_subset_version ( - rps, - march, - p, &major_version, &minor_version, - /* default_major_version= */ 2, - /* default_minor_version= */ 0, - /* std_ext_p= */TRUE); - riscv_add_subset (rps->subset_list, "i", major_version, minor_version); + /* The g-ext shouldn't has the version, so we just skip the setting if + user set a version to it. */ + p = riscv_parsing_subset_version (rps, + march, + ++p, + &major_version, + &minor_version, + TRUE, + &use_default_version); + + /* Set the version of g in -mriscv-isa-version is meaningless, + so just skip it. */ + if (update_version) + break; + + /* i-ext must be enabled. */ + rps->get_default_version ("i", + isa_spec_name, + &major_version, + &minor_version); + riscv_add_subset (rps->subset_list, "i", major_version, minor_version, + TRUE); for ( ; *std_exts != 'q'; std_exts++) { const char subset[] = {*std_exts, '\0'}; - riscv_add_subset ( - rps->subset_list, subset, major_version, minor_version); + rps->get_default_version (subset, + isa_spec_name, + &major_version, + &minor_version); + riscv_add_subset (rps->subset_list, subset, major_version, + minor_version, TRUE); } break; default: - rps->error_handler ( - "-march=%s: first ISA subset must be `e', `i' or `g'", march); - return NULL; + /* The first ISA subset of -mriscv-isa-version will not necessarily + be e/i/g. */ + if (!update_version) + { + rps->error_handler ( + "-march=%s: first ISA subset must be `e', `i' or `g'", march); + return NULL; + } } - while (*p) + /* The riscv_parsing_subset_version may set `p` to NULL, so I think we should + skip parsing the string if `p` is NULL or value of `p` is `\0`. */ + while (p != NULL && *p != '\0') { char subset[2] = {0, 0}; @@ -1218,21 +1316,37 @@ riscv_parse_std_ext (riscv_parse_subset_t *rps, march, *p); return NULL; } - std_exts++; - p++; - p = riscv_parsing_subset_version ( - rps, - march, - p, &major_version, &minor_version, - /* default_major_version= */ 2, - /* default_minor_version= */ 0, - /* std_ext_p= */TRUE); - + use_default_version = FALSE; subset[0] = std_ext; + p = riscv_parsing_subset_version (rps, + march, + ++p, + &major_version, + &minor_version, + TRUE, + &use_default_version); + + /* Update the version for exsiting extension. */ + if (update_version) + { + if (!riscv_update_subset_version (rps, march, subset, + major_version, + minor_version, + use_default_version)) + return NULL; + continue; + } - riscv_add_subset (rps->subset_list, subset, major_version, minor_version); + /* Find the default version if needed. */ + if (use_default_version) + rps->get_default_version (subset, + isa_spec_name, + &major_version, + &minor_version); + riscv_add_subset (rps->subset_list, subset, major_version, minor_version, + use_default_version); } return p; } @@ -1272,21 +1386,28 @@ typedef struct riscv_parse_config } riscv_parse_config_t; /* Parse a generic prefixed extension. - march: The full architecture string as passed in by "-march=...". - p: Point from which to start parsing the -march string. - config: What class of extensions to parse, predicate funcs, - and strings to use in error reporting. */ + `march`: The full architecture string as passed in by "-march=...". + `p`: Point from which to start parsing the -march string. + `config`: What class of extensions to parse, predicate funcs, + and strings to use in error reporting. + `isa_spec_name`: ISA spec name. We set the default ISA versions + according to it. + `update_version`: True if the -mriscv-isa-version is set, and we need + update the version for the existing extensions. */ 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 riscv_parse_config_t *config, + const char *isa_spec_name, + bfd_boolean update_version) { unsigned major_version = 0; unsigned minor_version = 0; const char *last_name; riscv_isa_ext_class_t class; + bfd_boolean use_default_version; while (*p) { @@ -1309,15 +1430,11 @@ riscv_parse_prefixed_ext (riscv_parse_subset_t *rps, while (*++q != '\0' && *q != '_' && !ISDIGIT (*q)) ; + use_default_version = FALSE; end_of_version = - riscv_parsing_subset_version ( - rps, - march, - q, &major_version, &minor_version, - /* default_major_version= */ 2, - /* default_minor_version= */ 0, - /* std_ext_p= */FALSE); - + riscv_parsing_subset_version (rps, march, q, &major_version, + &minor_version, FALSE, + &use_default_version); *q = '\0'; /* Check that the name is valid. @@ -1335,10 +1452,11 @@ riscv_parse_prefixed_ext (riscv_parse_subset_t *rps, return NULL; } - /* Check that the last item is not the same as this. */ + /* Check that the last item is not the same as this. Just skip this + check when updating the version. */ last_name = rps->subset_list->tail->name; - - if (!strcasecmp (last_name, subset)) + if (!update_version + && !strcasecmp (last_name, subset)) { rps->error_handler ("-march=%s: Duplicate %s ISA extension: \'%s\'", march, config->prefix, subset); @@ -1357,7 +1475,30 @@ riscv_parse_prefixed_ext (riscv_parse_subset_t *rps, return NULL; } - riscv_add_subset (rps->subset_list, subset, major_version, minor_version); + if (update_version) + { + /* Update the version for exsiting extension. */ + if (!riscv_update_subset_version (rps, march, subset, + major_version, + minor_version, + use_default_version)) + { + free (subset); + return NULL; + } + } + else + { + /* Find the default version if needed. */ + if (use_default_version) + rps->get_default_version (subset, + isa_spec_name, + &major_version, + &minor_version); + riscv_add_subset (rps->subset_list, subset, major_version, + minor_version, use_default_version); + } + free (subset); p += end_of_version - subset; @@ -1384,7 +1525,7 @@ riscv_parse_prefixed_ext (riscv_parse_subset_t *rps, static const char * const riscv_std_z_ext_strtab[] = { - NULL + "zicsr", NULL }; /* Same as `riscv_std_z_ext_strtab', but for S-class extensions. */ @@ -1457,11 +1598,17 @@ static const riscv_parse_config_t parse_config[] = Arguments: `rps`: Hooks and status for parsing subset. - `arch`: Arch string. */ + `arch`: Arch string. + `isa_spec_name`: The ISA spec name. We set the default ISA versions + according to it. + `update_version`: True if the -mriscv-isa-version is set, and we need + update the version for the existing extensions. */ bfd_boolean riscv_parse_subset (riscv_parse_subset_t *rps, - const char *arch) + const char *arch, + const char *isa_spec_name, + bfd_boolean update_version) { const char *p = arch; size_t i; @@ -1476,15 +1623,17 @@ riscv_parse_subset (riscv_parse_subset_t *rps, *rps->xlen = 64; p += 4; } - else + else if (!update_version) { + /* The string set by -mriscv-isa-version doesn't have to start + with rv32/rv64. */ rps->error_handler ("-march=%s: ISA string must begin with rv32 or rv64", arch); return FALSE; } /* Parsing standard extension. */ - p = riscv_parse_std_ext (rps, arch, p); + p = riscv_parse_std_ext (rps, arch, p, isa_spec_name, update_version); if (p == NULL) return FALSE; @@ -1492,7 +1641,8 @@ riscv_parse_subset (riscv_parse_subset_t *rps, /* Parse the different classes of extensions in the specified order. */ for (i = 0; i < ARRAY_SIZE (parse_config); ++i) { - p = riscv_parse_prefixed_ext (rps, arch, p, &parse_config[i]); + p = riscv_parse_prefixed_ext (rps, arch, p, &parse_config[i], + isa_spec_name, update_version); if (p == NULL) return FALSE; @@ -1543,7 +1693,8 @@ riscv_parse_subset (riscv_parse_subset_t *rps, void riscv_add_subset (riscv_subset_list_t *subset_list, const char *subset, - int major, int minor) + int major, int minor, + bfd_boolean use_default_version) { riscv_subset_t *s = xmalloc (sizeof *s); @@ -1553,6 +1704,9 @@ riscv_add_subset (riscv_subset_list_t *subset_list, s->name = xstrdup (subset); s->major_version = major; s->minor_version = minor; + /* Record whether the default version is used. The -mriscv-isa-version + only update the ISA which use the default version. */ + s->use_default_version = use_default_version; s->next = NULL; if (subset_list->tail != NULL) diff --git a/bfd/elfxx-riscv.h b/bfd/elfxx-riscv.h index 76ee274..e3d5177 100644 --- a/bfd/elfxx-riscv.h +++ b/bfd/elfxx-riscv.h @@ -40,6 +40,7 @@ struct riscv_subset_t const char *name; int major_version; int minor_version; + bfd_boolean use_default_version; struct riscv_subset_t *next; }; @@ -56,7 +57,8 @@ riscv_release_subset_list (riscv_subset_list_t *); extern void riscv_add_subset (riscv_subset_list_t *, const char *, - int, int); + int, int, + bfd_boolean); extern riscv_subset_t * riscv_lookup_subset (const riscv_subset_list_t *, @@ -72,11 +74,17 @@ typedef struct { void (*error_handler) (const char *, ...) ATTRIBUTE_PRINTF_1; unsigned *xlen; + void (*get_default_version) (const char *, + const char *, + unsigned int *, + unsigned int *); } riscv_parse_subset_t; extern bfd_boolean riscv_parse_subset (riscv_parse_subset_t *, - const char *); + const char *, + const char *, + bfd_boolean); extern const char * riscv_supported_std_ext (void); diff --git a/gas/config.in b/gas/config.in index 8724eb1..935bd9b 100644 --- a/gas/config.in +++ b/gas/config.in @@ -30,6 +30,9 @@ /* Default architecture. */ #undef DEFAULT_ARCH +/* Define default value for -march */ +#undef DEFAULT_ARCH_WITH_EXT + /* Default CRIS architecture. */ #undef DEFAULT_CRIS_ARCH @@ -50,12 +53,18 @@ /* Define to 1 if you want to generate x86 relax relocations by default. */ #undef DEFAULT_GENERATE_X86_RELAX_RELOCATIONS +/* Define default value for -misa-spec */ +#undef DEFAULT_ISA_SPEC + /* Define to 1 if you want to fix Loongson3 LLSC Errata by default. */ #undef DEFAULT_MIPS_FIX_LOONGSON3_LLSC /* Define to 1 if you want to generate RISC-V arch attribute by default. */ #undef DEFAULT_RISCV_ATTR +/* Define default isa version which are not covered by --with-isa-spec */ +#undef DEFAULT_RISCV_ISA_VERSION + /* Define to 1 if you want to generate GNU x86 used ISA and feature properties by default. */ #undef DEFAULT_X86_USED_NOTE diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c index 168561e..bfcf2f0 100644 --- a/gas/config/tc-riscv.c +++ b/gas/config/tc-riscv.c @@ -63,7 +63,22 @@ struct riscv_cl_insn #define DEFAULT_RISCV_ATTR 0 #endif +#ifndef DEFAULT_ARCH_WITH_EXT +#define DEFAULT_ARCH_WITH_EXT NULL +#endif + +#ifndef DEFAULT_ISA_SPEC +#define DEFAULT_ISA_SPEC "2p2" +#endif + +#ifndef DEFAULT_RISCV_ISA_VERSION +#define DEFAULT_RISCV_ISA_VERSION NULL +#endif + static const char default_arch[] = DEFAULT_ARCH; +static const char *default_arch_with_ext = DEFAULT_ARCH_WITH_EXT; +static const char *default_isa_spec = DEFAULT_ISA_SPEC; +static const char *default_riscv_isa_version = DEFAULT_RISCV_ISA_VERSION; static unsigned xlen = 0; /* width of an x-register */ static unsigned abi_xlen = 0; /* width of a pointer in the ABI */ @@ -147,18 +162,87 @@ riscv_multi_subset_supports (enum riscv_insn_class insn_class) } } +/* Handle of the extension with version hash table. */ +static struct hash_control *ext_version_hash = NULL; + +static struct hash_control * +init_ext_version_hash (const struct riscv_ext_version *table) +{ + int i = 0; + struct hash_control *hash = hash_new (); + + while (table[i].name) + { + const char *name = table[i].name; + const char *hash_error = + hash_insert (hash, name, (void *) &table[i]); + + if (hash_error != NULL) + { + fprintf (stderr, _("internal error: can't hash `%s': %s\n"), + table[i].name, hash_error); + /* Probably a memory allocation problem? Give up now. */ + as_fatal (_("Broken assembler. No assembly attempted.")); + return NULL; + } + + i++; + while (table[i].name + && strcmp (table[i].name, name) == 0) + i++; + } + + return hash; +} + +static void +riscv_get_default_ext_version (const char *name, + const char *spec_name, + unsigned int *major_version, + unsigned int *minor_version) +{ + struct riscv_ext_version *ext; + + *major_version = 0; + *minor_version = 0; + + if (name == NULL + || spec_name == NULL) + return; + + ext = (struct riscv_ext_version *) hash_find (ext_version_hash, name); + while (ext + && ext->name + && strcmp (ext->name, name) == 0) + { + if (ext->spec_name + && strcmp (ext->spec_name, spec_name) == 0) + { + *major_version = ext->major_version; + *minor_version = ext->minor_version; + return; + } + ext++; + } +} + /* Set which ISA and extensions are available. */ static void -riscv_set_arch (const char *s) +riscv_set_arch (const char *s, bfd_boolean update_version) { riscv_parse_subset_t rps; rps.subset_list = &riscv_subsets; rps.error_handler = as_fatal; rps.xlen = &xlen; + rps.get_default_version = riscv_get_default_ext_version; - riscv_release_subset_list (&riscv_subsets); - riscv_parse_subset (&rps, s); + if (s == NULL) + return; + + if (!update_version) + riscv_release_subset_list (&riscv_subsets); + riscv_parse_subset (&rps, s, default_isa_spec, update_version); } /* Handle of the OPCODE hash table. */ @@ -2348,6 +2432,8 @@ enum options OPTION_NO_ARCH_ATTR, OPTION_CSR_CHECK, OPTION_NO_CSR_CHECK, + OPTION_MISA_SPEC, + OPTION_MRISCV_ISA_VERSION, OPTION_END_OF_ENUM }; @@ -2364,6 +2450,8 @@ struct option md_longopts[] = {"mno-arch-attr", no_argument, NULL, OPTION_NO_ARCH_ATTR}, {"mcsr-check", no_argument, NULL, OPTION_CSR_CHECK}, {"mno-csr-check", no_argument, NULL, OPTION_NO_CSR_CHECK}, + {"misa-spec", required_argument, NULL, OPTION_MISA_SPEC}, + {"mriscv-isa-version", required_argument, NULL, OPTION_MRISCV_ISA_VERSION}, {NULL, no_argument, NULL, 0} }; @@ -2392,7 +2480,9 @@ md_parse_option (int c, const char *arg) switch (c) { case OPTION_MARCH: - riscv_set_arch (arg); + /* riscv_after_parse_args will call riscv_set_arch to parse + the architecture. */ + default_arch_with_ext = arg; break; case OPTION_NO_PIC: @@ -2450,6 +2540,14 @@ md_parse_option (int c, const char *arg) riscv_opts.csr_check = FALSE; break; + case OPTION_MISA_SPEC: + default_isa_spec = arg; + break; + + case OPTION_MRISCV_ISA_VERSION: + default_riscv_isa_version = arg; + break; + default: return 0; } @@ -2460,6 +2558,13 @@ md_parse_option (int c, const char *arg) void riscv_after_parse_args (void) { + /* Initialize the hash table for extensions with default version. */ + ext_version_hash = init_ext_version_hash (riscv_ext_version_table); + + /* The --with-arch is optional for now, so we have to set the xlen + according to the default_arch, which is set by the --targte, first. + Then, we use the xlen to set the default_arch_with_ext if the + -march and --with-arch are not set. */ if (xlen == 0) { if (strcmp (default_arch, "riscv32") == 0) @@ -2469,9 +2574,15 @@ 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"; + + /* Set the architecture according to -march or --with-arch. */ + riscv_set_arch (default_arch_with_ext, FALSE); - if (riscv_subsets.head == NULL) - riscv_set_arch (xlen == 64 ? "rv64g" : "rv32g"); + /* Update the version info according to -mriscv-isa-spec or + --with-riscv-isa-spec. */ + riscv_set_arch (default_riscv_isa_version, TRUE); /* Add the RVC extension, regardless of -march, to support .option rvc. */ riscv_set_rvc (FALSE); @@ -3366,7 +3477,7 @@ s_riscv_attribute (int ignored ATTRIBUTE_UNUSED) obj_attribute *attr; attr = elf_known_obj_attributes_proc (stdoutput); if (!start_assemble) - riscv_set_arch (attr[Tag_RISCV_arch].s); + riscv_set_arch (attr[Tag_RISCV_arch].s, FALSE); else as_fatal (_(".attribute arch must set before any instructions")); @@ -3379,6 +3490,9 @@ s_riscv_attribute (int ignored ATTRIBUTE_UNUSED) if (! bfd_set_arch_mach (stdoutput, bfd_arch_riscv, mach)) as_warn (_("Could not set architecture and machine")); } + + /* We also need to update the version of ISA here. */ + riscv_set_arch (default_riscv_isa_version, TRUE); } } diff --git a/gas/configure b/gas/configure index 1515787..bce847a 100755 --- a/gas/configure +++ b/gas/configure @@ -13009,7 +13009,7 @@ $as_echo "#define NDS32_DEFAULT_ZOL_EXT 1" >>confdefs.h $as_echo "$enable_zol_ext" >&6; } ;; - aarch64 | i386 | riscv | s390 | sparc) + aarch64 | i386 | s390 | sparc) if test $this_target = $target ; then cat >>confdefs.h <<_ACEOF @@ -13019,6 +13019,57 @@ _ACEOF fi ;; + riscv) + # --target=riscv[32|64]-*-*. */ + if test $this_target = $target ; then + +cat >>confdefs.h <<_ACEOF +#define DEFAULT_ARCH "${arch}" +_ACEOF + + fi + + # --with-arch=. The syntax of is same as Gas option -march. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for default configuration of --with-arch" >&5 +$as_echo_n "checking for default configuration of --with-arch... " >&6; } + if test "x${with_arch}" != x; then + +cat >>confdefs.h <<_ACEOF +#define DEFAULT_ARCH_WITH_EXT "$with_arch" +_ACEOF + + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_arch" >&5 +$as_echo "$with_arch" >&6; } + + # --with-isa-spec=[2p0|2p1|2p2|20190608|20191213]. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for default configuration of --with-isa-spec" >&5 +$as_echo_n "checking for default configuration of --with-isa-spec... " >&6; } + if test "x${with_isa_spec}" != x; then + +cat >>confdefs.h <<_ACEOF +#define DEFAULT_ISA_SPEC "$with_isa_spec" +_ACEOF + + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_isa_spec" >&5 +$as_echo "$with_isa_spec" >&6; } + + # --with-riscv-isa-version=. The syntax of is same as Gas + # -march, but without the rv[32|64] prefix. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for default configuration of --with-riscv-isa-version" >&5 +$as_echo_n "checking for default configuration of --with-riscv-isa-version... " >&6; } + if test "x${with_riscv_isa_version}" != x; then + +cat >>confdefs.h <<_ACEOF +#define DEFAULT_RISCV_ISA_VERSION "$with_riscv_isa_version" +_ACEOF + + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_riscv_isa_version" >&5 +$as_echo "$with_riscv_isa_version" >&6; } + ;; + rl78) f=rl78-parse.o case " $extra_objects " in diff --git a/gas/configure.ac b/gas/configure.ac index 6f32e55..be4ba20 100644 --- a/gas/configure.ac +++ b/gas/configure.ac @@ -569,12 +569,45 @@ changequote([,])dnl AC_MSG_RESULT($enable_zol_ext) ;; - aarch64 | i386 | riscv | s390 | sparc) + aarch64 | i386 | s390 | sparc) if test $this_target = $target ; then AC_DEFINE_UNQUOTED(DEFAULT_ARCH, "${arch}", [Default architecture.]) fi ;; + riscv) + # --target=riscv[32|64]-*-*. */ + if test $this_target = $target ; then + AC_DEFINE_UNQUOTED(DEFAULT_ARCH, "${arch}", [Default architecture.]) + fi + + # --with-arch=. The syntax of is same as Gas option -march. + AC_MSG_CHECKING(for default configuration of --with-arch) + if test "x${with_arch}" != x; then + AC_DEFINE_UNQUOTED(DEFAULT_ARCH_WITH_EXT, "$with_arch", + [Define default value for -march]) + fi + AC_MSG_RESULT($with_arch) + + # --with-isa-spec=[2p0|2p1|2p2|20190608|20191213]. + AC_MSG_CHECKING(for default configuration of --with-isa-spec) + if test "x${with_isa_spec}" != x; then + AC_DEFINE_UNQUOTED(DEFAULT_ISA_SPEC, "$with_isa_spec", + [Define default value for -misa-spec]) + fi + AC_MSG_RESULT($with_isa_spec) + + # --with-riscv-isa-version=. The syntax of is same as Gas + # -march, but without the rv[32|64] prefix. + AC_MSG_CHECKING(for default configuration of --with-riscv-isa-version) + if test "x${with_riscv_isa_version}" != x; then + AC_DEFINE_UNQUOTED(DEFAULT_RISCV_ISA_VERSION, "$with_riscv_isa_version", + [Define default isa version which are not + covered by --with-isa-spec]) + fi + AC_MSG_RESULT($with_riscv_isa_version) + ;; + rl78) f=rl78-parse.o case " $extra_objects " in diff --git a/gas/testsuite/gas/riscv/attribute-01.d b/gas/testsuite/gas/riscv/attribute-01.d index e22773e..3f9e841 100644 --- a/gas/testsuite/gas/riscv/attribute-01.d +++ b/gas/testsuite/gas/riscv/attribute-01.d @@ -1,4 +1,4 @@ -#as: -march=rv32g -march-attr +#as: -march=rv32g -march-attr -misa-spec=2p2 #readelf: -A #source: empty.s Attribute Section: riscv diff --git a/gas/testsuite/gas/riscv/attribute-02.d b/gas/testsuite/gas/riscv/attribute-02.d index bc3295b..a58248e 100644 --- a/gas/testsuite/gas/riscv/attribute-02.d +++ b/gas/testsuite/gas/riscv/attribute-02.d @@ -1,6 +1,6 @@ -#as: -march=rv32gxargle -march-attr +#as: -march=rv32gxargle -march-attr -misa-spec=2p2 #readelf: -A #source: empty.s Attribute Section: riscv File Attributes - Tag_RISCV_arch: "rv32i2p0_m2p0_a2p0_f2p0_d2p0_xargle2p0" + Tag_RISCV_arch: "rv32i2p0_m2p0_a2p0_f2p0_d2p0_xargle0p0" diff --git a/gas/testsuite/gas/riscv/attribute-03.d b/gas/testsuite/gas/riscv/attribute-03.d index 78b706a..04b9ab5 100644 --- a/gas/testsuite/gas/riscv/attribute-03.d +++ b/gas/testsuite/gas/riscv/attribute-03.d @@ -1,6 +1,6 @@ -#as: -march=rv32gxargle_xfoo -march-attr +#as: -march=rv32gxargle_xfoo -march-attr -misa-spec=2p2 #readelf: -A #source: empty.s Attribute Section: riscv File Attributes - Tag_RISCV_arch: "rv32i2p0_m2p0_a2p0_f2p0_d2p0_xargle2p0_xfoo2p0" + Tag_RISCV_arch: "rv32i2p0_m2p0_a2p0_f2p0_d2p0_xargle0p0_xfoo0p0" diff --git a/gas/testsuite/gas/riscv/attribute-04.d b/gas/testsuite/gas/riscv/attribute-04.d index c97bf03..8a3f51b 100644 --- a/gas/testsuite/gas/riscv/attribute-04.d +++ b/gas/testsuite/gas/riscv/attribute-04.d @@ -1,4 +1,4 @@ -#as: -march-attr +#as: -march-attr -misa-spec=2p2 #readelf: -A #source: attribute-04.s Attribute Section: riscv diff --git a/gas/testsuite/gas/riscv/attribute-05.d b/gas/testsuite/gas/riscv/attribute-05.d index f9b65f2..3309ff3 100644 --- a/gas/testsuite/gas/riscv/attribute-05.d +++ b/gas/testsuite/gas/riscv/attribute-05.d @@ -1,4 +1,4 @@ -#as: -march-attr +#as: -march-attr -misa-spec=2p2 #readelf: -A #source: attribute-05.s Attribute Section: riscv diff --git a/gas/testsuite/gas/riscv/attribute-06.d b/gas/testsuite/gas/riscv/attribute-06.d index 1abeb47..5c8a5c6 100644 --- a/gas/testsuite/gas/riscv/attribute-06.d +++ b/gas/testsuite/gas/riscv/attribute-06.d @@ -1,4 +1,4 @@ -#as: -march=rv32g2p0 -march-attr +#as: -march=rv32g2p1 -march-attr -misa-spec=2p2 #readelf: -A #source: attribute-06.s Attribute Section: riscv diff --git a/gas/testsuite/gas/riscv/attribute-07.d b/gas/testsuite/gas/riscv/attribute-07.d index dfd7e6b..20ac9be 100644 --- a/gas/testsuite/gas/riscv/attribute-07.d +++ b/gas/testsuite/gas/riscv/attribute-07.d @@ -1,4 +1,4 @@ -#as: -march=rv64g2p0 -march-attr +#as: -march=rv64g2p1 -march-attr -misa-spec=2p2 #readelf: -A #source: attribute-07.s Attribute Section: riscv diff --git a/gas/testsuite/gas/riscv/attribute-08.d b/gas/testsuite/gas/riscv/attribute-08.d index c10ac0c..7f580d3 100644 --- a/gas/testsuite/gas/riscv/attribute-08.d +++ b/gas/testsuite/gas/riscv/attribute-08.d @@ -1,4 +1,4 @@ -#as: -march-attr +#as: -march-attr -misa-spec=2p2 #readelf: -A #source: attribute-08.s Attribute Section: riscv diff --git a/gas/testsuite/gas/riscv/attribute-09.d b/gas/testsuite/gas/riscv/attribute-09.d new file mode 100644 index 0000000..77c7ef3 --- /dev/null +++ b/gas/testsuite/gas/riscv/attribute-09.d @@ -0,0 +1,6 @@ +#as: -march-attr -misa-spec=2p2 -mriscv-isa-version=i2p1a2p1v0p9 +#readelf: -A +#source: attribute-09.s +Attribute Section: riscv +File Attributes + Tag_RISCV_arch: "rv32i1p9_f2p0_v0p9_zicsr0p0" diff --git a/gas/testsuite/gas/riscv/attribute-09.s b/gas/testsuite/gas/riscv/attribute-09.s new file mode 100644 index 0000000..0b1b16c --- /dev/null +++ b/gas/testsuite/gas/riscv/attribute-09.s @@ -0,0 +1 @@ + .attribute arch, "rv32i1p9fv_zicsr" diff --git a/gas/testsuite/gas/riscv/attribute-10.d b/gas/testsuite/gas/riscv/attribute-10.d new file mode 100644 index 0000000..9c72035 --- /dev/null +++ b/gas/testsuite/gas/riscv/attribute-10.d @@ -0,0 +1,6 @@ +#as: -march-attr -march=rv32i_zicsr -misa-spec=20191213 +#readelf: -A +#source: empty.s +Attribute Section: riscv +File Attributes + Tag_RISCV_arch: "rv32i2p1_zicsr2p0" diff --git a/gas/testsuite/gas/riscv/attribute-11.d b/gas/testsuite/gas/riscv/attribute-11.d new file mode 100644 index 0000000..bc7f986 --- /dev/null +++ b/gas/testsuite/gas/riscv/attribute-11.d @@ -0,0 +1,6 @@ +#as: -march-attr -march=rv32i_zicsr -misa-spec=20191213 -mriscv-isa-version=zicsr2p1 +#readelf: -A +#source: empty.s +Attribute Section: riscv +File Attributes + Tag_RISCV_arch: "rv32i2p1_zicsr2p1" diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h index ac6e861..f8b0de3 100644 --- a/include/opcode/riscv.h +++ b/include/opcode/riscv.h @@ -343,6 +343,16 @@ struct riscv_opcode unsigned long pinfo; }; +/* This structure holds version information for specific ISA. */ + +struct riscv_ext_version +{ + const char *name; + const char *spec_name; + unsigned int major_version; + unsigned int minor_version; +}; + /* Instruction is a simple alias (e.g. "mv" for "addi"). */ #define INSN_ALIAS 0x00000001 @@ -420,5 +430,6 @@ extern const char * const riscv_fpr_names_abi[NFPR]; extern const struct riscv_opcode riscv_opcodes[]; extern const struct riscv_opcode riscv_insn_types[]; +extern const struct riscv_ext_version riscv_ext_version_table[]; #endif /* _RISCV_H_ */ diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c index ceedcaf..7b885bf 100644 --- a/opcodes/riscv-opc.c +++ b/opcodes/riscv-opc.c @@ -884,3 +884,56 @@ const struct riscv_opcode riscv_insn_types[] = /* Terminate the list. */ {0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0} }; + +const struct riscv_ext_version riscv_ext_version_table[] = +{ +/* name, spec name, major, minor. */ +{"e", "20191213", 1, 9}, +{"e", "20190608", 1, 9}, +{"e", "2p2", 1, 9}, + +{"i", "20191213", 2, 1}, +{"i", "20190608", 2, 1}, +{"i", "2p2", 2, 0}, + +{"m", "20191213", 2, 0}, +{"m", "20190608", 2, 0}, +{"m", "2p2", 2, 0}, + +{"a", "20191213", 2, 1}, +{"a", "20190608", 2, 0}, +{"a", "2p2", 2, 0}, + +{"f", "20191213", 2, 2}, +{"f", "20190608", 2, 2}, +{"f", "2p2", 2, 0}, + +{"d", "20191213", 2, 2}, +{"d", "20190608", 2, 2}, +{"d", "2p2", 2, 0}, + +{"q", "20191213", 2, 2}, +{"q", "20190608", 2, 2}, +{"q", "2p2", 2, 0}, + +{"c", "20191213", 2, 0}, +{"c", "20190608", 2, 0}, +{"c", "2p2", 2, 0}, + +{"p", "20191213", 0, 2}, +{"p", "20190608", 0, 2}, +{"p", "2p2", 0, 1}, + +{"v", "20191213", 0, 7}, +{"v", "20190608", 0, 7}, +{"v", "2p2", 0, 7}, + +{"n", "20190608", 1, 1}, +{"n", "2p2", 1, 1}, + +{"zicsr","20191213", 2, 0}, +{"zicsr","20190608", 2, 0}, + +/* Terminate the list. */ +{NULL, NULL, 0, 0} +}; -- 2.7.4