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

Reply via email to