RISC-V: Add support for the Zfa extension
authorChristoph Müllner <christoph.muellner@vrull.eu>
Mon, 27 Mar 2023 07:27:31 +0000 (09:27 +0200)
committerPhilipp Tomsich <philipp.tomsich@vrull.eu>
Fri, 30 Jun 2023 13:56:34 +0000 (15:56 +0200)
This patch adds support for the RISC-V Zfa extension,
which introduces additional floating-point instructions:
* fli (load-immediate) with pre-defined immediates
* fminm/fmaxm (like fmin/fmax but with different NaN behaviour)
* fround/froundmx (round to integer)
* fcvtmod.w.d (Modular Convert-to-Integer)
* fmv* to access high bits of FP registers in case XLEN < FLEN
* fleq/fltq (quiet comparison instructions)

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

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

The Zfa specification is frozen (and has passed public review).  It is
available as a chapter in "The RISC-V Instruction Set Manual: Volume 1":
  https://github.com/riscv/riscv-isa-manual/releases

bfd/ChangeLog:

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

gas/ChangeLog:

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

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

opcodes/ChangeLog:

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

Co-Developed-by: Tsukasa OI <research_trasio@irq.a4lg.com>
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
Co-Developed-by: Philipp Tomsich <philipp.tomsich@vrull.eu>
Acked-by: Palmer Dabbelt <palmer@rivosinc.com>
16 files changed:
bfd/elfxx-riscv.c
gas/config/tc-riscv.c
gas/doc/c-riscv.texi
gas/testsuite/gas/riscv/zfa-32.d [new file with mode: 0644]
gas/testsuite/gas/riscv/zfa-32.s [new file with mode: 0644]
gas/testsuite/gas/riscv/zfa-64.d [new file with mode: 0644]
gas/testsuite/gas/riscv/zfa-64.s [new file with mode: 0644]
gas/testsuite/gas/riscv/zfa-fail.d [new file with mode: 0644]
gas/testsuite/gas/riscv/zfa-fail.l [new file with mode: 0644]
gas/testsuite/gas/riscv/zfa-fail.s [new file with mode: 0644]
gas/testsuite/gas/riscv/zfa.d [new file with mode: 0644]
gas/testsuite/gas/riscv/zfa.s [new file with mode: 0644]
include/opcode/riscv-opc.h
include/opcode/riscv.h
opcodes/riscv-dis.c
opcodes/riscv-opc.c

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