@@ -2934,6 +2934,12 @@ riscv_ip (char *str, struct riscv_cl_ins
|| (rclass) != RCLASS_GPR \
|| !((regno) & 1))
+#define RV64_EVEN_CHECK(form, rclass, regno) \
+ (!(ip->insn_mo->pinfo & INSN_RV64_EVEN_##form) \
+ || xlen > 64 \
+ || (rclass) != RCLASS_GPR \
+ || !((regno) & (xlen == 32 ? 3 : 1)))
+
for (oparg = insn->args;; ++oparg)
{
opargStart = oparg;
@@ -3593,12 +3599,14 @@ riscv_ip (char *str, struct riscv_cl_ins
switch (c)
{
case 'D':
- if (!RV32_EVEN_CHECK (D, rclass, regno))
+ if (!RV32_EVEN_CHECK (D, rclass, regno)
+ || !RV64_EVEN_CHECK (D, rclass, regno))
break;
INSERT_OPERAND (RD, *ip, regno);
continue;
case 'S':
- if (!RV32_EVEN_CHECK (S, rclass, regno))
+ if (!RV32_EVEN_CHECK (S, rclass, regno)
+ || !RV64_EVEN_CHECK (S, rclass, regno))
break;
INSERT_OPERAND (RS1, *ip, regno);
continue;
@@ -3606,12 +3614,14 @@ riscv_ip (char *str, struct riscv_cl_ins
INSERT_OPERAND (RS1, *ip, regno);
/* Fall through. */
case 'T':
- if (!RV32_EVEN_CHECK (T, rclass, regno))
+ if (!RV32_EVEN_CHECK (T, rclass, regno)
+ || !RV64_EVEN_CHECK (T, rclass, regno))
break;
INSERT_OPERAND (RS2, *ip, regno);
continue;
case 'R':
- if (!RV32_EVEN_CHECK (R, rclass, regno))
+ if (!RV32_EVEN_CHECK (R, rclass, regno)
+ || !RV64_EVEN_CHECK (R, rclass, regno))
break;
INSERT_OPERAND (RS3, *ip, regno);
continue;
@@ -4312,6 +4322,7 @@ riscv_ip (char *str, struct riscv_cl_ins
}
#undef RV32_EVEN_CHECK
+#undef RV64_EVEN_CHECK
out:
/* Restore the character we might have clobbered above. */
@@ -0,0 +1,52 @@
+#as: -march=rv32i_zqinx
+#objdump: -dwr
+
+.*:[ ]+file format .*
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ ]+[0-9a-f]+:[ ]+078a7453[ ]+fadd\.q[ ]+s0,s4,s8
+[ ]+[0-9a-f]+:[ ]+078a0453[ ]+fadd\.q[ ]+s0,s4,s8,rne
+[ ]+[0-9a-f]+:[ ]+0f8a7453[ ]+fsub\.q[ ]+s0,s4,s8
+[ ]+[0-9a-f]+:[ ]+0f8a0453[ ]+fsub\.q[ ]+s0,s4,s8,rne
+[ ]+[0-9a-f]+:[ ]+178a7453[ ]+fmul\.q[ ]+s0,s4,s8
+[ ]+[0-9a-f]+:[ ]+178a0453[ ]+fmul\.q[ ]+s0,s4,s8,rne
+[ ]+[0-9a-f]+:[ ]+1f8a7453[ ]+fdiv\.q[ ]+s0,s4,s8
+[ ]+[0-9a-f]+:[ ]+1f8a0453[ ]+fdiv\.q[ ]+s0,s4,s8,rne
+[ ]+[0-9a-f]+:[ ]+5e0a7453[ ]+fsqrt\.q[ ]+s0,s4
+[ ]+[0-9a-f]+:[ ]+5e0a0453[ ]+fsqrt\.q[ ]+s0,s4,rne
+[ ]+[0-9a-f]+:[ ]+2f8a0453[ ]+fmin\.q[ ]+s0,s4,s8
+[ ]+[0-9a-f]+:[ ]+2f8a1453[ ]+fmax\.q[ ]+s0,s4,s8
+[ ]+[0-9a-f]+:[ ]+678a7443[ ]+fmadd\.q[ ]+s0,s4,s8,a2
+[ ]+[0-9a-f]+:[ ]+678a0443[ ]+fmadd\.q[ ]+s0,s4,s8,a2,rne
+[ ]+[0-9a-f]+:[ ]+678a744f[ ]+fnmadd\.q[ ]+s0,s4,s8,a2
+[ ]+[0-9a-f]+:[ ]+678a044f[ ]+fnmadd\.q[ ]+s0,s4,s8,a2,rne
+[ ]+[0-9a-f]+:[ ]+678a7447[ ]+fmsub\.q[ ]+s0,s4,s8,a2
+[ ]+[0-9a-f]+:[ ]+678a0447[ ]+fmsub\.q[ ]+s0,s4,s8,a2,rne
+[ ]+[0-9a-f]+:[ ]+678a744b[ ]+fnmsub\.q[ ]+s0,s4,s8,a2
+[ ]+[0-9a-f]+:[ ]+678a044b[ ]+fnmsub\.q[ ]+s0,s4,s8,a2,rne
+[ ]+[0-9a-f]+:[ ]+c60a75d3[ ]+fcvt\.w\.q[ ]+a1,s4
+[ ]+[0-9a-f]+:[ ]+c60a05d3[ ]+fcvt\.w\.q[ ]+a1,s4,rne
+[ ]+[0-9a-f]+:[ ]+c61a75d3[ ]+fcvt\.wu\.q[ ]+a1,s4
+[ ]+[0-9a-f]+:[ ]+c61a05d3[ ]+fcvt\.wu\.q[ ]+a1,s4,rne
+[ ]+[0-9a-f]+:[ ]+d6058453[ ]+fcvt\.q\.w[ ]+s0,a1
+[ ]+[0-9a-f]+:[ ]+d6158453[ ]+fcvt\.q\.wu[ ]+s0,a1
+[ ]+[0-9a-f]+:[ ]+46058453[ ]+fcvt\.q\.s[ ]+s0,a1
+[ ]+[0-9a-f]+:[ ]+403a75d3[ ]+fcvt\.s\.q[ ]+a1,s4
+[ ]+[0-9a-f]+:[ ]+403a05d3[ ]+fcvt\.s\.q[ ]+a1,s4,rne
+[ ]+[0-9a-f]+:[ ]+46150453[ ]+fcvt\.q\.d[ ]+s0,a0
+[ ]+[0-9a-f]+:[ ]+423a7553[ ]+fcvt\.d\.q[ ]+a0,s4
+[ ]+[0-9a-f]+:[ ]+423a0553[ ]+fcvt\.d\.q[ ]+a0,s4,rne
+[ ]+[0-9a-f]+:[ ]+46258453[ ]+fcvt\.q\.h[ ]+s0,a1
+[ ]+[0-9a-f]+:[ ]+443a75d3[ ]+fcvt\.h\.q[ ]+a1,s4
+[ ]+[0-9a-f]+:[ ]+443a05d3[ ]+fcvt\.h\.q[ ]+a1,s4,rne
+[ ]+[0-9a-f]+:[ ]+278a0453[ ]+fsgnj\.q[ ]+s0,s4,s8
+[ ]+[0-9a-f]+:[ ]+278a1453[ ]+fsgnjn\.q[ ]+s0,s4,s8
+[ ]+[0-9a-f]+:[ ]+278a2453[ ]+fsgnjx\.q[ ]+s0,s4,s8
+[ ]+[0-9a-f]+:[ ]+a78a25d3[ ]+feq\.q[ ]+a1,s4,s8
+[ ]+[0-9a-f]+:[ ]+a78a15d3[ ]+flt\.q[ ]+a1,s4,s8
+[ ]+[0-9a-f]+:[ ]+a78a05d3[ ]+fle\.q[ ]+a1,s4,s8
+[ ]+[0-9a-f]+:[ ]+a74c15d3[ ]+flt\.q[ ]+a1,s8,s4
+[ ]+[0-9a-f]+:[ ]+a74c05d3[ ]+fle\.q[ ]+a1,s8,s4
+[ ]+[0-9a-f]+:[ ]+274a0453[ ]+fmv\.q[ ]+s0,s4
@@ -0,0 +1,54 @@
+target:
+ fadd.q s0, s4, s8
+ fadd.q s0, s4, s8, rne
+ fsub.q s0, s4, s8
+ fsub.q s0, s4, s8, rne
+ fmul.q s0, s4, s8
+ fmul.q s0, s4, s8, rne
+ fdiv.q s0, s4, s8
+ fdiv.q s0, s4, s8, rne
+ fsqrt.q s0, s4
+ fsqrt.q s0, s4, rne
+ fmin.q s0, s4, s8
+ fmax.q s0, s4, s8
+ fmadd.q s0, s4, s8, a2
+ fmadd.q s0, s4, s8, a2, rne
+ fnmadd.q s0, s4, s8, a2
+ fnmadd.q s0, s4, s8, a2, rne
+ fmsub.q s0, s4, s8, a2
+ fmsub.q s0, s4, s8, a2, rne
+ fnmsub.q s0, s4, s8, a2
+ fnmsub.q s0, s4, s8, a2, rne
+
+ fcvt.w.q a1, s4
+ fcvt.w.q a1, s4, rne
+ fcvt.wu.q a1, s4
+ fcvt.wu.q a1, s4, rne
+ fcvt.q.w s0, a1
+ fcvt.q.wu s0, a1
+
+ fcvt.q.s s0, a1
+ fcvt.s.q a1, s4
+ fcvt.s.q a1, s4, rne
+
+ fcvt.q.d s0, a0
+ fcvt.d.q a0, s4
+ fcvt.d.q a0, s4, rne
+
+ .option push
+ .option arch, +zhinxmin
+ fcvt.q.h s0, a1
+ fcvt.h.q a1, s4
+ fcvt.h.q a1, s4, rne
+ .option pop
+
+ fsgnj.q s0, s4, s8
+ fsgnjn.q s0, s4, s8
+ fsgnjx.q s0, s4, s8
+ feq.q a1, s4, s8
+ flt.q a1, s4, s8
+ fle.q a1, s4, s8
+ fgt.q a1, s4, s8
+ fge.q a1, s4, s8
+
+ fmv.q s0, s4
@@ -0,0 +1,3 @@
+#as: -march=rv32i_zqinx
+#source: zqinx.s
+#error_output: zqinx-rv32-fail.l
@@ -0,0 +1,42 @@
+.*: Assembler messages:
+.*: Error: illegal operands `fadd\.q .*'
+.*: Error: illegal operands `fadd\.q .*'
+.*: Error: illegal operands `fsub\.q .*'
+.*: Error: illegal operands `fsub\.q .*'
+.*: Error: illegal operands `fmul\.q .*'
+.*: Error: illegal operands `fmul\.q .*'
+.*: Error: illegal operands `fdiv\.q .*'
+.*: Error: illegal operands `fdiv\.q .*'
+.*: Error: illegal operands `fsqrt\.q .*'
+.*: Error: illegal operands `fsqrt\.q .*'
+.*: Error: illegal operands `fmin\.q .*'
+.*: Error: illegal operands `fmax\.q .*'
+.*: Error: illegal operands `fmadd\.q .*'
+.*: Error: illegal operands `fmadd\.q .*'
+.*: Error: illegal operands `fnmadd\.q .*'
+.*: Error: illegal operands `fnmadd\.q .*'
+.*: Error: illegal operands `fmsub\.q .*'
+.*: Error: illegal operands `fmsub\.q .*'
+.*: Error: illegal operands `fnmsub\.q .*'
+.*: Error: illegal operands `fnmsub\.q .*'
+.*: Error: unrecognized opcode `fcvt\.l\.q .*'
+.*: Error: unrecognized opcode `fcvt\.l\.q .*'
+.*: Error: unrecognized opcode `fcvt\.lu\.q .*'
+.*: Error: unrecognized opcode `fcvt\.lu\.q .*'
+.*: Error: illegal operands `fcvt\.q\.w .*'
+.*: Error: illegal operands `fcvt\.q\.wu .*'
+.*: Error: unrecognized opcode `fcvt\.q\.l .*'
+.*: Error: unrecognized opcode `fcvt\.q\.lu .*'
+.*: Error: illegal operands `fcvt\.q\.s .*'
+.*: Error: illegal operands `fcvt\.q\.d .*'
+.*: Error: illegal operands `fsgnj\.q .*'
+.*: Error: illegal operands `fsgnjn\.q .*'
+.*: Error: illegal operands `fsgnjx\.q .*'
+.*: Error: illegal operands `feq\.q .*'
+.*: Error: illegal operands `flt\.q .*'
+.*: Error: illegal operands `fle\.q .*'
+.*: Error: illegal operands `fgt\.q .*'
+.*: Error: illegal operands `fge\.q .*'
+.*: Error: illegal operands `fmv\.q .*'
+.*: Error: illegal operands `fneg\.q .*'
+.*: Error: illegal operands `fabs\.q .*'
@@ -0,0 +1,2 @@
+#as: -march=rv64i_zqinx
+#error_output: zqinx-rv64-fail.l
@@ -0,0 +1,62 @@
+.*: Assembler messages:
+.*: Error: illegal operands `fadd\.q .*'
+.*: Error: illegal operands `fadd\.q .*'
+.*: Error: illegal operands `fadd\.q .*'
+.*: Error: illegal operands `fsub\.q .*'
+.*: Error: illegal operands `fsub\.q .*'
+.*: Error: illegal operands `fsub\.q .*'
+.*: Error: illegal operands `fmul\.q .*'
+.*: Error: illegal operands `fmul\.q .*'
+.*: Error: illegal operands `fmul\.q .*'
+.*: Error: illegal operands `fdiv\.q .*'
+.*: Error: illegal operands `fdiv\.q .*'
+.*: Error: illegal operands `fdiv\.q .*'
+.*: Error: illegal operands `fsqrt\.q .*'
+.*: Error: illegal operands `fsqrt\.q .*'
+.*: Error: illegal operands `fmin\.q .*'
+.*: Error: illegal operands `fmin\.q .*'
+.*: Error: illegal operands `fmin\.q .*'
+.*: Error: illegal operands `fmax\.q .*'
+.*: Error: illegal operands `fmax\.q .*'
+.*: Error: illegal operands `fmax\.q .*'
+.*: Error: illegal operands `fmadd\.q .*'
+.*: Error: illegal operands `fmadd\.q .*'
+.*: Error: illegal operands `fmadd\.q .*'
+.*: Error: illegal operands `fmadd\.q .*'
+.*: Error: illegal operands `fnmadd\.q .*'
+.*: Error: illegal operands `fnmadd\.q .*'
+.*: Error: illegal operands `fnmadd\.q .*'
+.*: Error: illegal operands `fnmadd\.q .*'
+.*: Error: illegal operands `fmsub\.q .*'
+.*: Error: illegal operands `fmsub\.q .*'
+.*: Error: illegal operands `fmsub\.q .*'
+.*: Error: illegal operands `fmsub\.q .*'
+.*: Error: illegal operands `fnmsub\.q .*'
+.*: Error: illegal operands `fnmsub\.q .*'
+.*: Error: illegal operands `fnmsub\.q .*'
+.*: Error: illegal operands `fnmsub\.q .*'
+.*: Error: illegal operands `fcvt\.w\.q .*'
+.*: Error: illegal operands `fcvt\.wu\.q .*'
+.*: Error: illegal operands `fcvt\.q\.w .*'
+.*: Error: illegal operands `fcvt\.q\.wu .*'
+.*: Error: illegal operands `fcvt\.q\.s .*'
+.*: Error: illegal operands `fcvt\.s\.q .*'
+.*: Error: illegal operands `fcvt\.q\.d .*'
+.*: Error: illegal operands `fcvt\.d\.q .*'
+.*: Error: illegal operands `fcvt\.q\.h .*'
+.*: Error: illegal operands `fcvt\.h\.q .*'
+.*: Error: illegal operands `fsgnj\.q .*'
+.*: Error: illegal operands `fsgnjn\.q .*'
+.*: Error: illegal operands `fsgnjx\.q .*'
+.*: Error: illegal operands `feq\.q .*'
+.*: Error: illegal operands `flt\.q .*'
+.*: Error: illegal operands `fle\.q .*'
+.*: Error: illegal operands `fgt\.q .*'
+.*: Error: illegal operands `fge\.q .*'
+.*: Error: illegal operands `fmv\.q .*'
+.*: Error: illegal operands `fmv\.q .*'
+.*: Error: illegal operands `fneg\.q .*'
+.*: Error: illegal operands `fneg\.q .*'
+.*: Error: illegal operands `fabs\.q .*'
+.*: Error: illegal operands `fabs\.q .*'
+.*: Error: illegal operands `fclass\.q .*'
@@ -0,0 +1,70 @@
+target:
+ fadd.q s1, s4, s8
+ fadd.q s0, s5, s8
+ fadd.q s0, s4, s9
+ fsub.q s1, s4, s8
+ fsub.q s0, s5, s8
+ fsub.q s0, s4, s9
+ fmul.q s1, s4, s8
+ fmul.q s0, s5, s8
+ fmul.q s0, s4, s9
+ fdiv.q s1, s4, s8
+ fdiv.q s0, s5, s8
+ fdiv.q s0, s4, s9
+ fsqrt.q s1, s4
+ fsqrt.q s0, s5
+ fmin.q s1, s4, s8
+ fmin.q s0, s5, s8
+ fmin.q s0, s4, s9
+ fmax.q s1, s4, s8
+ fmax.q s0, s5, s8
+ fmax.q s0, s4, s9
+ fmadd.q s1, s4, s8, a2
+ fmadd.q s0, s5, s8, a2
+ fmadd.q s0, s4, s9, a2
+ fmadd.q s0, s4, s8, a3
+ fnmadd.q s1, s4, s8, a2
+ fnmadd.q s0, s5, s8, a2
+ fnmadd.q s0, s4, s9, a2
+ fnmadd.q s0, s4, s8, a3
+ fmsub.q s1, s4, s8, a2
+ fmsub.q s0, s5, s8, a2
+ fmsub.q s0, s4, s9, a2
+ fmsub.q s0, s4, s8, a3
+ fnmsub.q s1, s4, s8, a2
+ fnmsub.q s0, s5, s8, a2
+ fnmsub.q s0, s4, s9, a2
+ fnmsub.q s0, s4, s8, a3
+
+ fcvt.w.q a0, s5
+ fcvt.wu.q a0, s5
+ fcvt.q.w s1, a0
+ fcvt.q.wu s1, a0
+
+ fcvt.q.s s1, a0
+ fcvt.s.q a0, s5
+
+ fcvt.q.d s1, a0
+ fcvt.d.q a0, s5
+
+ .option push
+ .option arch, +zhinxmin
+ fcvt.q.h s1, a0
+ fcvt.h.q a0, s5
+ .option pop
+
+ fsgnj.q s1, s4, s8
+ fsgnjn.q s0, s5, s8
+ fsgnjx.q s0, s4, s9
+ feq.q a0, s5, s8
+ flt.q a0, s4, s9
+ fle.q a0, s5, s8
+ fgt.q a0, s4, s9
+ fge.q a0, s5, s8
+ fmv.q s1, s4
+ fmv.q s0, s5
+ fneg.q s1, s4
+ fneg.q s0, s5
+ fabs.q s1, s4
+ fabs.q s0, s5
+ fclass.q a0, s5
@@ -691,6 +691,19 @@ struct riscv_opcode
#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)
+/* Operands required to be an even-numbered register (pair) in RV64, and one
+ divisible by 4 on RV32. */
+#define INSN_RV64_EVEN_D 0x00001000
+#define INSN_RV64_EVEN_S 0x00002000
+#define INSN_RV64_EVEN_T 0x00004000 /* Also covering U. */
+#define INSN_RV64_EVEN_R 0x00008000
+/* Shorthands for combinations of the above. */
+#define INSN_RV64_EVEN_DS (INSN_RV64_EVEN_D | INSN_RV64_EVEN_S)
+#define INSN_RV64_EVEN_DST (INSN_RV64_EVEN_DS | INSN_RV64_EVEN_T)
+#define INSN_RV64_EVEN_DSTR (INSN_RV64_EVEN_DST | INSN_RV64_EVEN_R)
+#define INSN_RV64_EVEN_DU (INSN_RV64_EVEN_D | INSN_RV64_EVEN_T)
+#define INSN_RV64_EVEN_ST (INSN_RV64_EVEN_S | INSN_RV64_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
@@ -1049,6 +1049,25 @@ riscv_disassemble_insn (bfd_vma memaddr,
&& (word & (1u << OP_SH_RS3)))
continue;
}
+
+ if (pd->xlen <= 64
+ && riscv_subset_supports (&pd->riscv_rps_dis, "zqinx"))
+ {
+ unsigned int mask = pd->xlen == 32 ? 3 : 1;
+
+ if ((op->pinfo & INSN_RV64_EVEN_D)
+ && (word & (mask << OP_SH_RD)))
+ continue;
+ if ((op->pinfo & INSN_RV64_EVEN_S)
+ && (word & (mask << OP_SH_RS1)))
+ continue;
+ if ((op->pinfo & INSN_RV64_EVEN_T)
+ && (word & (mask << OP_SH_RS2)))
+ continue;
+ if ((op->pinfo & INSN_RV64_EVEN_R)
+ && (word & (mask << OP_SH_RS3)))
+ continue;
+ }
}
/* It's a match. */
@@ -932,10 +932,10 @@ const struct riscv_opcode riscv_opcodes[
{"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, 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.q.h", 0, INSN_CLASS_ZFHMIN_AND_Q_INX, "D,S", MATCH_FCVT_Q_H, MASK_FCVT_Q_H|MASK_RM, match_opcode, INSN_RV64_EVEN_D },
{"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, 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 },
+{"fcvt.h.q", 0, INSN_CLASS_ZFHMIN_AND_Q_INX, "D,Sm", MATCH_FCVT_H_Q, MASK_FCVT_H_Q, match_opcode, INSN_RV64_EVEN_S },
{"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 },
{"flt.h", 0, INSN_CLASS_ZFH_INX, "d,S,T", MATCH_FLT_H, MASK_FLT_H, match_opcode, 0 },
@@ -1062,41 +1062,41 @@ const struct riscv_opcode riscv_opcodes[
{"flq", 0, INSN_CLASS_Q, "D,A,s", 0, (int) M_FLx, match_rs1_nonzero, INSN_MACRO },
{"fsq", 0, INSN_CLASS_Q, "T,q(s)", MATCH_FSQ, MASK_FSQ, match_opcode, INSN_DREF|INSN_16_BYTE },
{"fsq", 0, INSN_CLASS_Q, "T,A,s", 0, (int) M_Sx_FSx, match_rs1_nonzero, INSN_MACRO },
-{"fmv.q", 0, INSN_CLASS_Q_INX, "D,U", MATCH_FSGNJ_Q, MASK_FSGNJ_Q, match_rs1_eq_rs2, INSN_ALIAS },
-{"fneg.q", 0, INSN_CLASS_Q_INX, "D,U", MATCH_FSGNJN_Q, MASK_FSGNJN_Q, match_rs1_eq_rs2, INSN_ALIAS },
-{"fabs.q", 0, INSN_CLASS_Q_INX, "D,U", MATCH_FSGNJX_Q, MASK_FSGNJX_Q, match_rs1_eq_rs2, INSN_ALIAS },
-{"fsgnj.q", 0, INSN_CLASS_Q_INX, "D,S,T", MATCH_FSGNJ_Q, MASK_FSGNJ_Q, match_opcode, 0 },
-{"fsgnjn.q", 0, INSN_CLASS_Q_INX, "D,S,T", MATCH_FSGNJN_Q, MASK_FSGNJN_Q, match_opcode, 0 },
-{"fsgnjx.q", 0, INSN_CLASS_Q_INX, "D,S,T", MATCH_FSGNJX_Q, MASK_FSGNJX_Q, match_opcode, 0 },
-{"fadd.q", 0, INSN_CLASS_Q_INX, "D,S,Tm", MATCH_FADD_Q, MASK_FADD_Q, match_opcode, 0 },
-{"fsub.q", 0, INSN_CLASS_Q_INX, "D,S,Tm", MATCH_FSUB_Q, MASK_FSUB_Q, match_opcode, 0 },
-{"fmul.q", 0, INSN_CLASS_Q_INX, "D,S,Tm", MATCH_FMUL_Q, MASK_FMUL_Q, match_opcode, 0 },
-{"fdiv.q", 0, INSN_CLASS_Q_INX, "D,S,Tm", MATCH_FDIV_Q, MASK_FDIV_Q, match_opcode, 0 },
-{"fsqrt.q", 0, INSN_CLASS_Q_INX, "D,Sm", MATCH_FSQRT_Q, MASK_FSQRT_Q, match_opcode, 0 },
-{"fmin.q", 0, INSN_CLASS_Q_INX, "D,S,T", MATCH_FMIN_Q, MASK_FMIN_Q, match_opcode, 0 },
-{"fmax.q", 0, INSN_CLASS_Q_INX, "D,S,T", MATCH_FMAX_Q, MASK_FMAX_Q, match_opcode, 0 },
-{"fmadd.q", 0, INSN_CLASS_Q_INX, "D,S,T,Rm", MATCH_FMADD_Q, MASK_FMADD_Q, match_opcode, 0 },
-{"fnmadd.q", 0, INSN_CLASS_Q_INX, "D,S,T,Rm", MATCH_FNMADD_Q, MASK_FNMADD_Q, match_opcode, 0 },
-{"fmsub.q", 0, INSN_CLASS_Q_INX, "D,S,T,Rm", MATCH_FMSUB_Q, MASK_FMSUB_Q, match_opcode, 0 },
-{"fnmsub.q", 0, INSN_CLASS_Q_INX, "D,S,T,Rm", MATCH_FNMSUB_Q, MASK_FNMSUB_Q, match_opcode, 0 },
-{"fcvt.w.q", 0, INSN_CLASS_Q_INX, "d,Sm", MATCH_FCVT_W_Q, MASK_FCVT_W_Q, match_opcode, 0 },
-{"fcvt.wu.q", 0, INSN_CLASS_Q_INX, "d,Sm", MATCH_FCVT_WU_Q, MASK_FCVT_WU_Q, match_opcode, 0 },
-{"fcvt.q.w", 0, INSN_CLASS_Q_INX, "D,s", MATCH_FCVT_Q_W, MASK_FCVT_Q_W|MASK_RM, match_opcode, 0 },
-{"fcvt.q.wu", 0, INSN_CLASS_Q_INX, "D,s", MATCH_FCVT_Q_WU, MASK_FCVT_Q_WU|MASK_RM, match_opcode, 0 },
-{"fcvt.q.s", 0, INSN_CLASS_Q_INX, "D,S", MATCH_FCVT_Q_S, MASK_FCVT_Q_S|MASK_RM, match_opcode, 0 },
-{"fcvt.q.d", 0, INSN_CLASS_Q_INX, "D,S", MATCH_FCVT_Q_D, MASK_FCVT_Q_D|MASK_RM, match_opcode, 0 },
-{"fcvt.s.q", 0, INSN_CLASS_Q_INX, "D,Sm", MATCH_FCVT_S_Q, MASK_FCVT_S_Q, match_opcode, 0 },
-{"fcvt.d.q", 0, INSN_CLASS_Q_INX, "D,Sm", MATCH_FCVT_D_Q, MASK_FCVT_D_Q, match_opcode, 0 },
-{"fclass.q", 0, INSN_CLASS_Q_INX, "d,S", MATCH_FCLASS_Q, MASK_FCLASS_Q, match_opcode, 0 },
-{"feq.q", 0, INSN_CLASS_Q_INX, "d,S,T", MATCH_FEQ_Q, MASK_FEQ_Q, match_opcode, 0 },
-{"flt.q", 0, INSN_CLASS_Q_INX, "d,S,T", MATCH_FLT_Q, MASK_FLT_Q, match_opcode, 0 },
-{"fle.q", 0, INSN_CLASS_Q_INX, "d,S,T", MATCH_FLE_Q, MASK_FLE_Q, match_opcode, 0 },
-{"fgt.q", 0, INSN_CLASS_Q_INX, "d,T,S", MATCH_FLT_Q, MASK_FLT_Q, match_opcode, INSN_ALIAS },
-{"fge.q", 0, INSN_CLASS_Q_INX, "d,T,S", MATCH_FLE_Q, MASK_FLE_Q, match_opcode, INSN_ALIAS },
-{"fcvt.l.q", 64, INSN_CLASS_Q_INX, "d,Sm", MATCH_FCVT_L_Q, MASK_FCVT_L_Q, match_opcode, 0 },
-{"fcvt.lu.q", 64, INSN_CLASS_Q_INX, "d,Sm", MATCH_FCVT_LU_Q, MASK_FCVT_LU_Q, match_opcode, 0 },
-{"fcvt.q.l", 64, INSN_CLASS_Q_INX, "D,s", MATCH_FCVT_Q_L, MASK_FCVT_Q_L|MASK_RM, match_opcode, 0 },
-{"fcvt.q.lu", 64, INSN_CLASS_Q_INX, "D,s", MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU|MASK_RM, match_opcode, 0 },
+{"fmv.q", 0, INSN_CLASS_Q_INX, "D,U", MATCH_FSGNJ_Q, MASK_FSGNJ_Q, match_rs1_eq_rs2, INSN_ALIAS|INSN_RV64_EVEN_DU },
+{"fneg.q", 0, INSN_CLASS_Q_INX, "D,U", MATCH_FSGNJN_Q, MASK_FSGNJN_Q, match_rs1_eq_rs2, INSN_ALIAS|INSN_RV64_EVEN_DU },
+{"fabs.q", 0, INSN_CLASS_Q_INX, "D,U", MATCH_FSGNJX_Q, MASK_FSGNJX_Q, match_rs1_eq_rs2, INSN_ALIAS|INSN_RV64_EVEN_DU },
+{"fsgnj.q", 0, INSN_CLASS_Q_INX, "D,S,T", MATCH_FSGNJ_Q, MASK_FSGNJ_Q, match_opcode, INSN_RV64_EVEN_DST },
+{"fsgnjn.q", 0, INSN_CLASS_Q_INX, "D,S,T", MATCH_FSGNJN_Q, MASK_FSGNJN_Q, match_opcode, INSN_RV64_EVEN_DST },
+{"fsgnjx.q", 0, INSN_CLASS_Q_INX, "D,S,T", MATCH_FSGNJX_Q, MASK_FSGNJX_Q, match_opcode, INSN_RV64_EVEN_DST },
+{"fadd.q", 0, INSN_CLASS_Q_INX, "D,S,Tm", MATCH_FADD_Q, MASK_FADD_Q, match_opcode, INSN_RV64_EVEN_DST },
+{"fsub.q", 0, INSN_CLASS_Q_INX, "D,S,Tm", MATCH_FSUB_Q, MASK_FSUB_Q, match_opcode, INSN_RV64_EVEN_DST },
+{"fmul.q", 0, INSN_CLASS_Q_INX, "D,S,Tm", MATCH_FMUL_Q, MASK_FMUL_Q, match_opcode, INSN_RV64_EVEN_DST },
+{"fdiv.q", 0, INSN_CLASS_Q_INX, "D,S,Tm", MATCH_FDIV_Q, MASK_FDIV_Q, match_opcode, INSN_RV64_EVEN_DST },
+{"fsqrt.q", 0, INSN_CLASS_Q_INX, "D,Sm", MATCH_FSQRT_Q, MASK_FSQRT_Q, match_opcode, INSN_RV64_EVEN_DS },
+{"fmin.q", 0, INSN_CLASS_Q_INX, "D,S,T", MATCH_FMIN_Q, MASK_FMIN_Q, match_opcode, INSN_RV64_EVEN_DST },
+{"fmax.q", 0, INSN_CLASS_Q_INX, "D,S,T", MATCH_FMAX_Q, MASK_FMAX_Q, match_opcode, INSN_RV64_EVEN_DST },
+{"fmadd.q", 0, INSN_CLASS_Q_INX, "D,S,T,Rm", MATCH_FMADD_Q, MASK_FMADD_Q, match_opcode, INSN_RV64_EVEN_DSTR },
+{"fnmadd.q", 0, INSN_CLASS_Q_INX, "D,S,T,Rm", MATCH_FNMADD_Q, MASK_FNMADD_Q, match_opcode, INSN_RV64_EVEN_DSTR },
+{"fmsub.q", 0, INSN_CLASS_Q_INX, "D,S,T,Rm", MATCH_FMSUB_Q, MASK_FMSUB_Q, match_opcode, INSN_RV64_EVEN_DSTR },
+{"fnmsub.q", 0, INSN_CLASS_Q_INX, "D,S,T,Rm", MATCH_FNMSUB_Q, MASK_FNMSUB_Q, match_opcode, INSN_RV64_EVEN_DSTR },
+{"fcvt.w.q", 0, INSN_CLASS_Q_INX, "d,Sm", MATCH_FCVT_W_Q, MASK_FCVT_W_Q, match_opcode, INSN_RV64_EVEN_S },
+{"fcvt.wu.q", 0, INSN_CLASS_Q_INX, "d,Sm", MATCH_FCVT_WU_Q, MASK_FCVT_WU_Q, match_opcode, INSN_RV64_EVEN_S },
+{"fcvt.q.w", 0, INSN_CLASS_Q_INX, "D,s", MATCH_FCVT_Q_W, MASK_FCVT_Q_W|MASK_RM, match_opcode, INSN_RV64_EVEN_D },
+{"fcvt.q.wu", 0, INSN_CLASS_Q_INX, "D,s", MATCH_FCVT_Q_WU, MASK_FCVT_Q_WU|MASK_RM, match_opcode, INSN_RV64_EVEN_D },
+{"fcvt.q.s", 0, INSN_CLASS_Q_INX, "D,S", MATCH_FCVT_Q_S, MASK_FCVT_Q_S|MASK_RM, match_opcode, INSN_RV64_EVEN_D },
+{"fcvt.q.d", 0, INSN_CLASS_Q_INX, "D,S", MATCH_FCVT_Q_D, MASK_FCVT_Q_D|MASK_RM, match_opcode, INSN_RV64_EVEN_D|INSN_RV32_EVEN_S },
+{"fcvt.s.q", 0, INSN_CLASS_Q_INX, "D,Sm", MATCH_FCVT_S_Q, MASK_FCVT_S_Q, match_opcode, INSN_RV64_EVEN_S },
+{"fcvt.d.q", 0, INSN_CLASS_Q_INX, "D,Sm", MATCH_FCVT_D_Q, MASK_FCVT_D_Q, match_opcode, INSN_RV32_EVEN_D|INSN_RV64_EVEN_S },
+{"fclass.q", 0, INSN_CLASS_Q_INX, "d,S", MATCH_FCLASS_Q, MASK_FCLASS_Q, match_opcode, INSN_RV64_EVEN_S },
+{"feq.q", 0, INSN_CLASS_Q_INX, "d,S,T", MATCH_FEQ_Q, MASK_FEQ_Q, match_opcode, INSN_RV64_EVEN_ST },
+{"flt.q", 0, INSN_CLASS_Q_INX, "d,S,T", MATCH_FLT_Q, MASK_FLT_Q, match_opcode, INSN_RV64_EVEN_ST },
+{"fle.q", 0, INSN_CLASS_Q_INX, "d,S,T", MATCH_FLE_Q, MASK_FLE_Q, match_opcode, INSN_RV64_EVEN_ST },
+{"fgt.q", 0, INSN_CLASS_Q_INX, "d,T,S", MATCH_FLT_Q, MASK_FLT_Q, match_opcode, INSN_ALIAS|INSN_RV64_EVEN_ST },
+{"fge.q", 0, INSN_CLASS_Q_INX, "d,T,S", MATCH_FLE_Q, MASK_FLE_Q, match_opcode, INSN_ALIAS|INSN_RV64_EVEN_ST },
+{"fcvt.l.q", 64, INSN_CLASS_Q_INX, "d,Sm", MATCH_FCVT_L_Q, MASK_FCVT_L_Q, match_opcode, INSN_RV64_EVEN_S },
+{"fcvt.lu.q", 64, INSN_CLASS_Q_INX, "d,Sm", MATCH_FCVT_LU_Q, MASK_FCVT_LU_Q, match_opcode, INSN_RV64_EVEN_S },
+{"fcvt.q.l", 64, INSN_CLASS_Q_INX, "D,s", MATCH_FCVT_Q_L, MASK_FCVT_Q_L|MASK_RM, match_opcode, INSN_RV64_EVEN_D },
+{"fcvt.q.lu", 64, INSN_CLASS_Q_INX, "D,s", MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU|MASK_RM, match_opcode, INSN_RV64_EVEN_D },
/* Compressed instructions. */
{"c.unimp", 0, INSN_CLASS_ZCA, "", 0, 0xffffU, match_opcode, 0 },