From 7f99954970001cfc1b155d877ac2966d77e2c647 Mon Sep 17 00:00:00 2001 From: Jim Wilson Date: Fri, 18 May 2018 14:03:18 -0700 Subject: [PATCH] RISC-V: Add RV32E support. Kito Cheng Monk Chiang 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 | 5 ++++ bfd/elfnn-riscv.c | 8 ++++++ binutils/ChangeLog | 4 +++ binutils/readelf.c | 3 ++ gas/ChangeLog | 15 ++++++++++ gas/config/tc-riscv.c | 66 ++++++++++++++++++++++++++++++++++++------- gas/doc/c-riscv.texi | 3 +- include/ChangeLog | 4 +++ include/elf/riscv.h | 3 ++ 9 files changed, 100 insertions(+), 11 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index b24aba1afc8..cc8773cb144 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,8 @@ +2018-05-18 Kito Cheng + + * elfnn-riscv.c (_bfd_riscv_elf_merge_private_bfd_data): Handle + EF_RISCV_RVE. + 2018-05-18 Jim Wilson * elfnn-riscv.c (allocate_dynrelocs): Discard dynamic relocations if diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c index b17c0e10007..b82e655b7be 100644 --- a/bfd/elfnn-riscv.c +++ b/bfd/elfnn-riscv.c @@ -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; diff --git a/binutils/ChangeLog b/binutils/ChangeLog index fd77f44fbea..2943b1d31b4 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,7 @@ +2018-05-18 Kito Cheng + + * readelf.c (get_machine_flags): Handle EF_RISCV_RVE. + 2018-05-18 John Darrington * readelf.c: Add support for s12z architecture. diff --git a/binutils/readelf.c b/binutils/readelf.c index 6a9319f5dbf..8335538e033 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -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: diff --git a/gas/ChangeLog b/gas/ChangeLog index 39c51b23a06..272fbf8ff36 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,18 @@ +2018-05-18 Kito Cheng + Monk Chiang + Jim Wilson + + * 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 * Makefile.am: Add support for s12z target. diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c index be32e6c979e..43ae21fcb14 100644 --- a/gas/config/tc-riscv.c +++ b/gas/config/tc-riscv.c @@ -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)); } diff --git a/gas/doc/c-riscv.texi b/gas/doc/c-riscv.texi index 79bc4e37b6d..045c33a3aa7 100644 --- a/gas/doc/c-riscv.texi +++ b/gas/doc/c-riscv.texi @@ -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 diff --git a/include/ChangeLog b/include/ChangeLog index 649b65ce2d6..71d2eb6bb58 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,7 @@ +2018-05-18 Kito Cheng + + * elf/riscv.h (EF_RISCV_RVE): New define. + 2018-05-18 John Darrington * elf/s12z.h: New header. diff --git a/include/elf/riscv.h b/include/elf/riscv.h index defbbf4c246..d036e830700 100644 --- a/include/elf/riscv.h +++ b/include/elf/riscv.h @@ -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$" -- 2.39.2