+2018-05-18 Kito Cheng <kito.cheng@gmail.com>
+ Monk Chiang <sh.chiang04@gmail.com>
+ Jim Wilson <jimw@sifive.com>
+
+ * 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.
+
2018-05-18 Marc Glisse <marc.glisse@inria.fr>
PR c++/82899
#include "flags.h"
#include "diagnostic-core.h"
-/* Parse a RISC-V ISA string into an option mask. */
+/* Parse a RISC-V ISA string into an option mask. Must clear or set all arch
+ dependent mask bits, in case more than one -march string is passed. */
static void
riscv_parse_arch_string (const char *isa, int *flags, location_t loc)
{
p++;
+ *flags &= ~MASK_RVE;
+
*flags |= MASK_MUL;
*flags |= MASK_ATOMIC;
*flags |= MASK_HARD_FLOAT;
{
p++;
+ *flags &= ~MASK_RVE;
+
*flags &= ~MASK_MUL;
if (*p == 'm')
*flags |= MASK_MUL, p++;
}
}
}
+ else if (*p == 'e')
+ {
+ p++;
+
+ *flags |= MASK_RVE;
+
+ if (*flags & MASK_64BIT)
+ {
+ error ("RV64E is not a valid base ISA");
+ return;
+ }
+
+ *flags &= ~MASK_MUL;
+ if (*p == 'm')
+ *flags |= MASK_MUL, p++;
+
+ *flags &= ~MASK_ATOMIC;
+ if (*p == 'a')
+ *flags |= MASK_ATOMIC, p++;
+
+ *flags &= ~(MASK_HARD_FLOAT | MASK_DOUBLE_FLOAT);
+ }
else
{
error_at (loc, "-march=%s: invalid ISA string", isa);
# Infer arch from --with-arch, --target, and --with-abi.
case "${with_arch}" in
- rv32i* | rv32g* | rv64i* | rv64g*)
+ rv32e* | rv32i* | rv32g* | rv64i* | rv64g*)
# OK.
;;
"")
# Infer XLEN, but otherwise assume GC.
case "${with_abi}" in
+ ilp32e) with_arch="rv32e" ;;
ilp32 | ilp32f | ilp32d) with_arch="rv32gc" ;;
lp64 | lp64f | lp64d) with_arch="rv64gc" ;;
*) with_arch="rv${xlen}gc" ;;
esac
;;
*)
- echo "--with-arch=${with_arch} is not supported. The argument must begin with rv32i, rv32g, rv64i, or rv64g." 1>&2
+ echo "--with-arch=${with_arch} is not supported. The argument must begin with rv32e, rv32i, rv32g, rv64i, or rv64g." 1>&2
exit 1
;;
esac
# pick a default based on the ISA, preferring soft-float
# unless the D extension is present.
case "${with_abi}" in
- ilp32 | ilp32f | ilp32d | lp64 | lp64f | lp64d)
+ ilp32 | ilp32e | ilp32f | ilp32d | lp64 | 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 ;;
rv64*) with_abi=lp64 ;;
# Make sure ABI and ISA are compatible.
case "${with_abi},${with_arch}" in
- ilp32,rv32* \
+ ilp32,rv32* | ilp32e,rv32e* \
| ilp32f,rv32*f* | ilp32f,rv32g* \
| ilp32d,rv32*d* | ilp32d,rv32g* \
| lp64,rv64* \
if (TARGET_RVC)
builtin_define ("__riscv_compressed");
+ if (TARGET_RVE)
+ builtin_define ("__riscv_32e");
+
if (TARGET_ATOMIC)
builtin_define ("__riscv_atomic");
switch (riscv_abi)
{
case ABI_ILP32:
+ case ABI_ILP32E:
case ABI_LP64:
builtin_define ("__riscv_float_abi_soft");
break;
enum riscv_abi_type {
ABI_ILP32,
+ ABI_ILP32E,
ABI_ILP32F,
ABI_ILP32D,
ABI_LP64,
/* Only use save/restore routines if they don't alter the stack size. */
if (RISCV_STACK_ALIGN (num_save_restore * UNITS_PER_WORD) == x_save_size)
- frame->save_libcall_adjustment = x_save_size;
+ {
+ /* Libcall saves/restores 3 registers at once, so we need to
+ allocate 12 bytes for callee-saved register. */
+ if (TARGET_RVE)
+ x_save_size = 3 * UNITS_PER_WORD;
+
+ frame->save_libcall_adjustment = x_save_size;
+ }
offset += x_save_size;
}
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");
+
/* We do not yet support ILP32 on RV64. */
if (BITS_PER_WORD != POINTER_SIZE)
error ("ABI requires -march=rv%d", POINTER_SIZE);
static void
riscv_conditional_register_usage (void)
{
+ /* We have only x0~x15 on RV32E. */
+ if (TARGET_RVE)
+ {
+ for (int r = 16; r <= 31; r++)
+ fixed_regs[r] = 1;
+ }
+
+ if (riscv_abi == ABI_ILP32E)
+ {
+ for (int r = 16; r <= 31; r++)
+ call_used_regs[r] = 1;
+ }
+
if (!TARGET_HARD_FLOAT)
{
for (int regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
#define UNITS_PER_FP_REG (TARGET_DOUBLE_FLOAT ? 8 : 4)
/* The largest type that can be passed in floating-point registers. */
-#define UNITS_PER_FP_ARG \
- (riscv_abi == ABI_ILP32 || riscv_abi == ABI_LP64 ? 0 : \
- riscv_abi == ABI_ILP32F || riscv_abi == ABI_LP64F ? 4 : 8) \
+#define UNITS_PER_FP_ARG \
+ ((riscv_abi == ABI_ILP32 || riscv_abi == ABI_ILP32E \
+ || riscv_abi == ABI_LP64) \
+ ? 0 \
+ : ((riscv_abi == ABI_ILP32F || riscv_abi == ABI_LP64F) ? 4 : 8))
/* Set the sizes of the core types. */
#define SHORT_TYPE_SIZE 16
#define FUNCTION_BOUNDARY (TARGET_RVC ? 16 : 32)
/* The smallest supported stack boundary the calling convention supports. */
-#define STACK_BOUNDARY (2 * BITS_PER_WORD)
+#define STACK_BOUNDARY (TARGET_RVE ? BITS_PER_WORD : 2 * BITS_PER_WORD)
/* The ABI stack alignment. */
-#define ABI_STACK_BOUNDARY 128
+#define ABI_STACK_BOUNDARY (TARGET_RVE ? BITS_PER_WORD : 128)
/* There is no point aligning anything to a rounder boundary than this. */
#define BIGGEST_ALIGNMENT 128
/* Internal macros to classify an ISA register's type. */
#define GP_REG_FIRST 0
-#define GP_REG_LAST 31
+#define GP_REG_LAST (TARGET_RVE ? 15 : 31)
#define GP_REG_NUM (GP_REG_LAST - GP_REG_FIRST + 1)
#define FP_REG_FIRST 32
#define GP_RETURN GP_ARG_FIRST
#define FP_RETURN (UNITS_PER_FP_ARG == 0 ? GP_RETURN : FP_ARG_FIRST)
-#define MAX_ARGS_IN_REGISTERS 8
+#define MAX_ARGS_IN_REGISTERS (TARGET_RVE ? 6 : 8)
/* Symbolic macros for the first/last argument registers. */
#define ABI_SPEC \
"%{mabi=ilp32:ilp32}" \
+ "%{mabi=ilp32e:ilp32e}" \
"%{mabi=ilp32f:ilp32f}" \
"%{mabi=ilp32d:ilp32d}" \
"%{mabi=lp64:lp64}" \
EnumValue
Enum(abi_type) String(ilp32) Value(ABI_ILP32)
+EnumValue
+Enum(abi_type) String(ilp32e) Value(ABI_ILP32E)
+
EnumValue
Enum(abi_type) String(ilp32f) Value(ABI_ILP32F)
Mask(DOUBLE_FLOAT)
Mask(RVC)
+
+Mask(RVE)
@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.
+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.
@item -mfdiv
@itemx -mno-fdiv
@item -march=@var{ISA-string}
@opindex march
Generate code for given RISC-V ISA (e.g.@ @samp{rv64im}). ISA strings must be
-lower-case. Examples include @samp{rv64i}, @samp{rv32g}, and @samp{rv32imaf}.
+lower-case. Examples include @samp{rv64i}, @samp{rv32g}, @samp{rv32e}, and
+@samp{rv32imaf}.
@item -mtune=@var{processor-string}
@opindex mtune
+2018-05-18 Kito Cheng <kito.cheng@gmail.com>
+
+ * gcc.dg/stack-usage-1.c: Add support for rv32e.
+
2018-05-18 Marc Glisse <marc.glisse@inria.fr>
PR c++/82899
# define SIZE 240
# endif
#elif defined (__riscv)
-# define SIZE 240
+# if defined (__riscv_32e)
+# define SIZE 252
+# else
+# define SIZE 240
+# endif
#elif defined (__AVR__)
#if defined (__AVR_3_BYTE_PC__ )
# define SIZE 251 /* 256 - 2 bytes for Y - 3 bytes for return address */
+2018-05-18 Kito Cheng <kito.cheng@gmail.com>
+ Monk Chiang <sh.chiang04@gmail.com>
+ Jim Wilson <jimw@sifive.com>
+
+ * config/riscv/save-restore.S: Add support for rv32e.
+
2018-05-18 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* config/arm/libunwind.S: Update comment relating to armv5.
#else
+#ifdef __riscv_32e
+FUNC_BEGIN(__riscv_save_2)
+FUNC_BEGIN(__riscv_save_1)
+FUNC_BEGIN(__riscv_save_0)
+ .cfi_startproc
+ # __riscv_save_* routine use t0/x5 as return address
+ .cfi_return_column 5
+ addi sp, sp, -12
+ .cfi_def_cfa_offset 12
+ sw s1, 0(sp)
+ .cfi_offset 9, -12
+ sw s0, 4(sp)
+ .cfi_offset 8, -8
+ sw ra, 8(sp)
+ .cfi_offset 1, 0
+ jr t0
+ .cfi_endproc
+FUNC_END(__riscv_save_2)
+FUNC_END(__riscv_save_1)
+FUNC_END(__riscv_save_0)
+
+FUNC_BEGIN(__riscv_restore_2)
+FUNC_BEGIN(__riscv_restore_1)
+FUNC_BEGIN(__riscv_restore_0)
+ .cfi_startproc
+ .cfi_def_cfa_offset 14
+ lw s1, 0(sp)
+ .cfi_restore 9
+ lw s0, 4(sp)
+ .cfi_restore 8
+ lw ra, 8(sp)
+ .cfi_restore 1
+ addi sp, sp, 12
+ .cfi_def_cfa_offset 0
+ ret
+ .cfi_endproc
+FUNC_END(__riscv_restore_2)
+FUNC_END(__riscv_restore_1)
+FUNC_END(__riscv_restore_0)
+
+#else
+
FUNC_BEGIN (__riscv_save_12)
.cfi_startproc
# __riscv_save_* routine use t0/x5 as return address
FUNC_END (__riscv_restore_1)
FUNC_END (__riscv_restore_0)
-#endif
+#endif /* __riscv_32e */
+
+#endif /* __riscv_xlen == 64 */