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