RISC-V: Add RV32E support.
authorKito Cheng <kito.cheng@gmail.com>
Fri, 18 May 2018 22:53:55 +0000 (22:53 +0000)
committerJim Wilson <wilson@gcc.gnu.org>
Fri, 18 May 2018 22:53:55 +0000 (15:53 -0700)
Kito Cheng <kito.cheng@gmail.com>
Monk Chiang  <sh.chiang04@gmail.com>

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 <jimw@sifive.com>
Co-Authored-By: Monk Chiang <sh.chiang04@gmail.com>
From-SVN: r260384

13 files changed:
gcc/ChangeLog
gcc/common/config/riscv/riscv-common.c
gcc/config.gcc
gcc/config/riscv/riscv-c.c
gcc/config/riscv/riscv-opts.h
gcc/config/riscv/riscv.c
gcc/config/riscv/riscv.h
gcc/config/riscv/riscv.opt
gcc/doc/invoke.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/stack-usage-1.c
libgcc/ChangeLog
libgcc/config/riscv/save-restore.S

index 581f05076bc4003959e0b7b0d5959e7305c95ce0..145c3aa468ae45fbcd54dcebd04046e917463034 100644 (file)
@@ -1,3 +1,26 @@
+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
index 9db83015aedea26bc94bc83963280c7e82e0e4dc..8a78aebc320349aef5331b9d89bbea175430de52 100644 (file)
@@ -27,7 +27,8 @@ along with GCC; see the file COPYING3.  If not see
 #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)
@@ -48,6 +49,8 @@ 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;
@@ -57,6 +60,8 @@ riscv_parse_arch_string (const char *isa, int *flags, location_t loc)
     {
       p++;
 
+      *flags &= ~MASK_RVE;
+
       *flags &= ~MASK_MUL;
       if (*p == 'm')
        *flags |= MASK_MUL, p++;
@@ -77,6 +82,28 @@ riscv_parse_arch_string (const char *isa, int *flags, location_t loc)
            }
        }
     }
+  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);
index 8edd0cdbaed18d52bb1b82e995291edba74be362..96ae6a88a0db4c55341c094b73e2b23574d647a2 100644 (file)
@@ -4077,19 +4077,20 @@ case "${target}" in
 
                # 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
@@ -4098,11 +4099,12 @@ case "${target}" in
                # 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 ;;
@@ -4116,7 +4118,7 @@ case "${target}" in
 
                # 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* \
index 391b5eefc5cd208826560b76a37f267604b4bf4a..513f974d9aa2465062ed2f8cf8965bbaecd41bc0 100644 (file)
@@ -39,6 +39,9 @@ riscv_cpu_cpp_builtins (cpp_reader *pfile)
   if (TARGET_RVC)
     builtin_define ("__riscv_compressed");
   
+  if (TARGET_RVE)
+    builtin_define ("__riscv_32e");
+
   if (TARGET_ATOMIC)
     builtin_define ("__riscv_atomic");
   
@@ -62,6 +65,7 @@ riscv_cpu_cpp_builtins (cpp_reader *pfile)
   switch (riscv_abi)
     {
     case ABI_ILP32:
+    case ABI_ILP32E:
     case ABI_LP64:
       builtin_define ("__riscv_float_abi_soft");
       break;
index 3e10ab339a5421be276504efbb066a463899774f..b7ed72ebb75ee93c7699ef0ecd3019c383e93f84 100644 (file)
@@ -23,6 +23,7 @@ along with GCC; see the file COPYING3.  If not see
 
 enum riscv_abi_type {
   ABI_ILP32,
+  ABI_ILP32E,
   ABI_ILP32F,
   ABI_ILP32D,
   ABI_LP64,
index b4975888bbbe0a33ac7b6ade5808fa3c039d990a..9a9d9e1befe8f927716df8202a152323779a851d 100644 (file)
@@ -3334,7 +3334,14 @@ riscv_compute_frame_info (void)
 
       /* 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;
     }
@@ -4147,6 +4154,9 @@ 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");
+
   /* We do not yet support ILP32 on RV64.  */
   if (BITS_PER_WORD != POINTER_SIZE)
     error ("ABI requires -march=rv%d", POINTER_SIZE);
@@ -4171,6 +4181,19 @@ riscv_option_override (void)
 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++)
index 62279ff2cdef9dc32863a3fd311cae7c78dbd79f..a9111a483ab8c0c0ed28d151a9a73ff5dee0615d 100644 (file)
@@ -102,9 +102,11 @@ along with GCC; see the file COPYING3.  If not see
 #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
@@ -124,10 +126,10 @@ along with GCC; see the file COPYING3.  If not see
 #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
@@ -260,7 +262,7 @@ along with GCC; see the file COPYING3.  If not see
 /* 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
@@ -490,7 +492,7 @@ 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 8
+#define MAX_ARGS_IN_REGISTERS (TARGET_RVE ? 6 : 8)
 
 /* Symbolic macros for the first/last argument registers.  */
 
@@ -870,6 +872,7 @@ extern unsigned riscv_stack_boundary;
 
 #define ABI_SPEC \
   "%{mabi=ilp32:ilp32}" \
+  "%{mabi=ilp32e:ilp32e}" \
   "%{mabi=ilp32f:ilp32f}" \
   "%{mabi=ilp32d:ilp32d}" \
   "%{mabi=lp64:lp64}" \
index b37ac75d9bb4179cd8986ac99516d6c90f38127d..13693221d261d418b2cd9b905aaa1dcd28b79e93 100644 (file)
@@ -44,6 +44,9 @@ Supported ABIs (for use with the -mabi= option):
 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)
 
@@ -122,3 +125,5 @@ Mask(HARD_FLOAT)
 Mask(DOUBLE_FLOAT)
 
 Mask(RVC)
+
+Mask(RVE)
index 44b043384d924b51c98f16d46b52fd0393eab803..beba295bef505ae98e7d2d6bc59bb7ffc659c878 100644 (file)
@@ -23025,7 +23025,9 @@ 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.
+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
@@ -23044,7 +23046,8 @@ these instructions.
 @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
index 76e016990078946a7cd34c60d4851ee82d732afd..e757d806501be702183548f305391603fd8915b7 100644 (file)
@@ -1,3 +1,7 @@
+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
index 45d2c7b6aae0f5b691ae868ea32f178ad49fe7c8..038bd4ec05cc6a4c074c392bf57ff91564180243 100644 (file)
 #    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 */
index f6cf15e83a2032f53c8967ad11ff0f620cfa5949..e8886cfda7735096e4d49feadb4041a84f5541b5 100644 (file)
@@ -1,3 +1,9 @@
+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.
index 9a6d0c9fcfc869817e4b35ba4ff2bd72a3ecc2be..a76c978090227383605878d45927ba154318a051 100644 (file)
@@ -294,6 +294,48 @@ FUNC_END (__riscv_restore_0)
 
 #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
@@ -486,4 +528,6 @@ FUNC_END (__riscv_restore_2)
 FUNC_END (__riscv_restore_1)
 FUNC_END (__riscv_restore_0)
 
-#endif
+#endif /* __riscv_32e */
+
+#endif /* __riscv_xlen == 64 */