From: Liao Shihua <shi...@iscas.ac.cn> 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/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. * 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/riscv.cc | 4 ---- gcc/config/riscv/riscv.h | 8 ++++++-- gcc/config/riscv/riscv.md | 8 ++++++-- 4 files changed, 15 insertions(+), 8 deletions(-) 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/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..63aece89878 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. */ 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))] "" "" -- 2.38.0.windows.1