public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [RFC PATCH v5] RISC-V: Add support for the Zfa extension
@ 2023-04-13 13:36 Christoph Muellner
  2023-06-29  7:52 ` Christoph Müllner
  0 siblings, 1 reply; 19+ messages in thread
From: Christoph Muellner @ 2023-04-13 13:36 UTC (permalink / raw)
  To: binutils, Nelson Chu, Andrew Waterman, Palmer Dabbelt,
	Jim Wilson, Philipp Tomsich, Jan Beulich, Kito Cheng, Jeff Law,
	Tsukasa OI
  Cc: Christoph Müllner

From: Christoph Müllner <christoph.muellner@vrull.eu>

This patch adds support for the RISC-V Zfa extension,
which introduces additional floating-point instructions:
* fli (load-immediate) with pre-defined immediates
* fminm/fmaxm (like fmin/fmax but with different NaN behaviour)
* fround/froundmx (round to integer)
* fcvtmod.w.d (Modular Convert-to-Integer)
* fmv* to access high bits of FP registers in case XLEN < FLEN
* fleq/fltq (quiet comparison instructions)

Zfa defines its instructions in combination with the following
extensions:
* single-precision floating-point (F)
* double-precision floating-point (D)
* quad-precision floating-point (Q)
* half-precision floating-point (Zfh)

This patch is based on an earlier version from Tsukasa OI:
  https://sourceware.org/pipermail/binutils/2022-September/122939.html
Most significant change to that commit is the switch from the rs1-field
value to the actual floating-point value in the last operand of the fli*
instructions. Everything that strtof() can parse is accepted and
the '%a' printf specifier is used to output hex floating-point literals
in the disassembly.

The Zfa specification is not frozen at the moment (which is why this
patch is RFC) and can be found here:
  https://github.com/riscv/riscv-isa-manual/blob/master/src/zfa.tex

bfd/ChangeLog:

	* elfxx-riscv.c (riscv_multi_subset_supports): Add instruction
	class support for 'Zfa' extension.
	(riscv_multi_subset_supports_ext): Likewise.
	(riscv_implicit_subsets): Add 'Zfa' -> 'F' dependency.

gas/ChangeLog:

	* config/tc-riscv.c (flt_lookup): New helper to lookup a float value
	in an array.
	(validate_riscv_insn): Add 'Wfv' as new format string directive.
	(riscv_ip): Likewise.
	* doc/c-riscv.texi: Add floating-point chapter and describe
	limiations of the Zfa FP literal parsing.
	* testsuite/gas/riscv/zfa-32.d: New test.
	* testsuite/gas/riscv/zfa-32.s: New test.
	* testsuite/gas/riscv/zfa-64.d: New test.
	* testsuite/gas/riscv/zfa-64.s: New test.
	* testsuite/gas/riscv/zfa-fail.d: New test.
	* testsuite/gas/riscv/zfa-fail.l: New test.
	* testsuite/gas/riscv/zfa-fail.s: New test.
	* testsuite/gas/riscv/zfa.d: New test.
	* testsuite/gas/riscv/zfa.s: New test.
	* testsuite/gas/riscv/zfa.s: New test.

	* opcode/riscv-opc.h (MATCH_FLI_H): New.
	(MASK_FLI_H): New.
	(MATCH_FMINM_H): New.
	(MASK_FMINM_H): New.
	(MATCH_FMAXM_H): New.
	(MASK_FMAXM_H): New.
	(MATCH_FROUND_H): New.
	(MASK_FROUND_H): New.
	(MATCH_FROUNDNX_H): New.
	(MASK_FROUNDNX_H): New.
	(MATCH_FLTQ_H): New.
	(MASK_FLTQ_H): New.
	(MATCH_FLEQ_H): New.
	(MASK_FLEQ_H): New.
	(MATCH_FLI_S): New.
	(MASK_FLI_S): New.
	(MATCH_FMINM_S): New.
	(MASK_FMINM_S): New.
	(MATCH_FMAXM_S): New.
	(MASK_FMAXM_S): New.
	(MATCH_FROUND_S): New.
	(MASK_FROUND_S): New.
	(MATCH_FROUNDNX_S): New.
	(MASK_FROUNDNX_S): New.
	(MATCH_FLTQ_S): New.
	(MASK_FLTQ_S): New.
	(MATCH_FLEQ_S): New.
	(MASK_FLEQ_S): New.
	(MATCH_FLI_D): New.
	(MASK_FLI_D): New.
	(MATCH_FMINM_D): New.
	(MASK_FMINM_D): New.
	(MATCH_FMAXM_D): New.
	(MASK_FMAXM_D): New.
	(MATCH_FROUND_D): New.
	(MASK_FROUND_D): New.
	(MATCH_FROUNDNX_D): New.
	(MASK_FROUNDNX_D): New.
	(MATCH_FLTQ_D): New.
	(MASK_FLTQ_D): New.
	(MATCH_FLEQ_D): New.
	(MASK_FLEQ_D): New.
	(MATCH_FLI_Q): New.
	(MASK_FLI_Q): New.
	(MATCH_FMINM_Q): New.
	(MASK_FMINM_Q): New.
	(MATCH_FMAXM_Q): New.
	(MASK_FMAXM_Q): New.
	(MATCH_FROUND_Q): New.
	(MASK_FROUND_Q): New.
	(MATCH_FROUNDNX_Q): New.
	(MASK_FROUNDNX_Q): New.
	(MATCH_FLTQ_Q): New.
	(MASK_FLTQ_Q): New.
	(MATCH_FLEQ_Q): New.
	(MASK_FLEQ_Q): New.
	(MATCH_FCVTMOD_W_D): New.
	(MASK_FCVTMOD_W_D): New.
	(MATCH_FMVH_X_D): New.
	(MASK_FMVH_X_D): New.
	(MATCH_FMVH_X_Q): New.
	(MASK_FMVH_X_Q): New.
	(MATCH_FMVP_D_X): New.
	(MASK_FMVP_D_X): New.
	(MATCH_FMVP_Q_X): New.
	(MASK_FMVP_Q_X): New.
	(DECLARE_INSN): New.
	* opcode/riscv.h (enum riscv_insn_class): Add instruction
	classes for the Zfa extension.

opcodes/ChangeLog:

	* riscv-dis.c (print_insn_args): Add support for
	new format string directive 'Wfv'.
	* riscv-opc.c: Add Zfa instructions.

Co-Developed-by: Tsukasa OI <research_trasio@irq.a4lg.com>
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
---
Changes in v5:
* Fixes in texinfo directives (documentation)
* Make FLI error message more verbose

 bfd/elfxx-riscv.c                  | 39 ++++++++++++
 gas/config/tc-riscv.c              | 52 ++++++++++++++++
 gas/doc/c-riscv.texi               | 41 +++++++++++++
 gas/testsuite/gas/riscv/zfa-32.d   | 10 +++
 gas/testsuite/gas/riscv/zfa-32.s   |  3 +
 gas/testsuite/gas/riscv/zfa-64.d   | 10 +++
 gas/testsuite/gas/riscv/zfa-64.s   |  3 +
 gas/testsuite/gas/riscv/zfa-fail.d |  3 +
 gas/testsuite/gas/riscv/zfa-fail.l | 12 ++++
 gas/testsuite/gas/riscv/zfa-fail.s | 16 +++++
 gas/testsuite/gas/riscv/zfa.d      | 89 +++++++++++++++++++++++++++
 gas/testsuite/gas/riscv/zfa.s      | 87 ++++++++++++++++++++++++++
 include/opcode/riscv-opc.h         | 99 ++++++++++++++++++++++++++++++
 include/opcode/riscv.h             |  6 ++
 opcodes/riscv-dis.c                | 16 +++++
 opcodes/riscv-opc.c                | 64 +++++++++++++++++++
 16 files changed, 550 insertions(+)
 create mode 100644 gas/testsuite/gas/riscv/zfa-32.d
 create mode 100644 gas/testsuite/gas/riscv/zfa-32.s
 create mode 100644 gas/testsuite/gas/riscv/zfa-64.d
 create mode 100644 gas/testsuite/gas/riscv/zfa-64.s
 create mode 100644 gas/testsuite/gas/riscv/zfa-fail.d
 create mode 100644 gas/testsuite/gas/riscv/zfa-fail.l
 create mode 100644 gas/testsuite/gas/riscv/zfa-fail.s
 create mode 100644 gas/testsuite/gas/riscv/zfa.d
 create mode 100644 gas/testsuite/gas/riscv/zfa.s

diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index 19391d94e30..d57fe2400fd 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -1078,6 +1078,7 @@ static struct riscv_implicit_subset riscv_implicit_subsets[] =
   {"zvl256b", "zvl128b",	check_implicit_always},
   {"zvl128b", "zvl64b",		check_implicit_always},
   {"zvl64b", "zvl32b",		check_implicit_always},
+  {"zfa", "f",		check_implicit_always},
   {"d", "f",		check_implicit_always},
   {"zfh", "zfhmin",	check_implicit_always},
   {"zfhmin", "f",	check_implicit_always},
@@ -1175,6 +1176,7 @@ static struct riscv_supported_ext riscv_supported_std_z_ext[] =
   {"zihintpause",	ISA_SPEC_CLASS_DRAFT,		2, 0,  0 },
   {"zmmul",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
   {"zawrs",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
+  {"zfa",		ISA_SPEC_CLASS_DRAFT,		0, 1,  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 },
@@ -2313,6 +2315,17 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps,
 	       && riscv_subset_supports (rps, "q"))
 	      || (riscv_subset_supports (rps, "zhinxmin")
 		  && riscv_subset_supports (rps, "zqinx")));
+    case INSN_CLASS_ZFA:
+      return riscv_subset_supports (rps, "zfa");
+    case INSN_CLASS_D_AND_ZFA:
+      return riscv_subset_supports (rps, "d")
+	     && riscv_subset_supports (rps, "zfa");
+    case INSN_CLASS_Q_AND_ZFA:
+      return riscv_subset_supports (rps, "q")
+	     && riscv_subset_supports (rps, "zfa");
+    case INSN_CLASS_ZFH_AND_ZFA:
+      return riscv_subset_supports (rps, "zfh")
+	     && riscv_subset_supports (rps, "zfa");
     case INSN_CLASS_ZBA:
       return riscv_subset_supports (rps, "zba");
     case INSN_CLASS_ZBB:
@@ -2479,6 +2492,32 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
 	return "zhinxmin";
       else
 	return _("zfhmin' and `q', or `zhinxmin' and `zqinx");
+    case INSN_CLASS_ZFA:
+      return "zfa";
+    case INSN_CLASS_D_AND_ZFA:
+      if (!riscv_subset_supports (rps, "d")
+	  && !riscv_subset_supports (rps, "zfa"))
+	return _("d' and `zfa");
+      else if (!riscv_subset_supports (rps, "d"))
+	return "d";
+      else
+	return "zfa";
+    case INSN_CLASS_Q_AND_ZFA:
+      if (!riscv_subset_supports (rps, "q")
+	  && !riscv_subset_supports (rps, "zfa"))
+	return _("q' and `zfa");
+      else if (!riscv_subset_supports (rps, "q"))
+	return "q";
+      else
+	return "zfa";
+    case INSN_CLASS_ZFH_AND_ZFA:
+      if (!riscv_subset_supports (rps, "zfh")
+	  && !riscv_subset_supports (rps, "zfa"))
+	return _("zfh' and `zfa");
+      else if (!riscv_subset_supports (rps, "zfh"))
+	return "zfh";
+      else
+	return "zfa";
     case INSN_CLASS_ZBA:
       return "zba";
     case INSN_CLASS_ZBB:
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index 4eff07a6d4a..0fcc1f26587 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -1219,6 +1219,21 @@ arg_lookup (char **s, const char *const *array, size_t size, unsigned *regnop)
   return false;
 }
 
+static bool
+flt_lookup (float f, const float *array, size_t size, unsigned *regnop)
+{
+  size_t i;
+
+  for (i = 0; i < size; i++)
+    if (array[i] == f)
+      {
+	*regnop = i;
+	return true;
+      }
+
+  return false;
+}
+
 #define USE_BITS(mask,shift) (used_bits |= ((insn_t)(mask) << (shift)))
 #define USE_IMM(n, s) \
   (used_bits |= ((insn_t)((1ull<<n)-1) << (s)))
@@ -1399,6 +1414,14 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
 		  goto unknown_validate_operand;
 		}
 	      break;
+	    case 'f':
+	      switch (*++oparg)
+		{
+		case 'v': USE_BITS (OP_MASK_RS1, OP_SH_RS1); break;
+		default:
+		  goto unknown_validate_operand;
+		}
+	      break;
 	    default:
 	      goto unknown_validate_operand;
 	    }
@@ -3461,6 +3484,35 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 		      goto unknown_riscv_ip_operand;
 		    }
 		  break;
+		case 'f':
+		  switch (*++oparg)
+		    {
+		    case 'v':
+		      /* FLI.[HSDQ] value field for 'Zfa' extension.  */
+		      if (!arg_lookup (&asarg, riscv_fli_symval,
+				       ARRAY_SIZE (riscv_fli_symval), &regno))
+			{
+			  /* 0.0 is not a valid entry in riscv_fli_numval.  */
+			  errno = 0;
+			  float f = strtof (asarg, &asarg);
+			  if (errno != 0 || f == 0.0
+			      || !flt_lookup (f, riscv_fli_numval,
+					     ARRAY_SIZE(riscv_fli_numval),
+					     &regno))
+			    {
+			      as_bad (_("bad fli constant operand, "
+					"supported constants must be in "
+					"decimal or hexadecimal floating-point "
+					"literal form"));
+			      break;
+			    }
+			}
+		      INSERT_OPERAND (RS1, *ip, regno);
+		      continue;
+		    default:
+		      goto unknown_riscv_ip_operand;
+		    }
+		  break;
 		default:
 		  goto unknown_riscv_ip_operand;
 		}
diff --git a/gas/doc/c-riscv.texi b/gas/doc/c-riscv.texi
index 64fff6a7973..987c01f9d1d 100644
--- a/gas/doc/c-riscv.texi
+++ b/gas/doc/c-riscv.texi
@@ -18,6 +18,7 @@
 * RISC-V-Options::        RISC-V Options
 * RISC-V-Directives::     RISC-V Directives
 * RISC-V-Modifiers::      RISC-V Assembler Modifiers
+* RISC-V-Floating-Point:: RISC-V Floating Point
 * RISC-V-Formats::        RISC-V Instruction Formats
 * RISC-V-ATTRIBUTE::      RISC-V Object Attribute
 * RISC-V-CustomExts::     RISC-V Custom (Vendor-Defined) Extensions
@@ -382,6 +383,46 @@ The pseudo la.tls.gd instruction can be expended to
 
 @end table
 
+@node RISC-V-Floating-Point
+@section RISC-V Floating Point
+@cindex floating point, risc-v (@sc{ieee})
+@cindex RISC-V floating point (@sc{ieee})
+
+The RISC-V architecture uses @sc{ieee} floating-point numbers.
+
+The RISC-V Zfa extension includes a load-immediate instruction
+for floating-point registers, which allows specifying the immediate
+(from a pool of 32 predefined values defined in the specification)
+as operand.
+E.g. to load the value @code{0.0625} as single-precision FP value into
+the FP register @code{ft1} one of the following instructions can be used:
+
+	fli.s ft1, 0.0625 # dec floating-point literal
+	fli.s ft1, 0x1p-4 # hex floating-point literal
+	fli.s ft1, 0x0.8p-3
+	fli.s ft1, 0x1.0p-4
+	fli.s ft1, 0x2p-5
+	fli.s ft1, 0x4p-6
+	...
+
+As can be seen, many valid ways exist to express a floating-point value.
+This is realized by parsing the value operand using strtof() and
+comparing the parsed value against built-in float-constants that
+are written as hex floating-point literals.
+
+This approach works on all machines that use IEEE 754.
+However, there is a chance that this fails on other machines
+with the following error message:
+
+	Error: improper fli value operand
+	Error: illegal operands `fli.s ft1,0.0625
+
+The error indicates that parsing @samp{0x1p-4} and @samp{0.0625}
+to single-precision floating point numbers will not result
+in two equal values on that machine.
+
+If you encounter this problem, then please report it.
+
 @node RISC-V-Formats
 @section RISC-V Instruction Formats
 @cindex instruction formats, risc-v
diff --git a/gas/testsuite/gas/riscv/zfa-32.d b/gas/testsuite/gas/riscv/zfa-32.d
new file mode 100644
index 00000000000..48e20bf4675
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zfa-32.d
@@ -0,0 +1,10 @@
+#as: -march=rv32id_zfa
+#objdump: -d
+
+.*:[ 	]+file format .*
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+[0-9a-f]+:[ 	]+e2108553[ 	]+fmvh\.x\.d[ 	]+a0,ft1
+[ 	]+[0-9a-f]+:[ 	]+b2b500d3[ 	]+fmvp\.d\.x[ 	]+ft1,a0,a1
diff --git a/gas/testsuite/gas/riscv/zfa-32.s b/gas/testsuite/gas/riscv/zfa-32.s
new file mode 100644
index 00000000000..da95441cdc7
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zfa-32.s
@@ -0,0 +1,3 @@
+target:
+	fmvh.x.d	a0, ft1
+	fmvp.d.x	ft1, a0, a1
diff --git a/gas/testsuite/gas/riscv/zfa-64.d b/gas/testsuite/gas/riscv/zfa-64.d
new file mode 100644
index 00000000000..48b6d74ed9b
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zfa-64.d
@@ -0,0 +1,10 @@
+#as: -march=rv64iq_zfa
+#objdump: -d
+
+.*:[ 	]+file format .*
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+[0-9a-f]+:[ 	]+e6108553[ 	]+fmvh\.x\.q[ 	]+a0,ft1
+[ 	]+[0-9a-f]+:[ 	]+b6b500d3[ 	]+fmvp\.q\.x[ 	]+ft1,a0,a1
diff --git a/gas/testsuite/gas/riscv/zfa-64.s b/gas/testsuite/gas/riscv/zfa-64.s
new file mode 100644
index 00000000000..dc8129dae3e
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zfa-64.s
@@ -0,0 +1,3 @@
+target:
+	fmvh.x.q	a0, ft1
+	fmvp.q.x	ft1, a0, a1
diff --git a/gas/testsuite/gas/riscv/zfa-fail.d b/gas/testsuite/gas/riscv/zfa-fail.d
new file mode 100644
index 00000000000..2f0a69b247a
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zfa-fail.d
@@ -0,0 +1,3 @@
+#as: -march=rv64iq_zfa_zfh
+#source: zfa-fail.s
+#error_output: zfa-fail.l
diff --git a/gas/testsuite/gas/riscv/zfa-fail.l b/gas/testsuite/gas/riscv/zfa-fail.l
new file mode 100644
index 00000000000..efe9ba00e02
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zfa-fail.l
@@ -0,0 +1,12 @@
+.*: Assembler messages:
+.*: Error: bad fli constant operand, supported constants must be in decimal or hexadecimal floating-point literal form
+.*: Error: illegal operands `fli\.s ft1,infinity'
+.*: Error: bad fli constant operand, supported constants must be in decimal or hexadecimal floating-point literal form
+.*: Error: illegal operands `fli\.d ft1,invalid'
+.*: Error: illegal operands `fcvtmod\.w\.d a0,ft1'
+.*: Error: illegal operands `fcvtmod\.w\.d a0,ft1,rne'
+.*: Error: illegal operands `fcvtmod\.w\.d a0,ft1,rdn'
+.*: Error: illegal operands `fcvtmod\.w\.d a0,ft1,rup'
+.*: Error: illegal operands `fcvtmod\.w\.d a0,ft1,rmm'
+.*: Error: illegal operands `fcvtmod\.w\.d a0,ft1,dyn'
+.*: Error: illegal operands `fcvtmod\.w\.d a0,ft1,invalid'
diff --git a/gas/testsuite/gas/riscv/zfa-fail.s b/gas/testsuite/gas/riscv/zfa-fail.s
new file mode 100644
index 00000000000..98ffe7f3268
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zfa-fail.s
@@ -0,0 +1,16 @@
+target:
+	# fli.[sdqh]: Invalid value field
+	fli.s	ft1, infinity
+	fli.d	ft1, invalid
+
+	# fcvtmod.w.d: Requires explicit rounding mode.
+	fcvtmod.w.d	a0, ft1
+
+	# fcvtmod.w.d: Rounding mode other than rtz are reserved.
+	fcvtmod.w.d	a0, ft1, rne
+	fcvtmod.w.d	a0, ft1, rdn
+	fcvtmod.w.d	a0, ft1, rup
+	fcvtmod.w.d	a0, ft1, rmm
+	fcvtmod.w.d	a0, ft1, dyn
+	# fcvtmod.w.d: Invalid rounding mode is invalid.
+	fcvtmod.w.d	a0, ft1, invalid
diff --git a/gas/testsuite/gas/riscv/zfa.d b/gas/testsuite/gas/riscv/zfa.d
new file mode 100644
index 00000000000..cbfc72e6036
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zfa.d
@@ -0,0 +1,89 @@
+#as: -march=rv32iq_zfa_zfh
+#objdump: -d
+
+.*:[ 	]+file format .*
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+[0-9a-f]+:[ 	]+f01000d3[ 	]+fli\.s[ 		]+ft1,-0x1p\+0
+[ 	]+[0-9a-f]+:[ 	]+f01080d3[ 	]+fli\.s[ 		]+ft1,min
+[ 	]+[0-9a-f]+:[ 	]+f01100d3[ 	]+fli\.s[ 		]+ft1,0x1p-16
+[ 	]+[0-9a-f]+:[ 	]+f01180d3[ 	]+fli\.s[ 		]+ft1,0x1p-15
+[ 	]+[0-9a-f]+:[ 	]+f01200d3[ 	]+fli\.s[ 		]+ft1,0x1p-8
+[ 	]+[0-9a-f]+:[ 	]+f01280d3[ 	]+fli\.s[ 		]+ft1,0x1p-7
+[ 	]+[0-9a-f]+:[ 	]+f01300d3[ 	]+fli\.s[ 		]+ft1,0x1p-4
+[ 	]+[0-9a-f]+:[ 	]+f01380d3[ 	]+fli\.s[ 		]+ft1,0x1p-3
+[ 	]+[0-9a-f]+:[ 	]+f21400d3[ 	]+fli\.d[ 		]+ft1,0x1p-2
+[ 	]+[0-9a-f]+:[ 	]+f21480d3[ 	]+fli\.d[ 		]+ft1,0x1.4p-2
+[ 	]+[0-9a-f]+:[ 	]+f21500d3[ 	]+fli\.d[ 		]+ft1,0x1.8p-2
+[ 	]+[0-9a-f]+:[ 	]+f21580d3[ 	]+fli\.d[ 		]+ft1,0x1.cp-2
+[ 	]+[0-9a-f]+:[ 	]+f21600d3[ 	]+fli\.d[ 		]+ft1,0x1p-1
+[ 	]+[0-9a-f]+:[ 	]+f21680d3[ 	]+fli\.d[ 		]+ft1,0x1.4p-1
+[ 	]+[0-9a-f]+:[ 	]+f21700d3[ 	]+fli\.d[ 		]+ft1,0x1.8p-1
+[ 	]+[0-9a-f]+:[ 	]+f21780d3[ 	]+fli\.d[ 		]+ft1,0x1.cp-1
+[ 	]+[0-9a-f]+:[ 	]+f61800d3[ 	]+fli\.q[ 		]+ft1,0x1p\+0
+[ 	]+[0-9a-f]+:[ 	]+f61880d3[ 	]+fli\.q[ 		]+ft1,0x1.4p\+0
+[ 	]+[0-9a-f]+:[ 	]+f61900d3[ 	]+fli\.q[ 		]+ft1,0x1.8p\+0
+[ 	]+[0-9a-f]+:[ 	]+f61980d3[ 	]+fli\.q[ 		]+ft1,0x1.cp\+0
+[ 	]+[0-9a-f]+:[ 	]+f61a00d3[ 	]+fli\.q[ 		]+ft1,0x1p\+1
+[ 	]+[0-9a-f]+:[ 	]+f61a80d3[ 	]+fli\.q[ 		]+ft1,0x1.4p\+1
+[ 	]+[0-9a-f]+:[ 	]+f61b00d3[ 	]+fli\.q[ 		]+ft1,0x1.8p\+1
+[ 	]+[0-9a-f]+:[ 	]+f61b80d3[ 	]+fli\.q[ 		]+ft1,0x1p\+2
+[ 	]+[0-9a-f]+:[ 	]+f41c00d3[ 	]+fli\.h[ 		]+ft1,0x1p\+3
+[ 	]+[0-9a-f]+:[ 	]+f41c80d3[ 	]+fli\.h[ 		]+ft1,0x1p\+4
+[ 	]+[0-9a-f]+:[ 	]+f41d00d3[ 	]+fli\.h[ 		]+ft1,0x1p\+7
+[ 	]+[0-9a-f]+:[ 	]+f41d80d3[ 	]+fli\.h[ 		]+ft1,0x1p\+8
+[ 	]+[0-9a-f]+:[ 	]+f41e00d3[ 	]+fli\.h[ 		]+ft1,0x1p\+15
+[ 	]+[0-9a-f]+:[ 	]+f41e80d3[ 	]+fli\.h[ 		]+ft1,0x1p\+16
+[ 	]+[0-9a-f]+:[ 	]+f41f00d3[ 	]+fli\.h[ 		]+ft1,inf
+[ 	]+[0-9a-f]+:[ 	]+f41f80d3[ 	]+fli\.h[ 		]+ft1,nan
+[ 	]+[0-9a-f]+:[ 	]+2c3100d3[ 	]+fmin\.h[ 		]+ft1,ft2,ft3
+[ 	]+[0-9a-f]+:[ 	]+2c3120d3[ 	]+fminm\.h[ 		]+ft1,ft2,ft3
+[ 	]+[0-9a-f]+:[ 	]+283100d3[ 	]+fmin\.s[ 		]+ft1,ft2,ft3
+[ 	]+[0-9a-f]+:[ 	]+283120d3[ 	]+fminm\.s[ 		]+ft1,ft2,ft3
+[ 	]+[0-9a-f]+:[ 	]+2a3100d3[ 	]+fmin\.d[ 		]+ft1,ft2,ft3
+[ 	]+[0-9a-f]+:[ 	]+2a3120d3[ 	]+fminm\.d[ 		]+ft1,ft2,ft3
+[ 	]+[0-9a-f]+:[ 	]+2e3100d3[ 	]+fmin\.q[ 		]+ft1,ft2,ft3
+[ 	]+[0-9a-f]+:[ 	]+2e3120d3[ 	]+fminm\.q[ 		]+ft1,ft2,ft3
+[ 	]+[0-9a-f]+:[ 	]+2c3110d3[ 	]+fmax\.h[ 		]+ft1,ft2,ft3
+[ 	]+[0-9a-f]+:[ 	]+2c3130d3[ 	]+fmaxm\.h[ 		]+ft1,ft2,ft3
+[ 	]+[0-9a-f]+:[ 	]+283110d3[ 	]+fmax\.s[ 		]+ft1,ft2,ft3
+[ 	]+[0-9a-f]+:[ 	]+283130d3[ 	]+fmaxm\.s[ 		]+ft1,ft2,ft3
+[ 	]+[0-9a-f]+:[ 	]+2a3110d3[ 	]+fmax\.d[ 		]+ft1,ft2,ft3
+[ 	]+[0-9a-f]+:[ 	]+2a3130d3[ 	]+fmaxm\.d[ 		]+ft1,ft2,ft3
+[ 	]+[0-9a-f]+:[ 	]+2e3110d3[ 	]+fmax\.q[ 		]+ft1,ft2,ft3
+[ 	]+[0-9a-f]+:[ 	]+2e3130d3[ 	]+fmaxm\.q[ 		]+ft1,ft2,ft3
+[ 	]+[0-9a-f]+:[ 	]+4445f553[ 	]+fround\.h[ 		]+fa0,fa1
+[ 	]+[0-9a-f]+:[ 	]+44459553[ 	]+fround\.h[ 		]+fa0,fa1,rtz
+[ 	]+[0-9a-f]+:[ 	]+4045f553[ 	]+fround\.s[ 		]+fa0,fa1
+[ 	]+[0-9a-f]+:[ 	]+40459553[ 	]+fround\.s[ 		]+fa0,fa1,rtz
+[ 	]+[0-9a-f]+:[ 	]+4245f553[ 	]+fround\.d[ 		]+fa0,fa1
+[ 	]+[0-9a-f]+:[ 	]+42459553[ 	]+fround\.d[ 		]+fa0,fa1,rtz
+[ 	]+[0-9a-f]+:[ 	]+4645f553[ 	]+fround\.q[ 		]+fa0,fa1
+[ 	]+[0-9a-f]+:[ 	]+46459553[ 	]+fround\.q[ 		]+fa0,fa1,rtz
+[ 	]+[0-9a-f]+:[ 	]+4455f553[ 	]+froundnx\.h[ 		]+fa0,fa1
+[ 	]+[0-9a-f]+:[ 	]+44559553[ 	]+froundnx\.h[ 		]+fa0,fa1,rtz
+[ 	]+[0-9a-f]+:[ 	]+4055f553[ 	]+froundnx\.s[ 		]+fa0,fa1
+[ 	]+[0-9a-f]+:[ 	]+40559553[ 	]+froundnx\.s[ 		]+fa0,fa1,rtz
+[ 	]+[0-9a-f]+:[ 	]+4255f553[ 	]+froundnx\.d[ 		]+fa0,fa1
+[ 	]+[0-9a-f]+:[ 	]+42559553[ 	]+froundnx\.d[ 		]+fa0,fa1,rtz
+[ 	]+[0-9a-f]+:[ 	]+4655f553[ 	]+froundnx\.q[ 		]+fa0,fa1
+[ 	]+[0-9a-f]+:[ 	]+46559553[ 	]+froundnx\.q[ 		]+fa0,fa1,rtz
+[ 	]+[0-9a-f]+:[ 	]+c2809553[ 	]+fcvtmod\.w\.d[ 	]+a0,ft1,rtz
+[ 	]+[0-9a-f]+:[ 	]+a4209553[ 	]+flt\.h[ 		]+a0,ft1,ft2
+[ 	]+[0-9a-f]+:[ 	]+a420d553[ 	]+fltq\.h[ 		]+a0,ft1,ft2
+[ 	]+[0-9a-f]+:[ 	]+a0209553[ 	]+flt\.s[ 		]+a0,ft1,ft2
+[ 	]+[0-9a-f]+:[ 	]+a020d553[ 	]+fltq\.s[ 		]+a0,ft1,ft2
+[ 	]+[0-9a-f]+:[ 	]+a2209553[ 	]+flt\.d[ 		]+a0,ft1,ft2
+[ 	]+[0-9a-f]+:[ 	]+a220d553[ 	]+fltq\.d[ 		]+a0,ft1,ft2
+[ 	]+[0-9a-f]+:[ 	]+a6209553[ 	]+flt\.q[ 		]+a0,ft1,ft2
+[ 	]+[0-9a-f]+:[ 	]+a620d553[ 	]+fltq\.q[ 		]+a0,ft1,ft2
+[ 	]+[0-9a-f]+:[ 	]+a4208553[ 	]+fle\.h[ 		]+a0,ft1,ft2
+[ 	]+[0-9a-f]+:[ 	]+a420c553[ 	]+fleq\.h[ 		]+a0,ft1,ft2
+[ 	]+[0-9a-f]+:[ 	]+a0208553[ 	]+fle\.s[ 		]+a0,ft1,ft2
+[ 	]+[0-9a-f]+:[ 	]+a020c553[ 	]+fleq\.s[ 		]+a0,ft1,ft2
+[ 	]+[0-9a-f]+:[ 	]+a2208553[ 	]+fle\.d[ 		]+a0,ft1,ft2
+[ 	]+[0-9a-f]+:[ 	]+a220c553[ 	]+fleq\.d[ 		]+a0,ft1,ft2
+[ 	]+[0-9a-f]+:[ 	]+a6208553[ 	]+fle\.q[ 		]+a0,ft1,ft2
+[ 	]+[0-9a-f]+:[ 	]+a620c553[ 	]+fleq\.q[ 		]+a0,ft1,ft2
diff --git a/gas/testsuite/gas/riscv/zfa.s b/gas/testsuite/gas/riscv/zfa.s
new file mode 100644
index 00000000000..7fbcb17b611
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zfa.s
@@ -0,0 +1,87 @@
+target:
+	# fli
+	fli.s		ft1, -1
+	fli.s		ft1, min
+	fli.s		ft1, 0.0000152587890625
+	fli.s		ft1, 0x1p-15
+	fli.s		ft1, 0.00390625
+	fli.s		ft1, 0x1p-7
+	fli.s		ft1, 0.0625
+	fli.s		ft1, 0x1p-3
+	fli.d		ft1, 0.25
+	fli.d		ft1, 0x1.4p-2
+	fli.d		ft1, 0.375
+	fli.d		ft1, 0x1.cp-2
+	fli.d		ft1, 0.5
+	fli.d		ft1, 0x1.4p-1
+	fli.d		ft1, 0.75
+	fli.d		ft1, 0x1.cp-1
+	fli.q		ft1, 1
+	fli.q		ft1, 0x1.4p+0
+	fli.q		ft1, 1.5
+	fli.q		ft1, 0x1.cp0
+	fli.q		ft1, 2.0
+	fli.q		ft1, 0x1.4p+1
+	fli.q		ft1, 3
+	fli.q		ft1, 0x1p2
+	fli.h		ft1, 8.0
+	fli.h		ft1, 0x1p4
+	fli.h		ft1, 128.0
+	fli.h		ft1, 0x1p8
+	fli.h		ft1, 32768.0
+	fli.h		ft1, 0x1p16
+	fli.h		ft1, inf
+	fli.h		ft1, nan
+	# fminm/fmaxm
+	fmin.h		ft1, ft2, ft3
+	fminm.h		ft1, ft2, ft3
+	fmin.s		ft1, ft2, ft3
+	fminm.s		ft1, ft2, ft3
+	fmin.d		ft1, ft2, ft3
+	fminm.d		ft1, ft2, ft3
+	fmin.q		ft1, ft2, ft3
+	fminm.q		ft1, ft2, ft3
+	fmax.h		ft1, ft2, ft3
+	fmaxm.h		ft1, ft2, ft3
+	fmax.s		ft1, ft2, ft3
+	fmaxm.s		ft1, ft2, ft3
+	fmax.d		ft1, ft2, ft3
+	fmaxm.d		ft1, ft2, ft3
+	fmax.q		ft1, ft2, ft3
+	fmaxm.q		ft1, ft2, ft3
+	# fround/froundnx
+	fround.h	fa0, fa1
+	fround.h	fa0, fa1, rtz
+	fround.s	fa0, fa1
+	fround.s	fa0, fa1, rtz
+	fround.d	fa0, fa1
+	fround.d	fa0, fa1, rtz
+	fround.q	fa0, fa1
+	fround.q	fa0, fa1, rtz
+	froundnx.h	fa0, fa1
+	froundnx.h	fa0, fa1, rtz
+	froundnx.s	fa0, fa1
+	froundnx.s	fa0, fa1, rtz
+	froundnx.d	fa0, fa1
+	froundnx.d	fa0, fa1, rtz
+	froundnx.q	fa0, fa1
+	froundnx.q	fa0, fa1, rtz
+	# fcvtmod.w.d
+	fcvtmod.w.d	a0, ft1, rtz
+	# fltq/fleq
+	flt.h		a0, ft1, ft2
+	fltq.h		a0, ft1, ft2
+	flt.s		a0, ft1, ft2
+	fltq.s		a0, ft1, ft2
+	flt.d		a0, ft1, ft2
+	fltq.d		a0, ft1, ft2
+	flt.q		a0, ft1, ft2
+	fltq.q		a0, ft1, ft2
+	fle.h		a0, ft1, ft2
+	fleq.h		a0, ft1, ft2
+	fle.s		a0, ft1, ft2
+	fleq.s		a0, ft1, ft2
+	fle.d		a0, ft1, ft2
+	fleq.d		a0, ft1, ft2
+	fle.q		a0, ft1, ft2
+	fleq.q		a0, ft1, ft2
diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
index 85d35c1efc9..e141c377bde 100644
--- a/include/opcode/riscv-opc.h
+++ b/include/opcode/riscv-opc.h
@@ -419,6 +419,72 @@
 #define MASK_FCVT_Q_L  0xfff0007f
 #define MATCH_FCVT_Q_LU 0xd6300053
 #define MASK_FCVT_Q_LU  0xfff0007f
+#define MATCH_FLI_H 0xf4100053
+#define MASK_FLI_H 0xfff0707f
+#define MATCH_FMINM_H 0x2c002053
+#define MASK_FMINM_H 0xfe00707f
+#define MATCH_FMAXM_H 0x2c003053
+#define MASK_FMAXM_H 0xfe00707f
+#define MATCH_FROUND_H 0x44400053
+#define MASK_FROUND_H 0xfff0007f
+#define MATCH_FROUNDNX_H 0x44500053
+#define MASK_FROUNDNX_H 0xfff0007f
+#define MATCH_FLTQ_H 0xa4005053
+#define MASK_FLTQ_H 0xfe00707f
+#define MATCH_FLEQ_H 0xa4004053
+#define MASK_FLEQ_H 0xfe00707f
+#define MATCH_FLI_S 0xf0100053
+#define MASK_FLI_S 0xfff0707f
+#define MATCH_FMINM_S 0x28002053
+#define MASK_FMINM_S 0xfe00707f
+#define MATCH_FMAXM_S 0x28003053
+#define MASK_FMAXM_S 0xfe00707f
+#define MATCH_FROUND_S 0x40400053
+#define MASK_FROUND_S 0xfff0007f
+#define MATCH_FROUNDNX_S 0x40500053
+#define MASK_FROUNDNX_S 0xfff0007f
+#define MATCH_FLTQ_S 0xa0005053
+#define MASK_FLTQ_S 0xfe00707f
+#define MATCH_FLEQ_S 0xa0004053
+#define MASK_FLEQ_S 0xfe00707f
+#define MATCH_FLI_D 0xf2100053
+#define MASK_FLI_D 0xfff0707f
+#define MATCH_FMINM_D 0x2a002053
+#define MASK_FMINM_D 0xfe00707f
+#define MATCH_FMAXM_D 0x2a003053
+#define MASK_FMAXM_D 0xfe00707f
+#define MATCH_FROUND_D 0x42400053
+#define MASK_FROUND_D 0xfff0007f
+#define MATCH_FROUNDNX_D 0x42500053
+#define MASK_FROUNDNX_D 0xfff0007f
+#define MATCH_FLTQ_D 0xa2005053
+#define MASK_FLTQ_D 0xfe00707f
+#define MATCH_FLEQ_D 0xa2004053
+#define MASK_FLEQ_D 0xfe00707f
+#define MATCH_FLI_Q 0xf6100053
+#define MASK_FLI_Q 0xfff0707f
+#define MATCH_FMINM_Q 0x2e002053
+#define MASK_FMINM_Q 0xfe00707f
+#define MATCH_FMAXM_Q 0x2e003053
+#define MASK_FMAXM_Q 0xfe00707f
+#define MATCH_FROUND_Q 0x46400053
+#define MASK_FROUND_Q 0xfff0007f
+#define MATCH_FROUNDNX_Q 0x46500053
+#define MASK_FROUNDNX_Q 0xfff0007f
+#define MATCH_FLTQ_Q 0xa6005053
+#define MASK_FLTQ_Q 0xfe00707f
+#define MATCH_FLEQ_Q 0xa6004053
+#define MASK_FLEQ_Q 0xfe00707f
+#define MATCH_FCVTMOD_W_D 0xc2801053
+#define MASK_FCVTMOD_W_D 0xfff0707f
+#define MATCH_FMVH_X_D 0xe2100053
+#define MASK_FMVH_X_D 0xfff0707f
+#define MATCH_FMVH_X_Q 0xe6100053
+#define MASK_FMVH_X_Q 0xfff0707f
+#define MATCH_FMVP_D_X 0xb2000053
+#define MASK_FMVP_D_X 0xfe00707f
+#define MATCH_FMVP_Q_X 0xb6000053
+#define MASK_FMVP_Q_X 0xfe00707f
 #define MATCH_CLZ 0x60001013
 #define MASK_CLZ  0xfff0707f
 #define MATCH_CTZ 0x60101013
@@ -2981,6 +3047,39 @@ DECLARE_INSN(fcvt_q_w, MATCH_FCVT_Q_W, MASK_FCVT_Q_W)
 DECLARE_INSN(fcvt_q_wu, MATCH_FCVT_Q_WU, MASK_FCVT_Q_WU)
 DECLARE_INSN(fcvt_q_l, MATCH_FCVT_Q_L, MASK_FCVT_Q_L)
 DECLARE_INSN(fcvt_q_lu, MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU)
+DECLARE_INSN(fli_h, MATCH_FLI_H, MASK_FLI_H)
+DECLARE_INSN(fminm_h, MATCH_FMINM_H, MASK_FMINM_H)
+DECLARE_INSN(fmaxm_h, MATCH_FMAXM_H, MASK_FMAXM_H)
+DECLARE_INSN(fround_h, MATCH_FROUND_H, MASK_FROUND_H)
+DECLARE_INSN(fround_nx_h, MATCH_FROUNDNX_H, MASK_FROUNDNX_H)
+DECLARE_INSN(fltq_h, MATCH_FLTQ_H, MASK_FLTQ_H)
+DECLARE_INSN(fleq_h, MATCH_FLEQ_H, MASK_FLEQ_H)
+DECLARE_INSN(fli_s, MATCH_FLI_S, MASK_FLI_S)
+DECLARE_INSN(fminm_s, MATCH_FMINM_S, MASK_FMINM_S)
+DECLARE_INSN(fmaxm_s, MATCH_FMAXM_S, MASK_FMAXM_S)
+DECLARE_INSN(fround_s, MATCH_FROUND_S, MASK_FROUND_S)
+DECLARE_INSN(fround_nx_s, MATCH_FROUNDNX_S, MASK_FROUNDNX_S)
+DECLARE_INSN(fltq_s, MATCH_FLTQ_S, MASK_FLTQ_S)
+DECLARE_INSN(fleq_s, MATCH_FLEQ_S, MASK_FLEQ_S)
+DECLARE_INSN(fli_d, MATCH_FLI_D, MASK_FLI_D)
+DECLARE_INSN(fminm_d, MATCH_FMINM_D, MASK_FMINM_D)
+DECLARE_INSN(fmaxm_d, MATCH_FMAXM_D, MASK_FMAXM_D)
+DECLARE_INSN(fround_d, MATCH_FROUND_D, MASK_FROUND_D)
+DECLARE_INSN(fround_nx_d, MATCH_FROUNDNX_D, MASK_FROUNDNX_D)
+DECLARE_INSN(fltq_d, MATCH_FLTQ_D, MASK_FLTQ_D)
+DECLARE_INSN(fleq_d, MATCH_FLEQ_D, MASK_FLEQ_D)
+DECLARE_INSN(fli_q, MATCH_FLI_Q, MASK_FLI_Q)
+DECLARE_INSN(fminm_q, MATCH_FMINM_Q, MASK_FMINM_Q)
+DECLARE_INSN(fmaxm_q, MATCH_FMAXM_Q, MASK_FMAXM_Q)
+DECLARE_INSN(fround_q, MATCH_FROUND_Q, MASK_FROUND_Q)
+DECLARE_INSN(fround_nx_q, MATCH_FROUNDNX_Q, MASK_FROUNDNX_Q)
+DECLARE_INSN(fltq_q, MATCH_FLTQ_Q, MASK_FLTQ_Q)
+DECLARE_INSN(fleq_q, MATCH_FLEQ_Q, MASK_FLEQ_Q)
+DECLARE_INSN(fcvtmod_w_d, MATCH_FCVTMOD_W_D, MASK_FCVTMOD_W_D)
+DECLARE_INSN(fmvh_x_d, MATCH_FMVH_X_D, MASK_FMVH_X_D)
+DECLARE_INSN(fmvh_x_q, MATCH_FMVH_X_Q, MASK_FMVH_X_Q)
+DECLARE_INSN(fmvp_d_x, MATCH_FMVP_D_X, MASK_FMVP_D_X)
+DECLARE_INSN(fmvp_q_x, MATCH_FMVP_Q_X, MASK_FMVP_Q_X)
 DECLARE_INSN(clz, MATCH_CLZ, MASK_CLZ)
 DECLARE_INSN(ctz, MATCH_CTZ, MASK_CTZ)
 DECLARE_INSN(cpop, MATCH_CPOP, MASK_CPOP)
diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
index b4ae55249bb..accdf7db698 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -388,6 +388,10 @@ enum riscv_insn_class
   INSN_CLASS_ZFHMIN_INX,
   INSN_CLASS_ZFHMIN_AND_D_INX,
   INSN_CLASS_ZFHMIN_AND_Q_INX,
+  INSN_CLASS_ZFA,
+  INSN_CLASS_D_AND_ZFA,
+  INSN_CLASS_Q_AND_ZFA,
+  INSN_CLASS_ZFH_AND_ZFA,
   INSN_CLASS_ZBA,
   INSN_CLASS_ZBB,
   INSN_CLASS_ZBC,
@@ -554,6 +558,8 @@ extern const char * const riscv_vsew[8];
 extern const char * const riscv_vlmul[8];
 extern const char * const riscv_vta[2];
 extern const char * const riscv_vma[2];
+extern const char * const riscv_fli_symval[32];
+extern const float riscv_fli_numval[32];
 
 extern const struct riscv_opcode riscv_opcodes[];
 extern const struct riscv_opcode riscv_insn_types[];
diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index 3aaa45f419c..65ea6339c9a 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -592,6 +592,21 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
 		    goto undefined_modifier;
 		  }
 		  break;
+	      case 'f':
+		switch (*++oparg)
+		  {
+		  case 'v':
+		    if (riscv_fli_symval[rs1])
+		      print (info->stream, dis_style_text, "%s",
+			     riscv_fli_symval[rs1]);
+		    else
+		      print (info->stream, dis_style_immediate, "%a",
+			     riscv_fli_numval[rs1]);
+		    break;
+		  default:
+		    goto undefined_modifier;
+		  }
+		break;
 	      default:
 		goto undefined_modifier;
 	      }
@@ -640,6 +655,7 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
 	      }
 	  }
 	  break;
+
 	default:
 	undefined_modifier:
 	  /* xgettext:c-format */
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index d9d69cda548..4b970db9bcf 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -110,6 +110,27 @@ const char * const riscv_vma[2] =
   "mu", "ma"
 };
 
+/* The FLI.[HSDQ] symbolic constants (NULL for numeric constant).  */
+const char * const riscv_fli_symval[32] =
+{
+  NULL,  "min", NULL,  NULL,  NULL,  NULL,  NULL,  NULL,
+  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,
+  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,
+  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  "inf", "nan",
+};
+
+/* The FLI.[HSDQ] numeric constants (0.0 for symbolic constants).
+   The constants use the hex floating-point literal representation
+   that is printed when using the printf %a format specifier,
+   which matches the output that is generated by the disassembler.  */
+const float riscv_fli_numval[32] =
+{
+  -0x1p+0, 0x0p+0, 0x1p-16, 0x1p-15, 0x1p-8, 0x1p-7, 0x1p-4, 0x1p-3,
+  0x1p-2, 0x1.4p-2, 0x1.8p-2, 0x1.cp-2, 0x1p-1, 0x1.4p-1, 0x1.8p-1, 0x1.cp-1,
+  0x1p+0, 0x1.4p+0, 0x1.8p+0, 0x1.cp+0, 0x1p+1, 0x1.4p+1, 0x1.8p+1, 0x1p+2,
+  0x1p+3, 0x1p+4, 0x1p+7, 0x1p+8, 0x1p+15, 0x1p+16, 0x0p+0, 0x0p+0
+};
+
 /* The order of overloaded instructions matters.  Label arguments and
    register arguments look the same. Instructions that can have either
    for arguments must apear in the correct order in this table for the
@@ -939,6 +960,49 @@ 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 },
 
+/* 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 },
+{"fli.q",       0, INSN_CLASS_Q_AND_ZFA,   "D,Wfv", MATCH_FLI_Q, MASK_FLI_Q, match_opcode, 0 },
+{"fli.h",       0, INSN_CLASS_ZFH_AND_ZFA, "D,Wfv", MATCH_FLI_H, MASK_FLI_H, match_opcode, 0 },
+{"fminm.s",     0, INSN_CLASS_ZFA,         "D,S,T", MATCH_FMINM_S, MASK_FMINM_S, match_opcode, 0 },
+{"fmaxm.s",     0, INSN_CLASS_ZFA,         "D,S,T", MATCH_FMAXM_S, MASK_FMAXM_S, match_opcode, 0 },
+{"fminm.d",     0, INSN_CLASS_D_AND_ZFA,   "D,S,T", MATCH_FMINM_D, MASK_FMINM_D, match_opcode, 0 },
+{"fmaxm.d",     0, INSN_CLASS_D_AND_ZFA,   "D,S,T", MATCH_FMAXM_D, MASK_FMAXM_D, match_opcode, 0 },
+{"fminm.q",     0, INSN_CLASS_Q_AND_ZFA,   "D,S,T", MATCH_FMINM_Q, MASK_FMINM_Q, match_opcode, 0 },
+{"fmaxm.q",     0, INSN_CLASS_Q_AND_ZFA,   "D,S,T", MATCH_FMAXM_Q, MASK_FMAXM_Q, match_opcode, 0 },
+{"fminm.h",     0, INSN_CLASS_ZFH_AND_ZFA, "D,S,T", MATCH_FMINM_H, MASK_FMINM_H, match_opcode, 0 },
+{"fmaxm.h",     0, INSN_CLASS_ZFH_AND_ZFA, "D,S,T", MATCH_FMAXM_H, MASK_FMAXM_H, match_opcode, 0 },
+{"fround.s",    0, INSN_CLASS_ZFA,         "D,S",   MATCH_FROUND_S|MASK_RM, MASK_FROUND_S|MASK_RM, match_opcode, 0 },
+{"fround.s",    0, INSN_CLASS_ZFA,         "D,S,m", MATCH_FROUND_S, MASK_FROUND_S, match_opcode, 0 },
+{"froundnx.s",  0, INSN_CLASS_ZFA,         "D,S",   MATCH_FROUNDNX_S|MASK_RM, MASK_FROUNDNX_S|MASK_RM, match_opcode, 0 },
+{"froundnx.s",  0, INSN_CLASS_ZFA,         "D,S,m", MATCH_FROUNDNX_S, MASK_FROUNDNX_S, match_opcode, 0 },
+{"fround.d",    0, INSN_CLASS_D_AND_ZFA,   "D,S",   MATCH_FROUND_D|MASK_RM, MASK_FROUND_D|MASK_RM, match_opcode, 0 },
+{"fround.d",    0, INSN_CLASS_D_AND_ZFA,   "D,S,m", MATCH_FROUND_D, MASK_FROUND_D, match_opcode, 0 },
+{"froundnx.d",  0, INSN_CLASS_D_AND_ZFA,   "D,S",   MATCH_FROUNDNX_D|MASK_RM, MASK_FROUNDNX_D|MASK_RM, match_opcode, 0 },
+{"froundnx.d",  0, INSN_CLASS_D_AND_ZFA,   "D,S,m", MATCH_FROUNDNX_D, MASK_FROUNDNX_D, match_opcode, 0 },
+{"fround.q",    0, INSN_CLASS_Q_AND_ZFA,   "D,S",   MATCH_FROUND_Q|MASK_RM, MASK_FROUND_Q|MASK_RM, match_opcode, 0 },
+{"fround.q",    0, INSN_CLASS_Q_AND_ZFA,   "D,S,m", MATCH_FROUND_Q, MASK_FROUND_Q, match_opcode, 0 },
+{"froundnx.q",  0, INSN_CLASS_Q_AND_ZFA,   "D,S",   MATCH_FROUNDNX_Q|MASK_RM, MASK_FROUNDNX_Q|MASK_RM, match_opcode, 0 },
+{"froundnx.q",  0, INSN_CLASS_Q_AND_ZFA,   "D,S,m", MATCH_FROUNDNX_Q, MASK_FROUNDNX_Q, match_opcode, 0 },
+{"fround.h",    0, INSN_CLASS_ZFH_AND_ZFA, "D,S",   MATCH_FROUND_H|MASK_RM, MASK_FROUND_H|MASK_RM, match_opcode, 0 },
+{"fround.h",    0, INSN_CLASS_ZFH_AND_ZFA, "D,S,m", MATCH_FROUND_H, MASK_FROUND_H, match_opcode, 0 },
+{"froundnx.h",  0, INSN_CLASS_ZFH_AND_ZFA, "D,S",   MATCH_FROUNDNX_H|MASK_RM, MASK_FROUNDNX_H|MASK_RM, match_opcode, 0 },
+{"froundnx.h",  0, INSN_CLASS_ZFH_AND_ZFA, "D,S,m", MATCH_FROUNDNX_H, MASK_FROUNDNX_H, match_opcode, 0 },
+{"fcvtmod.w.d", 0, INSN_CLASS_D_AND_ZFA,   "d,S,m", MATCH_FCVTMOD_W_D, MASK_FCVTMOD_W_D, match_opcode, 0 },
+{"fmvh.x.d",   32, INSN_CLASS_D_AND_ZFA,   "d,S",   MATCH_FMVH_X_D, MASK_FMVH_X_D, match_opcode, 0 },
+{"fmvp.d.x",   32, INSN_CLASS_D_AND_ZFA,   "D,s,t", MATCH_FMVP_D_X, MASK_FMVP_D_X, match_opcode, 0 },
+{"fmvh.x.q",   64, INSN_CLASS_Q_AND_ZFA,   "d,S",   MATCH_FMVH_X_Q, MASK_FMVH_X_Q, match_opcode, 0 },
+{"fmvp.q.x",   64, INSN_CLASS_Q_AND_ZFA,   "D,s,t", MATCH_FMVP_Q_X, MASK_FMVP_Q_X, match_opcode, 0 },
+{"fltq.s",      0, INSN_CLASS_ZFA,         "d,S,T", MATCH_FLTQ_S, MASK_FLTQ_S, match_opcode, 0 },
+{"fleq.s",      0, INSN_CLASS_ZFA,         "d,S,T", MATCH_FLEQ_S, MASK_FLEQ_S, match_opcode, 0 },
+{"fltq.d",      0, INSN_CLASS_D_AND_ZFA,   "d,S,T", MATCH_FLTQ_D, MASK_FLTQ_D, match_opcode, 0 },
+{"fleq.d",      0, INSN_CLASS_D_AND_ZFA,   "d,S,T", MATCH_FLEQ_D, MASK_FLEQ_D, match_opcode, 0 },
+{"fltq.q",      0, INSN_CLASS_Q_AND_ZFA,   "d,S,T", MATCH_FLTQ_Q, MASK_FLTQ_Q, match_opcode, 0 },
+{"fleq.q",      0, INSN_CLASS_Q_AND_ZFA,   "d,S,T", MATCH_FLEQ_Q, MASK_FLEQ_Q, match_opcode, 0 },
+{"fltq.h",      0, INSN_CLASS_ZFH_AND_ZFA, "d,S,T", MATCH_FLTQ_H, MASK_FLTQ_H, match_opcode, 0 },
+{"fleq.h",      0, INSN_CLASS_ZFH_AND_ZFA, "d,S,T", MATCH_FLEQ_H, MASK_FLEQ_H, match_opcode, 0 },
+
 /* Zbb or zbkb instructions.  */
 {"clz",        0, INSN_CLASS_ZBB,  "d,s",   MATCH_CLZ, MASK_CLZ, match_opcode, 0 },
 {"ctz",        0, INSN_CLASS_ZBB,  "d,s",   MATCH_CTZ, MASK_CTZ, match_opcode, 0 },
-- 
2.39.2


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC PATCH v5] RISC-V: Add support for the Zfa extension
  2023-04-13 13:36 [RFC PATCH v5] RISC-V: Add support for the Zfa extension Christoph Muellner
@ 2023-06-29  7:52 ` Christoph Müllner
  2023-06-29  8:33   ` Christoph Müllner
  2023-06-29 15:07   ` Jeff Law
  0 siblings, 2 replies; 19+ messages in thread
From: Christoph Müllner @ 2023-06-29  7:52 UTC (permalink / raw)
  To: binutils, Nelson Chu, Andrew Waterman, Palmer Dabbelt,
	Jim Wilson, Philipp Tomsich, Jan Beulich, Kito Cheng, Jeff Law,
	Tsukasa OI

The RISC-V Zfa extension has been frozen.

As this was discussed elsewhere yesterday:
* Should this patch wait for ratification?
* Is this blocked by https://github.com/riscv-non-isa/riscv-asm-manual/pull/85 ?

Nelson stated on Apr 12 (response to v4):
"If there are no new instructions or encodings/formats changed in the
future spec, then you should commit the patch when the extension is
ratified."

So my understanding is that this needs to wait for ratification and is
not blocked by the mentioned PR.

BR
Christoph



On Thu, Apr 13, 2023 at 3:37 PM Christoph Muellner
<christoph.muellner@vrull.eu> wrote:
>
> From: Christoph Müllner <christoph.muellner@vrull.eu>
>
> This patch adds support for the RISC-V Zfa extension,
> which introduces additional floating-point instructions:
> * fli (load-immediate) with pre-defined immediates
> * fminm/fmaxm (like fmin/fmax but with different NaN behaviour)
> * fround/froundmx (round to integer)
> * fcvtmod.w.d (Modular Convert-to-Integer)
> * fmv* to access high bits of FP registers in case XLEN < FLEN
> * fleq/fltq (quiet comparison instructions)
>
> Zfa defines its instructions in combination with the following
> extensions:
> * single-precision floating-point (F)
> * double-precision floating-point (D)
> * quad-precision floating-point (Q)
> * half-precision floating-point (Zfh)
>
> This patch is based on an earlier version from Tsukasa OI:
>   https://sourceware.org/pipermail/binutils/2022-September/122939.html
> Most significant change to that commit is the switch from the rs1-field
> value to the actual floating-point value in the last operand of the fli*
> instructions. Everything that strtof() can parse is accepted and
> the '%a' printf specifier is used to output hex floating-point literals
> in the disassembly.
>
> The Zfa specification is not frozen at the moment (which is why this
> patch is RFC) and can be found here:
>   https://github.com/riscv/riscv-isa-manual/blob/master/src/zfa.tex
>
> bfd/ChangeLog:
>
>         * elfxx-riscv.c (riscv_multi_subset_supports): Add instruction
>         class support for 'Zfa' extension.
>         (riscv_multi_subset_supports_ext): Likewise.
>         (riscv_implicit_subsets): Add 'Zfa' -> 'F' dependency.
>
> gas/ChangeLog:
>
>         * config/tc-riscv.c (flt_lookup): New helper to lookup a float value
>         in an array.
>         (validate_riscv_insn): Add 'Wfv' as new format string directive.
>         (riscv_ip): Likewise.
>         * doc/c-riscv.texi: Add floating-point chapter and describe
>         limiations of the Zfa FP literal parsing.
>         * testsuite/gas/riscv/zfa-32.d: New test.
>         * testsuite/gas/riscv/zfa-32.s: New test.
>         * testsuite/gas/riscv/zfa-64.d: New test.
>         * testsuite/gas/riscv/zfa-64.s: New test.
>         * testsuite/gas/riscv/zfa-fail.d: New test.
>         * testsuite/gas/riscv/zfa-fail.l: New test.
>         * testsuite/gas/riscv/zfa-fail.s: New test.
>         * testsuite/gas/riscv/zfa.d: New test.
>         * testsuite/gas/riscv/zfa.s: New test.
>         * testsuite/gas/riscv/zfa.s: New test.
>
>         * opcode/riscv-opc.h (MATCH_FLI_H): New.
>         (MASK_FLI_H): New.
>         (MATCH_FMINM_H): New.
>         (MASK_FMINM_H): New.
>         (MATCH_FMAXM_H): New.
>         (MASK_FMAXM_H): New.
>         (MATCH_FROUND_H): New.
>         (MASK_FROUND_H): New.
>         (MATCH_FROUNDNX_H): New.
>         (MASK_FROUNDNX_H): New.
>         (MATCH_FLTQ_H): New.
>         (MASK_FLTQ_H): New.
>         (MATCH_FLEQ_H): New.
>         (MASK_FLEQ_H): New.
>         (MATCH_FLI_S): New.
>         (MASK_FLI_S): New.
>         (MATCH_FMINM_S): New.
>         (MASK_FMINM_S): New.
>         (MATCH_FMAXM_S): New.
>         (MASK_FMAXM_S): New.
>         (MATCH_FROUND_S): New.
>         (MASK_FROUND_S): New.
>         (MATCH_FROUNDNX_S): New.
>         (MASK_FROUNDNX_S): New.
>         (MATCH_FLTQ_S): New.
>         (MASK_FLTQ_S): New.
>         (MATCH_FLEQ_S): New.
>         (MASK_FLEQ_S): New.
>         (MATCH_FLI_D): New.
>         (MASK_FLI_D): New.
>         (MATCH_FMINM_D): New.
>         (MASK_FMINM_D): New.
>         (MATCH_FMAXM_D): New.
>         (MASK_FMAXM_D): New.
>         (MATCH_FROUND_D): New.
>         (MASK_FROUND_D): New.
>         (MATCH_FROUNDNX_D): New.
>         (MASK_FROUNDNX_D): New.
>         (MATCH_FLTQ_D): New.
>         (MASK_FLTQ_D): New.
>         (MATCH_FLEQ_D): New.
>         (MASK_FLEQ_D): New.
>         (MATCH_FLI_Q): New.
>         (MASK_FLI_Q): New.
>         (MATCH_FMINM_Q): New.
>         (MASK_FMINM_Q): New.
>         (MATCH_FMAXM_Q): New.
>         (MASK_FMAXM_Q): New.
>         (MATCH_FROUND_Q): New.
>         (MASK_FROUND_Q): New.
>         (MATCH_FROUNDNX_Q): New.
>         (MASK_FROUNDNX_Q): New.
>         (MATCH_FLTQ_Q): New.
>         (MASK_FLTQ_Q): New.
>         (MATCH_FLEQ_Q): New.
>         (MASK_FLEQ_Q): New.
>         (MATCH_FCVTMOD_W_D): New.
>         (MASK_FCVTMOD_W_D): New.
>         (MATCH_FMVH_X_D): New.
>         (MASK_FMVH_X_D): New.
>         (MATCH_FMVH_X_Q): New.
>         (MASK_FMVH_X_Q): New.
>         (MATCH_FMVP_D_X): New.
>         (MASK_FMVP_D_X): New.
>         (MATCH_FMVP_Q_X): New.
>         (MASK_FMVP_Q_X): New.
>         (DECLARE_INSN): New.
>         * opcode/riscv.h (enum riscv_insn_class): Add instruction
>         classes for the Zfa extension.
>
> opcodes/ChangeLog:
>
>         * riscv-dis.c (print_insn_args): Add support for
>         new format string directive 'Wfv'.
>         * riscv-opc.c: Add Zfa instructions.
>
> Co-Developed-by: Tsukasa OI <research_trasio@irq.a4lg.com>
> Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
> ---
> Changes in v5:
> * Fixes in texinfo directives (documentation)
> * Make FLI error message more verbose
>
>  bfd/elfxx-riscv.c                  | 39 ++++++++++++
>  gas/config/tc-riscv.c              | 52 ++++++++++++++++
>  gas/doc/c-riscv.texi               | 41 +++++++++++++
>  gas/testsuite/gas/riscv/zfa-32.d   | 10 +++
>  gas/testsuite/gas/riscv/zfa-32.s   |  3 +
>  gas/testsuite/gas/riscv/zfa-64.d   | 10 +++
>  gas/testsuite/gas/riscv/zfa-64.s   |  3 +
>  gas/testsuite/gas/riscv/zfa-fail.d |  3 +
>  gas/testsuite/gas/riscv/zfa-fail.l | 12 ++++
>  gas/testsuite/gas/riscv/zfa-fail.s | 16 +++++
>  gas/testsuite/gas/riscv/zfa.d      | 89 +++++++++++++++++++++++++++
>  gas/testsuite/gas/riscv/zfa.s      | 87 ++++++++++++++++++++++++++
>  include/opcode/riscv-opc.h         | 99 ++++++++++++++++++++++++++++++
>  include/opcode/riscv.h             |  6 ++
>  opcodes/riscv-dis.c                | 16 +++++
>  opcodes/riscv-opc.c                | 64 +++++++++++++++++++
>  16 files changed, 550 insertions(+)
>  create mode 100644 gas/testsuite/gas/riscv/zfa-32.d
>  create mode 100644 gas/testsuite/gas/riscv/zfa-32.s
>  create mode 100644 gas/testsuite/gas/riscv/zfa-64.d
>  create mode 100644 gas/testsuite/gas/riscv/zfa-64.s
>  create mode 100644 gas/testsuite/gas/riscv/zfa-fail.d
>  create mode 100644 gas/testsuite/gas/riscv/zfa-fail.l
>  create mode 100644 gas/testsuite/gas/riscv/zfa-fail.s
>  create mode 100644 gas/testsuite/gas/riscv/zfa.d
>  create mode 100644 gas/testsuite/gas/riscv/zfa.s
>
> diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
> index 19391d94e30..d57fe2400fd 100644
> --- a/bfd/elfxx-riscv.c
> +++ b/bfd/elfxx-riscv.c
> @@ -1078,6 +1078,7 @@ static struct riscv_implicit_subset riscv_implicit_subsets[] =
>    {"zvl256b", "zvl128b",       check_implicit_always},
>    {"zvl128b", "zvl64b",                check_implicit_always},
>    {"zvl64b", "zvl32b",         check_implicit_always},
> +  {"zfa", "f",         check_implicit_always},
>    {"d", "f",           check_implicit_always},
>    {"zfh", "zfhmin",    check_implicit_always},
>    {"zfhmin", "f",      check_implicit_always},
> @@ -1175,6 +1176,7 @@ static struct riscv_supported_ext riscv_supported_std_z_ext[] =
>    {"zihintpause",      ISA_SPEC_CLASS_DRAFT,           2, 0,  0 },
>    {"zmmul",            ISA_SPEC_CLASS_DRAFT,           1, 0,  0 },
>    {"zawrs",            ISA_SPEC_CLASS_DRAFT,           1, 0,  0 },
> +  {"zfa",              ISA_SPEC_CLASS_DRAFT,           0, 1,  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 },
> @@ -2313,6 +2315,17 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps,
>                && riscv_subset_supports (rps, "q"))
>               || (riscv_subset_supports (rps, "zhinxmin")
>                   && riscv_subset_supports (rps, "zqinx")));
> +    case INSN_CLASS_ZFA:
> +      return riscv_subset_supports (rps, "zfa");
> +    case INSN_CLASS_D_AND_ZFA:
> +      return riscv_subset_supports (rps, "d")
> +            && riscv_subset_supports (rps, "zfa");
> +    case INSN_CLASS_Q_AND_ZFA:
> +      return riscv_subset_supports (rps, "q")
> +            && riscv_subset_supports (rps, "zfa");
> +    case INSN_CLASS_ZFH_AND_ZFA:
> +      return riscv_subset_supports (rps, "zfh")
> +            && riscv_subset_supports (rps, "zfa");
>      case INSN_CLASS_ZBA:
>        return riscv_subset_supports (rps, "zba");
>      case INSN_CLASS_ZBB:
> @@ -2479,6 +2492,32 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
>         return "zhinxmin";
>        else
>         return _("zfhmin' and `q', or `zhinxmin' and `zqinx");
> +    case INSN_CLASS_ZFA:
> +      return "zfa";
> +    case INSN_CLASS_D_AND_ZFA:
> +      if (!riscv_subset_supports (rps, "d")
> +         && !riscv_subset_supports (rps, "zfa"))
> +       return _("d' and `zfa");
> +      else if (!riscv_subset_supports (rps, "d"))
> +       return "d";
> +      else
> +       return "zfa";
> +    case INSN_CLASS_Q_AND_ZFA:
> +      if (!riscv_subset_supports (rps, "q")
> +         && !riscv_subset_supports (rps, "zfa"))
> +       return _("q' and `zfa");
> +      else if (!riscv_subset_supports (rps, "q"))
> +       return "q";
> +      else
> +       return "zfa";
> +    case INSN_CLASS_ZFH_AND_ZFA:
> +      if (!riscv_subset_supports (rps, "zfh")
> +         && !riscv_subset_supports (rps, "zfa"))
> +       return _("zfh' and `zfa");
> +      else if (!riscv_subset_supports (rps, "zfh"))
> +       return "zfh";
> +      else
> +       return "zfa";
>      case INSN_CLASS_ZBA:
>        return "zba";
>      case INSN_CLASS_ZBB:
> diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
> index 4eff07a6d4a..0fcc1f26587 100644
> --- a/gas/config/tc-riscv.c
> +++ b/gas/config/tc-riscv.c
> @@ -1219,6 +1219,21 @@ arg_lookup (char **s, const char *const *array, size_t size, unsigned *regnop)
>    return false;
>  }
>
> +static bool
> +flt_lookup (float f, const float *array, size_t size, unsigned *regnop)
> +{
> +  size_t i;
> +
> +  for (i = 0; i < size; i++)
> +    if (array[i] == f)
> +      {
> +       *regnop = i;
> +       return true;
> +      }
> +
> +  return false;
> +}
> +
>  #define USE_BITS(mask,shift) (used_bits |= ((insn_t)(mask) << (shift)))
>  #define USE_IMM(n, s) \
>    (used_bits |= ((insn_t)((1ull<<n)-1) << (s)))
> @@ -1399,6 +1414,14 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
>                   goto unknown_validate_operand;
>                 }
>               break;
> +           case 'f':
> +             switch (*++oparg)
> +               {
> +               case 'v': USE_BITS (OP_MASK_RS1, OP_SH_RS1); break;
> +               default:
> +                 goto unknown_validate_operand;
> +               }
> +             break;
>             default:
>               goto unknown_validate_operand;
>             }
> @@ -3461,6 +3484,35 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
>                       goto unknown_riscv_ip_operand;
>                     }
>                   break;
> +               case 'f':
> +                 switch (*++oparg)
> +                   {
> +                   case 'v':
> +                     /* FLI.[HSDQ] value field for 'Zfa' extension.  */
> +                     if (!arg_lookup (&asarg, riscv_fli_symval,
> +                                      ARRAY_SIZE (riscv_fli_symval), &regno))
> +                       {
> +                         /* 0.0 is not a valid entry in riscv_fli_numval.  */
> +                         errno = 0;
> +                         float f = strtof (asarg, &asarg);
> +                         if (errno != 0 || f == 0.0
> +                             || !flt_lookup (f, riscv_fli_numval,
> +                                            ARRAY_SIZE(riscv_fli_numval),
> +                                            &regno))
> +                           {
> +                             as_bad (_("bad fli constant operand, "
> +                                       "supported constants must be in "
> +                                       "decimal or hexadecimal floating-point "
> +                                       "literal form"));
> +                             break;
> +                           }
> +                       }
> +                     INSERT_OPERAND (RS1, *ip, regno);
> +                     continue;
> +                   default:
> +                     goto unknown_riscv_ip_operand;
> +                   }
> +                 break;
>                 default:
>                   goto unknown_riscv_ip_operand;
>                 }
> diff --git a/gas/doc/c-riscv.texi b/gas/doc/c-riscv.texi
> index 64fff6a7973..987c01f9d1d 100644
> --- a/gas/doc/c-riscv.texi
> +++ b/gas/doc/c-riscv.texi
> @@ -18,6 +18,7 @@
>  * RISC-V-Options::        RISC-V Options
>  * RISC-V-Directives::     RISC-V Directives
>  * RISC-V-Modifiers::      RISC-V Assembler Modifiers
> +* RISC-V-Floating-Point:: RISC-V Floating Point
>  * RISC-V-Formats::        RISC-V Instruction Formats
>  * RISC-V-ATTRIBUTE::      RISC-V Object Attribute
>  * RISC-V-CustomExts::     RISC-V Custom (Vendor-Defined) Extensions
> @@ -382,6 +383,46 @@ The pseudo la.tls.gd instruction can be expended to
>
>  @end table
>
> +@node RISC-V-Floating-Point
> +@section RISC-V Floating Point
> +@cindex floating point, risc-v (@sc{ieee})
> +@cindex RISC-V floating point (@sc{ieee})
> +
> +The RISC-V architecture uses @sc{ieee} floating-point numbers.
> +
> +The RISC-V Zfa extension includes a load-immediate instruction
> +for floating-point registers, which allows specifying the immediate
> +(from a pool of 32 predefined values defined in the specification)
> +as operand.
> +E.g. to load the value @code{0.0625} as single-precision FP value into
> +the FP register @code{ft1} one of the following instructions can be used:
> +
> +       fli.s ft1, 0.0625 # dec floating-point literal
> +       fli.s ft1, 0x1p-4 # hex floating-point literal
> +       fli.s ft1, 0x0.8p-3
> +       fli.s ft1, 0x1.0p-4
> +       fli.s ft1, 0x2p-5
> +       fli.s ft1, 0x4p-6
> +       ...
> +
> +As can be seen, many valid ways exist to express a floating-point value.
> +This is realized by parsing the value operand using strtof() and
> +comparing the parsed value against built-in float-constants that
> +are written as hex floating-point literals.
> +
> +This approach works on all machines that use IEEE 754.
> +However, there is a chance that this fails on other machines
> +with the following error message:
> +
> +       Error: improper fli value operand
> +       Error: illegal operands `fli.s ft1,0.0625
> +
> +The error indicates that parsing @samp{0x1p-4} and @samp{0.0625}
> +to single-precision floating point numbers will not result
> +in two equal values on that machine.
> +
> +If you encounter this problem, then please report it.
> +
>  @node RISC-V-Formats
>  @section RISC-V Instruction Formats
>  @cindex instruction formats, risc-v
> diff --git a/gas/testsuite/gas/riscv/zfa-32.d b/gas/testsuite/gas/riscv/zfa-32.d
> new file mode 100644
> index 00000000000..48e20bf4675
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zfa-32.d
> @@ -0,0 +1,10 @@
> +#as: -march=rv32id_zfa
> +#objdump: -d
> +
> +.*:[   ]+file format .*
> +
> +Disassembly of section .text:
> +
> +0+000 <target>:
> +[      ]+[0-9a-f]+:[   ]+e2108553[     ]+fmvh\.x\.d[   ]+a0,ft1
> +[      ]+[0-9a-f]+:[   ]+b2b500d3[     ]+fmvp\.d\.x[   ]+ft1,a0,a1
> diff --git a/gas/testsuite/gas/riscv/zfa-32.s b/gas/testsuite/gas/riscv/zfa-32.s
> new file mode 100644
> index 00000000000..da95441cdc7
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zfa-32.s
> @@ -0,0 +1,3 @@
> +target:
> +       fmvh.x.d        a0, ft1
> +       fmvp.d.x        ft1, a0, a1
> diff --git a/gas/testsuite/gas/riscv/zfa-64.d b/gas/testsuite/gas/riscv/zfa-64.d
> new file mode 100644
> index 00000000000..48b6d74ed9b
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zfa-64.d
> @@ -0,0 +1,10 @@
> +#as: -march=rv64iq_zfa
> +#objdump: -d
> +
> +.*:[   ]+file format .*
> +
> +Disassembly of section .text:
> +
> +0+000 <target>:
> +[      ]+[0-9a-f]+:[   ]+e6108553[     ]+fmvh\.x\.q[   ]+a0,ft1
> +[      ]+[0-9a-f]+:[   ]+b6b500d3[     ]+fmvp\.q\.x[   ]+ft1,a0,a1
> diff --git a/gas/testsuite/gas/riscv/zfa-64.s b/gas/testsuite/gas/riscv/zfa-64.s
> new file mode 100644
> index 00000000000..dc8129dae3e
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zfa-64.s
> @@ -0,0 +1,3 @@
> +target:
> +       fmvh.x.q        a0, ft1
> +       fmvp.q.x        ft1, a0, a1
> diff --git a/gas/testsuite/gas/riscv/zfa-fail.d b/gas/testsuite/gas/riscv/zfa-fail.d
> new file mode 100644
> index 00000000000..2f0a69b247a
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zfa-fail.d
> @@ -0,0 +1,3 @@
> +#as: -march=rv64iq_zfa_zfh
> +#source: zfa-fail.s
> +#error_output: zfa-fail.l
> diff --git a/gas/testsuite/gas/riscv/zfa-fail.l b/gas/testsuite/gas/riscv/zfa-fail.l
> new file mode 100644
> index 00000000000..efe9ba00e02
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zfa-fail.l
> @@ -0,0 +1,12 @@
> +.*: Assembler messages:
> +.*: Error: bad fli constant operand, supported constants must be in decimal or hexadecimal floating-point literal form
> +.*: Error: illegal operands `fli\.s ft1,infinity'
> +.*: Error: bad fli constant operand, supported constants must be in decimal or hexadecimal floating-point literal form
> +.*: Error: illegal operands `fli\.d ft1,invalid'
> +.*: Error: illegal operands `fcvtmod\.w\.d a0,ft1'
> +.*: Error: illegal operands `fcvtmod\.w\.d a0,ft1,rne'
> +.*: Error: illegal operands `fcvtmod\.w\.d a0,ft1,rdn'
> +.*: Error: illegal operands `fcvtmod\.w\.d a0,ft1,rup'
> +.*: Error: illegal operands `fcvtmod\.w\.d a0,ft1,rmm'
> +.*: Error: illegal operands `fcvtmod\.w\.d a0,ft1,dyn'
> +.*: Error: illegal operands `fcvtmod\.w\.d a0,ft1,invalid'
> diff --git a/gas/testsuite/gas/riscv/zfa-fail.s b/gas/testsuite/gas/riscv/zfa-fail.s
> new file mode 100644
> index 00000000000..98ffe7f3268
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zfa-fail.s
> @@ -0,0 +1,16 @@
> +target:
> +       # fli.[sdqh]: Invalid value field
> +       fli.s   ft1, infinity
> +       fli.d   ft1, invalid
> +
> +       # fcvtmod.w.d: Requires explicit rounding mode.
> +       fcvtmod.w.d     a0, ft1
> +
> +       # fcvtmod.w.d: Rounding mode other than rtz are reserved.
> +       fcvtmod.w.d     a0, ft1, rne
> +       fcvtmod.w.d     a0, ft1, rdn
> +       fcvtmod.w.d     a0, ft1, rup
> +       fcvtmod.w.d     a0, ft1, rmm
> +       fcvtmod.w.d     a0, ft1, dyn
> +       # fcvtmod.w.d: Invalid rounding mode is invalid.
> +       fcvtmod.w.d     a0, ft1, invalid
> diff --git a/gas/testsuite/gas/riscv/zfa.d b/gas/testsuite/gas/riscv/zfa.d
> new file mode 100644
> index 00000000000..cbfc72e6036
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zfa.d
> @@ -0,0 +1,89 @@
> +#as: -march=rv32iq_zfa_zfh
> +#objdump: -d
> +
> +.*:[   ]+file format .*
> +
> +Disassembly of section .text:
> +
> +0+000 <target>:
> +[      ]+[0-9a-f]+:[   ]+f01000d3[     ]+fli\.s[               ]+ft1,-0x1p\+0
> +[      ]+[0-9a-f]+:[   ]+f01080d3[     ]+fli\.s[               ]+ft1,min
> +[      ]+[0-9a-f]+:[   ]+f01100d3[     ]+fli\.s[               ]+ft1,0x1p-16
> +[      ]+[0-9a-f]+:[   ]+f01180d3[     ]+fli\.s[               ]+ft1,0x1p-15
> +[      ]+[0-9a-f]+:[   ]+f01200d3[     ]+fli\.s[               ]+ft1,0x1p-8
> +[      ]+[0-9a-f]+:[   ]+f01280d3[     ]+fli\.s[               ]+ft1,0x1p-7
> +[      ]+[0-9a-f]+:[   ]+f01300d3[     ]+fli\.s[               ]+ft1,0x1p-4
> +[      ]+[0-9a-f]+:[   ]+f01380d3[     ]+fli\.s[               ]+ft1,0x1p-3
> +[      ]+[0-9a-f]+:[   ]+f21400d3[     ]+fli\.d[               ]+ft1,0x1p-2
> +[      ]+[0-9a-f]+:[   ]+f21480d3[     ]+fli\.d[               ]+ft1,0x1.4p-2
> +[      ]+[0-9a-f]+:[   ]+f21500d3[     ]+fli\.d[               ]+ft1,0x1.8p-2
> +[      ]+[0-9a-f]+:[   ]+f21580d3[     ]+fli\.d[               ]+ft1,0x1.cp-2
> +[      ]+[0-9a-f]+:[   ]+f21600d3[     ]+fli\.d[               ]+ft1,0x1p-1
> +[      ]+[0-9a-f]+:[   ]+f21680d3[     ]+fli\.d[               ]+ft1,0x1.4p-1
> +[      ]+[0-9a-f]+:[   ]+f21700d3[     ]+fli\.d[               ]+ft1,0x1.8p-1
> +[      ]+[0-9a-f]+:[   ]+f21780d3[     ]+fli\.d[               ]+ft1,0x1.cp-1
> +[      ]+[0-9a-f]+:[   ]+f61800d3[     ]+fli\.q[               ]+ft1,0x1p\+0
> +[      ]+[0-9a-f]+:[   ]+f61880d3[     ]+fli\.q[               ]+ft1,0x1.4p\+0
> +[      ]+[0-9a-f]+:[   ]+f61900d3[     ]+fli\.q[               ]+ft1,0x1.8p\+0
> +[      ]+[0-9a-f]+:[   ]+f61980d3[     ]+fli\.q[               ]+ft1,0x1.cp\+0
> +[      ]+[0-9a-f]+:[   ]+f61a00d3[     ]+fli\.q[               ]+ft1,0x1p\+1
> +[      ]+[0-9a-f]+:[   ]+f61a80d3[     ]+fli\.q[               ]+ft1,0x1.4p\+1
> +[      ]+[0-9a-f]+:[   ]+f61b00d3[     ]+fli\.q[               ]+ft1,0x1.8p\+1
> +[      ]+[0-9a-f]+:[   ]+f61b80d3[     ]+fli\.q[               ]+ft1,0x1p\+2
> +[      ]+[0-9a-f]+:[   ]+f41c00d3[     ]+fli\.h[               ]+ft1,0x1p\+3
> +[      ]+[0-9a-f]+:[   ]+f41c80d3[     ]+fli\.h[               ]+ft1,0x1p\+4
> +[      ]+[0-9a-f]+:[   ]+f41d00d3[     ]+fli\.h[               ]+ft1,0x1p\+7
> +[      ]+[0-9a-f]+:[   ]+f41d80d3[     ]+fli\.h[               ]+ft1,0x1p\+8
> +[      ]+[0-9a-f]+:[   ]+f41e00d3[     ]+fli\.h[               ]+ft1,0x1p\+15
> +[      ]+[0-9a-f]+:[   ]+f41e80d3[     ]+fli\.h[               ]+ft1,0x1p\+16
> +[      ]+[0-9a-f]+:[   ]+f41f00d3[     ]+fli\.h[               ]+ft1,inf
> +[      ]+[0-9a-f]+:[   ]+f41f80d3[     ]+fli\.h[               ]+ft1,nan
> +[      ]+[0-9a-f]+:[   ]+2c3100d3[     ]+fmin\.h[              ]+ft1,ft2,ft3
> +[      ]+[0-9a-f]+:[   ]+2c3120d3[     ]+fminm\.h[             ]+ft1,ft2,ft3
> +[      ]+[0-9a-f]+:[   ]+283100d3[     ]+fmin\.s[              ]+ft1,ft2,ft3
> +[      ]+[0-9a-f]+:[   ]+283120d3[     ]+fminm\.s[             ]+ft1,ft2,ft3
> +[      ]+[0-9a-f]+:[   ]+2a3100d3[     ]+fmin\.d[              ]+ft1,ft2,ft3
> +[      ]+[0-9a-f]+:[   ]+2a3120d3[     ]+fminm\.d[             ]+ft1,ft2,ft3
> +[      ]+[0-9a-f]+:[   ]+2e3100d3[     ]+fmin\.q[              ]+ft1,ft2,ft3
> +[      ]+[0-9a-f]+:[   ]+2e3120d3[     ]+fminm\.q[             ]+ft1,ft2,ft3
> +[      ]+[0-9a-f]+:[   ]+2c3110d3[     ]+fmax\.h[              ]+ft1,ft2,ft3
> +[      ]+[0-9a-f]+:[   ]+2c3130d3[     ]+fmaxm\.h[             ]+ft1,ft2,ft3
> +[      ]+[0-9a-f]+:[   ]+283110d3[     ]+fmax\.s[              ]+ft1,ft2,ft3
> +[      ]+[0-9a-f]+:[   ]+283130d3[     ]+fmaxm\.s[             ]+ft1,ft2,ft3
> +[      ]+[0-9a-f]+:[   ]+2a3110d3[     ]+fmax\.d[              ]+ft1,ft2,ft3
> +[      ]+[0-9a-f]+:[   ]+2a3130d3[     ]+fmaxm\.d[             ]+ft1,ft2,ft3
> +[      ]+[0-9a-f]+:[   ]+2e3110d3[     ]+fmax\.q[              ]+ft1,ft2,ft3
> +[      ]+[0-9a-f]+:[   ]+2e3130d3[     ]+fmaxm\.q[             ]+ft1,ft2,ft3
> +[      ]+[0-9a-f]+:[   ]+4445f553[     ]+fround\.h[            ]+fa0,fa1
> +[      ]+[0-9a-f]+:[   ]+44459553[     ]+fround\.h[            ]+fa0,fa1,rtz
> +[      ]+[0-9a-f]+:[   ]+4045f553[     ]+fround\.s[            ]+fa0,fa1
> +[      ]+[0-9a-f]+:[   ]+40459553[     ]+fround\.s[            ]+fa0,fa1,rtz
> +[      ]+[0-9a-f]+:[   ]+4245f553[     ]+fround\.d[            ]+fa0,fa1
> +[      ]+[0-9a-f]+:[   ]+42459553[     ]+fround\.d[            ]+fa0,fa1,rtz
> +[      ]+[0-9a-f]+:[   ]+4645f553[     ]+fround\.q[            ]+fa0,fa1
> +[      ]+[0-9a-f]+:[   ]+46459553[     ]+fround\.q[            ]+fa0,fa1,rtz
> +[      ]+[0-9a-f]+:[   ]+4455f553[     ]+froundnx\.h[          ]+fa0,fa1
> +[      ]+[0-9a-f]+:[   ]+44559553[     ]+froundnx\.h[          ]+fa0,fa1,rtz
> +[      ]+[0-9a-f]+:[   ]+4055f553[     ]+froundnx\.s[          ]+fa0,fa1
> +[      ]+[0-9a-f]+:[   ]+40559553[     ]+froundnx\.s[          ]+fa0,fa1,rtz
> +[      ]+[0-9a-f]+:[   ]+4255f553[     ]+froundnx\.d[          ]+fa0,fa1
> +[      ]+[0-9a-f]+:[   ]+42559553[     ]+froundnx\.d[          ]+fa0,fa1,rtz
> +[      ]+[0-9a-f]+:[   ]+4655f553[     ]+froundnx\.q[          ]+fa0,fa1
> +[      ]+[0-9a-f]+:[   ]+46559553[     ]+froundnx\.q[          ]+fa0,fa1,rtz
> +[      ]+[0-9a-f]+:[   ]+c2809553[     ]+fcvtmod\.w\.d[        ]+a0,ft1,rtz
> +[      ]+[0-9a-f]+:[   ]+a4209553[     ]+flt\.h[               ]+a0,ft1,ft2
> +[      ]+[0-9a-f]+:[   ]+a420d553[     ]+fltq\.h[              ]+a0,ft1,ft2
> +[      ]+[0-9a-f]+:[   ]+a0209553[     ]+flt\.s[               ]+a0,ft1,ft2
> +[      ]+[0-9a-f]+:[   ]+a020d553[     ]+fltq\.s[              ]+a0,ft1,ft2
> +[      ]+[0-9a-f]+:[   ]+a2209553[     ]+flt\.d[               ]+a0,ft1,ft2
> +[      ]+[0-9a-f]+:[   ]+a220d553[     ]+fltq\.d[              ]+a0,ft1,ft2
> +[      ]+[0-9a-f]+:[   ]+a6209553[     ]+flt\.q[               ]+a0,ft1,ft2
> +[      ]+[0-9a-f]+:[   ]+a620d553[     ]+fltq\.q[              ]+a0,ft1,ft2
> +[      ]+[0-9a-f]+:[   ]+a4208553[     ]+fle\.h[               ]+a0,ft1,ft2
> +[      ]+[0-9a-f]+:[   ]+a420c553[     ]+fleq\.h[              ]+a0,ft1,ft2
> +[      ]+[0-9a-f]+:[   ]+a0208553[     ]+fle\.s[               ]+a0,ft1,ft2
> +[      ]+[0-9a-f]+:[   ]+a020c553[     ]+fleq\.s[              ]+a0,ft1,ft2
> +[      ]+[0-9a-f]+:[   ]+a2208553[     ]+fle\.d[               ]+a0,ft1,ft2
> +[      ]+[0-9a-f]+:[   ]+a220c553[     ]+fleq\.d[              ]+a0,ft1,ft2
> +[      ]+[0-9a-f]+:[   ]+a6208553[     ]+fle\.q[               ]+a0,ft1,ft2
> +[      ]+[0-9a-f]+:[   ]+a620c553[     ]+fleq\.q[              ]+a0,ft1,ft2
> diff --git a/gas/testsuite/gas/riscv/zfa.s b/gas/testsuite/gas/riscv/zfa.s
> new file mode 100644
> index 00000000000..7fbcb17b611
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zfa.s
> @@ -0,0 +1,87 @@
> +target:
> +       # fli
> +       fli.s           ft1, -1
> +       fli.s           ft1, min
> +       fli.s           ft1, 0.0000152587890625
> +       fli.s           ft1, 0x1p-15
> +       fli.s           ft1, 0.00390625
> +       fli.s           ft1, 0x1p-7
> +       fli.s           ft1, 0.0625
> +       fli.s           ft1, 0x1p-3
> +       fli.d           ft1, 0.25
> +       fli.d           ft1, 0x1.4p-2
> +       fli.d           ft1, 0.375
> +       fli.d           ft1, 0x1.cp-2
> +       fli.d           ft1, 0.5
> +       fli.d           ft1, 0x1.4p-1
> +       fli.d           ft1, 0.75
> +       fli.d           ft1, 0x1.cp-1
> +       fli.q           ft1, 1
> +       fli.q           ft1, 0x1.4p+0
> +       fli.q           ft1, 1.5
> +       fli.q           ft1, 0x1.cp0
> +       fli.q           ft1, 2.0
> +       fli.q           ft1, 0x1.4p+1
> +       fli.q           ft1, 3
> +       fli.q           ft1, 0x1p2
> +       fli.h           ft1, 8.0
> +       fli.h           ft1, 0x1p4
> +       fli.h           ft1, 128.0
> +       fli.h           ft1, 0x1p8
> +       fli.h           ft1, 32768.0
> +       fli.h           ft1, 0x1p16
> +       fli.h           ft1, inf
> +       fli.h           ft1, nan
> +       # fminm/fmaxm
> +       fmin.h          ft1, ft2, ft3
> +       fminm.h         ft1, ft2, ft3
> +       fmin.s          ft1, ft2, ft3
> +       fminm.s         ft1, ft2, ft3
> +       fmin.d          ft1, ft2, ft3
> +       fminm.d         ft1, ft2, ft3
> +       fmin.q          ft1, ft2, ft3
> +       fminm.q         ft1, ft2, ft3
> +       fmax.h          ft1, ft2, ft3
> +       fmaxm.h         ft1, ft2, ft3
> +       fmax.s          ft1, ft2, ft3
> +       fmaxm.s         ft1, ft2, ft3
> +       fmax.d          ft1, ft2, ft3
> +       fmaxm.d         ft1, ft2, ft3
> +       fmax.q          ft1, ft2, ft3
> +       fmaxm.q         ft1, ft2, ft3
> +       # fround/froundnx
> +       fround.h        fa0, fa1
> +       fround.h        fa0, fa1, rtz
> +       fround.s        fa0, fa1
> +       fround.s        fa0, fa1, rtz
> +       fround.d        fa0, fa1
> +       fround.d        fa0, fa1, rtz
> +       fround.q        fa0, fa1
> +       fround.q        fa0, fa1, rtz
> +       froundnx.h      fa0, fa1
> +       froundnx.h      fa0, fa1, rtz
> +       froundnx.s      fa0, fa1
> +       froundnx.s      fa0, fa1, rtz
> +       froundnx.d      fa0, fa1
> +       froundnx.d      fa0, fa1, rtz
> +       froundnx.q      fa0, fa1
> +       froundnx.q      fa0, fa1, rtz
> +       # fcvtmod.w.d
> +       fcvtmod.w.d     a0, ft1, rtz
> +       # fltq/fleq
> +       flt.h           a0, ft1, ft2
> +       fltq.h          a0, ft1, ft2
> +       flt.s           a0, ft1, ft2
> +       fltq.s          a0, ft1, ft2
> +       flt.d           a0, ft1, ft2
> +       fltq.d          a0, ft1, ft2
> +       flt.q           a0, ft1, ft2
> +       fltq.q          a0, ft1, ft2
> +       fle.h           a0, ft1, ft2
> +       fleq.h          a0, ft1, ft2
> +       fle.s           a0, ft1, ft2
> +       fleq.s          a0, ft1, ft2
> +       fle.d           a0, ft1, ft2
> +       fleq.d          a0, ft1, ft2
> +       fle.q           a0, ft1, ft2
> +       fleq.q          a0, ft1, ft2
> diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
> index 85d35c1efc9..e141c377bde 100644
> --- a/include/opcode/riscv-opc.h
> +++ b/include/opcode/riscv-opc.h
> @@ -419,6 +419,72 @@
>  #define MASK_FCVT_Q_L  0xfff0007f
>  #define MATCH_FCVT_Q_LU 0xd6300053
>  #define MASK_FCVT_Q_LU  0xfff0007f
> +#define MATCH_FLI_H 0xf4100053
> +#define MASK_FLI_H 0xfff0707f
> +#define MATCH_FMINM_H 0x2c002053
> +#define MASK_FMINM_H 0xfe00707f
> +#define MATCH_FMAXM_H 0x2c003053
> +#define MASK_FMAXM_H 0xfe00707f
> +#define MATCH_FROUND_H 0x44400053
> +#define MASK_FROUND_H 0xfff0007f
> +#define MATCH_FROUNDNX_H 0x44500053
> +#define MASK_FROUNDNX_H 0xfff0007f
> +#define MATCH_FLTQ_H 0xa4005053
> +#define MASK_FLTQ_H 0xfe00707f
> +#define MATCH_FLEQ_H 0xa4004053
> +#define MASK_FLEQ_H 0xfe00707f
> +#define MATCH_FLI_S 0xf0100053
> +#define MASK_FLI_S 0xfff0707f
> +#define MATCH_FMINM_S 0x28002053
> +#define MASK_FMINM_S 0xfe00707f
> +#define MATCH_FMAXM_S 0x28003053
> +#define MASK_FMAXM_S 0xfe00707f
> +#define MATCH_FROUND_S 0x40400053
> +#define MASK_FROUND_S 0xfff0007f
> +#define MATCH_FROUNDNX_S 0x40500053
> +#define MASK_FROUNDNX_S 0xfff0007f
> +#define MATCH_FLTQ_S 0xa0005053
> +#define MASK_FLTQ_S 0xfe00707f
> +#define MATCH_FLEQ_S 0xa0004053
> +#define MASK_FLEQ_S 0xfe00707f
> +#define MATCH_FLI_D 0xf2100053
> +#define MASK_FLI_D 0xfff0707f
> +#define MATCH_FMINM_D 0x2a002053
> +#define MASK_FMINM_D 0xfe00707f
> +#define MATCH_FMAXM_D 0x2a003053
> +#define MASK_FMAXM_D 0xfe00707f
> +#define MATCH_FROUND_D 0x42400053
> +#define MASK_FROUND_D 0xfff0007f
> +#define MATCH_FROUNDNX_D 0x42500053
> +#define MASK_FROUNDNX_D 0xfff0007f
> +#define MATCH_FLTQ_D 0xa2005053
> +#define MASK_FLTQ_D 0xfe00707f
> +#define MATCH_FLEQ_D 0xa2004053
> +#define MASK_FLEQ_D 0xfe00707f
> +#define MATCH_FLI_Q 0xf6100053
> +#define MASK_FLI_Q 0xfff0707f
> +#define MATCH_FMINM_Q 0x2e002053
> +#define MASK_FMINM_Q 0xfe00707f
> +#define MATCH_FMAXM_Q 0x2e003053
> +#define MASK_FMAXM_Q 0xfe00707f
> +#define MATCH_FROUND_Q 0x46400053
> +#define MASK_FROUND_Q 0xfff0007f
> +#define MATCH_FROUNDNX_Q 0x46500053
> +#define MASK_FROUNDNX_Q 0xfff0007f
> +#define MATCH_FLTQ_Q 0xa6005053
> +#define MASK_FLTQ_Q 0xfe00707f
> +#define MATCH_FLEQ_Q 0xa6004053
> +#define MASK_FLEQ_Q 0xfe00707f
> +#define MATCH_FCVTMOD_W_D 0xc2801053
> +#define MASK_FCVTMOD_W_D 0xfff0707f
> +#define MATCH_FMVH_X_D 0xe2100053
> +#define MASK_FMVH_X_D 0xfff0707f
> +#define MATCH_FMVH_X_Q 0xe6100053
> +#define MASK_FMVH_X_Q 0xfff0707f
> +#define MATCH_FMVP_D_X 0xb2000053
> +#define MASK_FMVP_D_X 0xfe00707f
> +#define MATCH_FMVP_Q_X 0xb6000053
> +#define MASK_FMVP_Q_X 0xfe00707f
>  #define MATCH_CLZ 0x60001013
>  #define MASK_CLZ  0xfff0707f
>  #define MATCH_CTZ 0x60101013
> @@ -2981,6 +3047,39 @@ DECLARE_INSN(fcvt_q_w, MATCH_FCVT_Q_W, MASK_FCVT_Q_W)
>  DECLARE_INSN(fcvt_q_wu, MATCH_FCVT_Q_WU, MASK_FCVT_Q_WU)
>  DECLARE_INSN(fcvt_q_l, MATCH_FCVT_Q_L, MASK_FCVT_Q_L)
>  DECLARE_INSN(fcvt_q_lu, MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU)
> +DECLARE_INSN(fli_h, MATCH_FLI_H, MASK_FLI_H)
> +DECLARE_INSN(fminm_h, MATCH_FMINM_H, MASK_FMINM_H)
> +DECLARE_INSN(fmaxm_h, MATCH_FMAXM_H, MASK_FMAXM_H)
> +DECLARE_INSN(fround_h, MATCH_FROUND_H, MASK_FROUND_H)
> +DECLARE_INSN(fround_nx_h, MATCH_FROUNDNX_H, MASK_FROUNDNX_H)
> +DECLARE_INSN(fltq_h, MATCH_FLTQ_H, MASK_FLTQ_H)
> +DECLARE_INSN(fleq_h, MATCH_FLEQ_H, MASK_FLEQ_H)
> +DECLARE_INSN(fli_s, MATCH_FLI_S, MASK_FLI_S)
> +DECLARE_INSN(fminm_s, MATCH_FMINM_S, MASK_FMINM_S)
> +DECLARE_INSN(fmaxm_s, MATCH_FMAXM_S, MASK_FMAXM_S)
> +DECLARE_INSN(fround_s, MATCH_FROUND_S, MASK_FROUND_S)
> +DECLARE_INSN(fround_nx_s, MATCH_FROUNDNX_S, MASK_FROUNDNX_S)
> +DECLARE_INSN(fltq_s, MATCH_FLTQ_S, MASK_FLTQ_S)
> +DECLARE_INSN(fleq_s, MATCH_FLEQ_S, MASK_FLEQ_S)
> +DECLARE_INSN(fli_d, MATCH_FLI_D, MASK_FLI_D)
> +DECLARE_INSN(fminm_d, MATCH_FMINM_D, MASK_FMINM_D)
> +DECLARE_INSN(fmaxm_d, MATCH_FMAXM_D, MASK_FMAXM_D)
> +DECLARE_INSN(fround_d, MATCH_FROUND_D, MASK_FROUND_D)
> +DECLARE_INSN(fround_nx_d, MATCH_FROUNDNX_D, MASK_FROUNDNX_D)
> +DECLARE_INSN(fltq_d, MATCH_FLTQ_D, MASK_FLTQ_D)
> +DECLARE_INSN(fleq_d, MATCH_FLEQ_D, MASK_FLEQ_D)
> +DECLARE_INSN(fli_q, MATCH_FLI_Q, MASK_FLI_Q)
> +DECLARE_INSN(fminm_q, MATCH_FMINM_Q, MASK_FMINM_Q)
> +DECLARE_INSN(fmaxm_q, MATCH_FMAXM_Q, MASK_FMAXM_Q)
> +DECLARE_INSN(fround_q, MATCH_FROUND_Q, MASK_FROUND_Q)
> +DECLARE_INSN(fround_nx_q, MATCH_FROUNDNX_Q, MASK_FROUNDNX_Q)
> +DECLARE_INSN(fltq_q, MATCH_FLTQ_Q, MASK_FLTQ_Q)
> +DECLARE_INSN(fleq_q, MATCH_FLEQ_Q, MASK_FLEQ_Q)
> +DECLARE_INSN(fcvtmod_w_d, MATCH_FCVTMOD_W_D, MASK_FCVTMOD_W_D)
> +DECLARE_INSN(fmvh_x_d, MATCH_FMVH_X_D, MASK_FMVH_X_D)
> +DECLARE_INSN(fmvh_x_q, MATCH_FMVH_X_Q, MASK_FMVH_X_Q)
> +DECLARE_INSN(fmvp_d_x, MATCH_FMVP_D_X, MASK_FMVP_D_X)
> +DECLARE_INSN(fmvp_q_x, MATCH_FMVP_Q_X, MASK_FMVP_Q_X)
>  DECLARE_INSN(clz, MATCH_CLZ, MASK_CLZ)
>  DECLARE_INSN(ctz, MATCH_CTZ, MASK_CTZ)
>  DECLARE_INSN(cpop, MATCH_CPOP, MASK_CPOP)
> diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
> index b4ae55249bb..accdf7db698 100644
> --- a/include/opcode/riscv.h
> +++ b/include/opcode/riscv.h
> @@ -388,6 +388,10 @@ enum riscv_insn_class
>    INSN_CLASS_ZFHMIN_INX,
>    INSN_CLASS_ZFHMIN_AND_D_INX,
>    INSN_CLASS_ZFHMIN_AND_Q_INX,
> +  INSN_CLASS_ZFA,
> +  INSN_CLASS_D_AND_ZFA,
> +  INSN_CLASS_Q_AND_ZFA,
> +  INSN_CLASS_ZFH_AND_ZFA,
>    INSN_CLASS_ZBA,
>    INSN_CLASS_ZBB,
>    INSN_CLASS_ZBC,
> @@ -554,6 +558,8 @@ extern const char * const riscv_vsew[8];
>  extern const char * const riscv_vlmul[8];
>  extern const char * const riscv_vta[2];
>  extern const char * const riscv_vma[2];
> +extern const char * const riscv_fli_symval[32];
> +extern const float riscv_fli_numval[32];
>
>  extern const struct riscv_opcode riscv_opcodes[];
>  extern const struct riscv_opcode riscv_insn_types[];
> diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
> index 3aaa45f419c..65ea6339c9a 100644
> --- a/opcodes/riscv-dis.c
> +++ b/opcodes/riscv-dis.c
> @@ -592,6 +592,21 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
>                     goto undefined_modifier;
>                   }
>                   break;
> +             case 'f':
> +               switch (*++oparg)
> +                 {
> +                 case 'v':
> +                   if (riscv_fli_symval[rs1])
> +                     print (info->stream, dis_style_text, "%s",
> +                            riscv_fli_symval[rs1]);
> +                   else
> +                     print (info->stream, dis_style_immediate, "%a",
> +                            riscv_fli_numval[rs1]);
> +                   break;
> +                 default:
> +                   goto undefined_modifier;
> +                 }
> +               break;
>               default:
>                 goto undefined_modifier;
>               }
> @@ -640,6 +655,7 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
>               }
>           }
>           break;
> +
>         default:
>         undefined_modifier:
>           /* xgettext:c-format */
> diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
> index d9d69cda548..4b970db9bcf 100644
> --- a/opcodes/riscv-opc.c
> +++ b/opcodes/riscv-opc.c
> @@ -110,6 +110,27 @@ const char * const riscv_vma[2] =
>    "mu", "ma"
>  };
>
> +/* The FLI.[HSDQ] symbolic constants (NULL for numeric constant).  */
> +const char * const riscv_fli_symval[32] =
> +{
> +  NULL,  "min", NULL,  NULL,  NULL,  NULL,  NULL,  NULL,
> +  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,
> +  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,
> +  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  "inf", "nan",
> +};
> +
> +/* The FLI.[HSDQ] numeric constants (0.0 for symbolic constants).
> +   The constants use the hex floating-point literal representation
> +   that is printed when using the printf %a format specifier,
> +   which matches the output that is generated by the disassembler.  */
> +const float riscv_fli_numval[32] =
> +{
> +  -0x1p+0, 0x0p+0, 0x1p-16, 0x1p-15, 0x1p-8, 0x1p-7, 0x1p-4, 0x1p-3,
> +  0x1p-2, 0x1.4p-2, 0x1.8p-2, 0x1.cp-2, 0x1p-1, 0x1.4p-1, 0x1.8p-1, 0x1.cp-1,
> +  0x1p+0, 0x1.4p+0, 0x1.8p+0, 0x1.cp+0, 0x1p+1, 0x1.4p+1, 0x1.8p+1, 0x1p+2,
> +  0x1p+3, 0x1p+4, 0x1p+7, 0x1p+8, 0x1p+15, 0x1p+16, 0x0p+0, 0x0p+0
> +};
> +
>  /* The order of overloaded instructions matters.  Label arguments and
>     register arguments look the same. Instructions that can have either
>     for arguments must apear in the correct order in this table for the
> @@ -939,6 +960,49 @@ 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 },
>
> +/* 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 },
> +{"fli.q",       0, INSN_CLASS_Q_AND_ZFA,   "D,Wfv", MATCH_FLI_Q, MASK_FLI_Q, match_opcode, 0 },
> +{"fli.h",       0, INSN_CLASS_ZFH_AND_ZFA, "D,Wfv", MATCH_FLI_H, MASK_FLI_H, match_opcode, 0 },
> +{"fminm.s",     0, INSN_CLASS_ZFA,         "D,S,T", MATCH_FMINM_S, MASK_FMINM_S, match_opcode, 0 },
> +{"fmaxm.s",     0, INSN_CLASS_ZFA,         "D,S,T", MATCH_FMAXM_S, MASK_FMAXM_S, match_opcode, 0 },
> +{"fminm.d",     0, INSN_CLASS_D_AND_ZFA,   "D,S,T", MATCH_FMINM_D, MASK_FMINM_D, match_opcode, 0 },
> +{"fmaxm.d",     0, INSN_CLASS_D_AND_ZFA,   "D,S,T", MATCH_FMAXM_D, MASK_FMAXM_D, match_opcode, 0 },
> +{"fminm.q",     0, INSN_CLASS_Q_AND_ZFA,   "D,S,T", MATCH_FMINM_Q, MASK_FMINM_Q, match_opcode, 0 },
> +{"fmaxm.q",     0, INSN_CLASS_Q_AND_ZFA,   "D,S,T", MATCH_FMAXM_Q, MASK_FMAXM_Q, match_opcode, 0 },
> +{"fminm.h",     0, INSN_CLASS_ZFH_AND_ZFA, "D,S,T", MATCH_FMINM_H, MASK_FMINM_H, match_opcode, 0 },
> +{"fmaxm.h",     0, INSN_CLASS_ZFH_AND_ZFA, "D,S,T", MATCH_FMAXM_H, MASK_FMAXM_H, match_opcode, 0 },
> +{"fround.s",    0, INSN_CLASS_ZFA,         "D,S",   MATCH_FROUND_S|MASK_RM, MASK_FROUND_S|MASK_RM, match_opcode, 0 },
> +{"fround.s",    0, INSN_CLASS_ZFA,         "D,S,m", MATCH_FROUND_S, MASK_FROUND_S, match_opcode, 0 },
> +{"froundnx.s",  0, INSN_CLASS_ZFA,         "D,S",   MATCH_FROUNDNX_S|MASK_RM, MASK_FROUNDNX_S|MASK_RM, match_opcode, 0 },
> +{"froundnx.s",  0, INSN_CLASS_ZFA,         "D,S,m", MATCH_FROUNDNX_S, MASK_FROUNDNX_S, match_opcode, 0 },
> +{"fround.d",    0, INSN_CLASS_D_AND_ZFA,   "D,S",   MATCH_FROUND_D|MASK_RM, MASK_FROUND_D|MASK_RM, match_opcode, 0 },
> +{"fround.d",    0, INSN_CLASS_D_AND_ZFA,   "D,S,m", MATCH_FROUND_D, MASK_FROUND_D, match_opcode, 0 },
> +{"froundnx.d",  0, INSN_CLASS_D_AND_ZFA,   "D,S",   MATCH_FROUNDNX_D|MASK_RM, MASK_FROUNDNX_D|MASK_RM, match_opcode, 0 },
> +{"froundnx.d",  0, INSN_CLASS_D_AND_ZFA,   "D,S,m", MATCH_FROUNDNX_D, MASK_FROUNDNX_D, match_opcode, 0 },
> +{"fround.q",    0, INSN_CLASS_Q_AND_ZFA,   "D,S",   MATCH_FROUND_Q|MASK_RM, MASK_FROUND_Q|MASK_RM, match_opcode, 0 },
> +{"fround.q",    0, INSN_CLASS_Q_AND_ZFA,   "D,S,m", MATCH_FROUND_Q, MASK_FROUND_Q, match_opcode, 0 },
> +{"froundnx.q",  0, INSN_CLASS_Q_AND_ZFA,   "D,S",   MATCH_FROUNDNX_Q|MASK_RM, MASK_FROUNDNX_Q|MASK_RM, match_opcode, 0 },
> +{"froundnx.q",  0, INSN_CLASS_Q_AND_ZFA,   "D,S,m", MATCH_FROUNDNX_Q, MASK_FROUNDNX_Q, match_opcode, 0 },
> +{"fround.h",    0, INSN_CLASS_ZFH_AND_ZFA, "D,S",   MATCH_FROUND_H|MASK_RM, MASK_FROUND_H|MASK_RM, match_opcode, 0 },
> +{"fround.h",    0, INSN_CLASS_ZFH_AND_ZFA, "D,S,m", MATCH_FROUND_H, MASK_FROUND_H, match_opcode, 0 },
> +{"froundnx.h",  0, INSN_CLASS_ZFH_AND_ZFA, "D,S",   MATCH_FROUNDNX_H|MASK_RM, MASK_FROUNDNX_H|MASK_RM, match_opcode, 0 },
> +{"froundnx.h",  0, INSN_CLASS_ZFH_AND_ZFA, "D,S,m", MATCH_FROUNDNX_H, MASK_FROUNDNX_H, match_opcode, 0 },
> +{"fcvtmod.w.d", 0, INSN_CLASS_D_AND_ZFA,   "d,S,m", MATCH_FCVTMOD_W_D, MASK_FCVTMOD_W_D, match_opcode, 0 },
> +{"fmvh.x.d",   32, INSN_CLASS_D_AND_ZFA,   "d,S",   MATCH_FMVH_X_D, MASK_FMVH_X_D, match_opcode, 0 },
> +{"fmvp.d.x",   32, INSN_CLASS_D_AND_ZFA,   "D,s,t", MATCH_FMVP_D_X, MASK_FMVP_D_X, match_opcode, 0 },
> +{"fmvh.x.q",   64, INSN_CLASS_Q_AND_ZFA,   "d,S",   MATCH_FMVH_X_Q, MASK_FMVH_X_Q, match_opcode, 0 },
> +{"fmvp.q.x",   64, INSN_CLASS_Q_AND_ZFA,   "D,s,t", MATCH_FMVP_Q_X, MASK_FMVP_Q_X, match_opcode, 0 },
> +{"fltq.s",      0, INSN_CLASS_ZFA,         "d,S,T", MATCH_FLTQ_S, MASK_FLTQ_S, match_opcode, 0 },
> +{"fleq.s",      0, INSN_CLASS_ZFA,         "d,S,T", MATCH_FLEQ_S, MASK_FLEQ_S, match_opcode, 0 },
> +{"fltq.d",      0, INSN_CLASS_D_AND_ZFA,   "d,S,T", MATCH_FLTQ_D, MASK_FLTQ_D, match_opcode, 0 },
> +{"fleq.d",      0, INSN_CLASS_D_AND_ZFA,   "d,S,T", MATCH_FLEQ_D, MASK_FLEQ_D, match_opcode, 0 },
> +{"fltq.q",      0, INSN_CLASS_Q_AND_ZFA,   "d,S,T", MATCH_FLTQ_Q, MASK_FLTQ_Q, match_opcode, 0 },
> +{"fleq.q",      0, INSN_CLASS_Q_AND_ZFA,   "d,S,T", MATCH_FLEQ_Q, MASK_FLEQ_Q, match_opcode, 0 },
> +{"fltq.h",      0, INSN_CLASS_ZFH_AND_ZFA, "d,S,T", MATCH_FLTQ_H, MASK_FLTQ_H, match_opcode, 0 },
> +{"fleq.h",      0, INSN_CLASS_ZFH_AND_ZFA, "d,S,T", MATCH_FLEQ_H, MASK_FLEQ_H, match_opcode, 0 },
> +
>  /* Zbb or zbkb instructions.  */
>  {"clz",        0, INSN_CLASS_ZBB,  "d,s",   MATCH_CLZ, MASK_CLZ, match_opcode, 0 },
>  {"ctz",        0, INSN_CLASS_ZBB,  "d,s",   MATCH_CTZ, MASK_CTZ, match_opcode, 0 },
> --
> 2.39.2
>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC PATCH v5] RISC-V: Add support for the Zfa extension
  2023-06-29  7:52 ` Christoph Müllner
@ 2023-06-29  8:33   ` Christoph Müllner
  2023-06-29 15:07   ` Jeff Law
  1 sibling, 0 replies; 19+ messages in thread
From: Christoph Müllner @ 2023-06-29  8:33 UTC (permalink / raw)
  To: binutils, Nelson Chu, Andrew Waterman, Palmer Dabbelt,
	Jim Wilson, Philipp Tomsich, Jan Beulich, Kito Cheng, Jeff Law,
	Tsukasa OI

On Thu, Jun 29, 2023 at 9:52 AM Christoph Müllner
<christoph.muellner@vrull.eu> wrote:
>
> The RISC-V Zfa extension has been frozen.
>
> As this was discussed elsewhere yesterday:
> * Should this patch wait for ratification?
> * Is this blocked by https://github.com/riscv-non-isa/riscv-asm-manual/pull/85 ?

This question became obsolete after this PR has just been merged.

BR
Christoph

>
> Nelson stated on Apr 12 (response to v4):
> "If there are no new instructions or encodings/formats changed in the
> future spec, then you should commit the patch when the extension is
> ratified."
>
> So my understanding is that this needs to wait for ratification and is
> not blocked by the mentioned PR.
>
> BR
> Christoph
>
>
>
> On Thu, Apr 13, 2023 at 3:37 PM Christoph Muellner
> <christoph.muellner@vrull.eu> wrote:
> >
> > From: Christoph Müllner <christoph.muellner@vrull.eu>
> >
> > This patch adds support for the RISC-V Zfa extension,
> > which introduces additional floating-point instructions:
> > * fli (load-immediate) with pre-defined immediates
> > * fminm/fmaxm (like fmin/fmax but with different NaN behaviour)
> > * fround/froundmx (round to integer)
> > * fcvtmod.w.d (Modular Convert-to-Integer)
> > * fmv* to access high bits of FP registers in case XLEN < FLEN
> > * fleq/fltq (quiet comparison instructions)
> >
> > Zfa defines its instructions in combination with the following
> > extensions:
> > * single-precision floating-point (F)
> > * double-precision floating-point (D)
> > * quad-precision floating-point (Q)
> > * half-precision floating-point (Zfh)
> >
> > This patch is based on an earlier version from Tsukasa OI:
> >   https://sourceware.org/pipermail/binutils/2022-September/122939.html
> > Most significant change to that commit is the switch from the rs1-field
> > value to the actual floating-point value in the last operand of the fli*
> > instructions. Everything that strtof() can parse is accepted and
> > the '%a' printf specifier is used to output hex floating-point literals
> > in the disassembly.
> >
> > The Zfa specification is not frozen at the moment (which is why this
> > patch is RFC) and can be found here:
> >   https://github.com/riscv/riscv-isa-manual/blob/master/src/zfa.tex
> >
> > bfd/ChangeLog:
> >
> >         * elfxx-riscv.c (riscv_multi_subset_supports): Add instruction
> >         class support for 'Zfa' extension.
> >         (riscv_multi_subset_supports_ext): Likewise.
> >         (riscv_implicit_subsets): Add 'Zfa' -> 'F' dependency.
> >
> > gas/ChangeLog:
> >
> >         * config/tc-riscv.c (flt_lookup): New helper to lookup a float value
> >         in an array.
> >         (validate_riscv_insn): Add 'Wfv' as new format string directive.
> >         (riscv_ip): Likewise.
> >         * doc/c-riscv.texi: Add floating-point chapter and describe
> >         limiations of the Zfa FP literal parsing.
> >         * testsuite/gas/riscv/zfa-32.d: New test.
> >         * testsuite/gas/riscv/zfa-32.s: New test.
> >         * testsuite/gas/riscv/zfa-64.d: New test.
> >         * testsuite/gas/riscv/zfa-64.s: New test.
> >         * testsuite/gas/riscv/zfa-fail.d: New test.
> >         * testsuite/gas/riscv/zfa-fail.l: New test.
> >         * testsuite/gas/riscv/zfa-fail.s: New test.
> >         * testsuite/gas/riscv/zfa.d: New test.
> >         * testsuite/gas/riscv/zfa.s: New test.
> >         * testsuite/gas/riscv/zfa.s: New test.
> >
> >         * opcode/riscv-opc.h (MATCH_FLI_H): New.
> >         (MASK_FLI_H): New.
> >         (MATCH_FMINM_H): New.
> >         (MASK_FMINM_H): New.
> >         (MATCH_FMAXM_H): New.
> >         (MASK_FMAXM_H): New.
> >         (MATCH_FROUND_H): New.
> >         (MASK_FROUND_H): New.
> >         (MATCH_FROUNDNX_H): New.
> >         (MASK_FROUNDNX_H): New.
> >         (MATCH_FLTQ_H): New.
> >         (MASK_FLTQ_H): New.
> >         (MATCH_FLEQ_H): New.
> >         (MASK_FLEQ_H): New.
> >         (MATCH_FLI_S): New.
> >         (MASK_FLI_S): New.
> >         (MATCH_FMINM_S): New.
> >         (MASK_FMINM_S): New.
> >         (MATCH_FMAXM_S): New.
> >         (MASK_FMAXM_S): New.
> >         (MATCH_FROUND_S): New.
> >         (MASK_FROUND_S): New.
> >         (MATCH_FROUNDNX_S): New.
> >         (MASK_FROUNDNX_S): New.
> >         (MATCH_FLTQ_S): New.
> >         (MASK_FLTQ_S): New.
> >         (MATCH_FLEQ_S): New.
> >         (MASK_FLEQ_S): New.
> >         (MATCH_FLI_D): New.
> >         (MASK_FLI_D): New.
> >         (MATCH_FMINM_D): New.
> >         (MASK_FMINM_D): New.
> >         (MATCH_FMAXM_D): New.
> >         (MASK_FMAXM_D): New.
> >         (MATCH_FROUND_D): New.
> >         (MASK_FROUND_D): New.
> >         (MATCH_FROUNDNX_D): New.
> >         (MASK_FROUNDNX_D): New.
> >         (MATCH_FLTQ_D): New.
> >         (MASK_FLTQ_D): New.
> >         (MATCH_FLEQ_D): New.
> >         (MASK_FLEQ_D): New.
> >         (MATCH_FLI_Q): New.
> >         (MASK_FLI_Q): New.
> >         (MATCH_FMINM_Q): New.
> >         (MASK_FMINM_Q): New.
> >         (MATCH_FMAXM_Q): New.
> >         (MASK_FMAXM_Q): New.
> >         (MATCH_FROUND_Q): New.
> >         (MASK_FROUND_Q): New.
> >         (MATCH_FROUNDNX_Q): New.
> >         (MASK_FROUNDNX_Q): New.
> >         (MATCH_FLTQ_Q): New.
> >         (MASK_FLTQ_Q): New.
> >         (MATCH_FLEQ_Q): New.
> >         (MASK_FLEQ_Q): New.
> >         (MATCH_FCVTMOD_W_D): New.
> >         (MASK_FCVTMOD_W_D): New.
> >         (MATCH_FMVH_X_D): New.
> >         (MASK_FMVH_X_D): New.
> >         (MATCH_FMVH_X_Q): New.
> >         (MASK_FMVH_X_Q): New.
> >         (MATCH_FMVP_D_X): New.
> >         (MASK_FMVP_D_X): New.
> >         (MATCH_FMVP_Q_X): New.
> >         (MASK_FMVP_Q_X): New.
> >         (DECLARE_INSN): New.
> >         * opcode/riscv.h (enum riscv_insn_class): Add instruction
> >         classes for the Zfa extension.
> >
> > opcodes/ChangeLog:
> >
> >         * riscv-dis.c (print_insn_args): Add support for
> >         new format string directive 'Wfv'.
> >         * riscv-opc.c: Add Zfa instructions.
> >
> > Co-Developed-by: Tsukasa OI <research_trasio@irq.a4lg.com>
> > Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
> > ---
> > Changes in v5:
> > * Fixes in texinfo directives (documentation)
> > * Make FLI error message more verbose
> >
> >  bfd/elfxx-riscv.c                  | 39 ++++++++++++
> >  gas/config/tc-riscv.c              | 52 ++++++++++++++++
> >  gas/doc/c-riscv.texi               | 41 +++++++++++++
> >  gas/testsuite/gas/riscv/zfa-32.d   | 10 +++
> >  gas/testsuite/gas/riscv/zfa-32.s   |  3 +
> >  gas/testsuite/gas/riscv/zfa-64.d   | 10 +++
> >  gas/testsuite/gas/riscv/zfa-64.s   |  3 +
> >  gas/testsuite/gas/riscv/zfa-fail.d |  3 +
> >  gas/testsuite/gas/riscv/zfa-fail.l | 12 ++++
> >  gas/testsuite/gas/riscv/zfa-fail.s | 16 +++++
> >  gas/testsuite/gas/riscv/zfa.d      | 89 +++++++++++++++++++++++++++
> >  gas/testsuite/gas/riscv/zfa.s      | 87 ++++++++++++++++++++++++++
> >  include/opcode/riscv-opc.h         | 99 ++++++++++++++++++++++++++++++
> >  include/opcode/riscv.h             |  6 ++
> >  opcodes/riscv-dis.c                | 16 +++++
> >  opcodes/riscv-opc.c                | 64 +++++++++++++++++++
> >  16 files changed, 550 insertions(+)
> >  create mode 100644 gas/testsuite/gas/riscv/zfa-32.d
> >  create mode 100644 gas/testsuite/gas/riscv/zfa-32.s
> >  create mode 100644 gas/testsuite/gas/riscv/zfa-64.d
> >  create mode 100644 gas/testsuite/gas/riscv/zfa-64.s
> >  create mode 100644 gas/testsuite/gas/riscv/zfa-fail.d
> >  create mode 100644 gas/testsuite/gas/riscv/zfa-fail.l
> >  create mode 100644 gas/testsuite/gas/riscv/zfa-fail.s
> >  create mode 100644 gas/testsuite/gas/riscv/zfa.d
> >  create mode 100644 gas/testsuite/gas/riscv/zfa.s
> >
> > diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
> > index 19391d94e30..d57fe2400fd 100644
> > --- a/bfd/elfxx-riscv.c
> > +++ b/bfd/elfxx-riscv.c
> > @@ -1078,6 +1078,7 @@ static struct riscv_implicit_subset riscv_implicit_subsets[] =
> >    {"zvl256b", "zvl128b",       check_implicit_always},
> >    {"zvl128b", "zvl64b",                check_implicit_always},
> >    {"zvl64b", "zvl32b",         check_implicit_always},
> > +  {"zfa", "f",         check_implicit_always},
> >    {"d", "f",           check_implicit_always},
> >    {"zfh", "zfhmin",    check_implicit_always},
> >    {"zfhmin", "f",      check_implicit_always},
> > @@ -1175,6 +1176,7 @@ static struct riscv_supported_ext riscv_supported_std_z_ext[] =
> >    {"zihintpause",      ISA_SPEC_CLASS_DRAFT,           2, 0,  0 },
> >    {"zmmul",            ISA_SPEC_CLASS_DRAFT,           1, 0,  0 },
> >    {"zawrs",            ISA_SPEC_CLASS_DRAFT,           1, 0,  0 },
> > +  {"zfa",              ISA_SPEC_CLASS_DRAFT,           0, 1,  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 },
> > @@ -2313,6 +2315,17 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps,
> >                && riscv_subset_supports (rps, "q"))
> >               || (riscv_subset_supports (rps, "zhinxmin")
> >                   && riscv_subset_supports (rps, "zqinx")));
> > +    case INSN_CLASS_ZFA:
> > +      return riscv_subset_supports (rps, "zfa");
> > +    case INSN_CLASS_D_AND_ZFA:
> > +      return riscv_subset_supports (rps, "d")
> > +            && riscv_subset_supports (rps, "zfa");
> > +    case INSN_CLASS_Q_AND_ZFA:
> > +      return riscv_subset_supports (rps, "q")
> > +            && riscv_subset_supports (rps, "zfa");
> > +    case INSN_CLASS_ZFH_AND_ZFA:
> > +      return riscv_subset_supports (rps, "zfh")
> > +            && riscv_subset_supports (rps, "zfa");
> >      case INSN_CLASS_ZBA:
> >        return riscv_subset_supports (rps, "zba");
> >      case INSN_CLASS_ZBB:
> > @@ -2479,6 +2492,32 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
> >         return "zhinxmin";
> >        else
> >         return _("zfhmin' and `q', or `zhinxmin' and `zqinx");
> > +    case INSN_CLASS_ZFA:
> > +      return "zfa";
> > +    case INSN_CLASS_D_AND_ZFA:
> > +      if (!riscv_subset_supports (rps, "d")
> > +         && !riscv_subset_supports (rps, "zfa"))
> > +       return _("d' and `zfa");
> > +      else if (!riscv_subset_supports (rps, "d"))
> > +       return "d";
> > +      else
> > +       return "zfa";
> > +    case INSN_CLASS_Q_AND_ZFA:
> > +      if (!riscv_subset_supports (rps, "q")
> > +         && !riscv_subset_supports (rps, "zfa"))
> > +       return _("q' and `zfa");
> > +      else if (!riscv_subset_supports (rps, "q"))
> > +       return "q";
> > +      else
> > +       return "zfa";
> > +    case INSN_CLASS_ZFH_AND_ZFA:
> > +      if (!riscv_subset_supports (rps, "zfh")
> > +         && !riscv_subset_supports (rps, "zfa"))
> > +       return _("zfh' and `zfa");
> > +      else if (!riscv_subset_supports (rps, "zfh"))
> > +       return "zfh";
> > +      else
> > +       return "zfa";
> >      case INSN_CLASS_ZBA:
> >        return "zba";
> >      case INSN_CLASS_ZBB:
> > diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
> > index 4eff07a6d4a..0fcc1f26587 100644
> > --- a/gas/config/tc-riscv.c
> > +++ b/gas/config/tc-riscv.c
> > @@ -1219,6 +1219,21 @@ arg_lookup (char **s, const char *const *array, size_t size, unsigned *regnop)
> >    return false;
> >  }
> >
> > +static bool
> > +flt_lookup (float f, const float *array, size_t size, unsigned *regnop)
> > +{
> > +  size_t i;
> > +
> > +  for (i = 0; i < size; i++)
> > +    if (array[i] == f)
> > +      {
> > +       *regnop = i;
> > +       return true;
> > +      }
> > +
> > +  return false;
> > +}
> > +
> >  #define USE_BITS(mask,shift) (used_bits |= ((insn_t)(mask) << (shift)))
> >  #define USE_IMM(n, s) \
> >    (used_bits |= ((insn_t)((1ull<<n)-1) << (s)))
> > @@ -1399,6 +1414,14 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
> >                   goto unknown_validate_operand;
> >                 }
> >               break;
> > +           case 'f':
> > +             switch (*++oparg)
> > +               {
> > +               case 'v': USE_BITS (OP_MASK_RS1, OP_SH_RS1); break;
> > +               default:
> > +                 goto unknown_validate_operand;
> > +               }
> > +             break;
> >             default:
> >               goto unknown_validate_operand;
> >             }
> > @@ -3461,6 +3484,35 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
> >                       goto unknown_riscv_ip_operand;
> >                     }
> >                   break;
> > +               case 'f':
> > +                 switch (*++oparg)
> > +                   {
> > +                   case 'v':
> > +                     /* FLI.[HSDQ] value field for 'Zfa' extension.  */
> > +                     if (!arg_lookup (&asarg, riscv_fli_symval,
> > +                                      ARRAY_SIZE (riscv_fli_symval), &regno))
> > +                       {
> > +                         /* 0.0 is not a valid entry in riscv_fli_numval.  */
> > +                         errno = 0;
> > +                         float f = strtof (asarg, &asarg);
> > +                         if (errno != 0 || f == 0.0
> > +                             || !flt_lookup (f, riscv_fli_numval,
> > +                                            ARRAY_SIZE(riscv_fli_numval),
> > +                                            &regno))
> > +                           {
> > +                             as_bad (_("bad fli constant operand, "
> > +                                       "supported constants must be in "
> > +                                       "decimal or hexadecimal floating-point "
> > +                                       "literal form"));
> > +                             break;
> > +                           }
> > +                       }
> > +                     INSERT_OPERAND (RS1, *ip, regno);
> > +                     continue;
> > +                   default:
> > +                     goto unknown_riscv_ip_operand;
> > +                   }
> > +                 break;
> >                 default:
> >                   goto unknown_riscv_ip_operand;
> >                 }
> > diff --git a/gas/doc/c-riscv.texi b/gas/doc/c-riscv.texi
> > index 64fff6a7973..987c01f9d1d 100644
> > --- a/gas/doc/c-riscv.texi
> > +++ b/gas/doc/c-riscv.texi
> > @@ -18,6 +18,7 @@
> >  * RISC-V-Options::        RISC-V Options
> >  * RISC-V-Directives::     RISC-V Directives
> >  * RISC-V-Modifiers::      RISC-V Assembler Modifiers
> > +* RISC-V-Floating-Point:: RISC-V Floating Point
> >  * RISC-V-Formats::        RISC-V Instruction Formats
> >  * RISC-V-ATTRIBUTE::      RISC-V Object Attribute
> >  * RISC-V-CustomExts::     RISC-V Custom (Vendor-Defined) Extensions
> > @@ -382,6 +383,46 @@ The pseudo la.tls.gd instruction can be expended to
> >
> >  @end table
> >
> > +@node RISC-V-Floating-Point
> > +@section RISC-V Floating Point
> > +@cindex floating point, risc-v (@sc{ieee})
> > +@cindex RISC-V floating point (@sc{ieee})
> > +
> > +The RISC-V architecture uses @sc{ieee} floating-point numbers.
> > +
> > +The RISC-V Zfa extension includes a load-immediate instruction
> > +for floating-point registers, which allows specifying the immediate
> > +(from a pool of 32 predefined values defined in the specification)
> > +as operand.
> > +E.g. to load the value @code{0.0625} as single-precision FP value into
> > +the FP register @code{ft1} one of the following instructions can be used:
> > +
> > +       fli.s ft1, 0.0625 # dec floating-point literal
> > +       fli.s ft1, 0x1p-4 # hex floating-point literal
> > +       fli.s ft1, 0x0.8p-3
> > +       fli.s ft1, 0x1.0p-4
> > +       fli.s ft1, 0x2p-5
> > +       fli.s ft1, 0x4p-6
> > +       ...
> > +
> > +As can be seen, many valid ways exist to express a floating-point value.
> > +This is realized by parsing the value operand using strtof() and
> > +comparing the parsed value against built-in float-constants that
> > +are written as hex floating-point literals.
> > +
> > +This approach works on all machines that use IEEE 754.
> > +However, there is a chance that this fails on other machines
> > +with the following error message:
> > +
> > +       Error: improper fli value operand
> > +       Error: illegal operands `fli.s ft1,0.0625
> > +
> > +The error indicates that parsing @samp{0x1p-4} and @samp{0.0625}
> > +to single-precision floating point numbers will not result
> > +in two equal values on that machine.
> > +
> > +If you encounter this problem, then please report it.
> > +
> >  @node RISC-V-Formats
> >  @section RISC-V Instruction Formats
> >  @cindex instruction formats, risc-v
> > diff --git a/gas/testsuite/gas/riscv/zfa-32.d b/gas/testsuite/gas/riscv/zfa-32.d
> > new file mode 100644
> > index 00000000000..48e20bf4675
> > --- /dev/null
> > +++ b/gas/testsuite/gas/riscv/zfa-32.d
> > @@ -0,0 +1,10 @@
> > +#as: -march=rv32id_zfa
> > +#objdump: -d
> > +
> > +.*:[   ]+file format .*
> > +
> > +Disassembly of section .text:
> > +
> > +0+000 <target>:
> > +[      ]+[0-9a-f]+:[   ]+e2108553[     ]+fmvh\.x\.d[   ]+a0,ft1
> > +[      ]+[0-9a-f]+:[   ]+b2b500d3[     ]+fmvp\.d\.x[   ]+ft1,a0,a1
> > diff --git a/gas/testsuite/gas/riscv/zfa-32.s b/gas/testsuite/gas/riscv/zfa-32.s
> > new file mode 100644
> > index 00000000000..da95441cdc7
> > --- /dev/null
> > +++ b/gas/testsuite/gas/riscv/zfa-32.s
> > @@ -0,0 +1,3 @@
> > +target:
> > +       fmvh.x.d        a0, ft1
> > +       fmvp.d.x        ft1, a0, a1
> > diff --git a/gas/testsuite/gas/riscv/zfa-64.d b/gas/testsuite/gas/riscv/zfa-64.d
> > new file mode 100644
> > index 00000000000..48b6d74ed9b
> > --- /dev/null
> > +++ b/gas/testsuite/gas/riscv/zfa-64.d
> > @@ -0,0 +1,10 @@
> > +#as: -march=rv64iq_zfa
> > +#objdump: -d
> > +
> > +.*:[   ]+file format .*
> > +
> > +Disassembly of section .text:
> > +
> > +0+000 <target>:
> > +[      ]+[0-9a-f]+:[   ]+e6108553[     ]+fmvh\.x\.q[   ]+a0,ft1
> > +[      ]+[0-9a-f]+:[   ]+b6b500d3[     ]+fmvp\.q\.x[   ]+ft1,a0,a1
> > diff --git a/gas/testsuite/gas/riscv/zfa-64.s b/gas/testsuite/gas/riscv/zfa-64.s
> > new file mode 100644
> > index 00000000000..dc8129dae3e
> > --- /dev/null
> > +++ b/gas/testsuite/gas/riscv/zfa-64.s
> > @@ -0,0 +1,3 @@
> > +target:
> > +       fmvh.x.q        a0, ft1
> > +       fmvp.q.x        ft1, a0, a1
> > diff --git a/gas/testsuite/gas/riscv/zfa-fail.d b/gas/testsuite/gas/riscv/zfa-fail.d
> > new file mode 100644
> > index 00000000000..2f0a69b247a
> > --- /dev/null
> > +++ b/gas/testsuite/gas/riscv/zfa-fail.d
> > @@ -0,0 +1,3 @@
> > +#as: -march=rv64iq_zfa_zfh
> > +#source: zfa-fail.s
> > +#error_output: zfa-fail.l
> > diff --git a/gas/testsuite/gas/riscv/zfa-fail.l b/gas/testsuite/gas/riscv/zfa-fail.l
> > new file mode 100644
> > index 00000000000..efe9ba00e02
> > --- /dev/null
> > +++ b/gas/testsuite/gas/riscv/zfa-fail.l
> > @@ -0,0 +1,12 @@
> > +.*: Assembler messages:
> > +.*: Error: bad fli constant operand, supported constants must be in decimal or hexadecimal floating-point literal form
> > +.*: Error: illegal operands `fli\.s ft1,infinity'
> > +.*: Error: bad fli constant operand, supported constants must be in decimal or hexadecimal floating-point literal form
> > +.*: Error: illegal operands `fli\.d ft1,invalid'
> > +.*: Error: illegal operands `fcvtmod\.w\.d a0,ft1'
> > +.*: Error: illegal operands `fcvtmod\.w\.d a0,ft1,rne'
> > +.*: Error: illegal operands `fcvtmod\.w\.d a0,ft1,rdn'
> > +.*: Error: illegal operands `fcvtmod\.w\.d a0,ft1,rup'
> > +.*: Error: illegal operands `fcvtmod\.w\.d a0,ft1,rmm'
> > +.*: Error: illegal operands `fcvtmod\.w\.d a0,ft1,dyn'
> > +.*: Error: illegal operands `fcvtmod\.w\.d a0,ft1,invalid'
> > diff --git a/gas/testsuite/gas/riscv/zfa-fail.s b/gas/testsuite/gas/riscv/zfa-fail.s
> > new file mode 100644
> > index 00000000000..98ffe7f3268
> > --- /dev/null
> > +++ b/gas/testsuite/gas/riscv/zfa-fail.s
> > @@ -0,0 +1,16 @@
> > +target:
> > +       # fli.[sdqh]: Invalid value field
> > +       fli.s   ft1, infinity
> > +       fli.d   ft1, invalid
> > +
> > +       # fcvtmod.w.d: Requires explicit rounding mode.
> > +       fcvtmod.w.d     a0, ft1
> > +
> > +       # fcvtmod.w.d: Rounding mode other than rtz are reserved.
> > +       fcvtmod.w.d     a0, ft1, rne
> > +       fcvtmod.w.d     a0, ft1, rdn
> > +       fcvtmod.w.d     a0, ft1, rup
> > +       fcvtmod.w.d     a0, ft1, rmm
> > +       fcvtmod.w.d     a0, ft1, dyn
> > +       # fcvtmod.w.d: Invalid rounding mode is invalid.
> > +       fcvtmod.w.d     a0, ft1, invalid
> > diff --git a/gas/testsuite/gas/riscv/zfa.d b/gas/testsuite/gas/riscv/zfa.d
> > new file mode 100644
> > index 00000000000..cbfc72e6036
> > --- /dev/null
> > +++ b/gas/testsuite/gas/riscv/zfa.d
> > @@ -0,0 +1,89 @@
> > +#as: -march=rv32iq_zfa_zfh
> > +#objdump: -d
> > +
> > +.*:[   ]+file format .*
> > +
> > +Disassembly of section .text:
> > +
> > +0+000 <target>:
> > +[      ]+[0-9a-f]+:[   ]+f01000d3[     ]+fli\.s[               ]+ft1,-0x1p\+0
> > +[      ]+[0-9a-f]+:[   ]+f01080d3[     ]+fli\.s[               ]+ft1,min
> > +[      ]+[0-9a-f]+:[   ]+f01100d3[     ]+fli\.s[               ]+ft1,0x1p-16
> > +[      ]+[0-9a-f]+:[   ]+f01180d3[     ]+fli\.s[               ]+ft1,0x1p-15
> > +[      ]+[0-9a-f]+:[   ]+f01200d3[     ]+fli\.s[               ]+ft1,0x1p-8
> > +[      ]+[0-9a-f]+:[   ]+f01280d3[     ]+fli\.s[               ]+ft1,0x1p-7
> > +[      ]+[0-9a-f]+:[   ]+f01300d3[     ]+fli\.s[               ]+ft1,0x1p-4
> > +[      ]+[0-9a-f]+:[   ]+f01380d3[     ]+fli\.s[               ]+ft1,0x1p-3
> > +[      ]+[0-9a-f]+:[   ]+f21400d3[     ]+fli\.d[               ]+ft1,0x1p-2
> > +[      ]+[0-9a-f]+:[   ]+f21480d3[     ]+fli\.d[               ]+ft1,0x1.4p-2
> > +[      ]+[0-9a-f]+:[   ]+f21500d3[     ]+fli\.d[               ]+ft1,0x1.8p-2
> > +[      ]+[0-9a-f]+:[   ]+f21580d3[     ]+fli\.d[               ]+ft1,0x1.cp-2
> > +[      ]+[0-9a-f]+:[   ]+f21600d3[     ]+fli\.d[               ]+ft1,0x1p-1
> > +[      ]+[0-9a-f]+:[   ]+f21680d3[     ]+fli\.d[               ]+ft1,0x1.4p-1
> > +[      ]+[0-9a-f]+:[   ]+f21700d3[     ]+fli\.d[               ]+ft1,0x1.8p-1
> > +[      ]+[0-9a-f]+:[   ]+f21780d3[     ]+fli\.d[               ]+ft1,0x1.cp-1
> > +[      ]+[0-9a-f]+:[   ]+f61800d3[     ]+fli\.q[               ]+ft1,0x1p\+0
> > +[      ]+[0-9a-f]+:[   ]+f61880d3[     ]+fli\.q[               ]+ft1,0x1.4p\+0
> > +[      ]+[0-9a-f]+:[   ]+f61900d3[     ]+fli\.q[               ]+ft1,0x1.8p\+0
> > +[      ]+[0-9a-f]+:[   ]+f61980d3[     ]+fli\.q[               ]+ft1,0x1.cp\+0
> > +[      ]+[0-9a-f]+:[   ]+f61a00d3[     ]+fli\.q[               ]+ft1,0x1p\+1
> > +[      ]+[0-9a-f]+:[   ]+f61a80d3[     ]+fli\.q[               ]+ft1,0x1.4p\+1
> > +[      ]+[0-9a-f]+:[   ]+f61b00d3[     ]+fli\.q[               ]+ft1,0x1.8p\+1
> > +[      ]+[0-9a-f]+:[   ]+f61b80d3[     ]+fli\.q[               ]+ft1,0x1p\+2
> > +[      ]+[0-9a-f]+:[   ]+f41c00d3[     ]+fli\.h[               ]+ft1,0x1p\+3
> > +[      ]+[0-9a-f]+:[   ]+f41c80d3[     ]+fli\.h[               ]+ft1,0x1p\+4
> > +[      ]+[0-9a-f]+:[   ]+f41d00d3[     ]+fli\.h[               ]+ft1,0x1p\+7
> > +[      ]+[0-9a-f]+:[   ]+f41d80d3[     ]+fli\.h[               ]+ft1,0x1p\+8
> > +[      ]+[0-9a-f]+:[   ]+f41e00d3[     ]+fli\.h[               ]+ft1,0x1p\+15
> > +[      ]+[0-9a-f]+:[   ]+f41e80d3[     ]+fli\.h[               ]+ft1,0x1p\+16
> > +[      ]+[0-9a-f]+:[   ]+f41f00d3[     ]+fli\.h[               ]+ft1,inf
> > +[      ]+[0-9a-f]+:[   ]+f41f80d3[     ]+fli\.h[               ]+ft1,nan
> > +[      ]+[0-9a-f]+:[   ]+2c3100d3[     ]+fmin\.h[              ]+ft1,ft2,ft3
> > +[      ]+[0-9a-f]+:[   ]+2c3120d3[     ]+fminm\.h[             ]+ft1,ft2,ft3
> > +[      ]+[0-9a-f]+:[   ]+283100d3[     ]+fmin\.s[              ]+ft1,ft2,ft3
> > +[      ]+[0-9a-f]+:[   ]+283120d3[     ]+fminm\.s[             ]+ft1,ft2,ft3
> > +[      ]+[0-9a-f]+:[   ]+2a3100d3[     ]+fmin\.d[              ]+ft1,ft2,ft3
> > +[      ]+[0-9a-f]+:[   ]+2a3120d3[     ]+fminm\.d[             ]+ft1,ft2,ft3
> > +[      ]+[0-9a-f]+:[   ]+2e3100d3[     ]+fmin\.q[              ]+ft1,ft2,ft3
> > +[      ]+[0-9a-f]+:[   ]+2e3120d3[     ]+fminm\.q[             ]+ft1,ft2,ft3
> > +[      ]+[0-9a-f]+:[   ]+2c3110d3[     ]+fmax\.h[              ]+ft1,ft2,ft3
> > +[      ]+[0-9a-f]+:[   ]+2c3130d3[     ]+fmaxm\.h[             ]+ft1,ft2,ft3
> > +[      ]+[0-9a-f]+:[   ]+283110d3[     ]+fmax\.s[              ]+ft1,ft2,ft3
> > +[      ]+[0-9a-f]+:[   ]+283130d3[     ]+fmaxm\.s[             ]+ft1,ft2,ft3
> > +[      ]+[0-9a-f]+:[   ]+2a3110d3[     ]+fmax\.d[              ]+ft1,ft2,ft3
> > +[      ]+[0-9a-f]+:[   ]+2a3130d3[     ]+fmaxm\.d[             ]+ft1,ft2,ft3
> > +[      ]+[0-9a-f]+:[   ]+2e3110d3[     ]+fmax\.q[              ]+ft1,ft2,ft3
> > +[      ]+[0-9a-f]+:[   ]+2e3130d3[     ]+fmaxm\.q[             ]+ft1,ft2,ft3
> > +[      ]+[0-9a-f]+:[   ]+4445f553[     ]+fround\.h[            ]+fa0,fa1
> > +[      ]+[0-9a-f]+:[   ]+44459553[     ]+fround\.h[            ]+fa0,fa1,rtz
> > +[      ]+[0-9a-f]+:[   ]+4045f553[     ]+fround\.s[            ]+fa0,fa1
> > +[      ]+[0-9a-f]+:[   ]+40459553[     ]+fround\.s[            ]+fa0,fa1,rtz
> > +[      ]+[0-9a-f]+:[   ]+4245f553[     ]+fround\.d[            ]+fa0,fa1
> > +[      ]+[0-9a-f]+:[   ]+42459553[     ]+fround\.d[            ]+fa0,fa1,rtz
> > +[      ]+[0-9a-f]+:[   ]+4645f553[     ]+fround\.q[            ]+fa0,fa1
> > +[      ]+[0-9a-f]+:[   ]+46459553[     ]+fround\.q[            ]+fa0,fa1,rtz
> > +[      ]+[0-9a-f]+:[   ]+4455f553[     ]+froundnx\.h[          ]+fa0,fa1
> > +[      ]+[0-9a-f]+:[   ]+44559553[     ]+froundnx\.h[          ]+fa0,fa1,rtz
> > +[      ]+[0-9a-f]+:[   ]+4055f553[     ]+froundnx\.s[          ]+fa0,fa1
> > +[      ]+[0-9a-f]+:[   ]+40559553[     ]+froundnx\.s[          ]+fa0,fa1,rtz
> > +[      ]+[0-9a-f]+:[   ]+4255f553[     ]+froundnx\.d[          ]+fa0,fa1
> > +[      ]+[0-9a-f]+:[   ]+42559553[     ]+froundnx\.d[          ]+fa0,fa1,rtz
> > +[      ]+[0-9a-f]+:[   ]+4655f553[     ]+froundnx\.q[          ]+fa0,fa1
> > +[      ]+[0-9a-f]+:[   ]+46559553[     ]+froundnx\.q[          ]+fa0,fa1,rtz
> > +[      ]+[0-9a-f]+:[   ]+c2809553[     ]+fcvtmod\.w\.d[        ]+a0,ft1,rtz
> > +[      ]+[0-9a-f]+:[   ]+a4209553[     ]+flt\.h[               ]+a0,ft1,ft2
> > +[      ]+[0-9a-f]+:[   ]+a420d553[     ]+fltq\.h[              ]+a0,ft1,ft2
> > +[      ]+[0-9a-f]+:[   ]+a0209553[     ]+flt\.s[               ]+a0,ft1,ft2
> > +[      ]+[0-9a-f]+:[   ]+a020d553[     ]+fltq\.s[              ]+a0,ft1,ft2
> > +[      ]+[0-9a-f]+:[   ]+a2209553[     ]+flt\.d[               ]+a0,ft1,ft2
> > +[      ]+[0-9a-f]+:[   ]+a220d553[     ]+fltq\.d[              ]+a0,ft1,ft2
> > +[      ]+[0-9a-f]+:[   ]+a6209553[     ]+flt\.q[               ]+a0,ft1,ft2
> > +[      ]+[0-9a-f]+:[   ]+a620d553[     ]+fltq\.q[              ]+a0,ft1,ft2
> > +[      ]+[0-9a-f]+:[   ]+a4208553[     ]+fle\.h[               ]+a0,ft1,ft2
> > +[      ]+[0-9a-f]+:[   ]+a420c553[     ]+fleq\.h[              ]+a0,ft1,ft2
> > +[      ]+[0-9a-f]+:[   ]+a0208553[     ]+fle\.s[               ]+a0,ft1,ft2
> > +[      ]+[0-9a-f]+:[   ]+a020c553[     ]+fleq\.s[              ]+a0,ft1,ft2
> > +[      ]+[0-9a-f]+:[   ]+a2208553[     ]+fle\.d[               ]+a0,ft1,ft2
> > +[      ]+[0-9a-f]+:[   ]+a220c553[     ]+fleq\.d[              ]+a0,ft1,ft2
> > +[      ]+[0-9a-f]+:[   ]+a6208553[     ]+fle\.q[               ]+a0,ft1,ft2
> > +[      ]+[0-9a-f]+:[   ]+a620c553[     ]+fleq\.q[              ]+a0,ft1,ft2
> > diff --git a/gas/testsuite/gas/riscv/zfa.s b/gas/testsuite/gas/riscv/zfa.s
> > new file mode 100644
> > index 00000000000..7fbcb17b611
> > --- /dev/null
> > +++ b/gas/testsuite/gas/riscv/zfa.s
> > @@ -0,0 +1,87 @@
> > +target:
> > +       # fli
> > +       fli.s           ft1, -1
> > +       fli.s           ft1, min
> > +       fli.s           ft1, 0.0000152587890625
> > +       fli.s           ft1, 0x1p-15
> > +       fli.s           ft1, 0.00390625
> > +       fli.s           ft1, 0x1p-7
> > +       fli.s           ft1, 0.0625
> > +       fli.s           ft1, 0x1p-3
> > +       fli.d           ft1, 0.25
> > +       fli.d           ft1, 0x1.4p-2
> > +       fli.d           ft1, 0.375
> > +       fli.d           ft1, 0x1.cp-2
> > +       fli.d           ft1, 0.5
> > +       fli.d           ft1, 0x1.4p-1
> > +       fli.d           ft1, 0.75
> > +       fli.d           ft1, 0x1.cp-1
> > +       fli.q           ft1, 1
> > +       fli.q           ft1, 0x1.4p+0
> > +       fli.q           ft1, 1.5
> > +       fli.q           ft1, 0x1.cp0
> > +       fli.q           ft1, 2.0
> > +       fli.q           ft1, 0x1.4p+1
> > +       fli.q           ft1, 3
> > +       fli.q           ft1, 0x1p2
> > +       fli.h           ft1, 8.0
> > +       fli.h           ft1, 0x1p4
> > +       fli.h           ft1, 128.0
> > +       fli.h           ft1, 0x1p8
> > +       fli.h           ft1, 32768.0
> > +       fli.h           ft1, 0x1p16
> > +       fli.h           ft1, inf
> > +       fli.h           ft1, nan
> > +       # fminm/fmaxm
> > +       fmin.h          ft1, ft2, ft3
> > +       fminm.h         ft1, ft2, ft3
> > +       fmin.s          ft1, ft2, ft3
> > +       fminm.s         ft1, ft2, ft3
> > +       fmin.d          ft1, ft2, ft3
> > +       fminm.d         ft1, ft2, ft3
> > +       fmin.q          ft1, ft2, ft3
> > +       fminm.q         ft1, ft2, ft3
> > +       fmax.h          ft1, ft2, ft3
> > +       fmaxm.h         ft1, ft2, ft3
> > +       fmax.s          ft1, ft2, ft3
> > +       fmaxm.s         ft1, ft2, ft3
> > +       fmax.d          ft1, ft2, ft3
> > +       fmaxm.d         ft1, ft2, ft3
> > +       fmax.q          ft1, ft2, ft3
> > +       fmaxm.q         ft1, ft2, ft3
> > +       # fround/froundnx
> > +       fround.h        fa0, fa1
> > +       fround.h        fa0, fa1, rtz
> > +       fround.s        fa0, fa1
> > +       fround.s        fa0, fa1, rtz
> > +       fround.d        fa0, fa1
> > +       fround.d        fa0, fa1, rtz
> > +       fround.q        fa0, fa1
> > +       fround.q        fa0, fa1, rtz
> > +       froundnx.h      fa0, fa1
> > +       froundnx.h      fa0, fa1, rtz
> > +       froundnx.s      fa0, fa1
> > +       froundnx.s      fa0, fa1, rtz
> > +       froundnx.d      fa0, fa1
> > +       froundnx.d      fa0, fa1, rtz
> > +       froundnx.q      fa0, fa1
> > +       froundnx.q      fa0, fa1, rtz
> > +       # fcvtmod.w.d
> > +       fcvtmod.w.d     a0, ft1, rtz
> > +       # fltq/fleq
> > +       flt.h           a0, ft1, ft2
> > +       fltq.h          a0, ft1, ft2
> > +       flt.s           a0, ft1, ft2
> > +       fltq.s          a0, ft1, ft2
> > +       flt.d           a0, ft1, ft2
> > +       fltq.d          a0, ft1, ft2
> > +       flt.q           a0, ft1, ft2
> > +       fltq.q          a0, ft1, ft2
> > +       fle.h           a0, ft1, ft2
> > +       fleq.h          a0, ft1, ft2
> > +       fle.s           a0, ft1, ft2
> > +       fleq.s          a0, ft1, ft2
> > +       fle.d           a0, ft1, ft2
> > +       fleq.d          a0, ft1, ft2
> > +       fle.q           a0, ft1, ft2
> > +       fleq.q          a0, ft1, ft2
> > diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
> > index 85d35c1efc9..e141c377bde 100644
> > --- a/include/opcode/riscv-opc.h
> > +++ b/include/opcode/riscv-opc.h
> > @@ -419,6 +419,72 @@
> >  #define MASK_FCVT_Q_L  0xfff0007f
> >  #define MATCH_FCVT_Q_LU 0xd6300053
> >  #define MASK_FCVT_Q_LU  0xfff0007f
> > +#define MATCH_FLI_H 0xf4100053
> > +#define MASK_FLI_H 0xfff0707f
> > +#define MATCH_FMINM_H 0x2c002053
> > +#define MASK_FMINM_H 0xfe00707f
> > +#define MATCH_FMAXM_H 0x2c003053
> > +#define MASK_FMAXM_H 0xfe00707f
> > +#define MATCH_FROUND_H 0x44400053
> > +#define MASK_FROUND_H 0xfff0007f
> > +#define MATCH_FROUNDNX_H 0x44500053
> > +#define MASK_FROUNDNX_H 0xfff0007f
> > +#define MATCH_FLTQ_H 0xa4005053
> > +#define MASK_FLTQ_H 0xfe00707f
> > +#define MATCH_FLEQ_H 0xa4004053
> > +#define MASK_FLEQ_H 0xfe00707f
> > +#define MATCH_FLI_S 0xf0100053
> > +#define MASK_FLI_S 0xfff0707f
> > +#define MATCH_FMINM_S 0x28002053
> > +#define MASK_FMINM_S 0xfe00707f
> > +#define MATCH_FMAXM_S 0x28003053
> > +#define MASK_FMAXM_S 0xfe00707f
> > +#define MATCH_FROUND_S 0x40400053
> > +#define MASK_FROUND_S 0xfff0007f
> > +#define MATCH_FROUNDNX_S 0x40500053
> > +#define MASK_FROUNDNX_S 0xfff0007f
> > +#define MATCH_FLTQ_S 0xa0005053
> > +#define MASK_FLTQ_S 0xfe00707f
> > +#define MATCH_FLEQ_S 0xa0004053
> > +#define MASK_FLEQ_S 0xfe00707f
> > +#define MATCH_FLI_D 0xf2100053
> > +#define MASK_FLI_D 0xfff0707f
> > +#define MATCH_FMINM_D 0x2a002053
> > +#define MASK_FMINM_D 0xfe00707f
> > +#define MATCH_FMAXM_D 0x2a003053
> > +#define MASK_FMAXM_D 0xfe00707f
> > +#define MATCH_FROUND_D 0x42400053
> > +#define MASK_FROUND_D 0xfff0007f
> > +#define MATCH_FROUNDNX_D 0x42500053
> > +#define MASK_FROUNDNX_D 0xfff0007f
> > +#define MATCH_FLTQ_D 0xa2005053
> > +#define MASK_FLTQ_D 0xfe00707f
> > +#define MATCH_FLEQ_D 0xa2004053
> > +#define MASK_FLEQ_D 0xfe00707f
> > +#define MATCH_FLI_Q 0xf6100053
> > +#define MASK_FLI_Q 0xfff0707f
> > +#define MATCH_FMINM_Q 0x2e002053
> > +#define MASK_FMINM_Q 0xfe00707f
> > +#define MATCH_FMAXM_Q 0x2e003053
> > +#define MASK_FMAXM_Q 0xfe00707f
> > +#define MATCH_FROUND_Q 0x46400053
> > +#define MASK_FROUND_Q 0xfff0007f
> > +#define MATCH_FROUNDNX_Q 0x46500053
> > +#define MASK_FROUNDNX_Q 0xfff0007f
> > +#define MATCH_FLTQ_Q 0xa6005053
> > +#define MASK_FLTQ_Q 0xfe00707f
> > +#define MATCH_FLEQ_Q 0xa6004053
> > +#define MASK_FLEQ_Q 0xfe00707f
> > +#define MATCH_FCVTMOD_W_D 0xc2801053
> > +#define MASK_FCVTMOD_W_D 0xfff0707f
> > +#define MATCH_FMVH_X_D 0xe2100053
> > +#define MASK_FMVH_X_D 0xfff0707f
> > +#define MATCH_FMVH_X_Q 0xe6100053
> > +#define MASK_FMVH_X_Q 0xfff0707f
> > +#define MATCH_FMVP_D_X 0xb2000053
> > +#define MASK_FMVP_D_X 0xfe00707f
> > +#define MATCH_FMVP_Q_X 0xb6000053
> > +#define MASK_FMVP_Q_X 0xfe00707f
> >  #define MATCH_CLZ 0x60001013
> >  #define MASK_CLZ  0xfff0707f
> >  #define MATCH_CTZ 0x60101013
> > @@ -2981,6 +3047,39 @@ DECLARE_INSN(fcvt_q_w, MATCH_FCVT_Q_W, MASK_FCVT_Q_W)
> >  DECLARE_INSN(fcvt_q_wu, MATCH_FCVT_Q_WU, MASK_FCVT_Q_WU)
> >  DECLARE_INSN(fcvt_q_l, MATCH_FCVT_Q_L, MASK_FCVT_Q_L)
> >  DECLARE_INSN(fcvt_q_lu, MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU)
> > +DECLARE_INSN(fli_h, MATCH_FLI_H, MASK_FLI_H)
> > +DECLARE_INSN(fminm_h, MATCH_FMINM_H, MASK_FMINM_H)
> > +DECLARE_INSN(fmaxm_h, MATCH_FMAXM_H, MASK_FMAXM_H)
> > +DECLARE_INSN(fround_h, MATCH_FROUND_H, MASK_FROUND_H)
> > +DECLARE_INSN(fround_nx_h, MATCH_FROUNDNX_H, MASK_FROUNDNX_H)
> > +DECLARE_INSN(fltq_h, MATCH_FLTQ_H, MASK_FLTQ_H)
> > +DECLARE_INSN(fleq_h, MATCH_FLEQ_H, MASK_FLEQ_H)
> > +DECLARE_INSN(fli_s, MATCH_FLI_S, MASK_FLI_S)
> > +DECLARE_INSN(fminm_s, MATCH_FMINM_S, MASK_FMINM_S)
> > +DECLARE_INSN(fmaxm_s, MATCH_FMAXM_S, MASK_FMAXM_S)
> > +DECLARE_INSN(fround_s, MATCH_FROUND_S, MASK_FROUND_S)
> > +DECLARE_INSN(fround_nx_s, MATCH_FROUNDNX_S, MASK_FROUNDNX_S)
> > +DECLARE_INSN(fltq_s, MATCH_FLTQ_S, MASK_FLTQ_S)
> > +DECLARE_INSN(fleq_s, MATCH_FLEQ_S, MASK_FLEQ_S)
> > +DECLARE_INSN(fli_d, MATCH_FLI_D, MASK_FLI_D)
> > +DECLARE_INSN(fminm_d, MATCH_FMINM_D, MASK_FMINM_D)
> > +DECLARE_INSN(fmaxm_d, MATCH_FMAXM_D, MASK_FMAXM_D)
> > +DECLARE_INSN(fround_d, MATCH_FROUND_D, MASK_FROUND_D)
> > +DECLARE_INSN(fround_nx_d, MATCH_FROUNDNX_D, MASK_FROUNDNX_D)
> > +DECLARE_INSN(fltq_d, MATCH_FLTQ_D, MASK_FLTQ_D)
> > +DECLARE_INSN(fleq_d, MATCH_FLEQ_D, MASK_FLEQ_D)
> > +DECLARE_INSN(fli_q, MATCH_FLI_Q, MASK_FLI_Q)
> > +DECLARE_INSN(fminm_q, MATCH_FMINM_Q, MASK_FMINM_Q)
> > +DECLARE_INSN(fmaxm_q, MATCH_FMAXM_Q, MASK_FMAXM_Q)
> > +DECLARE_INSN(fround_q, MATCH_FROUND_Q, MASK_FROUND_Q)
> > +DECLARE_INSN(fround_nx_q, MATCH_FROUNDNX_Q, MASK_FROUNDNX_Q)
> > +DECLARE_INSN(fltq_q, MATCH_FLTQ_Q, MASK_FLTQ_Q)
> > +DECLARE_INSN(fleq_q, MATCH_FLEQ_Q, MASK_FLEQ_Q)
> > +DECLARE_INSN(fcvtmod_w_d, MATCH_FCVTMOD_W_D, MASK_FCVTMOD_W_D)
> > +DECLARE_INSN(fmvh_x_d, MATCH_FMVH_X_D, MASK_FMVH_X_D)
> > +DECLARE_INSN(fmvh_x_q, MATCH_FMVH_X_Q, MASK_FMVH_X_Q)
> > +DECLARE_INSN(fmvp_d_x, MATCH_FMVP_D_X, MASK_FMVP_D_X)
> > +DECLARE_INSN(fmvp_q_x, MATCH_FMVP_Q_X, MASK_FMVP_Q_X)
> >  DECLARE_INSN(clz, MATCH_CLZ, MASK_CLZ)
> >  DECLARE_INSN(ctz, MATCH_CTZ, MASK_CTZ)
> >  DECLARE_INSN(cpop, MATCH_CPOP, MASK_CPOP)
> > diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
> > index b4ae55249bb..accdf7db698 100644
> > --- a/include/opcode/riscv.h
> > +++ b/include/opcode/riscv.h
> > @@ -388,6 +388,10 @@ enum riscv_insn_class
> >    INSN_CLASS_ZFHMIN_INX,
> >    INSN_CLASS_ZFHMIN_AND_D_INX,
> >    INSN_CLASS_ZFHMIN_AND_Q_INX,
> > +  INSN_CLASS_ZFA,
> > +  INSN_CLASS_D_AND_ZFA,
> > +  INSN_CLASS_Q_AND_ZFA,
> > +  INSN_CLASS_ZFH_AND_ZFA,
> >    INSN_CLASS_ZBA,
> >    INSN_CLASS_ZBB,
> >    INSN_CLASS_ZBC,
> > @@ -554,6 +558,8 @@ extern const char * const riscv_vsew[8];
> >  extern const char * const riscv_vlmul[8];
> >  extern const char * const riscv_vta[2];
> >  extern const char * const riscv_vma[2];
> > +extern const char * const riscv_fli_symval[32];
> > +extern const float riscv_fli_numval[32];
> >
> >  extern const struct riscv_opcode riscv_opcodes[];
> >  extern const struct riscv_opcode riscv_insn_types[];
> > diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
> > index 3aaa45f419c..65ea6339c9a 100644
> > --- a/opcodes/riscv-dis.c
> > +++ b/opcodes/riscv-dis.c
> > @@ -592,6 +592,21 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
> >                     goto undefined_modifier;
> >                   }
> >                   break;
> > +             case 'f':
> > +               switch (*++oparg)
> > +                 {
> > +                 case 'v':
> > +                   if (riscv_fli_symval[rs1])
> > +                     print (info->stream, dis_style_text, "%s",
> > +                            riscv_fli_symval[rs1]);
> > +                   else
> > +                     print (info->stream, dis_style_immediate, "%a",
> > +                            riscv_fli_numval[rs1]);
> > +                   break;
> > +                 default:
> > +                   goto undefined_modifier;
> > +                 }
> > +               break;
> >               default:
> >                 goto undefined_modifier;
> >               }
> > @@ -640,6 +655,7 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
> >               }
> >           }
> >           break;
> > +
> >         default:
> >         undefined_modifier:
> >           /* xgettext:c-format */
> > diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
> > index d9d69cda548..4b970db9bcf 100644
> > --- a/opcodes/riscv-opc.c
> > +++ b/opcodes/riscv-opc.c
> > @@ -110,6 +110,27 @@ const char * const riscv_vma[2] =
> >    "mu", "ma"
> >  };
> >
> > +/* The FLI.[HSDQ] symbolic constants (NULL for numeric constant).  */
> > +const char * const riscv_fli_symval[32] =
> > +{
> > +  NULL,  "min", NULL,  NULL,  NULL,  NULL,  NULL,  NULL,
> > +  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,
> > +  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,
> > +  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  "inf", "nan",
> > +};
> > +
> > +/* The FLI.[HSDQ] numeric constants (0.0 for symbolic constants).
> > +   The constants use the hex floating-point literal representation
> > +   that is printed when using the printf %a format specifier,
> > +   which matches the output that is generated by the disassembler.  */
> > +const float riscv_fli_numval[32] =
> > +{
> > +  -0x1p+0, 0x0p+0, 0x1p-16, 0x1p-15, 0x1p-8, 0x1p-7, 0x1p-4, 0x1p-3,
> > +  0x1p-2, 0x1.4p-2, 0x1.8p-2, 0x1.cp-2, 0x1p-1, 0x1.4p-1, 0x1.8p-1, 0x1.cp-1,
> > +  0x1p+0, 0x1.4p+0, 0x1.8p+0, 0x1.cp+0, 0x1p+1, 0x1.4p+1, 0x1.8p+1, 0x1p+2,
> > +  0x1p+3, 0x1p+4, 0x1p+7, 0x1p+8, 0x1p+15, 0x1p+16, 0x0p+0, 0x0p+0
> > +};
> > +
> >  /* The order of overloaded instructions matters.  Label arguments and
> >     register arguments look the same. Instructions that can have either
> >     for arguments must apear in the correct order in this table for the
> > @@ -939,6 +960,49 @@ 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 },
> >
> > +/* 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 },
> > +{"fli.q",       0, INSN_CLASS_Q_AND_ZFA,   "D,Wfv", MATCH_FLI_Q, MASK_FLI_Q, match_opcode, 0 },
> > +{"fli.h",       0, INSN_CLASS_ZFH_AND_ZFA, "D,Wfv", MATCH_FLI_H, MASK_FLI_H, match_opcode, 0 },
> > +{"fminm.s",     0, INSN_CLASS_ZFA,         "D,S,T", MATCH_FMINM_S, MASK_FMINM_S, match_opcode, 0 },
> > +{"fmaxm.s",     0, INSN_CLASS_ZFA,         "D,S,T", MATCH_FMAXM_S, MASK_FMAXM_S, match_opcode, 0 },
> > +{"fminm.d",     0, INSN_CLASS_D_AND_ZFA,   "D,S,T", MATCH_FMINM_D, MASK_FMINM_D, match_opcode, 0 },
> > +{"fmaxm.d",     0, INSN_CLASS_D_AND_ZFA,   "D,S,T", MATCH_FMAXM_D, MASK_FMAXM_D, match_opcode, 0 },
> > +{"fminm.q",     0, INSN_CLASS_Q_AND_ZFA,   "D,S,T", MATCH_FMINM_Q, MASK_FMINM_Q, match_opcode, 0 },
> > +{"fmaxm.q",     0, INSN_CLASS_Q_AND_ZFA,   "D,S,T", MATCH_FMAXM_Q, MASK_FMAXM_Q, match_opcode, 0 },
> > +{"fminm.h",     0, INSN_CLASS_ZFH_AND_ZFA, "D,S,T", MATCH_FMINM_H, MASK_FMINM_H, match_opcode, 0 },
> > +{"fmaxm.h",     0, INSN_CLASS_ZFH_AND_ZFA, "D,S,T", MATCH_FMAXM_H, MASK_FMAXM_H, match_opcode, 0 },
> > +{"fround.s",    0, INSN_CLASS_ZFA,         "D,S",   MATCH_FROUND_S|MASK_RM, MASK_FROUND_S|MASK_RM, match_opcode, 0 },
> > +{"fround.s",    0, INSN_CLASS_ZFA,         "D,S,m", MATCH_FROUND_S, MASK_FROUND_S, match_opcode, 0 },
> > +{"froundnx.s",  0, INSN_CLASS_ZFA,         "D,S",   MATCH_FROUNDNX_S|MASK_RM, MASK_FROUNDNX_S|MASK_RM, match_opcode, 0 },
> > +{"froundnx.s",  0, INSN_CLASS_ZFA,         "D,S,m", MATCH_FROUNDNX_S, MASK_FROUNDNX_S, match_opcode, 0 },
> > +{"fround.d",    0, INSN_CLASS_D_AND_ZFA,   "D,S",   MATCH_FROUND_D|MASK_RM, MASK_FROUND_D|MASK_RM, match_opcode, 0 },
> > +{"fround.d",    0, INSN_CLASS_D_AND_ZFA,   "D,S,m", MATCH_FROUND_D, MASK_FROUND_D, match_opcode, 0 },
> > +{"froundnx.d",  0, INSN_CLASS_D_AND_ZFA,   "D,S",   MATCH_FROUNDNX_D|MASK_RM, MASK_FROUNDNX_D|MASK_RM, match_opcode, 0 },
> > +{"froundnx.d",  0, INSN_CLASS_D_AND_ZFA,   "D,S,m", MATCH_FROUNDNX_D, MASK_FROUNDNX_D, match_opcode, 0 },
> > +{"fround.q",    0, INSN_CLASS_Q_AND_ZFA,   "D,S",   MATCH_FROUND_Q|MASK_RM, MASK_FROUND_Q|MASK_RM, match_opcode, 0 },
> > +{"fround.q",    0, INSN_CLASS_Q_AND_ZFA,   "D,S,m", MATCH_FROUND_Q, MASK_FROUND_Q, match_opcode, 0 },
> > +{"froundnx.q",  0, INSN_CLASS_Q_AND_ZFA,   "D,S",   MATCH_FROUNDNX_Q|MASK_RM, MASK_FROUNDNX_Q|MASK_RM, match_opcode, 0 },
> > +{"froundnx.q",  0, INSN_CLASS_Q_AND_ZFA,   "D,S,m", MATCH_FROUNDNX_Q, MASK_FROUNDNX_Q, match_opcode, 0 },
> > +{"fround.h",    0, INSN_CLASS_ZFH_AND_ZFA, "D,S",   MATCH_FROUND_H|MASK_RM, MASK_FROUND_H|MASK_RM, match_opcode, 0 },
> > +{"fround.h",    0, INSN_CLASS_ZFH_AND_ZFA, "D,S,m", MATCH_FROUND_H, MASK_FROUND_H, match_opcode, 0 },
> > +{"froundnx.h",  0, INSN_CLASS_ZFH_AND_ZFA, "D,S",   MATCH_FROUNDNX_H|MASK_RM, MASK_FROUNDNX_H|MASK_RM, match_opcode, 0 },
> > +{"froundnx.h",  0, INSN_CLASS_ZFH_AND_ZFA, "D,S,m", MATCH_FROUNDNX_H, MASK_FROUNDNX_H, match_opcode, 0 },
> > +{"fcvtmod.w.d", 0, INSN_CLASS_D_AND_ZFA,   "d,S,m", MATCH_FCVTMOD_W_D, MASK_FCVTMOD_W_D, match_opcode, 0 },
> > +{"fmvh.x.d",   32, INSN_CLASS_D_AND_ZFA,   "d,S",   MATCH_FMVH_X_D, MASK_FMVH_X_D, match_opcode, 0 },
> > +{"fmvp.d.x",   32, INSN_CLASS_D_AND_ZFA,   "D,s,t", MATCH_FMVP_D_X, MASK_FMVP_D_X, match_opcode, 0 },
> > +{"fmvh.x.q",   64, INSN_CLASS_Q_AND_ZFA,   "d,S",   MATCH_FMVH_X_Q, MASK_FMVH_X_Q, match_opcode, 0 },
> > +{"fmvp.q.x",   64, INSN_CLASS_Q_AND_ZFA,   "D,s,t", MATCH_FMVP_Q_X, MASK_FMVP_Q_X, match_opcode, 0 },
> > +{"fltq.s",      0, INSN_CLASS_ZFA,         "d,S,T", MATCH_FLTQ_S, MASK_FLTQ_S, match_opcode, 0 },
> > +{"fleq.s",      0, INSN_CLASS_ZFA,         "d,S,T", MATCH_FLEQ_S, MASK_FLEQ_S, match_opcode, 0 },
> > +{"fltq.d",      0, INSN_CLASS_D_AND_ZFA,   "d,S,T", MATCH_FLTQ_D, MASK_FLTQ_D, match_opcode, 0 },
> > +{"fleq.d",      0, INSN_CLASS_D_AND_ZFA,   "d,S,T", MATCH_FLEQ_D, MASK_FLEQ_D, match_opcode, 0 },
> > +{"fltq.q",      0, INSN_CLASS_Q_AND_ZFA,   "d,S,T", MATCH_FLTQ_Q, MASK_FLTQ_Q, match_opcode, 0 },
> > +{"fleq.q",      0, INSN_CLASS_Q_AND_ZFA,   "d,S,T", MATCH_FLEQ_Q, MASK_FLEQ_Q, match_opcode, 0 },
> > +{"fltq.h",      0, INSN_CLASS_ZFH_AND_ZFA, "d,S,T", MATCH_FLTQ_H, MASK_FLTQ_H, match_opcode, 0 },
> > +{"fleq.h",      0, INSN_CLASS_ZFH_AND_ZFA, "d,S,T", MATCH_FLEQ_H, MASK_FLEQ_H, match_opcode, 0 },
> > +
> >  /* Zbb or zbkb instructions.  */
> >  {"clz",        0, INSN_CLASS_ZBB,  "d,s",   MATCH_CLZ, MASK_CLZ, match_opcode, 0 },
> >  {"ctz",        0, INSN_CLASS_ZBB,  "d,s",   MATCH_CTZ, MASK_CTZ, match_opcode, 0 },
> > --
> > 2.39.2
> >

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC PATCH v5] RISC-V: Add support for the Zfa extension
  2023-06-29  7:52 ` Christoph Müllner
  2023-06-29  8:33   ` Christoph Müllner
@ 2023-06-29 15:07   ` Jeff Law
  2023-06-29 15:10     ` Christoph Müllner
  1 sibling, 1 reply; 19+ messages in thread
From: Jeff Law @ 2023-06-29 15:07 UTC (permalink / raw)
  To: Christoph Müllner, binutils, Nelson Chu, Andrew Waterman,
	Palmer Dabbelt, Jim Wilson, Philipp Tomsich, Jan Beulich,
	Kito Cheng, Tsukasa OI



On 6/29/23 01:52, Christoph Müllner wrote:
> The RISC-V Zfa extension has been frozen.
> 
> As this was discussed elsewhere yesterday:
> * Should this patch wait for ratification?
> * Is this blocked by https://github.com/riscv-non-isa/riscv-asm-manual/pull/85 ?
> 
> Nelson stated on Apr 12 (response to v4):
> "If there are no new instructions or encodings/formats changed in the
> future spec, then you should commit the patch when the extension is
> ratified."
> 
> So my understanding is that this needs to wait for ratification and is
> not blocked by the mentioned PR.
Is there something special about Zfa that makes it desirable to wait for 
ratification as opposed to standard practice of gating things as the 
specs get to a Frozen state?

jeff

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC PATCH v5] RISC-V: Add support for the Zfa extension
  2023-06-29 15:07   ` Jeff Law
@ 2023-06-29 15:10     ` Christoph Müllner
  2023-06-29 15:37       ` Palmer Dabbelt
  0 siblings, 1 reply; 19+ messages in thread
From: Christoph Müllner @ 2023-06-29 15:10 UTC (permalink / raw)
  To: Jeff Law
  Cc: binutils, Nelson Chu, Andrew Waterman, Palmer Dabbelt,
	Jim Wilson, Philipp Tomsich, Jan Beulich, Kito Cheng, Tsukasa OI

On Thu, Jun 29, 2023 at 5:07 PM Jeff Law <jeffreyalaw@gmail.com> wrote:
>
>
>
> On 6/29/23 01:52, Christoph Müllner wrote:
> > The RISC-V Zfa extension has been frozen.
> >
> > As this was discussed elsewhere yesterday:
> > * Should this patch wait for ratification?
> > * Is this blocked by https://github.com/riscv-non-isa/riscv-asm-manual/pull/85 ?
> >
> > Nelson stated on Apr 12 (response to v4):
> > "If there are no new instructions or encodings/formats changed in the
> > future spec, then you should commit the patch when the extension is
> > ratified."
> >
> > So my understanding is that this needs to wait for ratification and is
> > not blocked by the mentioned PR.
> Is there something special about Zfa that makes it desirable to wait for
> ratification as opposed to standard practice of gating things as the
> specs get to a Frozen state?

Not to my knowledge.

BR
Christoph

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC PATCH v5] RISC-V: Add support for the Zfa extension
  2023-06-29 15:10     ` Christoph Müllner
@ 2023-06-29 15:37       ` Palmer Dabbelt
  2023-06-29 15:49         ` Jeff Law
  0 siblings, 1 reply; 19+ messages in thread
From: Palmer Dabbelt @ 2023-06-29 15:37 UTC (permalink / raw)
  To: christoph.muellner
  Cc: jeffreyalaw, binutils, nelson, Andrew Waterman, Jim Wilson,
	philipp.tomsich, jbeulich, Kito Cheng, research_trasio

On Thu, 29 Jun 2023 08:10:40 PDT (-0700), christoph.muellner@vrull.eu wrote:
> On Thu, Jun 29, 2023 at 5:07 PM Jeff Law <jeffreyalaw@gmail.com> wrote:
>>
>>
>>
>> On 6/29/23 01:52, Christoph Müllner wrote:
>> > The RISC-V Zfa extension has been frozen.
>> >
>> > As this was discussed elsewhere yesterday:
>> > * Should this patch wait for ratification?
>> > * Is this blocked by https://github.com/riscv-non-isa/riscv-asm-manual/pull/85 ?
>> >
>> > Nelson stated on Apr 12 (response to v4):
>> > "If there are no new instructions or encodings/formats changed in the
>> > future spec, then you should commit the patch when the extension is
>> > ratified."
>> >
>> > So my understanding is that this needs to wait for ratification and is
>> > not blocked by the mentioned PR.
>> Is there something special about Zfa that makes it desirable to wait for
>> ratification as opposed to standard practice of gating things as the
>> specs get to a Frozen state?
>
> Not to my knowledge.

Waiting for ratification is probably a bad idea, there's really no way 
to schedule around it.  That's a big part of the reason we've just 
waited for frozen.

IIUC we're just waiting on the assembler syntax to be accepted, it's not 
an ISA problem right now.

That said, we haven't historically even waited for RVI to define 
assembly syntax.  I think folks were hoping that some of the new RVI 
process would make sure all these other things get done as part of the 
standardization process, but in practice it's just ended up being a bit 
of red tape that results in no meaningful work getting done.

It's not all that hard to just add more flavors of assembler syntax 
later, so maybe we just merge this and stop bothering to wait for all 
these other non-ISA specs to resolve?

> BR
> Christoph

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC PATCH v5] RISC-V: Add support for the Zfa extension
  2023-06-29 15:37       ` Palmer Dabbelt
@ 2023-06-29 15:49         ` Jeff Law
  2023-06-29 15:51           ` Philipp Tomsich
  2023-06-29 15:52           ` Palmer Dabbelt
  0 siblings, 2 replies; 19+ messages in thread
From: Jeff Law @ 2023-06-29 15:49 UTC (permalink / raw)
  To: Palmer Dabbelt, christoph.muellner
  Cc: binutils, nelson, Andrew Waterman, Jim Wilson, philipp.tomsich,
	jbeulich, Kito Cheng, research_trasio



On 6/29/23 09:37, Palmer Dabbelt wrote:

>>> > So my understanding is that this needs to wait for ratification and is
>>> > not blocked by the mentioned PR.
>>> Is there something special about Zfa that makes it desirable to wait for
>>> ratification as opposed to standard practice of gating things as the
>>> specs get to a Frozen state?
>>
>> Not to my knowledge.
> 
> Waiting for ratification is probably a bad idea, there's really no way 
> to schedule around it.  That's a big part of the reason we've just 
> waited for frozen.
Exactly.  ISTM that frozen is the right point to trigger.

> 
> IIUC we're just waiting on the assembler syntax to be accepted, it's not 
> an ISA problem right now.
And I think enough of it is settled that we can move forward. If RVI 
changes the set of forms allowed, then we can adjust.


> 
> It's not all that hard to just add more flavors of assembler syntax 
> later, so maybe we just merge this and stop bothering to wait for all 
> these other non-ISA specs to resolve?
I'd be more worried about them removing a supported form as that would 
result in hand-coded assembly might needing to be adjusted.  But I 
wouldn't expect there's much hand-coded Zfa code out there.

Jeff

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC PATCH v5] RISC-V: Add support for the Zfa extension
  2023-06-29 15:49         ` Jeff Law
@ 2023-06-29 15:51           ` Philipp Tomsich
  2023-06-30 13:40             ` Jeff Law
  2023-06-29 15:52           ` Palmer Dabbelt
  1 sibling, 1 reply; 19+ messages in thread
From: Philipp Tomsich @ 2023-06-29 15:51 UTC (permalink / raw)
  To: Jeff Law
  Cc: Palmer Dabbelt, christoph.muellner, binutils, nelson,
	Andrew Waterman, Jim Wilson, jbeulich, Kito Cheng,
	research_trasio

On Thu, 29 Jun 2023 at 08:49, Jeff Law <jeffreyalaw@gmail.com> wrote:
>
>
>
> On 6/29/23 09:37, Palmer Dabbelt wrote:
>
> >>> > So my understanding is that this needs to wait for ratification and is
> >>> > not blocked by the mentioned PR.
> >>> Is there something special about Zfa that makes it desirable to wait for
> >>> ratification as opposed to standard practice of gating things as the
> >>> specs get to a Frozen state?
> >>
> >> Not to my knowledge.
> >
> > Waiting for ratification is probably a bad idea, there's really no way
> > to schedule around it.  That's a big part of the reason we've just
> > waited for frozen.
> Exactly.  ISTM that frozen is the right point to trigger.

Is this an OK to apply the changes to trunk?

Thanks,
Philipp.

> > IIUC we're just waiting on the assembler syntax to be accepted, it's not
> > an ISA problem right now.
> And I think enough of it is settled that we can move forward. If RVI
> changes the set of forms allowed, then we can adjust.
>
>
> >
> > It's not all that hard to just add more flavors of assembler syntax
> > later, so maybe we just merge this and stop bothering to wait for all
> > these other non-ISA specs to resolve?
> I'd be more worried about them removing a supported form as that would
> result in hand-coded assembly might needing to be adjusted.  But I
> wouldn't expect there's much hand-coded Zfa code out there.
>
> Jeff

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC PATCH v5] RISC-V: Add support for the Zfa extension
  2023-06-29 15:49         ` Jeff Law
  2023-06-29 15:51           ` Philipp Tomsich
@ 2023-06-29 15:52           ` Palmer Dabbelt
  2023-06-29 16:03             ` Jeff Law
  2023-06-30  0:47             ` Nelson Chu
  1 sibling, 2 replies; 19+ messages in thread
From: Palmer Dabbelt @ 2023-06-29 15:52 UTC (permalink / raw)
  To: jeffreyalaw
  Cc: christoph.muellner, binutils, nelson, Andrew Waterman,
	Jim Wilson, philipp.tomsich, jbeulich, Kito Cheng,
	research_trasio

On Thu, 29 Jun 2023 08:49:16 PDT (-0700), jeffreyalaw@gmail.com wrote:
>
>
> On 6/29/23 09:37, Palmer Dabbelt wrote:
>
>>>> > So my understanding is that this needs to wait for ratification and is
>>>> > not blocked by the mentioned PR.
>>>> Is there something special about Zfa that makes it desirable to wait for
>>>> ratification as opposed to standard practice of gating things as the
>>>> specs get to a Frozen state?
>>>
>>> Not to my knowledge.
>>
>> Waiting for ratification is probably a bad idea, there's really no way
>> to schedule around it.  That's a big part of the reason we've just
>> waited for frozen.
> Exactly.  ISTM that frozen is the right point to trigger.
>
>>
>> IIUC we're just waiting on the assembler syntax to be accepted, it's not
>> an ISA problem right now.
> And I think enough of it is settled that we can move forward. If RVI
> changes the set of forms allowed, then we can adjust.

Works for me.  So

Acked-by: Palmer Dabbelt <palmer@rivosinc.com>

Presumably someone's actually looked at the code?  If not I can look 
over it...

>> It's not all that hard to just add more flavors of assembler syntax
>> later, so maybe we just merge this and stop bothering to wait for all
>> these other non-ISA specs to resolve?
> I'd be more worried about them removing a supported form as that would
> result in hand-coded assembly might needing to be adjusted.  But I
> wouldn't expect there's much hand-coded Zfa code out there.

Historically we've just kept whatever is released as a compatibility 
mechanism and then added stuff, but I guess we can sort that out when it 
comes to it.

>
> Jeff

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC PATCH v5] RISC-V: Add support for the Zfa extension
  2023-06-29 15:52           ` Palmer Dabbelt
@ 2023-06-29 16:03             ` Jeff Law
  2023-06-29 16:12               ` Palmer Dabbelt
  2023-06-30  0:47             ` Nelson Chu
  1 sibling, 1 reply; 19+ messages in thread
From: Jeff Law @ 2023-06-29 16:03 UTC (permalink / raw)
  To: Palmer Dabbelt
  Cc: christoph.muellner, binutils, nelson, Andrew Waterman,
	Jim Wilson, philipp.tomsich, jbeulich, Kito Cheng,
	research_trasio



On 6/29/23 09:52, Palmer Dabbelt wrote:

> 
> Acked-by: Palmer Dabbelt <palmer@rivosinc.com>
> 
> Presumably someone's actually looked at the code?  If not I can look 
> over it...
I've looked at it earlier.  But I'll go over it again.


> 
> Historically we've just kept whatever is released as a compatibility 
> mechanism and then added stuff, but I guess we can sort that out when it 
> comes to it.
ACK.

jeff

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC PATCH v5] RISC-V: Add support for the Zfa extension
  2023-06-29 16:03             ` Jeff Law
@ 2023-06-29 16:12               ` Palmer Dabbelt
  2023-06-30 14:07                 ` Philipp Tomsich
  0 siblings, 1 reply; 19+ messages in thread
From: Palmer Dabbelt @ 2023-06-29 16:12 UTC (permalink / raw)
  To: jeffreyalaw
  Cc: christoph.muellner, binutils, nelson, Andrew Waterman,
	Jim Wilson, philipp.tomsich, jbeulich, Kito Cheng,
	research_trasio

On Thu, 29 Jun 2023 09:03:58 PDT (-0700), jeffreyalaw@gmail.com wrote:
>
>
> On 6/29/23 09:52, Palmer Dabbelt wrote:
>
>>
>> Acked-by: Palmer Dabbelt <palmer@rivosinc.com>
>>
>> Presumably someone's actually looked at the code?  If not I can look
>> over it...
> I've looked at it earlier.  But I'll go over it again.

Thanks.  If it looks good and passes the tests without any substantive 
changes then feel free to commit it, any problems should be pretty 
self-contained.

>
>
>>
>> Historically we've just kept whatever is released as a compatibility
>> mechanism and then added stuff, but I guess we can sort that out when it
>> comes to it.
> ACK.
>
> jeff

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC PATCH v5] RISC-V: Add support for the Zfa extension
  2023-06-29 15:52           ` Palmer Dabbelt
  2023-06-29 16:03             ` Jeff Law
@ 2023-06-30  0:47             ` Nelson Chu
  2023-06-30  6:49               ` Kito Cheng
  2023-06-30 13:38               ` Jeff Law
  1 sibling, 2 replies; 19+ messages in thread
From: Nelson Chu @ 2023-06-30  0:47 UTC (permalink / raw)
  To: Palmer Dabbelt
  Cc: jeffreyalaw, christoph.muellner, binutils, Andrew Waterman,
	Jim Wilson, philipp.tomsich, jbeulich, Kito Cheng,
	research_trasio

[-- Attachment #1: Type: text/plain, Size: 2149 bytes --]

On Thu, Jun 29, 2023 at 11:52 PM Palmer Dabbelt <palmer@dabbelt.com> wrote:

> On Thu, 29 Jun 2023 08:49:16 PDT (-0700), jeffreyalaw@gmail.com wrote:
> >
> >
> > On 6/29/23 09:37, Palmer Dabbelt wrote:
> >
> >>>> > So my understanding is that this needs to wait for ratification and
> is
> >>>> > not blocked by the mentioned PR.
> >>>> Is there something special about Zfa that makes it desirable to wait
> for
> >>>> ratification as opposed to standard practice of gating things as the
> >>>> specs get to a Frozen state?
> >>>
> >>> Not to my knowledge.
> >>
> >> Waiting for ratification is probably a bad idea, there's really no way
> >> to schedule around it.  That's a big part of the reason we've just
> >> waited for frozen.
> > Exactly.  ISTM that frozen is the right point to trigger.
>

Okay, I never figured out the difference between ratified and frozen, since
both of them have examples that change the behaviors and syntaxes, even
encodings.  But anyway, thanks for clarifying the current rule that we
should commit when extension is frozen, not ratified.


> > And I think enough of it is settled that we can move forward. If RVI
> > changes the set of forms allowed, then we can adjust.
>

Does that mean we don't need to care about compatibility before the
ratified extensions?  That means we can simply change anything and don't
need to maintain the code even if it is frozen.  If that is so, then Jim,
Kito and I had agreed a very long time ago that we should accept the
experiment extension, which hasn't been frozen yet, with the
-experiment-extension option that is the same as LLVM.


> Presumably someone's actually looked at the code?  If not I can look
> over it...
>

I have looked and replied, Kito and Jan should also have looked.  The
special zfa syntax should be the same as LLVM when I looked.  But since
that is almost two month ago, it's good if someone helps to review it again
to make sure everything is on the line.

> I've looked at it earlier.  But I'll go over it again.

Thanks, Jeff, it would be great to get your approval as well.

Thanks
Nelson

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC PATCH v5] RISC-V: Add support for the Zfa extension
  2023-06-30  0:47             ` Nelson Chu
@ 2023-06-30  6:49               ` Kito Cheng
  2023-06-30 13:38               ` Jeff Law
  1 sibling, 0 replies; 19+ messages in thread
From: Kito Cheng @ 2023-06-30  6:49 UTC (permalink / raw)
  To: Nelson Chu
  Cc: Palmer Dabbelt, jeffreyalaw, christoph.muellner, binutils,
	Andrew Waterman, Jim Wilson, philipp.tomsich, jbeulich,
	research_trasio

Hi Nelson:

> > Presumably someone's actually looked at the code?  If not I can look
> > over it...
> >
>
> I have looked and replied, Kito and Jan should also have looked.  The
> special zfa syntax should be the same as LLVM when I looked.  But since
> that is almost two month ago, it's good if someone helps to review it again
> to make sure everything is on the line.

The syntax part matches
https://github.com/riscv-non-isa/riscv-asm-manual/pull/85, which also
matches LLVM implementation.

I am happy to see no syntax divergence on both sides :)

So give my blessing, this patch LGTM.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC PATCH v5] RISC-V: Add support for the Zfa extension
  2023-06-30  0:47             ` Nelson Chu
  2023-06-30  6:49               ` Kito Cheng
@ 2023-06-30 13:38               ` Jeff Law
  1 sibling, 0 replies; 19+ messages in thread
From: Jeff Law @ 2023-06-30 13:38 UTC (permalink / raw)
  To: Nelson Chu, Palmer Dabbelt
  Cc: christoph.muellner, binutils, Andrew Waterman, Jim Wilson,
	philipp.tomsich, jbeulich, Kito Cheng, research_trasio



On 6/29/23 18:47, Nelson Chu wrote:
> 
> 
> On Thu, Jun 29, 2023 at 11:52 PM Palmer Dabbelt <palmer@dabbelt.com 
> <mailto:palmer@dabbelt.com>> wrote:
> 
>     On Thu, 29 Jun 2023 08:49:16 PDT (-0700), jeffreyalaw@gmail.com
>     <mailto:jeffreyalaw@gmail.com> wrote:
>      >
>      >
>      > On 6/29/23 09:37, Palmer Dabbelt wrote:
>      >
>      >>>> > So my understanding is that this needs to wait for
>     ratification and is
>      >>>> > not blocked by the mentioned PR.
>      >>>> Is there something special about Zfa that makes it desirable
>     to wait for
>      >>>> ratification as opposed to standard practice of gating things
>     as the
>      >>>> specs get to a Frozen state?
>      >>>
>      >>> Not to my knowledge.
>      >>
>      >> Waiting for ratification is probably a bad idea, there's really
>     no way
>      >> to schedule around it.  That's a big part of the reason we've just
>      >> waited for frozen.
>      > Exactly.  ISTM that frozen is the right point to trigger.
> 
> 
> Okay, I never figured out the difference between ratified and frozen, 
> since both of them have examples that change the behaviors and syntaxes, 
> even encodings.  But anyway, thanks for clarifying the current rule that 
> we should commit when extension is frozen, not ratified.
Well as the newcomer to RISC-V I don't have the history.  In general I 
would expect very few changes from frozen to ratified and probably just 
things like semantic clarifications for issues that slipped through the 
prior states.  If things like encodings are still changing post-freeze, 
then that's a major failing of the process.

Also as the newcomer I tend to rely heavily on policies that other have 
set and the policy around this that has been drummed into my brain is 
freeze time :-)




> 
>      > And I think enough of it is settled that we can move forward. If RVI
>      > changes the set of forms allowed, then we can adjust.
> 
> 
> Does that mean we don't need to care about compatibility before the 
> ratified extensions?  That means we can simply change anything and don't 
> need to maintain the code even if it is frozen.  If that is so, then 
> Jim, Kito and I had agreed a very long time ago that we should accept 
> the experiment extension, which hasn't been frozen yet, with the 
> -experiment-extension option that is the same as LLVM.
If they were to change the forms of FP constants allowed, then we'd 
adjust.  If they add new allowed forms, then that's easy, we just need 
to build a suitable parser to recognize them.  The more interesting 
problem is if they remove allowed forms -- and as Palmer said, we'd try 
to keep the old forms for the sake of compatibility.



> I have looked and replied, Kito and Jan should also have looked.  The 
> special zfa syntax should be the same as LLVM when I looked.  But since 
> that is almost two month ago, it's good if someone helps to review it 
> again to make sure everything is on the line.
>  > I've looked at it earlier.  But I'll go over it again.
Last I heard the only issue was whether or not to allow an integer index 
into the table.  That's rough because one could easily confuse "2.0" 
with "2" though they'd have totally different meanings.  As a result 
LLVM removed the ability to use the table index IIRC.

> 
> Thanks, Jeff, it would be great to get your approval as well.
Happy to do so.  Hell, I wouldn't be comfortable merging it myself if I 
didn't.

jeff

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC PATCH v5] RISC-V: Add support for the Zfa extension
  2023-06-29 15:51           ` Philipp Tomsich
@ 2023-06-30 13:40             ` Jeff Law
  2023-06-30 14:06               ` Jeff Law
  0 siblings, 1 reply; 19+ messages in thread
From: Jeff Law @ 2023-06-30 13:40 UTC (permalink / raw)
  To: Philipp Tomsich
  Cc: Palmer Dabbelt, christoph.muellner, binutils, nelson,
	Andrew Waterman, Jim Wilson, jbeulich, Kito Cheng,
	research_trasio



On 6/29/23 09:51, Philipp Tomsich wrote:
> On Thu, 29 Jun 2023 at 08:49, Jeff Law <jeffreyalaw@gmail.com> wrote:
>>
>>
>>
>> On 6/29/23 09:37, Palmer Dabbelt wrote:
>>
>>>>>> So my understanding is that this needs to wait for ratification and is
>>>>>> not blocked by the mentioned PR.
>>>>> Is there something special about Zfa that makes it desirable to wait for
>>>>> ratification as opposed to standard practice of gating things as the
>>>>> specs get to a Frozen state?
>>>>
>>>> Not to my knowledge.
>>>
>>> Waiting for ratification is probably a bad idea, there's really no way
>>> to schedule around it.  That's a big part of the reason we've just
>>> waited for frozen.
>> Exactly.  ISTM that frozen is the right point to trigger.
> 
> Is this an OK to apply the changes to trunk?
I'll do another pass over and assuming everything looks good, I'll 
commit it later today.  Obviously the main driver is the upcoming 2.41 
release.  I'd rather have it in before Nick cuts the branch.


Jeff

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC PATCH v5] RISC-V: Add support for the Zfa extension
  2023-06-30 13:40             ` Jeff Law
@ 2023-06-30 14:06               ` Jeff Law
  2023-06-30 14:08                 ` Philipp Tomsich
  0 siblings, 1 reply; 19+ messages in thread
From: Jeff Law @ 2023-06-30 14:06 UTC (permalink / raw)
  To: Philipp Tomsich
  Cc: Palmer Dabbelt, christoph.muellner, binutils, nelson,
	Andrew Waterman, Jim Wilson, jbeulich, Kito Cheng,
	research_trasio



On 6/30/23 07:40, Jeff Law wrote:
> 
> 
> On 6/29/23 09:51, Philipp Tomsich wrote:
>> On Thu, 29 Jun 2023 at 08:49, Jeff Law <jeffreyalaw@gmail.com> wrote:
>>>
>>>
>>>
>>> On 6/29/23 09:37, Palmer Dabbelt wrote:
>>>
>>>>>>> So my understanding is that this needs to wait for ratification 
>>>>>>> and is
>>>>>>> not blocked by the mentioned PR.
>>>>>> Is there something special about Zfa that makes it desirable to 
>>>>>> wait for
>>>>>> ratification as opposed to standard practice of gating things as the
>>>>>> specs get to a Frozen state?
>>>>>
>>>>> Not to my knowledge.
>>>>
>>>> Waiting for ratification is probably a bad idea, there's really no way
>>>> to schedule around it.  That's a big part of the reason we've just
>>>> waited for frozen.
>>> Exactly.  ISTM that frozen is the right point to trigger.
>>
>> Is this an OK to apply the changes to trunk?
> I'll do another pass over and assuming everything looks good, I'll 
> commit it later today.  Obviously the main driver is the upcoming 2.41 
> release.  I'd rather have it in before Nick cuts the branch.
Y'all beat me to it :-)

Thanks,
jeff

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC PATCH v5] RISC-V: Add support for the Zfa extension
  2023-06-29 16:12               ` Palmer Dabbelt
@ 2023-06-30 14:07                 ` Philipp Tomsich
  0 siblings, 0 replies; 19+ messages in thread
From: Philipp Tomsich @ 2023-06-30 14:07 UTC (permalink / raw)
  To: Palmer Dabbelt
  Cc: jeffreyalaw, christoph.muellner, binutils, nelson,
	Andrew Waterman, Jim Wilson, jbeulich, Kito Cheng,
	research_trasio

Thanks, applied to master!

Philipp,


On Thu, 29 Jun 2023 at 09:12, Palmer Dabbelt <palmer@dabbelt.com> wrote:
>
> On Thu, 29 Jun 2023 09:03:58 PDT (-0700), jeffreyalaw@gmail.com wrote:
> >
> >
> > On 6/29/23 09:52, Palmer Dabbelt wrote:
> >
> >>
> >> Acked-by: Palmer Dabbelt <palmer@rivosinc.com>
> >>
> >> Presumably someone's actually looked at the code?  If not I can look
> >> over it...
> > I've looked at it earlier.  But I'll go over it again.
>
> Thanks.  If it looks good and passes the tests without any substantive
> changes then feel free to commit it, any problems should be pretty
> self-contained.
>
> >
> >
> >>
> >> Historically we've just kept whatever is released as a compatibility
> >> mechanism and then added stuff, but I guess we can sort that out when it
> >> comes to it.
> > ACK.
> >
> > jeff

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC PATCH v5] RISC-V: Add support for the Zfa extension
  2023-06-30 14:06               ` Jeff Law
@ 2023-06-30 14:08                 ` Philipp Tomsich
  2023-06-30 14:39                   ` Jeff Law
  0 siblings, 1 reply; 19+ messages in thread
From: Philipp Tomsich @ 2023-06-30 14:08 UTC (permalink / raw)
  To: Jeff Law
  Cc: Palmer Dabbelt, christoph.muellner, binutils, nelson,
	Andrew Waterman, Jim Wilson, jbeulich, Kito Cheng,
	research_trasio

I added a small change to list this in binutils/NEWS.
Please check if we added other extensions in this release that are
missing from there.

On Fri, 30 Jun 2023 at 07:06, Jeff Law <jeffreyalaw@gmail.com> wrote:
>
>
>
> On 6/30/23 07:40, Jeff Law wrote:
> >
> >
> > On 6/29/23 09:51, Philipp Tomsich wrote:
> >> On Thu, 29 Jun 2023 at 08:49, Jeff Law <jeffreyalaw@gmail.com> wrote:
> >>>
> >>>
> >>>
> >>> On 6/29/23 09:37, Palmer Dabbelt wrote:
> >>>
> >>>>>>> So my understanding is that this needs to wait for ratification
> >>>>>>> and is
> >>>>>>> not blocked by the mentioned PR.
> >>>>>> Is there something special about Zfa that makes it desirable to
> >>>>>> wait for
> >>>>>> ratification as opposed to standard practice of gating things as the
> >>>>>> specs get to a Frozen state?
> >>>>>
> >>>>> Not to my knowledge.
> >>>>
> >>>> Waiting for ratification is probably a bad idea, there's really no way
> >>>> to schedule around it.  That's a big part of the reason we've just
> >>>> waited for frozen.
> >>> Exactly.  ISTM that frozen is the right point to trigger.
> >>
> >> Is this an OK to apply the changes to trunk?
> > I'll do another pass over and assuming everything looks good, I'll
> > commit it later today.  Obviously the main driver is the upcoming 2.41
> > release.  I'd rather have it in before Nick cuts the branch.
> Y'all beat me to it :-)
>
> Thanks,
> jeff

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC PATCH v5] RISC-V: Add support for the Zfa extension
  2023-06-30 14:08                 ` Philipp Tomsich
@ 2023-06-30 14:39                   ` Jeff Law
  0 siblings, 0 replies; 19+ messages in thread
From: Jeff Law @ 2023-06-30 14:39 UTC (permalink / raw)
  To: Philipp Tomsich
  Cc: Palmer Dabbelt, christoph.muellner, binutils, nelson,
	Andrew Waterman, Jim Wilson, jbeulich, Kito Cheng,
	research_trasio



On 6/30/23 08:08, Philipp Tomsich wrote:
> I added a small change to list this in binutils/NEWS.
> Please check if we added other extensions in this release that are
> missing from there.
Yea, it's probably worth a top-to-bottom review for extensions.

We've got an interest in seeing vector crypto move forward and we've 
been using your team's patches to-date.  So I'll take a look at those next.

Zc* is also out there.  They're lower priority for Ventana than vector 
crypto and more importantly I think Nelson has some state on them.  So 
I'll leave them in his hands.

jeff


^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2023-06-30 14:39 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-04-13 13:36 [RFC PATCH v5] RISC-V: Add support for the Zfa extension Christoph Muellner
2023-06-29  7:52 ` Christoph Müllner
2023-06-29  8:33   ` Christoph Müllner
2023-06-29 15:07   ` Jeff Law
2023-06-29 15:10     ` Christoph Müllner
2023-06-29 15:37       ` Palmer Dabbelt
2023-06-29 15:49         ` Jeff Law
2023-06-29 15:51           ` Philipp Tomsich
2023-06-30 13:40             ` Jeff Law
2023-06-30 14:06               ` Jeff Law
2023-06-30 14:08                 ` Philipp Tomsich
2023-06-30 14:39                   ` Jeff Law
2023-06-29 15:52           ` Palmer Dabbelt
2023-06-29 16:03             ` Jeff Law
2023-06-29 16:12               ` Palmer Dabbelt
2023-06-30 14:07                 ` Philipp Tomsich
2023-06-30  0:47             ` Nelson Chu
2023-06-30  6:49               ` Kito Cheng
2023-06-30 13:38               ` Jeff Law

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).