[binutils-gdb] RISC-V: check operands for Zdinx in RV32

Jan Beulich jbeulich@sourceware.org
Fri Jul 31 09:54:10 GMT 2026


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=0aa268acc97528c98434c787ab479f89fef12c10

commit 0aa268acc97528c98434c787ab479f89fef12c10
Author: Jan Beulich <jbeulich@suse.com>
Date:   Fri Jul 31 11:51:12 2026 +0200

    RISC-V: check operands for Zdinx in RV32
    
    Like for Zilsd, register pair operands are required to be encoded with the
    low bit clear. Since match functions don't have XLEN available, introduce
    respective flags, to be used explicitly in assembler and disassembler.

Diff:
---
 gas/config/tc-riscv.c                     | 34 ++++++++++++----
 gas/testsuite/gas/riscv/zdinx-rv32-fail.d |  3 ++
 gas/testsuite/gas/riscv/zdinx-rv32-fail.l | 47 +++++++++++++++++++++++
 gas/testsuite/gas/riscv/zdinx-rv32.d      | 52 +++++++++++++++++++++++++
 gas/testsuite/gas/riscv/zdinx-rv32.s      | 52 +++++++++++++++++++++++++
 include/opcode/riscv.h                    | 12 ++++++
 opcodes/riscv-dis.c                       | 17 ++++++++
 opcodes/riscv-opc.c                       | 64 +++++++++++++++----------------
 8 files changed, 241 insertions(+), 40 deletions(-)

diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index ec35444ccf9..1fa33da6ec3 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -3004,6 +3004,12 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
       *imm_reloc = BFD_RELOC_UNUSED;
       p = percent_op_null;
 
+#define RV32_EVEN_CHECK(form, rclass, regno)     \
+  (!(ip->insn_mo->pinfo & INSN_RV32_EVEN_##form) \
+   || xlen != 32                                 \
+   || (rclass) != RCLASS_GPR                     \
+   || !((regno) & 1))
+
       for (oparg = insn->args;; ++oparg)
 	{
 	  opargStart = oparg;
@@ -3011,6 +3017,8 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 	    ++asarg;
 	  switch (*oparg)
 	    {
+	      enum reg_class rclass;
+
 	    case '\0': /* End of args.  */
 	      if (insn->match_func && !insn->match_func (insn, ip->insn_opcode))
 		break;
@@ -3670,32 +3678,40 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 	    case 'T': /* Floating point RS2.  */
 	    case 'U': /* Floating point RS1 and RS2.  */
 	    case 'R': /* Floating point RS3.  */
-	      if (reg_lookup (&asarg,
-			      (riscv_subset_supports (&riscv_rps_as, "zfinx")
-			      ? RCLASS_GPR : RCLASS_FPR), &regno))
+	      rclass = riscv_subset_supports (&riscv_rps_as, "zfinx")
+		       ? RCLASS_GPR : RCLASS_FPR;
+	      if (reg_lookup (&asarg, rclass, &regno))
 		{
 		  char c = *oparg;
 		  if (is_whitespace (*asarg))
 		    ++asarg;
+
 		  switch (c)
 		    {
 		    case 'D':
+		      if (!RV32_EVEN_CHECK (D, rclass, regno))
+			break;
 		      INSERT_OPERAND (RD, *ip, regno);
-		      break;
+		      continue;
 		    case 'S':
+		      if (!RV32_EVEN_CHECK (S, rclass, regno))
+			break;
 		      INSERT_OPERAND (RS1, *ip, regno);
-		      break;
+		      continue;
 		    case 'U':
 		      INSERT_OPERAND (RS1, *ip, regno);
 		      /* Fall through.  */
 		    case 'T':
+		      if (!RV32_EVEN_CHECK (T, rclass, regno))
+			break;
 		      INSERT_OPERAND (RS2, *ip, regno);
-		      break;
+		      continue;
 		    case 'R':
+		      if (!RV32_EVEN_CHECK (R, rclass, regno))
+			break;
 		      INSERT_OPERAND (RS3, *ip, regno);
-		      break;
+		      continue;
 		    }
-		  continue;
 		}
 	      break;
 
@@ -4530,6 +4546,8 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
       insn_with_csr = false;
     }
 
+#undef RV32_EVEN_CHECK
+
  out:
   /* Restore the character we might have clobbered above.  */
   if (save_c)
diff --git a/gas/testsuite/gas/riscv/zdinx-rv32-fail.d b/gas/testsuite/gas/riscv/zdinx-rv32-fail.d
new file mode 100644
index 00000000000..7d7b8d80296
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zdinx-rv32-fail.d
@@ -0,0 +1,3 @@
+#as: -march=rv32i_zdinx
+#source: zdinx.s
+#error_output: zdinx-rv32-fail.l
diff --git a/gas/testsuite/gas/riscv/zdinx-rv32-fail.l b/gas/testsuite/gas/riscv/zdinx-rv32-fail.l
new file mode 100644
index 00000000000..e5c1592b89b
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zdinx-rv32-fail.l
@@ -0,0 +1,47 @@
+.*: Assembler messages:
+.*: Error: illegal operands `fadd\.d .*'
+.*: Error: illegal operands `fadd\.d .*'
+.*: Error: illegal operands `fsub\.d .*'
+.*: Error: illegal operands `fsub\.d .*'
+.*: Error: illegal operands `fmul\.d .*'
+.*: Error: illegal operands `fmul\.d .*'
+.*: Error: illegal operands `fdiv\.d .*'
+.*: Error: illegal operands `fdiv\.d .*'
+.*: Error: illegal operands `fsqrt\.d .*'
+.*: Error: illegal operands `fsqrt\.d .*'
+.*: Error: illegal operands `fmin\.d .*'
+.*: Error: illegal operands `fmax\.d .*'
+.*: Error: illegal operands `fmadd\.d .*'
+.*: Error: illegal operands `fmadd\.d .*'
+.*: Error: illegal operands `fnmadd\.d .*'
+.*: Error: illegal operands `fnmadd\.d .*'
+.*: Error: illegal operands `fmsub\.d .*'
+.*: Error: illegal operands `fmsub\.d .*'
+.*: Error: illegal operands `fnmsub\.d .*'
+.*: Error: illegal operands `fnmsub\.d .*'
+.*: Error: illegal operands `fcvt\.w\.d .*'
+.*: Error: illegal operands `fcvt\.w\.d .*'
+.*: Error: illegal operands `fcvt\.wu\.d .*'
+.*: Error: illegal operands `fcvt\.wu\.d .*'
+.*: Error: unrecognized opcode `fcvt\.l\.d .*'
+.*: Error: unrecognized opcode `fcvt\.l\.d .*'
+.*: Error: unrecognized opcode `fcvt\.lu\.d .*'
+.*: Error: unrecognized opcode `fcvt\.lu\.d .*'
+.*: Error: unrecognized opcode `fcvt\.d\.l .*'
+.*: Error: unrecognized opcode `fcvt\.d\.l .*'
+.*: Error: unrecognized opcode `fcvt\.d\.lu .*'
+.*: Error: unrecognized opcode `fcvt\.d\.lu .*'
+.*: Error: illegal operands `fcvt\.s\.d .*'
+.*: Error: illegal operands `fcvt\.s\.d .*'
+.*: Error: illegal operands `fsgnj\.d .*'
+.*: Error: illegal operands `fsgnjn\.d .*'
+.*: Error: illegal operands `fsgnjx\.d .*'
+.*: Error: illegal operands `feq\.d .*'
+.*: Error: illegal operands `flt\.d .*'
+.*: Error: illegal operands `fle\.d .*'
+.*: Error: illegal operands `fgt\.d .*'
+.*: Error: illegal operands `fge\.d .*'
+.*: Error: illegal operands `fmv\.d .*'
+.*: Error: illegal operands `fneg\.d .*'
+.*: Error: illegal operands `fabs\.d .*'
+.*: Error: illegal operands `fclass\.d .*'
diff --git a/gas/testsuite/gas/riscv/zdinx-rv32.d b/gas/testsuite/gas/riscv/zdinx-rv32.d
new file mode 100644
index 00000000000..863f316645a
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zdinx-rv32.d
@@ -0,0 +1,52 @@
+#as: -march=rv32i_zdinx
+#objdump: -dwr
+
+.*:[ 	]+file format .*
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+[0-9a-f]+:[ 	]+02e67553[ 	]+fadd\.d[ 	]+a0,a2,a4
+[ 	]+[0-9a-f]+:[ 	]+02e60553[ 	]+fadd\.d[ 	]+a0,a2,a4,rne
+[ 	]+[0-9a-f]+:[ 	]+0ae67553[ 	]+fsub\.d[ 	]+a0,a2,a4
+[ 	]+[0-9a-f]+:[ 	]+0ae60553[ 	]+fsub\.d[ 	]+a0,a2,a4,rne
+[ 	]+[0-9a-f]+:[ 	]+12e67553[ 	]+fmul\.d[ 	]+a0,a2,a4
+[ 	]+[0-9a-f]+:[ 	]+12e60553[ 	]+fmul\.d[ 	]+a0,a2,a4,rne
+[ 	]+[0-9a-f]+:[ 	]+1ae67553[ 	]+fdiv\.d[ 	]+a0,a2,a4
+[ 	]+[0-9a-f]+:[ 	]+1ae60553[ 	]+fdiv\.d[ 	]+a0,a2,a4,rne
+[ 	]+[0-9a-f]+:[ 	]+5a067553[ 	]+fsqrt\.d[ 	]+a0,a2
+[ 	]+[0-9a-f]+:[ 	]+5a060553[ 	]+fsqrt\.d[ 	]+a0,a2,rne
+[ 	]+[0-9a-f]+:[ 	]+2ae60553[ 	]+fmin\.d[ 	]+a0,a2,a4
+[ 	]+[0-9a-f]+:[ 	]+2ae61553[ 	]+fmax\.d[ 	]+a0,a2,a4
+[ 	]+[0-9a-f]+:[ 	]+82e67543[ 	]+fmadd\.d[ 	]+a0,a2,a4,a6
+[ 	]+[0-9a-f]+:[ 	]+82e60543[ 	]+fmadd\.d[ 	]+a0,a2,a4,a6,rne
+[ 	]+[0-9a-f]+:[ 	]+82e6754f[ 	]+fnmadd\.d[ 	]+a0,a2,a4,a6
+[ 	]+[0-9a-f]+:[ 	]+82e6054f[ 	]+fnmadd\.d[ 	]+a0,a2,a4,a6,rne
+[ 	]+[0-9a-f]+:[ 	]+82e67547[ 	]+fmsub\.d[ 	]+a0,a2,a4,a6
+[ 	]+[0-9a-f]+:[ 	]+82e60547[ 	]+fmsub\.d[ 	]+a0,a2,a4,a6,rne
+[ 	]+[0-9a-f]+:[ 	]+82e6754b[ 	]+fnmsub\.d[ 	]+a0,a2,a4,a6
+[ 	]+[0-9a-f]+:[ 	]+82e6054b[ 	]+fnmsub\.d[ 	]+a0,a2,a4,a6,rne
+[ 	]+[0-9a-f]+:[ 	]+c20675d3[ 	]+fcvt\.w\.d[ 	]+a1,a2
+[ 	]+[0-9a-f]+:[ 	]+c20605d3[ 	]+fcvt\.w\.d[ 	]+a1,a2,rne
+[ 	]+[0-9a-f]+:[ 	]+c21675d3[ 	]+fcvt\.wu\.d[ 	]+a1,a2
+[ 	]+[0-9a-f]+:[ 	]+c21605d3[ 	]+fcvt\.wu\.d[ 	]+a1,a2,rne
+[ 	]+[0-9a-f]+:[ 	]+d2058553[ 	]+fcvt\.d\.w[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+d2158553[ 	]+fcvt\.d\.wu[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+42058553[ 	]+fcvt\.d\.s[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+401675d3[ 	]+fcvt\.s\.d[ 	]+a1,a2
+[ 	]+[0-9a-f]+:[ 	]+401605d3[ 	]+fcvt\.s\.d[ 	]+a1,a2,rne
+[ 	]+[0-9a-f]+:[ 	]+42258553[ 	]+fcvt\.d\.h[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+441675d3[ 	]+fcvt\.h\.d[ 	]+a1,a2
+[ 	]+[0-9a-f]+:[ 	]+441605d3[ 	]+fcvt\.h\.d[ 	]+a1,a2,rne
+[ 	]+[0-9a-f]+:[ 	]+22e60553[ 	]+fsgnj\.d[ 	]+a0,a2,a4
+[ 	]+[0-9a-f]+:[ 	]+22e61553[ 	]+fsgnjn\.d[ 	]+a0,a2,a4
+[ 	]+[0-9a-f]+:[ 	]+22e62553[ 	]+fsgnjx\.d[ 	]+a0,a2,a4
+[ 	]+[0-9a-f]+:[ 	]+a2e625d3[ 	]+feq\.d[ 	]+a1,a2,a4
+[ 	]+[0-9a-f]+:[ 	]+a2e615d3[ 	]+flt\.d[ 	]+a1,a2,a4
+[ 	]+[0-9a-f]+:[ 	]+a2e605d3[ 	]+fle\.d[ 	]+a1,a2,a4
+[ 	]+[0-9a-f]+:[ 	]+a2c715d3[ 	]+flt\.d[ 	]+a1,a4,a2
+[ 	]+[0-9a-f]+:[ 	]+a2c705d3[ 	]+fle\.d[ 	]+a1,a4,a2
+[ 	]+[0-9a-f]+:[ 	]+22c60553[ 	]+fmv\.d[ 	]+a0,a2
+[ 	]+[0-9a-f]+:[ 	]+22c61553[ 	]+fneg\.d[ 	]+a0,a2
+[ 	]+[0-9a-f]+:[ 	]+22c62553[ 	]+fabs\.d[ 	]+a0,a2
+[ 	]+[0-9a-f]+:[ 	]+e20615d3[ 	]+fclass\.d[ 	]+a1,a2
diff --git a/gas/testsuite/gas/riscv/zdinx-rv32.s b/gas/testsuite/gas/riscv/zdinx-rv32.s
new file mode 100644
index 00000000000..d6684c0e8a5
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zdinx-rv32.s
@@ -0,0 +1,52 @@
+target:
+	fadd.d		a0, a2, a4
+	fadd.d		a0, a2, a4, rne
+	fsub.d		a0, a2, a4
+	fsub.d		a0, a2, a4, rne
+	fmul.d		a0, a2, a4
+	fmul.d		a0, a2, a4, rne
+	fdiv.d		a0, a2, a4
+	fdiv.d		a0, a2, a4, rne
+	fsqrt.d		a0, a2
+	fsqrt.d		a0, a2, rne
+	fmin.d		a0, a2, a4
+	fmax.d		a0, a2, a4
+	fmadd.d		a0, a2, a4, a6
+	fmadd.d		a0, a2, a4, a6, rne
+	fnmadd.d	a0, a2, a4, a6
+	fnmadd.d	a0, a2, a4, a6, rne
+	fmsub.d		a0, a2, a4, a6
+	fmsub.d		a0, a2, a4, a6, rne
+	fnmsub.d	a0, a2, a4, a6
+	fnmsub.d	a0, a2, a4, a6, rne
+
+	fcvt.w.d	a1, a2
+	fcvt.w.d	a1, a2, rne
+	fcvt.wu.d	a1, a2
+	fcvt.wu.d	a1, a2, rne
+	fcvt.d.w	a0, a1
+	fcvt.d.wu	a0, a1
+
+	fcvt.d.s	a0, a1
+	fcvt.s.d	a1, a2
+	fcvt.s.d	a1, a2, rne
+
+	.option push
+	.option arch, +zhinxmin
+	fcvt.d.h	a0, a1
+	fcvt.h.d	a1, a2
+	fcvt.h.d	a1, a2, rne
+	.option pop
+
+	fsgnj.d		a0, a2, a4
+	fsgnjn.d	a0, a2, a4
+	fsgnjx.d	a0, a2, a4
+	feq.d		a1, a2, a4
+	flt.d		a1, a2, a4
+	fle.d		a1, a2, a4
+	fgt.d		a1, a2, a4
+	fge.d		a1, a2, a4
+	fmv.d		a0, a2
+	fneg.d		a0, a2
+	fabs.d		a0, a2
+	fclass.d	a1, a2
diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
index 132be423878..d142d3401fa 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -709,6 +709,18 @@ struct riscv_opcode
 #define INSN_8_BYTE		0x00000040
 #define INSN_16_BYTE		0x00000050
 
+/* Operands required to be an even-numbered register (pair) in RV32.  */
+#define INSN_RV32_EVEN_D	0x00000100
+#define INSN_RV32_EVEN_S	0x00000200
+#define INSN_RV32_EVEN_T	0x00000400 /* Also covering U.  */
+#define INSN_RV32_EVEN_R	0x00000800
+/* Shorthands for combinations of the above.  */
+#define INSN_RV32_EVEN_DS	(INSN_RV32_EVEN_D   | INSN_RV32_EVEN_S)
+#define INSN_RV32_EVEN_DST	(INSN_RV32_EVEN_DS  | INSN_RV32_EVEN_T)
+#define INSN_RV32_EVEN_DSTR	(INSN_RV32_EVEN_DST | INSN_RV32_EVEN_R)
+#define INSN_RV32_EVEN_DU	(INSN_RV32_EVEN_D   | INSN_RV32_EVEN_T)
+#define INSN_RV32_EVEN_ST	(INSN_RV32_EVEN_S   | INSN_RV32_EVEN_T)
+
 /* Instruction is actually a macro.  It should be ignored by the
    disassembler, and requires special treatment by the assembler.  */
 #define INSN_MACRO		0xffffffff
diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index e43c4e524ca..696f2d9777f 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -1138,6 +1138,23 @@ riscv_disassemble_insn (bfd_vma memaddr,
 	      if (!riscv_multi_subset_supports (&pd->riscv_rps_dis,
 						op->insn_class))
 		continue;
+
+	      if (pd->xlen == 32
+		  && riscv_subset_supports (&pd->riscv_rps_dis, "zdinx"))
+		{
+		  if ((op->pinfo & INSN_RV32_EVEN_D)
+		      && (word & (1u << OP_SH_RD)))
+		    continue;
+		  if ((op->pinfo & INSN_RV32_EVEN_S)
+		      && (word & (1u << OP_SH_RS1)))
+		    continue;
+		  if ((op->pinfo & INSN_RV32_EVEN_T)
+		      && (word & (1u << OP_SH_RS2)))
+		    continue;
+		  if ((op->pinfo & INSN_RV32_EVEN_R)
+		      && (word & (1u << OP_SH_RS3)))
+		    continue;
+		}
 	    }
 
 	  /* It's a match.  */
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index f9c5224c2b0..6b01851b757 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -955,10 +955,10 @@ const struct riscv_opcode riscv_opcodes[] =
 {"fcvt.h.w",   0, INSN_CLASS_ZFH_INX,  "D,sm",      MATCH_FCVT_H_W, MASK_FCVT_H_W, match_opcode, 0 },
 {"fcvt.h.wu",  0, INSN_CLASS_ZFH_INX,  "D,sm",      MATCH_FCVT_H_WU, MASK_FCVT_H_WU, match_opcode, 0 },
 {"fcvt.s.h",   0, INSN_CLASS_ZFHMIN_INX, "D,S",     MATCH_FCVT_S_H, MASK_FCVT_S_H|MASK_RM, match_opcode, 0 },
-{"fcvt.d.h",   0, INSN_CLASS_ZFHMIN_AND_D_INX,     "D,S",       MATCH_FCVT_D_H, MASK_FCVT_D_H|MASK_RM, match_opcode, 0 },
-{"fcvt.q.h",   0, INSN_CLASS_ZFHMIN_AND_Q_INX,     "D,S",       MATCH_FCVT_Q_H, MASK_FCVT_Q_H|MASK_RM, match_opcode, 0 },
+{"fcvt.d.h",   0, INSN_CLASS_ZFHMIN_AND_D_INX, "D,S", MATCH_FCVT_D_H, MASK_FCVT_D_H|MASK_RM, match_opcode, INSN_RV32_EVEN_D },
+{"fcvt.q.h",   0, INSN_CLASS_ZFHMIN_AND_Q_INX, "D,S", MATCH_FCVT_Q_H, MASK_FCVT_Q_H|MASK_RM, match_opcode, 0 },
 {"fcvt.h.s",   0, INSN_CLASS_ZFHMIN_INX, "D,Sm",    MATCH_FCVT_H_S, MASK_FCVT_H_S, match_opcode, 0 },
-{"fcvt.h.d",   0, INSN_CLASS_ZFHMIN_AND_D_INX, "D,Sm", MATCH_FCVT_H_D, MASK_FCVT_H_D, match_opcode, 0 },
+{"fcvt.h.d",   0, INSN_CLASS_ZFHMIN_AND_D_INX, "D,Sm", MATCH_FCVT_H_D, MASK_FCVT_H_D, match_opcode, INSN_RV32_EVEN_S },
 {"fcvt.h.q",   0, INSN_CLASS_ZFHMIN_AND_Q_INX, "D,Sm", MATCH_FCVT_H_Q, MASK_FCVT_H_Q, match_opcode, 0 },
 {"fclass.h",   0, INSN_CLASS_ZFH_INX,   "d,S",       MATCH_FCLASS_H, MASK_FCLASS_H, match_opcode, 0 },
 {"feq.h",      0, INSN_CLASS_ZFH_INX,   "d,S,T",     MATCH_FEQ_H, MASK_FEQ_H, match_opcode, 0 },
@@ -1045,35 +1045,35 @@ const struct riscv_opcode riscv_opcodes[] =
 {"fsd",        0, INSN_CLASS_ZCD, "CD,Cl(Cs)", MATCH_C_FSD, MASK_C_FSD, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
 {"fsd",        0, INSN_CLASS_D,   "T,q(s)",    MATCH_FSD, MASK_FSD, match_opcode, INSN_DREF|INSN_8_BYTE },
 {"fsd",        0, INSN_CLASS_D,   "T,A,s",     0, (int) M_Sx_FSx, match_rs1_nonzero, INSN_MACRO },
-{"fmv.d",      0, INSN_CLASS_D_INX,   "D,U",       MATCH_FSGNJ_D, MASK_FSGNJ_D, match_rs1_eq_rs2, INSN_ALIAS },
-{"fneg.d",     0, INSN_CLASS_D_INX,   "D,U",       MATCH_FSGNJN_D, MASK_FSGNJN_D, match_rs1_eq_rs2, INSN_ALIAS },
-{"fabs.d",     0, INSN_CLASS_D_INX,   "D,U",       MATCH_FSGNJX_D, MASK_FSGNJX_D, match_rs1_eq_rs2, INSN_ALIAS },
-{"fsgnj.d",    0, INSN_CLASS_D_INX,   "D,S,T",     MATCH_FSGNJ_D, MASK_FSGNJ_D, match_opcode, 0 },
-{"fsgnjn.d",   0, INSN_CLASS_D_INX,   "D,S,T",     MATCH_FSGNJN_D, MASK_FSGNJN_D, match_opcode, 0 },
-{"fsgnjx.d",   0, INSN_CLASS_D_INX,   "D,S,T",     MATCH_FSGNJX_D, MASK_FSGNJX_D, match_opcode, 0 },
-{"fadd.d",     0, INSN_CLASS_D_INX,   "D,S,Tm",    MATCH_FADD_D, MASK_FADD_D, match_opcode, 0 },
-{"fsub.d",     0, INSN_CLASS_D_INX,   "D,S,Tm",    MATCH_FSUB_D, MASK_FSUB_D, match_opcode, 0 },
-{"fmul.d",     0, INSN_CLASS_D_INX,   "D,S,Tm",    MATCH_FMUL_D, MASK_FMUL_D, match_opcode, 0 },
-{"fdiv.d",     0, INSN_CLASS_D_INX,   "D,S,Tm",    MATCH_FDIV_D, MASK_FDIV_D, match_opcode, 0 },
-{"fsqrt.d",    0, INSN_CLASS_D_INX,   "D,Sm",      MATCH_FSQRT_D, MASK_FSQRT_D, match_opcode, 0 },
-{"fmin.d",     0, INSN_CLASS_D_INX,   "D,S,T",     MATCH_FMIN_D, MASK_FMIN_D, match_opcode, 0 },
-{"fmax.d",     0, INSN_CLASS_D_INX,   "D,S,T",     MATCH_FMAX_D, MASK_FMAX_D, match_opcode, 0 },
-{"fmadd.d",    0, INSN_CLASS_D_INX,   "D,S,T,Rm",  MATCH_FMADD_D, MASK_FMADD_D, match_opcode, 0 },
-{"fnmadd.d",   0, INSN_CLASS_D_INX,   "D,S,T,Rm",  MATCH_FNMADD_D, MASK_FNMADD_D, match_opcode, 0 },
-{"fmsub.d",    0, INSN_CLASS_D_INX,   "D,S,T,Rm",  MATCH_FMSUB_D, MASK_FMSUB_D, match_opcode, 0 },
-{"fnmsub.d",   0, INSN_CLASS_D_INX,   "D,S,T,Rm",  MATCH_FNMSUB_D, MASK_FNMSUB_D, match_opcode, 0 },
-{"fcvt.w.d",   0, INSN_CLASS_D_INX,   "d,Sm",      MATCH_FCVT_W_D, MASK_FCVT_W_D, match_opcode, 0 },
-{"fcvt.wu.d",  0, INSN_CLASS_D_INX,   "d,Sm",      MATCH_FCVT_WU_D, MASK_FCVT_WU_D, match_opcode, 0 },
-{"fcvt.d.w",   0, INSN_CLASS_D_INX,   "D,s",       MATCH_FCVT_D_W, MASK_FCVT_D_W|MASK_RM, match_opcode, 0 },
-{"fcvt.d.wu",  0, INSN_CLASS_D_INX,   "D,s",       MATCH_FCVT_D_WU, MASK_FCVT_D_WU|MASK_RM, match_opcode, 0 },
-{"fcvt.d.s",   0, INSN_CLASS_D_INX,   "D,S",       MATCH_FCVT_D_S, MASK_FCVT_D_S|MASK_RM, match_opcode, 0 },
-{"fcvt.s.d",   0, INSN_CLASS_D_INX,   "D,Sm",      MATCH_FCVT_S_D, MASK_FCVT_S_D, match_opcode, 0 },
-{"fclass.d",   0, INSN_CLASS_D_INX,   "d,S",       MATCH_FCLASS_D, MASK_FCLASS_D, match_opcode, 0 },
-{"feq.d",      0, INSN_CLASS_D_INX,   "d,S,T",     MATCH_FEQ_D, MASK_FEQ_D, match_opcode, 0 },
-{"flt.d",      0, INSN_CLASS_D_INX,   "d,S,T",     MATCH_FLT_D, MASK_FLT_D, match_opcode, 0 },
-{"fle.d",      0, INSN_CLASS_D_INX,   "d,S,T",     MATCH_FLE_D, MASK_FLE_D, match_opcode, 0 },
-{"fgt.d",      0, INSN_CLASS_D_INX,   "d,T,S",     MATCH_FLT_D, MASK_FLT_D, match_opcode, INSN_ALIAS },
-{"fge.d",      0, INSN_CLASS_D_INX,   "d,T,S",     MATCH_FLE_D, MASK_FLE_D, match_opcode, INSN_ALIAS },
+{"fmv.d",      0, INSN_CLASS_D_INX,   "D,U",       MATCH_FSGNJ_D, MASK_FSGNJ_D, match_rs1_eq_rs2, INSN_ALIAS|INSN_RV32_EVEN_DU },
+{"fneg.d",     0, INSN_CLASS_D_INX,   "D,U",       MATCH_FSGNJN_D, MASK_FSGNJN_D, match_rs1_eq_rs2, INSN_ALIAS|INSN_RV32_EVEN_DU },
+{"fabs.d",     0, INSN_CLASS_D_INX,   "D,U",       MATCH_FSGNJX_D, MASK_FSGNJX_D, match_rs1_eq_rs2, INSN_ALIAS|INSN_RV32_EVEN_DU },
+{"fsgnj.d",    0, INSN_CLASS_D_INX,   "D,S,T",     MATCH_FSGNJ_D, MASK_FSGNJ_D, match_opcode, INSN_RV32_EVEN_DST },
+{"fsgnjn.d",   0, INSN_CLASS_D_INX,   "D,S,T",     MATCH_FSGNJN_D, MASK_FSGNJN_D, match_opcode, INSN_RV32_EVEN_DST },
+{"fsgnjx.d",   0, INSN_CLASS_D_INX,   "D,S,T",     MATCH_FSGNJX_D, MASK_FSGNJX_D, match_opcode, INSN_RV32_EVEN_DST },
+{"fadd.d",     0, INSN_CLASS_D_INX,   "D,S,Tm",    MATCH_FADD_D, MASK_FADD_D, match_opcode, INSN_RV32_EVEN_DST },
+{"fsub.d",     0, INSN_CLASS_D_INX,   "D,S,Tm",    MATCH_FSUB_D, MASK_FSUB_D, match_opcode, INSN_RV32_EVEN_DST },
+{"fmul.d",     0, INSN_CLASS_D_INX,   "D,S,Tm",    MATCH_FMUL_D, MASK_FMUL_D, match_opcode, INSN_RV32_EVEN_DST },
+{"fdiv.d",     0, INSN_CLASS_D_INX,   "D,S,Tm",    MATCH_FDIV_D, MASK_FDIV_D, match_opcode, INSN_RV32_EVEN_DST },
+{"fsqrt.d",    0, INSN_CLASS_D_INX,   "D,Sm",      MATCH_FSQRT_D, MASK_FSQRT_D, match_opcode, INSN_RV32_EVEN_DS },
+{"fmin.d",     0, INSN_CLASS_D_INX,   "D,S,T",     MATCH_FMIN_D, MASK_FMIN_D, match_opcode, INSN_RV32_EVEN_DST },
+{"fmax.d",     0, INSN_CLASS_D_INX,   "D,S,T",     MATCH_FMAX_D, MASK_FMAX_D, match_opcode, INSN_RV32_EVEN_DST },
+{"fmadd.d",    0, INSN_CLASS_D_INX,   "D,S,T,Rm",  MATCH_FMADD_D, MASK_FMADD_D, match_opcode, INSN_RV32_EVEN_DSTR },
+{"fnmadd.d",   0, INSN_CLASS_D_INX,   "D,S,T,Rm",  MATCH_FNMADD_D, MASK_FNMADD_D, match_opcode, INSN_RV32_EVEN_DSTR },
+{"fmsub.d",    0, INSN_CLASS_D_INX,   "D,S,T,Rm",  MATCH_FMSUB_D, MASK_FMSUB_D, match_opcode, INSN_RV32_EVEN_DSTR },
+{"fnmsub.d",   0, INSN_CLASS_D_INX,   "D,S,T,Rm",  MATCH_FNMSUB_D, MASK_FNMSUB_D, match_opcode, INSN_RV32_EVEN_DSTR },
+{"fcvt.w.d",   0, INSN_CLASS_D_INX,   "d,Sm",      MATCH_FCVT_W_D, MASK_FCVT_W_D, match_opcode, INSN_RV32_EVEN_S },
+{"fcvt.wu.d",  0, INSN_CLASS_D_INX,   "d,Sm",      MATCH_FCVT_WU_D, MASK_FCVT_WU_D, match_opcode, INSN_RV32_EVEN_S },
+{"fcvt.d.w",   0, INSN_CLASS_D_INX,   "D,s",       MATCH_FCVT_D_W, MASK_FCVT_D_W|MASK_RM, match_opcode, INSN_RV32_EVEN_D },
+{"fcvt.d.wu",  0, INSN_CLASS_D_INX,   "D,s",       MATCH_FCVT_D_WU, MASK_FCVT_D_WU|MASK_RM, match_opcode, INSN_RV32_EVEN_D },
+{"fcvt.d.s",   0, INSN_CLASS_D_INX,   "D,S",       MATCH_FCVT_D_S, MASK_FCVT_D_S|MASK_RM, match_opcode, INSN_RV32_EVEN_D },
+{"fcvt.s.d",   0, INSN_CLASS_D_INX,   "D,Sm",      MATCH_FCVT_S_D, MASK_FCVT_S_D, match_opcode, INSN_RV32_EVEN_S },
+{"fclass.d",   0, INSN_CLASS_D_INX,   "d,S",       MATCH_FCLASS_D, MASK_FCLASS_D, match_opcode, INSN_RV32_EVEN_S },
+{"feq.d",      0, INSN_CLASS_D_INX,   "d,S,T",     MATCH_FEQ_D, MASK_FEQ_D, match_opcode, INSN_RV32_EVEN_ST },
+{"flt.d",      0, INSN_CLASS_D_INX,   "d,S,T",     MATCH_FLT_D, MASK_FLT_D, match_opcode, INSN_RV32_EVEN_ST },
+{"fle.d",      0, INSN_CLASS_D_INX,   "d,S,T",     MATCH_FLE_D, MASK_FLE_D, match_opcode, INSN_RV32_EVEN_ST },
+{"fgt.d",      0, INSN_CLASS_D_INX,   "d,T,S",     MATCH_FLT_D, MASK_FLT_D, match_opcode, INSN_ALIAS|INSN_RV32_EVEN_ST },
+{"fge.d",      0, INSN_CLASS_D_INX,   "d,T,S",     MATCH_FLE_D, MASK_FLE_D, match_opcode, INSN_ALIAS|INSN_RV32_EVEN_ST },
 {"fmv.x.d",   64, INSN_CLASS_D,   "d,S",       MATCH_FMV_X_D, MASK_FMV_X_D, match_opcode, 0 },
 {"fmv.d.x",   64, INSN_CLASS_D,   "D,s",       MATCH_FMV_D_X, MASK_FMV_D_X, match_opcode, 0 },
 {"fcvt.l.d",  64, INSN_CLASS_D_INX,   "d,Sm",      MATCH_FCVT_L_D, MASK_FCVT_L_D, match_opcode, 0 },


More information about the Binutils-cvs mailing list