aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorChristoph Müllner <christoph.muellner@vrull.eu>2023-03-27 09:27:31 +0200
committerPhilipp Tomsich <philipp.tomsich@vrull.eu>2023-06-30 15:56:34 +0200
commit1f3fc45bddc7147a2e59346a59290094137ef1e1 (patch)
tree43ea1a750ff6505a7656fd6336f2de06808edb2c /gas
parent3713e829be7e0195a78de17282304bebf8746b67 (diff)
downloadfsf-binutils-gdb-1f3fc45bddc7147a2e59346a59290094137ef1e1.zip
fsf-binutils-gdb-1f3fc45bddc7147a2e59346a59290094137ef1e1.tar.gz
fsf-binutils-gdb-1f3fc45bddc7147a2e59346a59290094137ef1e1.tar.bz2
RISC-V: Add support for the Zfa extension
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>
Diffstat (limited to 'gas')
-rw-r--r--gas/config/tc-riscv.c52
-rw-r--r--gas/doc/c-riscv.texi41
-rw-r--r--gas/testsuite/gas/riscv/zfa-32.d10
-rw-r--r--gas/testsuite/gas/riscv/zfa-32.s3
-rw-r--r--gas/testsuite/gas/riscv/zfa-64.d10
-rw-r--r--gas/testsuite/gas/riscv/zfa-64.s3
-rw-r--r--gas/testsuite/gas/riscv/zfa-fail.d3
-rw-r--r--gas/testsuite/gas/riscv/zfa-fail.l12
-rw-r--r--gas/testsuite/gas/riscv/zfa-fail.s16
-rw-r--r--gas/testsuite/gas/riscv/zfa.d89
-rw-r--r--gas/testsuite/gas/riscv/zfa.s87
11 files changed, 326 insertions, 0 deletions
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index e915b82..6bd3b2f 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -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;
}
diff --git a/gas/doc/c-riscv.texi b/gas/doc/c-riscv.texi
index 98d5d1b..b175ba0 100644
--- a/gas/doc/c-riscv.texi
+++ b/gas/doc/c-riscv.texi
@@ -18,6 +18,7 @@
* RISC-V-Options:: RISC-V Options
* RISC-V-Directives:: RISC-V Directives
* RISC-V-Modifiers:: RISC-V Assembler Modifiers
+* RISC-V-Floating-Point:: RISC-V Floating Point
* RISC-V-Formats:: RISC-V Instruction Formats
* RISC-V-ATTRIBUTE:: RISC-V Object Attribute
* RISC-V-CustomExts:: RISC-V Custom (Vendor-Defined) Extensions
@@ -382,6 +383,46 @@ The pseudo la.tls.gd instruction can be expended to
@end table
+@node RISC-V-Floating-Point
+@section RISC-V Floating Point
+@cindex floating point, risc-v (@sc{ieee})
+@cindex RISC-V floating point (@sc{ieee})
+
+The RISC-V architecture uses @sc{ieee} floating-point numbers.
+
+The RISC-V Zfa extension includes a load-immediate instruction
+for floating-point registers, which allows specifying the immediate
+(from a pool of 32 predefined values defined in the specification)
+as operand.
+E.g. to load the value @code{0.0625} as single-precision FP value into
+the FP register @code{ft1} one of the following instructions can be used:
+
+ fli.s ft1, 0.0625 # dec floating-point literal
+ fli.s ft1, 0x1p-4 # hex floating-point literal
+ fli.s ft1, 0x0.8p-3
+ fli.s ft1, 0x1.0p-4
+ fli.s ft1, 0x2p-5
+ fli.s ft1, 0x4p-6
+ ...
+
+As can be seen, many valid ways exist to express a floating-point value.
+This is realized by parsing the value operand using strtof() and
+comparing the parsed value against built-in float-constants that
+are written as hex floating-point literals.
+
+This approach works on all machines that use IEEE 754.
+However, there is a chance that this fails on other machines
+with the following error message:
+
+ Error: improper fli value operand
+ Error: illegal operands `fli.s ft1,0.0625
+
+The error indicates that parsing @samp{0x1p-4} and @samp{0.0625}
+to single-precision floating point numbers will not result
+in two equal values on that machine.
+
+If you encounter this problem, then please report it.
+
@node RISC-V-Formats
@section RISC-V Instruction Formats
@cindex instruction formats, risc-v
diff --git a/gas/testsuite/gas/riscv/zfa-32.d b/gas/testsuite/gas/riscv/zfa-32.d
new file mode 100644
index 0000000..48e20bf
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zfa-32.d
@@ -0,0 +1,10 @@
+#as: -march=rv32id_zfa
+#objdump: -d
+
+.*:[ ]+file format .*
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ ]+[0-9a-f]+:[ ]+e2108553[ ]+fmvh\.x\.d[ ]+a0,ft1
+[ ]+[0-9a-f]+:[ ]+b2b500d3[ ]+fmvp\.d\.x[ ]+ft1,a0,a1
diff --git a/gas/testsuite/gas/riscv/zfa-32.s b/gas/testsuite/gas/riscv/zfa-32.s
new file mode 100644
index 0000000..da95441
--- /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 0000000..48b6d74
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zfa-64.d
@@ -0,0 +1,10 @@
+#as: -march=rv64iq_zfa
+#objdump: -d
+
+.*:[ ]+file format .*
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ ]+[0-9a-f]+:[ ]+e6108553[ ]+fmvh\.x\.q[ ]+a0,ft1
+[ ]+[0-9a-f]+:[ ]+b6b500d3[ ]+fmvp\.q\.x[ ]+ft1,a0,a1
diff --git a/gas/testsuite/gas/riscv/zfa-64.s b/gas/testsuite/gas/riscv/zfa-64.s
new file mode 100644
index 0000000..dc8129d
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zfa-64.s
@@ -0,0 +1,3 @@
+target:
+ fmvh.x.q a0, ft1
+ fmvp.q.x ft1, a0, a1
diff --git a/gas/testsuite/gas/riscv/zfa-fail.d b/gas/testsuite/gas/riscv/zfa-fail.d
new file mode 100644
index 0000000..2f0a69b
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zfa-fail.d
@@ -0,0 +1,3 @@
+#as: -march=rv64iq_zfa_zfh
+#source: zfa-fail.s
+#error_output: zfa-fail.l
diff --git a/gas/testsuite/gas/riscv/zfa-fail.l b/gas/testsuite/gas/riscv/zfa-fail.l
new file mode 100644
index 0000000..efe9ba0
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zfa-fail.l
@@ -0,0 +1,12 @@
+.*: Assembler messages:
+.*: Error: bad fli constant operand, supported constants must be in decimal or hexadecimal floating-point literal form
+.*: Error: illegal operands `fli\.s ft1,infinity'
+.*: Error: bad fli constant operand, supported constants must be in decimal or hexadecimal floating-point literal form
+.*: Error: illegal operands `fli\.d ft1,invalid'
+.*: Error: illegal operands `fcvtmod\.w\.d a0,ft1'
+.*: Error: illegal operands `fcvtmod\.w\.d a0,ft1,rne'
+.*: Error: illegal operands `fcvtmod\.w\.d a0,ft1,rdn'
+.*: Error: illegal operands `fcvtmod\.w\.d a0,ft1,rup'
+.*: Error: illegal operands `fcvtmod\.w\.d a0,ft1,rmm'
+.*: Error: illegal operands `fcvtmod\.w\.d a0,ft1,dyn'
+.*: Error: illegal operands `fcvtmod\.w\.d a0,ft1,invalid'
diff --git a/gas/testsuite/gas/riscv/zfa-fail.s b/gas/testsuite/gas/riscv/zfa-fail.s
new file mode 100644
index 0000000..98ffe7f
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zfa-fail.s
@@ -0,0 +1,16 @@
+target:
+ # fli.[sdqh]: Invalid value field
+ fli.s ft1, infinity
+ fli.d ft1, invalid
+
+ # fcvtmod.w.d: Requires explicit rounding mode.
+ fcvtmod.w.d a0, ft1
+
+ # fcvtmod.w.d: Rounding mode other than rtz are reserved.
+ fcvtmod.w.d a0, ft1, rne
+ fcvtmod.w.d a0, ft1, rdn
+ fcvtmod.w.d a0, ft1, rup
+ fcvtmod.w.d a0, ft1, rmm
+ fcvtmod.w.d a0, ft1, dyn
+ # fcvtmod.w.d: Invalid rounding mode is invalid.
+ fcvtmod.w.d a0, ft1, invalid
diff --git a/gas/testsuite/gas/riscv/zfa.d b/gas/testsuite/gas/riscv/zfa.d
new file mode 100644
index 0000000..cbfc72e
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zfa.d
@@ -0,0 +1,89 @@
+#as: -march=rv32iq_zfa_zfh
+#objdump: -d
+
+.*:[ ]+file format .*
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ ]+[0-9a-f]+:[ ]+f01000d3[ ]+fli\.s[ ]+ft1,-0x1p\+0
+[ ]+[0-9a-f]+:[ ]+f01080d3[ ]+fli\.s[ ]+ft1,min
+[ ]+[0-9a-f]+:[ ]+f01100d3[ ]+fli\.s[ ]+ft1,0x1p-16
+[ ]+[0-9a-f]+:[ ]+f01180d3[ ]+fli\.s[ ]+ft1,0x1p-15
+[ ]+[0-9a-f]+:[ ]+f01200d3[ ]+fli\.s[ ]+ft1,0x1p-8
+[ ]+[0-9a-f]+:[ ]+f01280d3[ ]+fli\.s[ ]+ft1,0x1p-7
+[ ]+[0-9a-f]+:[ ]+f01300d3[ ]+fli\.s[ ]+ft1,0x1p-4
+[ ]+[0-9a-f]+:[ ]+f01380d3[ ]+fli\.s[ ]+ft1,0x1p-3
+[ ]+[0-9a-f]+:[ ]+f21400d3[ ]+fli\.d[ ]+ft1,0x1p-2
+[ ]+[0-9a-f]+:[ ]+f21480d3[ ]+fli\.d[ ]+ft1,0x1.4p-2
+[ ]+[0-9a-f]+:[ ]+f21500d3[ ]+fli\.d[ ]+ft1,0x1.8p-2
+[ ]+[0-9a-f]+:[ ]+f21580d3[ ]+fli\.d[ ]+ft1,0x1.cp-2
+[ ]+[0-9a-f]+:[ ]+f21600d3[ ]+fli\.d[ ]+ft1,0x1p-1
+[ ]+[0-9a-f]+:[ ]+f21680d3[ ]+fli\.d[ ]+ft1,0x1.4p-1
+[ ]+[0-9a-f]+:[ ]+f21700d3[ ]+fli\.d[ ]+ft1,0x1.8p-1
+[ ]+[0-9a-f]+:[ ]+f21780d3[ ]+fli\.d[ ]+ft1,0x1.cp-1
+[ ]+[0-9a-f]+:[ ]+f61800d3[ ]+fli\.q[ ]+ft1,0x1p\+0
+[ ]+[0-9a-f]+:[ ]+f61880d3[ ]+fli\.q[ ]+ft1,0x1.4p\+0
+[ ]+[0-9a-f]+:[ ]+f61900d3[ ]+fli\.q[ ]+ft1,0x1.8p\+0
+[ ]+[0-9a-f]+:[ ]+f61980d3[ ]+fli\.q[ ]+ft1,0x1.cp\+0
+[ ]+[0-9a-f]+:[ ]+f61a00d3[ ]+fli\.q[ ]+ft1,0x1p\+1
+[ ]+[0-9a-f]+:[ ]+f61a80d3[ ]+fli\.q[ ]+ft1,0x1.4p\+1
+[ ]+[0-9a-f]+:[ ]+f61b00d3[ ]+fli\.q[ ]+ft1,0x1.8p\+1
+[ ]+[0-9a-f]+:[ ]+f61b80d3[ ]+fli\.q[ ]+ft1,0x1p\+2
+[ ]+[0-9a-f]+:[ ]+f41c00d3[ ]+fli\.h[ ]+ft1,0x1p\+3
+[ ]+[0-9a-f]+:[ ]+f41c80d3[ ]+fli\.h[ ]+ft1,0x1p\+4
+[ ]+[0-9a-f]+:[ ]+f41d00d3[ ]+fli\.h[ ]+ft1,0x1p\+7
+[ ]+[0-9a-f]+:[ ]+f41d80d3[ ]+fli\.h[ ]+ft1,0x1p\+8
+[ ]+[0-9a-f]+:[ ]+f41e00d3[ ]+fli\.h[ ]+ft1,0x1p\+15
+[ ]+[0-9a-f]+:[ ]+f41e80d3[ ]+fli\.h[ ]+ft1,0x1p\+16
+[ ]+[0-9a-f]+:[ ]+f41f00d3[ ]+fli\.h[ ]+ft1,inf
+[ ]+[0-9a-f]+:[ ]+f41f80d3[ ]+fli\.h[ ]+ft1,nan
+[ ]+[0-9a-f]+:[ ]+2c3100d3[ ]+fmin\.h[ ]+ft1,ft2,ft3
+[ ]+[0-9a-f]+:[ ]+2c3120d3[ ]+fminm\.h[ ]+ft1,ft2,ft3
+[ ]+[0-9a-f]+:[ ]+283100d3[ ]+fmin\.s[ ]+ft1,ft2,ft3
+[ ]+[0-9a-f]+:[ ]+283120d3[ ]+fminm\.s[ ]+ft1,ft2,ft3
+[ ]+[0-9a-f]+:[ ]+2a3100d3[ ]+fmin\.d[ ]+ft1,ft2,ft3
+[ ]+[0-9a-f]+:[ ]+2a3120d3[ ]+fminm\.d[ ]+ft1,ft2,ft3
+[ ]+[0-9a-f]+:[ ]+2e3100d3[ ]+fmin\.q[ ]+ft1,ft2,ft3
+[ ]+[0-9a-f]+:[ ]+2e3120d3[ ]+fminm\.q[ ]+ft1,ft2,ft3
+[ ]+[0-9a-f]+:[ ]+2c3110d3[ ]+fmax\.h[ ]+ft1,ft2,ft3
+[ ]+[0-9a-f]+:[ ]+2c3130d3[ ]+fmaxm\.h[ ]+ft1,ft2,ft3
+[ ]+[0-9a-f]+:[ ]+283110d3[ ]+fmax\.s[ ]+ft1,ft2,ft3
+[ ]+[0-9a-f]+:[ ]+283130d3[ ]+fmaxm\.s[ ]+ft1,ft2,ft3
+[ ]+[0-9a-f]+:[ ]+2a3110d3[ ]+fmax\.d[ ]+ft1,ft2,ft3
+[ ]+[0-9a-f]+:[ ]+2a3130d3[ ]+fmaxm\.d[ ]+ft1,ft2,ft3
+[ ]+[0-9a-f]+:[ ]+2e3110d3[ ]+fmax\.q[ ]+ft1,ft2,ft3
+[ ]+[0-9a-f]+:[ ]+2e3130d3[ ]+fmaxm\.q[ ]+ft1,ft2,ft3
+[ ]+[0-9a-f]+:[ ]+4445f553[ ]+fround\.h[ ]+fa0,fa1
+[ ]+[0-9a-f]+:[ ]+44459553[ ]+fround\.h[ ]+fa0,fa1,rtz
+[ ]+[0-9a-f]+:[ ]+4045f553[ ]+fround\.s[ ]+fa0,fa1
+[ ]+[0-9a-f]+:[ ]+40459553[ ]+fround\.s[ ]+fa0,fa1,rtz
+[ ]+[0-9a-f]+:[ ]+4245f553[ ]+fround\.d[ ]+fa0,fa1
+[ ]+[0-9a-f]+:[ ]+42459553[ ]+fround\.d[ ]+fa0,fa1,rtz
+[ ]+[0-9a-f]+:[ ]+4645f553[ ]+fround\.q[ ]+fa0,fa1
+[ ]+[0-9a-f]+:[ ]+46459553[ ]+fround\.q[ ]+fa0,fa1,rtz
+[ ]+[0-9a-f]+:[ ]+4455f553[ ]+froundnx\.h[ ]+fa0,fa1
+[ ]+[0-9a-f]+:[ ]+44559553[ ]+froundnx\.h[ ]+fa0,fa1,rtz
+[ ]+[0-9a-f]+:[ ]+4055f553[ ]+froundnx\.s[ ]+fa0,fa1
+[ ]+[0-9a-f]+:[ ]+40559553[ ]+froundnx\.s[ ]+fa0,fa1,rtz
+[ ]+[0-9a-f]+:[ ]+4255f553[ ]+froundnx\.d[ ]+fa0,fa1
+[ ]+[0-9a-f]+:[ ]+42559553[ ]+froundnx\.d[ ]+fa0,fa1,rtz
+[ ]+[0-9a-f]+:[ ]+4655f553[ ]+froundnx\.q[ ]+fa0,fa1
+[ ]+[0-9a-f]+:[ ]+46559553[ ]+froundnx\.q[ ]+fa0,fa1,rtz
+[ ]+[0-9a-f]+:[ ]+c2809553[ ]+fcvtmod\.w\.d[ ]+a0,ft1,rtz
+[ ]+[0-9a-f]+:[ ]+a4209553[ ]+flt\.h[ ]+a0,ft1,ft2
+[ ]+[0-9a-f]+:[ ]+a420d553[ ]+fltq\.h[ ]+a0,ft1,ft2
+[ ]+[0-9a-f]+:[ ]+a0209553[ ]+flt\.s[ ]+a0,ft1,ft2
+[ ]+[0-9a-f]+:[ ]+a020d553[ ]+fltq\.s[ ]+a0,ft1,ft2
+[ ]+[0-9a-f]+:[ ]+a2209553[ ]+flt\.d[ ]+a0,ft1,ft2
+[ ]+[0-9a-f]+:[ ]+a220d553[ ]+fltq\.d[ ]+a0,ft1,ft2
+[ ]+[0-9a-f]+:[ ]+a6209553[ ]+flt\.q[ ]+a0,ft1,ft2
+[ ]+[0-9a-f]+:[ ]+a620d553[ ]+fltq\.q[ ]+a0,ft1,ft2
+[ ]+[0-9a-f]+:[ ]+a4208553[ ]+fle\.h[ ]+a0,ft1,ft2
+[ ]+[0-9a-f]+:[ ]+a420c553[ ]+fleq\.h[ ]+a0,ft1,ft2
+[ ]+[0-9a-f]+:[ ]+a0208553[ ]+fle\.s[ ]+a0,ft1,ft2
+[ ]+[0-9a-f]+:[ ]+a020c553[ ]+fleq\.s[ ]+a0,ft1,ft2
+[ ]+[0-9a-f]+:[ ]+a2208553[ ]+fle\.d[ ]+a0,ft1,ft2
+[ ]+[0-9a-f]+:[ ]+a220c553[ ]+fleq\.d[ ]+a0,ft1,ft2
+[ ]+[0-9a-f]+:[ ]+a6208553[ ]+fle\.q[ ]+a0,ft1,ft2
+[ ]+[0-9a-f]+:[ ]+a620c553[ ]+fleq\.q[ ]+a0,ft1,ft2
diff --git a/gas/testsuite/gas/riscv/zfa.s b/gas/testsuite/gas/riscv/zfa.s
new file mode 100644
index 0000000..7fbcb17
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zfa.s
@@ -0,0 +1,87 @@
+target:
+ # fli
+ fli.s ft1, -1
+ fli.s ft1, min
+ fli.s ft1, 0.0000152587890625
+ fli.s ft1, 0x1p-15
+ fli.s ft1, 0.00390625
+ fli.s ft1, 0x1p-7
+ fli.s ft1, 0.0625
+ fli.s ft1, 0x1p-3
+ fli.d ft1, 0.25
+ fli.d ft1, 0x1.4p-2
+ fli.d ft1, 0.375
+ fli.d ft1, 0x1.cp-2
+ fli.d ft1, 0.5
+ fli.d ft1, 0x1.4p-1
+ fli.d ft1, 0.75
+ fli.d ft1, 0x1.cp-1
+ fli.q ft1, 1
+ fli.q ft1, 0x1.4p+0
+ fli.q ft1, 1.5
+ fli.q ft1, 0x1.cp0
+ fli.q ft1, 2.0
+ fli.q ft1, 0x1.4p+1
+ fli.q ft1, 3
+ fli.q ft1, 0x1p2
+ fli.h ft1, 8.0
+ fli.h ft1, 0x1p4
+ fli.h ft1, 128.0
+ fli.h ft1, 0x1p8
+ fli.h ft1, 32768.0
+ fli.h ft1, 0x1p16
+ fli.h ft1, inf
+ fli.h ft1, nan
+ # fminm/fmaxm
+ fmin.h ft1, ft2, ft3
+ fminm.h ft1, ft2, ft3
+ fmin.s ft1, ft2, ft3
+ fminm.s ft1, ft2, ft3
+ fmin.d ft1, ft2, ft3
+ fminm.d ft1, ft2, ft3
+ fmin.q ft1, ft2, ft3
+ fminm.q ft1, ft2, ft3
+ fmax.h ft1, ft2, ft3
+ fmaxm.h ft1, ft2, ft3
+ fmax.s ft1, ft2, ft3
+ fmaxm.s ft1, ft2, ft3
+ fmax.d ft1, ft2, ft3
+ fmaxm.d ft1, ft2, ft3
+ fmax.q ft1, ft2, ft3
+ fmaxm.q ft1, ft2, ft3
+ # fround/froundnx
+ fround.h fa0, fa1
+ fround.h fa0, fa1, rtz
+ fround.s fa0, fa1
+ fround.s fa0, fa1, rtz
+ fround.d fa0, fa1
+ fround.d fa0, fa1, rtz
+ fround.q fa0, fa1
+ fround.q fa0, fa1, rtz
+ froundnx.h fa0, fa1
+ froundnx.h fa0, fa1, rtz
+ froundnx.s fa0, fa1
+ froundnx.s fa0, fa1, rtz
+ froundnx.d fa0, fa1
+ froundnx.d fa0, fa1, rtz
+ froundnx.q fa0, fa1
+ froundnx.q fa0, fa1, rtz
+ # fcvtmod.w.d
+ fcvtmod.w.d a0, ft1, rtz
+ # fltq/fleq
+ flt.h a0, ft1, ft2
+ fltq.h a0, ft1, ft2
+ flt.s a0, ft1, ft2
+ fltq.s a0, ft1, ft2
+ flt.d a0, ft1, ft2
+ fltq.d a0, ft1, ft2
+ flt.q a0, ft1, ft2
+ fltq.q a0, ft1, ft2
+ fle.h a0, ft1, ft2
+ fleq.h a0, ft1, ft2
+ fle.s a0, ft1, ft2
+ fleq.s a0, ft1, ft2
+ fle.d a0, ft1, ft2
+ fleq.d a0, ft1, ft2
+ fle.q a0, ft1, ft2
+ fleq.q a0, ft1, ft2