[REVIEW,ONLY,3/4] UNRATIFIED RISC-V: Add 'Zvfbfwma' extension

Message ID 407c1a1b2b8ba154e50906360bdf44953eef153d.1691021079.git.research_trasio@irq.a4lg.com
State Unresolved
Headers
Series UNRATIFIED RISC-V: Add support for BFloat16 extensions |

Checks

Context Check Description
snail/binutils-gdb-check warning Git am fail log

Commit Message

Tsukasa OI Aug. 3, 2023, 12:04 a.m. UTC
  From: Tsukasa OI <research_trasio@irq.a4lg.com>

[DO NOT MERGE]
Until RISC-V BF16 extensions are frozen/ratified and the final version
number is determined, this patch should not be merged upstream. This
commit uses unratified version 0.8 as in the latest PDF documentation
(instead of possible 1.0 after ratification).

This commit adds support for the 'Zvfbfwma' extension, the vector BF16
multiply then FP32 accumlation extension, consisting of two widening
multiply-accumulate instructions.

This commit is based on the following specification:
<https://github.com/riscv/riscv-bfloat16/commit/5578e34e15a44e9ad13246072a29f51274b4d999>

bfd/ChangeLog:

	* elfxx-riscv.c (riscv_implicit_subsets) Add 'Zvfbfwma'
	-> 'Zvfbfmin' implication.
	(riscv_supported_std_z_ext): Add 'Zvfbfwma'.
	(riscv_multi_subset_supports): Add support to INSN_CLASS_ZVFBFWMA.
	(riscv_multi_subset_supports_ext): Likewise.

gas/ChangeLog:

	* testsuite/gas/riscv/zvfbfwma.s: New test.
	* testsuite/gas/riscv/zvfbfwma.d: Likewise.

include/ChangeLog:

	* opcode/riscv-opc.h (MATCH_VFWMACCBF16_VF, MASK_VFWMACCBF16_VF,
	MATCH_VFWMACCBF16_VV, MASK_VFWMACCBF16_VV) New.
	* opcode/riscv.h (enum riscv_insn_class): Add new instruction class
	INSN_CLASS_ZVFBFWMA.

opcodes/ChangeLog:

	* riscv-opc.c (riscv_opcodes): Add 'Zvfbfwma' instructions.
---
 bfd/elfxx-riscv.c                  |  6 ++++++
 gas/testsuite/gas/riscv/zvfbfwma.d | 12 ++++++++++++
 gas/testsuite/gas/riscv/zvfbfwma.s |  5 +++++
 include/opcode/riscv-opc.h         |  8 ++++++++
 include/opcode/riscv.h             |  1 +
 opcodes/riscv-opc.c                |  4 ++++
 6 files changed, 36 insertions(+)
 create mode 100644 gas/testsuite/gas/riscv/zvfbfwma.d
 create mode 100644 gas/testsuite/gas/riscv/zvfbfwma.s
  

Patch

diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index daf60010640a..57bbc82f7f7f 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -1110,6 +1110,7 @@  static struct riscv_implicit_subset riscv_implicit_subsets[] =
   {"v", "d",		check_implicit_always},
   {"v", "zve64d",	check_implicit_always},
   {"v", "zvl128b",	check_implicit_always},
+  {"zvfbfwma", "zvfbfmin",	check_implicit_always},
   {"zvfbfmin", "zfbfmin",	check_implicit_always},
   {"zvfbfmin", "zve32f",	check_implicit_always},
   {"zve64d", "d",	check_implicit_always},
@@ -1291,6 +1292,7 @@  static struct riscv_supported_ext riscv_supported_std_z_ext[] =
   {"zvbb",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
   {"zvbc",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
   {"zvfbfmin",		ISA_SPEC_CLASS_DRAFT,		0, 8,  0 },
+  {"zvfbfwma",		ISA_SPEC_CLASS_DRAFT,		0, 8,  0 },
   {"zvkg",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
   {"zvkn",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
   {"zvkng",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
@@ -2507,6 +2509,8 @@  riscv_multi_subset_supports (riscv_parse_subset_t *rps,
       return riscv_subset_supports (rps, "zvbc");
     case INSN_CLASS_ZVFBFMIN:
       return riscv_subset_supports (rps, "zvfbfmin");
+    case INSN_CLASS_ZVFBFWMA:
+      return riscv_subset_supports (rps, "zvfbfwma");
     case INSN_CLASS_ZVKG:
       return riscv_subset_supports (rps, "zvkg");
     case INSN_CLASS_ZVKNED:
@@ -2729,6 +2733,8 @@  riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
       return _("zvbb");
     case INSN_CLASS_ZVFBFMIN:
       return "zvfbfmin";
+    case INSN_CLASS_ZVFBFWMA:
+      return "zvfbfwma";
     case INSN_CLASS_ZVBC:
       return _("zvbc");
     case INSN_CLASS_ZVKG:
diff --git a/gas/testsuite/gas/riscv/zvfbfwma.d b/gas/testsuite/gas/riscv/zvfbfwma.d
new file mode 100644
index 000000000000..3597bde0e4af
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zvfbfwma.d
@@ -0,0 +1,12 @@ 
+#as: -march=rv32i_zvfbfwma
+#objdump: -d
+
+.*:[ 	]+file format .*
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+[0-9a-f]+:[ 	]+ee861257[ 	]+vfwmaccbf16.vv[ 	]+v4,v8,v12
+[ 	]+[0-9a-f]+:[ 	]+ee865257[ 	]+vfwmaccbf16.vf[ 	]+v4,v8,fa2
+[ 	]+[0-9a-f]+:[ 	]+ec861257[ 	]+vfwmaccbf16.vv[ 	]+v4,v8,v12,v0.t
+[ 	]+[0-9a-f]+:[ 	]+ec865257[ 	]+vfwmaccbf16.vf[ 	]+v4,v8,fa2,v0.t
diff --git a/gas/testsuite/gas/riscv/zvfbfwma.s b/gas/testsuite/gas/riscv/zvfbfwma.s
new file mode 100644
index 000000000000..d44c09c27f10
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zvfbfwma.s
@@ -0,0 +1,5 @@ 
+target:
+	vfwmaccbf16.vv v4, v8, v12
+	vfwmaccbf16.vf v4, v8, fa2
+	vfwmaccbf16.vv v4, v8, v12, v0.t
+	vfwmaccbf16.vf v4, v8, fa2, v0.t
diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
index 2a631a871ecd..f57aca4c6498 100644
--- a/include/opcode/riscv-opc.h
+++ b/include/opcode/riscv-opc.h
@@ -2173,6 +2173,11 @@ 
 #define MASK_VFNCVTBF16_F_F_W 0xfc0ff07f
 #define MATCH_VFWCVTBF16_F_F_V 0x48069057
 #define MASK_VFWCVTBF16_F_F_V 0xfc0ff07f
+/* Zvfbfwma instructions.  */
+#define MATCH_VFWMACCBF16_VF 0xec005057
+#define MASK_VFWMACCBF16_VF 0xfc00707f
+#define MATCH_VFWMACCBF16_VV 0xec001057
+#define MASK_VFWMACCBF16_VV 0xfc00707f
 /* Zvkg instructions.  */
 #define MATCH_VGHSH_VV 0xb2002077
 #define MASK_VGHSH_VV 0xfe00707f
@@ -3382,6 +3387,9 @@  DECLARE_INSN(vclmulh_vx, MATCH_VCLMULH_VX, MASK_VCLMULH_VX)
 /* Zvfbfmin instructions.  */
 DECLARE_INSN(vfncvtbf16_f_f_w, MATCH_VFNCVTBF16_F_F_W, MASK_VFNCVTBF16_F_F_W)
 DECLARE_INSN(vfwcvtbf16_f_f_v, MATCH_VFWCVTBF16_F_F_V, MASK_VFWCVTBF16_F_F_V)
+/* Zvfbfwma instructions.  */
+DECLARE_INSN(vfwmaccbf16_vf, MATCH_VFWMACCBF16_VF, MASK_VFWMACCBF16_VF)
+DECLARE_INSN(vfwmaccbf16_vv, MATCH_VFWMACCBF16_VV, MASK_VFWMACCBF16_VV)
 /* Zvkg instructions.  */
 DECLARE_INSN(vghsh_vv, MATCH_VGHSH_VV, MASK_VGHSH_VV)
 DECLARE_INSN(vgmul_vv, MATCH_VGMUL_VV, MASK_VGMUL_VV)
diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
index 44105ba8698b..9fbe5392a45e 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -428,6 +428,7 @@  enum riscv_insn_class
   INSN_CLASS_ZVBB,
   INSN_CLASS_ZVBC,
   INSN_CLASS_ZVFBFMIN,
+  INSN_CLASS_ZVFBFWMA,
   INSN_CLASS_ZVKG,
   INSN_CLASS_ZVKNED,
   INSN_CLASS_ZVKNHA_OR_ZVKNHB,
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index c2f90c900bd1..f8001b601d90 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -1930,6 +1930,10 @@  const struct riscv_opcode riscv_opcodes[] =
 {"vfncvtbf16.f.f.w", 0, INSN_CLASS_ZVFBFMIN, "Vd,VtVm", MATCH_VFNCVTBF16_F_F_W, MASK_VFNCVTBF16_F_F_W, match_opcode, 0},
 {"vfwcvtbf16.f.f.v", 0, INSN_CLASS_ZVFBFMIN, "Vd,VtVm", MATCH_VFWCVTBF16_F_F_V, MASK_VFWCVTBF16_F_F_V, match_opcode, 0},
 
+/* Zvfbfwma instructions.  */
+{"vfwmaccbf16.vv",   0, INSN_CLASS_ZVFBFWMA, "Vd,Vt,VsVm", MATCH_VFWMACCBF16_VV, MASK_VFWMACCBF16_VV, match_opcode, 0},
+{"vfwmaccbf16.vf",   0, INSN_CLASS_ZVFBFWMA, "Vd,Vt,SVm", MATCH_VFWMACCBF16_VF, MASK_VFWMACCBF16_VF, match_opcode, 0},
+
 /* Zvkg instructions.  */
 {"vghsh.vv",   0, INSN_CLASS_ZVKG, "Vd,Vt,Vs", MATCH_VGHSH_VV, MASK_VGHSH_VV, match_opcode, 0},
 {"vgmul.vv",   0, INSN_CLASS_ZVKG, "Vd,Vt", MATCH_VGMUL_VV, MASK_VGMUL_VV, match_opcode, 0},