[REVIEW,ONLY,1/4] UNRATIFIED RISC-V: Add 'Zfbfmin' extension

Message ID 6c69c88bbca589e29567a4aa406c04ca2eaf11d6.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 'Zfbfmin' extension, the scalar BF16
conversion extension.  It consists of two new instructions and four
previously 'Zfhmin'-only 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 'Zfbfmin' -> 'F'.
	(riscv_supported_std_z_ext): Add 'Zfbfmin'.
	(riscv_multi_subset_supports): Recategory INSN_CLASS_ZFHMIN to mean
	'Zfhmin' or 'Zfbfmin'.  Add support to INSN_CLASS_ZFBFMIN.
	(riscv_multi_subset_supports_ext): Likewise.

gas/ChangeLog:

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

include/ChangeLog:

	* opcode/riscv-opc.h (MATCH_FCVT_BF16_S, MASK_FCVT_BF16_S,
	MATCH_FCVT_S_BF16, MASK_FCVT_S_BF16) New.
	* opcode/riscv.h (enum riscv_insn_class): Add new instruction class
	INSN_CLASS_ZFBFMIN.

opcodes/ChangeLog:

	* riscv-opc.c (riscv_opcodes): Add 'Zfbfmin'-only instructions.
---
 bfd/elfxx-riscv.c                 | 11 +++++++++--
 gas/testsuite/gas/riscv/zfbfmin.d | 15 +++++++++++++++
 gas/testsuite/gas/riscv/zfbfmin.s | 10 ++++++++++
 include/opcode/riscv-opc.h        |  8 ++++++++
 include/opcode/riscv.h            |  1 +
 opcodes/riscv-opc.c               |  5 +++++
 6 files changed, 48 insertions(+), 2 deletions(-)
 create mode 100644 gas/testsuite/gas/riscv/zfbfmin.d
 create mode 100644 gas/testsuite/gas/riscv/zfbfmin.s
  

Patch

diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index ba5165766b2b..edc2b17f5d3a 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -1136,6 +1136,7 @@  static struct riscv_implicit_subset riscv_implicit_subsets[] =
   {"zcf", "f",		check_implicit_always},
   {"zfa", "f",		check_implicit_always},
   {"d", "f",		check_implicit_always},
+  {"zfbfmin", "f",	check_implicit_always},
   {"zfh", "zfhmin",	check_implicit_always},
   {"zfhmin", "f",	check_implicit_always},
   {"f", "zicsr",	check_implicit_always},
@@ -1254,6 +1255,7 @@  static struct riscv_supported_ext riscv_supported_std_z_ext[] =
   {"zmmul",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
   {"zawrs",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
   {"zfa",		ISA_SPEC_CLASS_DRAFT,		0, 1,  0 },
+  {"zfbfmin",		ISA_SPEC_CLASS_DRAFT,		0, 8,  0 },
   {"zfh",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
   {"zfhmin",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
   {"zfinx",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
@@ -2422,11 +2424,14 @@  riscv_multi_subset_supports (riscv_parse_subset_t *rps,
     case INSN_CLASS_Q_INX:
       return (riscv_subset_supports (rps, "q")
 	      || riscv_subset_supports (rps, "zqinx"));
+    case INSN_CLASS_ZFBFMIN:
+      return riscv_subset_supports (rps, "zfbfmin");
     case INSN_CLASS_ZFH_INX:
       return (riscv_subset_supports (rps, "zfh")
 	      || riscv_subset_supports (rps, "zhinx"));
     case INSN_CLASS_ZFHMIN:
-      return riscv_subset_supports (rps, "zfhmin");
+      return (riscv_subset_supports (rps, "zfhmin")
+	      || riscv_subset_supports (rps, "zfbfmin"));
     case INSN_CLASS_ZFHMIN_INX:
       return (riscv_subset_supports (rps, "zfhmin")
 	      || riscv_subset_supports (rps, "zhinxmin"));
@@ -2625,10 +2630,12 @@  riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
       return _("d' or `zdinx");
     case INSN_CLASS_Q_INX:
       return _("q' or `zqinx");
+    case INSN_CLASS_ZFBFMIN:
+      return "zfbfmin";
     case INSN_CLASS_ZFH_INX:
       return _("zfh' or `zhinx");
     case INSN_CLASS_ZFHMIN:
-      return "zfhmin";
+      return _("zfhmin' or `zfbfmin");
     case INSN_CLASS_ZFHMIN_INX:
       return _("zfhmin' or `zhinxmin");
     case INSN_CLASS_ZFHMIN_AND_D_INX:
diff --git a/gas/testsuite/gas/riscv/zfbfmin.d b/gas/testsuite/gas/riscv/zfbfmin.d
new file mode 100644
index 000000000000..28675457a0a9
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zfbfmin.d
@@ -0,0 +1,15 @@ 
+#as: -march=rv32i_zfbfmin
+#objdump: -d
+
+.*:[ 	]+file format .*
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+[0-9a-f]+:[ 	]+4485f553[ 	]+fcvt\.bf16\.s[ 	]+fa0,fa1
+[ 	]+[0-9a-f]+:[ 	]+44859553[ 	]+fcvt\.bf16\.s[ 	]+fa0,fa1,rtz
+[ 	]+[0-9a-f]+:[ 	]+40658553[ 	]+fcvt\.s\.bf16[ 	]+fa0,fa1
+[ 	]+[0-9a-f]+:[ 	]+00059507[ 	]+flh[ 	]+fa0,0\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+00a59027[ 	]+fsh[ 	]+fa0,0\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+e4058553[ 	]+fmv\.x\.h[ 	]+a0,fa1
+[ 	]+[0-9a-f]+:[ 	]+f4058553[ 	]+fmv\.h\.x[ 	]+fa0,a1
diff --git a/gas/testsuite/gas/riscv/zfbfmin.s b/gas/testsuite/gas/riscv/zfbfmin.s
new file mode 100644
index 000000000000..a0670a33ce69
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zfbfmin.s
@@ -0,0 +1,10 @@ 
+target:
+	# Zfbfmin only instructions
+	fcvt.bf16.s	fa0, fa1
+	fcvt.bf16.s	fa0, fa1, rtz
+	fcvt.s.bf16	fa0, fa1
+	# Instructions shared with Zfhmin
+	flh		fa0, 0(a1)
+	fsh		fa0, 0(a1)
+	fmv.x.h		a0, fa1
+	fmv.h.x		fa0, a1
diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
index 53f5f2005085..864faddcc6a5 100644
--- a/include/opcode/riscv-opc.h
+++ b/include/opcode/riscv-opc.h
@@ -2121,6 +2121,11 @@ 
 #define MASK_VDOTUVV  0xfc00707f
 #define MATCH_VFDOTVV  0xe4001057
 #define MASK_VFDOTVV  0xfc00707f
+/* Zfbfmin instructions.  */
+#define MATCH_FCVT_BF16_S 0x44800053
+#define MASK_FCVT_BF16_S 0xfff0007f
+#define MATCH_FCVT_S_BF16 0x40600053
+#define MASK_FCVT_S_BF16 0xfff0007f
 /* Zvbb instructions.  */
 #define MATCH_VANDN_VV 0x4000057
 #define MASK_VANDN_VV 0xfc00707f
@@ -3344,6 +3349,9 @@  DECLARE_INSN(czero_nez, MATCH_CZERO_NEZ, MASK_CZERO_NEZ)
 /* Zawrs instructions.  */
 DECLARE_INSN(wrs_nto, MATCH_WRS_NTO, MASK_WRS_NTO)
 DECLARE_INSN(wrs_sto, MATCH_WRS_STO, MASK_WRS_STO)
+/* Zfbfmin instructions.  */
+DECLARE_INSN(fcvt_bf16_s, MATCH_FCVT_BF16_S, MASK_FCVT_BF16_S)
+DECLARE_INSN(fcvt_s_bf16, MATCH_FCVT_S_BF16, MASK_FCVT_S_BF16)
 /* Zvbb instructions.  */
 DECLARE_INSN(vandn_vv, MATCH_VANDN_VV, MASK_VANDN_VV)
 DECLARE_INSN(vandn_vx, MATCH_VANDN_VX, MASK_VANDN_VX)
diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
index 808f36573030..4db29287ebe9 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -398,6 +398,7 @@  enum riscv_insn_class
   INSN_CLASS_F_INX,
   INSN_CLASS_D_INX,
   INSN_CLASS_Q_INX,
+  INSN_CLASS_ZFBFMIN,
   INSN_CLASS_ZFH_INX,
   INSN_CLASS_ZFHMIN,
   INSN_CLASS_ZFHMIN_INX,
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 6a854736fec0..5c9809c3c4f7 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -974,6 +974,11 @@  const struct riscv_opcode riscv_opcodes[] =
 {"wrs.nto",    0, INSN_CLASS_ZAWRS, "", MATCH_WRS_NTO, MASK_WRS_NTO, match_opcode, 0 },
 {"wrs.sto",    0, INSN_CLASS_ZAWRS, "", MATCH_WRS_STO, MASK_WRS_STO, match_opcode, 0 },
 
+/* Zfbfmin instructions.  */
+{"fcvt.bf16.s", 0, INSN_CLASS_ZFBFMIN,     "D,S",   MATCH_FCVT_BF16_S|MASK_RM, MASK_FCVT_BF16_S|MASK_RM, match_opcode, 0 },
+{"fcvt.bf16.s", 0, INSN_CLASS_ZFBFMIN,     "D,S,m", MATCH_FCVT_BF16_S, MASK_FCVT_BF16_S, match_opcode, 0 },
+{"fcvt.s.bf16", 0, INSN_CLASS_ZFBFMIN,     "D,S",   MATCH_FCVT_S_BF16, MASK_FCVT_S_BF16|MASK_RM, match_opcode, 0 },
+
 /* Zfa instructions.  */
 {"fli.s",       0, INSN_CLASS_ZFA,         "D,Wfv", MATCH_FLI_S, MASK_FLI_S, match_opcode, 0 },
 {"fli.d",       0, INSN_CLASS_D_AND_ZFA,   "D,Wfv", MATCH_FLI_D, MASK_FLI_D, match_opcode, 0 },