[gcc(refs/vendors/riscv/heads/gcc-13-with-riscv-opts)] RISC-V: Initial RV64E and LP64E support
Jeff Law
law@gcc.gnu.org
Mon Dec 4 03:42:26 GMT 2023
https://gcc.gnu.org/g:206fed657e1d01fe36c8b9bd4019af9b5a4158f8
commit 206fed657e1d01fe36c8b9bd4019af9b5a4158f8
Author: Tsukasa OI <research_trasio@irq.a4lg.com>
Date: Sat Oct 21 05:29:06 2023 +0000
RISC-V: Initial RV64E and LP64E support
Along with RV32E, RV64E is ratified. Though ILP32E and LP64E ABIs are
still draft, it's worth supporting it.
gcc/ChangeLog:
* common/config/riscv/riscv-common.cc
(riscv_ext_version_table): Set version to ratified 2.0.
(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.
(cherry picked from commit 006e90e13441c3716b40616282b200a0ef689376)
Diff:
---
gcc/common/config/riscv/riscv-common.cc | 8 ++--
gcc/config.gcc | 10 +++--
gcc/config/riscv/arch-canonicalize | 2 +-
gcc/config/riscv/riscv-c.cc | 3 +-
gcc/config/riscv/riscv-d.cc | 1 +
gcc/config/riscv/riscv-opts.h | 1 +
gcc/config/riscv/riscv.cc | 19 +++++----
gcc/config/riscv/riscv.h | 17 ++++++--
gcc/config/riscv/riscv.opt | 3 ++
gcc/doc/invoke.texi | 7 ++--
gcc/testsuite/gcc.target/riscv/predef-1.c | 3 ++
gcc/testsuite/gcc.target/riscv/predef-2.c | 3 ++
gcc/testsuite/gcc.target/riscv/predef-3.c | 3 ++
gcc/testsuite/gcc.target/riscv/predef-4.c | 3 ++
gcc/testsuite/gcc.target/riscv/predef-5.c | 3 ++
gcc/testsuite/gcc.target/riscv/predef-6.c | 3 ++
gcc/testsuite/gcc.target/riscv/predef-7.c | 3 ++
gcc/testsuite/gcc.target/riscv/predef-8.c | 3 ++
gcc/testsuite/gcc.target/riscv/predef-9.c | 66 +++++++++++++++++++++++++++++++
19 files changed, 137 insertions(+), 24 deletions(-)
diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc
index 5111626157b..ded85b4c578 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -169,9 +169,9 @@ struct riscv_ext_version
static const struct riscv_ext_version riscv_ext_version_table[] =
{
/* name, ISA spec, major version, minor_version. */
- {"e", ISA_SPEC_CLASS_20191213, 1, 9},
- {"e", ISA_SPEC_CLASS_20190608, 1, 9},
- {"e", ISA_SPEC_CLASS_2P2, 1, 9},
+ {"e", ISA_SPEC_CLASS_20191213, 2, 0},
+ {"e", ISA_SPEC_CLASS_20190608, 2, 0},
+ {"e", ISA_SPEC_CLASS_2P2, 2, 0},
{"i", ISA_SPEC_CLASS_20191213, 2, 1},
{"i", ISA_SPEC_CLASS_20190608, 2, 1},
@@ -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);
diff --git a/gcc/config.gcc b/gcc/config.gcc
index a5d870b37af..b49a4107cf5 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -4609,7 +4609,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.
;;
"")
@@ -4618,11 +4618,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
@@ -4636,7 +4637,7 @@ 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
@@ -4644,6 +4645,7 @@ case "${target}" in
rv32e*) with_abi=ilp32e ;;
rv32*) with_abi=ilp32 ;;
rv64*d* | rv64g*) with_abi=lp64d ;;
+ rv64e*) with_abi=lp64e ;;
rv64*) with_abi=lp64 ;;
esac
;;
@@ -4659,7 +4661,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*)
;;
diff --git a/gcc/config/riscv/arch-canonicalize b/gcc/config/riscv/arch-canonicalize
index bbb9261bd87..ea2f67a0944 100755
--- a/gcc/config/riscv/arch-canonicalize
+++ b/gcc/config/riscv/arch-canonicalize
@@ -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']
diff --git a/gcc/config/riscv/riscv-c.cc b/gcc/config/riscv/riscv-c.cc
index dd1bd0596fc..d70eb8ed361 100644
--- a/gcc/config/riscv/riscv-c.cc
+++ b/gcc/config/riscv/riscv-c.cc
@@ -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");
@@ -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 ();
diff --git a/gcc/config/riscv/riscv-d.cc b/gcc/config/riscv/riscv-d.cc
index cfeafa81978..3ba34708e76 100644
--- a/gcc/config/riscv/riscv-d.cc
+++ b/gcc/config/riscv/riscv-d.cc
@@ -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;
diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h
index 0b242f068e1..e6e55ad7071 100644
--- a/gcc/config/riscv/riscv-opts.h
+++ b/gcc/config/riscv/riscv-opts.h
@@ -27,6 +27,7 @@ enum riscv_abi_type {
ABI_ILP32F,
ABI_ILP32D,
ABI_LP64,
+ ABI_LP64E,
ABI_LP64F,
ABI_LP64D
};
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 425463ebb18..a4fc858fb50 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -8669,13 +8669,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)
@@ -8801,7 +8806,7 @@ static GTY (()) tree riscv_previous_fndecl;
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++)
diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
index 6205d7533f4..6df9ec73c5e 100644
--- a/gcc/config/riscv/riscv.h
+++ b/gcc/config/riscv/riscv.h
@@ -170,7 +170,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))
@@ -193,10 +193,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
@@ -669,7 +674,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)
@@ -1138,6 +1146,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}" \
diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt
index 11526f9cc2a..0c6517bdc8b 100644
--- a/gcc/config/riscv/riscv.opt
+++ b/gcc/config/riscv/riscv.opt
@@ -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)
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 2667a7d7acc..f712ab68f87 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -28941,9 +28941,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 the @samp{lp64e} ABI that
+can only be used with the @samp{rv64e}. Those ABIs are not well specified at
+present, and are subject to change.
@opindex mfdiv
@item -mfdiv
diff --git a/gcc/testsuite/gcc.target/riscv/predef-1.c b/gcc/testsuite/gcc.target/riscv/predef-1.c
index 9dddc184963..250812a1040 100644
--- a/gcc/testsuite/gcc.target/riscv/predef-1.c
+++ b/gcc/testsuite/gcc.target/riscv/predef-1.c
@@ -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"
diff --git a/gcc/testsuite/gcc.target/riscv/predef-2.c b/gcc/testsuite/gcc.target/riscv/predef-2.c
index 755fe4ef7d8..fa5bdea7f3a 100644
--- a/gcc/testsuite/gcc.target/riscv/predef-2.c
+++ b/gcc/testsuite/gcc.target/riscv/predef-2.c
@@ -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"
diff --git a/gcc/testsuite/gcc.target/riscv/predef-3.c b/gcc/testsuite/gcc.target/riscv/predef-3.c
index 513645351c0..868b5611847 100644
--- a/gcc/testsuite/gcc.target/riscv/predef-3.c
+++ b/gcc/testsuite/gcc.target/riscv/predef-3.c
@@ -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"
diff --git a/gcc/testsuite/gcc.target/riscv/predef-4.c b/gcc/testsuite/gcc.target/riscv/predef-4.c
index 76b6feec6b6..ba8b5c785a9 100644
--- a/gcc/testsuite/gcc.target/riscv/predef-4.c
+++ b/gcc/testsuite/gcc.target/riscv/predef-4.c
@@ -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"
diff --git a/gcc/testsuite/gcc.target/riscv/predef-5.c b/gcc/testsuite/gcc.target/riscv/predef-5.c
index 54a51508afb..560d6ea823f 100644
--- a/gcc/testsuite/gcc.target/riscv/predef-5.c
+++ b/gcc/testsuite/gcc.target/riscv/predef-5.c
@@ -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"
diff --git a/gcc/testsuite/gcc.target/riscv/predef-6.c b/gcc/testsuite/gcc.target/riscv/predef-6.c
index f61709f7bf3..8987b72a5db 100644
--- a/gcc/testsuite/gcc.target/riscv/predef-6.c
+++ b/gcc/testsuite/gcc.target/riscv/predef-6.c
@@ -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"
diff --git a/gcc/testsuite/gcc.target/riscv/predef-7.c b/gcc/testsuite/gcc.target/riscv/predef-7.c
index 41217554c4d..833e2be887d 100644
--- a/gcc/testsuite/gcc.target/riscv/predef-7.c
+++ b/gcc/testsuite/gcc.target/riscv/predef-7.c
@@ -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"
diff --git a/gcc/testsuite/gcc.target/riscv/predef-8.c b/gcc/testsuite/gcc.target/riscv/predef-8.c
index 982056a5343..8fa8b42f334 100644
--- a/gcc/testsuite/gcc.target/riscv/predef-8.c
+++ b/gcc/testsuite/gcc.target/riscv/predef-8.c
@@ -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"
diff --git a/gcc/testsuite/gcc.target/riscv/predef-9.c b/gcc/testsuite/gcc.target/riscv/predef-9.c
new file mode 100644
index 00000000000..cc3abc9a741
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/predef-9.c
@@ -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;
+}
More information about the Gcc-cvs
mailing list