Skip to content

Commit 09baee1

Browse files
kito-chengJim Wilson
authored andcommitted
RISC-V: Add RV32E support.
Kito Cheng <[email protected]> Monk Chiang <[email protected]> gcc/ * common/config/riscv/riscv-common.c (riscv_parse_arch_string): Add support to parse rv32e*. Clear MASK_RVE for rv32i and rv64i. * config.gcc (riscv*-*-*): Add support for rv32e* and ilp32e. * config/riscv/riscv-c.c (riscv_cpu_cpp_builtins): Define __riscv_32e when TARGET_RVE. Handle ABI_ILP32E as soft-float ABI. * config/riscv/riscv-opts.h (riscv_abi_type): Add ABI_ILP32E. * config/riscv/riscv.c (riscv_compute_frame_info): When TARGET_RVE, compute save_libcall_adjustment properly. (riscv_option_override): Call error if TARGET_RVE and not ABI_ILP32E. (riscv_conditional_register_usage): Handle TARGET_RVE and ABI_ILP32E. * config/riscv/riscv.h (UNITS_PER_FP_ARG): Handle ABI_ILP32E. (STACK_BOUNDARY, ABI_STACK_BOUNDARY): Handle TARGET_RVE. (GP_REG_LAST, MAX_ARGS_IN_REGISTERS): Likewise. (ABI_SPEC): Handle mabi=ilp32e. * config/riscv/riscv.opt (abi_type): Add ABI_ILP32E. (RVE): Add RVE mask. * doc/invoke.texi (RISC-V options) <-mabi>: Add ilp32e info. <-march>: Add rv32e as an example. gcc/testsuite/ * gcc.dg/stack-usage-1.c: Add support for rv32e. libgcc/ * config/riscv/save-restore.S: Add support for rv32e. Co-Authored-By: Jim Wilson <[email protected]> Co-Authored-By: Monk Chiang <[email protected]> From-SVN: r260384
1 parent dc2ebc9 commit 09baee1

File tree

13 files changed

+166
-17
lines changed

13 files changed

+166
-17
lines changed

gcc/ChangeLog

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,26 @@
1+
2018-05-18 Kito Cheng <[email protected]>
2+
Monk Chiang <[email protected]>
3+
Jim Wilson <[email protected]>
4+
5+
* common/config/riscv/riscv-common.c (riscv_parse_arch_string):
6+
Add support to parse rv32e*. Clear MASK_RVE for rv32i and rv64i.
7+
* config.gcc (riscv*-*-*): Add support for rv32e* and ilp32e.
8+
* config/riscv/riscv-c.c (riscv_cpu_cpp_builtins): Define
9+
__riscv_32e when TARGET_RVE. Handle ABI_ILP32E as soft-float ABI.
10+
* config/riscv/riscv-opts.h (riscv_abi_type): Add ABI_ILP32E.
11+
* config/riscv/riscv.c (riscv_compute_frame_info): When TARGET_RVE,
12+
compute save_libcall_adjustment properly.
13+
(riscv_option_override): Call error if TARGET_RVE and not ABI_ILP32E.
14+
(riscv_conditional_register_usage): Handle TARGET_RVE and ABI_ILP32E.
15+
* config/riscv/riscv.h (UNITS_PER_FP_ARG): Handle ABI_ILP32E.
16+
(STACK_BOUNDARY, ABI_STACK_BOUNDARY): Handle TARGET_RVE.
17+
(GP_REG_LAST, MAX_ARGS_IN_REGISTERS): Likewise.
18+
(ABI_SPEC): Handle mabi=ilp32e.
19+
* config/riscv/riscv.opt (abi_type): Add ABI_ILP32E.
20+
(RVE): Add RVE mask.
21+
* doc/invoke.texi (RISC-V options) <-mabi>: Add ilp32e info.
22+
<-march>: Add rv32e as an example.
23+
124
2018-05-18 Marc Glisse <[email protected]>
225

326
PR c++/82899

gcc/common/config/riscv/riscv-common.c

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ along with GCC; see the file COPYING3. If not see
2727
#include "flags.h"
2828
#include "diagnostic-core.h"
2929

30-
/* Parse a RISC-V ISA string into an option mask. */
30+
/* Parse a RISC-V ISA string into an option mask. Must clear or set all arch
31+
dependent mask bits, in case more than one -march string is passed. */
3132

3233
static void
3334
riscv_parse_arch_string (const char *isa, int *flags, location_t loc)
@@ -48,6 +49,8 @@ riscv_parse_arch_string (const char *isa, int *flags, location_t loc)
4849
{
4950
p++;
5051

52+
*flags &= ~MASK_RVE;
53+
5154
*flags |= MASK_MUL;
5255
*flags |= MASK_ATOMIC;
5356
*flags |= MASK_HARD_FLOAT;
@@ -57,6 +60,8 @@ riscv_parse_arch_string (const char *isa, int *flags, location_t loc)
5760
{
5861
p++;
5962

63+
*flags &= ~MASK_RVE;
64+
6065
*flags &= ~MASK_MUL;
6166
if (*p == 'm')
6267
*flags |= MASK_MUL, p++;
@@ -77,6 +82,28 @@ riscv_parse_arch_string (const char *isa, int *flags, location_t loc)
7782
}
7883
}
7984
}
85+
else if (*p == 'e')
86+
{
87+
p++;
88+
89+
*flags |= MASK_RVE;
90+
91+
if (*flags & MASK_64BIT)
92+
{
93+
error ("RV64E is not a valid base ISA");
94+
return;
95+
}
96+
97+
*flags &= ~MASK_MUL;
98+
if (*p == 'm')
99+
*flags |= MASK_MUL, p++;
100+
101+
*flags &= ~MASK_ATOMIC;
102+
if (*p == 'a')
103+
*flags |= MASK_ATOMIC, p++;
104+
105+
*flags &= ~(MASK_HARD_FLOAT | MASK_DOUBLE_FLOAT);
106+
}
80107
else
81108
{
82109
error_at (loc, "-march=%s: invalid ISA string", isa);

gcc/config.gcc

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4077,19 +4077,20 @@ case "${target}" in
40774077

40784078
# Infer arch from --with-arch, --target, and --with-abi.
40794079
case "${with_arch}" in
4080-
rv32i* | rv32g* | rv64i* | rv64g*)
4080+
rv32e* | rv32i* | rv32g* | rv64i* | rv64g*)
40814081
# OK.
40824082
;;
40834083
"")
40844084
# Infer XLEN, but otherwise assume GC.
40854085
case "${with_abi}" in
4086+
ilp32e) with_arch="rv32e" ;;
40864087
ilp32 | ilp32f | ilp32d) with_arch="rv32gc" ;;
40874088
lp64 | lp64f | lp64d) with_arch="rv64gc" ;;
40884089
*) with_arch="rv${xlen}gc" ;;
40894090
esac
40904091
;;
40914092
*)
4092-
echo "--with-arch=${with_arch} is not supported. The argument must begin with rv32i, rv32g, rv64i, or rv64g." 1>&2
4093+
echo "--with-arch=${with_arch} is not supported. The argument must begin with rv32e, rv32i, rv32g, rv64i, or rv64g." 1>&2
40934094
exit 1
40944095
;;
40954096
esac
@@ -4098,11 +4099,12 @@ case "${target}" in
40984099
# pick a default based on the ISA, preferring soft-float
40994100
# unless the D extension is present.
41004101
case "${with_abi}" in
4101-
ilp32 | ilp32f | ilp32d | lp64 | lp64f | lp64d)
4102+
ilp32 | ilp32e | ilp32f | ilp32d | lp64 | lp64f | lp64d)
41024103
;;
41034104
"")
41044105
case "${with_arch}" in
41054106
rv32*d* | rv32g*) with_abi=ilp32d ;;
4107+
rv32e*) with_abi=ilp32e ;;
41064108
rv32*) with_abi=ilp32 ;;
41074109
rv64*d* | rv64g*) with_abi=lp64d ;;
41084110
rv64*) with_abi=lp64 ;;
@@ -4116,7 +4118,7 @@ case "${target}" in
41164118

41174119
# Make sure ABI and ISA are compatible.
41184120
case "${with_abi},${with_arch}" in
4119-
ilp32,rv32* \
4121+
ilp32,rv32* | ilp32e,rv32e* \
41204122
| ilp32f,rv32*f* | ilp32f,rv32g* \
41214123
| ilp32d,rv32*d* | ilp32d,rv32g* \
41224124
| lp64,rv64* \

gcc/config/riscv/riscv-c.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ riscv_cpu_cpp_builtins (cpp_reader *pfile)
3939
if (TARGET_RVC)
4040
builtin_define ("__riscv_compressed");
4141

42+
if (TARGET_RVE)
43+
builtin_define ("__riscv_32e");
44+
4245
if (TARGET_ATOMIC)
4346
builtin_define ("__riscv_atomic");
4447

@@ -62,6 +65,7 @@ riscv_cpu_cpp_builtins (cpp_reader *pfile)
6265
switch (riscv_abi)
6366
{
6467
case ABI_ILP32:
68+
case ABI_ILP32E:
6569
case ABI_LP64:
6670
builtin_define ("__riscv_float_abi_soft");
6771
break;

gcc/config/riscv/riscv-opts.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see
2323

2424
enum riscv_abi_type {
2525
ABI_ILP32,
26+
ABI_ILP32E,
2627
ABI_ILP32F,
2728
ABI_ILP32D,
2829
ABI_LP64,

gcc/config/riscv/riscv.c

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3334,7 +3334,14 @@ riscv_compute_frame_info (void)
33343334

33353335
/* Only use save/restore routines if they don't alter the stack size. */
33363336
if (RISCV_STACK_ALIGN (num_save_restore * UNITS_PER_WORD) == x_save_size)
3337-
frame->save_libcall_adjustment = x_save_size;
3337+
{
3338+
/* Libcall saves/restores 3 registers at once, so we need to
3339+
allocate 12 bytes for callee-saved register. */
3340+
if (TARGET_RVE)
3341+
x_save_size = 3 * UNITS_PER_WORD;
3342+
3343+
frame->save_libcall_adjustment = x_save_size;
3344+
}
33383345

33393346
offset += x_save_size;
33403347
}
@@ -4147,6 +4154,9 @@ riscv_option_override (void)
41474154
error ("requested ABI requires -march to subsume the %qc extension",
41484155
UNITS_PER_FP_ARG > 8 ? 'Q' : (UNITS_PER_FP_ARG > 4 ? 'D' : 'F'));
41494156

4157+
if (TARGET_RVE && riscv_abi != ABI_ILP32E)
4158+
error ("rv32e requires ilp32e ABI");
4159+
41504160
/* We do not yet support ILP32 on RV64. */
41514161
if (BITS_PER_WORD != POINTER_SIZE)
41524162
error ("ABI requires -march=rv%d", POINTER_SIZE);
@@ -4171,6 +4181,19 @@ riscv_option_override (void)
41714181
static void
41724182
riscv_conditional_register_usage (void)
41734183
{
4184+
/* We have only x0~x15 on RV32E. */
4185+
if (TARGET_RVE)
4186+
{
4187+
for (int r = 16; r <= 31; r++)
4188+
fixed_regs[r] = 1;
4189+
}
4190+
4191+
if (riscv_abi == ABI_ILP32E)
4192+
{
4193+
for (int r = 16; r <= 31; r++)
4194+
call_used_regs[r] = 1;
4195+
}
4196+
41744197
if (!TARGET_HARD_FLOAT)
41754198
{
41764199
for (int regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)

gcc/config/riscv/riscv.h

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,11 @@ along with GCC; see the file COPYING3. If not see
102102
#define UNITS_PER_FP_REG (TARGET_DOUBLE_FLOAT ? 8 : 4)
103103

104104
/* The largest type that can be passed in floating-point registers. */
105-
#define UNITS_PER_FP_ARG \
106-
(riscv_abi == ABI_ILP32 || riscv_abi == ABI_LP64 ? 0 : \
107-
riscv_abi == ABI_ILP32F || riscv_abi == ABI_LP64F ? 4 : 8) \
105+
#define UNITS_PER_FP_ARG \
106+
((riscv_abi == ABI_ILP32 || riscv_abi == ABI_ILP32E \
107+
|| riscv_abi == ABI_LP64) \
108+
? 0 \
109+
: ((riscv_abi == ABI_ILP32F || riscv_abi == ABI_LP64F) ? 4 : 8))
108110

109111
/* Set the sizes of the core types. */
110112
#define SHORT_TYPE_SIZE 16
@@ -124,10 +126,10 @@ along with GCC; see the file COPYING3. If not see
124126
#define FUNCTION_BOUNDARY (TARGET_RVC ? 16 : 32)
125127

126128
/* The smallest supported stack boundary the calling convention supports. */
127-
#define STACK_BOUNDARY (2 * BITS_PER_WORD)
129+
#define STACK_BOUNDARY (TARGET_RVE ? BITS_PER_WORD : 2 * BITS_PER_WORD)
128130

129131
/* The ABI stack alignment. */
130-
#define ABI_STACK_BOUNDARY 128
132+
#define ABI_STACK_BOUNDARY (TARGET_RVE ? BITS_PER_WORD : 128)
131133

132134
/* There is no point aligning anything to a rounder boundary than this. */
133135
#define BIGGEST_ALIGNMENT 128
@@ -260,7 +262,7 @@ along with GCC; see the file COPYING3. If not see
260262
/* Internal macros to classify an ISA register's type. */
261263

262264
#define GP_REG_FIRST 0
263-
#define GP_REG_LAST 31
265+
#define GP_REG_LAST (TARGET_RVE ? 15 : 31)
264266
#define GP_REG_NUM (GP_REG_LAST - GP_REG_FIRST + 1)
265267

266268
#define FP_REG_FIRST 32
@@ -490,7 +492,7 @@ enum reg_class
490492
#define GP_RETURN GP_ARG_FIRST
491493
#define FP_RETURN (UNITS_PER_FP_ARG == 0 ? GP_RETURN : FP_ARG_FIRST)
492494

493-
#define MAX_ARGS_IN_REGISTERS 8
495+
#define MAX_ARGS_IN_REGISTERS (TARGET_RVE ? 6 : 8)
494496

495497
/* Symbolic macros for the first/last argument registers. */
496498

@@ -870,6 +872,7 @@ extern unsigned riscv_stack_boundary;
870872

871873
#define ABI_SPEC \
872874
"%{mabi=ilp32:ilp32}" \
875+
"%{mabi=ilp32e:ilp32e}" \
873876
"%{mabi=ilp32f:ilp32f}" \
874877
"%{mabi=ilp32d:ilp32d}" \
875878
"%{mabi=lp64:lp64}" \

gcc/config/riscv/riscv.opt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ Supported ABIs (for use with the -mabi= option):
4444
EnumValue
4545
Enum(abi_type) String(ilp32) Value(ABI_ILP32)
4646

47+
EnumValue
48+
Enum(abi_type) String(ilp32e) Value(ABI_ILP32E)
49+
4750
EnumValue
4851
Enum(abi_type) String(ilp32f) Value(ABI_ILP32F)
4952

@@ -122,3 +125,5 @@ Mask(HARD_FLOAT)
122125
Mask(DOUBLE_FLOAT)
123126

124127
Mask(RVC)
128+
129+
Mask(RVE)

gcc/doc/invoke.texi

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23025,7 +23025,9 @@ conventions are: @samp{ilp32}, @samp{ilp32f}, @samp{ilp32d}, @samp{lp64},
2302523025
@samp{lp64f}, and @samp{lp64d}. Some calling conventions are impossible to
2302623026
implement on some ISAs: for example, @samp{-march=rv32if -mabi=ilp32d} is
2302723027
invalid because the ABI requires 64-bit values be passed in F registers, but F
23028-
registers are only 32 bits wide.
23028+
registers are only 32 bits wide. There is also the @samp{ilp32e} ABI that can
23029+
only be used with the @samp{rv32e} architecture. This ABI is not well
23030+
specified at present, and is subject to change.
2302923031

2303023032
@item -mfdiv
2303123033
@itemx -mno-fdiv
@@ -23044,7 +23046,8 @@ these instructions.
2304423046
@item -march=@var{ISA-string}
2304523047
@opindex march
2304623048
Generate code for given RISC-V ISA (e.g.@ @samp{rv64im}). ISA strings must be
23047-
lower-case. Examples include @samp{rv64i}, @samp{rv32g}, and @samp{rv32imaf}.
23049+
lower-case. Examples include @samp{rv64i}, @samp{rv32g}, @samp{rv32e}, and
23050+
@samp{rv32imaf}.
2304823051

2304923052
@item -mtune=@var{processor-string}
2305023053
@opindex mtune

gcc/testsuite/ChangeLog

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
2018-05-18 Kito Cheng <[email protected]>
2+
3+
* gcc.dg/stack-usage-1.c: Add support for rv32e.
4+
15
2018-05-18 Marc Glisse <[email protected]>
26

37
PR c++/82899

gcc/testsuite/gcc.dg/stack-usage-1.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,11 @@
6464
# define SIZE 240
6565
# endif
6666
#elif defined (__riscv)
67-
# define SIZE 240
67+
# if defined (__riscv_32e)
68+
# define SIZE 252
69+
# else
70+
# define SIZE 240
71+
# endif
6872
#elif defined (__AVR__)
6973
#if defined (__AVR_3_BYTE_PC__ )
7074
# define SIZE 251 /* 256 - 2 bytes for Y - 3 bytes for return address */

libgcc/ChangeLog

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
2018-05-18 Kito Cheng <[email protected]>
2+
Monk Chiang <[email protected]>
3+
Jim Wilson <[email protected]>
4+
5+
* config/riscv/save-restore.S: Add support for rv32e.
6+
17
2018-05-18 Kyrylo Tkachov <[email protected]>
28

39
* config/arm/libunwind.S: Update comment relating to armv5.

libgcc/config/riscv/save-restore.S

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,48 @@ FUNC_END (__riscv_restore_0)
294294

295295
#else
296296

297+
#ifdef __riscv_32e
298+
FUNC_BEGIN(__riscv_save_2)
299+
FUNC_BEGIN(__riscv_save_1)
300+
FUNC_BEGIN(__riscv_save_0)
301+
.cfi_startproc
302+
# __riscv_save_* routine use t0/x5 as return address
303+
.cfi_return_column 5
304+
addi sp, sp, -12
305+
.cfi_def_cfa_offset 12
306+
sw s1, 0(sp)
307+
.cfi_offset 9, -12
308+
sw s0, 4(sp)
309+
.cfi_offset 8, -8
310+
sw ra, 8(sp)
311+
.cfi_offset 1, 0
312+
jr t0
313+
.cfi_endproc
314+
FUNC_END(__riscv_save_2)
315+
FUNC_END(__riscv_save_1)
316+
FUNC_END(__riscv_save_0)
317+
318+
FUNC_BEGIN(__riscv_restore_2)
319+
FUNC_BEGIN(__riscv_restore_1)
320+
FUNC_BEGIN(__riscv_restore_0)
321+
.cfi_startproc
322+
.cfi_def_cfa_offset 14
323+
lw s1, 0(sp)
324+
.cfi_restore 9
325+
lw s0, 4(sp)
326+
.cfi_restore 8
327+
lw ra, 8(sp)
328+
.cfi_restore 1
329+
addi sp, sp, 12
330+
.cfi_def_cfa_offset 0
331+
ret
332+
.cfi_endproc
333+
FUNC_END(__riscv_restore_2)
334+
FUNC_END(__riscv_restore_1)
335+
FUNC_END(__riscv_restore_0)
336+
337+
#else
338+
297339
FUNC_BEGIN (__riscv_save_12)
298340
.cfi_startproc
299341
# __riscv_save_* routine use t0/x5 as return address
@@ -486,4 +528,6 @@ FUNC_END (__riscv_restore_2)
486528
FUNC_END (__riscv_restore_1)
487529
FUNC_END (__riscv_restore_0)
488530

489-
#endif
531+
#endif /* __riscv_32e */
532+
533+
#endif /* __riscv_xlen == 64 */

0 commit comments

Comments
 (0)