[PATCH] Support N32(32-bit ABI on 64-bit ISA) in riscv
Guo Ren
guoren@kernel.org
Sat Nov 16 08:58:40 GMT 2024
More information about the Binutils mailing list
Sat Nov 16 08:58:40 GMT 2024
- Previous message (by thread): [PATCH] Support N32(32-bit ABI on 64-bit ISA) in riscv
- Next message (by thread): [PATCH] Support N32(32-bit ABI on 64-bit ISA) in riscv
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
This patch works fine with the rv64ilp32 Linux kernel self building. Tested-by: Guo Ren <guoren@kernel.org> On Sat, Nov 16, 2024 at 12:16 PM Liao Shihua <shihua@iscas.ac.cn> wrote: > > 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): > > --- > 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; > -- > 2.34.1 > > -- Best Regards Guo Ren
- Previous message (by thread): [PATCH] Support N32(32-bit ABI on 64-bit ISA) in riscv
- Next message (by thread): [PATCH] Support N32(32-bit ABI on 64-bit ISA) in riscv
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Binutils mailing list