[RFC,v2] Support RV64-ILP32

Message ID 20221228040154.778-1-shihua@iscas.ac.cn
State New
Headers
Series [RFC,v2] Support RV64-ILP32 |

Commit Message

Liao Shihua Dec. 28, 2022, 4:01 a.m. UTC
  From: Liao Shihua <shihua@iscas.ac.cn>

patch v1<https://gcc.gnu.org/pipermail/gcc-patches/2022-December/608370.html>

1. use ABI_LEN_SPEC instead of ABI_LEN_SPEC


      This patch support rv64 insn in ilp32 ABI. It was inspired by aarch64 both 
   support 64-bit and 32-bit ABI with the same set of instructions.

gcc/ChangeLog:

        * config.gcc: Implememt ilp32* with rv64*.
        * config/riscv/elf.h (LINK_SPEC): use ABI_LEN_SPEC instead of XLEN_SPEC
        * config/riscv/freebsd.h (LINK_SPEC): Likewise
        (STARTFILE_PREFIX_SPEC): Likewise
        * config/riscv/linux.h (GLIBC_DYNAMIC_LINKER): Likewise
        (MUSL_DYNAMIC_LINKER): Likewise
        (LINK_SPEC): Likewise
        (STARTFILE_PREFIX_SPEC): Likewise
        * config/riscv/riscv.cc (riscv_option_override): Remove the constraint between RV64 and ILP32.
        * config/riscv/riscv.h (TARGET_ILP32): Define TARGET_ILP32 with riscv_abi.
        (POINTER_SIZE): POINTER_SIZE will change with TARGET_ILP32.
        (Pmode): Likewise.
        (XLEN_SPEC): Remove
        (ABI_LEN_SPEC): Define ABI_LEN_SPEC with -mabi option .
        * config/riscv/riscv.md: Convert split mode with Pmode and change mode form Xmode to Pmode in stack_tie.
---
 gcc/config.gcc             |  3 +++
 gcc/config/riscv/elf.h     |  2 +-
 gcc/config/riscv/freebsd.h |  6 +++---
 gcc/config/riscv/linux.h   | 10 +++++-----
 gcc/config/riscv/riscv.cc  |  4 ----
 gcc/config/riscv/riscv.h   | 14 +++++++++-----
 gcc/config/riscv/riscv.md  |  8 ++++++--
 7 files changed, 27 insertions(+), 20 deletions(-)
  

Patch

diff --git a/gcc/config.gcc b/gcc/config.gcc
index c5064dd3766..069293a6e19 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -4748,6 +4748,9 @@  case "${target}" in
 		ilp32,rv32* | ilp32e,rv32e* \
 		| ilp32f,rv32*f* | ilp32f,rv32g* \
 		| ilp32d,rv32*d* | ilp32d,rv32g* \
+		| ilp32f,rv64*f* | ilp32f,rv64g* \
+		| ilp32d,rv64*d* | ilp32d,rv64g* \
+		| ilp32,rv64* \
 		| lp64,rv64* \
 		| lp64f,rv64*f* | lp64f,rv64g* \
 		| lp64d,rv64*d* | lp64d,rv64g*)
diff --git a/gcc/config/riscv/elf.h b/gcc/config/riscv/elf.h
index f0e865d6ef4..efc79f3147b 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} \
 %{mbig-endian:-EB} \
 %{mlittle-endian:-EL} \
diff --git a/gcc/config/riscv/freebsd.h b/gcc/config/riscv/freebsd.h
index 5e5cbe03166..8d72611db7b 100644
--- a/gcc/config/riscv/freebsd.h
+++ b/gcc/config/riscv/freebsd.h
@@ -40,7 +40,7 @@  along with GCC; see the file COPYING3.  If not see
 
 #undef LINK_SPEC
 #define LINK_SPEC "						\
-  -melf" XLEN_SPEC DEFAULT_ENDIAN_SPEC "riscv			\
+  -melf" ABI_LEN_SPEC DEFAULT_ENDIAN_SPEC "riscv			\
   %{p:%nconsider using `-pg' instead of `-p' with gprof (1)}	\
   %{v:-V}							\
   %{assert*} %{R*} %{rpath*} %{defsym*}				\
@@ -56,7 +56,7 @@  along with GCC; see the file COPYING3.  If not see
         %{static:-static}}"
 
 #define STARTFILE_PREFIX_SPEC 			\
-   "/lib" XLEN_SPEC "/" ABI_SPEC "/ "		\
-   "/usr/lib" XLEN_SPEC "/" ABI_SPEC "/ "	\
+   "/lib" ABI_LEN_SPEC "/" ABI_SPEC "/ "		\
+   "/usr/lib" ABI_LEN_SPEC "/" ABI_SPEC "/ "	\
    "/lib/ "					\
    "/usr/lib/ "
diff --git a/gcc/config/riscv/linux.h b/gcc/config/riscv/linux.h
index 38803723ba9..0953809976a 100644
--- a/gcc/config/riscv/linux.h
+++ b/gcc/config/riscv/linux.h
@@ -22,7 +22,7 @@  along with GCC; see the file COPYING3.  If not see
     GNU_USER_TARGET_OS_CPP_BUILTINS();				\
   } while (0)
 
-#define GLIBC_DYNAMIC_LINKER "/lib/ld-linux-riscv" XLEN_SPEC "-" ABI_SPEC ".so.1"
+#define GLIBC_DYNAMIC_LINKER "/lib/ld-linux-riscv" ABI_LEN_SPEC "-" ABI_SPEC ".so.1"
 
 #define MUSL_ABI_SUFFIX \
   "%{mabi=ilp32:-sf}" \
@@ -33,7 +33,7 @@  along with GCC; see the file COPYING3.  If not see
   "%{mabi=lp64d:}"
 
 #undef MUSL_DYNAMIC_LINKER
-#define MUSL_DYNAMIC_LINKER "/lib/ld-musl-riscv" XLEN_SPEC MUSL_ABI_SUFFIX ".so.1"
+#define MUSL_DYNAMIC_LINKER "/lib/ld-musl-riscv" ABI_LEN_SPEC MUSL_ABI_SUFFIX ".so.1"
 
 /* Because RISC-V only has word-sized atomics, it requries libatomic where
    others do not.  So link libatomic by default, as needed.  */
@@ -58,7 +58,7 @@  along with GCC; see the file COPYING3.  If not see
   "%{mabi=ilp32:_ilp32}"
 
 #define LINK_SPEC "\
--melf" XLEN_SPEC DEFAULT_ENDIAN_SPEC "riscv" LD_EMUL_SUFFIX " \
+-melf" ABI_LEN_SPEC DEFAULT_ENDIAN_SPEC "riscv" LD_EMUL_SUFFIX " \
 %{mno-relax:--no-relax} \
 %{mbig-endian:-EB} \
 %{mlittle-endian:-EL} \
@@ -72,7 +72,7 @@  along with GCC; see the file COPYING3.  If not see
 #define TARGET_ASM_FILE_END file_end_indicate_exec_stack
 
 #define STARTFILE_PREFIX_SPEC 			\
-   "/lib" XLEN_SPEC "/" ABI_SPEC "/ "		\
-   "/usr/lib" XLEN_SPEC "/" ABI_SPEC "/ "	\
+   "/lib" ABI_LEN_SPEC "/" ABI_SPEC "/ "		\
+   "/usr/lib" ABI_LEN_SPEC "/" ABI_SPEC "/ "	\
    "/lib/ "					\
    "/usr/lib/ "
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index ee756aab694..03f313e2b28 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -5026,10 +5026,6 @@  riscv_option_override (void)
   if (TARGET_RVE && riscv_abi != ABI_ILP32E)
     error ("rv32e requires ilp32e ABI");
 
-  /* We do not yet support ILP32 on RV64.  */
-  if (BITS_PER_WORD != POINTER_SIZE)
-    error ("ABI requires %<-march=rv%d%>", POINTER_SIZE);
-
   /* Validate -mpreferred-stack-boundary= value.  */
   riscv_stack_boundary = ABI_STACK_BOUNDARY;
   if (riscv_preferred_stack_boundary_arg)
diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
index 8a4d2cf7f85..0acdacf5df0 100644
--- a/gcc/config/riscv/riscv.h
+++ b/gcc/config/riscv/riscv.h
@@ -79,6 +79,10 @@  extern const char *riscv_default_mtune (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
@@ -167,7 +171,7 @@  ASM_MISA_SPEC
 #define SHORT_TYPE_SIZE 16
 #define INT_TYPE_SIZE 32
 #define LONG_LONG_TYPE_SIZE 64
-#define POINTER_SIZE (riscv_abi >= ABI_LP64 ? 64 : 32)
+#define POINTER_SIZE           (TARGET_ILP32 ? 32 : 64)
 #define LONG_TYPE_SIZE POINTER_SIZE
 
 #define FLOAT_TYPE_SIZE 32
@@ -729,7 +733,7 @@  typedef struct {
    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)
 
 /* Give call MEMs SImode since it is the "most permissive" mode
    for both 32-bit and 64-bit targets.  */
@@ -960,9 +964,9 @@  extern unsigned riscv_stack_boundary;
 #define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) \
   (((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | DW_EH_PE_sdata4)
 
-#define XLEN_SPEC \
-  "%{march=rv32*:32}" \
-  "%{march=rv64*:64}" \
+#define ABI_LEN_SPEC \
+  "%{mabi=ilp32*:32}" \
+  "%{mabi=lp64*:64}" \
 
 #define ABI_SPEC \
   "%{mabi=ilp32:ilp32}" \
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index b3c5bce842a..34034aec8c0 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -2559,6 +2559,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;
 })
@@ -2759,8 +2763,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))]
   ""
   ""