diff options
author | Nelson Chu <nelson.chu@sifive.com> | 2021-11-17 18:46:11 +0800 |
---|---|---|
committer | Nelson Chu <nelson.chu@sifive.com> | 2021-11-17 20:18:11 +0800 |
commit | 65e4a99a26452d99d586f6e5a0c43e24348a5125 (patch) | |
tree | 92a3eca7a03c023591d661a6869135e3bf1522f1 /bfd/elfxx-riscv.c | |
parent | 486f9e20e037f1eea2dce98dc393db60df5feef3 (diff) |
RISC-V: Support rvv extension with released version 1.0.
2021-11-17 Jim Wilson <jimw@sifive.com>
Kito Cheng <kito.cheng@sifive.com>
Nelson Chu <nelson.chu@sifive.com>
This patch is porting from the following riscv github,
https://github.com/riscv/riscv-binutils-gdb/tree/rvv-1.0.x
And here is the vector spec,
https://github.com/riscv/riscv-v-spec
bfd/
* elfxx-riscv.c (riscv_implicit_subsets): Added imply rules
of v, zve and zvl extensions.
(riscv_supported_std_ext): Updated verison of v to 1.0.
(riscv_supported_std_z_ext): Added zve and zvl extensions.
(riscv_parse_check_conflicts): The zvl extensions need to
enable either v or zve extension.
(riscv_multi_subset_supports): Check the subset list to know
if the INSN_CLASS_V and INSN_CLASS_ZVEF instructions are supported.
gas/
* config/tc-riscv.c (enum riscv_csr_class): Added CSR_CLASS_V.
(enum reg_class): Added RCLASS_VECR and RCLASS_VECM.
(validate_riscv_insn): Check whether the rvv operands are valid.
(md_begin): Initialize register hash for rvv registers.
(macro_build): Added rvv operands when expanding rvv pseudoes.
(vector_macro): Expand rvv macros into one or more instructions.
(macro): Likewise.
(my_getVsetvliExpression): Similar to my_getVsetvliExpression,
but used for parsing vsetvli operands.
(riscv_ip): Parse and encode rvv operands. Besides, The rvv loads
and stores with EEW 64 cannot be used when zve32x is enabled.
* testsuite/gas/riscv/priv-reg-fail-version-1p10.d: Updated -march
to rv32ifv_zkr.
* testsuite/gas/riscv/priv-reg-fail-version-1p11.d: Likewise.
* testsuite/gas/riscv/priv-reg-fail-version-1p9p1.d: Likewise.
* testsuite/gas/riscv/priv-reg.s: Added rvv csr testcases.
* testsuite/gas/riscv/priv-reg-version-1p10.d: Likewise.
* testsuite/gas/riscv/priv-reg-version-1p11.d: Likewise.
* testsuite/gas/riscv/priv-reg-version-1p9p1.d: Likewise.
* testsuite/gas/riscv/march-imply-v.d: New testcase.
* testsuite/gas/riscv/vector-insns-fail-zve32xf.d: Likewise.
* testsuite/gas/riscv/vector-insns-fail-zve32xf.l: Likewise.
* testsuite/gas/riscv/vector-insns-fail-zvl.d: Likewise.
* testsuite/gas/riscv/vector-insns-fail-zvl.l: Likewise.
* testsuite/gas/riscv/vector-insns-vmsgtvx.d: Likewise.
* testsuite/gas/riscv/vector-insns-vmsgtvx.s: Likewise.
* testsuite/gas/riscv/vector-insns-zero-imm.d: Likewise.
* testsuite/gas/riscv/vector-insns-zero-imm.s: Likewise.
* testsuite/gas/riscv/vector-insns.d: Likewise.
* testsuite/gas/riscv/vector-insns.s: Likewise.
include/
* opcode/riscv-opc.h: Defined mask/match encodings and csrs for rvv.
* opcode/riscv.h: Defined rvv immediate encodings and fields.
(enum riscv_insn_class): Added INSN_CLASS_V and INSN_CLASS_ZVEF.
(INSN_V_EEW64): Defined.
(M_VMSGE, M_VMSGEU): Added for the rvv pseudoes.
opcodes/
* riscv-dis.c (print_insn_args): Dump the rvv operands.
* riscv-opc.c (riscv_vecr_names_numeric): Defined rvv registers.
(riscv_vecm_names_numeric): Likewise.
(riscv_vsew): Likewise.
(riscv_vlmul): Likewise.
(riscv_vta): Likewise.
(riscv_vma): Likewise.
(match_vs1_eq_vs2): Added for rvv Vu operand.
(match_vd_eq_vs1_eq_vs2): Added for rvv Vv operand.
(riscv_opcodes): Added rvv v1.0 instructions.
Diffstat (limited to 'bfd/elfxx-riscv.c')
-rw-r--r-- | bfd/elfxx-riscv.c | 76 |
1 files changed, 75 insertions, 1 deletions
diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c index e2fb400338..78b1517bd8 100644 --- a/bfd/elfxx-riscv.c +++ b/bfd/elfxx-riscv.c @@ -1073,6 +1073,31 @@ static struct riscv_implicit_subset riscv_implicit_subsets[] = {"g", "zicsr", check_implicit_always}, {"g", "zifencei", check_implicit_always}, {"q", "d", check_implicit_always}, + {"v", "d", check_implicit_always}, + {"v", "zve64d", check_implicit_always}, + {"v", "zvl128b", check_implicit_always}, + {"zve64d", "d", check_implicit_always}, + {"zve64d", "zve64f", check_implicit_always}, + {"zve64f", "zve32f", check_implicit_always}, + {"zve64f", "zve64x", check_implicit_always}, + {"zve64f", "zvl64b", check_implicit_always}, + {"zve32f", "f", check_implicit_always}, + {"zve32f", "zvl32b", check_implicit_always}, + {"zve32f", "zve32x", check_implicit_always}, + {"zve64x", "zve32x", check_implicit_always}, + {"zve64x", "zvl64b", check_implicit_always}, + {"zve32x", "zvl32b", check_implicit_always}, + {"zvl65536b", "zvl32768b", check_implicit_always}, + {"zvl32768b", "zvl16384b", check_implicit_always}, + {"zvl16384b", "zvl8192b", check_implicit_always}, + {"zvl8192b", "zvl4096b", check_implicit_always}, + {"zvl4096b", "zvl2048b", check_implicit_always}, + {"zvl2048b", "zvl1024b", check_implicit_always}, + {"zvl1024b", "zvl512b", check_implicit_always}, + {"zvl512b", "zvl256b", check_implicit_always}, + {"zvl256b", "zvl128b", check_implicit_always}, + {"zvl128b", "zvl64b", check_implicit_always}, + {"zvl64b", "zvl32b", check_implicit_always}, {"d", "f", check_implicit_always}, {"f", "zicsr", check_implicit_always}, {"zk", "zkn", check_implicit_always}, @@ -1145,7 +1170,7 @@ static struct riscv_supported_ext riscv_supported_std_ext[] = {"j", ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 }, {"t", ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 }, {"p", ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 }, - {"v", ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 }, + {"v", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {"n", ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 }, {NULL, 0, 0, 0, 0} }; @@ -1174,6 +1199,24 @@ static struct riscv_supported_ext riscv_supported_std_z_ext[] = {"zksed", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {"zksh", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {"zkt", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, + {"zve32x", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, + {"zve32f", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, + {"zve32d", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, + {"zve64x", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, + {"zve64f", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, + {"zve64d", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, + {"zvl32b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, + {"zvl64b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, + {"zvl128b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, + {"zvl256b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, + {"zvl512b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, + {"zvl1024b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, + {"zvl2048b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, + {"zvl4096b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, + {"zvl8192b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, + {"zvl16384b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, + {"zvl32768b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, + {"zvl65536b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {NULL, 0, 0, 0, 0} }; @@ -1854,6 +1897,28 @@ riscv_parse_check_conflicts (riscv_parse_subset_t *rps) (_("rv32e does not support the `f' extension")); no_conflict = false; } + + bool support_zve = false; + bool support_zvl = false; + riscv_subset_t *s = rps->subset_list->head; + for (; s != NULL; s = s->next) + { + if (!support_zve + && strncmp (s->name, "zve", 3) == 0) + support_zve = true; + if (!support_zvl + && strncmp (s->name, "zvl", 3) == 0) + support_zvl = true; + if (support_zve && support_zvl) + break; + } + if (support_zvl && !support_zve) + { + rps->error_handler + (_("zvl*b extensions need to enable either `v' or `zve' extension")); + no_conflict = false; + } + return no_conflict; } @@ -2205,6 +2270,15 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps, return riscv_subset_supports (rps, "zksed"); case INSN_CLASS_ZKSH: return riscv_subset_supports (rps, "zksh"); + case INSN_CLASS_V: + return (riscv_subset_supports (rps, "v") + || riscv_subset_supports (rps, "zve64x") + || riscv_subset_supports (rps, "zve32x")); + case INSN_CLASS_ZVEF: + return (riscv_subset_supports (rps, "v") + || riscv_subset_supports (rps, "zve64d") + || riscv_subset_supports (rps, "zve64f") + || riscv_subset_supports (rps, "zve32f")); default: rps->error_handler (_("internal: unreachable INSN_CLASS_*")); |