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