From 7f99954970001cfc1b155d877ac2966d77e2c647 Mon Sep 17 00:00:00 2001 From: Jim Wilson Date: Fri, 18 May 2018 14:03:18 -0700 Subject: 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. --- gas/ChangeLog | 15 ++++++++++++ gas/config/tc-riscv.c | 66 +++++++++++++++++++++++++++++++++++++++++++-------- gas/doc/c-riscv.texi | 3 ++- 3 files changed, 73 insertions(+), 11 deletions(-) (limited to 'gas') diff --git a/gas/ChangeLog b/gas/ChangeLog index 39c51b2..272fbf8 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 be32e6c..43ae21f 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 79bc4e3..045c33a 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 -- cgit v1.1