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


Reply via email to