Skip to content

Commit 72be4bc

Browse files
committed
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. 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.
1 parent bcc5054 commit 72be4bc

File tree

19 files changed

+134
-21
lines changed

19 files changed

+134
-21
lines changed

gcc/common/config/riscv/riscv-common.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -963,7 +963,7 @@ riscv_subset_list::parse_std_ext (const char *p)
963963

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

966-
if (m_xlen > 32)
966+
if (m_xlen > 64)
967967
{
968968
error_at (m_loc, "%<-march=%s%>: rv%de is not a valid base ISA",
969969
m_arch, m_xlen);

gcc/config.gcc

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4695,7 +4695,7 @@ case "${target}" in
46954695

46964696
# Infer arch from --with-arch, --target, and --with-abi.
46974697
case "${with_arch}" in
4698-
rv32e* | rv32i* | rv32g* | rv64i* | rv64g*)
4698+
rv32e* | rv32i* | rv32g* | rv64e* | rv64i* | rv64g*)
46994699
# OK.
47004700
;;
47014701
"")
@@ -4704,11 +4704,12 @@ case "${target}" in
47044704
ilp32e) with_arch="rv32e" ;;
47054705
ilp32 | ilp32f | ilp32d) with_arch="rv32gc" ;;
47064706
lp64 | lp64f | lp64d) with_arch="rv64gc" ;;
4707+
lp64e) with_arch="rv64e" ;;
47074708
*) with_arch="rv${xlen}gc" ;;
47084709
esac
47094710
;;
47104711
*)
4711-
echo "--with-arch=${with_arch} is not supported. The argument must begin with rv32e, rv32i, rv32g, rv64i, or rv64g." 1>&2
4712+
echo "--with-arch=${with_arch} is not supported. The argument must begin with rv32e, rv32i, rv32g, rv64e, rv64i, or rv64g." 1>&2
47124713
exit 1
47134714
;;
47144715
esac
@@ -4722,14 +4723,15 @@ case "${target}" in
47224723
# pick a default based on the ISA, preferring soft-float
47234724
# unless the D extension is present.
47244725
case "${with_abi}" in
4725-
ilp32 | ilp32e | ilp32f | ilp32d | lp64 | lp64f | lp64d)
4726+
ilp32 | ilp32e | ilp32f | ilp32d | lp64 | lp64e | lp64f | lp64d)
47264727
;;
47274728
"")
47284729
case "${with_arch}" in
47294730
rv32*d* | rv32g*) with_abi=ilp32d ;;
47304731
rv32e*) with_abi=ilp32e ;;
47314732
rv32*) with_abi=ilp32 ;;
47324733
rv64*d* | rv64g*) with_abi=lp64d ;;
4734+
rv64e*) with_abi=lp64e ;;
47334735
rv64*) with_abi=lp64 ;;
47344736
esac
47354737
;;
@@ -4745,7 +4747,7 @@ case "${target}" in
47454747
ilp32,rv32* | ilp32e,rv32e* \
47464748
| ilp32f,rv32*f* | ilp32f,rv32g* \
47474749
| ilp32d,rv32*d* | ilp32d,rv32g* \
4748-
| lp64,rv64* \
4750+
| lp64,rv64* | lp64e,rv64e* \
47494751
| lp64f,rv64*f* | lp64f,rv64g* \
47504752
| lp64d,rv64*d* | lp64d,rv64g*)
47514753
;;

gcc/config/riscv/arch-canonicalize

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ def arch_canonicalize(arch, isa_spec):
8383
new_arch = ""
8484
extra_long_ext = []
8585
std_exts = []
86-
if arch[:5] in ['rv32e', 'rv32i', 'rv32g', 'rv64i', 'rv64g']:
86+
if arch[:5] in ['rv32e', 'rv32i', 'rv32g', 'rv64e', 'rv64i', 'rv64g']:
8787
new_arch = arch[:5].replace("g", "i")
8888
if arch[:5] in ['rv32g', 'rv64g']:
8989
std_exts = ['m', 'a', 'f', 'd']

gcc/config/riscv/riscv-c.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ riscv_cpu_cpp_builtins (cpp_reader *pfile)
5151
builtin_define ("__riscv_compressed");
5252

5353
if (TARGET_RVE)
54-
builtin_define ("__riscv_32e");
54+
builtin_define (TARGET_64BIT ? "__riscv_64e" : "__riscv_32e");
5555

5656
if (TARGET_ATOMIC)
5757
builtin_define ("__riscv_atomic");
@@ -76,6 +76,7 @@ riscv_cpu_cpp_builtins (cpp_reader *pfile)
7676
switch (riscv_abi)
7777
{
7878
case ABI_ILP32E:
79+
case ABI_LP64E:
7980
builtin_define ("__riscv_abi_rve");
8081
gcc_fallthrough ();
8182

gcc/config/riscv/riscv-d.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ riscv_d_handle_target_float_abi (void)
5252
{
5353
case ABI_ILP32E:
5454
case ABI_ILP32:
55+
case ABI_LP64E:
5556
case ABI_LP64:
5657
abi = "soft";
5758
break;

gcc/config/riscv/riscv-opts.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ enum riscv_abi_type {
2727
ABI_ILP32F,
2828
ABI_ILP32D,
2929
ABI_LP64,
30+
ABI_LP64E,
3031
ABI_LP64F,
3132
ABI_LP64D
3233
};

gcc/config/riscv/riscv.cc

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8136,13 +8136,18 @@ riscv_option_override (void)
81368136
error ("requested ABI requires %<-march%> to subsume the %qc extension",
81378137
UNITS_PER_FP_ARG > 8 ? 'Q' : (UNITS_PER_FP_ARG > 4 ? 'D' : 'F'));
81388138

8139-
if (TARGET_RVE && riscv_abi != ABI_ILP32E)
8140-
error ("rv32e requires ilp32e ABI");
8139+
/* RVE requires specific ABI. */
8140+
if (TARGET_RVE)
8141+
if (!TARGET_64BIT && riscv_abi != ABI_ILP32E)
8142+
error ("rv32e requires ilp32e ABI");
8143+
else if (TARGET_64BIT && riscv_abi != ABI_LP64E)
8144+
error ("rv64e requires lp64e ABI");
81418145

8142-
// Zfinx require abi ilp32,ilp32e or lp64.
8143-
if (TARGET_ZFINX && riscv_abi != ABI_ILP32
8144-
&& riscv_abi != ABI_LP64 && riscv_abi != ABI_ILP32E)
8145-
error ("z*inx requires ABI ilp32, ilp32e or lp64");
8146+
/* Zfinx require abi ilp32, ilp32e, lp64 or lp64e. */
8147+
if (TARGET_ZFINX
8148+
&& riscv_abi != ABI_ILP32 && riscv_abi != ABI_LP64
8149+
&& riscv_abi != ABI_ILP32E && riscv_abi != ABI_LP64E)
8150+
error ("z*inx requires ABI ilp32, ilp32e, lp64 or lp64e");
81468151

81478152
/* We do not yet support ILP32 on RV64. */
81488153
if (BITS_PER_WORD != POINTER_SIZE)
@@ -8235,7 +8240,7 @@ riscv_option_override (void)
82358240
static void
82368241
riscv_conditional_register_usage (void)
82378242
{
8238-
/* We have only x0~x15 on RV32E. */
8243+
/* We have only x0~x15 on RV32E/RV64E. */
82398244
if (TARGET_RVE)
82408245
{
82418246
for (int r = 16; r <= 31; r++)

gcc/config/riscv/riscv.h

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ ASM_MISA_SPEC
168168
/* The largest type that can be passed in floating-point registers. */
169169
#define UNITS_PER_FP_ARG \
170170
((riscv_abi == ABI_ILP32 || riscv_abi == ABI_ILP32E \
171-
|| riscv_abi == ABI_LP64) \
171+
|| riscv_abi == ABI_LP64 || riscv_abi == ABI_LP64E) \
172172
? 0 \
173173
: ((riscv_abi == ABI_ILP32F || riscv_abi == ABI_LP64F) ? 4 : 8))
174174

@@ -191,10 +191,15 @@ ASM_MISA_SPEC
191191

192192
/* The smallest supported stack boundary the calling convention supports. */
193193
#define STACK_BOUNDARY \
194-
(riscv_abi == ABI_ILP32E ? BITS_PER_WORD : 2 * BITS_PER_WORD)
194+
(riscv_abi == ABI_ILP32E || riscv_abi == ABI_LP64E \
195+
? BITS_PER_WORD \
196+
: 2 * BITS_PER_WORD)
195197

196198
/* The ABI stack alignment. */
197-
#define ABI_STACK_BOUNDARY (riscv_abi == ABI_ILP32E ? BITS_PER_WORD : 128)
199+
#define ABI_STACK_BOUNDARY \
200+
(riscv_abi == ABI_ILP32E || riscv_abi == ABI_LP64E \
201+
? BITS_PER_WORD \
202+
: 128)
198203

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

668-
#define MAX_ARGS_IN_REGISTERS (riscv_abi == ABI_ILP32E ? 6 : 8)
673+
#define MAX_ARGS_IN_REGISTERS \
674+
(riscv_abi == ABI_ILP32E || riscv_abi == ABI_LP64E \
675+
? 6 \
676+
: 8)
669677

670678
#define MAX_ARGS_IN_VECTOR_REGISTERS (16)
671679
#define MAX_ARGS_IN_MASK_REGISTERS (1)
@@ -1130,6 +1138,7 @@ extern poly_int64 riscv_v_adjust_bytesize (enum machine_mode, int);
11301138
"%{mabi=ilp32f:ilp32f}" \
11311139
"%{mabi=ilp32d:ilp32d}" \
11321140
"%{mabi=lp64:lp64}" \
1141+
"%{mabi=lp64e:lp64e}" \
11331142
"%{mabi=lp64f:lp64f}" \
11341143
"%{mabi=lp64d:lp64d}" \
11351144

gcc/config/riscv/riscv.opt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ Enum(abi_type) String(ilp32d) Value(ABI_ILP32D)
6464
EnumValue
6565
Enum(abi_type) String(lp64) Value(ABI_LP64)
6666

67+
EnumValue
68+
Enum(abi_type) String(lp64e) Value(ABI_LP64E)
69+
6770
EnumValue
6871
Enum(abi_type) String(lp64f) Value(ABI_LP64F)
6972

gcc/doc/invoke.texi

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29468,9 +29468,10 @@ conventions are: @samp{ilp32}, @samp{ilp32f}, @samp{ilp32d}, @samp{lp64},
2946829468
@samp{lp64f}, and @samp{lp64d}. Some calling conventions are impossible to
2946929469
implement on some ISAs: for example, @samp{-march=rv32if -mabi=ilp32d} is
2947029470
invalid because the ABI requires 64-bit values be passed in F registers, but F
29471-
registers are only 32 bits wide. There is also the @samp{ilp32e} ABI that can
29472-
only be used with the @samp{rv32e} architecture. This ABI is not well
29473-
specified at present, and is subject to change.
29471+
registers are only 32 bits wide. There are also the @samp{ilp32e} ABI that can
29472+
only be used with the @samp{rv32e} architecture and @samp{lp64e} ABI that can
29473+
only be used with the @samp{rv64e}. Those ABI are not well specified at
29474+
present, and is subject to change.
2947429475

2947529476
@opindex mfdiv
2947629477
@item -mfdiv

0 commit comments

Comments
 (0)