public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [REVIEW ONLY 0/1] RISC-V (unratified): Add 'Zfa' extension
@ 2022-09-18 10:12 Tsukasa OI
  2022-09-18 10:12 ` [REVIEW ONLY 1/1] UNRATIFIED RISC-V: " Tsukasa OI
  0 siblings, 1 reply; 10+ messages in thread
From: Tsukasa OI @ 2022-09-18 10:12 UTC (permalink / raw)
  To: Tsukasa OI; +Cc: binutils

*** WAIT FOR SPECIFICATION FREEZE ***
This is an implementation for unratified and unfrozen RISC-V extension
and not intended to be merged as of now.
The only intent to submit this patchset is to test new instructions for
your (possibly virtual) environment and early review for fast adoption
after ratification.


[Cover Letter: Common in 'Zihintntl' and 'Zfa' patchsets]

As someone (I can't remember) pointed out in the RISC-V BoF of GNU Tools
Cauldron 2022, we don't have a policy to accept unstable extensions yet.
Still, at least we can talk about new extensions now...

1.  To try new instructions/features as fast as possible,
2.  To make actual adoption as fast as possible and
3.  To avoid redoing someone else's work

I'm working on following unratified RISC-V extensions:

1.  'Zihintntl' [resent as v2]
    <https://github.com/a4lg/binutils-gdb/wiki/riscv_zihintntl>
    <https://sourceware.org/pipermail/binutils/2022-July/121682.html>
2.  'Smrnmi' (resumable NMI)
    <https://github.com/a4lg/binutils-gdb/wiki/riscv_smrnmi>
    <https://sourceware.org/pipermail/binutils/2022-July/121689.html>
3.  'Zfa' [NEW]
    <https://github.com/a4lg/binutils-gdb/wiki/riscv_zfa>

I will resend 'Zihintntl' (squashed and applied minor formatting fixes)
and submit new 'Zfa' extension as a remainder of what am I doing.



['Zfa': Standard Extension for Additional Floating-Point Instructions]

This draft standard extension implements:

-   Load immediate instructions
    (allows to load 32 floating point constants)
-   IEEE 754-2019 operations
-   Modular Convert-to-Integer Instruction
    (to accelerate JavaScript Number handling)
-   Move instructions
    (RV32D/RV64Q: move high part)

This is based on:
<https://github.com/riscv/riscv-isa-manual/commit/ae683aec28ec707a3c4bb6f588491f0840d52f43>
(latest commit of the 'zfb' branch as of this writing)

Note that this extension is still highly unstable (except encoding).



[RFC: Adding another character operand prefix?]

Also, it will raise another issue.  It adds an operand type solely for
FLI.[HSDQ] instructions.  This is absolutely necessary because the spec
requires to accept either:

-   Decimal values: 0...29
    (I talked to Andrew and he considers accepting complex expression
    [not just decimal constants] is harmless)
-   Special operands:
    -   "min" (encoded as  1; 1 is also acceptable)
    -   "inf" (encoded as 30; invalid as a constant)
    -   "nan" (encoded as 31; invalid as a constant)

We may need to allocate a prefix for less common operands to avoid
filling the first-class character space with such minor ones.  I tentatively
propose 'W' for this purpose.

Example:
'Zicbop' PREFETCH.[IRW] : 'f' -> "Wf"
         (fetch offset)
'Zfa'    FLI.[HSDQ]     : 'i' -> "Wv"
         (value to load)


Thanks,
Tsukasa




Tsukasa OI (1):
  UNRATIFIED RISC-V: Add 'Zfa' extension

 bfd/elfxx-riscv.c                             | 39 ++++++++
 gas/config/tc-riscv.c                         | 21 ++++
 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/riscv/zfa-fail-fcvtmod.w.d.d          |  3 +
 .../gas/riscv/zfa-fail-fcvtmod.w.d.l          |  8 ++
 .../gas/riscv/zfa-fail-fcvtmod.w.d.s          | 11 +++
 gas/testsuite/gas/riscv/zfa-fail-fli.d        |  3 +
 gas/testsuite/gas/riscv/zfa-fail-fli.l        | 21 ++++
 gas/testsuite/gas/riscv/zfa-fail-fli.s        | 21 ++++
 gas/testsuite/gas/riscv/zfa.d                 | 93 +++++++++++++++++
 gas/testsuite/gas/riscv/zfa.s                 | 92 +++++++++++++++++
 include/opcode/riscv-opc.h                    | 99 +++++++++++++++++++
 include/opcode/riscv.h                        |  5 +
 opcodes/riscv-dis.c                           |  7 ++
 opcodes/riscv-opc.c                           | 52 +++++++++-
 18 files changed, 500 insertions(+), 1 deletion(-)
 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-fcvtmod.w.d.d
 create mode 100644 gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.l
 create mode 100644 gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.s
 create mode 100644 gas/testsuite/gas/riscv/zfa-fail-fli.d
 create mode 100644 gas/testsuite/gas/riscv/zfa-fail-fli.l
 create mode 100644 gas/testsuite/gas/riscv/zfa-fail-fli.s
 create mode 100644 gas/testsuite/gas/riscv/zfa.d
 create mode 100644 gas/testsuite/gas/riscv/zfa.s


base-commit: 4e38ed582cb9a2e09141126c2e0a527816e702e6
-- 
2.34.1


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

* [REVIEW ONLY 1/1] UNRATIFIED RISC-V: Add 'Zfa' extension
  2022-09-18 10:12 [REVIEW ONLY 0/1] RISC-V (unratified): Add 'Zfa' extension Tsukasa OI
@ 2022-09-18 10:12 ` Tsukasa OI
  2023-03-22 15:47   ` Christoph Müllner
  0 siblings, 1 reply; 10+ messages in thread
From: Tsukasa OI @ 2022-09-18 10:12 UTC (permalink / raw)
  To: Tsukasa OI; +Cc: binutils

[DO NOT MERGE]
Until 'Zfa' extension is frozen/ratified and final version number is
determined, this patch should not merged upstream. This commit uses
unratified version 0.1 as in documentation (instead of possible 1.0
after ratification).

This commit adds the 'Zfa' extension (its instructions and new operand
type for FLI instructions).

This is based on:
<https://github.com/riscv/riscv-isa-manual/commit/ae683aec28ec707a3c4bb6f588491f0840d52f43>
(latest commit of the 'zfb' branch as of this writing)

Note: the author is calling FLI instructions' RS1 encoded field as
"value".  It must be reviewed before the specification is frozen.

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:

	* testsuite/gas/riscv/zfa.s: New test.
	* testsuite/gas/riscv/zfa.d: Likewise.
	* testsuite/gas/riscv/zfa-32.s: New test.
	* testsuite/gas/riscv/zfa-32.d: Likewise.
	* testsuite/gas/riscv/zfa-64.s: New test.
	* testsuite/gas/riscv/zfa-64.d: Likewise.
	* testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.s: New failure test for
	the "fcvtmod.w.d" instruction.
	* testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.d: Likewise.
	* testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.l: Likewise.
	* testsuite/gas/riscv/zfa-fail-fli.s: New failure test for "fli"
	instructions.
	* testsuite/gas/riscv/zfa-fail-fli.d: Likewise.
	* testsuite/gas/riscv/zfa-fail-fli.l: Likewise.

include/ChangeLog:

	* opcode/riscv-opc.h (MATCH_FLI_H, MASK_FLI_H, MATCH_FMINI_H,
	MASK_FMINI_H, MATCH_FMAXI_H, MASK_FMAXI_H, MATCH_FROUND_H,
	MASK_FROUND_H, MATCH_FROUNDNX_H, MASK_FROUNDNX_H, MATCH_FLTQ_H,
	MASK_FLTQ_H, MATCH_FLEQ_H, MASK_FLEQ_H, MATCH_FLI_S, MASK_FLI_S,
	MATCH_FMINI_S, MASK_FMINI_S, MATCH_FMAXI_S, MASK_FMAXI_S,
	MATCH_FROUND_S, MASK_FROUND_S, MATCH_FROUNDNX_S, MASK_FROUNDNX_S,
	MATCH_FLTQ_S, MASK_FLTQ_S, MATCH_FLEQ_S, MASK_FLEQ_S, MATCH_FLI_D,
	MASK_FLI_D, MATCH_FMINI_D, MASK_FMINI_D, MATCH_FMAXI_D,
	MASK_FMAXI_D, MATCH_FROUND_D, MASK_FROUND_D, MATCH_FROUNDNX_D,
	MASK_FROUNDNX_D, MATCH_FLTQ_D, MASK_FLTQ_D, MATCH_FLEQ_D,
	MASK_FLEQ_D, MATCH_FLI_Q, MASK_FLI_Q, MATCH_FMINI_Q, MASK_FMINI_Q,
	MATCH_FMAXI_Q, MASK_FMAXI_Q, MATCH_FROUND_Q, MASK_FROUND_Q,
	MATCH_FROUNDNX_Q, MASK_FROUNDNX_Q, MATCH_FLTQ_Q, MASK_FLTQ_Q,
	MATCH_FLEQ_Q, MASK_FLEQ_Q, MATCH_FCVTMOD_W_D, MASK_FCVTMOD_W_D,
	MATCH_FMVH_X_D, MASK_FMVH_X_D, MATCH_FMVH_X_Q, MASK_FMVH_X_Q,
	MATCH_FMVP_D_X, MASK_FMVP_D_X, MATCH_FMVP_Q_X, MASK_FMVP_Q_X): New.
	* opcode/riscv.h (enum riscv_insn_class): Add instruction
	classes for 'Zfa' extension.

opcodes/ChangeLog:

	* riscv-opc.c (riscv_opcodes): Add 'Zfa' instructions.
---
 bfd/elfxx-riscv.c                             | 39 ++++++++
 gas/config/tc-riscv.c                         | 21 ++++
 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/riscv/zfa-fail-fcvtmod.w.d.d          |  3 +
 .../gas/riscv/zfa-fail-fcvtmod.w.d.l          |  8 ++
 .../gas/riscv/zfa-fail-fcvtmod.w.d.s          | 11 +++
 gas/testsuite/gas/riscv/zfa-fail-fli.d        |  3 +
 gas/testsuite/gas/riscv/zfa-fail-fli.l        | 21 ++++
 gas/testsuite/gas/riscv/zfa-fail-fli.s        | 21 ++++
 gas/testsuite/gas/riscv/zfa.d                 | 93 +++++++++++++++++
 gas/testsuite/gas/riscv/zfa.s                 | 92 +++++++++++++++++
 include/opcode/riscv-opc.h                    | 99 +++++++++++++++++++
 include/opcode/riscv.h                        |  5 +
 opcodes/riscv-dis.c                           |  7 ++
 opcodes/riscv-opc.c                           | 52 +++++++++-
 18 files changed, 500 insertions(+), 1 deletion(-)
 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-fcvtmod.w.d.d
 create mode 100644 gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.l
 create mode 100644 gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.s
 create mode 100644 gas/testsuite/gas/riscv/zfa-fail-fli.d
 create mode 100644 gas/testsuite/gas/riscv/zfa-fail-fli.l
 create mode 100644 gas/testsuite/gas/riscv/zfa-fail-fli.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 e03b312a381..1c6d1505d54 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -1073,6 +1073,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},
@@ -1162,6 +1163,7 @@ static struct riscv_supported_ext riscv_supported_std_z_ext[] =
   {"zifencei",		ISA_SPEC_CLASS_20190608,	2, 0,  0 },
   {"zihintpause",	ISA_SPEC_CLASS_DRAFT,		2, 0,  0 },
   {"zmmul",		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 },
@@ -2334,6 +2336,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:
@@ -2469,6 +2482,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 2f5ee18e451..ffbc7fbdda2 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -1208,6 +1208,7 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
 	case 'd': USE_BITS (OP_MASK_RD, OP_SH_RD); break;
 	case 'y': USE_BITS (OP_MASK_BS,	OP_SH_BS); break;
 	case 'Y': USE_BITS (OP_MASK_RNUM, OP_SH_RNUM); break;
+	case 'i': /* RS1, FLI.[HSDQ] value field.  */
 	case 'Z': /* RS1, CSR number.  */
 	case 'S': /* RS1, floating point.  */
 	case 's': USE_BITS (OP_MASK_RS1, OP_SH_RS1); break;
@@ -3262,6 +3263,26 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 	      asarg = expr_end;
 	      continue;
 
+	    case 'i': /* FLI.[HSDQ] constant immediate.  */
+	      if (arg_lookup (&asarg, riscv_fli_value,
+			      ARRAY_SIZE (riscv_fli_value), &regno))
+		INSERT_OPERAND (RS1, *ip, regno);
+	      else
+		{
+		  if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
+		      || imm_expr->X_op != O_constant)
+		    break;
+		  if (imm_expr->X_add_number < 0
+		      || imm_expr->X_add_number > 29)
+		    as_bad (_ ("improper fli value field (%ld), "
+			       "value must be 0...29 or min, inf or nan"),
+			    (long) imm_expr->X_add_number);
+		  INSERT_OPERAND (RS1, *ip, imm_expr->X_add_number);
+		  imm_expr->X_op = O_absent;
+		  asarg = expr_end;
+		}
+	      continue;
+
 	    default:
 	    unknown_riscv_ip_operand:
 	      as_fatal (_("internal: unknown argument type `%s'"),
diff --git a/gas/testsuite/gas/riscv/zfa-32.d b/gas/testsuite/gas/riscv/zfa-32.d
new file mode 100644
index 00000000000..0f0cbfcdc70
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zfa-32.d
@@ -0,0 +1,10 @@
+#as: -march=rv32id_zfa
+#objdump: -dr
+
+.*:[ 	]+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..f942d616959
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zfa-64.d
@@ -0,0 +1,10 @@
+#as: -march=rv64iq_zfa
+#objdump: -dr
+
+.*:[ 	]+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-fcvtmod.w.d.d b/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.d
new file mode 100644
index 00000000000..5234c49de75
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.d
@@ -0,0 +1,3 @@
+#as: -march=rv64id_zfa
+#objdump: -dr
+#error_output: zfa-fail-fcvtmod.w.d.l
diff --git a/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.l b/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.l
new file mode 100644
index 00000000000..4ea048a3356
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.l
@@ -0,0 +1,8 @@
+.*: Assembler messages:
+.*: 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-fcvtmod.w.d.s b/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.s
new file mode 100644
index 00000000000..5984f6676d8
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.s
@@ -0,0 +1,11 @@
+target:
+	# fcvtmod.w.d requires explicit rounding mode.
+	fcvtmod.w.d	a0, ft1
+	# 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
+	# Invalid rounding mode is invalid.
+	fcvtmod.w.d	a0, ft1, invalid
diff --git a/gas/testsuite/gas/riscv/zfa-fail-fli.d b/gas/testsuite/gas/riscv/zfa-fail-fli.d
new file mode 100644
index 00000000000..3753a4d185e
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zfa-fail-fli.d
@@ -0,0 +1,3 @@
+#as: -march=rv64iq_zfa_zfh
+#objdump: -dr
+#error_output: zfa-fail-fli.l
diff --git a/gas/testsuite/gas/riscv/zfa-fail-fli.l b/gas/testsuite/gas/riscv/zfa-fail-fli.l
new file mode 100644
index 00000000000..b7532f80fd4
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zfa-fail-fli.l
@@ -0,0 +1,21 @@
+.*: Assembler messages:
+.*: Error: improper fli value field \(-1\), value must be 0\.\.\.29 or min, inf or nan
+.*: Error: improper fli value field \(-1\), value must be 0\.\.\.29 or min, inf or nan
+.*: Error: improper fli value field \(-1\), value must be 0\.\.\.29 or min, inf or nan
+.*: Error: improper fli value field \(-1\), value must be 0\.\.\.29 or min, inf or nan
+.*: Error: improper fli value field \(-2\), value must be 0\.\.\.29 or min, inf or nan
+.*: Error: improper fli value field \(-2\), value must be 0\.\.\.29 or min, inf or nan
+.*: Error: improper fli value field \(-2\), value must be 0\.\.\.29 or min, inf or nan
+.*: Error: improper fli value field \(-2\), value must be 0\.\.\.29 or min, inf or nan
+.*: Error: improper fli value field \(30\), value must be 0\.\.\.29 or min, inf or nan
+.*: Error: improper fli value field \(30\), value must be 0\.\.\.29 or min, inf or nan
+.*: Error: improper fli value field \(30\), value must be 0\.\.\.29 or min, inf or nan
+.*: Error: improper fli value field \(30\), value must be 0\.\.\.29 or min, inf or nan
+.*: Error: improper fli value field \(32\), value must be 0\.\.\.29 or min, inf or nan
+.*: Error: improper fli value field \(32\), value must be 0\.\.\.29 or min, inf or nan
+.*: Error: improper fli value field \(32\), value must be 0\.\.\.29 or min, inf or nan
+.*: Error: improper fli value field \(32\), value must be 0\.\.\.29 or min, inf or nan
+.*: Error: illegal operands `fli\.h ft1,invalid'
+.*: Error: illegal operands `fli\.s ft1,invalid'
+.*: Error: illegal operands `fli\.d ft1,invalid'
+.*: Error: illegal operands `fli\.q ft1,invalid'
diff --git a/gas/testsuite/gas/riscv/zfa-fail-fli.s b/gas/testsuite/gas/riscv/zfa-fail-fli.s
new file mode 100644
index 00000000000..4c600b5d578
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zfa-fail-fli.s
@@ -0,0 +1,21 @@
+target:
+	fli.h	ft1, -1
+	fli.s	ft1, -1
+	fli.d	ft1, -1
+	fli.q	ft1, -1
+	fli.h	ft1, -2
+	fli.s	ft1, -2
+	fli.d	ft1, -2
+	fli.q	ft1, -2
+	fli.h	ft1, 30
+	fli.s	ft1, 30
+	fli.d	ft1, 30
+	fli.q	ft1, 30
+	fli.h	ft1, 32
+	fli.s	ft1, 32
+	fli.d	ft1, 32
+	fli.q	ft1, 32
+	fli.h	ft1, invalid
+	fli.s	ft1, invalid
+	fli.d	ft1, invalid
+	fli.q	ft1, invalid
diff --git a/gas/testsuite/gas/riscv/zfa.d b/gas/testsuite/gas/riscv/zfa.d
new file mode 100644
index 00000000000..3701a41e485
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zfa.d
@@ -0,0 +1,93 @@
+#as: -march=rv64iq_zfa_zfh
+#objdump: -dr
+
+.*:[ 	]+file format .*
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+[0-9a-f]+:[ 	]+f41000d3[ 	]+fli\.h[ 		]+ft1,0
+[ 	]+[0-9a-f]+:[ 	]+f41080d3[ 	]+fli\.h[ 		]+ft1,min
+[ 	]+[0-9a-f]+:[ 	]+f41100d3[ 	]+fli\.h[ 		]+ft1,2
+[ 	]+[0-9a-f]+:[ 	]+f41d80d3[ 	]+fli\.h[ 		]+ft1,27
+[ 	]+[0-9a-f]+:[ 	]+f41e00d3[ 	]+fli\.h[ 		]+ft1,28
+[ 	]+[0-9a-f]+:[ 	]+f41e80d3[ 	]+fli\.h[ 		]+ft1,29
+[ 	]+[0-9a-f]+:[ 	]+f41080d3[ 	]+fli\.h[ 		]+ft1,min
+[ 	]+[0-9a-f]+:[ 	]+f41f00d3[ 	]+fli\.h[ 		]+ft1,inf
+[ 	]+[0-9a-f]+:[ 	]+f41f80d3[ 	]+fli\.h[ 		]+ft1,nan
+[ 	]+[0-9a-f]+:[ 	]+f01000d3[ 	]+fli\.s[ 		]+ft1,0
+[ 	]+[0-9a-f]+:[ 	]+f01080d3[ 	]+fli\.s[ 		]+ft1,min
+[ 	]+[0-9a-f]+:[ 	]+f01100d3[ 	]+fli\.s[ 		]+ft1,2
+[ 	]+[0-9a-f]+:[ 	]+f01d80d3[ 	]+fli\.s[ 		]+ft1,27
+[ 	]+[0-9a-f]+:[ 	]+f01e00d3[ 	]+fli\.s[ 		]+ft1,28
+[ 	]+[0-9a-f]+:[ 	]+f01e80d3[ 	]+fli\.s[ 		]+ft1,29
+[ 	]+[0-9a-f]+:[ 	]+f01080d3[ 	]+fli\.s[ 		]+ft1,min
+[ 	]+[0-9a-f]+:[ 	]+f01f00d3[ 	]+fli\.s[ 		]+ft1,inf
+[ 	]+[0-9a-f]+:[ 	]+f01f80d3[ 	]+fli\.s[ 		]+ft1,nan
+[ 	]+[0-9a-f]+:[ 	]+f21000d3[ 	]+fli\.d[ 		]+ft1,0
+[ 	]+[0-9a-f]+:[ 	]+f21080d3[ 	]+fli\.d[ 		]+ft1,min
+[ 	]+[0-9a-f]+:[ 	]+f21100d3[ 	]+fli\.d[ 		]+ft1,2
+[ 	]+[0-9a-f]+:[ 	]+f21d80d3[ 	]+fli\.d[ 		]+ft1,27
+[ 	]+[0-9a-f]+:[ 	]+f21e00d3[ 	]+fli\.d[ 		]+ft1,28
+[ 	]+[0-9a-f]+:[ 	]+f21e80d3[ 	]+fli\.d[ 		]+ft1,29
+[ 	]+[0-9a-f]+:[ 	]+f21080d3[ 	]+fli\.d[ 		]+ft1,min
+[ 	]+[0-9a-f]+:[ 	]+f21f00d3[ 	]+fli\.d[ 		]+ft1,inf
+[ 	]+[0-9a-f]+:[ 	]+f21f80d3[ 	]+fli\.d[ 		]+ft1,nan
+[ 	]+[0-9a-f]+:[ 	]+f61000d3[ 	]+fli\.q[ 		]+ft1,0
+[ 	]+[0-9a-f]+:[ 	]+f61080d3[ 	]+fli\.q[ 		]+ft1,min
+[ 	]+[0-9a-f]+:[ 	]+f61100d3[ 	]+fli\.q[ 		]+ft1,2
+[ 	]+[0-9a-f]+:[ 	]+f61d80d3[ 	]+fli\.q[ 		]+ft1,27
+[ 	]+[0-9a-f]+:[ 	]+f61e00d3[ 	]+fli\.q[ 		]+ft1,28
+[ 	]+[0-9a-f]+:[ 	]+f61e80d3[ 	]+fli\.q[ 		]+ft1,29
+[ 	]+[0-9a-f]+:[ 	]+f61080d3[ 	]+fli\.q[ 		]+ft1,min
+[ 	]+[0-9a-f]+:[ 	]+f61f00d3[ 	]+fli\.q[ 		]+ft1,inf
+[ 	]+[0-9a-f]+:[ 	]+f61f80d3[ 	]+fli\.q[ 		]+ft1,nan
+[ 	]+[0-9a-f]+:[ 	]+2c3100d3[ 	]+fmin\.h[ 		]+ft1,ft2,ft3
+[ 	]+[0-9a-f]+:[ 	]+2c3120d3[ 	]+fmini\.h[ 		]+ft1,ft2,ft3
+[ 	]+[0-9a-f]+:[ 	]+283100d3[ 	]+fmin\.s[ 		]+ft1,ft2,ft3
+[ 	]+[0-9a-f]+:[ 	]+283120d3[ 	]+fmini\.s[ 		]+ft1,ft2,ft3
+[ 	]+[0-9a-f]+:[ 	]+2a3100d3[ 	]+fmin\.d[ 		]+ft1,ft2,ft3
+[ 	]+[0-9a-f]+:[ 	]+2a3120d3[ 	]+fmini\.d[ 		]+ft1,ft2,ft3
+[ 	]+[0-9a-f]+:[ 	]+2e3100d3[ 	]+fmin\.q[ 		]+ft1,ft2,ft3
+[ 	]+[0-9a-f]+:[ 	]+2e3120d3[ 	]+fmini\.q[ 		]+ft1,ft2,ft3
+[ 	]+[0-9a-f]+:[ 	]+2c3110d3[ 	]+fmax\.h[ 		]+ft1,ft2,ft3
+[ 	]+[0-9a-f]+:[ 	]+2c3130d3[ 	]+fmaxi\.h[ 		]+ft1,ft2,ft3
+[ 	]+[0-9a-f]+:[ 	]+283110d3[ 	]+fmax\.s[ 		]+ft1,ft2,ft3
+[ 	]+[0-9a-f]+:[ 	]+283130d3[ 	]+fmaxi\.s[ 		]+ft1,ft2,ft3
+[ 	]+[0-9a-f]+:[ 	]+2a3110d3[ 	]+fmax\.d[ 		]+ft1,ft2,ft3
+[ 	]+[0-9a-f]+:[ 	]+2a3130d3[ 	]+fmaxi\.d[ 		]+ft1,ft2,ft3
+[ 	]+[0-9a-f]+:[ 	]+2e3110d3[ 	]+fmax\.q[ 		]+ft1,ft2,ft3
+[ 	]+[0-9a-f]+:[ 	]+2e3130d3[ 	]+fmaxi\.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..fb79792bf10
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zfa.s
@@ -0,0 +1,92 @@
+target:
+	# fli: test both decimal and symbol representations
+	#      (0..29, min==1, inf==(30), nan==(31))
+	fli.h		ft1, 0
+	fli.h		ft1, 1
+	fli.h		ft1, 2
+	fli.h		ft1, 27
+	fli.h		ft1, 28
+	fli.h		ft1, 29
+	fli.h		ft1, min
+	fli.h		ft1, inf
+	fli.h		ft1, nan
+	fli.s		ft1, 0
+	fli.s		ft1, 1
+	fli.s		ft1, 2
+	fli.s		ft1, 27
+	fli.s		ft1, 28
+	fli.s		ft1, 29
+	fli.s		ft1, min
+	fli.s		ft1, inf
+	fli.s		ft1, nan
+	fli.d		ft1, 0
+	fli.d		ft1, 1
+	fli.d		ft1, 2
+	fli.d		ft1, 27
+	fli.d		ft1, 28
+	fli.d		ft1, 29
+	fli.d		ft1, min
+	fli.d		ft1, inf
+	fli.d		ft1, nan
+	fli.q		ft1, 0
+	fli.q		ft1, 1
+	fli.q		ft1, 2
+	fli.q		ft1, 27
+	fli.q		ft1, 28
+	fli.q		ft1, 29
+	fli.q		ft1, min
+	fli.q		ft1, inf
+	fli.q		ft1, nan
+	# fmini/fmaxi (Zfa): same as fmin/fmax (Zfh/F/D/Q) except bit 13 set
+	fmin.h		ft1, ft2, ft3
+	fmini.h		ft1, ft2, ft3
+	fmin.s		ft1, ft2, ft3
+	fmini.s		ft1, ft2, ft3
+	fmin.d		ft1, ft2, ft3
+	fmini.d		ft1, ft2, ft3
+	fmin.q		ft1, ft2, ft3
+	fmini.q		ft1, ft2, ft3
+	fmax.h		ft1, ft2, ft3
+	fmaxi.h		ft1, ft2, ft3
+	fmax.s		ft1, ft2, ft3
+	fmaxi.s		ft1, ft2, ft3
+	fmax.d		ft1, ft2, ft3
+	fmaxi.d		ft1, ft2, ft3
+	fmax.q		ft1, ft2, ft3
+	fmaxi.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 (Zfa): same as flt/fle (Zfh/F/D/Q) except bit 14 set
+	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 88b8d7ff595..9739ad24538 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_FMINI_H 0x2c002053
+#define MASK_FMINI_H 0xfe00707f
+#define MATCH_FMAXI_H 0x2c003053
+#define MASK_FMAXI_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_FMINI_S 0x28002053
+#define MASK_FMINI_S 0xfe00707f
+#define MATCH_FMAXI_S 0x28003053
+#define MASK_FMAXI_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_FMINI_D 0x2a002053
+#define MASK_FMINI_D 0xfe00707f
+#define MATCH_FMAXI_D 0x2a003053
+#define MASK_FMAXI_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_FMINI_Q 0x2e002053
+#define MASK_FMINI_Q 0xfe00707f
+#define MATCH_FMAXI_Q 0x2e003053
+#define MASK_FMAXI_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
@@ -2718,6 +2784,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(fmini_h, MATCH_FMINI_H, MASK_FMINI_H)
+DECLARE_INSN(fmaxi_h, MATCH_FMAXI_H, MASK_FMAXI_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(fmini_s, MATCH_FMINI_S, MASK_FMINI_S)
+DECLARE_INSN(fmaxi_s, MATCH_FMAXI_S, MASK_FMAXI_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(fmini_d, MATCH_FMINI_D, MASK_FMINI_D)
+DECLARE_INSN(fmaxi_d, MATCH_FMAXI_D, MASK_FMAXI_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(fmini_q, MATCH_FMINI_Q, MASK_FMINI_Q)
+DECLARE_INSN(fmaxi_q, MATCH_FMAXI_Q, MASK_FMAXI_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 f1dabeaab8e..3e9feaac2a7 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -376,6 +376,10 @@ enum riscv_insn_class
   INSN_CLASS_ZFHMIN_OR_ZHINXMIN,
   INSN_CLASS_ZFHMIN_AND_D,
   INSN_CLASS_ZFHMIN_AND_Q,
+  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,
@@ -528,6 +532,7 @@ 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_value[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 7ae6e709290..7a8be52281f 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -563,6 +563,13 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
 	  print (info->stream, dis_style_text, "%d", rs1);
 	  break;
 
+	case 'i':
+	  if (riscv_fli_value[rs1])
+	    print (info->stream, dis_style_text, "%s", riscv_fli_value[rs1]);
+	  else
+	    print (info->stream, dis_style_immediate, "%d", rs1);
+	  break;
+
 	default:
 	  /* xgettext:c-format */
 	  print (info->stream, dis_style_text,
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 79be78eb367..eb4da1a7485 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -97,6 +97,15 @@ const char * const riscv_vma[2] =
   "mu", "ma"
 };
 
+/* The FLI.[HSDQ] value constants.  */
+const char * const riscv_fli_value[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 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
@@ -636,6 +645,15 @@ const struct riscv_opcode riscv_opcodes[] =
 {"fcvt.h.l",  64, INSN_CLASS_ZFH_OR_ZHINX,   "D,s,m",     MATCH_FCVT_H_L, MASK_FCVT_H_L, match_opcode, 0 },
 {"fcvt.h.lu", 64, INSN_CLASS_ZFH_OR_ZHINX,   "D,s",       MATCH_FCVT_H_LU|MASK_RM, MASK_FCVT_H_LU|MASK_RM, match_opcode, 0 },
 {"fcvt.h.lu", 64, INSN_CLASS_ZFH_OR_ZHINX,   "D,s,m",     MATCH_FCVT_H_LU, MASK_FCVT_H_LU, match_opcode, 0 },
+{"fli.h",      0, INSN_CLASS_ZFH_AND_ZFA,    "D,i",       MATCH_FLI_H, MASK_FLI_H, match_opcode, 0 },
+{"fmini.h",    0, INSN_CLASS_ZFH_AND_ZFA,    "D,S,T",     MATCH_FMINI_H, MASK_FMINI_H, match_opcode, 0 },
+{"fmaxi.h",    0, INSN_CLASS_ZFH_AND_ZFA,    "D,S,T",     MATCH_FMAXI_H, MASK_FMAXI_H, 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 },
+{"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 },
 
 /* Single-precision floating-point instruction subset.  */
 {"frcsr",      0, INSN_CLASS_F_OR_ZFINX,   "d",         MATCH_FRCSR, MASK_FRCSR, match_opcode, INSN_ALIAS },
@@ -714,7 +732,16 @@ const struct riscv_opcode riscv_opcodes[] =
 {"fcvt.s.l",  64, INSN_CLASS_F_OR_ZFINX,   "D,s,m",     MATCH_FCVT_S_L, MASK_FCVT_S_L, match_opcode, 0 },
 {"fcvt.s.lu", 64, INSN_CLASS_F_OR_ZFINX,   "D,s",       MATCH_FCVT_S_LU|MASK_RM, MASK_FCVT_S_LU|MASK_RM, match_opcode, 0 },
 {"fcvt.s.lu", 64, INSN_CLASS_F_OR_ZFINX,   "D,s,m",     MATCH_FCVT_S_LU, MASK_FCVT_S_LU, match_opcode, 0 },
-
+{"fli.s",      0, INSN_CLASS_ZFA,          "D,i",       MATCH_FLI_S, MASK_FLI_S, match_opcode, 0 },
+{"fmini.s",    0, INSN_CLASS_ZFA,          "D,S,T",     MATCH_FMINI_S, MASK_FMINI_S, match_opcode, 0 },
+{"fmaxi.s",    0, INSN_CLASS_ZFA,          "D,S,T",     MATCH_FMAXI_S, MASK_FMAXI_S, 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 },
+{"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 },
+ 
 /* Double-precision floating-point instruction subset.  */
 {"fld",        0, INSN_CLASS_D_AND_C, "D,Cn(Cc)",  MATCH_C_FLDSP, MASK_C_FLDSP, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
 {"fld",        0, INSN_CLASS_D_AND_C, "CD,Cl(Cs)", MATCH_C_FLD, MASK_C_FLD, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
@@ -775,6 +802,18 @@ const struct riscv_opcode riscv_opcodes[] =
 {"fcvt.d.l",  64, INSN_CLASS_D_OR_ZDINX,   "D,s,m",     MATCH_FCVT_D_L, MASK_FCVT_D_L, match_opcode, 0 },
 {"fcvt.d.lu", 64, INSN_CLASS_D_OR_ZDINX,   "D,s",       MATCH_FCVT_D_LU|MASK_RM, MASK_FCVT_D_LU|MASK_RM, match_opcode, 0 },
 {"fcvt.d.lu", 64, INSN_CLASS_D_OR_ZDINX,   "D,s,m",     MATCH_FCVT_D_LU, MASK_FCVT_D_LU, match_opcode, 0 },
+{"fli.d",       0, INSN_CLASS_D_AND_ZFA,   "D,i",       MATCH_FLI_D, MASK_FLI_D, match_opcode, 0 },
+{"fmini.d",     0, INSN_CLASS_D_AND_ZFA,   "D,S,T",     MATCH_FMINI_D, MASK_FMINI_D, match_opcode, 0 },
+{"fmaxi.d",     0, INSN_CLASS_D_AND_ZFA,   "D,S,T",     MATCH_FMAXI_D, MASK_FMAXI_D, 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 },
+{"fcvtmod.w.d", 0, INSN_CLASS_D_AND_ZFA,   "d,S,m",     MATCH_FCVTMOD_W_D, MASK_FCVTMOD_W_D, 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 },
+{"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},
 
 /* Quad-precision floating-point instruction subset.  */
 {"flq",        0, INSN_CLASS_Q,   "D,o(s)",    MATCH_FLQ, MASK_FLQ, match_opcode, INSN_DREF|INSN_16_BYTE },
@@ -833,6 +872,17 @@ const struct riscv_opcode riscv_opcodes[] =
 {"fcvt.q.l",  64, INSN_CLASS_Q_OR_ZQINX,   "D,s,m",     MATCH_FCVT_Q_L, MASK_FCVT_Q_L, match_opcode, 0 },
 {"fcvt.q.lu", 64, INSN_CLASS_Q_OR_ZQINX,   "D,s",       MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU|MASK_RM, match_opcode, 0 },
 {"fcvt.q.lu", 64, INSN_CLASS_Q_OR_ZQINX,   "D,s,m",     MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU, match_opcode, 0 },
+{"fli.q",       0, INSN_CLASS_Q_AND_ZFA,   "D,i",       MATCH_FLI_Q, MASK_FLI_Q, match_opcode, 0 },
+{"fmini.q",     0, INSN_CLASS_Q_AND_ZFA,   "D,S,T",     MATCH_FMINI_Q, MASK_FMINI_Q, match_opcode, 0 },
+{"fmaxi.q",     0, INSN_CLASS_Q_AND_ZFA,   "D,S,T",     MATCH_FMAXI_Q, MASK_FMAXI_Q, 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 },
+{"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 },
+{"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},
 
 /* Compressed instructions.  */
 {"c.unimp",    0, INSN_CLASS_C,   "",          0, 0xffffU,  match_opcode, 0 },
-- 
2.34.1


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

* Re: [REVIEW ONLY 1/1] UNRATIFIED RISC-V: Add 'Zfa' extension
  2022-09-18 10:12 ` [REVIEW ONLY 1/1] UNRATIFIED RISC-V: " Tsukasa OI
@ 2023-03-22 15:47   ` Christoph Müllner
  2023-03-22 16:01     ` Philipp Tomsich
                       ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Christoph Müllner @ 2023-03-22 15:47 UTC (permalink / raw)
  To: Tsukasa OI; +Cc: binutils, Philipp Tomsich, Andrew Waterman

On Sun, Sep 18, 2022 at 12:13 PM Tsukasa OI via Binutils
<binutils@sourceware.org> wrote:
>
> [DO NOT MERGE]
> Until 'Zfa' extension is frozen/ratified and final version number is
> determined, this patch should not merged upstream. This commit uses
> unratified version 0.1 as in documentation (instead of possible 1.0
> after ratification).
>
> This commit adds the 'Zfa' extension (its instructions and new operand
> type for FLI instructions).
>
> This is based on:
> <https://github.com/riscv/riscv-isa-manual/commit/ae683aec28ec707a3c4bb6f588491f0840d52f43>
> (latest commit of the 'zfb' branch as of this writing)
>
> Note: the author is calling FLI instructions' RS1 encoded field as
> "value".  It must be reviewed before the specification is frozen.
>
> 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:
>
>         * testsuite/gas/riscv/zfa.s: New test.
>         * testsuite/gas/riscv/zfa.d: Likewise.
>         * testsuite/gas/riscv/zfa-32.s: New test.
>         * testsuite/gas/riscv/zfa-32.d: Likewise.
>         * testsuite/gas/riscv/zfa-64.s: New test.
>         * testsuite/gas/riscv/zfa-64.d: Likewise.
>         * testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.s: New failure test for
>         the "fcvtmod.w.d" instruction.
>         * testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.d: Likewise.
>         * testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.l: Likewise.
>         * testsuite/gas/riscv/zfa-fail-fli.s: New failure test for "fli"
>         instructions.
>         * testsuite/gas/riscv/zfa-fail-fli.d: Likewise.
>         * testsuite/gas/riscv/zfa-fail-fli.l: Likewise.
>
> include/ChangeLog:
>
>         * opcode/riscv-opc.h (MATCH_FLI_H, MASK_FLI_H, MATCH_FMINI_H,
>         MASK_FMINI_H, MATCH_FMAXI_H, MASK_FMAXI_H, MATCH_FROUND_H,
>         MASK_FROUND_H, MATCH_FROUNDNX_H, MASK_FROUNDNX_H, MATCH_FLTQ_H,
>         MASK_FLTQ_H, MATCH_FLEQ_H, MASK_FLEQ_H, MATCH_FLI_S, MASK_FLI_S,
>         MATCH_FMINI_S, MASK_FMINI_S, MATCH_FMAXI_S, MASK_FMAXI_S,
>         MATCH_FROUND_S, MASK_FROUND_S, MATCH_FROUNDNX_S, MASK_FROUNDNX_S,
>         MATCH_FLTQ_S, MASK_FLTQ_S, MATCH_FLEQ_S, MASK_FLEQ_S, MATCH_FLI_D,
>         MASK_FLI_D, MATCH_FMINI_D, MASK_FMINI_D, MATCH_FMAXI_D,
>         MASK_FMAXI_D, MATCH_FROUND_D, MASK_FROUND_D, MATCH_FROUNDNX_D,
>         MASK_FROUNDNX_D, MATCH_FLTQ_D, MASK_FLTQ_D, MATCH_FLEQ_D,
>         MASK_FLEQ_D, MATCH_FLI_Q, MASK_FLI_Q, MATCH_FMINI_Q, MASK_FMINI_Q,
>         MATCH_FMAXI_Q, MASK_FMAXI_Q, MATCH_FROUND_Q, MASK_FROUND_Q,
>         MATCH_FROUNDNX_Q, MASK_FROUNDNX_Q, MATCH_FLTQ_Q, MASK_FLTQ_Q,
>         MATCH_FLEQ_Q, MASK_FLEQ_Q, MATCH_FCVTMOD_W_D, MASK_FCVTMOD_W_D,
>         MATCH_FMVH_X_D, MASK_FMVH_X_D, MATCH_FMVH_X_Q, MASK_FMVH_X_Q,
>         MATCH_FMVP_D_X, MASK_FMVP_D_X, MATCH_FMVP_Q_X, MASK_FMVP_Q_X): New.
>         * opcode/riscv.h (enum riscv_insn_class): Add instruction
>         classes for 'Zfa' extension.
>
> opcodes/ChangeLog:
>
>         * riscv-opc.c (riscv_opcodes): Add 'Zfa' instructions.
> ---
>  bfd/elfxx-riscv.c                             | 39 ++++++++
>  gas/config/tc-riscv.c                         | 21 ++++
>  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/riscv/zfa-fail-fcvtmod.w.d.d          |  3 +
>  .../gas/riscv/zfa-fail-fcvtmod.w.d.l          |  8 ++
>  .../gas/riscv/zfa-fail-fcvtmod.w.d.s          | 11 +++
>  gas/testsuite/gas/riscv/zfa-fail-fli.d        |  3 +
>  gas/testsuite/gas/riscv/zfa-fail-fli.l        | 21 ++++
>  gas/testsuite/gas/riscv/zfa-fail-fli.s        | 21 ++++
>  gas/testsuite/gas/riscv/zfa.d                 | 93 +++++++++++++++++
>  gas/testsuite/gas/riscv/zfa.s                 | 92 +++++++++++++++++
>  include/opcode/riscv-opc.h                    | 99 +++++++++++++++++++
>  include/opcode/riscv.h                        |  5 +
>  opcodes/riscv-dis.c                           |  7 ++
>  opcodes/riscv-opc.c                           | 52 +++++++++-
>  18 files changed, 500 insertions(+), 1 deletion(-)
>  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-fcvtmod.w.d.d
>  create mode 100644 gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.l
>  create mode 100644 gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.s
>  create mode 100644 gas/testsuite/gas/riscv/zfa-fail-fli.d
>  create mode 100644 gas/testsuite/gas/riscv/zfa-fail-fli.l
>  create mode 100644 gas/testsuite/gas/riscv/zfa-fail-fli.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 e03b312a381..1c6d1505d54 100644
> --- a/bfd/elfxx-riscv.c
> +++ b/bfd/elfxx-riscv.c
> @@ -1073,6 +1073,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},
> @@ -1162,6 +1163,7 @@ static struct riscv_supported_ext riscv_supported_std_z_ext[] =
>    {"zifencei",         ISA_SPEC_CLASS_20190608,        2, 0,  0 },
>    {"zihintpause",      ISA_SPEC_CLASS_DRAFT,           2, 0,  0 },
>    {"zmmul",            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 },
> @@ -2334,6 +2336,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:
> @@ -2469,6 +2482,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 2f5ee18e451..ffbc7fbdda2 100644
> --- a/gas/config/tc-riscv.c
> +++ b/gas/config/tc-riscv.c
> @@ -1208,6 +1208,7 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
>         case 'd': USE_BITS (OP_MASK_RD, OP_SH_RD); break;
>         case 'y': USE_BITS (OP_MASK_BS, OP_SH_BS); break;
>         case 'Y': USE_BITS (OP_MASK_RNUM, OP_SH_RNUM); break;
> +       case 'i': /* RS1, FLI.[HSDQ] value field.  */
>         case 'Z': /* RS1, CSR number.  */
>         case 'S': /* RS1, floating point.  */
>         case 's': USE_BITS (OP_MASK_RS1, OP_SH_RS1); break;
> @@ -3262,6 +3263,26 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
>               asarg = expr_end;
>               continue;
>
> +           case 'i': /* FLI.[HSDQ] constant immediate.  */
> +             if (arg_lookup (&asarg, riscv_fli_value,
> +                             ARRAY_SIZE (riscv_fli_value), &regno))
> +               INSERT_OPERAND (RS1, *ip, regno);
> +             else
> +               {
> +                 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
> +                     || imm_expr->X_op != O_constant)
> +                   break;
> +                 if (imm_expr->X_add_number < 0
> +                     || imm_expr->X_add_number > 29)
> +                   as_bad (_ ("improper fli value field (%ld), "
> +                              "value must be 0...29 or min, inf or nan"),
> +                           (long) imm_expr->X_add_number);
> +                 INSERT_OPERAND (RS1, *ip, imm_expr->X_add_number);
> +                 imm_expr->X_op = O_absent;
> +                 asarg = expr_end;
> +               }
> +             continue;
> +
>             default:
>             unknown_riscv_ip_operand:
>               as_fatal (_("internal: unknown argument type `%s'"),
> diff --git a/gas/testsuite/gas/riscv/zfa-32.d b/gas/testsuite/gas/riscv/zfa-32.d
> new file mode 100644
> index 00000000000..0f0cbfcdc70
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zfa-32.d
> @@ -0,0 +1,10 @@
> +#as: -march=rv32id_zfa
> +#objdump: -dr
> +
> +.*:[   ]+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..f942d616959
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zfa-64.d
> @@ -0,0 +1,10 @@
> +#as: -march=rv64iq_zfa
> +#objdump: -dr
> +
> +.*:[   ]+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-fcvtmod.w.d.d b/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.d
> new file mode 100644
> index 00000000000..5234c49de75
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.d
> @@ -0,0 +1,3 @@
> +#as: -march=rv64id_zfa
> +#objdump: -dr
> +#error_output: zfa-fail-fcvtmod.w.d.l
> diff --git a/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.l b/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.l
> new file mode 100644
> index 00000000000..4ea048a3356
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.l
> @@ -0,0 +1,8 @@
> +.*: Assembler messages:
> +.*: 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-fcvtmod.w.d.s b/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.s
> new file mode 100644
> index 00000000000..5984f6676d8
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.s
> @@ -0,0 +1,11 @@
> +target:
> +       # fcvtmod.w.d requires explicit rounding mode.
> +       fcvtmod.w.d     a0, ft1
> +       # 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
> +       # Invalid rounding mode is invalid.
> +       fcvtmod.w.d     a0, ft1, invalid
> diff --git a/gas/testsuite/gas/riscv/zfa-fail-fli.d b/gas/testsuite/gas/riscv/zfa-fail-fli.d
> new file mode 100644
> index 00000000000..3753a4d185e
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zfa-fail-fli.d
> @@ -0,0 +1,3 @@
> +#as: -march=rv64iq_zfa_zfh
> +#objdump: -dr
> +#error_output: zfa-fail-fli.l
> diff --git a/gas/testsuite/gas/riscv/zfa-fail-fli.l b/gas/testsuite/gas/riscv/zfa-fail-fli.l
> new file mode 100644
> index 00000000000..b7532f80fd4
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zfa-fail-fli.l
> @@ -0,0 +1,21 @@
> +.*: Assembler messages:
> +.*: Error: improper fli value field \(-1\), value must be 0\.\.\.29 or min, inf or nan
> +.*: Error: improper fli value field \(-1\), value must be 0\.\.\.29 or min, inf or nan
> +.*: Error: improper fli value field \(-1\), value must be 0\.\.\.29 or min, inf or nan
> +.*: Error: improper fli value field \(-1\), value must be 0\.\.\.29 or min, inf or nan
> +.*: Error: improper fli value field \(-2\), value must be 0\.\.\.29 or min, inf or nan
> +.*: Error: improper fli value field \(-2\), value must be 0\.\.\.29 or min, inf or nan
> +.*: Error: improper fli value field \(-2\), value must be 0\.\.\.29 or min, inf or nan
> +.*: Error: improper fli value field \(-2\), value must be 0\.\.\.29 or min, inf or nan
> +.*: Error: improper fli value field \(30\), value must be 0\.\.\.29 or min, inf or nan
> +.*: Error: improper fli value field \(30\), value must be 0\.\.\.29 or min, inf or nan
> +.*: Error: improper fli value field \(30\), value must be 0\.\.\.29 or min, inf or nan
> +.*: Error: improper fli value field \(30\), value must be 0\.\.\.29 or min, inf or nan
> +.*: Error: improper fli value field \(32\), value must be 0\.\.\.29 or min, inf or nan
> +.*: Error: improper fli value field \(32\), value must be 0\.\.\.29 or min, inf or nan
> +.*: Error: improper fli value field \(32\), value must be 0\.\.\.29 or min, inf or nan
> +.*: Error: improper fli value field \(32\), value must be 0\.\.\.29 or min, inf or nan
> +.*: Error: illegal operands `fli\.h ft1,invalid'
> +.*: Error: illegal operands `fli\.s ft1,invalid'
> +.*: Error: illegal operands `fli\.d ft1,invalid'
> +.*: Error: illegal operands `fli\.q ft1,invalid'
> diff --git a/gas/testsuite/gas/riscv/zfa-fail-fli.s b/gas/testsuite/gas/riscv/zfa-fail-fli.s
> new file mode 100644
> index 00000000000..4c600b5d578
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zfa-fail-fli.s
> @@ -0,0 +1,21 @@
> +target:
> +       fli.h   ft1, -1
> +       fli.s   ft1, -1
> +       fli.d   ft1, -1
> +       fli.q   ft1, -1
> +       fli.h   ft1, -2
> +       fli.s   ft1, -2
> +       fli.d   ft1, -2
> +       fli.q   ft1, -2
> +       fli.h   ft1, 30
> +       fli.s   ft1, 30
> +       fli.d   ft1, 30
> +       fli.q   ft1, 30
> +       fli.h   ft1, 32
> +       fli.s   ft1, 32
> +       fli.d   ft1, 32
> +       fli.q   ft1, 32
> +       fli.h   ft1, invalid
> +       fli.s   ft1, invalid
> +       fli.d   ft1, invalid
> +       fli.q   ft1, invalid
> diff --git a/gas/testsuite/gas/riscv/zfa.d b/gas/testsuite/gas/riscv/zfa.d
> new file mode 100644
> index 00000000000..3701a41e485
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zfa.d
> @@ -0,0 +1,93 @@
> +#as: -march=rv64iq_zfa_zfh
> +#objdump: -dr
> +
> +.*:[   ]+file format .*
> +
> +Disassembly of section .text:
> +
> +0+000 <target>:

Hi Tsukasa,

There seems to be a misunderstanding of the spec.
The second operand of the fli should be the constant itself ("Value"
column of the specification) in C-like syntax.
E.g.:
  fli.h ft1, -1.0 # encoding rs1=0
  fli.h ft1, min # encoding rs1=1
  fli.h ft1, 0.0000152587890625 # encoding rs1=2
  ...
  fli.h ft1, 16 # encoding rs1=25
  ...
  fli.h ft1, nan # encoding rs1=31

So we have 3 strings ("min", "inf", "nan") and 29 constants.

BR
Christoph

> +[      ]+[0-9a-f]+:[   ]+f41000d3[     ]+fli\.h[               ]+ft1,0
> +[      ]+[0-9a-f]+:[   ]+f41080d3[     ]+fli\.h[               ]+ft1,min
> +[      ]+[0-9a-f]+:[   ]+f41100d3[     ]+fli\.h[               ]+ft1,2
> +[      ]+[0-9a-f]+:[   ]+f41d80d3[     ]+fli\.h[               ]+ft1,27
> +[      ]+[0-9a-f]+:[   ]+f41e00d3[     ]+fli\.h[               ]+ft1,28
> +[      ]+[0-9a-f]+:[   ]+f41e80d3[     ]+fli\.h[               ]+ft1,29
> +[      ]+[0-9a-f]+:[   ]+f41080d3[     ]+fli\.h[               ]+ft1,min
> +[      ]+[0-9a-f]+:[   ]+f41f00d3[     ]+fli\.h[               ]+ft1,inf
> +[      ]+[0-9a-f]+:[   ]+f41f80d3[     ]+fli\.h[               ]+ft1,nan
> +[      ]+[0-9a-f]+:[   ]+f01000d3[     ]+fli\.s[               ]+ft1,0
> +[      ]+[0-9a-f]+:[   ]+f01080d3[     ]+fli\.s[               ]+ft1,min
> +[      ]+[0-9a-f]+:[   ]+f01100d3[     ]+fli\.s[               ]+ft1,2
> +[      ]+[0-9a-f]+:[   ]+f01d80d3[     ]+fli\.s[               ]+ft1,27
> +[      ]+[0-9a-f]+:[   ]+f01e00d3[     ]+fli\.s[               ]+ft1,28
> +[      ]+[0-9a-f]+:[   ]+f01e80d3[     ]+fli\.s[               ]+ft1,29
> +[      ]+[0-9a-f]+:[   ]+f01080d3[     ]+fli\.s[               ]+ft1,min
> +[      ]+[0-9a-f]+:[   ]+f01f00d3[     ]+fli\.s[               ]+ft1,inf
> +[      ]+[0-9a-f]+:[   ]+f01f80d3[     ]+fli\.s[               ]+ft1,nan
> +[      ]+[0-9a-f]+:[   ]+f21000d3[     ]+fli\.d[               ]+ft1,0
> +[      ]+[0-9a-f]+:[   ]+f21080d3[     ]+fli\.d[               ]+ft1,min
> +[      ]+[0-9a-f]+:[   ]+f21100d3[     ]+fli\.d[               ]+ft1,2
> +[      ]+[0-9a-f]+:[   ]+f21d80d3[     ]+fli\.d[               ]+ft1,27
> +[      ]+[0-9a-f]+:[   ]+f21e00d3[     ]+fli\.d[               ]+ft1,28
> +[      ]+[0-9a-f]+:[   ]+f21e80d3[     ]+fli\.d[               ]+ft1,29
> +[      ]+[0-9a-f]+:[   ]+f21080d3[     ]+fli\.d[               ]+ft1,min
> +[      ]+[0-9a-f]+:[   ]+f21f00d3[     ]+fli\.d[               ]+ft1,inf
> +[      ]+[0-9a-f]+:[   ]+f21f80d3[     ]+fli\.d[               ]+ft1,nan
> +[      ]+[0-9a-f]+:[   ]+f61000d3[     ]+fli\.q[               ]+ft1,0
> +[      ]+[0-9a-f]+:[   ]+f61080d3[     ]+fli\.q[               ]+ft1,min
> +[      ]+[0-9a-f]+:[   ]+f61100d3[     ]+fli\.q[               ]+ft1,2
> +[      ]+[0-9a-f]+:[   ]+f61d80d3[     ]+fli\.q[               ]+ft1,27
> +[      ]+[0-9a-f]+:[   ]+f61e00d3[     ]+fli\.q[               ]+ft1,28
> +[      ]+[0-9a-f]+:[   ]+f61e80d3[     ]+fli\.q[               ]+ft1,29
> +[      ]+[0-9a-f]+:[   ]+f61080d3[     ]+fli\.q[               ]+ft1,min
> +[      ]+[0-9a-f]+:[   ]+f61f00d3[     ]+fli\.q[               ]+ft1,inf
> +[      ]+[0-9a-f]+:[   ]+f61f80d3[     ]+fli\.q[               ]+ft1,nan
> +[      ]+[0-9a-f]+:[   ]+2c3100d3[     ]+fmin\.h[              ]+ft1,ft2,ft3
> +[      ]+[0-9a-f]+:[   ]+2c3120d3[     ]+fmini\.h[             ]+ft1,ft2,ft3
> +[      ]+[0-9a-f]+:[   ]+283100d3[     ]+fmin\.s[              ]+ft1,ft2,ft3
> +[      ]+[0-9a-f]+:[   ]+283120d3[     ]+fmini\.s[             ]+ft1,ft2,ft3
> +[      ]+[0-9a-f]+:[   ]+2a3100d3[     ]+fmin\.d[              ]+ft1,ft2,ft3
> +[      ]+[0-9a-f]+:[   ]+2a3120d3[     ]+fmini\.d[             ]+ft1,ft2,ft3
> +[      ]+[0-9a-f]+:[   ]+2e3100d3[     ]+fmin\.q[              ]+ft1,ft2,ft3
> +[      ]+[0-9a-f]+:[   ]+2e3120d3[     ]+fmini\.q[             ]+ft1,ft2,ft3
> +[      ]+[0-9a-f]+:[   ]+2c3110d3[     ]+fmax\.h[              ]+ft1,ft2,ft3
> +[      ]+[0-9a-f]+:[   ]+2c3130d3[     ]+fmaxi\.h[             ]+ft1,ft2,ft3
> +[      ]+[0-9a-f]+:[   ]+283110d3[     ]+fmax\.s[              ]+ft1,ft2,ft3
> +[      ]+[0-9a-f]+:[   ]+283130d3[     ]+fmaxi\.s[             ]+ft1,ft2,ft3
> +[      ]+[0-9a-f]+:[   ]+2a3110d3[     ]+fmax\.d[              ]+ft1,ft2,ft3
> +[      ]+[0-9a-f]+:[   ]+2a3130d3[     ]+fmaxi\.d[             ]+ft1,ft2,ft3
> +[      ]+[0-9a-f]+:[   ]+2e3110d3[     ]+fmax\.q[              ]+ft1,ft2,ft3
> +[      ]+[0-9a-f]+:[   ]+2e3130d3[     ]+fmaxi\.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..fb79792bf10
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zfa.s
> @@ -0,0 +1,92 @@
> +target:
> +       # fli: test both decimal and symbol representations
> +       #      (0..29, min==1, inf==(30), nan==(31))
> +       fli.h           ft1, 0
> +       fli.h           ft1, 1
> +       fli.h           ft1, 2
> +       fli.h           ft1, 27
> +       fli.h           ft1, 28
> +       fli.h           ft1, 29
> +       fli.h           ft1, min
> +       fli.h           ft1, inf
> +       fli.h           ft1, nan
> +       fli.s           ft1, 0
> +       fli.s           ft1, 1
> +       fli.s           ft1, 2
> +       fli.s           ft1, 27
> +       fli.s           ft1, 28
> +       fli.s           ft1, 29
> +       fli.s           ft1, min
> +       fli.s           ft1, inf
> +       fli.s           ft1, nan
> +       fli.d           ft1, 0
> +       fli.d           ft1, 1
> +       fli.d           ft1, 2
> +       fli.d           ft1, 27
> +       fli.d           ft1, 28
> +       fli.d           ft1, 29
> +       fli.d           ft1, min
> +       fli.d           ft1, inf
> +       fli.d           ft1, nan
> +       fli.q           ft1, 0
> +       fli.q           ft1, 1
> +       fli.q           ft1, 2
> +       fli.q           ft1, 27
> +       fli.q           ft1, 28
> +       fli.q           ft1, 29
> +       fli.q           ft1, min
> +       fli.q           ft1, inf
> +       fli.q           ft1, nan
> +       # fmini/fmaxi (Zfa): same as fmin/fmax (Zfh/F/D/Q) except bit 13 set
> +       fmin.h          ft1, ft2, ft3
> +       fmini.h         ft1, ft2, ft3
> +       fmin.s          ft1, ft2, ft3
> +       fmini.s         ft1, ft2, ft3
> +       fmin.d          ft1, ft2, ft3
> +       fmini.d         ft1, ft2, ft3
> +       fmin.q          ft1, ft2, ft3
> +       fmini.q         ft1, ft2, ft3
> +       fmax.h          ft1, ft2, ft3
> +       fmaxi.h         ft1, ft2, ft3
> +       fmax.s          ft1, ft2, ft3
> +       fmaxi.s         ft1, ft2, ft3
> +       fmax.d          ft1, ft2, ft3
> +       fmaxi.d         ft1, ft2, ft3
> +       fmax.q          ft1, ft2, ft3
> +       fmaxi.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 (Zfa): same as flt/fle (Zfh/F/D/Q) except bit 14 set
> +       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 88b8d7ff595..9739ad24538 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_FMINI_H 0x2c002053
> +#define MASK_FMINI_H 0xfe00707f
> +#define MATCH_FMAXI_H 0x2c003053
> +#define MASK_FMAXI_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_FMINI_S 0x28002053
> +#define MASK_FMINI_S 0xfe00707f
> +#define MATCH_FMAXI_S 0x28003053
> +#define MASK_FMAXI_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_FMINI_D 0x2a002053
> +#define MASK_FMINI_D 0xfe00707f
> +#define MATCH_FMAXI_D 0x2a003053
> +#define MASK_FMAXI_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_FMINI_Q 0x2e002053
> +#define MASK_FMINI_Q 0xfe00707f
> +#define MATCH_FMAXI_Q 0x2e003053
> +#define MASK_FMAXI_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
> @@ -2718,6 +2784,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(fmini_h, MATCH_FMINI_H, MASK_FMINI_H)
> +DECLARE_INSN(fmaxi_h, MATCH_FMAXI_H, MASK_FMAXI_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(fmini_s, MATCH_FMINI_S, MASK_FMINI_S)
> +DECLARE_INSN(fmaxi_s, MATCH_FMAXI_S, MASK_FMAXI_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(fmini_d, MATCH_FMINI_D, MASK_FMINI_D)
> +DECLARE_INSN(fmaxi_d, MATCH_FMAXI_D, MASK_FMAXI_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(fmini_q, MATCH_FMINI_Q, MASK_FMINI_Q)
> +DECLARE_INSN(fmaxi_q, MATCH_FMAXI_Q, MASK_FMAXI_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 f1dabeaab8e..3e9feaac2a7 100644
> --- a/include/opcode/riscv.h
> +++ b/include/opcode/riscv.h
> @@ -376,6 +376,10 @@ enum riscv_insn_class
>    INSN_CLASS_ZFHMIN_OR_ZHINXMIN,
>    INSN_CLASS_ZFHMIN_AND_D,
>    INSN_CLASS_ZFHMIN_AND_Q,
> +  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,
> @@ -528,6 +532,7 @@ 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_value[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 7ae6e709290..7a8be52281f 100644
> --- a/opcodes/riscv-dis.c
> +++ b/opcodes/riscv-dis.c
> @@ -563,6 +563,13 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
>           print (info->stream, dis_style_text, "%d", rs1);
>           break;
>
> +       case 'i':
> +         if (riscv_fli_value[rs1])
> +           print (info->stream, dis_style_text, "%s", riscv_fli_value[rs1]);
> +         else
> +           print (info->stream, dis_style_immediate, "%d", rs1);
> +         break;
> +
>         default:
>           /* xgettext:c-format */
>           print (info->stream, dis_style_text,
> diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
> index 79be78eb367..eb4da1a7485 100644
> --- a/opcodes/riscv-opc.c
> +++ b/opcodes/riscv-opc.c
> @@ -97,6 +97,15 @@ const char * const riscv_vma[2] =
>    "mu", "ma"
>  };
>
> +/* The FLI.[HSDQ] value constants.  */
> +const char * const riscv_fli_value[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 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
> @@ -636,6 +645,15 @@ const struct riscv_opcode riscv_opcodes[] =
>  {"fcvt.h.l",  64, INSN_CLASS_ZFH_OR_ZHINX,   "D,s,m",     MATCH_FCVT_H_L, MASK_FCVT_H_L, match_opcode, 0 },
>  {"fcvt.h.lu", 64, INSN_CLASS_ZFH_OR_ZHINX,   "D,s",       MATCH_FCVT_H_LU|MASK_RM, MASK_FCVT_H_LU|MASK_RM, match_opcode, 0 },
>  {"fcvt.h.lu", 64, INSN_CLASS_ZFH_OR_ZHINX,   "D,s,m",     MATCH_FCVT_H_LU, MASK_FCVT_H_LU, match_opcode, 0 },
> +{"fli.h",      0, INSN_CLASS_ZFH_AND_ZFA,    "D,i",       MATCH_FLI_H, MASK_FLI_H, match_opcode, 0 },
> +{"fmini.h",    0, INSN_CLASS_ZFH_AND_ZFA,    "D,S,T",     MATCH_FMINI_H, MASK_FMINI_H, match_opcode, 0 },
> +{"fmaxi.h",    0, INSN_CLASS_ZFH_AND_ZFA,    "D,S,T",     MATCH_FMAXI_H, MASK_FMAXI_H, 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 },
> +{"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 },
>
>  /* Single-precision floating-point instruction subset.  */
>  {"frcsr",      0, INSN_CLASS_F_OR_ZFINX,   "d",         MATCH_FRCSR, MASK_FRCSR, match_opcode, INSN_ALIAS },
> @@ -714,7 +732,16 @@ const struct riscv_opcode riscv_opcodes[] =
>  {"fcvt.s.l",  64, INSN_CLASS_F_OR_ZFINX,   "D,s,m",     MATCH_FCVT_S_L, MASK_FCVT_S_L, match_opcode, 0 },
>  {"fcvt.s.lu", 64, INSN_CLASS_F_OR_ZFINX,   "D,s",       MATCH_FCVT_S_LU|MASK_RM, MASK_FCVT_S_LU|MASK_RM, match_opcode, 0 },
>  {"fcvt.s.lu", 64, INSN_CLASS_F_OR_ZFINX,   "D,s,m",     MATCH_FCVT_S_LU, MASK_FCVT_S_LU, match_opcode, 0 },
> -
> +{"fli.s",      0, INSN_CLASS_ZFA,          "D,i",       MATCH_FLI_S, MASK_FLI_S, match_opcode, 0 },
> +{"fmini.s",    0, INSN_CLASS_ZFA,          "D,S,T",     MATCH_FMINI_S, MASK_FMINI_S, match_opcode, 0 },
> +{"fmaxi.s",    0, INSN_CLASS_ZFA,          "D,S,T",     MATCH_FMAXI_S, MASK_FMAXI_S, 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 },
> +{"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 },
> +
>  /* Double-precision floating-point instruction subset.  */
>  {"fld",        0, INSN_CLASS_D_AND_C, "D,Cn(Cc)",  MATCH_C_FLDSP, MASK_C_FLDSP, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
>  {"fld",        0, INSN_CLASS_D_AND_C, "CD,Cl(Cs)", MATCH_C_FLD, MASK_C_FLD, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
> @@ -775,6 +802,18 @@ const struct riscv_opcode riscv_opcodes[] =
>  {"fcvt.d.l",  64, INSN_CLASS_D_OR_ZDINX,   "D,s,m",     MATCH_FCVT_D_L, MASK_FCVT_D_L, match_opcode, 0 },
>  {"fcvt.d.lu", 64, INSN_CLASS_D_OR_ZDINX,   "D,s",       MATCH_FCVT_D_LU|MASK_RM, MASK_FCVT_D_LU|MASK_RM, match_opcode, 0 },
>  {"fcvt.d.lu", 64, INSN_CLASS_D_OR_ZDINX,   "D,s,m",     MATCH_FCVT_D_LU, MASK_FCVT_D_LU, match_opcode, 0 },
> +{"fli.d",       0, INSN_CLASS_D_AND_ZFA,   "D,i",       MATCH_FLI_D, MASK_FLI_D, match_opcode, 0 },
> +{"fmini.d",     0, INSN_CLASS_D_AND_ZFA,   "D,S,T",     MATCH_FMINI_D, MASK_FMINI_D, match_opcode, 0 },
> +{"fmaxi.d",     0, INSN_CLASS_D_AND_ZFA,   "D,S,T",     MATCH_FMAXI_D, MASK_FMAXI_D, 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 },
> +{"fcvtmod.w.d", 0, INSN_CLASS_D_AND_ZFA,   "d,S,m",     MATCH_FCVTMOD_W_D, MASK_FCVTMOD_W_D, 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 },
> +{"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},
>
>  /* Quad-precision floating-point instruction subset.  */
>  {"flq",        0, INSN_CLASS_Q,   "D,o(s)",    MATCH_FLQ, MASK_FLQ, match_opcode, INSN_DREF|INSN_16_BYTE },
> @@ -833,6 +872,17 @@ const struct riscv_opcode riscv_opcodes[] =
>  {"fcvt.q.l",  64, INSN_CLASS_Q_OR_ZQINX,   "D,s,m",     MATCH_FCVT_Q_L, MASK_FCVT_Q_L, match_opcode, 0 },
>  {"fcvt.q.lu", 64, INSN_CLASS_Q_OR_ZQINX,   "D,s",       MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU|MASK_RM, match_opcode, 0 },
>  {"fcvt.q.lu", 64, INSN_CLASS_Q_OR_ZQINX,   "D,s,m",     MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU, match_opcode, 0 },
> +{"fli.q",       0, INSN_CLASS_Q_AND_ZFA,   "D,i",       MATCH_FLI_Q, MASK_FLI_Q, match_opcode, 0 },
> +{"fmini.q",     0, INSN_CLASS_Q_AND_ZFA,   "D,S,T",     MATCH_FMINI_Q, MASK_FMINI_Q, match_opcode, 0 },
> +{"fmaxi.q",     0, INSN_CLASS_Q_AND_ZFA,   "D,S,T",     MATCH_FMAXI_Q, MASK_FMAXI_Q, 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 },
> +{"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 },
> +{"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},
>
>  /* Compressed instructions.  */
>  {"c.unimp",    0, INSN_CLASS_C,   "",          0, 0xffffU,  match_opcode, 0 },
> --
> 2.34.1
>

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

* Re: [REVIEW ONLY 1/1] UNRATIFIED RISC-V: Add 'Zfa' extension
  2023-03-22 15:47   ` Christoph Müllner
@ 2023-03-22 16:01     ` Philipp Tomsich
  2023-03-22 16:07     ` Tsukasa OI
  2023-03-26 15:43     ` Jeff Law
  2 siblings, 0 replies; 10+ messages in thread
From: Philipp Tomsich @ 2023-03-22 16:01 UTC (permalink / raw)
  To: Christoph Müllner; +Cc: Tsukasa OI, binutils, Andrew Waterman

On Wed, 22 Mar 2023 at 23:47, Christoph Müllner
<christoph.muellner@vrull.eu> wrote:
>
> On Sun, Sep 18, 2022 at 12:13 PM Tsukasa OI via Binutils
> <binutils@sourceware.org> wrote:
> >
> > [DO NOT MERGE]
> > Until 'Zfa' extension is frozen/ratified and final version number is
> > determined, this patch should not merged upstream. This commit uses
> > unratified version 0.1 as in documentation (instead of possible 1.0
> > after ratification).
> >
> > This commit adds the 'Zfa' extension (its instructions and new operand
> > type for FLI instructions).
> >
> > This is based on:
> > <https://github.com/riscv/riscv-isa-manual/commit/ae683aec28ec707a3c4bb6f588491f0840d52f43>
> > (latest commit of the 'zfb' branch as of this writing)
> >
> > Note: the author is calling FLI instructions' RS1 encoded field as
> > "value".  It must be reviewed before the specification is frozen.
> >
> > 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:
> >
> >         * testsuite/gas/riscv/zfa.s: New test.
> >         * testsuite/gas/riscv/zfa.d: Likewise.
> >         * testsuite/gas/riscv/zfa-32.s: New test.
> >         * testsuite/gas/riscv/zfa-32.d: Likewise.
> >         * testsuite/gas/riscv/zfa-64.s: New test.
> >         * testsuite/gas/riscv/zfa-64.d: Likewise.
> >         * testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.s: New failure test for
> >         the "fcvtmod.w.d" instruction.
> >         * testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.d: Likewise.
> >         * testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.l: Likewise.
> >         * testsuite/gas/riscv/zfa-fail-fli.s: New failure test for "fli"
> >         instructions.
> >         * testsuite/gas/riscv/zfa-fail-fli.d: Likewise.
> >         * testsuite/gas/riscv/zfa-fail-fli.l: Likewise.
> >
> > include/ChangeLog:
> >
> >         * opcode/riscv-opc.h (MATCH_FLI_H, MASK_FLI_H, MATCH_FMINI_H,
> >         MASK_FMINI_H, MATCH_FMAXI_H, MASK_FMAXI_H, MATCH_FROUND_H,
> >         MASK_FROUND_H, MATCH_FROUNDNX_H, MASK_FROUNDNX_H, MATCH_FLTQ_H,
> >         MASK_FLTQ_H, MATCH_FLEQ_H, MASK_FLEQ_H, MATCH_FLI_S, MASK_FLI_S,
> >         MATCH_FMINI_S, MASK_FMINI_S, MATCH_FMAXI_S, MASK_FMAXI_S,
> >         MATCH_FROUND_S, MASK_FROUND_S, MATCH_FROUNDNX_S, MASK_FROUNDNX_S,
> >         MATCH_FLTQ_S, MASK_FLTQ_S, MATCH_FLEQ_S, MASK_FLEQ_S, MATCH_FLI_D,
> >         MASK_FLI_D, MATCH_FMINI_D, MASK_FMINI_D, MATCH_FMAXI_D,
> >         MASK_FMAXI_D, MATCH_FROUND_D, MASK_FROUND_D, MATCH_FROUNDNX_D,
> >         MASK_FROUNDNX_D, MATCH_FLTQ_D, MASK_FLTQ_D, MATCH_FLEQ_D,
> >         MASK_FLEQ_D, MATCH_FLI_Q, MASK_FLI_Q, MATCH_FMINI_Q, MASK_FMINI_Q,
> >         MATCH_FMAXI_Q, MASK_FMAXI_Q, MATCH_FROUND_Q, MASK_FROUND_Q,
> >         MATCH_FROUNDNX_Q, MASK_FROUNDNX_Q, MATCH_FLTQ_Q, MASK_FLTQ_Q,
> >         MATCH_FLEQ_Q, MASK_FLEQ_Q, MATCH_FCVTMOD_W_D, MASK_FCVTMOD_W_D,
> >         MATCH_FMVH_X_D, MASK_FMVH_X_D, MATCH_FMVH_X_Q, MASK_FMVH_X_Q,
> >         MATCH_FMVP_D_X, MASK_FMVP_D_X, MATCH_FMVP_Q_X, MASK_FMVP_Q_X): New.
> >         * opcode/riscv.h (enum riscv_insn_class): Add instruction
> >         classes for 'Zfa' extension.
> >
> > opcodes/ChangeLog:
> >
> >         * riscv-opc.c (riscv_opcodes): Add 'Zfa' instructions.
> > ---
> >  bfd/elfxx-riscv.c                             | 39 ++++++++
> >  gas/config/tc-riscv.c                         | 21 ++++
> >  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/riscv/zfa-fail-fcvtmod.w.d.d          |  3 +
> >  .../gas/riscv/zfa-fail-fcvtmod.w.d.l          |  8 ++
> >  .../gas/riscv/zfa-fail-fcvtmod.w.d.s          | 11 +++
> >  gas/testsuite/gas/riscv/zfa-fail-fli.d        |  3 +
> >  gas/testsuite/gas/riscv/zfa-fail-fli.l        | 21 ++++
> >  gas/testsuite/gas/riscv/zfa-fail-fli.s        | 21 ++++
> >  gas/testsuite/gas/riscv/zfa.d                 | 93 +++++++++++++++++
> >  gas/testsuite/gas/riscv/zfa.s                 | 92 +++++++++++++++++
> >  include/opcode/riscv-opc.h                    | 99 +++++++++++++++++++
> >  include/opcode/riscv.h                        |  5 +
> >  opcodes/riscv-dis.c                           |  7 ++
> >  opcodes/riscv-opc.c                           | 52 +++++++++-
> >  18 files changed, 500 insertions(+), 1 deletion(-)
> >  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-fcvtmod.w.d.d
> >  create mode 100644 gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.l
> >  create mode 100644 gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.s
> >  create mode 100644 gas/testsuite/gas/riscv/zfa-fail-fli.d
> >  create mode 100644 gas/testsuite/gas/riscv/zfa-fail-fli.l
> >  create mode 100644 gas/testsuite/gas/riscv/zfa-fail-fli.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 e03b312a381..1c6d1505d54 100644
> > --- a/bfd/elfxx-riscv.c
> > +++ b/bfd/elfxx-riscv.c
> > @@ -1073,6 +1073,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},
> > @@ -1162,6 +1163,7 @@ static struct riscv_supported_ext riscv_supported_std_z_ext[] =
> >    {"zifencei",         ISA_SPEC_CLASS_20190608,        2, 0,  0 },
> >    {"zihintpause",      ISA_SPEC_CLASS_DRAFT,           2, 0,  0 },
> >    {"zmmul",            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 },
> > @@ -2334,6 +2336,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:
> > @@ -2469,6 +2482,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 2f5ee18e451..ffbc7fbdda2 100644
> > --- a/gas/config/tc-riscv.c
> > +++ b/gas/config/tc-riscv.c
> > @@ -1208,6 +1208,7 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
> >         case 'd': USE_BITS (OP_MASK_RD, OP_SH_RD); break;
> >         case 'y': USE_BITS (OP_MASK_BS, OP_SH_BS); break;
> >         case 'Y': USE_BITS (OP_MASK_RNUM, OP_SH_RNUM); break;
> > +       case 'i': /* RS1, FLI.[HSDQ] value field.  */
> >         case 'Z': /* RS1, CSR number.  */
> >         case 'S': /* RS1, floating point.  */
> >         case 's': USE_BITS (OP_MASK_RS1, OP_SH_RS1); break;
> > @@ -3262,6 +3263,26 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
> >               asarg = expr_end;
> >               continue;
> >
> > +           case 'i': /* FLI.[HSDQ] constant immediate.  */
> > +             if (arg_lookup (&asarg, riscv_fli_value,
> > +                             ARRAY_SIZE (riscv_fli_value), &regno))
> > +               INSERT_OPERAND (RS1, *ip, regno);
> > +             else
> > +               {
> > +                 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
> > +                     || imm_expr->X_op != O_constant)
> > +                   break;
> > +                 if (imm_expr->X_add_number < 0
> > +                     || imm_expr->X_add_number > 29)
> > +                   as_bad (_ ("improper fli value field (%ld), "
> > +                              "value must be 0...29 or min, inf or nan"),
> > +                           (long) imm_expr->X_add_number);
> > +                 INSERT_OPERAND (RS1, *ip, imm_expr->X_add_number);
> > +                 imm_expr->X_op = O_absent;
> > +                 asarg = expr_end;
> > +               }
> > +             continue;
> > +
> >             default:
> >             unknown_riscv_ip_operand:
> >               as_fatal (_("internal: unknown argument type `%s'"),
> > diff --git a/gas/testsuite/gas/riscv/zfa-32.d b/gas/testsuite/gas/riscv/zfa-32.d
> > new file mode 100644
> > index 00000000000..0f0cbfcdc70
> > --- /dev/null
> > +++ b/gas/testsuite/gas/riscv/zfa-32.d
> > @@ -0,0 +1,10 @@
> > +#as: -march=rv32id_zfa
> > +#objdump: -dr
> > +
> > +.*:[   ]+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..f942d616959
> > --- /dev/null
> > +++ b/gas/testsuite/gas/riscv/zfa-64.d
> > @@ -0,0 +1,10 @@
> > +#as: -march=rv64iq_zfa
> > +#objdump: -dr
> > +
> > +.*:[   ]+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-fcvtmod.w.d.d b/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.d
> > new file mode 100644
> > index 00000000000..5234c49de75
> > --- /dev/null
> > +++ b/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.d
> > @@ -0,0 +1,3 @@
> > +#as: -march=rv64id_zfa
> > +#objdump: -dr
> > +#error_output: zfa-fail-fcvtmod.w.d.l
> > diff --git a/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.l b/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.l
> > new file mode 100644
> > index 00000000000..4ea048a3356
> > --- /dev/null
> > +++ b/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.l
> > @@ -0,0 +1,8 @@
> > +.*: Assembler messages:
> > +.*: 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-fcvtmod.w.d.s b/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.s
> > new file mode 100644
> > index 00000000000..5984f6676d8
> > --- /dev/null
> > +++ b/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.s
> > @@ -0,0 +1,11 @@
> > +target:
> > +       # fcvtmod.w.d requires explicit rounding mode.
> > +       fcvtmod.w.d     a0, ft1
> > +       # 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
> > +       # Invalid rounding mode is invalid.
> > +       fcvtmod.w.d     a0, ft1, invalid
> > diff --git a/gas/testsuite/gas/riscv/zfa-fail-fli.d b/gas/testsuite/gas/riscv/zfa-fail-fli.d
> > new file mode 100644
> > index 00000000000..3753a4d185e
> > --- /dev/null
> > +++ b/gas/testsuite/gas/riscv/zfa-fail-fli.d
> > @@ -0,0 +1,3 @@
> > +#as: -march=rv64iq_zfa_zfh
> > +#objdump: -dr
> > +#error_output: zfa-fail-fli.l
> > diff --git a/gas/testsuite/gas/riscv/zfa-fail-fli.l b/gas/testsuite/gas/riscv/zfa-fail-fli.l
> > new file mode 100644
> > index 00000000000..b7532f80fd4
> > --- /dev/null
> > +++ b/gas/testsuite/gas/riscv/zfa-fail-fli.l
> > @@ -0,0 +1,21 @@
> > +.*: Assembler messages:
> > +.*: Error: improper fli value field \(-1\), value must be 0\.\.\.29 or min, inf or nan
> > +.*: Error: improper fli value field \(-1\), value must be 0\.\.\.29 or min, inf or nan
> > +.*: Error: improper fli value field \(-1\), value must be 0\.\.\.29 or min, inf or nan
> > +.*: Error: improper fli value field \(-1\), value must be 0\.\.\.29 or min, inf or nan
> > +.*: Error: improper fli value field \(-2\), value must be 0\.\.\.29 or min, inf or nan
> > +.*: Error: improper fli value field \(-2\), value must be 0\.\.\.29 or min, inf or nan
> > +.*: Error: improper fli value field \(-2\), value must be 0\.\.\.29 or min, inf or nan
> > +.*: Error: improper fli value field \(-2\), value must be 0\.\.\.29 or min, inf or nan
> > +.*: Error: improper fli value field \(30\), value must be 0\.\.\.29 or min, inf or nan
> > +.*: Error: improper fli value field \(30\), value must be 0\.\.\.29 or min, inf or nan
> > +.*: Error: improper fli value field \(30\), value must be 0\.\.\.29 or min, inf or nan
> > +.*: Error: improper fli value field \(30\), value must be 0\.\.\.29 or min, inf or nan
> > +.*: Error: improper fli value field \(32\), value must be 0\.\.\.29 or min, inf or nan
> > +.*: Error: improper fli value field \(32\), value must be 0\.\.\.29 or min, inf or nan
> > +.*: Error: improper fli value field \(32\), value must be 0\.\.\.29 or min, inf or nan
> > +.*: Error: improper fli value field \(32\), value must be 0\.\.\.29 or min, inf or nan
> > +.*: Error: illegal operands `fli\.h ft1,invalid'
> > +.*: Error: illegal operands `fli\.s ft1,invalid'
> > +.*: Error: illegal operands `fli\.d ft1,invalid'
> > +.*: Error: illegal operands `fli\.q ft1,invalid'
> > diff --git a/gas/testsuite/gas/riscv/zfa-fail-fli.s b/gas/testsuite/gas/riscv/zfa-fail-fli.s
> > new file mode 100644
> > index 00000000000..4c600b5d578
> > --- /dev/null
> > +++ b/gas/testsuite/gas/riscv/zfa-fail-fli.s
> > @@ -0,0 +1,21 @@
> > +target:
> > +       fli.h   ft1, -1
> > +       fli.s   ft1, -1
> > +       fli.d   ft1, -1
> > +       fli.q   ft1, -1
> > +       fli.h   ft1, -2
> > +       fli.s   ft1, -2
> > +       fli.d   ft1, -2
> > +       fli.q   ft1, -2
> > +       fli.h   ft1, 30
> > +       fli.s   ft1, 30
> > +       fli.d   ft1, 30
> > +       fli.q   ft1, 30
> > +       fli.h   ft1, 32
> > +       fli.s   ft1, 32
> > +       fli.d   ft1, 32
> > +       fli.q   ft1, 32
> > +       fli.h   ft1, invalid
> > +       fli.s   ft1, invalid
> > +       fli.d   ft1, invalid
> > +       fli.q   ft1, invalid
> > diff --git a/gas/testsuite/gas/riscv/zfa.d b/gas/testsuite/gas/riscv/zfa.d
> > new file mode 100644
> > index 00000000000..3701a41e485
> > --- /dev/null
> > +++ b/gas/testsuite/gas/riscv/zfa.d
> > @@ -0,0 +1,93 @@
> > +#as: -march=rv64iq_zfa_zfh
> > +#objdump: -dr
> > +
> > +.*:[   ]+file format .*
> > +
> > +Disassembly of section .text:
> > +
> > +0+000 <target>:
>
> Hi Tsukasa,
>
> There seems to be a misunderstanding of the spec.
> The second operand of the fli should be the constant itself ("Value"
> column of the specification) in C-like syntax.
> E.g.:
>   fli.h ft1, -1.0 # encoding rs1=0
>   fli.h ft1, min # encoding rs1=1
>   fli.h ft1, 0.0000152587890625 # encoding rs1=2
>   ...
>   fli.h ft1, 16 # encoding rs1=25
>   ...
>   fli.h ft1, nan # encoding rs1=31
>
> So we have 3 strings ("min", "inf", "nan") and 29 constants.

Note that value #29 is not representable for fli.h (i.e., 65536.0 is
not representable and will also encode +inf).
So "fli.h ft1, 65536.0" should either be rejected or generate a warning.

--Philipp.

>
> BR
> Christoph
>
> > +[      ]+[0-9a-f]+:[   ]+f41000d3[     ]+fli\.h[               ]+ft1,0
> > +[      ]+[0-9a-f]+:[   ]+f41080d3[     ]+fli\.h[               ]+ft1,min
> > +[      ]+[0-9a-f]+:[   ]+f41100d3[     ]+fli\.h[               ]+ft1,2
> > +[      ]+[0-9a-f]+:[   ]+f41d80d3[     ]+fli\.h[               ]+ft1,27
> > +[      ]+[0-9a-f]+:[   ]+f41e00d3[     ]+fli\.h[               ]+ft1,28
> > +[      ]+[0-9a-f]+:[   ]+f41e80d3[     ]+fli\.h[               ]+ft1,29
> > +[      ]+[0-9a-f]+:[   ]+f41080d3[     ]+fli\.h[               ]+ft1,min
> > +[      ]+[0-9a-f]+:[   ]+f41f00d3[     ]+fli\.h[               ]+ft1,inf
> > +[      ]+[0-9a-f]+:[   ]+f41f80d3[     ]+fli\.h[               ]+ft1,nan
> > +[      ]+[0-9a-f]+:[   ]+f01000d3[     ]+fli\.s[               ]+ft1,0
> > +[      ]+[0-9a-f]+:[   ]+f01080d3[     ]+fli\.s[               ]+ft1,min
> > +[      ]+[0-9a-f]+:[   ]+f01100d3[     ]+fli\.s[               ]+ft1,2
> > +[      ]+[0-9a-f]+:[   ]+f01d80d3[     ]+fli\.s[               ]+ft1,27
> > +[      ]+[0-9a-f]+:[   ]+f01e00d3[     ]+fli\.s[               ]+ft1,28
> > +[      ]+[0-9a-f]+:[   ]+f01e80d3[     ]+fli\.s[               ]+ft1,29
> > +[      ]+[0-9a-f]+:[   ]+f01080d3[     ]+fli\.s[               ]+ft1,min
> > +[      ]+[0-9a-f]+:[   ]+f01f00d3[     ]+fli\.s[               ]+ft1,inf
> > +[      ]+[0-9a-f]+:[   ]+f01f80d3[     ]+fli\.s[               ]+ft1,nan
> > +[      ]+[0-9a-f]+:[   ]+f21000d3[     ]+fli\.d[               ]+ft1,0
> > +[      ]+[0-9a-f]+:[   ]+f21080d3[     ]+fli\.d[               ]+ft1,min
> > +[      ]+[0-9a-f]+:[   ]+f21100d3[     ]+fli\.d[               ]+ft1,2
> > +[      ]+[0-9a-f]+:[   ]+f21d80d3[     ]+fli\.d[               ]+ft1,27
> > +[      ]+[0-9a-f]+:[   ]+f21e00d3[     ]+fli\.d[               ]+ft1,28
> > +[      ]+[0-9a-f]+:[   ]+f21e80d3[     ]+fli\.d[               ]+ft1,29
> > +[      ]+[0-9a-f]+:[   ]+f21080d3[     ]+fli\.d[               ]+ft1,min
> > +[      ]+[0-9a-f]+:[   ]+f21f00d3[     ]+fli\.d[               ]+ft1,inf
> > +[      ]+[0-9a-f]+:[   ]+f21f80d3[     ]+fli\.d[               ]+ft1,nan
> > +[      ]+[0-9a-f]+:[   ]+f61000d3[     ]+fli\.q[               ]+ft1,0
> > +[      ]+[0-9a-f]+:[   ]+f61080d3[     ]+fli\.q[               ]+ft1,min
> > +[      ]+[0-9a-f]+:[   ]+f61100d3[     ]+fli\.q[               ]+ft1,2
> > +[      ]+[0-9a-f]+:[   ]+f61d80d3[     ]+fli\.q[               ]+ft1,27
> > +[      ]+[0-9a-f]+:[   ]+f61e00d3[     ]+fli\.q[               ]+ft1,28
> > +[      ]+[0-9a-f]+:[   ]+f61e80d3[     ]+fli\.q[               ]+ft1,29
> > +[      ]+[0-9a-f]+:[   ]+f61080d3[     ]+fli\.q[               ]+ft1,min
> > +[      ]+[0-9a-f]+:[   ]+f61f00d3[     ]+fli\.q[               ]+ft1,inf
> > +[      ]+[0-9a-f]+:[   ]+f61f80d3[     ]+fli\.q[               ]+ft1,nan
> > +[      ]+[0-9a-f]+:[   ]+2c3100d3[     ]+fmin\.h[              ]+ft1,ft2,ft3
> > +[      ]+[0-9a-f]+:[   ]+2c3120d3[     ]+fmini\.h[             ]+ft1,ft2,ft3
> > +[      ]+[0-9a-f]+:[   ]+283100d3[     ]+fmin\.s[              ]+ft1,ft2,ft3
> > +[      ]+[0-9a-f]+:[   ]+283120d3[     ]+fmini\.s[             ]+ft1,ft2,ft3
> > +[      ]+[0-9a-f]+:[   ]+2a3100d3[     ]+fmin\.d[              ]+ft1,ft2,ft3
> > +[      ]+[0-9a-f]+:[   ]+2a3120d3[     ]+fmini\.d[             ]+ft1,ft2,ft3
> > +[      ]+[0-9a-f]+:[   ]+2e3100d3[     ]+fmin\.q[              ]+ft1,ft2,ft3
> > +[      ]+[0-9a-f]+:[   ]+2e3120d3[     ]+fmini\.q[             ]+ft1,ft2,ft3
> > +[      ]+[0-9a-f]+:[   ]+2c3110d3[     ]+fmax\.h[              ]+ft1,ft2,ft3
> > +[      ]+[0-9a-f]+:[   ]+2c3130d3[     ]+fmaxi\.h[             ]+ft1,ft2,ft3
> > +[      ]+[0-9a-f]+:[   ]+283110d3[     ]+fmax\.s[              ]+ft1,ft2,ft3
> > +[      ]+[0-9a-f]+:[   ]+283130d3[     ]+fmaxi\.s[             ]+ft1,ft2,ft3
> > +[      ]+[0-9a-f]+:[   ]+2a3110d3[     ]+fmax\.d[              ]+ft1,ft2,ft3
> > +[      ]+[0-9a-f]+:[   ]+2a3130d3[     ]+fmaxi\.d[             ]+ft1,ft2,ft3
> > +[      ]+[0-9a-f]+:[   ]+2e3110d3[     ]+fmax\.q[              ]+ft1,ft2,ft3
> > +[      ]+[0-9a-f]+:[   ]+2e3130d3[     ]+fmaxi\.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..fb79792bf10
> > --- /dev/null
> > +++ b/gas/testsuite/gas/riscv/zfa.s
> > @@ -0,0 +1,92 @@
> > +target:
> > +       # fli: test both decimal and symbol representations
> > +       #      (0..29, min==1, inf==(30), nan==(31))
> > +       fli.h           ft1, 0
> > +       fli.h           ft1, 1
> > +       fli.h           ft1, 2
> > +       fli.h           ft1, 27
> > +       fli.h           ft1, 28
> > +       fli.h           ft1, 29
> > +       fli.h           ft1, min
> > +       fli.h           ft1, inf
> > +       fli.h           ft1, nan
> > +       fli.s           ft1, 0
> > +       fli.s           ft1, 1
> > +       fli.s           ft1, 2
> > +       fli.s           ft1, 27
> > +       fli.s           ft1, 28
> > +       fli.s           ft1, 29
> > +       fli.s           ft1, min
> > +       fli.s           ft1, inf
> > +       fli.s           ft1, nan
> > +       fli.d           ft1, 0
> > +       fli.d           ft1, 1
> > +       fli.d           ft1, 2
> > +       fli.d           ft1, 27
> > +       fli.d           ft1, 28
> > +       fli.d           ft1, 29
> > +       fli.d           ft1, min
> > +       fli.d           ft1, inf
> > +       fli.d           ft1, nan
> > +       fli.q           ft1, 0
> > +       fli.q           ft1, 1
> > +       fli.q           ft1, 2
> > +       fli.q           ft1, 27
> > +       fli.q           ft1, 28
> > +       fli.q           ft1, 29
> > +       fli.q           ft1, min
> > +       fli.q           ft1, inf
> > +       fli.q           ft1, nan
> > +       # fmini/fmaxi (Zfa): same as fmin/fmax (Zfh/F/D/Q) except bit 13 set
> > +       fmin.h          ft1, ft2, ft3
> > +       fmini.h         ft1, ft2, ft3
> > +       fmin.s          ft1, ft2, ft3
> > +       fmini.s         ft1, ft2, ft3
> > +       fmin.d          ft1, ft2, ft3
> > +       fmini.d         ft1, ft2, ft3
> > +       fmin.q          ft1, ft2, ft3
> > +       fmini.q         ft1, ft2, ft3
> > +       fmax.h          ft1, ft2, ft3
> > +       fmaxi.h         ft1, ft2, ft3
> > +       fmax.s          ft1, ft2, ft3
> > +       fmaxi.s         ft1, ft2, ft3
> > +       fmax.d          ft1, ft2, ft3
> > +       fmaxi.d         ft1, ft2, ft3
> > +       fmax.q          ft1, ft2, ft3
> > +       fmaxi.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 (Zfa): same as flt/fle (Zfh/F/D/Q) except bit 14 set
> > +       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 88b8d7ff595..9739ad24538 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_FMINI_H 0x2c002053
> > +#define MASK_FMINI_H 0xfe00707f
> > +#define MATCH_FMAXI_H 0x2c003053
> > +#define MASK_FMAXI_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_FMINI_S 0x28002053
> > +#define MASK_FMINI_S 0xfe00707f
> > +#define MATCH_FMAXI_S 0x28003053
> > +#define MASK_FMAXI_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_FMINI_D 0x2a002053
> > +#define MASK_FMINI_D 0xfe00707f
> > +#define MATCH_FMAXI_D 0x2a003053
> > +#define MASK_FMAXI_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_FMINI_Q 0x2e002053
> > +#define MASK_FMINI_Q 0xfe00707f
> > +#define MATCH_FMAXI_Q 0x2e003053
> > +#define MASK_FMAXI_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
> > @@ -2718,6 +2784,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(fmini_h, MATCH_FMINI_H, MASK_FMINI_H)
> > +DECLARE_INSN(fmaxi_h, MATCH_FMAXI_H, MASK_FMAXI_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(fmini_s, MATCH_FMINI_S, MASK_FMINI_S)
> > +DECLARE_INSN(fmaxi_s, MATCH_FMAXI_S, MASK_FMAXI_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(fmini_d, MATCH_FMINI_D, MASK_FMINI_D)
> > +DECLARE_INSN(fmaxi_d, MATCH_FMAXI_D, MASK_FMAXI_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(fmini_q, MATCH_FMINI_Q, MASK_FMINI_Q)
> > +DECLARE_INSN(fmaxi_q, MATCH_FMAXI_Q, MASK_FMAXI_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 f1dabeaab8e..3e9feaac2a7 100644
> > --- a/include/opcode/riscv.h
> > +++ b/include/opcode/riscv.h
> > @@ -376,6 +376,10 @@ enum riscv_insn_class
> >    INSN_CLASS_ZFHMIN_OR_ZHINXMIN,
> >    INSN_CLASS_ZFHMIN_AND_D,
> >    INSN_CLASS_ZFHMIN_AND_Q,
> > +  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,
> > @@ -528,6 +532,7 @@ 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_value[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 7ae6e709290..7a8be52281f 100644
> > --- a/opcodes/riscv-dis.c
> > +++ b/opcodes/riscv-dis.c
> > @@ -563,6 +563,13 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
> >           print (info->stream, dis_style_text, "%d", rs1);
> >           break;
> >
> > +       case 'i':
> > +         if (riscv_fli_value[rs1])
> > +           print (info->stream, dis_style_text, "%s", riscv_fli_value[rs1]);
> > +         else
> > +           print (info->stream, dis_style_immediate, "%d", rs1);
> > +         break;
> > +
> >         default:
> >           /* xgettext:c-format */
> >           print (info->stream, dis_style_text,
> > diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
> > index 79be78eb367..eb4da1a7485 100644
> > --- a/opcodes/riscv-opc.c
> > +++ b/opcodes/riscv-opc.c
> > @@ -97,6 +97,15 @@ const char * const riscv_vma[2] =
> >    "mu", "ma"
> >  };
> >
> > +/* The FLI.[HSDQ] value constants.  */
> > +const char * const riscv_fli_value[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 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
> > @@ -636,6 +645,15 @@ const struct riscv_opcode riscv_opcodes[] =
> >  {"fcvt.h.l",  64, INSN_CLASS_ZFH_OR_ZHINX,   "D,s,m",     MATCH_FCVT_H_L, MASK_FCVT_H_L, match_opcode, 0 },
> >  {"fcvt.h.lu", 64, INSN_CLASS_ZFH_OR_ZHINX,   "D,s",       MATCH_FCVT_H_LU|MASK_RM, MASK_FCVT_H_LU|MASK_RM, match_opcode, 0 },
> >  {"fcvt.h.lu", 64, INSN_CLASS_ZFH_OR_ZHINX,   "D,s,m",     MATCH_FCVT_H_LU, MASK_FCVT_H_LU, match_opcode, 0 },
> > +{"fli.h",      0, INSN_CLASS_ZFH_AND_ZFA,    "D,i",       MATCH_FLI_H, MASK_FLI_H, match_opcode, 0 },
> > +{"fmini.h",    0, INSN_CLASS_ZFH_AND_ZFA,    "D,S,T",     MATCH_FMINI_H, MASK_FMINI_H, match_opcode, 0 },
> > +{"fmaxi.h",    0, INSN_CLASS_ZFH_AND_ZFA,    "D,S,T",     MATCH_FMAXI_H, MASK_FMAXI_H, 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 },
> > +{"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 },
> >
> >  /* Single-precision floating-point instruction subset.  */
> >  {"frcsr",      0, INSN_CLASS_F_OR_ZFINX,   "d",         MATCH_FRCSR, MASK_FRCSR, match_opcode, INSN_ALIAS },
> > @@ -714,7 +732,16 @@ const struct riscv_opcode riscv_opcodes[] =
> >  {"fcvt.s.l",  64, INSN_CLASS_F_OR_ZFINX,   "D,s,m",     MATCH_FCVT_S_L, MASK_FCVT_S_L, match_opcode, 0 },
> >  {"fcvt.s.lu", 64, INSN_CLASS_F_OR_ZFINX,   "D,s",       MATCH_FCVT_S_LU|MASK_RM, MASK_FCVT_S_LU|MASK_RM, match_opcode, 0 },
> >  {"fcvt.s.lu", 64, INSN_CLASS_F_OR_ZFINX,   "D,s,m",     MATCH_FCVT_S_LU, MASK_FCVT_S_LU, match_opcode, 0 },
> > -
> > +{"fli.s",      0, INSN_CLASS_ZFA,          "D,i",       MATCH_FLI_S, MASK_FLI_S, match_opcode, 0 },
> > +{"fmini.s",    0, INSN_CLASS_ZFA,          "D,S,T",     MATCH_FMINI_S, MASK_FMINI_S, match_opcode, 0 },
> > +{"fmaxi.s",    0, INSN_CLASS_ZFA,          "D,S,T",     MATCH_FMAXI_S, MASK_FMAXI_S, 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 },
> > +{"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 },
> > +
> >  /* Double-precision floating-point instruction subset.  */
> >  {"fld",        0, INSN_CLASS_D_AND_C, "D,Cn(Cc)",  MATCH_C_FLDSP, MASK_C_FLDSP, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
> >  {"fld",        0, INSN_CLASS_D_AND_C, "CD,Cl(Cs)", MATCH_C_FLD, MASK_C_FLD, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
> > @@ -775,6 +802,18 @@ const struct riscv_opcode riscv_opcodes[] =
> >  {"fcvt.d.l",  64, INSN_CLASS_D_OR_ZDINX,   "D,s,m",     MATCH_FCVT_D_L, MASK_FCVT_D_L, match_opcode, 0 },
> >  {"fcvt.d.lu", 64, INSN_CLASS_D_OR_ZDINX,   "D,s",       MATCH_FCVT_D_LU|MASK_RM, MASK_FCVT_D_LU|MASK_RM, match_opcode, 0 },
> >  {"fcvt.d.lu", 64, INSN_CLASS_D_OR_ZDINX,   "D,s,m",     MATCH_FCVT_D_LU, MASK_FCVT_D_LU, match_opcode, 0 },
> > +{"fli.d",       0, INSN_CLASS_D_AND_ZFA,   "D,i",       MATCH_FLI_D, MASK_FLI_D, match_opcode, 0 },
> > +{"fmini.d",     0, INSN_CLASS_D_AND_ZFA,   "D,S,T",     MATCH_FMINI_D, MASK_FMINI_D, match_opcode, 0 },
> > +{"fmaxi.d",     0, INSN_CLASS_D_AND_ZFA,   "D,S,T",     MATCH_FMAXI_D, MASK_FMAXI_D, 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 },
> > +{"fcvtmod.w.d", 0, INSN_CLASS_D_AND_ZFA,   "d,S,m",     MATCH_FCVTMOD_W_D, MASK_FCVTMOD_W_D, 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 },
> > +{"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},
> >
> >  /* Quad-precision floating-point instruction subset.  */
> >  {"flq",        0, INSN_CLASS_Q,   "D,o(s)",    MATCH_FLQ, MASK_FLQ, match_opcode, INSN_DREF|INSN_16_BYTE },
> > @@ -833,6 +872,17 @@ const struct riscv_opcode riscv_opcodes[] =
> >  {"fcvt.q.l",  64, INSN_CLASS_Q_OR_ZQINX,   "D,s,m",     MATCH_FCVT_Q_L, MASK_FCVT_Q_L, match_opcode, 0 },
> >  {"fcvt.q.lu", 64, INSN_CLASS_Q_OR_ZQINX,   "D,s",       MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU|MASK_RM, match_opcode, 0 },
> >  {"fcvt.q.lu", 64, INSN_CLASS_Q_OR_ZQINX,   "D,s,m",     MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU, match_opcode, 0 },
> > +{"fli.q",       0, INSN_CLASS_Q_AND_ZFA,   "D,i",       MATCH_FLI_Q, MASK_FLI_Q, match_opcode, 0 },
> > +{"fmini.q",     0, INSN_CLASS_Q_AND_ZFA,   "D,S,T",     MATCH_FMINI_Q, MASK_FMINI_Q, match_opcode, 0 },
> > +{"fmaxi.q",     0, INSN_CLASS_Q_AND_ZFA,   "D,S,T",     MATCH_FMAXI_Q, MASK_FMAXI_Q, 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 },
> > +{"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 },
> > +{"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},
> >
> >  /* Compressed instructions.  */
> >  {"c.unimp",    0, INSN_CLASS_C,   "",          0, 0xffffU,  match_opcode, 0 },
> > --
> > 2.34.1
> >

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

* Re: [REVIEW ONLY 1/1] UNRATIFIED RISC-V: Add 'Zfa' extension
  2023-03-22 15:47   ` Christoph Müllner
  2023-03-22 16:01     ` Philipp Tomsich
@ 2023-03-22 16:07     ` Tsukasa OI
  2023-03-22 16:21       ` Christoph Müllner
  2023-03-26 15:43     ` Jeff Law
  2 siblings, 1 reply; 10+ messages in thread
From: Tsukasa OI @ 2023-03-22 16:07 UTC (permalink / raw)
  To: Christoph Müllner; +Cc: binutils, Philipp Tomsich, Andrew Waterman

On 2023/03/23 0:47, Christoph Müllner wrote:
> On Sun, Sep 18, 2022 at 12:13 PM Tsukasa OI via Binutils
> <binutils@sourceware.org> wrote:
>>
>> [DO NOT MERGE]
>> Until 'Zfa' extension is frozen/ratified and final version number is
>> determined, this patch should not merged upstream. This commit uses
>> unratified version 0.1 as in documentation (instead of possible 1.0
>> after ratification).
>>
>> This commit adds the 'Zfa' extension (its instructions and new operand
>> type for FLI instructions).
>>
>> This is based on:
>> <https://github.com/riscv/riscv-isa-manual/commit/ae683aec28ec707a3c4bb6f588491f0840d52f43>
>> (latest commit of the 'zfb' branch as of this writing)
>>
>> Note: the author is calling FLI instructions' RS1 encoded field as
>> "value".  It must be reviewed before the specification is frozen.
>>
>> 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:
>>
>>         * testsuite/gas/riscv/zfa.s: New test.
>>         * testsuite/gas/riscv/zfa.d: Likewise.
>>         * testsuite/gas/riscv/zfa-32.s: New test.
>>         * testsuite/gas/riscv/zfa-32.d: Likewise.
>>         * testsuite/gas/riscv/zfa-64.s: New test.
>>         * testsuite/gas/riscv/zfa-64.d: Likewise.
>>         * testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.s: New failure test for
>>         the "fcvtmod.w.d" instruction.
>>         * testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.d: Likewise.
>>         * testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.l: Likewise.
>>         * testsuite/gas/riscv/zfa-fail-fli.s: New failure test for "fli"
>>         instructions.
>>         * testsuite/gas/riscv/zfa-fail-fli.d: Likewise.
>>         * testsuite/gas/riscv/zfa-fail-fli.l: Likewise.
>>
>> include/ChangeLog:
>>
>>         * opcode/riscv-opc.h (MATCH_FLI_H, MASK_FLI_H, MATCH_FMINI_H,
>>         MASK_FMINI_H, MATCH_FMAXI_H, MASK_FMAXI_H, MATCH_FROUND_H,
>>         MASK_FROUND_H, MATCH_FROUNDNX_H, MASK_FROUNDNX_H, MATCH_FLTQ_H,
>>         MASK_FLTQ_H, MATCH_FLEQ_H, MASK_FLEQ_H, MATCH_FLI_S, MASK_FLI_S,
>>         MATCH_FMINI_S, MASK_FMINI_S, MATCH_FMAXI_S, MASK_FMAXI_S,
>>         MATCH_FROUND_S, MASK_FROUND_S, MATCH_FROUNDNX_S, MASK_FROUNDNX_S,
>>         MATCH_FLTQ_S, MASK_FLTQ_S, MATCH_FLEQ_S, MASK_FLEQ_S, MATCH_FLI_D,
>>         MASK_FLI_D, MATCH_FMINI_D, MASK_FMINI_D, MATCH_FMAXI_D,
>>         MASK_FMAXI_D, MATCH_FROUND_D, MASK_FROUND_D, MATCH_FROUNDNX_D,
>>         MASK_FROUNDNX_D, MATCH_FLTQ_D, MASK_FLTQ_D, MATCH_FLEQ_D,
>>         MASK_FLEQ_D, MATCH_FLI_Q, MASK_FLI_Q, MATCH_FMINI_Q, MASK_FMINI_Q,
>>         MATCH_FMAXI_Q, MASK_FMAXI_Q, MATCH_FROUND_Q, MASK_FROUND_Q,
>>         MATCH_FROUNDNX_Q, MASK_FROUNDNX_Q, MATCH_FLTQ_Q, MASK_FLTQ_Q,
>>         MATCH_FLEQ_Q, MASK_FLEQ_Q, MATCH_FCVTMOD_W_D, MASK_FCVTMOD_W_D,
>>         MATCH_FMVH_X_D, MASK_FMVH_X_D, MATCH_FMVH_X_Q, MASK_FMVH_X_Q,
>>         MATCH_FMVP_D_X, MASK_FMVP_D_X, MATCH_FMVP_Q_X, MASK_FMVP_Q_X): New.
>>         * opcode/riscv.h (enum riscv_insn_class): Add instruction
>>         classes for 'Zfa' extension.
>>
>> opcodes/ChangeLog:
>>
>>         * riscv-opc.c (riscv_opcodes): Add 'Zfa' instructions.
>> ---
>>  bfd/elfxx-riscv.c                             | 39 ++++++++
>>  gas/config/tc-riscv.c                         | 21 ++++
>>  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/riscv/zfa-fail-fcvtmod.w.d.d          |  3 +
>>  .../gas/riscv/zfa-fail-fcvtmod.w.d.l          |  8 ++
>>  .../gas/riscv/zfa-fail-fcvtmod.w.d.s          | 11 +++
>>  gas/testsuite/gas/riscv/zfa-fail-fli.d        |  3 +
>>  gas/testsuite/gas/riscv/zfa-fail-fli.l        | 21 ++++
>>  gas/testsuite/gas/riscv/zfa-fail-fli.s        | 21 ++++
>>  gas/testsuite/gas/riscv/zfa.d                 | 93 +++++++++++++++++
>>  gas/testsuite/gas/riscv/zfa.s                 | 92 +++++++++++++++++
>>  include/opcode/riscv-opc.h                    | 99 +++++++++++++++++++
>>  include/opcode/riscv.h                        |  5 +
>>  opcodes/riscv-dis.c                           |  7 ++
>>  opcodes/riscv-opc.c                           | 52 +++++++++-
>>  18 files changed, 500 insertions(+), 1 deletion(-)
>>  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-fcvtmod.w.d.d
>>  create mode 100644 gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.l
>>  create mode 100644 gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.s
>>  create mode 100644 gas/testsuite/gas/riscv/zfa-fail-fli.d
>>  create mode 100644 gas/testsuite/gas/riscv/zfa-fail-fli.l
>>  create mode 100644 gas/testsuite/gas/riscv/zfa-fail-fli.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 e03b312a381..1c6d1505d54 100644
>> --- a/bfd/elfxx-riscv.c
>> +++ b/bfd/elfxx-riscv.c
>> @@ -1073,6 +1073,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},
>> @@ -1162,6 +1163,7 @@ static struct riscv_supported_ext riscv_supported_std_z_ext[] =
>>    {"zifencei",         ISA_SPEC_CLASS_20190608,        2, 0,  0 },
>>    {"zihintpause",      ISA_SPEC_CLASS_DRAFT,           2, 0,  0 },
>>    {"zmmul",            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 },
>> @@ -2334,6 +2336,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:
>> @@ -2469,6 +2482,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 2f5ee18e451..ffbc7fbdda2 100644
>> --- a/gas/config/tc-riscv.c
>> +++ b/gas/config/tc-riscv.c
>> @@ -1208,6 +1208,7 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
>>         case 'd': USE_BITS (OP_MASK_RD, OP_SH_RD); break;
>>         case 'y': USE_BITS (OP_MASK_BS, OP_SH_BS); break;
>>         case 'Y': USE_BITS (OP_MASK_RNUM, OP_SH_RNUM); break;
>> +       case 'i': /* RS1, FLI.[HSDQ] value field.  */
>>         case 'Z': /* RS1, CSR number.  */
>>         case 'S': /* RS1, floating point.  */
>>         case 's': USE_BITS (OP_MASK_RS1, OP_SH_RS1); break;
>> @@ -3262,6 +3263,26 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
>>               asarg = expr_end;
>>               continue;
>>
>> +           case 'i': /* FLI.[HSDQ] constant immediate.  */
>> +             if (arg_lookup (&asarg, riscv_fli_value,
>> +                             ARRAY_SIZE (riscv_fli_value), &regno))
>> +               INSERT_OPERAND (RS1, *ip, regno);
>> +             else
>> +               {
>> +                 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
>> +                     || imm_expr->X_op != O_constant)
>> +                   break;
>> +                 if (imm_expr->X_add_number < 0
>> +                     || imm_expr->X_add_number > 29)
>> +                   as_bad (_ ("improper fli value field (%ld), "
>> +                              "value must be 0...29 or min, inf or nan"),
>> +                           (long) imm_expr->X_add_number);
>> +                 INSERT_OPERAND (RS1, *ip, imm_expr->X_add_number);
>> +                 imm_expr->X_op = O_absent;
>> +                 asarg = expr_end;
>> +               }
>> +             continue;
>> +
>>             default:
>>             unknown_riscv_ip_operand:
>>               as_fatal (_("internal: unknown argument type `%s'"),
>> diff --git a/gas/testsuite/gas/riscv/zfa-32.d b/gas/testsuite/gas/riscv/zfa-32.d
>> new file mode 100644
>> index 00000000000..0f0cbfcdc70
>> --- /dev/null
>> +++ b/gas/testsuite/gas/riscv/zfa-32.d
>> @@ -0,0 +1,10 @@
>> +#as: -march=rv32id_zfa
>> +#objdump: -dr
>> +
>> +.*:[   ]+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..f942d616959
>> --- /dev/null
>> +++ b/gas/testsuite/gas/riscv/zfa-64.d
>> @@ -0,0 +1,10 @@
>> +#as: -march=rv64iq_zfa
>> +#objdump: -dr
>> +
>> +.*:[   ]+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-fcvtmod.w.d.d b/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.d
>> new file mode 100644
>> index 00000000000..5234c49de75
>> --- /dev/null
>> +++ b/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.d
>> @@ -0,0 +1,3 @@
>> +#as: -march=rv64id_zfa
>> +#objdump: -dr
>> +#error_output: zfa-fail-fcvtmod.w.d.l
>> diff --git a/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.l b/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.l
>> new file mode 100644
>> index 00000000000..4ea048a3356
>> --- /dev/null
>> +++ b/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.l
>> @@ -0,0 +1,8 @@
>> +.*: Assembler messages:
>> +.*: 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-fcvtmod.w.d.s b/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.s
>> new file mode 100644
>> index 00000000000..5984f6676d8
>> --- /dev/null
>> +++ b/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.s
>> @@ -0,0 +1,11 @@
>> +target:
>> +       # fcvtmod.w.d requires explicit rounding mode.
>> +       fcvtmod.w.d     a0, ft1
>> +       # 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
>> +       # Invalid rounding mode is invalid.
>> +       fcvtmod.w.d     a0, ft1, invalid
>> diff --git a/gas/testsuite/gas/riscv/zfa-fail-fli.d b/gas/testsuite/gas/riscv/zfa-fail-fli.d
>> new file mode 100644
>> index 00000000000..3753a4d185e
>> --- /dev/null
>> +++ b/gas/testsuite/gas/riscv/zfa-fail-fli.d
>> @@ -0,0 +1,3 @@
>> +#as: -march=rv64iq_zfa_zfh
>> +#objdump: -dr
>> +#error_output: zfa-fail-fli.l
>> diff --git a/gas/testsuite/gas/riscv/zfa-fail-fli.l b/gas/testsuite/gas/riscv/zfa-fail-fli.l
>> new file mode 100644
>> index 00000000000..b7532f80fd4
>> --- /dev/null
>> +++ b/gas/testsuite/gas/riscv/zfa-fail-fli.l
>> @@ -0,0 +1,21 @@
>> +.*: Assembler messages:
>> +.*: Error: improper fli value field \(-1\), value must be 0\.\.\.29 or min, inf or nan
>> +.*: Error: improper fli value field \(-1\), value must be 0\.\.\.29 or min, inf or nan
>> +.*: Error: improper fli value field \(-1\), value must be 0\.\.\.29 or min, inf or nan
>> +.*: Error: improper fli value field \(-1\), value must be 0\.\.\.29 or min, inf or nan
>> +.*: Error: improper fli value field \(-2\), value must be 0\.\.\.29 or min, inf or nan
>> +.*: Error: improper fli value field \(-2\), value must be 0\.\.\.29 or min, inf or nan
>> +.*: Error: improper fli value field \(-2\), value must be 0\.\.\.29 or min, inf or nan
>> +.*: Error: improper fli value field \(-2\), value must be 0\.\.\.29 or min, inf or nan
>> +.*: Error: improper fli value field \(30\), value must be 0\.\.\.29 or min, inf or nan
>> +.*: Error: improper fli value field \(30\), value must be 0\.\.\.29 or min, inf or nan
>> +.*: Error: improper fli value field \(30\), value must be 0\.\.\.29 or min, inf or nan
>> +.*: Error: improper fli value field \(30\), value must be 0\.\.\.29 or min, inf or nan
>> +.*: Error: improper fli value field \(32\), value must be 0\.\.\.29 or min, inf or nan
>> +.*: Error: improper fli value field \(32\), value must be 0\.\.\.29 or min, inf or nan
>> +.*: Error: improper fli value field \(32\), value must be 0\.\.\.29 or min, inf or nan
>> +.*: Error: improper fli value field \(32\), value must be 0\.\.\.29 or min, inf or nan
>> +.*: Error: illegal operands `fli\.h ft1,invalid'
>> +.*: Error: illegal operands `fli\.s ft1,invalid'
>> +.*: Error: illegal operands `fli\.d ft1,invalid'
>> +.*: Error: illegal operands `fli\.q ft1,invalid'
>> diff --git a/gas/testsuite/gas/riscv/zfa-fail-fli.s b/gas/testsuite/gas/riscv/zfa-fail-fli.s
>> new file mode 100644
>> index 00000000000..4c600b5d578
>> --- /dev/null
>> +++ b/gas/testsuite/gas/riscv/zfa-fail-fli.s
>> @@ -0,0 +1,21 @@
>> +target:
>> +       fli.h   ft1, -1
>> +       fli.s   ft1, -1
>> +       fli.d   ft1, -1
>> +       fli.q   ft1, -1
>> +       fli.h   ft1, -2
>> +       fli.s   ft1, -2
>> +       fli.d   ft1, -2
>> +       fli.q   ft1, -2
>> +       fli.h   ft1, 30
>> +       fli.s   ft1, 30
>> +       fli.d   ft1, 30
>> +       fli.q   ft1, 30
>> +       fli.h   ft1, 32
>> +       fli.s   ft1, 32
>> +       fli.d   ft1, 32
>> +       fli.q   ft1, 32
>> +       fli.h   ft1, invalid
>> +       fli.s   ft1, invalid
>> +       fli.d   ft1, invalid
>> +       fli.q   ft1, invalid
>> diff --git a/gas/testsuite/gas/riscv/zfa.d b/gas/testsuite/gas/riscv/zfa.d
>> new file mode 100644
>> index 00000000000..3701a41e485
>> --- /dev/null
>> +++ b/gas/testsuite/gas/riscv/zfa.d
>> @@ -0,0 +1,93 @@
>> +#as: -march=rv64iq_zfa_zfh
>> +#objdump: -dr
>> +
>> +.*:[   ]+file format .*
>> +
>> +Disassembly of section .text:
>> +
>> +0+000 <target>:
> 
> Hi Tsukasa,
> 
> There seems to be a misunderstanding of the spec.
> The second operand of the fli should be the constant itself ("Value"
> column of the specification) in C-like syntax.
> E.g.:
>   fli.h ft1, -1.0 # encoding rs1=0
>   fli.h ft1, min # encoding rs1=1
>   fli.h ft1, 0.0000152587890625 # encoding rs1=2
>   ...
>   fli.h ft1, 16 # encoding rs1=25
>   ...
>   fli.h ft1, nan # encoding rs1=31
> 
> So we have 3 strings ("min", "inf", "nan") and 29 constants.
> 
> BR
> Christoph

Hi,

I showed very early patchset of 'Zfa' to Andrew and I misunderstood that
he was okay with that operands.  Now the situation is clearer but due to
my poor health conditions, it might not be soon to make a new patchset
(I'm working on it but the progress is very slow).  If my new patchset
for 'Zfa' isn't posted until mid-May, it'll be better that someone else
make their 'Zfa' patchset.

Tsukasa

> 
>> +[      ]+[0-9a-f]+:[   ]+f41000d3[     ]+fli\.h[               ]+ft1,0
>> +[      ]+[0-9a-f]+:[   ]+f41080d3[     ]+fli\.h[               ]+ft1,min
>> +[      ]+[0-9a-f]+:[   ]+f41100d3[     ]+fli\.h[               ]+ft1,2
>> +[      ]+[0-9a-f]+:[   ]+f41d80d3[     ]+fli\.h[               ]+ft1,27
>> +[      ]+[0-9a-f]+:[   ]+f41e00d3[     ]+fli\.h[               ]+ft1,28
>> +[      ]+[0-9a-f]+:[   ]+f41e80d3[     ]+fli\.h[               ]+ft1,29
>> +[      ]+[0-9a-f]+:[   ]+f41080d3[     ]+fli\.h[               ]+ft1,min
>> +[      ]+[0-9a-f]+:[   ]+f41f00d3[     ]+fli\.h[               ]+ft1,inf
>> +[      ]+[0-9a-f]+:[   ]+f41f80d3[     ]+fli\.h[               ]+ft1,nan
>> +[      ]+[0-9a-f]+:[   ]+f01000d3[     ]+fli\.s[               ]+ft1,0
>> +[      ]+[0-9a-f]+:[   ]+f01080d3[     ]+fli\.s[               ]+ft1,min
>> +[      ]+[0-9a-f]+:[   ]+f01100d3[     ]+fli\.s[               ]+ft1,2
>> +[      ]+[0-9a-f]+:[   ]+f01d80d3[     ]+fli\.s[               ]+ft1,27
>> +[      ]+[0-9a-f]+:[   ]+f01e00d3[     ]+fli\.s[               ]+ft1,28
>> +[      ]+[0-9a-f]+:[   ]+f01e80d3[     ]+fli\.s[               ]+ft1,29
>> +[      ]+[0-9a-f]+:[   ]+f01080d3[     ]+fli\.s[               ]+ft1,min
>> +[      ]+[0-9a-f]+:[   ]+f01f00d3[     ]+fli\.s[               ]+ft1,inf
>> +[      ]+[0-9a-f]+:[   ]+f01f80d3[     ]+fli\.s[               ]+ft1,nan
>> +[      ]+[0-9a-f]+:[   ]+f21000d3[     ]+fli\.d[               ]+ft1,0
>> +[      ]+[0-9a-f]+:[   ]+f21080d3[     ]+fli\.d[               ]+ft1,min
>> +[      ]+[0-9a-f]+:[   ]+f21100d3[     ]+fli\.d[               ]+ft1,2
>> +[      ]+[0-9a-f]+:[   ]+f21d80d3[     ]+fli\.d[               ]+ft1,27
>> +[      ]+[0-9a-f]+:[   ]+f21e00d3[     ]+fli\.d[               ]+ft1,28
>> +[      ]+[0-9a-f]+:[   ]+f21e80d3[     ]+fli\.d[               ]+ft1,29
>> +[      ]+[0-9a-f]+:[   ]+f21080d3[     ]+fli\.d[               ]+ft1,min
>> +[      ]+[0-9a-f]+:[   ]+f21f00d3[     ]+fli\.d[               ]+ft1,inf
>> +[      ]+[0-9a-f]+:[   ]+f21f80d3[     ]+fli\.d[               ]+ft1,nan
>> +[      ]+[0-9a-f]+:[   ]+f61000d3[     ]+fli\.q[               ]+ft1,0
>> +[      ]+[0-9a-f]+:[   ]+f61080d3[     ]+fli\.q[               ]+ft1,min
>> +[      ]+[0-9a-f]+:[   ]+f61100d3[     ]+fli\.q[               ]+ft1,2
>> +[      ]+[0-9a-f]+:[   ]+f61d80d3[     ]+fli\.q[               ]+ft1,27
>> +[      ]+[0-9a-f]+:[   ]+f61e00d3[     ]+fli\.q[               ]+ft1,28
>> +[      ]+[0-9a-f]+:[   ]+f61e80d3[     ]+fli\.q[               ]+ft1,29
>> +[      ]+[0-9a-f]+:[   ]+f61080d3[     ]+fli\.q[               ]+ft1,min
>> +[      ]+[0-9a-f]+:[   ]+f61f00d3[     ]+fli\.q[               ]+ft1,inf
>> +[      ]+[0-9a-f]+:[   ]+f61f80d3[     ]+fli\.q[               ]+ft1,nan
>> +[      ]+[0-9a-f]+:[   ]+2c3100d3[     ]+fmin\.h[              ]+ft1,ft2,ft3
>> +[      ]+[0-9a-f]+:[   ]+2c3120d3[     ]+fmini\.h[             ]+ft1,ft2,ft3
>> +[      ]+[0-9a-f]+:[   ]+283100d3[     ]+fmin\.s[              ]+ft1,ft2,ft3
>> +[      ]+[0-9a-f]+:[   ]+283120d3[     ]+fmini\.s[             ]+ft1,ft2,ft3
>> +[      ]+[0-9a-f]+:[   ]+2a3100d3[     ]+fmin\.d[              ]+ft1,ft2,ft3
>> +[      ]+[0-9a-f]+:[   ]+2a3120d3[     ]+fmini\.d[             ]+ft1,ft2,ft3
>> +[      ]+[0-9a-f]+:[   ]+2e3100d3[     ]+fmin\.q[              ]+ft1,ft2,ft3
>> +[      ]+[0-9a-f]+:[   ]+2e3120d3[     ]+fmini\.q[             ]+ft1,ft2,ft3
>> +[      ]+[0-9a-f]+:[   ]+2c3110d3[     ]+fmax\.h[              ]+ft1,ft2,ft3
>> +[      ]+[0-9a-f]+:[   ]+2c3130d3[     ]+fmaxi\.h[             ]+ft1,ft2,ft3
>> +[      ]+[0-9a-f]+:[   ]+283110d3[     ]+fmax\.s[              ]+ft1,ft2,ft3
>> +[      ]+[0-9a-f]+:[   ]+283130d3[     ]+fmaxi\.s[             ]+ft1,ft2,ft3
>> +[      ]+[0-9a-f]+:[   ]+2a3110d3[     ]+fmax\.d[              ]+ft1,ft2,ft3
>> +[      ]+[0-9a-f]+:[   ]+2a3130d3[     ]+fmaxi\.d[             ]+ft1,ft2,ft3
>> +[      ]+[0-9a-f]+:[   ]+2e3110d3[     ]+fmax\.q[              ]+ft1,ft2,ft3
>> +[      ]+[0-9a-f]+:[   ]+2e3130d3[     ]+fmaxi\.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..fb79792bf10
>> --- /dev/null
>> +++ b/gas/testsuite/gas/riscv/zfa.s
>> @@ -0,0 +1,92 @@
>> +target:
>> +       # fli: test both decimal and symbol representations
>> +       #      (0..29, min==1, inf==(30), nan==(31))
>> +       fli.h           ft1, 0
>> +       fli.h           ft1, 1
>> +       fli.h           ft1, 2
>> +       fli.h           ft1, 27
>> +       fli.h           ft1, 28
>> +       fli.h           ft1, 29
>> +       fli.h           ft1, min
>> +       fli.h           ft1, inf
>> +       fli.h           ft1, nan
>> +       fli.s           ft1, 0
>> +       fli.s           ft1, 1
>> +       fli.s           ft1, 2
>> +       fli.s           ft1, 27
>> +       fli.s           ft1, 28
>> +       fli.s           ft1, 29
>> +       fli.s           ft1, min
>> +       fli.s           ft1, inf
>> +       fli.s           ft1, nan
>> +       fli.d           ft1, 0
>> +       fli.d           ft1, 1
>> +       fli.d           ft1, 2
>> +       fli.d           ft1, 27
>> +       fli.d           ft1, 28
>> +       fli.d           ft1, 29
>> +       fli.d           ft1, min
>> +       fli.d           ft1, inf
>> +       fli.d           ft1, nan
>> +       fli.q           ft1, 0
>> +       fli.q           ft1, 1
>> +       fli.q           ft1, 2
>> +       fli.q           ft1, 27
>> +       fli.q           ft1, 28
>> +       fli.q           ft1, 29
>> +       fli.q           ft1, min
>> +       fli.q           ft1, inf
>> +       fli.q           ft1, nan
>> +       # fmini/fmaxi (Zfa): same as fmin/fmax (Zfh/F/D/Q) except bit 13 set
>> +       fmin.h          ft1, ft2, ft3
>> +       fmini.h         ft1, ft2, ft3
>> +       fmin.s          ft1, ft2, ft3
>> +       fmini.s         ft1, ft2, ft3
>> +       fmin.d          ft1, ft2, ft3
>> +       fmini.d         ft1, ft2, ft3
>> +       fmin.q          ft1, ft2, ft3
>> +       fmini.q         ft1, ft2, ft3
>> +       fmax.h          ft1, ft2, ft3
>> +       fmaxi.h         ft1, ft2, ft3
>> +       fmax.s          ft1, ft2, ft3
>> +       fmaxi.s         ft1, ft2, ft3
>> +       fmax.d          ft1, ft2, ft3
>> +       fmaxi.d         ft1, ft2, ft3
>> +       fmax.q          ft1, ft2, ft3
>> +       fmaxi.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 (Zfa): same as flt/fle (Zfh/F/D/Q) except bit 14 set
>> +       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 88b8d7ff595..9739ad24538 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_FMINI_H 0x2c002053
>> +#define MASK_FMINI_H 0xfe00707f
>> +#define MATCH_FMAXI_H 0x2c003053
>> +#define MASK_FMAXI_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_FMINI_S 0x28002053
>> +#define MASK_FMINI_S 0xfe00707f
>> +#define MATCH_FMAXI_S 0x28003053
>> +#define MASK_FMAXI_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_FMINI_D 0x2a002053
>> +#define MASK_FMINI_D 0xfe00707f
>> +#define MATCH_FMAXI_D 0x2a003053
>> +#define MASK_FMAXI_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_FMINI_Q 0x2e002053
>> +#define MASK_FMINI_Q 0xfe00707f
>> +#define MATCH_FMAXI_Q 0x2e003053
>> +#define MASK_FMAXI_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
>> @@ -2718,6 +2784,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(fmini_h, MATCH_FMINI_H, MASK_FMINI_H)
>> +DECLARE_INSN(fmaxi_h, MATCH_FMAXI_H, MASK_FMAXI_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(fmini_s, MATCH_FMINI_S, MASK_FMINI_S)
>> +DECLARE_INSN(fmaxi_s, MATCH_FMAXI_S, MASK_FMAXI_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(fmini_d, MATCH_FMINI_D, MASK_FMINI_D)
>> +DECLARE_INSN(fmaxi_d, MATCH_FMAXI_D, MASK_FMAXI_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(fmini_q, MATCH_FMINI_Q, MASK_FMINI_Q)
>> +DECLARE_INSN(fmaxi_q, MATCH_FMAXI_Q, MASK_FMAXI_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 f1dabeaab8e..3e9feaac2a7 100644
>> --- a/include/opcode/riscv.h
>> +++ b/include/opcode/riscv.h
>> @@ -376,6 +376,10 @@ enum riscv_insn_class
>>    INSN_CLASS_ZFHMIN_OR_ZHINXMIN,
>>    INSN_CLASS_ZFHMIN_AND_D,
>>    INSN_CLASS_ZFHMIN_AND_Q,
>> +  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,
>> @@ -528,6 +532,7 @@ 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_value[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 7ae6e709290..7a8be52281f 100644
>> --- a/opcodes/riscv-dis.c
>> +++ b/opcodes/riscv-dis.c
>> @@ -563,6 +563,13 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
>>           print (info->stream, dis_style_text, "%d", rs1);
>>           break;
>>
>> +       case 'i':
>> +         if (riscv_fli_value[rs1])
>> +           print (info->stream, dis_style_text, "%s", riscv_fli_value[rs1]);
>> +         else
>> +           print (info->stream, dis_style_immediate, "%d", rs1);
>> +         break;
>> +
>>         default:
>>           /* xgettext:c-format */
>>           print (info->stream, dis_style_text,
>> diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
>> index 79be78eb367..eb4da1a7485 100644
>> --- a/opcodes/riscv-opc.c
>> +++ b/opcodes/riscv-opc.c
>> @@ -97,6 +97,15 @@ const char * const riscv_vma[2] =
>>    "mu", "ma"
>>  };
>>
>> +/* The FLI.[HSDQ] value constants.  */
>> +const char * const riscv_fli_value[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 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
>> @@ -636,6 +645,15 @@ const struct riscv_opcode riscv_opcodes[] =
>>  {"fcvt.h.l",  64, INSN_CLASS_ZFH_OR_ZHINX,   "D,s,m",     MATCH_FCVT_H_L, MASK_FCVT_H_L, match_opcode, 0 },
>>  {"fcvt.h.lu", 64, INSN_CLASS_ZFH_OR_ZHINX,   "D,s",       MATCH_FCVT_H_LU|MASK_RM, MASK_FCVT_H_LU|MASK_RM, match_opcode, 0 },
>>  {"fcvt.h.lu", 64, INSN_CLASS_ZFH_OR_ZHINX,   "D,s,m",     MATCH_FCVT_H_LU, MASK_FCVT_H_LU, match_opcode, 0 },
>> +{"fli.h",      0, INSN_CLASS_ZFH_AND_ZFA,    "D,i",       MATCH_FLI_H, MASK_FLI_H, match_opcode, 0 },
>> +{"fmini.h",    0, INSN_CLASS_ZFH_AND_ZFA,    "D,S,T",     MATCH_FMINI_H, MASK_FMINI_H, match_opcode, 0 },
>> +{"fmaxi.h",    0, INSN_CLASS_ZFH_AND_ZFA,    "D,S,T",     MATCH_FMAXI_H, MASK_FMAXI_H, 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 },
>> +{"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 },
>>
>>  /* Single-precision floating-point instruction subset.  */
>>  {"frcsr",      0, INSN_CLASS_F_OR_ZFINX,   "d",         MATCH_FRCSR, MASK_FRCSR, match_opcode, INSN_ALIAS },
>> @@ -714,7 +732,16 @@ const struct riscv_opcode riscv_opcodes[] =
>>  {"fcvt.s.l",  64, INSN_CLASS_F_OR_ZFINX,   "D,s,m",     MATCH_FCVT_S_L, MASK_FCVT_S_L, match_opcode, 0 },
>>  {"fcvt.s.lu", 64, INSN_CLASS_F_OR_ZFINX,   "D,s",       MATCH_FCVT_S_LU|MASK_RM, MASK_FCVT_S_LU|MASK_RM, match_opcode, 0 },
>>  {"fcvt.s.lu", 64, INSN_CLASS_F_OR_ZFINX,   "D,s,m",     MATCH_FCVT_S_LU, MASK_FCVT_S_LU, match_opcode, 0 },
>> -
>> +{"fli.s",      0, INSN_CLASS_ZFA,          "D,i",       MATCH_FLI_S, MASK_FLI_S, match_opcode, 0 },
>> +{"fmini.s",    0, INSN_CLASS_ZFA,          "D,S,T",     MATCH_FMINI_S, MASK_FMINI_S, match_opcode, 0 },
>> +{"fmaxi.s",    0, INSN_CLASS_ZFA,          "D,S,T",     MATCH_FMAXI_S, MASK_FMAXI_S, 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 },
>> +{"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 },
>> +
>>  /* Double-precision floating-point instruction subset.  */
>>  {"fld",        0, INSN_CLASS_D_AND_C, "D,Cn(Cc)",  MATCH_C_FLDSP, MASK_C_FLDSP, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
>>  {"fld",        0, INSN_CLASS_D_AND_C, "CD,Cl(Cs)", MATCH_C_FLD, MASK_C_FLD, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
>> @@ -775,6 +802,18 @@ const struct riscv_opcode riscv_opcodes[] =
>>  {"fcvt.d.l",  64, INSN_CLASS_D_OR_ZDINX,   "D,s,m",     MATCH_FCVT_D_L, MASK_FCVT_D_L, match_opcode, 0 },
>>  {"fcvt.d.lu", 64, INSN_CLASS_D_OR_ZDINX,   "D,s",       MATCH_FCVT_D_LU|MASK_RM, MASK_FCVT_D_LU|MASK_RM, match_opcode, 0 },
>>  {"fcvt.d.lu", 64, INSN_CLASS_D_OR_ZDINX,   "D,s,m",     MATCH_FCVT_D_LU, MASK_FCVT_D_LU, match_opcode, 0 },
>> +{"fli.d",       0, INSN_CLASS_D_AND_ZFA,   "D,i",       MATCH_FLI_D, MASK_FLI_D, match_opcode, 0 },
>> +{"fmini.d",     0, INSN_CLASS_D_AND_ZFA,   "D,S,T",     MATCH_FMINI_D, MASK_FMINI_D, match_opcode, 0 },
>> +{"fmaxi.d",     0, INSN_CLASS_D_AND_ZFA,   "D,S,T",     MATCH_FMAXI_D, MASK_FMAXI_D, 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 },
>> +{"fcvtmod.w.d", 0, INSN_CLASS_D_AND_ZFA,   "d,S,m",     MATCH_FCVTMOD_W_D, MASK_FCVTMOD_W_D, 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 },
>> +{"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},
>>
>>  /* Quad-precision floating-point instruction subset.  */
>>  {"flq",        0, INSN_CLASS_Q,   "D,o(s)",    MATCH_FLQ, MASK_FLQ, match_opcode, INSN_DREF|INSN_16_BYTE },
>> @@ -833,6 +872,17 @@ const struct riscv_opcode riscv_opcodes[] =
>>  {"fcvt.q.l",  64, INSN_CLASS_Q_OR_ZQINX,   "D,s,m",     MATCH_FCVT_Q_L, MASK_FCVT_Q_L, match_opcode, 0 },
>>  {"fcvt.q.lu", 64, INSN_CLASS_Q_OR_ZQINX,   "D,s",       MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU|MASK_RM, match_opcode, 0 },
>>  {"fcvt.q.lu", 64, INSN_CLASS_Q_OR_ZQINX,   "D,s,m",     MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU, match_opcode, 0 },
>> +{"fli.q",       0, INSN_CLASS_Q_AND_ZFA,   "D,i",       MATCH_FLI_Q, MASK_FLI_Q, match_opcode, 0 },
>> +{"fmini.q",     0, INSN_CLASS_Q_AND_ZFA,   "D,S,T",     MATCH_FMINI_Q, MASK_FMINI_Q, match_opcode, 0 },
>> +{"fmaxi.q",     0, INSN_CLASS_Q_AND_ZFA,   "D,S,T",     MATCH_FMAXI_Q, MASK_FMAXI_Q, 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 },
>> +{"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 },
>> +{"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},
>>
>>  /* Compressed instructions.  */
>>  {"c.unimp",    0, INSN_CLASS_C,   "",          0, 0xffffU,  match_opcode, 0 },
>> --
>> 2.34.1
>>
> 

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

* Re: [REVIEW ONLY 1/1] UNRATIFIED RISC-V: Add 'Zfa' extension
  2023-03-22 16:07     ` Tsukasa OI
@ 2023-03-22 16:21       ` Christoph Müllner
  2023-03-22 17:00         ` Tsukasa OI
  0 siblings, 1 reply; 10+ messages in thread
From: Christoph Müllner @ 2023-03-22 16:21 UTC (permalink / raw)
  To: Tsukasa OI; +Cc: binutils, Philipp Tomsich, Andrew Waterman

On Wed, Mar 22, 2023 at 5:07 PM Tsukasa OI <research_trasio@irq.a4lg.com> wrote:
>
> On 2023/03/23 0:47, Christoph Müllner wrote:
> > On Sun, Sep 18, 2022 at 12:13 PM Tsukasa OI via Binutils
> > <binutils@sourceware.org> wrote:
> >>
> >> [DO NOT MERGE]
> >> Until 'Zfa' extension is frozen/ratified and final version number is
> >> determined, this patch should not merged upstream. This commit uses
> >> unratified version 0.1 as in documentation (instead of possible 1.0
> >> after ratification).
> >>
> >> This commit adds the 'Zfa' extension (its instructions and new operand
> >> type for FLI instructions).
> >>
> >> This is based on:
> >> <https://github.com/riscv/riscv-isa-manual/commit/ae683aec28ec707a3c4bb6f588491f0840d52f43>
> >> (latest commit of the 'zfb' branch as of this writing)
> >>
> >> Note: the author is calling FLI instructions' RS1 encoded field as
> >> "value".  It must be reviewed before the specification is frozen.
> >>
> >> 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:
> >>
> >>         * testsuite/gas/riscv/zfa.s: New test.
> >>         * testsuite/gas/riscv/zfa.d: Likewise.
> >>         * testsuite/gas/riscv/zfa-32.s: New test.
> >>         * testsuite/gas/riscv/zfa-32.d: Likewise.
> >>         * testsuite/gas/riscv/zfa-64.s: New test.
> >>         * testsuite/gas/riscv/zfa-64.d: Likewise.
> >>         * testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.s: New failure test for
> >>         the "fcvtmod.w.d" instruction.
> >>         * testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.d: Likewise.
> >>         * testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.l: Likewise.
> >>         * testsuite/gas/riscv/zfa-fail-fli.s: New failure test for "fli"
> >>         instructions.
> >>         * testsuite/gas/riscv/zfa-fail-fli.d: Likewise.
> >>         * testsuite/gas/riscv/zfa-fail-fli.l: Likewise.
> >>
> >> include/ChangeLog:
> >>
> >>         * opcode/riscv-opc.h (MATCH_FLI_H, MASK_FLI_H, MATCH_FMINI_H,
> >>         MASK_FMINI_H, MATCH_FMAXI_H, MASK_FMAXI_H, MATCH_FROUND_H,
> >>         MASK_FROUND_H, MATCH_FROUNDNX_H, MASK_FROUNDNX_H, MATCH_FLTQ_H,
> >>         MASK_FLTQ_H, MATCH_FLEQ_H, MASK_FLEQ_H, MATCH_FLI_S, MASK_FLI_S,
> >>         MATCH_FMINI_S, MASK_FMINI_S, MATCH_FMAXI_S, MASK_FMAXI_S,
> >>         MATCH_FROUND_S, MASK_FROUND_S, MATCH_FROUNDNX_S, MASK_FROUNDNX_S,
> >>         MATCH_FLTQ_S, MASK_FLTQ_S, MATCH_FLEQ_S, MASK_FLEQ_S, MATCH_FLI_D,
> >>         MASK_FLI_D, MATCH_FMINI_D, MASK_FMINI_D, MATCH_FMAXI_D,
> >>         MASK_FMAXI_D, MATCH_FROUND_D, MASK_FROUND_D, MATCH_FROUNDNX_D,
> >>         MASK_FROUNDNX_D, MATCH_FLTQ_D, MASK_FLTQ_D, MATCH_FLEQ_D,
> >>         MASK_FLEQ_D, MATCH_FLI_Q, MASK_FLI_Q, MATCH_FMINI_Q, MASK_FMINI_Q,
> >>         MATCH_FMAXI_Q, MASK_FMAXI_Q, MATCH_FROUND_Q, MASK_FROUND_Q,
> >>         MATCH_FROUNDNX_Q, MASK_FROUNDNX_Q, MATCH_FLTQ_Q, MASK_FLTQ_Q,
> >>         MATCH_FLEQ_Q, MASK_FLEQ_Q, MATCH_FCVTMOD_W_D, MASK_FCVTMOD_W_D,
> >>         MATCH_FMVH_X_D, MASK_FMVH_X_D, MATCH_FMVH_X_Q, MASK_FMVH_X_Q,
> >>         MATCH_FMVP_D_X, MASK_FMVP_D_X, MATCH_FMVP_Q_X, MASK_FMVP_Q_X): New.
> >>         * opcode/riscv.h (enum riscv_insn_class): Add instruction
> >>         classes for 'Zfa' extension.
> >>
> >> opcodes/ChangeLog:
> >>
> >>         * riscv-opc.c (riscv_opcodes): Add 'Zfa' instructions.
> >> ---
> >>  bfd/elfxx-riscv.c                             | 39 ++++++++
> >>  gas/config/tc-riscv.c                         | 21 ++++
> >>  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/riscv/zfa-fail-fcvtmod.w.d.d          |  3 +
> >>  .../gas/riscv/zfa-fail-fcvtmod.w.d.l          |  8 ++
> >>  .../gas/riscv/zfa-fail-fcvtmod.w.d.s          | 11 +++
> >>  gas/testsuite/gas/riscv/zfa-fail-fli.d        |  3 +
> >>  gas/testsuite/gas/riscv/zfa-fail-fli.l        | 21 ++++
> >>  gas/testsuite/gas/riscv/zfa-fail-fli.s        | 21 ++++
> >>  gas/testsuite/gas/riscv/zfa.d                 | 93 +++++++++++++++++
> >>  gas/testsuite/gas/riscv/zfa.s                 | 92 +++++++++++++++++
> >>  include/opcode/riscv-opc.h                    | 99 +++++++++++++++++++
> >>  include/opcode/riscv.h                        |  5 +
> >>  opcodes/riscv-dis.c                           |  7 ++
> >>  opcodes/riscv-opc.c                           | 52 +++++++++-
> >>  18 files changed, 500 insertions(+), 1 deletion(-)
> >>  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-fcvtmod.w.d.d
> >>  create mode 100644 gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.l
> >>  create mode 100644 gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.s
> >>  create mode 100644 gas/testsuite/gas/riscv/zfa-fail-fli.d
> >>  create mode 100644 gas/testsuite/gas/riscv/zfa-fail-fli.l
> >>  create mode 100644 gas/testsuite/gas/riscv/zfa-fail-fli.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 e03b312a381..1c6d1505d54 100644
> >> --- a/bfd/elfxx-riscv.c
> >> +++ b/bfd/elfxx-riscv.c
> >> @@ -1073,6 +1073,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},
> >> @@ -1162,6 +1163,7 @@ static struct riscv_supported_ext riscv_supported_std_z_ext[] =
> >>    {"zifencei",         ISA_SPEC_CLASS_20190608,        2, 0,  0 },
> >>    {"zihintpause",      ISA_SPEC_CLASS_DRAFT,           2, 0,  0 },
> >>    {"zmmul",            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 },
> >> @@ -2334,6 +2336,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:
> >> @@ -2469,6 +2482,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 2f5ee18e451..ffbc7fbdda2 100644
> >> --- a/gas/config/tc-riscv.c
> >> +++ b/gas/config/tc-riscv.c
> >> @@ -1208,6 +1208,7 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
> >>         case 'd': USE_BITS (OP_MASK_RD, OP_SH_RD); break;
> >>         case 'y': USE_BITS (OP_MASK_BS, OP_SH_BS); break;
> >>         case 'Y': USE_BITS (OP_MASK_RNUM, OP_SH_RNUM); break;
> >> +       case 'i': /* RS1, FLI.[HSDQ] value field.  */
> >>         case 'Z': /* RS1, CSR number.  */
> >>         case 'S': /* RS1, floating point.  */
> >>         case 's': USE_BITS (OP_MASK_RS1, OP_SH_RS1); break;
> >> @@ -3262,6 +3263,26 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
> >>               asarg = expr_end;
> >>               continue;
> >>
> >> +           case 'i': /* FLI.[HSDQ] constant immediate.  */
> >> +             if (arg_lookup (&asarg, riscv_fli_value,
> >> +                             ARRAY_SIZE (riscv_fli_value), &regno))
> >> +               INSERT_OPERAND (RS1, *ip, regno);
> >> +             else
> >> +               {
> >> +                 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
> >> +                     || imm_expr->X_op != O_constant)
> >> +                   break;
> >> +                 if (imm_expr->X_add_number < 0
> >> +                     || imm_expr->X_add_number > 29)
> >> +                   as_bad (_ ("improper fli value field (%ld), "
> >> +                              "value must be 0...29 or min, inf or nan"),
> >> +                           (long) imm_expr->X_add_number);
> >> +                 INSERT_OPERAND (RS1, *ip, imm_expr->X_add_number);
> >> +                 imm_expr->X_op = O_absent;
> >> +                 asarg = expr_end;
> >> +               }
> >> +             continue;
> >> +
> >>             default:
> >>             unknown_riscv_ip_operand:
> >>               as_fatal (_("internal: unknown argument type `%s'"),
> >> diff --git a/gas/testsuite/gas/riscv/zfa-32.d b/gas/testsuite/gas/riscv/zfa-32.d
> >> new file mode 100644
> >> index 00000000000..0f0cbfcdc70
> >> --- /dev/null
> >> +++ b/gas/testsuite/gas/riscv/zfa-32.d
> >> @@ -0,0 +1,10 @@
> >> +#as: -march=rv32id_zfa
> >> +#objdump: -dr
> >> +
> >> +.*:[   ]+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..f942d616959
> >> --- /dev/null
> >> +++ b/gas/testsuite/gas/riscv/zfa-64.d
> >> @@ -0,0 +1,10 @@
> >> +#as: -march=rv64iq_zfa
> >> +#objdump: -dr
> >> +
> >> +.*:[   ]+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-fcvtmod.w.d.d b/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.d
> >> new file mode 100644
> >> index 00000000000..5234c49de75
> >> --- /dev/null
> >> +++ b/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.d
> >> @@ -0,0 +1,3 @@
> >> +#as: -march=rv64id_zfa
> >> +#objdump: -dr
> >> +#error_output: zfa-fail-fcvtmod.w.d.l
> >> diff --git a/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.l b/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.l
> >> new file mode 100644
> >> index 00000000000..4ea048a3356
> >> --- /dev/null
> >> +++ b/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.l
> >> @@ -0,0 +1,8 @@
> >> +.*: Assembler messages:
> >> +.*: 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-fcvtmod.w.d.s b/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.s
> >> new file mode 100644
> >> index 00000000000..5984f6676d8
> >> --- /dev/null
> >> +++ b/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.s
> >> @@ -0,0 +1,11 @@
> >> +target:
> >> +       # fcvtmod.w.d requires explicit rounding mode.
> >> +       fcvtmod.w.d     a0, ft1
> >> +       # 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
> >> +       # Invalid rounding mode is invalid.
> >> +       fcvtmod.w.d     a0, ft1, invalid
> >> diff --git a/gas/testsuite/gas/riscv/zfa-fail-fli.d b/gas/testsuite/gas/riscv/zfa-fail-fli.d
> >> new file mode 100644
> >> index 00000000000..3753a4d185e
> >> --- /dev/null
> >> +++ b/gas/testsuite/gas/riscv/zfa-fail-fli.d
> >> @@ -0,0 +1,3 @@
> >> +#as: -march=rv64iq_zfa_zfh
> >> +#objdump: -dr
> >> +#error_output: zfa-fail-fli.l
> >> diff --git a/gas/testsuite/gas/riscv/zfa-fail-fli.l b/gas/testsuite/gas/riscv/zfa-fail-fli.l
> >> new file mode 100644
> >> index 00000000000..b7532f80fd4
> >> --- /dev/null
> >> +++ b/gas/testsuite/gas/riscv/zfa-fail-fli.l
> >> @@ -0,0 +1,21 @@
> >> +.*: Assembler messages:
> >> +.*: Error: improper fli value field \(-1\), value must be 0\.\.\.29 or min, inf or nan
> >> +.*: Error: improper fli value field \(-1\), value must be 0\.\.\.29 or min, inf or nan
> >> +.*: Error: improper fli value field \(-1\), value must be 0\.\.\.29 or min, inf or nan
> >> +.*: Error: improper fli value field \(-1\), value must be 0\.\.\.29 or min, inf or nan
> >> +.*: Error: improper fli value field \(-2\), value must be 0\.\.\.29 or min, inf or nan
> >> +.*: Error: improper fli value field \(-2\), value must be 0\.\.\.29 or min, inf or nan
> >> +.*: Error: improper fli value field \(-2\), value must be 0\.\.\.29 or min, inf or nan
> >> +.*: Error: improper fli value field \(-2\), value must be 0\.\.\.29 or min, inf or nan
> >> +.*: Error: improper fli value field \(30\), value must be 0\.\.\.29 or min, inf or nan
> >> +.*: Error: improper fli value field \(30\), value must be 0\.\.\.29 or min, inf or nan
> >> +.*: Error: improper fli value field \(30\), value must be 0\.\.\.29 or min, inf or nan
> >> +.*: Error: improper fli value field \(30\), value must be 0\.\.\.29 or min, inf or nan
> >> +.*: Error: improper fli value field \(32\), value must be 0\.\.\.29 or min, inf or nan
> >> +.*: Error: improper fli value field \(32\), value must be 0\.\.\.29 or min, inf or nan
> >> +.*: Error: improper fli value field \(32\), value must be 0\.\.\.29 or min, inf or nan
> >> +.*: Error: improper fli value field \(32\), value must be 0\.\.\.29 or min, inf or nan
> >> +.*: Error: illegal operands `fli\.h ft1,invalid'
> >> +.*: Error: illegal operands `fli\.s ft1,invalid'
> >> +.*: Error: illegal operands `fli\.d ft1,invalid'
> >> +.*: Error: illegal operands `fli\.q ft1,invalid'
> >> diff --git a/gas/testsuite/gas/riscv/zfa-fail-fli.s b/gas/testsuite/gas/riscv/zfa-fail-fli.s
> >> new file mode 100644
> >> index 00000000000..4c600b5d578
> >> --- /dev/null
> >> +++ b/gas/testsuite/gas/riscv/zfa-fail-fli.s
> >> @@ -0,0 +1,21 @@
> >> +target:
> >> +       fli.h   ft1, -1
> >> +       fli.s   ft1, -1
> >> +       fli.d   ft1, -1
> >> +       fli.q   ft1, -1
> >> +       fli.h   ft1, -2
> >> +       fli.s   ft1, -2
> >> +       fli.d   ft1, -2
> >> +       fli.q   ft1, -2
> >> +       fli.h   ft1, 30
> >> +       fli.s   ft1, 30
> >> +       fli.d   ft1, 30
> >> +       fli.q   ft1, 30
> >> +       fli.h   ft1, 32
> >> +       fli.s   ft1, 32
> >> +       fli.d   ft1, 32
> >> +       fli.q   ft1, 32
> >> +       fli.h   ft1, invalid
> >> +       fli.s   ft1, invalid
> >> +       fli.d   ft1, invalid
> >> +       fli.q   ft1, invalid
> >> diff --git a/gas/testsuite/gas/riscv/zfa.d b/gas/testsuite/gas/riscv/zfa.d
> >> new file mode 100644
> >> index 00000000000..3701a41e485
> >> --- /dev/null
> >> +++ b/gas/testsuite/gas/riscv/zfa.d
> >> @@ -0,0 +1,93 @@
> >> +#as: -march=rv64iq_zfa_zfh
> >> +#objdump: -dr
> >> +
> >> +.*:[   ]+file format .*
> >> +
> >> +Disassembly of section .text:
> >> +
> >> +0+000 <target>:
> >
> > Hi Tsukasa,
> >
> > There seems to be a misunderstanding of the spec.
> > The second operand of the fli should be the constant itself ("Value"
> > column of the specification) in C-like syntax.
> > E.g.:
> >   fli.h ft1, -1.0 # encoding rs1=0
> >   fli.h ft1, min # encoding rs1=1
> >   fli.h ft1, 0.0000152587890625 # encoding rs1=2
> >   ...
> >   fli.h ft1, 16 # encoding rs1=25
> >   ...
> >   fli.h ft1, nan # encoding rs1=31
> >
> > So we have 3 strings ("min", "inf", "nan") and 29 constants.
> >
> > BR
> > Christoph
>
> Hi,
>
> I showed very early patchset of 'Zfa' to Andrew and I misunderstood that
> he was okay with that operands.  Now the situation is clearer but due to
> my poor health conditions, it might not be soon to make a new patchset
> (I'm working on it but the progress is very slow).  If my new patchset
> for 'Zfa' isn't posted until mid-May, it'll be better that someone else
> make their 'Zfa' patchset.

We are working on a couple of other Zfa enablement patches and we need
a solution earlier than mid-May (we target the end of this month).
Is it ok for you if I take over the patch and add you as Co-developed-by?
I would also use your "RISC-V: Allocate "various" operand type" commit as base.

Get well soon!

BR
Christoph

>
> Tsukasa
>
> >
> >> +[      ]+[0-9a-f]+:[   ]+f41000d3[     ]+fli\.h[               ]+ft1,0
> >> +[      ]+[0-9a-f]+:[   ]+f41080d3[     ]+fli\.h[               ]+ft1,min
> >> +[      ]+[0-9a-f]+:[   ]+f41100d3[     ]+fli\.h[               ]+ft1,2
> >> +[      ]+[0-9a-f]+:[   ]+f41d80d3[     ]+fli\.h[               ]+ft1,27
> >> +[      ]+[0-9a-f]+:[   ]+f41e00d3[     ]+fli\.h[               ]+ft1,28
> >> +[      ]+[0-9a-f]+:[   ]+f41e80d3[     ]+fli\.h[               ]+ft1,29
> >> +[      ]+[0-9a-f]+:[   ]+f41080d3[     ]+fli\.h[               ]+ft1,min
> >> +[      ]+[0-9a-f]+:[   ]+f41f00d3[     ]+fli\.h[               ]+ft1,inf
> >> +[      ]+[0-9a-f]+:[   ]+f41f80d3[     ]+fli\.h[               ]+ft1,nan
> >> +[      ]+[0-9a-f]+:[   ]+f01000d3[     ]+fli\.s[               ]+ft1,0
> >> +[      ]+[0-9a-f]+:[   ]+f01080d3[     ]+fli\.s[               ]+ft1,min
> >> +[      ]+[0-9a-f]+:[   ]+f01100d3[     ]+fli\.s[               ]+ft1,2
> >> +[      ]+[0-9a-f]+:[   ]+f01d80d3[     ]+fli\.s[               ]+ft1,27
> >> +[      ]+[0-9a-f]+:[   ]+f01e00d3[     ]+fli\.s[               ]+ft1,28
> >> +[      ]+[0-9a-f]+:[   ]+f01e80d3[     ]+fli\.s[               ]+ft1,29
> >> +[      ]+[0-9a-f]+:[   ]+f01080d3[     ]+fli\.s[               ]+ft1,min
> >> +[      ]+[0-9a-f]+:[   ]+f01f00d3[     ]+fli\.s[               ]+ft1,inf
> >> +[      ]+[0-9a-f]+:[   ]+f01f80d3[     ]+fli\.s[               ]+ft1,nan
> >> +[      ]+[0-9a-f]+:[   ]+f21000d3[     ]+fli\.d[               ]+ft1,0
> >> +[      ]+[0-9a-f]+:[   ]+f21080d3[     ]+fli\.d[               ]+ft1,min
> >> +[      ]+[0-9a-f]+:[   ]+f21100d3[     ]+fli\.d[               ]+ft1,2
> >> +[      ]+[0-9a-f]+:[   ]+f21d80d3[     ]+fli\.d[               ]+ft1,27
> >> +[      ]+[0-9a-f]+:[   ]+f21e00d3[     ]+fli\.d[               ]+ft1,28
> >> +[      ]+[0-9a-f]+:[   ]+f21e80d3[     ]+fli\.d[               ]+ft1,29
> >> +[      ]+[0-9a-f]+:[   ]+f21080d3[     ]+fli\.d[               ]+ft1,min
> >> +[      ]+[0-9a-f]+:[   ]+f21f00d3[     ]+fli\.d[               ]+ft1,inf
> >> +[      ]+[0-9a-f]+:[   ]+f21f80d3[     ]+fli\.d[               ]+ft1,nan
> >> +[      ]+[0-9a-f]+:[   ]+f61000d3[     ]+fli\.q[               ]+ft1,0
> >> +[      ]+[0-9a-f]+:[   ]+f61080d3[     ]+fli\.q[               ]+ft1,min
> >> +[      ]+[0-9a-f]+:[   ]+f61100d3[     ]+fli\.q[               ]+ft1,2
> >> +[      ]+[0-9a-f]+:[   ]+f61d80d3[     ]+fli\.q[               ]+ft1,27
> >> +[      ]+[0-9a-f]+:[   ]+f61e00d3[     ]+fli\.q[               ]+ft1,28
> >> +[      ]+[0-9a-f]+:[   ]+f61e80d3[     ]+fli\.q[               ]+ft1,29
> >> +[      ]+[0-9a-f]+:[   ]+f61080d3[     ]+fli\.q[               ]+ft1,min
> >> +[      ]+[0-9a-f]+:[   ]+f61f00d3[     ]+fli\.q[               ]+ft1,inf
> >> +[      ]+[0-9a-f]+:[   ]+f61f80d3[     ]+fli\.q[               ]+ft1,nan
> >> +[      ]+[0-9a-f]+:[   ]+2c3100d3[     ]+fmin\.h[              ]+ft1,ft2,ft3
> >> +[      ]+[0-9a-f]+:[   ]+2c3120d3[     ]+fmini\.h[             ]+ft1,ft2,ft3
> >> +[      ]+[0-9a-f]+:[   ]+283100d3[     ]+fmin\.s[              ]+ft1,ft2,ft3
> >> +[      ]+[0-9a-f]+:[   ]+283120d3[     ]+fmini\.s[             ]+ft1,ft2,ft3
> >> +[      ]+[0-9a-f]+:[   ]+2a3100d3[     ]+fmin\.d[              ]+ft1,ft2,ft3
> >> +[      ]+[0-9a-f]+:[   ]+2a3120d3[     ]+fmini\.d[             ]+ft1,ft2,ft3
> >> +[      ]+[0-9a-f]+:[   ]+2e3100d3[     ]+fmin\.q[              ]+ft1,ft2,ft3
> >> +[      ]+[0-9a-f]+:[   ]+2e3120d3[     ]+fmini\.q[             ]+ft1,ft2,ft3
> >> +[      ]+[0-9a-f]+:[   ]+2c3110d3[     ]+fmax\.h[              ]+ft1,ft2,ft3
> >> +[      ]+[0-9a-f]+:[   ]+2c3130d3[     ]+fmaxi\.h[             ]+ft1,ft2,ft3
> >> +[      ]+[0-9a-f]+:[   ]+283110d3[     ]+fmax\.s[              ]+ft1,ft2,ft3
> >> +[      ]+[0-9a-f]+:[   ]+283130d3[     ]+fmaxi\.s[             ]+ft1,ft2,ft3
> >> +[      ]+[0-9a-f]+:[   ]+2a3110d3[     ]+fmax\.d[              ]+ft1,ft2,ft3
> >> +[      ]+[0-9a-f]+:[   ]+2a3130d3[     ]+fmaxi\.d[             ]+ft1,ft2,ft3
> >> +[      ]+[0-9a-f]+:[   ]+2e3110d3[     ]+fmax\.q[              ]+ft1,ft2,ft3
> >> +[      ]+[0-9a-f]+:[   ]+2e3130d3[     ]+fmaxi\.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..fb79792bf10
> >> --- /dev/null
> >> +++ b/gas/testsuite/gas/riscv/zfa.s
> >> @@ -0,0 +1,92 @@
> >> +target:
> >> +       # fli: test both decimal and symbol representations
> >> +       #      (0..29, min==1, inf==(30), nan==(31))
> >> +       fli.h           ft1, 0
> >> +       fli.h           ft1, 1
> >> +       fli.h           ft1, 2
> >> +       fli.h           ft1, 27
> >> +       fli.h           ft1, 28
> >> +       fli.h           ft1, 29
> >> +       fli.h           ft1, min
> >> +       fli.h           ft1, inf
> >> +       fli.h           ft1, nan
> >> +       fli.s           ft1, 0
> >> +       fli.s           ft1, 1
> >> +       fli.s           ft1, 2
> >> +       fli.s           ft1, 27
> >> +       fli.s           ft1, 28
> >> +       fli.s           ft1, 29
> >> +       fli.s           ft1, min
> >> +       fli.s           ft1, inf
> >> +       fli.s           ft1, nan
> >> +       fli.d           ft1, 0
> >> +       fli.d           ft1, 1
> >> +       fli.d           ft1, 2
> >> +       fli.d           ft1, 27
> >> +       fli.d           ft1, 28
> >> +       fli.d           ft1, 29
> >> +       fli.d           ft1, min
> >> +       fli.d           ft1, inf
> >> +       fli.d           ft1, nan
> >> +       fli.q           ft1, 0
> >> +       fli.q           ft1, 1
> >> +       fli.q           ft1, 2
> >> +       fli.q           ft1, 27
> >> +       fli.q           ft1, 28
> >> +       fli.q           ft1, 29
> >> +       fli.q           ft1, min
> >> +       fli.q           ft1, inf
> >> +       fli.q           ft1, nan
> >> +       # fmini/fmaxi (Zfa): same as fmin/fmax (Zfh/F/D/Q) except bit 13 set
> >> +       fmin.h          ft1, ft2, ft3
> >> +       fmini.h         ft1, ft2, ft3
> >> +       fmin.s          ft1, ft2, ft3
> >> +       fmini.s         ft1, ft2, ft3
> >> +       fmin.d          ft1, ft2, ft3
> >> +       fmini.d         ft1, ft2, ft3
> >> +       fmin.q          ft1, ft2, ft3
> >> +       fmini.q         ft1, ft2, ft3
> >> +       fmax.h          ft1, ft2, ft3
> >> +       fmaxi.h         ft1, ft2, ft3
> >> +       fmax.s          ft1, ft2, ft3
> >> +       fmaxi.s         ft1, ft2, ft3
> >> +       fmax.d          ft1, ft2, ft3
> >> +       fmaxi.d         ft1, ft2, ft3
> >> +       fmax.q          ft1, ft2, ft3
> >> +       fmaxi.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 (Zfa): same as flt/fle (Zfh/F/D/Q) except bit 14 set
> >> +       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 88b8d7ff595..9739ad24538 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_FMINI_H 0x2c002053
> >> +#define MASK_FMINI_H 0xfe00707f
> >> +#define MATCH_FMAXI_H 0x2c003053
> >> +#define MASK_FMAXI_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_FMINI_S 0x28002053
> >> +#define MASK_FMINI_S 0xfe00707f
> >> +#define MATCH_FMAXI_S 0x28003053
> >> +#define MASK_FMAXI_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_FMINI_D 0x2a002053
> >> +#define MASK_FMINI_D 0xfe00707f
> >> +#define MATCH_FMAXI_D 0x2a003053
> >> +#define MASK_FMAXI_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_FMINI_Q 0x2e002053
> >> +#define MASK_FMINI_Q 0xfe00707f
> >> +#define MATCH_FMAXI_Q 0x2e003053
> >> +#define MASK_FMAXI_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
> >> @@ -2718,6 +2784,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(fmini_h, MATCH_FMINI_H, MASK_FMINI_H)
> >> +DECLARE_INSN(fmaxi_h, MATCH_FMAXI_H, MASK_FMAXI_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(fmini_s, MATCH_FMINI_S, MASK_FMINI_S)
> >> +DECLARE_INSN(fmaxi_s, MATCH_FMAXI_S, MASK_FMAXI_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(fmini_d, MATCH_FMINI_D, MASK_FMINI_D)
> >> +DECLARE_INSN(fmaxi_d, MATCH_FMAXI_D, MASK_FMAXI_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(fmini_q, MATCH_FMINI_Q, MASK_FMINI_Q)
> >> +DECLARE_INSN(fmaxi_q, MATCH_FMAXI_Q, MASK_FMAXI_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 f1dabeaab8e..3e9feaac2a7 100644
> >> --- a/include/opcode/riscv.h
> >> +++ b/include/opcode/riscv.h
> >> @@ -376,6 +376,10 @@ enum riscv_insn_class
> >>    INSN_CLASS_ZFHMIN_OR_ZHINXMIN,
> >>    INSN_CLASS_ZFHMIN_AND_D,
> >>    INSN_CLASS_ZFHMIN_AND_Q,
> >> +  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,
> >> @@ -528,6 +532,7 @@ 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_value[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 7ae6e709290..7a8be52281f 100644
> >> --- a/opcodes/riscv-dis.c
> >> +++ b/opcodes/riscv-dis.c
> >> @@ -563,6 +563,13 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
> >>           print (info->stream, dis_style_text, "%d", rs1);
> >>           break;
> >>
> >> +       case 'i':
> >> +         if (riscv_fli_value[rs1])
> >> +           print (info->stream, dis_style_text, "%s", riscv_fli_value[rs1]);
> >> +         else
> >> +           print (info->stream, dis_style_immediate, "%d", rs1);
> >> +         break;
> >> +
> >>         default:
> >>           /* xgettext:c-format */
> >>           print (info->stream, dis_style_text,
> >> diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
> >> index 79be78eb367..eb4da1a7485 100644
> >> --- a/opcodes/riscv-opc.c
> >> +++ b/opcodes/riscv-opc.c
> >> @@ -97,6 +97,15 @@ const char * const riscv_vma[2] =
> >>    "mu", "ma"
> >>  };
> >>
> >> +/* The FLI.[HSDQ] value constants.  */
> >> +const char * const riscv_fli_value[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 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
> >> @@ -636,6 +645,15 @@ const struct riscv_opcode riscv_opcodes[] =
> >>  {"fcvt.h.l",  64, INSN_CLASS_ZFH_OR_ZHINX,   "D,s,m",     MATCH_FCVT_H_L, MASK_FCVT_H_L, match_opcode, 0 },
> >>  {"fcvt.h.lu", 64, INSN_CLASS_ZFH_OR_ZHINX,   "D,s",       MATCH_FCVT_H_LU|MASK_RM, MASK_FCVT_H_LU|MASK_RM, match_opcode, 0 },
> >>  {"fcvt.h.lu", 64, INSN_CLASS_ZFH_OR_ZHINX,   "D,s,m",     MATCH_FCVT_H_LU, MASK_FCVT_H_LU, match_opcode, 0 },
> >> +{"fli.h",      0, INSN_CLASS_ZFH_AND_ZFA,    "D,i",       MATCH_FLI_H, MASK_FLI_H, match_opcode, 0 },
> >> +{"fmini.h",    0, INSN_CLASS_ZFH_AND_ZFA,    "D,S,T",     MATCH_FMINI_H, MASK_FMINI_H, match_opcode, 0 },
> >> +{"fmaxi.h",    0, INSN_CLASS_ZFH_AND_ZFA,    "D,S,T",     MATCH_FMAXI_H, MASK_FMAXI_H, 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 },
> >> +{"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 },
> >>
> >>  /* Single-precision floating-point instruction subset.  */
> >>  {"frcsr",      0, INSN_CLASS_F_OR_ZFINX,   "d",         MATCH_FRCSR, MASK_FRCSR, match_opcode, INSN_ALIAS },
> >> @@ -714,7 +732,16 @@ const struct riscv_opcode riscv_opcodes[] =
> >>  {"fcvt.s.l",  64, INSN_CLASS_F_OR_ZFINX,   "D,s,m",     MATCH_FCVT_S_L, MASK_FCVT_S_L, match_opcode, 0 },
> >>  {"fcvt.s.lu", 64, INSN_CLASS_F_OR_ZFINX,   "D,s",       MATCH_FCVT_S_LU|MASK_RM, MASK_FCVT_S_LU|MASK_RM, match_opcode, 0 },
> >>  {"fcvt.s.lu", 64, INSN_CLASS_F_OR_ZFINX,   "D,s,m",     MATCH_FCVT_S_LU, MASK_FCVT_S_LU, match_opcode, 0 },
> >> -
> >> +{"fli.s",      0, INSN_CLASS_ZFA,          "D,i",       MATCH_FLI_S, MASK_FLI_S, match_opcode, 0 },
> >> +{"fmini.s",    0, INSN_CLASS_ZFA,          "D,S,T",     MATCH_FMINI_S, MASK_FMINI_S, match_opcode, 0 },
> >> +{"fmaxi.s",    0, INSN_CLASS_ZFA,          "D,S,T",     MATCH_FMAXI_S, MASK_FMAXI_S, 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 },
> >> +{"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 },
> >> +
> >>  /* Double-precision floating-point instruction subset.  */
> >>  {"fld",        0, INSN_CLASS_D_AND_C, "D,Cn(Cc)",  MATCH_C_FLDSP, MASK_C_FLDSP, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
> >>  {"fld",        0, INSN_CLASS_D_AND_C, "CD,Cl(Cs)", MATCH_C_FLD, MASK_C_FLD, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
> >> @@ -775,6 +802,18 @@ const struct riscv_opcode riscv_opcodes[] =
> >>  {"fcvt.d.l",  64, INSN_CLASS_D_OR_ZDINX,   "D,s,m",     MATCH_FCVT_D_L, MASK_FCVT_D_L, match_opcode, 0 },
> >>  {"fcvt.d.lu", 64, INSN_CLASS_D_OR_ZDINX,   "D,s",       MATCH_FCVT_D_LU|MASK_RM, MASK_FCVT_D_LU|MASK_RM, match_opcode, 0 },
> >>  {"fcvt.d.lu", 64, INSN_CLASS_D_OR_ZDINX,   "D,s,m",     MATCH_FCVT_D_LU, MASK_FCVT_D_LU, match_opcode, 0 },
> >> +{"fli.d",       0, INSN_CLASS_D_AND_ZFA,   "D,i",       MATCH_FLI_D, MASK_FLI_D, match_opcode, 0 },
> >> +{"fmini.d",     0, INSN_CLASS_D_AND_ZFA,   "D,S,T",     MATCH_FMINI_D, MASK_FMINI_D, match_opcode, 0 },
> >> +{"fmaxi.d",     0, INSN_CLASS_D_AND_ZFA,   "D,S,T",     MATCH_FMAXI_D, MASK_FMAXI_D, 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 },
> >> +{"fcvtmod.w.d", 0, INSN_CLASS_D_AND_ZFA,   "d,S,m",     MATCH_FCVTMOD_W_D, MASK_FCVTMOD_W_D, 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 },
> >> +{"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},
> >>
> >>  /* Quad-precision floating-point instruction subset.  */
> >>  {"flq",        0, INSN_CLASS_Q,   "D,o(s)",    MATCH_FLQ, MASK_FLQ, match_opcode, INSN_DREF|INSN_16_BYTE },
> >> @@ -833,6 +872,17 @@ const struct riscv_opcode riscv_opcodes[] =
> >>  {"fcvt.q.l",  64, INSN_CLASS_Q_OR_ZQINX,   "D,s,m",     MATCH_FCVT_Q_L, MASK_FCVT_Q_L, match_opcode, 0 },
> >>  {"fcvt.q.lu", 64, INSN_CLASS_Q_OR_ZQINX,   "D,s",       MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU|MASK_RM, match_opcode, 0 },
> >>  {"fcvt.q.lu", 64, INSN_CLASS_Q_OR_ZQINX,   "D,s,m",     MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU, match_opcode, 0 },
> >> +{"fli.q",       0, INSN_CLASS_Q_AND_ZFA,   "D,i",       MATCH_FLI_Q, MASK_FLI_Q, match_opcode, 0 },
> >> +{"fmini.q",     0, INSN_CLASS_Q_AND_ZFA,   "D,S,T",     MATCH_FMINI_Q, MASK_FMINI_Q, match_opcode, 0 },
> >> +{"fmaxi.q",     0, INSN_CLASS_Q_AND_ZFA,   "D,S,T",     MATCH_FMAXI_Q, MASK_FMAXI_Q, 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 },
> >> +{"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 },
> >> +{"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},
> >>
> >>  /* Compressed instructions.  */
> >>  {"c.unimp",    0, INSN_CLASS_C,   "",          0, 0xffffU,  match_opcode, 0 },
> >> --
> >> 2.34.1
> >>
> >

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

* Re: [REVIEW ONLY 1/1] UNRATIFIED RISC-V: Add 'Zfa' extension
  2023-03-22 16:21       ` Christoph Müllner
@ 2023-03-22 17:00         ` Tsukasa OI
  2023-03-23 13:17           ` Kito Cheng
  0 siblings, 1 reply; 10+ messages in thread
From: Tsukasa OI @ 2023-03-22 17:00 UTC (permalink / raw)
  To: Christoph Müllner; +Cc: binutils, Philipp Tomsich, Andrew Waterman



On 2023/03/23 1:21, Christoph Müllner wrote:
> On Wed, Mar 22, 2023 at 5:07 PM Tsukasa OI <research_trasio@irq.a4lg.com> wrote:
>>
>> On 2023/03/23 0:47, Christoph Müllner wrote:
>>> On Sun, Sep 18, 2022 at 12:13 PM Tsukasa OI via Binutils
>>> <binutils@sourceware.org> wrote:
>>>>
>>>> [DO NOT MERGE]
>>>> Until 'Zfa' extension is frozen/ratified and final version number is
>>>> determined, this patch should not merged upstream. This commit uses
>>>> unratified version 0.1 as in documentation (instead of possible 1.0
>>>> after ratification).
>>>>
>>>> This commit adds the 'Zfa' extension (its instructions and new operand
>>>> type for FLI instructions).
>>>>
>>>> This is based on:
>>>> <https://github.com/riscv/riscv-isa-manual/commit/ae683aec28ec707a3c4bb6f588491f0840d52f43>
>>>> (latest commit of the 'zfb' branch as of this writing)
>>>>
>>>> Note: the author is calling FLI instructions' RS1 encoded field as
>>>> "value".  It must be reviewed before the specification is frozen.
>>>>
>>>> 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:
>>>>
>>>>         * testsuite/gas/riscv/zfa.s: New test.
>>>>         * testsuite/gas/riscv/zfa.d: Likewise.
>>>>         * testsuite/gas/riscv/zfa-32.s: New test.
>>>>         * testsuite/gas/riscv/zfa-32.d: Likewise.
>>>>         * testsuite/gas/riscv/zfa-64.s: New test.
>>>>         * testsuite/gas/riscv/zfa-64.d: Likewise.
>>>>         * testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.s: New failure test for
>>>>         the "fcvtmod.w.d" instruction.
>>>>         * testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.d: Likewise.
>>>>         * testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.l: Likewise.
>>>>         * testsuite/gas/riscv/zfa-fail-fli.s: New failure test for "fli"
>>>>         instructions.
>>>>         * testsuite/gas/riscv/zfa-fail-fli.d: Likewise.
>>>>         * testsuite/gas/riscv/zfa-fail-fli.l: Likewise.
>>>>
>>>> include/ChangeLog:
>>>>
>>>>         * opcode/riscv-opc.h (MATCH_FLI_H, MASK_FLI_H, MATCH_FMINI_H,
>>>>         MASK_FMINI_H, MATCH_FMAXI_H, MASK_FMAXI_H, MATCH_FROUND_H,
>>>>         MASK_FROUND_H, MATCH_FROUNDNX_H, MASK_FROUNDNX_H, MATCH_FLTQ_H,
>>>>         MASK_FLTQ_H, MATCH_FLEQ_H, MASK_FLEQ_H, MATCH_FLI_S, MASK_FLI_S,
>>>>         MATCH_FMINI_S, MASK_FMINI_S, MATCH_FMAXI_S, MASK_FMAXI_S,
>>>>         MATCH_FROUND_S, MASK_FROUND_S, MATCH_FROUNDNX_S, MASK_FROUNDNX_S,
>>>>         MATCH_FLTQ_S, MASK_FLTQ_S, MATCH_FLEQ_S, MASK_FLEQ_S, MATCH_FLI_D,
>>>>         MASK_FLI_D, MATCH_FMINI_D, MASK_FMINI_D, MATCH_FMAXI_D,
>>>>         MASK_FMAXI_D, MATCH_FROUND_D, MASK_FROUND_D, MATCH_FROUNDNX_D,
>>>>         MASK_FROUNDNX_D, MATCH_FLTQ_D, MASK_FLTQ_D, MATCH_FLEQ_D,
>>>>         MASK_FLEQ_D, MATCH_FLI_Q, MASK_FLI_Q, MATCH_FMINI_Q, MASK_FMINI_Q,
>>>>         MATCH_FMAXI_Q, MASK_FMAXI_Q, MATCH_FROUND_Q, MASK_FROUND_Q,
>>>>         MATCH_FROUNDNX_Q, MASK_FROUNDNX_Q, MATCH_FLTQ_Q, MASK_FLTQ_Q,
>>>>         MATCH_FLEQ_Q, MASK_FLEQ_Q, MATCH_FCVTMOD_W_D, MASK_FCVTMOD_W_D,
>>>>         MATCH_FMVH_X_D, MASK_FMVH_X_D, MATCH_FMVH_X_Q, MASK_FMVH_X_Q,
>>>>         MATCH_FMVP_D_X, MASK_FMVP_D_X, MATCH_FMVP_Q_X, MASK_FMVP_Q_X): New.
>>>>         * opcode/riscv.h (enum riscv_insn_class): Add instruction
>>>>         classes for 'Zfa' extension.
>>>>
>>>> opcodes/ChangeLog:
>>>>
>>>>         * riscv-opc.c (riscv_opcodes): Add 'Zfa' instructions.
>>>> ---
>>>>  bfd/elfxx-riscv.c                             | 39 ++++++++
>>>>  gas/config/tc-riscv.c                         | 21 ++++
>>>>  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/riscv/zfa-fail-fcvtmod.w.d.d          |  3 +
>>>>  .../gas/riscv/zfa-fail-fcvtmod.w.d.l          |  8 ++
>>>>  .../gas/riscv/zfa-fail-fcvtmod.w.d.s          | 11 +++
>>>>  gas/testsuite/gas/riscv/zfa-fail-fli.d        |  3 +
>>>>  gas/testsuite/gas/riscv/zfa-fail-fli.l        | 21 ++++
>>>>  gas/testsuite/gas/riscv/zfa-fail-fli.s        | 21 ++++
>>>>  gas/testsuite/gas/riscv/zfa.d                 | 93 +++++++++++++++++
>>>>  gas/testsuite/gas/riscv/zfa.s                 | 92 +++++++++++++++++
>>>>  include/opcode/riscv-opc.h                    | 99 +++++++++++++++++++
>>>>  include/opcode/riscv.h                        |  5 +
>>>>  opcodes/riscv-dis.c                           |  7 ++
>>>>  opcodes/riscv-opc.c                           | 52 +++++++++-
>>>>  18 files changed, 500 insertions(+), 1 deletion(-)
>>>>  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-fcvtmod.w.d.d
>>>>  create mode 100644 gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.l
>>>>  create mode 100644 gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.s
>>>>  create mode 100644 gas/testsuite/gas/riscv/zfa-fail-fli.d
>>>>  create mode 100644 gas/testsuite/gas/riscv/zfa-fail-fli.l
>>>>  create mode 100644 gas/testsuite/gas/riscv/zfa-fail-fli.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 e03b312a381..1c6d1505d54 100644
>>>> --- a/bfd/elfxx-riscv.c
>>>> +++ b/bfd/elfxx-riscv.c
>>>> @@ -1073,6 +1073,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},
>>>> @@ -1162,6 +1163,7 @@ static struct riscv_supported_ext riscv_supported_std_z_ext[] =
>>>>    {"zifencei",         ISA_SPEC_CLASS_20190608,        2, 0,  0 },
>>>>    {"zihintpause",      ISA_SPEC_CLASS_DRAFT,           2, 0,  0 },
>>>>    {"zmmul",            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 },
>>>> @@ -2334,6 +2336,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:
>>>> @@ -2469,6 +2482,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 2f5ee18e451..ffbc7fbdda2 100644
>>>> --- a/gas/config/tc-riscv.c
>>>> +++ b/gas/config/tc-riscv.c
>>>> @@ -1208,6 +1208,7 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
>>>>         case 'd': USE_BITS (OP_MASK_RD, OP_SH_RD); break;
>>>>         case 'y': USE_BITS (OP_MASK_BS, OP_SH_BS); break;
>>>>         case 'Y': USE_BITS (OP_MASK_RNUM, OP_SH_RNUM); break;
>>>> +       case 'i': /* RS1, FLI.[HSDQ] value field.  */
>>>>         case 'Z': /* RS1, CSR number.  */
>>>>         case 'S': /* RS1, floating point.  */
>>>>         case 's': USE_BITS (OP_MASK_RS1, OP_SH_RS1); break;
>>>> @@ -3262,6 +3263,26 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
>>>>               asarg = expr_end;
>>>>               continue;
>>>>
>>>> +           case 'i': /* FLI.[HSDQ] constant immediate.  */
>>>> +             if (arg_lookup (&asarg, riscv_fli_value,
>>>> +                             ARRAY_SIZE (riscv_fli_value), &regno))
>>>> +               INSERT_OPERAND (RS1, *ip, regno);
>>>> +             else
>>>> +               {
>>>> +                 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
>>>> +                     || imm_expr->X_op != O_constant)
>>>> +                   break;
>>>> +                 if (imm_expr->X_add_number < 0
>>>> +                     || imm_expr->X_add_number > 29)
>>>> +                   as_bad (_ ("improper fli value field (%ld), "
>>>> +                              "value must be 0...29 or min, inf or nan"),
>>>> +                           (long) imm_expr->X_add_number);
>>>> +                 INSERT_OPERAND (RS1, *ip, imm_expr->X_add_number);
>>>> +                 imm_expr->X_op = O_absent;
>>>> +                 asarg = expr_end;
>>>> +               }
>>>> +             continue;
>>>> +
>>>>             default:
>>>>             unknown_riscv_ip_operand:
>>>>               as_fatal (_("internal: unknown argument type `%s'"),
>>>> diff --git a/gas/testsuite/gas/riscv/zfa-32.d b/gas/testsuite/gas/riscv/zfa-32.d
>>>> new file mode 100644
>>>> index 00000000000..0f0cbfcdc70
>>>> --- /dev/null
>>>> +++ b/gas/testsuite/gas/riscv/zfa-32.d
>>>> @@ -0,0 +1,10 @@
>>>> +#as: -march=rv32id_zfa
>>>> +#objdump: -dr
>>>> +
>>>> +.*:[   ]+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..f942d616959
>>>> --- /dev/null
>>>> +++ b/gas/testsuite/gas/riscv/zfa-64.d
>>>> @@ -0,0 +1,10 @@
>>>> +#as: -march=rv64iq_zfa
>>>> +#objdump: -dr
>>>> +
>>>> +.*:[   ]+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-fcvtmod.w.d.d b/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.d
>>>> new file mode 100644
>>>> index 00000000000..5234c49de75
>>>> --- /dev/null
>>>> +++ b/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.d
>>>> @@ -0,0 +1,3 @@
>>>> +#as: -march=rv64id_zfa
>>>> +#objdump: -dr
>>>> +#error_output: zfa-fail-fcvtmod.w.d.l
>>>> diff --git a/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.l b/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.l
>>>> new file mode 100644
>>>> index 00000000000..4ea048a3356
>>>> --- /dev/null
>>>> +++ b/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.l
>>>> @@ -0,0 +1,8 @@
>>>> +.*: Assembler messages:
>>>> +.*: 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-fcvtmod.w.d.s b/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.s
>>>> new file mode 100644
>>>> index 00000000000..5984f6676d8
>>>> --- /dev/null
>>>> +++ b/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.s
>>>> @@ -0,0 +1,11 @@
>>>> +target:
>>>> +       # fcvtmod.w.d requires explicit rounding mode.
>>>> +       fcvtmod.w.d     a0, ft1
>>>> +       # 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
>>>> +       # Invalid rounding mode is invalid.
>>>> +       fcvtmod.w.d     a0, ft1, invalid
>>>> diff --git a/gas/testsuite/gas/riscv/zfa-fail-fli.d b/gas/testsuite/gas/riscv/zfa-fail-fli.d
>>>> new file mode 100644
>>>> index 00000000000..3753a4d185e
>>>> --- /dev/null
>>>> +++ b/gas/testsuite/gas/riscv/zfa-fail-fli.d
>>>> @@ -0,0 +1,3 @@
>>>> +#as: -march=rv64iq_zfa_zfh
>>>> +#objdump: -dr
>>>> +#error_output: zfa-fail-fli.l
>>>> diff --git a/gas/testsuite/gas/riscv/zfa-fail-fli.l b/gas/testsuite/gas/riscv/zfa-fail-fli.l
>>>> new file mode 100644
>>>> index 00000000000..b7532f80fd4
>>>> --- /dev/null
>>>> +++ b/gas/testsuite/gas/riscv/zfa-fail-fli.l
>>>> @@ -0,0 +1,21 @@
>>>> +.*: Assembler messages:
>>>> +.*: Error: improper fli value field \(-1\), value must be 0\.\.\.29 or min, inf or nan
>>>> +.*: Error: improper fli value field \(-1\), value must be 0\.\.\.29 or min, inf or nan
>>>> +.*: Error: improper fli value field \(-1\), value must be 0\.\.\.29 or min, inf or nan
>>>> +.*: Error: improper fli value field \(-1\), value must be 0\.\.\.29 or min, inf or nan
>>>> +.*: Error: improper fli value field \(-2\), value must be 0\.\.\.29 or min, inf or nan
>>>> +.*: Error: improper fli value field \(-2\), value must be 0\.\.\.29 or min, inf or nan
>>>> +.*: Error: improper fli value field \(-2\), value must be 0\.\.\.29 or min, inf or nan
>>>> +.*: Error: improper fli value field \(-2\), value must be 0\.\.\.29 or min, inf or nan
>>>> +.*: Error: improper fli value field \(30\), value must be 0\.\.\.29 or min, inf or nan
>>>> +.*: Error: improper fli value field \(30\), value must be 0\.\.\.29 or min, inf or nan
>>>> +.*: Error: improper fli value field \(30\), value must be 0\.\.\.29 or min, inf or nan
>>>> +.*: Error: improper fli value field \(30\), value must be 0\.\.\.29 or min, inf or nan
>>>> +.*: Error: improper fli value field \(32\), value must be 0\.\.\.29 or min, inf or nan
>>>> +.*: Error: improper fli value field \(32\), value must be 0\.\.\.29 or min, inf or nan
>>>> +.*: Error: improper fli value field \(32\), value must be 0\.\.\.29 or min, inf or nan
>>>> +.*: Error: improper fli value field \(32\), value must be 0\.\.\.29 or min, inf or nan
>>>> +.*: Error: illegal operands `fli\.h ft1,invalid'
>>>> +.*: Error: illegal operands `fli\.s ft1,invalid'
>>>> +.*: Error: illegal operands `fli\.d ft1,invalid'
>>>> +.*: Error: illegal operands `fli\.q ft1,invalid'
>>>> diff --git a/gas/testsuite/gas/riscv/zfa-fail-fli.s b/gas/testsuite/gas/riscv/zfa-fail-fli.s
>>>> new file mode 100644
>>>> index 00000000000..4c600b5d578
>>>> --- /dev/null
>>>> +++ b/gas/testsuite/gas/riscv/zfa-fail-fli.s
>>>> @@ -0,0 +1,21 @@
>>>> +target:
>>>> +       fli.h   ft1, -1
>>>> +       fli.s   ft1, -1
>>>> +       fli.d   ft1, -1
>>>> +       fli.q   ft1, -1
>>>> +       fli.h   ft1, -2
>>>> +       fli.s   ft1, -2
>>>> +       fli.d   ft1, -2
>>>> +       fli.q   ft1, -2
>>>> +       fli.h   ft1, 30
>>>> +       fli.s   ft1, 30
>>>> +       fli.d   ft1, 30
>>>> +       fli.q   ft1, 30
>>>> +       fli.h   ft1, 32
>>>> +       fli.s   ft1, 32
>>>> +       fli.d   ft1, 32
>>>> +       fli.q   ft1, 32
>>>> +       fli.h   ft1, invalid
>>>> +       fli.s   ft1, invalid
>>>> +       fli.d   ft1, invalid
>>>> +       fli.q   ft1, invalid
>>>> diff --git a/gas/testsuite/gas/riscv/zfa.d b/gas/testsuite/gas/riscv/zfa.d
>>>> new file mode 100644
>>>> index 00000000000..3701a41e485
>>>> --- /dev/null
>>>> +++ b/gas/testsuite/gas/riscv/zfa.d
>>>> @@ -0,0 +1,93 @@
>>>> +#as: -march=rv64iq_zfa_zfh
>>>> +#objdump: -dr
>>>> +
>>>> +.*:[   ]+file format .*
>>>> +
>>>> +Disassembly of section .text:
>>>> +
>>>> +0+000 <target>:
>>>
>>> Hi Tsukasa,
>>>
>>> There seems to be a misunderstanding of the spec.
>>> The second operand of the fli should be the constant itself ("Value"
>>> column of the specification) in C-like syntax.
>>> E.g.:
>>>   fli.h ft1, -1.0 # encoding rs1=0
>>>   fli.h ft1, min # encoding rs1=1
>>>   fli.h ft1, 0.0000152587890625 # encoding rs1=2
>>>   ...
>>>   fli.h ft1, 16 # encoding rs1=25
>>>   ...
>>>   fli.h ft1, nan # encoding rs1=31
>>>
>>> So we have 3 strings ("min", "inf", "nan") and 29 constants.
>>>
>>> BR
>>> Christoph
>>
>> Hi,
>>
>> I showed very early patchset of 'Zfa' to Andrew and I misunderstood that
>> he was okay with that operands.  Now the situation is clearer but due to
>> my poor health conditions, it might not be soon to make a new patchset
>> (I'm working on it but the progress is very slow).  If my new patchset
>> for 'Zfa' isn't posted until mid-May, it'll be better that someone else
>> make their 'Zfa' patchset.
> 
> We are working on a couple of other Zfa enablement patches and we need
> a solution earlier than mid-May (we target the end of this month).
> Is it ok for you if I take over the patch and add you as Co-developed-by?0
> I would also use your "RISC-V: Allocate "various" operand type" commit as base.
> 
> Get well soon!
> 
> BR
> Christoph

Of course!

> I would also use your "RISC-V: Allocate "various" operand type" commit as base.

Yes, that would be important more than I first thought because current
design would require four "fli" constant operands.

Thanks and I hope that I'm back online in June,
Tsukasa

> 
>>
>> Tsukasa
>>
>>>
>>>> +[      ]+[0-9a-f]+:[   ]+f41000d3[     ]+fli\.h[               ]+ft1,0
>>>> +[      ]+[0-9a-f]+:[   ]+f41080d3[     ]+fli\.h[               ]+ft1,min
>>>> +[      ]+[0-9a-f]+:[   ]+f41100d3[     ]+fli\.h[               ]+ft1,2
>>>> +[      ]+[0-9a-f]+:[   ]+f41d80d3[     ]+fli\.h[               ]+ft1,27
>>>> +[      ]+[0-9a-f]+:[   ]+f41e00d3[     ]+fli\.h[               ]+ft1,28
>>>> +[      ]+[0-9a-f]+:[   ]+f41e80d3[     ]+fli\.h[               ]+ft1,29
>>>> +[      ]+[0-9a-f]+:[   ]+f41080d3[     ]+fli\.h[               ]+ft1,min
>>>> +[      ]+[0-9a-f]+:[   ]+f41f00d3[     ]+fli\.h[               ]+ft1,inf
>>>> +[      ]+[0-9a-f]+:[   ]+f41f80d3[     ]+fli\.h[               ]+ft1,nan
>>>> +[      ]+[0-9a-f]+:[   ]+f01000d3[     ]+fli\.s[               ]+ft1,0
>>>> +[      ]+[0-9a-f]+:[   ]+f01080d3[     ]+fli\.s[               ]+ft1,min
>>>> +[      ]+[0-9a-f]+:[   ]+f01100d3[     ]+fli\.s[               ]+ft1,2
>>>> +[      ]+[0-9a-f]+:[   ]+f01d80d3[     ]+fli\.s[               ]+ft1,27
>>>> +[      ]+[0-9a-f]+:[   ]+f01e00d3[     ]+fli\.s[               ]+ft1,28
>>>> +[      ]+[0-9a-f]+:[   ]+f01e80d3[     ]+fli\.s[               ]+ft1,29
>>>> +[      ]+[0-9a-f]+:[   ]+f01080d3[     ]+fli\.s[               ]+ft1,min
>>>> +[      ]+[0-9a-f]+:[   ]+f01f00d3[     ]+fli\.s[               ]+ft1,inf
>>>> +[      ]+[0-9a-f]+:[   ]+f01f80d3[     ]+fli\.s[               ]+ft1,nan
>>>> +[      ]+[0-9a-f]+:[   ]+f21000d3[     ]+fli\.d[               ]+ft1,0
>>>> +[      ]+[0-9a-f]+:[   ]+f21080d3[     ]+fli\.d[               ]+ft1,min
>>>> +[      ]+[0-9a-f]+:[   ]+f21100d3[     ]+fli\.d[               ]+ft1,2
>>>> +[      ]+[0-9a-f]+:[   ]+f21d80d3[     ]+fli\.d[               ]+ft1,27
>>>> +[      ]+[0-9a-f]+:[   ]+f21e00d3[     ]+fli\.d[               ]+ft1,28
>>>> +[      ]+[0-9a-f]+:[   ]+f21e80d3[     ]+fli\.d[               ]+ft1,29
>>>> +[      ]+[0-9a-f]+:[   ]+f21080d3[     ]+fli\.d[               ]+ft1,min
>>>> +[      ]+[0-9a-f]+:[   ]+f21f00d3[     ]+fli\.d[               ]+ft1,inf
>>>> +[      ]+[0-9a-f]+:[   ]+f21f80d3[     ]+fli\.d[               ]+ft1,nan
>>>> +[      ]+[0-9a-f]+:[   ]+f61000d3[     ]+fli\.q[               ]+ft1,0
>>>> +[      ]+[0-9a-f]+:[   ]+f61080d3[     ]+fli\.q[               ]+ft1,min
>>>> +[      ]+[0-9a-f]+:[   ]+f61100d3[     ]+fli\.q[               ]+ft1,2
>>>> +[      ]+[0-9a-f]+:[   ]+f61d80d3[     ]+fli\.q[               ]+ft1,27
>>>> +[      ]+[0-9a-f]+:[   ]+f61e00d3[     ]+fli\.q[               ]+ft1,28
>>>> +[      ]+[0-9a-f]+:[   ]+f61e80d3[     ]+fli\.q[               ]+ft1,29
>>>> +[      ]+[0-9a-f]+:[   ]+f61080d3[     ]+fli\.q[               ]+ft1,min
>>>> +[      ]+[0-9a-f]+:[   ]+f61f00d3[     ]+fli\.q[               ]+ft1,inf
>>>> +[      ]+[0-9a-f]+:[   ]+f61f80d3[     ]+fli\.q[               ]+ft1,nan
>>>> +[      ]+[0-9a-f]+:[   ]+2c3100d3[     ]+fmin\.h[              ]+ft1,ft2,ft3
>>>> +[      ]+[0-9a-f]+:[   ]+2c3120d3[     ]+fmini\.h[             ]+ft1,ft2,ft3
>>>> +[      ]+[0-9a-f]+:[   ]+283100d3[     ]+fmin\.s[              ]+ft1,ft2,ft3
>>>> +[      ]+[0-9a-f]+:[   ]+283120d3[     ]+fmini\.s[             ]+ft1,ft2,ft3
>>>> +[      ]+[0-9a-f]+:[   ]+2a3100d3[     ]+fmin\.d[              ]+ft1,ft2,ft3
>>>> +[      ]+[0-9a-f]+:[   ]+2a3120d3[     ]+fmini\.d[             ]+ft1,ft2,ft3
>>>> +[      ]+[0-9a-f]+:[   ]+2e3100d3[     ]+fmin\.q[              ]+ft1,ft2,ft3
>>>> +[      ]+[0-9a-f]+:[   ]+2e3120d3[     ]+fmini\.q[             ]+ft1,ft2,ft3
>>>> +[      ]+[0-9a-f]+:[   ]+2c3110d3[     ]+fmax\.h[              ]+ft1,ft2,ft3
>>>> +[      ]+[0-9a-f]+:[   ]+2c3130d3[     ]+fmaxi\.h[             ]+ft1,ft2,ft3
>>>> +[      ]+[0-9a-f]+:[   ]+283110d3[     ]+fmax\.s[              ]+ft1,ft2,ft3
>>>> +[      ]+[0-9a-f]+:[   ]+283130d3[     ]+fmaxi\.s[             ]+ft1,ft2,ft3
>>>> +[      ]+[0-9a-f]+:[   ]+2a3110d3[     ]+fmax\.d[              ]+ft1,ft2,ft3
>>>> +[      ]+[0-9a-f]+:[   ]+2a3130d3[     ]+fmaxi\.d[             ]+ft1,ft2,ft3
>>>> +[      ]+[0-9a-f]+:[   ]+2e3110d3[     ]+fmax\.q[              ]+ft1,ft2,ft3
>>>> +[      ]+[0-9a-f]+:[   ]+2e3130d3[     ]+fmaxi\.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..fb79792bf10
>>>> --- /dev/null
>>>> +++ b/gas/testsuite/gas/riscv/zfa.s
>>>> @@ -0,0 +1,92 @@
>>>> +target:
>>>> +       # fli: test both decimal and symbol representations
>>>> +       #      (0..29, min==1, inf==(30), nan==(31))
>>>> +       fli.h           ft1, 0
>>>> +       fli.h           ft1, 1
>>>> +       fli.h           ft1, 2
>>>> +       fli.h           ft1, 27
>>>> +       fli.h           ft1, 28
>>>> +       fli.h           ft1, 29
>>>> +       fli.h           ft1, min
>>>> +       fli.h           ft1, inf
>>>> +       fli.h           ft1, nan
>>>> +       fli.s           ft1, 0
>>>> +       fli.s           ft1, 1
>>>> +       fli.s           ft1, 2
>>>> +       fli.s           ft1, 27
>>>> +       fli.s           ft1, 28
>>>> +       fli.s           ft1, 29
>>>> +       fli.s           ft1, min
>>>> +       fli.s           ft1, inf
>>>> +       fli.s           ft1, nan
>>>> +       fli.d           ft1, 0
>>>> +       fli.d           ft1, 1
>>>> +       fli.d           ft1, 2
>>>> +       fli.d           ft1, 27
>>>> +       fli.d           ft1, 28
>>>> +       fli.d           ft1, 29
>>>> +       fli.d           ft1, min
>>>> +       fli.d           ft1, inf
>>>> +       fli.d           ft1, nan
>>>> +       fli.q           ft1, 0
>>>> +       fli.q           ft1, 1
>>>> +       fli.q           ft1, 2
>>>> +       fli.q           ft1, 27
>>>> +       fli.q           ft1, 28
>>>> +       fli.q           ft1, 29
>>>> +       fli.q           ft1, min
>>>> +       fli.q           ft1, inf
>>>> +       fli.q           ft1, nan
>>>> +       # fmini/fmaxi (Zfa): same as fmin/fmax (Zfh/F/D/Q) except bit 13 set
>>>> +       fmin.h          ft1, ft2, ft3
>>>> +       fmini.h         ft1, ft2, ft3
>>>> +       fmin.s          ft1, ft2, ft3
>>>> +       fmini.s         ft1, ft2, ft3
>>>> +       fmin.d          ft1, ft2, ft3
>>>> +       fmini.d         ft1, ft2, ft3
>>>> +       fmin.q          ft1, ft2, ft3
>>>> +       fmini.q         ft1, ft2, ft3
>>>> +       fmax.h          ft1, ft2, ft3
>>>> +       fmaxi.h         ft1, ft2, ft3
>>>> +       fmax.s          ft1, ft2, ft3
>>>> +       fmaxi.s         ft1, ft2, ft3
>>>> +       fmax.d          ft1, ft2, ft3
>>>> +       fmaxi.d         ft1, ft2, ft3
>>>> +       fmax.q          ft1, ft2, ft3
>>>> +       fmaxi.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 (Zfa): same as flt/fle (Zfh/F/D/Q) except bit 14 set
>>>> +       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 88b8d7ff595..9739ad24538 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_FMINI_H 0x2c002053
>>>> +#define MASK_FMINI_H 0xfe00707f
>>>> +#define MATCH_FMAXI_H 0x2c003053
>>>> +#define MASK_FMAXI_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_FMINI_S 0x28002053
>>>> +#define MASK_FMINI_S 0xfe00707f
>>>> +#define MATCH_FMAXI_S 0x28003053
>>>> +#define MASK_FMAXI_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_FMINI_D 0x2a002053
>>>> +#define MASK_FMINI_D 0xfe00707f
>>>> +#define MATCH_FMAXI_D 0x2a003053
>>>> +#define MASK_FMAXI_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_FMINI_Q 0x2e002053
>>>> +#define MASK_FMINI_Q 0xfe00707f
>>>> +#define MATCH_FMAXI_Q 0x2e003053
>>>> +#define MASK_FMAXI_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
>>>> @@ -2718,6 +2784,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(fmini_h, MATCH_FMINI_H, MASK_FMINI_H)
>>>> +DECLARE_INSN(fmaxi_h, MATCH_FMAXI_H, MASK_FMAXI_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(fmini_s, MATCH_FMINI_S, MASK_FMINI_S)
>>>> +DECLARE_INSN(fmaxi_s, MATCH_FMAXI_S, MASK_FMAXI_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(fmini_d, MATCH_FMINI_D, MASK_FMINI_D)
>>>> +DECLARE_INSN(fmaxi_d, MATCH_FMAXI_D, MASK_FMAXI_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(fmini_q, MATCH_FMINI_Q, MASK_FMINI_Q)
>>>> +DECLARE_INSN(fmaxi_q, MATCH_FMAXI_Q, MASK_FMAXI_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 f1dabeaab8e..3e9feaac2a7 100644
>>>> --- a/include/opcode/riscv.h
>>>> +++ b/include/opcode/riscv.h
>>>> @@ -376,6 +376,10 @@ enum riscv_insn_class
>>>>    INSN_CLASS_ZFHMIN_OR_ZHINXMIN,
>>>>    INSN_CLASS_ZFHMIN_AND_D,
>>>>    INSN_CLASS_ZFHMIN_AND_Q,
>>>> +  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,
>>>> @@ -528,6 +532,7 @@ 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_value[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 7ae6e709290..7a8be52281f 100644
>>>> --- a/opcodes/riscv-dis.c
>>>> +++ b/opcodes/riscv-dis.c
>>>> @@ -563,6 +563,13 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
>>>>           print (info->stream, dis_style_text, "%d", rs1);
>>>>           break;
>>>>
>>>> +       case 'i':
>>>> +         if (riscv_fli_value[rs1])
>>>> +           print (info->stream, dis_style_text, "%s", riscv_fli_value[rs1]);
>>>> +         else
>>>> +           print (info->stream, dis_style_immediate, "%d", rs1);
>>>> +         break;
>>>> +
>>>>         default:
>>>>           /* xgettext:c-format */
>>>>           print (info->stream, dis_style_text,
>>>> diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
>>>> index 79be78eb367..eb4da1a7485 100644
>>>> --- a/opcodes/riscv-opc.c
>>>> +++ b/opcodes/riscv-opc.c
>>>> @@ -97,6 +97,15 @@ const char * const riscv_vma[2] =
>>>>    "mu", "ma"
>>>>  };
>>>>
>>>> +/* The FLI.[HSDQ] value constants.  */
>>>> +const char * const riscv_fli_value[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 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
>>>> @@ -636,6 +645,15 @@ const struct riscv_opcode riscv_opcodes[] =
>>>>  {"fcvt.h.l",  64, INSN_CLASS_ZFH_OR_ZHINX,   "D,s,m",     MATCH_FCVT_H_L, MASK_FCVT_H_L, match_opcode, 0 },
>>>>  {"fcvt.h.lu", 64, INSN_CLASS_ZFH_OR_ZHINX,   "D,s",       MATCH_FCVT_H_LU|MASK_RM, MASK_FCVT_H_LU|MASK_RM, match_opcode, 0 },
>>>>  {"fcvt.h.lu", 64, INSN_CLASS_ZFH_OR_ZHINX,   "D,s,m",     MATCH_FCVT_H_LU, MASK_FCVT_H_LU, match_opcode, 0 },
>>>> +{"fli.h",      0, INSN_CLASS_ZFH_AND_ZFA,    "D,i",       MATCH_FLI_H, MASK_FLI_H, match_opcode, 0 },
>>>> +{"fmini.h",    0, INSN_CLASS_ZFH_AND_ZFA,    "D,S,T",     MATCH_FMINI_H, MASK_FMINI_H, match_opcode, 0 },
>>>> +{"fmaxi.h",    0, INSN_CLASS_ZFH_AND_ZFA,    "D,S,T",     MATCH_FMAXI_H, MASK_FMAXI_H, 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 },
>>>> +{"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 },
>>>>
>>>>  /* Single-precision floating-point instruction subset.  */
>>>>  {"frcsr",      0, INSN_CLASS_F_OR_ZFINX,   "d",         MATCH_FRCSR, MASK_FRCSR, match_opcode, INSN_ALIAS },
>>>> @@ -714,7 +732,16 @@ const struct riscv_opcode riscv_opcodes[] =
>>>>  {"fcvt.s.l",  64, INSN_CLASS_F_OR_ZFINX,   "D,s,m",     MATCH_FCVT_S_L, MASK_FCVT_S_L, match_opcode, 0 },
>>>>  {"fcvt.s.lu", 64, INSN_CLASS_F_OR_ZFINX,   "D,s",       MATCH_FCVT_S_LU|MASK_RM, MASK_FCVT_S_LU|MASK_RM, match_opcode, 0 },
>>>>  {"fcvt.s.lu", 64, INSN_CLASS_F_OR_ZFINX,   "D,s,m",     MATCH_FCVT_S_LU, MASK_FCVT_S_LU, match_opcode, 0 },
>>>> -
>>>> +{"fli.s",      0, INSN_CLASS_ZFA,          "D,i",       MATCH_FLI_S, MASK_FLI_S, match_opcode, 0 },
>>>> +{"fmini.s",    0, INSN_CLASS_ZFA,          "D,S,T",     MATCH_FMINI_S, MASK_FMINI_S, match_opcode, 0 },
>>>> +{"fmaxi.s",    0, INSN_CLASS_ZFA,          "D,S,T",     MATCH_FMAXI_S, MASK_FMAXI_S, 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 },
>>>> +{"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 },
>>>> +
>>>>  /* Double-precision floating-point instruction subset.  */
>>>>  {"fld",        0, INSN_CLASS_D_AND_C, "D,Cn(Cc)",  MATCH_C_FLDSP, MASK_C_FLDSP, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
>>>>  {"fld",        0, INSN_CLASS_D_AND_C, "CD,Cl(Cs)", MATCH_C_FLD, MASK_C_FLD, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
>>>> @@ -775,6 +802,18 @@ const struct riscv_opcode riscv_opcodes[] =
>>>>  {"fcvt.d.l",  64, INSN_CLASS_D_OR_ZDINX,   "D,s,m",     MATCH_FCVT_D_L, MASK_FCVT_D_L, match_opcode, 0 },
>>>>  {"fcvt.d.lu", 64, INSN_CLASS_D_OR_ZDINX,   "D,s",       MATCH_FCVT_D_LU|MASK_RM, MASK_FCVT_D_LU|MASK_RM, match_opcode, 0 },
>>>>  {"fcvt.d.lu", 64, INSN_CLASS_D_OR_ZDINX,   "D,s,m",     MATCH_FCVT_D_LU, MASK_FCVT_D_LU, match_opcode, 0 },
>>>> +{"fli.d",       0, INSN_CLASS_D_AND_ZFA,   "D,i",       MATCH_FLI_D, MASK_FLI_D, match_opcode, 0 },
>>>> +{"fmini.d",     0, INSN_CLASS_D_AND_ZFA,   "D,S,T",     MATCH_FMINI_D, MASK_FMINI_D, match_opcode, 0 },
>>>> +{"fmaxi.d",     0, INSN_CLASS_D_AND_ZFA,   "D,S,T",     MATCH_FMAXI_D, MASK_FMAXI_D, 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 },
>>>> +{"fcvtmod.w.d", 0, INSN_CLASS_D_AND_ZFA,   "d,S,m",     MATCH_FCVTMOD_W_D, MASK_FCVTMOD_W_D, 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 },
>>>> +{"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},
>>>>
>>>>  /* Quad-precision floating-point instruction subset.  */
>>>>  {"flq",        0, INSN_CLASS_Q,   "D,o(s)",    MATCH_FLQ, MASK_FLQ, match_opcode, INSN_DREF|INSN_16_BYTE },
>>>> @@ -833,6 +872,17 @@ const struct riscv_opcode riscv_opcodes[] =
>>>>  {"fcvt.q.l",  64, INSN_CLASS_Q_OR_ZQINX,   "D,s,m",     MATCH_FCVT_Q_L, MASK_FCVT_Q_L, match_opcode, 0 },
>>>>  {"fcvt.q.lu", 64, INSN_CLASS_Q_OR_ZQINX,   "D,s",       MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU|MASK_RM, match_opcode, 0 },
>>>>  {"fcvt.q.lu", 64, INSN_CLASS_Q_OR_ZQINX,   "D,s,m",     MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU, match_opcode, 0 },
>>>> +{"fli.q",       0, INSN_CLASS_Q_AND_ZFA,   "D,i",       MATCH_FLI_Q, MASK_FLI_Q, match_opcode, 0 },
>>>> +{"fmini.q",     0, INSN_CLASS_Q_AND_ZFA,   "D,S,T",     MATCH_FMINI_Q, MASK_FMINI_Q, match_opcode, 0 },
>>>> +{"fmaxi.q",     0, INSN_CLASS_Q_AND_ZFA,   "D,S,T",     MATCH_FMAXI_Q, MASK_FMAXI_Q, 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 },
>>>> +{"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 },
>>>> +{"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},
>>>>
>>>>  /* Compressed instructions.  */
>>>>  {"c.unimp",    0, INSN_CLASS_C,   "",          0, 0xffffU,  match_opcode, 0 },
>>>> --
>>>> 2.34.1
>>>>
>>>
> 

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

* Re: [REVIEW ONLY 1/1] UNRATIFIED RISC-V: Add 'Zfa' extension
  2023-03-22 17:00         ` Tsukasa OI
@ 2023-03-23 13:17           ` Kito Cheng
  0 siblings, 0 replies; 10+ messages in thread
From: Kito Cheng @ 2023-03-23 13:17 UTC (permalink / raw)
  To: Tsukasa OI
  Cc: Christoph Müllner, binutils, Philipp Tomsich,
	Andrew Waterman, Jin Ma

c.c. Jin Ma who has proposed GCC patch for Zfa

Some info about fli operand I've discussed with Andrew and Craig Topper:

Some input value of fli might be imprecise (or hard to write precise
by human brain) to write in decimal like 1.0 * 2^-16,
we would like to accept hex floating point format for those values and
reject imprecise values.
e.g.
1.0 * 2^-16 must be 0.0000152587890625, 1.52587890625e-05 or 0x1p-16

And Andrew is happy to mention those 3 forms in the spec once we
confirm GNU toolchain and LLVM
could support all of those forms :)



On Thu, Mar 23, 2023 at 1:01 AM Tsukasa OI via Binutils
<binutils@sourceware.org> wrote:
>
>
>
> On 2023/03/23 1:21, Christoph Müllner wrote:
> > On Wed, Mar 22, 2023 at 5:07 PM Tsukasa OI <research_trasio@irq.a4lg.com> wrote:
> >>
> >> On 2023/03/23 0:47, Christoph Müllner wrote:
> >>> On Sun, Sep 18, 2022 at 12:13 PM Tsukasa OI via Binutils
> >>> <binutils@sourceware.org> wrote:
> >>>>
> >>>> [DO NOT MERGE]
> >>>> Until 'Zfa' extension is frozen/ratified and final version number is
> >>>> determined, this patch should not merged upstream. This commit uses
> >>>> unratified version 0.1 as in documentation (instead of possible 1.0
> >>>> after ratification).
> >>>>
> >>>> This commit adds the 'Zfa' extension (its instructions and new operand
> >>>> type for FLI instructions).
> >>>>
> >>>> This is based on:
> >>>> <https://github.com/riscv/riscv-isa-manual/commit/ae683aec28ec707a3c4bb6f588491f0840d52f43>
> >>>> (latest commit of the 'zfb' branch as of this writing)
> >>>>
> >>>> Note: the author is calling FLI instructions' RS1 encoded field as
> >>>> "value".  It must be reviewed before the specification is frozen.
> >>>>
> >>>> 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:
> >>>>
> >>>>         * testsuite/gas/riscv/zfa.s: New test.
> >>>>         * testsuite/gas/riscv/zfa.d: Likewise.
> >>>>         * testsuite/gas/riscv/zfa-32.s: New test.
> >>>>         * testsuite/gas/riscv/zfa-32.d: Likewise.
> >>>>         * testsuite/gas/riscv/zfa-64.s: New test.
> >>>>         * testsuite/gas/riscv/zfa-64.d: Likewise.
> >>>>         * testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.s: New failure test for
> >>>>         the "fcvtmod.w.d" instruction.
> >>>>         * testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.d: Likewise.
> >>>>         * testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.l: Likewise.
> >>>>         * testsuite/gas/riscv/zfa-fail-fli.s: New failure test for "fli"
> >>>>         instructions.
> >>>>         * testsuite/gas/riscv/zfa-fail-fli.d: Likewise.
> >>>>         * testsuite/gas/riscv/zfa-fail-fli.l: Likewise.
> >>>>
> >>>> include/ChangeLog:
> >>>>
> >>>>         * opcode/riscv-opc.h (MATCH_FLI_H, MASK_FLI_H, MATCH_FMINI_H,
> >>>>         MASK_FMINI_H, MATCH_FMAXI_H, MASK_FMAXI_H, MATCH_FROUND_H,
> >>>>         MASK_FROUND_H, MATCH_FROUNDNX_H, MASK_FROUNDNX_H, MATCH_FLTQ_H,
> >>>>         MASK_FLTQ_H, MATCH_FLEQ_H, MASK_FLEQ_H, MATCH_FLI_S, MASK_FLI_S,
> >>>>         MATCH_FMINI_S, MASK_FMINI_S, MATCH_FMAXI_S, MASK_FMAXI_S,
> >>>>         MATCH_FROUND_S, MASK_FROUND_S, MATCH_FROUNDNX_S, MASK_FROUNDNX_S,
> >>>>         MATCH_FLTQ_S, MASK_FLTQ_S, MATCH_FLEQ_S, MASK_FLEQ_S, MATCH_FLI_D,
> >>>>         MASK_FLI_D, MATCH_FMINI_D, MASK_FMINI_D, MATCH_FMAXI_D,
> >>>>         MASK_FMAXI_D, MATCH_FROUND_D, MASK_FROUND_D, MATCH_FROUNDNX_D,
> >>>>         MASK_FROUNDNX_D, MATCH_FLTQ_D, MASK_FLTQ_D, MATCH_FLEQ_D,
> >>>>         MASK_FLEQ_D, MATCH_FLI_Q, MASK_FLI_Q, MATCH_FMINI_Q, MASK_FMINI_Q,
> >>>>         MATCH_FMAXI_Q, MASK_FMAXI_Q, MATCH_FROUND_Q, MASK_FROUND_Q,
> >>>>         MATCH_FROUNDNX_Q, MASK_FROUNDNX_Q, MATCH_FLTQ_Q, MASK_FLTQ_Q,
> >>>>         MATCH_FLEQ_Q, MASK_FLEQ_Q, MATCH_FCVTMOD_W_D, MASK_FCVTMOD_W_D,
> >>>>         MATCH_FMVH_X_D, MASK_FMVH_X_D, MATCH_FMVH_X_Q, MASK_FMVH_X_Q,
> >>>>         MATCH_FMVP_D_X, MASK_FMVP_D_X, MATCH_FMVP_Q_X, MASK_FMVP_Q_X): New.
> >>>>         * opcode/riscv.h (enum riscv_insn_class): Add instruction
> >>>>         classes for 'Zfa' extension.
> >>>>
> >>>> opcodes/ChangeLog:
> >>>>
> >>>>         * riscv-opc.c (riscv_opcodes): Add 'Zfa' instructions.
> >>>> ---
> >>>>  bfd/elfxx-riscv.c                             | 39 ++++++++
> >>>>  gas/config/tc-riscv.c                         | 21 ++++
> >>>>  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/riscv/zfa-fail-fcvtmod.w.d.d          |  3 +
> >>>>  .../gas/riscv/zfa-fail-fcvtmod.w.d.l          |  8 ++
> >>>>  .../gas/riscv/zfa-fail-fcvtmod.w.d.s          | 11 +++
> >>>>  gas/testsuite/gas/riscv/zfa-fail-fli.d        |  3 +
> >>>>  gas/testsuite/gas/riscv/zfa-fail-fli.l        | 21 ++++
> >>>>  gas/testsuite/gas/riscv/zfa-fail-fli.s        | 21 ++++
> >>>>  gas/testsuite/gas/riscv/zfa.d                 | 93 +++++++++++++++++
> >>>>  gas/testsuite/gas/riscv/zfa.s                 | 92 +++++++++++++++++
> >>>>  include/opcode/riscv-opc.h                    | 99 +++++++++++++++++++
> >>>>  include/opcode/riscv.h                        |  5 +
> >>>>  opcodes/riscv-dis.c                           |  7 ++
> >>>>  opcodes/riscv-opc.c                           | 52 +++++++++-
> >>>>  18 files changed, 500 insertions(+), 1 deletion(-)
> >>>>  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-fcvtmod.w.d.d
> >>>>  create mode 100644 gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.l
> >>>>  create mode 100644 gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.s
> >>>>  create mode 100644 gas/testsuite/gas/riscv/zfa-fail-fli.d
> >>>>  create mode 100644 gas/testsuite/gas/riscv/zfa-fail-fli.l
> >>>>  create mode 100644 gas/testsuite/gas/riscv/zfa-fail-fli.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 e03b312a381..1c6d1505d54 100644
> >>>> --- a/bfd/elfxx-riscv.c
> >>>> +++ b/bfd/elfxx-riscv.c
> >>>> @@ -1073,6 +1073,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},
> >>>> @@ -1162,6 +1163,7 @@ static struct riscv_supported_ext riscv_supported_std_z_ext[] =
> >>>>    {"zifencei",         ISA_SPEC_CLASS_20190608,        2, 0,  0 },
> >>>>    {"zihintpause",      ISA_SPEC_CLASS_DRAFT,           2, 0,  0 },
> >>>>    {"zmmul",            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 },
> >>>> @@ -2334,6 +2336,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:
> >>>> @@ -2469,6 +2482,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 2f5ee18e451..ffbc7fbdda2 100644
> >>>> --- a/gas/config/tc-riscv.c
> >>>> +++ b/gas/config/tc-riscv.c
> >>>> @@ -1208,6 +1208,7 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
> >>>>         case 'd': USE_BITS (OP_MASK_RD, OP_SH_RD); break;
> >>>>         case 'y': USE_BITS (OP_MASK_BS, OP_SH_BS); break;
> >>>>         case 'Y': USE_BITS (OP_MASK_RNUM, OP_SH_RNUM); break;
> >>>> +       case 'i': /* RS1, FLI.[HSDQ] value field.  */
> >>>>         case 'Z': /* RS1, CSR number.  */
> >>>>         case 'S': /* RS1, floating point.  */
> >>>>         case 's': USE_BITS (OP_MASK_RS1, OP_SH_RS1); break;
> >>>> @@ -3262,6 +3263,26 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
> >>>>               asarg = expr_end;
> >>>>               continue;
> >>>>
> >>>> +           case 'i': /* FLI.[HSDQ] constant immediate.  */
> >>>> +             if (arg_lookup (&asarg, riscv_fli_value,
> >>>> +                             ARRAY_SIZE (riscv_fli_value), &regno))
> >>>> +               INSERT_OPERAND (RS1, *ip, regno);
> >>>> +             else
> >>>> +               {
> >>>> +                 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
> >>>> +                     || imm_expr->X_op != O_constant)
> >>>> +                   break;
> >>>> +                 if (imm_expr->X_add_number < 0
> >>>> +                     || imm_expr->X_add_number > 29)
> >>>> +                   as_bad (_ ("improper fli value field (%ld), "
> >>>> +                              "value must be 0...29 or min, inf or nan"),
> >>>> +                           (long) imm_expr->X_add_number);
> >>>> +                 INSERT_OPERAND (RS1, *ip, imm_expr->X_add_number);
> >>>> +                 imm_expr->X_op = O_absent;
> >>>> +                 asarg = expr_end;
> >>>> +               }
> >>>> +             continue;
> >>>> +
> >>>>             default:
> >>>>             unknown_riscv_ip_operand:
> >>>>               as_fatal (_("internal: unknown argument type `%s'"),
> >>>> diff --git a/gas/testsuite/gas/riscv/zfa-32.d b/gas/testsuite/gas/riscv/zfa-32.d
> >>>> new file mode 100644
> >>>> index 00000000000..0f0cbfcdc70
> >>>> --- /dev/null
> >>>> +++ b/gas/testsuite/gas/riscv/zfa-32.d
> >>>> @@ -0,0 +1,10 @@
> >>>> +#as: -march=rv32id_zfa
> >>>> +#objdump: -dr
> >>>> +
> >>>> +.*:[   ]+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..f942d616959
> >>>> --- /dev/null
> >>>> +++ b/gas/testsuite/gas/riscv/zfa-64.d
> >>>> @@ -0,0 +1,10 @@
> >>>> +#as: -march=rv64iq_zfa
> >>>> +#objdump: -dr
> >>>> +
> >>>> +.*:[   ]+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-fcvtmod.w.d.d b/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.d
> >>>> new file mode 100644
> >>>> index 00000000000..5234c49de75
> >>>> --- /dev/null
> >>>> +++ b/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.d
> >>>> @@ -0,0 +1,3 @@
> >>>> +#as: -march=rv64id_zfa
> >>>> +#objdump: -dr
> >>>> +#error_output: zfa-fail-fcvtmod.w.d.l
> >>>> diff --git a/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.l b/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.l
> >>>> new file mode 100644
> >>>> index 00000000000..4ea048a3356
> >>>> --- /dev/null
> >>>> +++ b/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.l
> >>>> @@ -0,0 +1,8 @@
> >>>> +.*: Assembler messages:
> >>>> +.*: 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-fcvtmod.w.d.s b/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.s
> >>>> new file mode 100644
> >>>> index 00000000000..5984f6676d8
> >>>> --- /dev/null
> >>>> +++ b/gas/testsuite/gas/riscv/zfa-fail-fcvtmod.w.d.s
> >>>> @@ -0,0 +1,11 @@
> >>>> +target:
> >>>> +       # fcvtmod.w.d requires explicit rounding mode.
> >>>> +       fcvtmod.w.d     a0, ft1
> >>>> +       # 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
> >>>> +       # Invalid rounding mode is invalid.
> >>>> +       fcvtmod.w.d     a0, ft1, invalid
> >>>> diff --git a/gas/testsuite/gas/riscv/zfa-fail-fli.d b/gas/testsuite/gas/riscv/zfa-fail-fli.d
> >>>> new file mode 100644
> >>>> index 00000000000..3753a4d185e
> >>>> --- /dev/null
> >>>> +++ b/gas/testsuite/gas/riscv/zfa-fail-fli.d
> >>>> @@ -0,0 +1,3 @@
> >>>> +#as: -march=rv64iq_zfa_zfh
> >>>> +#objdump: -dr
> >>>> +#error_output: zfa-fail-fli.l
> >>>> diff --git a/gas/testsuite/gas/riscv/zfa-fail-fli.l b/gas/testsuite/gas/riscv/zfa-fail-fli.l
> >>>> new file mode 100644
> >>>> index 00000000000..b7532f80fd4
> >>>> --- /dev/null
> >>>> +++ b/gas/testsuite/gas/riscv/zfa-fail-fli.l
> >>>> @@ -0,0 +1,21 @@
> >>>> +.*: Assembler messages:
> >>>> +.*: Error: improper fli value field \(-1\), value must be 0\.\.\.29 or min, inf or nan
> >>>> +.*: Error: improper fli value field \(-1\), value must be 0\.\.\.29 or min, inf or nan
> >>>> +.*: Error: improper fli value field \(-1\), value must be 0\.\.\.29 or min, inf or nan
> >>>> +.*: Error: improper fli value field \(-1\), value must be 0\.\.\.29 or min, inf or nan
> >>>> +.*: Error: improper fli value field \(-2\), value must be 0\.\.\.29 or min, inf or nan
> >>>> +.*: Error: improper fli value field \(-2\), value must be 0\.\.\.29 or min, inf or nan
> >>>> +.*: Error: improper fli value field \(-2\), value must be 0\.\.\.29 or min, inf or nan
> >>>> +.*: Error: improper fli value field \(-2\), value must be 0\.\.\.29 or min, inf or nan
> >>>> +.*: Error: improper fli value field \(30\), value must be 0\.\.\.29 or min, inf or nan
> >>>> +.*: Error: improper fli value field \(30\), value must be 0\.\.\.29 or min, inf or nan
> >>>> +.*: Error: improper fli value field \(30\), value must be 0\.\.\.29 or min, inf or nan
> >>>> +.*: Error: improper fli value field \(30\), value must be 0\.\.\.29 or min, inf or nan
> >>>> +.*: Error: improper fli value field \(32\), value must be 0\.\.\.29 or min, inf or nan
> >>>> +.*: Error: improper fli value field \(32\), value must be 0\.\.\.29 or min, inf or nan
> >>>> +.*: Error: improper fli value field \(32\), value must be 0\.\.\.29 or min, inf or nan
> >>>> +.*: Error: improper fli value field \(32\), value must be 0\.\.\.29 or min, inf or nan
> >>>> +.*: Error: illegal operands `fli\.h ft1,invalid'
> >>>> +.*: Error: illegal operands `fli\.s ft1,invalid'
> >>>> +.*: Error: illegal operands `fli\.d ft1,invalid'
> >>>> +.*: Error: illegal operands `fli\.q ft1,invalid'
> >>>> diff --git a/gas/testsuite/gas/riscv/zfa-fail-fli.s b/gas/testsuite/gas/riscv/zfa-fail-fli.s
> >>>> new file mode 100644
> >>>> index 00000000000..4c600b5d578
> >>>> --- /dev/null
> >>>> +++ b/gas/testsuite/gas/riscv/zfa-fail-fli.s
> >>>> @@ -0,0 +1,21 @@
> >>>> +target:
> >>>> +       fli.h   ft1, -1
> >>>> +       fli.s   ft1, -1
> >>>> +       fli.d   ft1, -1
> >>>> +       fli.q   ft1, -1
> >>>> +       fli.h   ft1, -2
> >>>> +       fli.s   ft1, -2
> >>>> +       fli.d   ft1, -2
> >>>> +       fli.q   ft1, -2
> >>>> +       fli.h   ft1, 30
> >>>> +       fli.s   ft1, 30
> >>>> +       fli.d   ft1, 30
> >>>> +       fli.q   ft1, 30
> >>>> +       fli.h   ft1, 32
> >>>> +       fli.s   ft1, 32
> >>>> +       fli.d   ft1, 32
> >>>> +       fli.q   ft1, 32
> >>>> +       fli.h   ft1, invalid
> >>>> +       fli.s   ft1, invalid
> >>>> +       fli.d   ft1, invalid
> >>>> +       fli.q   ft1, invalid
> >>>> diff --git a/gas/testsuite/gas/riscv/zfa.d b/gas/testsuite/gas/riscv/zfa.d
> >>>> new file mode 100644
> >>>> index 00000000000..3701a41e485
> >>>> --- /dev/null
> >>>> +++ b/gas/testsuite/gas/riscv/zfa.d
> >>>> @@ -0,0 +1,93 @@
> >>>> +#as: -march=rv64iq_zfa_zfh
> >>>> +#objdump: -dr
> >>>> +
> >>>> +.*:[   ]+file format .*
> >>>> +
> >>>> +Disassembly of section .text:
> >>>> +
> >>>> +0+000 <target>:
> >>>
> >>> Hi Tsukasa,
> >>>
> >>> There seems to be a misunderstanding of the spec.
> >>> The second operand of the fli should be the constant itself ("Value"
> >>> column of the specification) in C-like syntax.
> >>> E.g.:
> >>>   fli.h ft1, -1.0 # encoding rs1=0
> >>>   fli.h ft1, min # encoding rs1=1
> >>>   fli.h ft1, 0.0000152587890625 # encoding rs1=2
> >>>   ...
> >>>   fli.h ft1, 16 # encoding rs1=25
> >>>   ...
> >>>   fli.h ft1, nan # encoding rs1=31
> >>>
> >>> So we have 3 strings ("min", "inf", "nan") and 29 constants.
> >>>
> >>> BR
> >>> Christoph
> >>
> >> Hi,
> >>
> >> I showed very early patchset of 'Zfa' to Andrew and I misunderstood that
> >> he was okay with that operands.  Now the situation is clearer but due to
> >> my poor health conditions, it might not be soon to make a new patchset
> >> (I'm working on it but the progress is very slow).  If my new patchset
> >> for 'Zfa' isn't posted until mid-May, it'll be better that someone else
> >> make their 'Zfa' patchset.
> >
> > We are working on a couple of other Zfa enablement patches and we need
> > a solution earlier than mid-May (we target the end of this month).
> > Is it ok for you if I take over the patch and add you as Co-developed-by?0
> > I would also use your "RISC-V: Allocate "various" operand type" commit as base.
> >
> > Get well soon!
> >
> > BR
> > Christoph
>
> Of course!
>
> > I would also use your "RISC-V: Allocate "various" operand type" commit as base.
>
> Yes, that would be important more than I first thought because current
> design would require four "fli" constant operands.
>
> Thanks and I hope that I'm back online in June,
> Tsukasa
>
> >
> >>
> >> Tsukasa
> >>
> >>>
> >>>> +[      ]+[0-9a-f]+:[   ]+f41000d3[     ]+fli\.h[               ]+ft1,0
> >>>> +[      ]+[0-9a-f]+:[   ]+f41080d3[     ]+fli\.h[               ]+ft1,min
> >>>> +[      ]+[0-9a-f]+:[   ]+f41100d3[     ]+fli\.h[               ]+ft1,2
> >>>> +[      ]+[0-9a-f]+:[   ]+f41d80d3[     ]+fli\.h[               ]+ft1,27
> >>>> +[      ]+[0-9a-f]+:[   ]+f41e00d3[     ]+fli\.h[               ]+ft1,28
> >>>> +[      ]+[0-9a-f]+:[   ]+f41e80d3[     ]+fli\.h[               ]+ft1,29
> >>>> +[      ]+[0-9a-f]+:[   ]+f41080d3[     ]+fli\.h[               ]+ft1,min
> >>>> +[      ]+[0-9a-f]+:[   ]+f41f00d3[     ]+fli\.h[               ]+ft1,inf
> >>>> +[      ]+[0-9a-f]+:[   ]+f41f80d3[     ]+fli\.h[               ]+ft1,nan
> >>>> +[      ]+[0-9a-f]+:[   ]+f01000d3[     ]+fli\.s[               ]+ft1,0
> >>>> +[      ]+[0-9a-f]+:[   ]+f01080d3[     ]+fli\.s[               ]+ft1,min
> >>>> +[      ]+[0-9a-f]+:[   ]+f01100d3[     ]+fli\.s[               ]+ft1,2
> >>>> +[      ]+[0-9a-f]+:[   ]+f01d80d3[     ]+fli\.s[               ]+ft1,27
> >>>> +[      ]+[0-9a-f]+:[   ]+f01e00d3[     ]+fli\.s[               ]+ft1,28
> >>>> +[      ]+[0-9a-f]+:[   ]+f01e80d3[     ]+fli\.s[               ]+ft1,29
> >>>> +[      ]+[0-9a-f]+:[   ]+f01080d3[     ]+fli\.s[               ]+ft1,min
> >>>> +[      ]+[0-9a-f]+:[   ]+f01f00d3[     ]+fli\.s[               ]+ft1,inf
> >>>> +[      ]+[0-9a-f]+:[   ]+f01f80d3[     ]+fli\.s[               ]+ft1,nan
> >>>> +[      ]+[0-9a-f]+:[   ]+f21000d3[     ]+fli\.d[               ]+ft1,0
> >>>> +[      ]+[0-9a-f]+:[   ]+f21080d3[     ]+fli\.d[               ]+ft1,min
> >>>> +[      ]+[0-9a-f]+:[   ]+f21100d3[     ]+fli\.d[               ]+ft1,2
> >>>> +[      ]+[0-9a-f]+:[   ]+f21d80d3[     ]+fli\.d[               ]+ft1,27
> >>>> +[      ]+[0-9a-f]+:[   ]+f21e00d3[     ]+fli\.d[               ]+ft1,28
> >>>> +[      ]+[0-9a-f]+:[   ]+f21e80d3[     ]+fli\.d[               ]+ft1,29
> >>>> +[      ]+[0-9a-f]+:[   ]+f21080d3[     ]+fli\.d[               ]+ft1,min
> >>>> +[      ]+[0-9a-f]+:[   ]+f21f00d3[     ]+fli\.d[               ]+ft1,inf
> >>>> +[      ]+[0-9a-f]+:[   ]+f21f80d3[     ]+fli\.d[               ]+ft1,nan
> >>>> +[      ]+[0-9a-f]+:[   ]+f61000d3[     ]+fli\.q[               ]+ft1,0
> >>>> +[      ]+[0-9a-f]+:[   ]+f61080d3[     ]+fli\.q[               ]+ft1,min
> >>>> +[      ]+[0-9a-f]+:[   ]+f61100d3[     ]+fli\.q[               ]+ft1,2
> >>>> +[      ]+[0-9a-f]+:[   ]+f61d80d3[     ]+fli\.q[               ]+ft1,27
> >>>> +[      ]+[0-9a-f]+:[   ]+f61e00d3[     ]+fli\.q[               ]+ft1,28
> >>>> +[      ]+[0-9a-f]+:[   ]+f61e80d3[     ]+fli\.q[               ]+ft1,29
> >>>> +[      ]+[0-9a-f]+:[   ]+f61080d3[     ]+fli\.q[               ]+ft1,min
> >>>> +[      ]+[0-9a-f]+:[   ]+f61f00d3[     ]+fli\.q[               ]+ft1,inf
> >>>> +[      ]+[0-9a-f]+:[   ]+f61f80d3[     ]+fli\.q[               ]+ft1,nan
> >>>> +[      ]+[0-9a-f]+:[   ]+2c3100d3[     ]+fmin\.h[              ]+ft1,ft2,ft3
> >>>> +[      ]+[0-9a-f]+:[   ]+2c3120d3[     ]+fmini\.h[             ]+ft1,ft2,ft3
> >>>> +[      ]+[0-9a-f]+:[   ]+283100d3[     ]+fmin\.s[              ]+ft1,ft2,ft3
> >>>> +[      ]+[0-9a-f]+:[   ]+283120d3[     ]+fmini\.s[             ]+ft1,ft2,ft3
> >>>> +[      ]+[0-9a-f]+:[   ]+2a3100d3[     ]+fmin\.d[              ]+ft1,ft2,ft3
> >>>> +[      ]+[0-9a-f]+:[   ]+2a3120d3[     ]+fmini\.d[             ]+ft1,ft2,ft3
> >>>> +[      ]+[0-9a-f]+:[   ]+2e3100d3[     ]+fmin\.q[              ]+ft1,ft2,ft3
> >>>> +[      ]+[0-9a-f]+:[   ]+2e3120d3[     ]+fmini\.q[             ]+ft1,ft2,ft3
> >>>> +[      ]+[0-9a-f]+:[   ]+2c3110d3[     ]+fmax\.h[              ]+ft1,ft2,ft3
> >>>> +[      ]+[0-9a-f]+:[   ]+2c3130d3[     ]+fmaxi\.h[             ]+ft1,ft2,ft3
> >>>> +[      ]+[0-9a-f]+:[   ]+283110d3[     ]+fmax\.s[              ]+ft1,ft2,ft3
> >>>> +[      ]+[0-9a-f]+:[   ]+283130d3[     ]+fmaxi\.s[             ]+ft1,ft2,ft3
> >>>> +[      ]+[0-9a-f]+:[   ]+2a3110d3[     ]+fmax\.d[              ]+ft1,ft2,ft3
> >>>> +[      ]+[0-9a-f]+:[   ]+2a3130d3[     ]+fmaxi\.d[             ]+ft1,ft2,ft3
> >>>> +[      ]+[0-9a-f]+:[   ]+2e3110d3[     ]+fmax\.q[              ]+ft1,ft2,ft3
> >>>> +[      ]+[0-9a-f]+:[   ]+2e3130d3[     ]+fmaxi\.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..fb79792bf10
> >>>> --- /dev/null
> >>>> +++ b/gas/testsuite/gas/riscv/zfa.s
> >>>> @@ -0,0 +1,92 @@
> >>>> +target:
> >>>> +       # fli: test both decimal and symbol representations
> >>>> +       #      (0..29, min==1, inf==(30), nan==(31))
> >>>> +       fli.h           ft1, 0
> >>>> +       fli.h           ft1, 1
> >>>> +       fli.h           ft1, 2
> >>>> +       fli.h           ft1, 27
> >>>> +       fli.h           ft1, 28
> >>>> +       fli.h           ft1, 29
> >>>> +       fli.h           ft1, min
> >>>> +       fli.h           ft1, inf
> >>>> +       fli.h           ft1, nan
> >>>> +       fli.s           ft1, 0
> >>>> +       fli.s           ft1, 1
> >>>> +       fli.s           ft1, 2
> >>>> +       fli.s           ft1, 27
> >>>> +       fli.s           ft1, 28
> >>>> +       fli.s           ft1, 29
> >>>> +       fli.s           ft1, min
> >>>> +       fli.s           ft1, inf
> >>>> +       fli.s           ft1, nan
> >>>> +       fli.d           ft1, 0
> >>>> +       fli.d           ft1, 1
> >>>> +       fli.d           ft1, 2
> >>>> +       fli.d           ft1, 27
> >>>> +       fli.d           ft1, 28
> >>>> +       fli.d           ft1, 29
> >>>> +       fli.d           ft1, min
> >>>> +       fli.d           ft1, inf
> >>>> +       fli.d           ft1, nan
> >>>> +       fli.q           ft1, 0
> >>>> +       fli.q           ft1, 1
> >>>> +       fli.q           ft1, 2
> >>>> +       fli.q           ft1, 27
> >>>> +       fli.q           ft1, 28
> >>>> +       fli.q           ft1, 29
> >>>> +       fli.q           ft1, min
> >>>> +       fli.q           ft1, inf
> >>>> +       fli.q           ft1, nan
> >>>> +       # fmini/fmaxi (Zfa): same as fmin/fmax (Zfh/F/D/Q) except bit 13 set
> >>>> +       fmin.h          ft1, ft2, ft3
> >>>> +       fmini.h         ft1, ft2, ft3
> >>>> +       fmin.s          ft1, ft2, ft3
> >>>> +       fmini.s         ft1, ft2, ft3
> >>>> +       fmin.d          ft1, ft2, ft3
> >>>> +       fmini.d         ft1, ft2, ft3
> >>>> +       fmin.q          ft1, ft2, ft3
> >>>> +       fmini.q         ft1, ft2, ft3
> >>>> +       fmax.h          ft1, ft2, ft3
> >>>> +       fmaxi.h         ft1, ft2, ft3
> >>>> +       fmax.s          ft1, ft2, ft3
> >>>> +       fmaxi.s         ft1, ft2, ft3
> >>>> +       fmax.d          ft1, ft2, ft3
> >>>> +       fmaxi.d         ft1, ft2, ft3
> >>>> +       fmax.q          ft1, ft2, ft3
> >>>> +       fmaxi.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 (Zfa): same as flt/fle (Zfh/F/D/Q) except bit 14 set
> >>>> +       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 88b8d7ff595..9739ad24538 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_FMINI_H 0x2c002053
> >>>> +#define MASK_FMINI_H 0xfe00707f
> >>>> +#define MATCH_FMAXI_H 0x2c003053
> >>>> +#define MASK_FMAXI_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_FMINI_S 0x28002053
> >>>> +#define MASK_FMINI_S 0xfe00707f
> >>>> +#define MATCH_FMAXI_S 0x28003053
> >>>> +#define MASK_FMAXI_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_FMINI_D 0x2a002053
> >>>> +#define MASK_FMINI_D 0xfe00707f
> >>>> +#define MATCH_FMAXI_D 0x2a003053
> >>>> +#define MASK_FMAXI_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_FMINI_Q 0x2e002053
> >>>> +#define MASK_FMINI_Q 0xfe00707f
> >>>> +#define MATCH_FMAXI_Q 0x2e003053
> >>>> +#define MASK_FMAXI_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
> >>>> @@ -2718,6 +2784,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(fmini_h, MATCH_FMINI_H, MASK_FMINI_H)
> >>>> +DECLARE_INSN(fmaxi_h, MATCH_FMAXI_H, MASK_FMAXI_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(fmini_s, MATCH_FMINI_S, MASK_FMINI_S)
> >>>> +DECLARE_INSN(fmaxi_s, MATCH_FMAXI_S, MASK_FMAXI_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(fmini_d, MATCH_FMINI_D, MASK_FMINI_D)
> >>>> +DECLARE_INSN(fmaxi_d, MATCH_FMAXI_D, MASK_FMAXI_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(fmini_q, MATCH_FMINI_Q, MASK_FMINI_Q)
> >>>> +DECLARE_INSN(fmaxi_q, MATCH_FMAXI_Q, MASK_FMAXI_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 f1dabeaab8e..3e9feaac2a7 100644
> >>>> --- a/include/opcode/riscv.h
> >>>> +++ b/include/opcode/riscv.h
> >>>> @@ -376,6 +376,10 @@ enum riscv_insn_class
> >>>>    INSN_CLASS_ZFHMIN_OR_ZHINXMIN,
> >>>>    INSN_CLASS_ZFHMIN_AND_D,
> >>>>    INSN_CLASS_ZFHMIN_AND_Q,
> >>>> +  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,
> >>>> @@ -528,6 +532,7 @@ 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_value[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 7ae6e709290..7a8be52281f 100644
> >>>> --- a/opcodes/riscv-dis.c
> >>>> +++ b/opcodes/riscv-dis.c
> >>>> @@ -563,6 +563,13 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
> >>>>           print (info->stream, dis_style_text, "%d", rs1);
> >>>>           break;
> >>>>
> >>>> +       case 'i':
> >>>> +         if (riscv_fli_value[rs1])
> >>>> +           print (info->stream, dis_style_text, "%s", riscv_fli_value[rs1]);
> >>>> +         else
> >>>> +           print (info->stream, dis_style_immediate, "%d", rs1);
> >>>> +         break;
> >>>> +
> >>>>         default:
> >>>>           /* xgettext:c-format */
> >>>>           print (info->stream, dis_style_text,
> >>>> diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
> >>>> index 79be78eb367..eb4da1a7485 100644
> >>>> --- a/opcodes/riscv-opc.c
> >>>> +++ b/opcodes/riscv-opc.c
> >>>> @@ -97,6 +97,15 @@ const char * const riscv_vma[2] =
> >>>>    "mu", "ma"
> >>>>  };
> >>>>
> >>>> +/* The FLI.[HSDQ] value constants.  */
> >>>> +const char * const riscv_fli_value[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 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
> >>>> @@ -636,6 +645,15 @@ const struct riscv_opcode riscv_opcodes[] =
> >>>>  {"fcvt.h.l",  64, INSN_CLASS_ZFH_OR_ZHINX,   "D,s,m",     MATCH_FCVT_H_L, MASK_FCVT_H_L, match_opcode, 0 },
> >>>>  {"fcvt.h.lu", 64, INSN_CLASS_ZFH_OR_ZHINX,   "D,s",       MATCH_FCVT_H_LU|MASK_RM, MASK_FCVT_H_LU|MASK_RM, match_opcode, 0 },
> >>>>  {"fcvt.h.lu", 64, INSN_CLASS_ZFH_OR_ZHINX,   "D,s,m",     MATCH_FCVT_H_LU, MASK_FCVT_H_LU, match_opcode, 0 },
> >>>> +{"fli.h",      0, INSN_CLASS_ZFH_AND_ZFA,    "D,i",       MATCH_FLI_H, MASK_FLI_H, match_opcode, 0 },
> >>>> +{"fmini.h",    0, INSN_CLASS_ZFH_AND_ZFA,    "D,S,T",     MATCH_FMINI_H, MASK_FMINI_H, match_opcode, 0 },
> >>>> +{"fmaxi.h",    0, INSN_CLASS_ZFH_AND_ZFA,    "D,S,T",     MATCH_FMAXI_H, MASK_FMAXI_H, 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 },
> >>>> +{"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 },
> >>>>
> >>>>  /* Single-precision floating-point instruction subset.  */
> >>>>  {"frcsr",      0, INSN_CLASS_F_OR_ZFINX,   "d",         MATCH_FRCSR, MASK_FRCSR, match_opcode, INSN_ALIAS },
> >>>> @@ -714,7 +732,16 @@ const struct riscv_opcode riscv_opcodes[] =
> >>>>  {"fcvt.s.l",  64, INSN_CLASS_F_OR_ZFINX,   "D,s,m",     MATCH_FCVT_S_L, MASK_FCVT_S_L, match_opcode, 0 },
> >>>>  {"fcvt.s.lu", 64, INSN_CLASS_F_OR_ZFINX,   "D,s",       MATCH_FCVT_S_LU|MASK_RM, MASK_FCVT_S_LU|MASK_RM, match_opcode, 0 },
> >>>>  {"fcvt.s.lu", 64, INSN_CLASS_F_OR_ZFINX,   "D,s,m",     MATCH_FCVT_S_LU, MASK_FCVT_S_LU, match_opcode, 0 },
> >>>> -
> >>>> +{"fli.s",      0, INSN_CLASS_ZFA,          "D,i",       MATCH_FLI_S, MASK_FLI_S, match_opcode, 0 },
> >>>> +{"fmini.s",    0, INSN_CLASS_ZFA,          "D,S,T",     MATCH_FMINI_S, MASK_FMINI_S, match_opcode, 0 },
> >>>> +{"fmaxi.s",    0, INSN_CLASS_ZFA,          "D,S,T",     MATCH_FMAXI_S, MASK_FMAXI_S, 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 },
> >>>> +{"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 },
> >>>> +
> >>>>  /* Double-precision floating-point instruction subset.  */
> >>>>  {"fld",        0, INSN_CLASS_D_AND_C, "D,Cn(Cc)",  MATCH_C_FLDSP, MASK_C_FLDSP, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
> >>>>  {"fld",        0, INSN_CLASS_D_AND_C, "CD,Cl(Cs)", MATCH_C_FLD, MASK_C_FLD, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
> >>>> @@ -775,6 +802,18 @@ const struct riscv_opcode riscv_opcodes[] =
> >>>>  {"fcvt.d.l",  64, INSN_CLASS_D_OR_ZDINX,   "D,s,m",     MATCH_FCVT_D_L, MASK_FCVT_D_L, match_opcode, 0 },
> >>>>  {"fcvt.d.lu", 64, INSN_CLASS_D_OR_ZDINX,   "D,s",       MATCH_FCVT_D_LU|MASK_RM, MASK_FCVT_D_LU|MASK_RM, match_opcode, 0 },
> >>>>  {"fcvt.d.lu", 64, INSN_CLASS_D_OR_ZDINX,   "D,s,m",     MATCH_FCVT_D_LU, MASK_FCVT_D_LU, match_opcode, 0 },
> >>>> +{"fli.d",       0, INSN_CLASS_D_AND_ZFA,   "D,i",       MATCH_FLI_D, MASK_FLI_D, match_opcode, 0 },
> >>>> +{"fmini.d",     0, INSN_CLASS_D_AND_ZFA,   "D,S,T",     MATCH_FMINI_D, MASK_FMINI_D, match_opcode, 0 },
> >>>> +{"fmaxi.d",     0, INSN_CLASS_D_AND_ZFA,   "D,S,T",     MATCH_FMAXI_D, MASK_FMAXI_D, 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 },
> >>>> +{"fcvtmod.w.d", 0, INSN_CLASS_D_AND_ZFA,   "d,S,m",     MATCH_FCVTMOD_W_D, MASK_FCVTMOD_W_D, 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 },
> >>>> +{"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},
> >>>>
> >>>>  /* Quad-precision floating-point instruction subset.  */
> >>>>  {"flq",        0, INSN_CLASS_Q,   "D,o(s)",    MATCH_FLQ, MASK_FLQ, match_opcode, INSN_DREF|INSN_16_BYTE },
> >>>> @@ -833,6 +872,17 @@ const struct riscv_opcode riscv_opcodes[] =
> >>>>  {"fcvt.q.l",  64, INSN_CLASS_Q_OR_ZQINX,   "D,s,m",     MATCH_FCVT_Q_L, MASK_FCVT_Q_L, match_opcode, 0 },
> >>>>  {"fcvt.q.lu", 64, INSN_CLASS_Q_OR_ZQINX,   "D,s",       MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU|MASK_RM, match_opcode, 0 },
> >>>>  {"fcvt.q.lu", 64, INSN_CLASS_Q_OR_ZQINX,   "D,s,m",     MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU, match_opcode, 0 },
> >>>> +{"fli.q",       0, INSN_CLASS_Q_AND_ZFA,   "D,i",       MATCH_FLI_Q, MASK_FLI_Q, match_opcode, 0 },
> >>>> +{"fmini.q",     0, INSN_CLASS_Q_AND_ZFA,   "D,S,T",     MATCH_FMINI_Q, MASK_FMINI_Q, match_opcode, 0 },
> >>>> +{"fmaxi.q",     0, INSN_CLASS_Q_AND_ZFA,   "D,S,T",     MATCH_FMAXI_Q, MASK_FMAXI_Q, 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 },
> >>>> +{"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 },
> >>>> +{"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},
> >>>>
> >>>>  /* Compressed instructions.  */
> >>>>  {"c.unimp",    0, INSN_CLASS_C,   "",          0, 0xffffU,  match_opcode, 0 },
> >>>> --
> >>>> 2.34.1
> >>>>
> >>>
> >

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

* Re: [REVIEW ONLY 1/1] UNRATIFIED RISC-V: Add 'Zfa' extension
  2023-03-22 15:47   ` Christoph Müllner
  2023-03-22 16:01     ` Philipp Tomsich
  2023-03-22 16:07     ` Tsukasa OI
@ 2023-03-26 15:43     ` Jeff Law
  2023-03-27  0:13       ` Philipp Tomsich
  2 siblings, 1 reply; 10+ messages in thread
From: Jeff Law @ 2023-03-26 15:43 UTC (permalink / raw)
  To: Christoph Müllner, Tsukasa OI
  Cc: binutils, Philipp Tomsich, Andrew Waterman



On 3/22/23 09:47, Christoph Müllner wrote:

> 
> Hi Tsukasa,
> 
> There seems to be a misunderstanding of the spec.
> The second operand of the fli should be the constant itself ("Value"
> column of the specification) in C-like syntax.
> E.g.:
>    fli.h ft1, -1.0 # encoding rs1=0
>    fli.h ft1, min # encoding rs1=1
>    fli.h ft1, 0.0000152587890625 # encoding rs1=2
>    ...
>    fli.h ft1, 16 # encoding rs1=25
>    ...
>    fli.h ft1, nan # encoding rs1=31
> 
> So we have 3 strings ("min", "inf", "nan") and 29 constants.
Ouch.  So we've got to parse & match the actual constant.  I worked on a 
processor with similar capabilities, but we defined the assembly syntax 
to use the table index for the constant rather than the constant itself.

I'd strongly suggest supporting the %a/%A hex notation for the 
constants.  It's unambiguous and less error prone.  I think Kito made a 
similar suggestion downthread.

When I read through the basics of Zfa I was a bit disappointed.  99% of 
the time the fli is going to feed one or more FP arithmetic 
instructions.  It'd be more efficient to be able to access those FP 
constants in the FP arithmetic instruction itself.  I guess that ship 
has sailed.

Jeff

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

* Re: [REVIEW ONLY 1/1] UNRATIFIED RISC-V: Add 'Zfa' extension
  2023-03-26 15:43     ` Jeff Law
@ 2023-03-27  0:13       ` Philipp Tomsich
  0 siblings, 0 replies; 10+ messages in thread
From: Philipp Tomsich @ 2023-03-27  0:13 UTC (permalink / raw)
  To: Jeff Law; +Cc: Andrew Waterman, Christoph Müllner, Tsukasa OI, binutils

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

On Sun 26. Mar 2023 at 23:43, Jeff Law <jeffreyalaw@gmail.com> wrote:

>
>
> On 3/22/23 09:47, Christoph Müllner wrote:
>
> >
> > Hi Tsukasa,
> >
> > There seems to be a misunderstanding of the spec.
> > The second operand of the fli should be the constant itself ("Value"
> > column of the specification) in C-like syntax.
> > E.g.:
> >    fli.h ft1, -1.0 # encoding rs1=0
> >    fli.h ft1, min # encoding rs1=1
> >    fli.h ft1, 0.0000152587890625 # encoding rs1=2
> >    ...
> >    fli.h ft1, 16 # encoding rs1=25
> >    ...
> >    fli.h ft1, nan # encoding rs1=31
> >
> > So we have 3 strings ("min", "inf", "nan") and 29 constants.
> Ouch.  So we've got to parse & match the actual constant.  I worked on a
> processor with similar capabilities, but we defined the assembly syntax
> to use the table index for the constant rather than the constant itself.


> I'd strongly suggest supporting the %a/%A hex notation for the
> constants.  It's unambiguous and less error prone.  I think Kito made a
> similar suggestion downthread.


That had been my initial reaction as well, when discussing the expected
assembly syntax with Andrew (the specification was not explicit enough to
me, as the table index will also be a decimal constant).  However, after
giving it a little thought, matching the FP-constant dies offer its own set
of advantages:
(a) it makes it clear to assembly writers and (more importantly) readers
what numeric value is intended; if we use the table index only, the typical
use will have a comment with the value next to it
(b) it is a clear improvement over today (where either the
hex-representation will be in the constant pool or a load-imm sequence will
be used).

Accepting both notations (possibly prefixing the index with #) sounds
reasonable. For disassembly, the fp-constant is preferable … sane for
compiler output (unless we want to emit a comment for verbose-asm).

The extra effort to handle the FP constants in the assembler certainly
seems worth the improved readability of the assembly.

When I read through the basics of Zfa I was a bit disappointed.  99% of
> the time the fli is going to feed one or more FP arithmetic
> instructions.


As the ship for fp-immediates in fp-arith has sailed (at least in the 32
bit encoding space), this fli-construction will at least offer
opportunities for fast result forwarding/bypass or for instruction fusion.

It'd be more efficient to be able to access those FP
> constants in the FP arithmetic instruction itself.  I guess that ship
> has sailed.
>
> Jeff
>

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

end of thread, other threads:[~2023-03-27  0:14 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-09-18 10:12 [REVIEW ONLY 0/1] RISC-V (unratified): Add 'Zfa' extension Tsukasa OI
2022-09-18 10:12 ` [REVIEW ONLY 1/1] UNRATIFIED RISC-V: " Tsukasa OI
2023-03-22 15:47   ` Christoph Müllner
2023-03-22 16:01     ` Philipp Tomsich
2023-03-22 16:07     ` Tsukasa OI
2023-03-22 16:21       ` Christoph Müllner
2023-03-22 17:00         ` Tsukasa OI
2023-03-23 13:17           ` Kito Cheng
2023-03-26 15:43     ` Jeff Law
2023-03-27  0:13       ` Philipp Tomsich

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).