This patch works fine with the rv64ilp32 Linux kernel self-building. It is tested with binutils together.
Tested-by: Guo Ren <guo...@kernel.org> On Sat, Nov 16, 2024 at 12:22 PM Liao Shihua <shi...@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 support N32(32-bit ABI on 64-bit ISA) in riscv > It remove option check when -march=rv64* -mabi=ilp32. And replace XLEN_SPEC in > LINK_SPEC by ABI_LEN_SPEC. In addition, it some machine descriptions. > > gcc/ChangeLog: > > * config.gcc:Allow rv64* ISA use ilp32 ABI > * config/riscv/bitmanip.md: change some machine descriptions. > * config/riscv/elf.h (LINK_SPEC): Enable elf32 on rv64 ISA > * config/riscv/riscv.cc (riscv_option_override): remove check ilp32 > on rv64. > * config/riscv/riscv.h (TARGET_ILP32): Add TARGET_ILP32 like > TARGET_64BIT. > (POINTER_SIZE): Change POINTER_SIZE belong to ABI. > (Pmode): Likewise. > (ABI_LEN_SPEC): Likewise > * config/riscv/riscv.md: Change some machine descriptions. > > --- > gcc/config.gcc | 3 +++ > gcc/config/riscv/bitmanip.md | 4 ++-- > gcc/config/riscv/elf.h | 2 +- > gcc/config/riscv/riscv.cc | 3 ++- > gcc/config/riscv/riscv.h | 10 +++++++++- > gcc/config/riscv/riscv.md | 20 ++++++++++++-------- > 6 files changed, 29 insertions(+), 13 deletions(-) > > diff --git a/gcc/config.gcc b/gcc/config.gcc > index 9b616bd6e1f..a1b737117a0 100644 > --- a/gcc/config.gcc > +++ b/gcc/config.gcc > @@ -4828,6 +4828,9 @@ case "${target}" in > ilp32,rv32* | ilp32e,rv32e* \ > | ilp32f,rv32*f* | ilp32f,rv32g* \ > | ilp32d,rv32*d* | ilp32d,rv32g* \ > + | ilp32,rv64* | ilp32e,rv64e* \ > + | ilp32f,rv64*f* | ilp32f,rv64g* \ > + | ilp32d,rv64*d* | ilp32d,rv64g* \ > | lp64,rv64* | lp64e,rv64e* \ > | lp64f,rv64*f* | lp64f,rv64g* \ > | lp64d,rv64*d* | lp64d,rv64g*) > diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md > index 06ff698bfe7..4002f05acb8 100644 > --- a/gcc/config/riscv/bitmanip.md > +++ b/gcc/config/riscv/bitmanip.md > @@ -351,7 +351,7 @@ > { > if (TARGET_XTHEADBB && !immediate_operand (operands[2], VOIDmode)) > FAIL; > - if (TARGET_64BIT && register_operand (operands[2], QImode)) > + if (TARGET_64BIT && !TARGET_ILP32 && register_operand (operands[2], > QImode)) > { > rtx t = gen_reg_rtx (DImode); > emit_insn (gen_rotrsi3_sext (t, operands[1], operands[2])); > @@ -393,7 +393,7 @@ > (match_operand:QI 2 "register_operand" "r")))] > "TARGET_ZBB || TARGET_ZBKB" > { > - if (TARGET_64BIT) > + if (TARGET_64BIT && !TARGET_ILP32) > { > rtx t = gen_reg_rtx (DImode); > emit_insn (gen_rotlsi3_sext (t, operands[1], operands[2])); > diff --git a/gcc/config/riscv/elf.h b/gcc/config/riscv/elf.h > index c97f13c0cca..d4afa78230b 100644 > --- a/gcc/config/riscv/elf.h > +++ b/gcc/config/riscv/elf.h > @@ -18,7 +18,7 @@ along with GCC; see the file COPYING3. If not see > <http://www.gnu.org/licenses/>. */ > > #define LINK_SPEC "\ > --melf" XLEN_SPEC DEFAULT_ENDIAN_SPEC "riscv \ > +-melf" ABI_LEN_SPEC DEFAULT_ENDIAN_SPEC "riscv \ > %{mno-relax:--no-relax} \ > -X \ > %{mbig-endian:-EB} \ > diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc > index 7694954c4c5..0390bece98b 100644 > --- a/gcc/config/riscv/riscv.cc > +++ b/gcc/config/riscv/riscv.cc > @@ -10471,7 +10471,8 @@ riscv_option_override (void) > error ("z*inx requires ABI ilp32, ilp32e, lp64 or lp64e"); > > /* We do not yet support ILP32 on RV64. */ > - if (BITS_PER_WORD != POINTER_SIZE) > + if (BITS_PER_WORD != POINTER_SIZE > + && !(BITS_PER_WORD == 64 && POINTER_SIZE == 32)) > error ("ABI requires %<-march=rv%d%>", POINTER_SIZE); > > /* Validate -mpreferred-stack-boundary= value. */ > diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h > index 8a8b08b6b51..726f6b73f33 100644 > --- a/gcc/config/riscv/riscv.h > +++ b/gcc/config/riscv/riscv.h > @@ -84,6 +84,10 @@ extern const char *riscv_arch_help (int argc, const char > **argv); > #define TARGET_64BIT (__riscv_xlen == 64) > #endif /* IN_LIBGCC2 */ > > +#ifndef TARGET_ILP32 > +#define TARGET_ILP32 (riscv_abi <= ABI_ILP32D) > +#endif /* TARGET_ILP32. */ > + > #ifdef HAVE_AS_MISA_SPEC > #define ASM_MISA_SPEC "%{misa-spec=*}" > #else > @@ -916,7 +920,7 @@ extern enum riscv_cc get_riscv_cc (const rtx use); > After generation of rtl, the compiler makes no further distinction > between pointers and any other objects of this machine mode. */ > > -#define Pmode word_mode > +#define Pmode (TARGET_ILP32 ? SImode : DImode) > > /* Specify the machine mode that registers have. */ > > @@ -1197,6 +1201,10 @@ extern poly_int64 riscv_v_adjust_bytesize (enum > machine_mode, int); > "%{march=rv32*:32}" \ > "%{march=rv64*:64}" \ > > +#define ABI_LEN_SPEC \ > + "%{mabi=ilp32*:32}" \ > + "%{mabi=lp64*:64}" \ > + > #define ABI_SPEC \ > "%{mabi=ilp32:ilp32}" \ > "%{mabi=ilp32e:ilp32e}" \ > diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md > index 5b7b73535a3..09ae8e8309d 100644 > --- a/gcc/config/riscv/riscv.md > +++ b/gcc/config/riscv/riscv.md > @@ -694,7 +694,7 @@ > (match_operand:SI 2 "arith_operand" " r,I")))] > "" > { > - if (TARGET_64BIT) > + if (TARGET_64BIT && !TARGET_ILP32) > { > rtx t = gen_reg_rtx (DImode); > emit_insn (gen_addsi3_extended (t, operands[1], operands[2])); > @@ -892,7 +892,7 @@ > (match_operand:SI 2 "register_operand" " r")))] > "" > { > - if (TARGET_64BIT) > + if (TARGET_64BIT && !TARGET_ILP32) > { > rtx t = gen_reg_rtx (DImode); > emit_insn (gen_subsi3_extended (t, operands[1], operands[2])); > @@ -1025,7 +1025,7 @@ > (neg:SI (match_operand:SI 1 "register_operand" " r")))] > "" > { > - if (TARGET_64BIT) > + if (TARGET_64BIT && !TARGET_ILP32) > { > rtx t = gen_reg_rtx (DImode); > emit_insn (gen_negsi2_extended (t, operands[1])); > @@ -1088,7 +1088,7 @@ > (match_operand:SI 2 "register_operand" " r")))] > "TARGET_ZMMUL || TARGET_MUL" > { > - if (TARGET_64BIT) > + if (TARGET_64BIT && !TARGET_ILP32) > { > rtx t = gen_reg_rtx (DImode); > emit_insn (gen_mulsi3_extended (t, operands[1], operands[2])); > @@ -1376,7 +1376,7 @@ > (match_operand:SI 2 "register_operand" " r")))] > "TARGET_DIV" > { > - if (TARGET_64BIT) > + if (TARGET_64BIT && !TARGET_ILP32) > { > rtx t = gen_reg_rtx (DImode); > emit_insn (gen_<optab>si3_extended (t, operands[1], operands[2])); > @@ -2845,7 +2845,7 @@ > (match_operand:QI 2 "arith_operand" " rI")))] > "" > { > - if (TARGET_64BIT) > + if (TARGET_64BIT && !TARGET_ILP32) > { > rtx t = gen_reg_rtx (DImode); > emit_insn (gen_<optab>si3_extend (t, operands[1], operands[2])); > @@ -3818,6 +3818,10 @@ > "reload_completed" > [(const_int 0)] > { > + if (GET_MODE (operands[0]) != Pmode) > + operands[0] = convert_to_mode (Pmode, operands[0], 0); > + if (GET_MODE (operands[1]) != Pmode) > + operands[1] = convert_to_mode (Pmode, operands[1], 0); > riscv_set_return_address (operands[0], operands[1]); > DONE; > }) > @@ -4072,8 +4076,8 @@ > > (define_insn "stack_tie<mode>" > [(set (mem:BLK (scratch)) > - (unspec:BLK [(match_operand:X 0 "register_operand" "r") > - (match_operand:X 1 "register_operand" "r")] > + (unspec:BLK [(match_operand:P 0 "register_operand" "r") > + (match_operand:P 1 "register_operand" "r")] > UNSPEC_TIE))] > "!rtx_equal_p (operands[0], operands[1])" > "" > -- > 2.34.1 > > -- Best Regards Guo Ren