Skip to content

Commit

Permalink
RISC-V: Initial RV64E and LP64E support
Browse files Browse the repository at this point in the history
Along with RV32E, RV64E is ratified.  Though ILP32E and LP64E ABIs are
still draft, it's worth supporting it.

This commit should not be merged until two proposals below are
going to proceed.

LP64E proposal (including suggested changes):
<riscv-non-isa/riscv-elf-psabi-doc#299>

New "__riscv_64e" proposal by the author of this commit:
<riscv-non-isa/riscv-c-api-doc#52>

gcc/ChangeLog:

	* common/config/riscv/riscv-common.cc
	(riscv_subset_list::parse_std_ext): Allow RV64E.
	* config.gcc: Parse base ISA 'rv64e' and ABI 'lp64e'.
	* config/riscv/arch-canonicalize: Parse base ISA 'rv64e'.
	* config/riscv/riscv-c.cc (riscv_cpu_cpp_builtins):
	Define different macro per XLEN.  Add handling for ABI_LP64E.
	* config/riscv/riscv-d.cc (riscv_d_handle_target_float_abi):
	Add handling for ABI_LP64E.
	* config/riscv/riscv-opts.h (enum riscv_abi_type): Add ABI_LP64E.
	* config/riscv/riscv.cc (riscv_option_override): Enhance error
	handling to support RV64E and LP64E.
	(riscv_conditional_register_usage): Change "RV32E" in a comment
	to "RV32E/RV64E".
	* config/riscv/riscv.h
	(UNITS_PER_FP_ARG): Add handling for ABI_LP64E.
	(STACK_BOUNDARY): Ditto.
	(ABI_STACK_BOUNDARY): Ditto.
	(MAX_ARGS_IN_REGISTERS): Ditto.
	(ABI_SPEC): Add support for "lp64e".
	* config/riscv/riscv.opt: Parse -mabi=lp64e as ABI_LP64E.
	* doc/invoke.texi: Add documentation of the LP64E ABI.

gcc/testsuite/ChangeLog:

	* gcc.target/riscv/predef-1.c: Test for __riscv_64e.
	* gcc.target/riscv/predef-2.c: Ditto.
	* gcc.target/riscv/predef-3.c: Ditto.
	* gcc.target/riscv/predef-4.c: Ditto.
	* gcc.target/riscv/predef-5.c: Ditto.
	* gcc.target/riscv/predef-6.c: Ditto.
	* gcc.target/riscv/predef-7.c: Ditto.
	* gcc.target/riscv/predef-8.c: Ditto.
	* gcc.target/riscv/predef-9.c: New test for RV64E and LP64E,
	based on predef-7.c.
  • Loading branch information
a4lg committed Oct 23, 2023
1 parent bcc5054 commit 72be4bc
Show file tree
Hide file tree
Showing 19 changed files with 134 additions and 21 deletions.
2 changes: 1 addition & 1 deletion gcc/common/config/riscv/riscv-common.cc
Original file line number Diff line number Diff line change
Expand Up @@ -963,7 +963,7 @@ riscv_subset_list::parse_std_ext (const char *p)

add ("e", major_version, minor_version, explicit_version_p, false);

if (m_xlen > 32)
if (m_xlen > 64)
{
error_at (m_loc, "%<-march=%s%>: rv%de is not a valid base ISA",
m_arch, m_xlen);
Expand Down
10 changes: 6 additions & 4 deletions gcc/config.gcc
Original file line number Diff line number Diff line change
Expand Up @@ -4695,7 +4695,7 @@ case "${target}" in

# Infer arch from --with-arch, --target, and --with-abi.
case "${with_arch}" in
rv32e* | rv32i* | rv32g* | rv64i* | rv64g*)
rv32e* | rv32i* | rv32g* | rv64e* | rv64i* | rv64g*)
# OK.
;;
"")
Expand All @@ -4704,11 +4704,12 @@ case "${target}" in
ilp32e) with_arch="rv32e" ;;
ilp32 | ilp32f | ilp32d) with_arch="rv32gc" ;;
lp64 | lp64f | lp64d) with_arch="rv64gc" ;;
lp64e) with_arch="rv64e" ;;
*) with_arch="rv${xlen}gc" ;;
esac
;;
*)
echo "--with-arch=${with_arch} is not supported. The argument must begin with rv32e, rv32i, rv32g, rv64i, or rv64g." 1>&2
echo "--with-arch=${with_arch} is not supported. The argument must begin with rv32e, rv32i, rv32g, rv64e, rv64i, or rv64g." 1>&2
exit 1
;;
esac
Expand All @@ -4722,14 +4723,15 @@ case "${target}" in
# pick a default based on the ISA, preferring soft-float
# unless the D extension is present.
case "${with_abi}" in
ilp32 | ilp32e | ilp32f | ilp32d | lp64 | lp64f | lp64d)
ilp32 | ilp32e | ilp32f | ilp32d | lp64 | lp64e | lp64f | lp64d)
;;
"")
case "${with_arch}" in
rv32*d* | rv32g*) with_abi=ilp32d ;;
rv32e*) with_abi=ilp32e ;;
rv32*) with_abi=ilp32 ;;
rv64*d* | rv64g*) with_abi=lp64d ;;
rv64e*) with_abi=lp64e ;;
rv64*) with_abi=lp64 ;;
esac
;;
Expand All @@ -4745,7 +4747,7 @@ case "${target}" in
ilp32,rv32* | ilp32e,rv32e* \
| ilp32f,rv32*f* | ilp32f,rv32g* \
| ilp32d,rv32*d* | ilp32d,rv32g* \
| lp64,rv64* \
| lp64,rv64* | lp64e,rv64e* \
| lp64f,rv64*f* | lp64f,rv64g* \
| lp64d,rv64*d* | lp64d,rv64g*)
;;
Expand Down
2 changes: 1 addition & 1 deletion gcc/config/riscv/arch-canonicalize
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def arch_canonicalize(arch, isa_spec):
new_arch = ""
extra_long_ext = []
std_exts = []
if arch[:5] in ['rv32e', 'rv32i', 'rv32g', 'rv64i', 'rv64g']:
if arch[:5] in ['rv32e', 'rv32i', 'rv32g', 'rv64e', 'rv64i', 'rv64g']:
new_arch = arch[:5].replace("g", "i")
if arch[:5] in ['rv32g', 'rv64g']:
std_exts = ['m', 'a', 'f', 'd']
Expand Down
3 changes: 2 additions & 1 deletion gcc/config/riscv/riscv-c.cc
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ riscv_cpu_cpp_builtins (cpp_reader *pfile)
builtin_define ("__riscv_compressed");

if (TARGET_RVE)
builtin_define ("__riscv_32e");
builtin_define (TARGET_64BIT ? "__riscv_64e" : "__riscv_32e");

if (TARGET_ATOMIC)
builtin_define ("__riscv_atomic");
Expand All @@ -76,6 +76,7 @@ riscv_cpu_cpp_builtins (cpp_reader *pfile)
switch (riscv_abi)
{
case ABI_ILP32E:
case ABI_LP64E:
builtin_define ("__riscv_abi_rve");
gcc_fallthrough ();

Expand Down
1 change: 1 addition & 0 deletions gcc/config/riscv/riscv-d.cc
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ riscv_d_handle_target_float_abi (void)
{
case ABI_ILP32E:
case ABI_ILP32:
case ABI_LP64E:
case ABI_LP64:
abi = "soft";
break;
Expand Down
1 change: 1 addition & 0 deletions gcc/config/riscv/riscv-opts.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ enum riscv_abi_type {
ABI_ILP32F,
ABI_ILP32D,
ABI_LP64,
ABI_LP64E,
ABI_LP64F,
ABI_LP64D
};
Expand Down
19 changes: 12 additions & 7 deletions gcc/config/riscv/riscv.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8136,13 +8136,18 @@ riscv_option_override (void)
error ("requested ABI requires %<-march%> to subsume the %qc extension",
UNITS_PER_FP_ARG > 8 ? 'Q' : (UNITS_PER_FP_ARG > 4 ? 'D' : 'F'));

if (TARGET_RVE && riscv_abi != ABI_ILP32E)
error ("rv32e requires ilp32e ABI");
/* RVE requires specific ABI. */
if (TARGET_RVE)
if (!TARGET_64BIT && riscv_abi != ABI_ILP32E)
error ("rv32e requires ilp32e ABI");
else if (TARGET_64BIT && riscv_abi != ABI_LP64E)
error ("rv64e requires lp64e ABI");

// Zfinx require abi ilp32,ilp32e or lp64.
if (TARGET_ZFINX && riscv_abi != ABI_ILP32
&& riscv_abi != ABI_LP64 && riscv_abi != ABI_ILP32E)
error ("z*inx requires ABI ilp32, ilp32e or lp64");
/* Zfinx require abi ilp32, ilp32e, lp64 or lp64e. */
if (TARGET_ZFINX
&& riscv_abi != ABI_ILP32 && riscv_abi != ABI_LP64
&& riscv_abi != ABI_ILP32E && riscv_abi != ABI_LP64E)
error ("z*inx requires ABI ilp32, ilp32e, lp64 or lp64e");

/* We do not yet support ILP32 on RV64. */
if (BITS_PER_WORD != POINTER_SIZE)
Expand Down Expand Up @@ -8235,7 +8240,7 @@ riscv_option_override (void)
static void
riscv_conditional_register_usage (void)
{
/* We have only x0~x15 on RV32E. */
/* We have only x0~x15 on RV32E/RV64E. */
if (TARGET_RVE)
{
for (int r = 16; r <= 31; r++)
Expand Down
17 changes: 13 additions & 4 deletions gcc/config/riscv/riscv.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ ASM_MISA_SPEC
/* The largest type that can be passed in floating-point registers. */
#define UNITS_PER_FP_ARG \
((riscv_abi == ABI_ILP32 || riscv_abi == ABI_ILP32E \
|| riscv_abi == ABI_LP64) \
|| riscv_abi == ABI_LP64 || riscv_abi == ABI_LP64E) \
? 0 \
: ((riscv_abi == ABI_ILP32F || riscv_abi == ABI_LP64F) ? 4 : 8))

Expand All @@ -191,10 +191,15 @@ ASM_MISA_SPEC

/* The smallest supported stack boundary the calling convention supports. */
#define STACK_BOUNDARY \
(riscv_abi == ABI_ILP32E ? BITS_PER_WORD : 2 * BITS_PER_WORD)
(riscv_abi == ABI_ILP32E || riscv_abi == ABI_LP64E \
? BITS_PER_WORD \
: 2 * BITS_PER_WORD)

/* The ABI stack alignment. */
#define ABI_STACK_BOUNDARY (riscv_abi == ABI_ILP32E ? BITS_PER_WORD : 128)
#define ABI_STACK_BOUNDARY \
(riscv_abi == ABI_ILP32E || riscv_abi == ABI_LP64E \
? BITS_PER_WORD \
: 128)

/* There is no point aligning anything to a rounder boundary than this. */
#define BIGGEST_ALIGNMENT 128
Expand Down Expand Up @@ -665,7 +670,10 @@ enum reg_class
#define GP_RETURN GP_ARG_FIRST
#define FP_RETURN (UNITS_PER_FP_ARG == 0 ? GP_RETURN : FP_ARG_FIRST)

#define MAX_ARGS_IN_REGISTERS (riscv_abi == ABI_ILP32E ? 6 : 8)
#define MAX_ARGS_IN_REGISTERS \
(riscv_abi == ABI_ILP32E || riscv_abi == ABI_LP64E \
? 6 \
: 8)

#define MAX_ARGS_IN_VECTOR_REGISTERS (16)
#define MAX_ARGS_IN_MASK_REGISTERS (1)
Expand Down Expand Up @@ -1130,6 +1138,7 @@ extern poly_int64 riscv_v_adjust_bytesize (enum machine_mode, int);
"%{mabi=ilp32f:ilp32f}" \
"%{mabi=ilp32d:ilp32d}" \
"%{mabi=lp64:lp64}" \
"%{mabi=lp64e:lp64e}" \
"%{mabi=lp64f:lp64f}" \
"%{mabi=lp64d:lp64d}" \

Expand Down
3 changes: 3 additions & 0 deletions gcc/config/riscv/riscv.opt
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ Enum(abi_type) String(ilp32d) Value(ABI_ILP32D)
EnumValue
Enum(abi_type) String(lp64) Value(ABI_LP64)

EnumValue
Enum(abi_type) String(lp64e) Value(ABI_LP64E)

EnumValue
Enum(abi_type) String(lp64f) Value(ABI_LP64F)

Expand Down
7 changes: 4 additions & 3 deletions gcc/doc/invoke.texi
Original file line number Diff line number Diff line change
Expand Up @@ -29468,9 +29468,10 @@ conventions are: @samp{ilp32}, @samp{ilp32f}, @samp{ilp32d}, @samp{lp64},
@samp{lp64f}, and @samp{lp64d}. Some calling conventions are impossible to
implement on some ISAs: for example, @samp{-march=rv32if -mabi=ilp32d} is
invalid because the ABI requires 64-bit values be passed in F registers, but F
registers are only 32 bits wide. There is also the @samp{ilp32e} ABI that can
only be used with the @samp{rv32e} architecture. This ABI is not well
specified at present, and is subject to change.
registers are only 32 bits wide. There are also the @samp{ilp32e} ABI that can
only be used with the @samp{rv32e} architecture and @samp{lp64e} ABI that can
only be used with the @samp{rv64e}. Those ABI are not well specified at
present, and is subject to change.

@opindex mfdiv
@item -mfdiv
Expand Down
3 changes: 3 additions & 0 deletions gcc/testsuite/gcc.target/riscv/predef-1.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ int main () {
#if defined(__riscv_32e)
#error "__riscv_32e"
#endif
#if defined(__riscv_64e)
#error "__riscv_64e"
#endif

#if defined(__riscv_atomic)
#error "__riscv_atomic"
Expand Down
3 changes: 3 additions & 0 deletions gcc/testsuite/gcc.target/riscv/predef-2.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ int main () {
#if defined(__riscv_32e)
#error "__riscv_32e"
#endif
#if defined(__riscv_64e)
#error "__riscv_64e"
#endif

#if !defined(__riscv_atomic)
#error "__riscv_atomic"
Expand Down
3 changes: 3 additions & 0 deletions gcc/testsuite/gcc.target/riscv/predef-3.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ int main () {
#if defined(__riscv_32e)
#error "__riscv_32e"
#endif
#if defined(__riscv_64e)
#error "__riscv_64e"
#endif

#if !defined(__riscv_atomic)
#error "__riscv_atomic"
Expand Down
3 changes: 3 additions & 0 deletions gcc/testsuite/gcc.target/riscv/predef-4.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ int main () {
#if defined(__riscv_32e)
#error "__riscv_32e"
#endif
#if defined(__riscv_64e)
#error "__riscv_64e"
#endif

#if !defined(__riscv_atomic)
#error "__riscv_atomic"
Expand Down
3 changes: 3 additions & 0 deletions gcc/testsuite/gcc.target/riscv/predef-5.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ int main () {
#if defined(__riscv_32e)
#error "__riscv_32e"
#endif
#if defined(__riscv_64e)
#error "__riscv_64e"
#endif

#if defined(__riscv_atomic)
#error "__riscv_atomic"
Expand Down
3 changes: 3 additions & 0 deletions gcc/testsuite/gcc.target/riscv/predef-6.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ int main () {
#if defined(__riscv_32e)
#error "__riscv_32e"
#endif
#if defined(__riscv_64e)
#error "__riscv_64e"
#endif

#if !defined(__riscv_atomic)
#error "__riscv_atomic"
Expand Down
3 changes: 3 additions & 0 deletions gcc/testsuite/gcc.target/riscv/predef-7.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ int main () {
#if !defined(__riscv_32e)
#error "__riscv_32e"
#endif
#if defined(__riscv_64e)
#error "__riscv_64e"
#endif

#if defined(__riscv_atomic)
#error "__riscv_atomic"
Expand Down
3 changes: 3 additions & 0 deletions gcc/testsuite/gcc.target/riscv/predef-8.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ int main () {
#if defined(__riscv_32e)
#error "__riscv_32e"
#endif
#if defined(__riscv_64e)
#error "__riscv_64e"
#endif

#if defined(__riscv_atomic)
#error "__riscv_atomic"
Expand Down
66 changes: 66 additions & 0 deletions gcc/testsuite/gcc.target/riscv/predef-9.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/* { dg-do compile } */
/* { dg-options "-march=rv64em -mabi=lp64e -mno-div -mcmodel=medlow" } */

int main () {
#if !defined(__riscv)
#error "__riscv"
#endif

#if defined(__riscv_compressed)
#error "__riscv_compressed"
#endif

#if defined(__riscv_32e)
#error "__riscv_32e"
#endif
#if !defined(__riscv_64e)
#error "__riscv_64e"
#endif

#if defined(__riscv_atomic)
#error "__riscv_atomic"
#endif

#if !defined(__riscv_mul)
#error "__riscv_mul"
#endif
#if defined(__riscv_div)
#error "__riscv_div"
#endif
#if defined(__riscv_muldiv)
#error "__riscv_muldiv"
#endif

#if __riscv_xlen != 64
#error "__riscv_xlen"
#endif

#if defined(__riscv_fdiv)
#error "__riscv_fdiv"
#endif
#if defined(__riscv_fsqrt)
#error "__riscv_fsqrt"
#endif

#if !defined(__riscv_abi_rve)
#error "__riscv_abi_rve"
#endif
#if !defined(__riscv_float_abi_soft)
#error "__riscv_float_abi_soft"
#endif
#if defined(__riscv_float_abi_single)
#error "__riscv_float_abi_single"
#endif
#if defined(__riscv_float_abi_double)
#error "__riscv_float_abi_double"
#endif

#if !defined(__riscv_cmodel_medlow)
#error "__riscv_cmodel_medlow"
#endif
#if defined(__riscv_cmodel_medany)
#error "__riscv_cmodel_medlow"
#endif

return 0;
}

0 comments on commit 72be4bc

Please sign in to comment.