summaryrefslogtreecommitdiff
path: root/bfd/elfxx-riscv.c
diff options
context:
space:
mode:
authorNelson Chu <nelson.chu@sifive.com>2021-11-17 18:46:11 +0800
committerNelson Chu <nelson.chu@sifive.com>2021-11-17 20:18:11 +0800
commit65e4a99a26452d99d586f6e5a0c43e24348a5125 (patch)
tree92a3eca7a03c023591d661a6869135e3bf1522f1 /bfd/elfxx-riscv.c
parent486f9e20e037f1eea2dce98dc393db60df5feef3 (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.c76
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_*"));