[PATCH v2 19/16] RISC-V: check operands for Zqinx
Jan Beulich
jbeulich@suse.com
Fri Jun 5 09:30:06 GMT 2026
By analogy to Zdinx on RV32, register pair operands are presumably (there
not being any formal spec afaict) required to be encoded with the low bit
clear in RV64; in RV32 the low two bits need to be clear. Since match
functions don't have XLEN available, introduce respective flags, to be
used explicitly in assembler and disassembler.
---
Does Zqinx actually make much sense in RV32? Function argument passing,
for example, ends up odd: a0..a3 aren't suitable to hold an argument.
Hence only a single argument can be passed in registers (a2..a5).
No similar checking is easily possible for scalar vector insns, as element
width there isn't encoded in the insn. (Plus V and Zqinx can't be enabled
together right now anyway.)
---
v2: New.
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -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. */
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zqinx-rv32.d
@@ -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
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zqinx-rv32.s
@@ -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
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zqinx-rv32-fail.d
@@ -0,0 +1,3 @@
+#as: -march=rv32i_zqinx
+#source: zqinx.s
+#error_output: zqinx-rv32-fail.l
--- /dev/null
+++ b/gas/testsuite/gas/riscv/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 .*'
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zqinx-rv64-fail.d
@@ -0,0 +1,2 @@
+#as: -march=rv64i_zqinx
+#error_output: zqinx-rv64-fail.l
--- /dev/null
+++ b/gas/testsuite/gas/riscv/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 .*'
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zqinx-rv64-fail.s
@@ -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
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -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
+ divisble 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
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -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. */
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -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 },
More information about the Binutils
mailing list