From patchwork Sat Nov 16 03:13:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Liao Shihua X-Patchwork-Id: 101248 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A96E83858039 for ; Sat, 16 Nov 2024 03:15:21 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A96E83858039 X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from cstnet.cn (smtp81.cstnet.cn [159.226.251.81]) by sourceware.org (Postfix) with ESMTPS id 453113858290 for ; Sat, 16 Nov 2024 03:14:19 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 453113858290 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=iscas.ac.cn Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=iscas.ac.cn ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 453113858290 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=159.226.251.81 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1731726861; cv=none; b=QoxFAsVOHgyRRu3qoKVX3hBje6eBOf9gmD8/3WFp4WbLMcU7UzpgMvipknhjOo0uMPBYkEMU9BPW+6Q9kBdEHo4NVs2/Vnvu633Ot37ntJQqWRo414fZX866KzLskiihmYozp9razbkGzonLtf43CbIYVni2G1EYOM9be6SpIkw= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1731726861; c=relaxed/simple; bh=uXQrlIqv0TVzARbyXVG6JqXESo+xJa0H5uZsfSyYNww=; h=From:To:Subject:Date:Message-Id:MIME-Version; b=EFF7Ab8v2aK+hOeCA8y3C2K8fBhpzSz8yeAoEb4CRC3aiC+C30dBSnID3hNurAUQoR2/5Wj2X+b9GRssZFKMc90d0fLeBdLud6AgzOr7YAEE+IRLWRwSz0kgPoqna4ia8PpYodmf70uvlcHPKs5HDH67cBZLyhGv1Z53EbbnSAw= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 453113858290 Received: from localhost.localdomain (unknown [122.8.183.87]) by APP-03 (Coremail) with SMTP id rQCowABnx4r_DThnD1jnAg--.7070S2; Sat, 16 Nov 2024 11:14:11 +0800 (CST) From: Liao Shihua To: binutils@sourceware.org Cc: kito.cheng@gmail.com, shiyulong@iscas.ac.cn, jiawei@iscas.ac.cn, chenyixuan@iscas.ac.cn, guoren@kernel.org, wuwei2016@iscas.ac.cn, Liao Shihua Subject: [PATCH] Support N32(32-bit ABI on 64-bit ISA) in riscv Date: Sat, 16 Nov 2024 11:13:59 +0800 Message-Id: <20241116031359.3415911-1-shihua@iscas.ac.cn> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 X-CM-TRANSID: rQCowABnx4r_DThnD1jnAg--.7070S2 X-Coremail-Antispam: 1UD129KBjvAXoW3tw1xZF17Ww4UurWfZF1DZFb_yoW8JFW5to Z3Wa1rtF4jgFy7Cr4kAF4rXrWDurn5WayDXa10grWrJ3WUAryrCryxKwnrua98tr1xGFs5 Xa47Ar45JFyvg3W3n29KB7ZKAUJUUUU8529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjp_UUUYw7AC8VAFwI0_Gr0_Xr1l1xkIjI8I6I8E6xAIw20EY4v20xva j40_Wr0E3s1l1IIY67AEw4v_Jr0_Jr4l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0rcxSw2 x7M28EF7xvwVC0I7IYx2IY67AKxVWUJVWUCwA2z4x0Y4vE2Ix0cI8IcVCY1x0267AKxVWU JVW8JwA2z4x0Y4vEx4A2jsIE14v26r4UJVWxJr1l84ACjcxK6I8E87Iv6xkF7I0E14v26r 4UJVWxJr1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrVC2j2Wl Yx0E2Ix0cI8IcVAFwI0_Jr0_Jr4lYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE7xkEbV WUJVW8JwACjcxG0xvY0x0EwIxGrwACjI8F5VA0II8E6IAqYI8I648v4I1lc7CjxVAaw2AF wI0_JF0_Jw1l42xK82IYc2Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4 xG67AKxVWUJVWUGwC20s026x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r1q6r43 MIIYrxkI7VAKI48JMIIF0xvE2Ix0cI8IcVAFwI0_Jr0_JF4lIxAIcVC0I7IYx2IY6xkF7I 0E14v26r1j6r4UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVWU JVW8JwCI42IY6I8E87Iv6xkF7I0E14v26r1j6r4UYxBIdaVFxhVjvjDU0xZFpf9x0JUBVb kUUUUU= X-Originating-IP: [122.8.183.87] X-CM-SenderInfo: xvklx33d6l2u1dvotugofq/1tbiBwkDEWc36f47RQAAsl X-Spam-Status: No, score=-13.0 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, RCVD_IN_DNSWL_LOW, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: binutils@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: binutils-bounces~patchwork=sourceware.org@sourceware.org RISC-V N32 ABI means using 32-bit ABI on 64-bit ISA, the discussion in https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/381 . At this moment, N32 is supported batemental toolchain. Three OpenSource RTOS using this feature and have been merged in upstream. You can see them in EasyXem (AUTOSAR CP R19-11): https://atomgit.com/easyxmen/XMen/tree/rv64ilp32-dev Nuttx: https://github.com/apache/nuttx RT-Thread:https://github.com/RT-Thread/rt-thread/pull/9194 This patch add a new bfd_mach bfd_mach_riscv64n32 and a new e_flags N32. bfd_mach_riscv64n32 has the same bits in a word/address and ARCH_SIZE with rv32, but use rv64's PRSTATUS. N32 use the 6th bit of e_flags layout. In addition, this patch replace xlen with abi_xlen in riscv_target_format(). bfd/ChangeLog: * archures.c: Add bfd_mach_riscv64n32. * bfd-in2.h (bfd_mach_riscv64n32): Ditto. * cpu-riscv.c: Ditto. * elfnn-riscv.c (ABI_N32_P):Add ABI_N32_P (perform_relocation):Ditto. (riscv_merge_arch_attr_info):Remove elf check when using N32. (_bfd_riscv_elf_merge_private_bfd_data):Ditto. (_bfd_riscv_relax_section):Ditto. (riscv_elf_object_p):Using bfd_mach_riscv64n32 with N32. binutils/ChangeLog: * readelf.c (decode_RISCV_machine_flags):Add N32 Flag. gas/ChangeLog: * config/tc-riscv.c (riscv_set_n32):Set N32 flag. (riscv_set_abi_by_arch):Removed check. (riscv_target_format):Ditto (md_begin):Ditto (s_riscv_attribute):Ditto * testsuite/gas/riscv/mabi-fail-rv64iq-ilp32.d: Removed. * testsuite/gas/riscv/mabi-fail-rv64iq-ilp32.l: Removed. include/ChangeLog: * elf/riscv.h (EF_RISCV_N32):Add N32 Flag. opcodes/ChangeLog: * riscv-dis.c (print_insn_args): (riscv_disassemble_insn): Tested-by: Guo Ren --- bfd/archures.c | 1 + bfd/bfd-in2.h | 1 + bfd/cpu-riscv.c | 2 ++ bfd/elfnn-riscv.c | 32 +++++++++++++------ binutils/readelf.c | 3 ++ gas/config/tc-riscv.c | 23 ++++++++++--- .../gas/riscv/mabi-fail-rv64iq-ilp32.d | 3 -- .../gas/riscv/mabi-fail-rv64iq-ilp32.l | 2 -- include/elf/riscv.h | 3 ++ opcodes/riscv-dis.c | 6 ++-- 10 files changed, 53 insertions(+), 23 deletions(-) delete mode 100644 gas/testsuite/gas/riscv/mabi-fail-rv64iq-ilp32.d delete mode 100644 gas/testsuite/gas/riscv/mabi-fail-rv64iq-ilp32.l diff --git a/bfd/archures.c b/bfd/archures.c index c4decc59e4a..063659631fa 100644 --- a/bfd/archures.c +++ b/bfd/archures.c @@ -448,6 +448,7 @@ DESCRIPTION . bfd_arch_riscv, .#define bfd_mach_riscv32 132 .#define bfd_mach_riscv64 164 +.#define bfd_mach_riscv64n32 16432 . bfd_arch_rl78, .#define bfd_mach_rl78 0x75 . bfd_arch_rx, {* Renesas RX. *} diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 3b047d922f3..0ee6bbc2a73 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -1714,6 +1714,7 @@ enum bfd_architecture bfd_arch_riscv, #define bfd_mach_riscv32 132 #define bfd_mach_riscv64 164 +#define bfd_mach_riscv64n32 16432 bfd_arch_rl78, #define bfd_mach_rl78 0x75 bfd_arch_rx, /* Renesas RX. */ diff --git a/bfd/cpu-riscv.c b/bfd/cpu-riscv.c index 58cbdd846be..1df99dc6e2d 100644 --- a/bfd/cpu-riscv.c +++ b/bfd/cpu-riscv.c @@ -86,6 +86,7 @@ riscv_scan (const struct bfd_arch_info *info, const char *string) enum { I_riscv64, + I_riscv64n32, I_riscv32 }; @@ -96,6 +97,7 @@ enum static const bfd_arch_info_type arch_info_struct[] = { N (64, bfd_mach_riscv64, "riscv:rv64", false, NN (I_riscv64)), + N (32, bfd_mach_riscv64n32, "riscv:rv64", false, NN (I_riscv64n32)), N (32, bfd_mach_riscv32, "riscv:rv32", false, NULL) }; diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c index c8bf45f4293..b05f4fde433 100644 --- a/bfd/elfnn-riscv.c +++ b/bfd/elfnn-riscv.c @@ -138,6 +138,11 @@ #define RISCV_ELF_WORD_BYTES (1 << RISCV_ELF_LOG_WORD_BYTES) +#define ABI_N32_P(abfd) \ + ((elf_elfheader (abfd)->e_flags & EF_RISCV_N32) != 0) + +static bool ABI_N32 = false; + /* The name of the dynamic interpreter. This is put in the .interp section. */ @@ -1823,7 +1828,8 @@ perform_relocation (const reloc_howto_type *howto, case R_RISCV_CALL: case R_RISCV_CALL_PLT: - if (ARCH_SIZE > 32 && !VALID_UTYPE_IMM (RISCV_CONST_HIGH_PART (value))) + if ((ARCH_SIZE > 32 || ABI_N32_P (input_bfd)) + && !VALID_UTYPE_IMM (RISCV_CONST_HIGH_PART (value))) return bfd_reloc_overflow; value = ENCODE_UTYPE_IMM (RISCV_CONST_HIGH_PART (value)) | (ENCODE_ITYPE_IMM (value) << 32); @@ -3927,7 +3933,7 @@ riscv_merge_arch_attr_info (bfd *ibfd, char *in_arch, char *out_arch) return NULL; /* Checking XLEN. */ - if (xlen_out != xlen_in) + if (xlen_out != xlen_in && !ABI_N32_P (ibfd)) { _bfd_error_handler (_("error: %pB: ISA string of input (%s) doesn't match " @@ -3947,7 +3953,7 @@ riscv_merge_arch_attr_info (bfd *ibfd, char *in_arch, char *out_arch) if (!riscv_merge_multi_letter_ext (&in, &out)) return NULL; - if (xlen_in != xlen_out) + if (xlen_in != xlen_out && !ABI_N32_P (ibfd)) { _bfd_error_handler (_("error: %pB: XLEN of input (%u) doesn't match " @@ -3955,7 +3961,7 @@ riscv_merge_arch_attr_info (bfd *ibfd, char *in_arch, char *out_arch) return NULL; } - if (xlen_in != ARCH_SIZE) + if (xlen_in != ARCH_SIZE && !ABI_N32_P (ibfd)) { _bfd_error_handler (_("error: %pB: unsupported XLEN (%u), you might be " @@ -3963,7 +3969,7 @@ riscv_merge_arch_attr_info (bfd *ibfd, char *in_arch, char *out_arch) return NULL; } - merged_arch_str = riscv_arch_str (ARCH_SIZE, &merged_subsets); + merged_arch_str = riscv_arch_str (xlen_in, &merged_subsets); /* Release the subset lists. */ riscv_release_subset_list (&in_subsets); @@ -4233,6 +4239,9 @@ _bfd_riscv_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info) /* Allow linking TSO and non-TSO, and keep the TSO flag. */ elf_elfheader (obfd)->e_flags |= new_flags & EF_RISCV_TSO; + + /* Allow linking N32 and non-N32, and keep the N32 flag. */ + elf_elfheader (obfd)->e_flags |= new_flags & EF_RISCV_N32; return true; @@ -5400,7 +5409,7 @@ _bfd_riscv_relax_section (bfd *abfd, asection *sec, return ret; } -#if ARCH_SIZE == 32 +#if ARCH_SIZE == 32 && !ABI_N32 # define PRSTATUS_SIZE 204 # define PRSTATUS_OFFSET_PR_CURSIG 12 # define PRSTATUS_OFFSET_PR_PID 24 @@ -5570,10 +5579,13 @@ riscv_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note) static bool riscv_elf_object_p (bfd *abfd) { - /* There are only two mach types in RISCV currently. */ - if (strcmp (abfd->xvec->name, "elf32-littleriscv") == 0 - || strcmp (abfd->xvec->name, "elf32-bigriscv") == 0) - bfd_default_set_arch_mach (abfd, bfd_arch_riscv, bfd_mach_riscv32); + ABI_N32 = ABI_N32_P (abfd); + /* There are only three mach types in RISCV currently. */ + if (ABI_N32) + bfd_default_set_arch_mach (abfd, bfd_arch_riscv, bfd_mach_riscv64n32); + else if (strcmp (abfd->xvec->name, "elf32-littleriscv") == 0 + || strcmp (abfd->xvec->name, "elf32-bigriscv") == 0) + bfd_default_set_arch_mach (abfd, bfd_arch_riscv, bfd_mach_riscv32); else bfd_default_set_arch_mach (abfd, bfd_arch_riscv, bfd_mach_riscv64); diff --git a/binutils/readelf.c b/binutils/readelf.c index 73163e0ee21..58248d84135 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -4532,6 +4532,9 @@ decode_RISCV_machine_flags (char *out, unsigned e_flags) if (e_flags & EF_RISCV_TSO) out = stpcpy (out, ", TSO"); + if (e_flags & EF_RISCV_N32) + out = stpcpy (out, ", N32"); + switch (e_flags & EF_RISCV_FLOAT_ABI) { case EF_RISCV_FLOAT_ABI_SOFT: diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c index e19142dca19..dde9c52ccc1 100644 --- a/gas/config/tc-riscv.c +++ b/gas/config/tc-riscv.c @@ -306,6 +306,13 @@ riscv_set_tso (void) elf_flags |= EF_RISCV_TSO; } +/* Turn on the n32 flag for elf_flags once we have enabled n32 model. */ +static void +riscv_set_n32 (void) +{ + elf_flags |= EF_RISCV_N32; +} + /* The linked list hanging off of .subsets_list records all enabled extensions, which are parsed from the architecture string. The architecture string can be set by the -march option, the elf architecture attributes, and the @@ -409,7 +416,7 @@ riscv_set_abi_by_arch (void) gas_assert (abi_xlen != 0 && xlen != 0 && float_abi != FLOAT_ABI_DEFAULT); if (abi_xlen > xlen) as_bad ("can't have %d-bit ABI on %d-bit ISA", abi_xlen, xlen); - else if (abi_xlen < xlen) + else if (abi_xlen < xlen && (abi_xlen != 32 && xlen != 64)) as_bad ("%d-bit ABI not yet supported on %d-bit ISA", abi_xlen, xlen); if (riscv_subset_supports (&riscv_rps_as, "e") && !rve_abi) @@ -435,6 +442,10 @@ riscv_set_abi_by_arch (void) if (rve_abi) elf_flags |= EF_RISCV_RVE; + + if (abi_xlen == 32 && xlen == 64) + riscv_set_n32 (); + } /* Handle of the OPCODE hash table. */ @@ -734,9 +745,9 @@ const char * riscv_target_format (void) { if (target_big_endian) - return xlen == 64 ? "elf64-bigriscv" : "elf32-bigriscv"; + return abi_xlen == 64 ? "elf64-bigriscv" : "elf32-bigriscv"; else - return xlen == 64 ? "elf64-littleriscv" : "elf32-littleriscv"; + return abi_xlen == 64 ? "elf64-littleriscv" : "elf32-littleriscv"; } /* Return the length of instruction INSN. */ @@ -1876,7 +1887,8 @@ riscv_record_pcrel_fixup (htab_t p, const asection *sec, bfd_vma address, void md_begin (void) { - unsigned long mach = xlen == 64 ? bfd_mach_riscv64 : bfd_mach_riscv32; + unsigned long mach = xlen == 64 ? + (abi_xlen == 32 ? bfd_mach_riscv64n32 : bfd_mach_riscv64) : bfd_mach_riscv32; if (! bfd_set_arch_mach (stdoutput, bfd_arch_riscv, mach)) as_warn (_("could not set architecture and machine")); @@ -5674,7 +5686,8 @@ s_riscv_attribute (int ignored ATTRIBUTE_UNUSED) if (old_xlen != xlen) { /* We must re-init bfd again if xlen is changed. */ - unsigned long mach = xlen == 64 ? bfd_mach_riscv64 : bfd_mach_riscv32; + unsigned long mach = xlen == 64 ? + (abi_xlen == 32 ? bfd_mach_riscv64n32 : bfd_mach_riscv64) : bfd_mach_riscv32; bfd_find_target (riscv_target_format (), stdoutput); if (! bfd_set_arch_mach (stdoutput, bfd_arch_riscv, mach)) diff --git a/gas/testsuite/gas/riscv/mabi-fail-rv64iq-ilp32.d b/gas/testsuite/gas/riscv/mabi-fail-rv64iq-ilp32.d deleted file mode 100644 index e3155f48956..00000000000 --- a/gas/testsuite/gas/riscv/mabi-fail-rv64iq-ilp32.d +++ /dev/null @@ -1,3 +0,0 @@ -#as: -march-attr -mabi=ilp32 -#source: mabi-attr-rv64iq.s -#error_output: mabi-fail-rv64iq-ilp32.l diff --git a/gas/testsuite/gas/riscv/mabi-fail-rv64iq-ilp32.l b/gas/testsuite/gas/riscv/mabi-fail-rv64iq-ilp32.l deleted file mode 100644 index 8d45a07fd36..00000000000 --- a/gas/testsuite/gas/riscv/mabi-fail-rv64iq-ilp32.l +++ /dev/null @@ -1,2 +0,0 @@ -.*Assembler messages: -.*Error: 32-bit ABI not yet supported on 64-bit ISA diff --git a/include/elf/riscv.h b/include/elf/riscv.h index 24903c04d91..f88a1c0701a 100644 --- a/include/elf/riscv.h +++ b/include/elf/riscv.h @@ -140,6 +140,9 @@ END_RELOC_NUMBERS (R_RISCV_max) /* File uses the TSO model. */ #define EF_RISCV_TSO 0x0010 +/* File uses the N32 model. */ +#define EF_RISCV_N32 0x0020 + /* Additional section types. */ #define SHT_RISCV_ATTRIBUTES (SHT_LOPROC + 3) /* Section holds attributes. */ diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c index 80018db837a..09fac0c3cbe 100644 --- a/opcodes/riscv-dis.c +++ b/opcodes/riscv-dis.c @@ -349,7 +349,7 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info case 'j': if (((l & MASK_C_ADDI) == MATCH_C_ADDI) && rd != 0) maybe_print_address (pd, rd, EXTRACT_CITYPE_IMM (l), 0); - if (info->mach == bfd_mach_riscv64 + if (info->mach == bfd_mach_riscv64 || info->mach == bfd_mach_riscv64n32 && ((l & MASK_C_ADDIW) == MATCH_C_ADDIW) && rd != 0) maybe_print_address (pd, rd, EXTRACT_CITYPE_IMM (l), 1); print (info->stream, dis_style_immediate, "%d", @@ -555,7 +555,7 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info if (((l & MASK_ADDI) == MATCH_ADDI && rs1 != 0) || (l & MASK_JALR) == MATCH_JALR) maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), 0); - if (info->mach == bfd_mach_riscv64 + if (info->mach == bfd_mach_riscv64|| info->mach == bfd_mach_riscv64n32 && ((l & MASK_ADDIW) == MATCH_ADDIW) && rs1 != 0) maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), 1); print (info->stream, dis_style_immediate, "%d", @@ -941,7 +941,7 @@ riscv_disassemble_insn (bfd_vma memaddr, if (op != NULL) { /* If XLEN is not known, get its value from the ELF class. */ - if (info->mach == bfd_mach_riscv64) + if (info->mach == bfd_mach_riscv64 || info->mach == bfd_mach_riscv64n32) xlen = 64; else if (info->mach == bfd_mach_riscv32) xlen = 32;