RISC-V: Add RV32E support.
authorJim Wilson <jimw@sifive.com>
Fri, 18 May 2018 21:03:18 +0000 (14:03 -0700)
committerJim Wilson <jimw@sifive.com>
Fri, 18 May 2018 21:03:18 +0000 (14:03 -0700)
Kito Cheng  <kito.cheng@gmail.com>
Monk Chiang  <sh.chiang04@gmail.com>

bfd/
* elfnn-riscv.c (_bfd_riscv_elf_merge_private_bfd_data): Handle
EF_RISCV_RVE.

binutils/
* readelf.c (get_machine_flags): Handle EF_RISCV_RVE.

gas/
* config/tc-riscv.c (rve_abi): New.
(riscv_set_options): Add rve field.  Initialize it.
(riscv_set_rve) New function.
(riscv_set_arch): Support 'e' ISA subset.
(reg_lookup_internal): If rve, check register is available.
(riscv_set_abi): New parameter rve.
(md_parse_option): Pass new argument to riscv_set_abi.
(riscv_after_parse_args): Call riscv_set_rve.  If rve_abi, set
EF_RISCV_RVE.
* doc/c-riscv.texi (-mabi): Document new ilp32e argument.

include/
* elf/riscv.h (EF_RISCV_RVE): New define.

bfd/ChangeLog
bfd/elfnn-riscv.c
binutils/ChangeLog
binutils/readelf.c
gas/ChangeLog
gas/config/tc-riscv.c
gas/doc/c-riscv.texi
include/ChangeLog
include/elf/riscv.h

index b24aba1afc8e646edbf32fb6c5b4b04e1c1e47be..cc8773cb144597218fa6a6af7ccccb6056de8c30 100644 (file)
@@ -1,3 +1,8 @@
+2018-05-18  Kito Cheng  <kito.cheng@gmail.com>
+
+       * elfnn-riscv.c (_bfd_riscv_elf_merge_private_bfd_data): Handle
+       EF_RISCV_RVE.
+
 2018-05-18  Jim Wilson  <jimw@sifive.com>
 
        * elfnn-riscv.c (allocate_dynrelocs): Discard dynamic relocations if
index b17c0e10007d4bcd1d3314db46523834e4c431be..b82e655b7be5f0363be32a1ba7a995febdeda168 100644 (file)
@@ -2625,6 +2625,14 @@ _bfd_riscv_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
       goto fail;
     }
 
+  /* Disallow linking RVE and non-RVE.  */
+  if ((old_flags ^ new_flags) & EF_RISCV_RVE)
+    {
+      (*_bfd_error_handler)
+       (_("%pB: can't link RVE with other target"), ibfd);
+      goto fail;
+    }
+
   /* Allow linking RVC and non-RVC, and keep the RVC flag.  */
   elf_elfheader (obfd)->e_flags |= new_flags & EF_RISCV_RVC;
 
index fd77f44fbea091849685ebdc2a7b555526607f83..2943b1d31b4d343ffe5a0d5e79ffd93f08d8b9c0 100644 (file)
@@ -1,3 +1,7 @@
+2018-05-18  Kito Cheng  <kito.cheng@gmail.com>
+
+       * readelf.c (get_machine_flags): Handle EF_RISCV_RVE.
+
 2018-05-18  John Darrington  <john@darrington.wattle.id.au>
 
        * readelf.c: Add support for s12z architecture.
index 6a9319f5dbfb545be3bd49a4f1b1c8dc517a018a..8335538e0334572d164e4fd50f292ea25ac42bbb 100644 (file)
@@ -3472,6 +3472,9 @@ get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
          if (e_flags & EF_RISCV_RVC)
            strcat (buf, ", RVC");
 
+         if (e_flags & EF_RISCV_RVE)
+           strcat (buf, ", RVE");
+
          switch (e_flags & EF_RISCV_FLOAT_ABI)
            {
            case EF_RISCV_FLOAT_ABI_SOFT:
index 39c51b23a0658ad90e6951369e15a9a2935e9f50..272fbf8ff366f4694c05b511f949073179d3f4c9 100644 (file)
@@ -1,3 +1,18 @@
+2018-05-18  Kito Cheng  <kito.cheng@gmail.com>
+           Monk Chiang  <sh.chiang04@gmail.com>
+           Jim Wilson <jimw@sifive.com>
+
+       * config/tc-riscv.c (rve_abi): New.
+       (riscv_set_options): Add rve field.  Initialize it.
+       (riscv_set_rve) New function.
+       (riscv_set_arch): Support 'e' ISA subset.
+       (reg_lookup_internal): If rve, check register is available.
+       (riscv_set_abi): New parameter rve.
+       (md_parse_option): Pass new argument to riscv_set_abi.
+       (riscv_after_parse_args): Call riscv_set_rve.  If rve_abi, set
+       EF_RISCV_RVE.
+       * doc/c-riscv.texi (-mabi): Document new ilp32e argument.
+
 2018-05-18  John Darrington  <john@darrington.wattle.id.au>
 
        * Makefile.am: Add support for s12z target.
index be32e6c979e21d80a4e8ca4e914c3a568549051b..43ae21fcb1428f38e7285297f1fb3ec77321e3a7 100644 (file)
@@ -63,6 +63,7 @@ static const char default_arch[] = DEFAULT_ARCH;
 
 static unsigned xlen = 0; /* width of an x-register */
 static unsigned abi_xlen = 0; /* width of a pointer in the ABI */
+static bfd_boolean rve_abi = FALSE;
 
 #define LOAD_ADDRESS_INSN (abi_xlen == 64 ? "ld" : "lw")
 #define ADD32_INSN (xlen == 64 ? "addiw" : "addi")
@@ -75,6 +76,7 @@ struct riscv_set_options
 {
   int pic; /* Generate position-independent code.  */
   int rvc; /* Generate RVC code.  */
+  int rve; /* Generate RVE code.  */
   int relax; /* Emit relocs the linker is allowed to relax.  */
 };
 
@@ -82,6 +84,7 @@ static struct riscv_set_options riscv_opts =
 {
   0,   /* pic */
   0,   /* rvc */
+  0,   /* rve */
   1,   /* relax */
 };
 
@@ -94,6 +97,12 @@ riscv_set_rvc (bfd_boolean rvc_value)
   riscv_opts.rvc = rvc_value;
 }
 
+static void
+riscv_set_rve (bfd_boolean rve_value)
+{
+  riscv_opts.rve = rve_value;
+}
+
 struct riscv_subset
 {
   const char *name;
@@ -171,6 +180,16 @@ riscv_set_arch (const char *s)
       case 'i':
        break;
 
+      case 'e':
+       p++;
+       riscv_add_subset ("e");
+       riscv_add_subset ("i");
+
+       if (xlen > 32)
+         as_fatal ("-march=%s: rv%de is not a valid base ISA", s, xlen);
+
+       break;
+
       case 'g':
        p++;
        for ( ; *all_subsets != 'q'; all_subsets++)
@@ -181,7 +200,7 @@ riscv_set_arch (const char *s)
        break;
 
       default:
-       as_fatal ("-march=%s: first ISA subset must be `i' or `g'", s);
+       as_fatal ("-march=%s: first ISA subset must be `e', `i' or `g'", s);
     }
 
   while (*p)
@@ -215,6 +234,18 @@ riscv_set_arch (const char *s)
        as_fatal ("-march=%s: unsupported ISA subset `%c'", s, *p);
     }
 
+  if (riscv_subset_supports ("e") && riscv_subset_supports ("f"))
+    as_fatal ("-march=%s: rv32e does not support the `f' extension", s);
+
+  if (riscv_subset_supports ("d") && !riscv_subset_supports ("f"))
+    as_fatal ("-march=%s: `d' extension requires `f' extension", s);
+
+  if (riscv_subset_supports ("q") && !riscv_subset_supports ("d"))
+    as_fatal ("-march=%s: `q' extension requires `d' extension", s);
+
+  if (riscv_subset_supports ("q") && xlen < 64)
+    as_fatal ("-march=%s: rv32 does not support the `q' extension", s);
+
   free (extension);
 }
 
@@ -546,6 +577,10 @@ reg_lookup_internal (const char *s, enum reg_class class)
 
   if (r == NULL || DECODE_REG_CLASS (r) != class)
     return -1;
+
+  if (riscv_opts.rve && class == RCLASS_GPR && DECODE_REG_NUM (r) > 15)
+    return -1;
+
   return DECODE_REG_NUM (r);
 }
 
@@ -2165,10 +2200,11 @@ enum float_abi {
 static enum float_abi float_abi = FLOAT_ABI_DEFAULT;
 
 static void
-riscv_set_abi (unsigned new_xlen, enum float_abi new_float_abi)
+riscv_set_abi (unsigned new_xlen, enum float_abi new_float_abi, bfd_boolean rve)
 {
   abi_xlen = new_xlen;
   float_abi = new_float_abi;
+  rve_abi = rve;
 }
 
 int
@@ -2190,21 +2226,23 @@ md_parse_option (int c, const char *arg)
 
     case OPTION_MABI:
       if (strcmp (arg, "ilp32") == 0)
-       riscv_set_abi (32, FLOAT_ABI_SOFT);
+       riscv_set_abi (32, FLOAT_ABI_SOFT, FALSE);
+      else if (strcmp (arg, "ilp32e") == 0)
+       riscv_set_abi (32, FLOAT_ABI_SOFT, TRUE);
       else if (strcmp (arg, "ilp32f") == 0)
-       riscv_set_abi (32, FLOAT_ABI_SINGLE);
+       riscv_set_abi (32, FLOAT_ABI_SINGLE, FALSE);
       else if (strcmp (arg, "ilp32d") == 0)
-       riscv_set_abi (32, FLOAT_ABI_DOUBLE);
+       riscv_set_abi (32, FLOAT_ABI_DOUBLE, FALSE);
       else if (strcmp (arg, "ilp32q") == 0)
-       riscv_set_abi (32, FLOAT_ABI_QUAD);
+       riscv_set_abi (32, FLOAT_ABI_QUAD, FALSE);
       else if (strcmp (arg, "lp64") == 0)
-       riscv_set_abi (64, FLOAT_ABI_SOFT);
+       riscv_set_abi (64, FLOAT_ABI_SOFT, FALSE);
       else if (strcmp (arg, "lp64f") == 0)
-       riscv_set_abi (64, FLOAT_ABI_SINGLE);
+       riscv_set_abi (64, FLOAT_ABI_SINGLE, FALSE);
       else if (strcmp (arg, "lp64d") == 0)
-       riscv_set_abi (64, FLOAT_ABI_DOUBLE);
+       riscv_set_abi (64, FLOAT_ABI_DOUBLE, FALSE);
       else if (strcmp (arg, "lp64q") == 0)
-       riscv_set_abi (64, FLOAT_ABI_QUAD);
+       riscv_set_abi (64, FLOAT_ABI_QUAD, FALSE);
       else
        return 0;
       break;
@@ -2247,6 +2285,11 @@ riscv_after_parse_args (void)
   else
     riscv_add_subset ("c");
 
+  /* Enable RVE if specified by the -march option.  */
+  riscv_set_rve (FALSE);
+  if (riscv_subset_supports ("e"))
+    riscv_set_rve (TRUE);
+
   /* Infer ABI from ISA if not specified on command line.  */
   if (abi_xlen == 0)
     abi_xlen = xlen;
@@ -2271,6 +2314,9 @@ riscv_after_parse_args (void)
        }
     }
 
+  if (rve_abi)
+    elf_flags |= EF_RISCV_RVE;
+
   /* Insert float_abi into the EF_RISCV_FLOAT_ABI field of elf_flags.  */
   elf_flags |= float_abi * (EF_RISCV_FLOAT_ABI & ~(EF_RISCV_FLOAT_ABI << 1));
 }
index 79bc4e37b6d720e1ef714752b80a93a8984d4efe..045c33a3aa7b1c4fe7821c1e12835a8f9877987b 100644 (file)
@@ -46,7 +46,8 @@ Select the base isa, as specified by ISA.  For example -march=rv32ima.
 Selects the ABI, which is either "ilp32" or "lp64", optionally followed
 by "f", "d", or "q" to indicate single-precision, double-precision, or
 quad-precision floating-point calling convention, or none to indicate
-the soft-float calling convention.
+the soft-float calling convention.  Also, "ilp32" can optionally be followed
+by "e" to indicate the RVE ABI, which is always soft-float.
 
 @cindex @samp{-mrelax} option, RISC-V
 @item -mrelax
index 649b65ce2d61ddb3a3fb3c4e7c56b3318aac03ab..71d2eb6bb58537bfc95449bb639d457efa3dc215 100644 (file)
@@ -1,3 +1,7 @@
+2018-05-18  Kito Cheng  <kito.cheng@gmail.com>
+
+       * elf/riscv.h (EF_RISCV_RVE): New define.
+
 2018-05-18  John Darrington  <john@darrington.wattle.id.au>
 
        * elf/s12z.h: New header.
index defbbf4c246c06843d4294c39072f6428d4c4dbb..d036e830700518b2f885501fef3c021f1049dcac 100644 (file)
@@ -110,6 +110,9 @@ END_RELOC_NUMBERS (R_RISCV_max)
 /* File uses the quad-float ABI.  */
 #define EF_RISCV_FLOAT_ABI_QUAD 0x0006
 
+/* File uses the 32E base integer instruction.  */
+#define EF_RISCV_RVE 0x0008
+
 /* The name of the global pointer symbol.  */
 #define RISCV_GP_SYMBOL "__global_pointer$"