Re: [PATCH v4 06/12] RISC-V: check operands for Zdinx in RV32
Nelson Chu <[email protected]> Mon, 27 Jul 2026 11:08:55 +0800
| Newsgroups | gmane.comp.gnu.binutils |
|---|---|
| Message-ID | <CAHT-pJzzME-GEWcZ6J3-Jd0vaQO_eez5EDcsH_ktt9ZDPDr3Kg@mail.gmail.com> |
I used to have reservations about these assembler constraint checks (including those for RVV) because, at the time, there were strong objections from people whose random test case generators were failing due to this feature. Essentially, the project involves randomly generating various assembler instructions (including illegal ones) and feeding them to the hardware to verify whether the DV (Design Verification) setup correctly detects the invalid instructions. There was previously a compromise involving an option to let users toggle these checks on or off, but I didn't think the option was a good idea - since it was specific to RVV and addressed only a very small number of edge cases - so I ultimately removed it. In fact, people can still assemble these illegal instructions by .insn directives, but it just wasn't adopted at the time due to the complex certain political reasons. So now I think it's time to correct the wrong decision and do the right thing - I think what you are doing is right, allowing illegal instructions for assembler is wrong and dangerous for general users, so this patch (and maybe further patches for constraints) looks good to me. Thanks Nelson On Fri, Jul 24, 2026 at 6:04 PM Jan Beulich <[email protected]> wrote: > > 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. > --- > No similar checking is easily possible for scalar vector insns, as element > width there isn't encoded in the insn. (Plus V and Zdinx can't be enabled > together right now anyway.) > > We could further use RV32_EVEN_CHECK for Zilsd as well, then allowing to > eliminate one or two match functions. (Hence RV32_EVEN_CHECK()'s scope is > pretty wide.) > > --- a/gas/config/tc-riscv.c > +++ b/gas/config/tc-riscv.c > @@ -3004,6 +3004,12 @@ riscv_ip (char *str, struct riscv_cl_ins > *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_ins > ++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_ins > 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), ®no)) > + rclass = riscv_subset_supports (&riscv_rps_as, "zfinx") > + ? RCLASS_GPR : RCLASS_FPR; > + if (reg_lookup (&asarg, rclass, ®no)) > { > 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_ins > insn_with_csr = false; > } > > +#undef RV32_EVEN_CHECK > + > out: > /* Restore the character we might have clobbered above. */ > if (save_c) > --- /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 > --- /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 > --- /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 > --- /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 .*' > --- 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 > --- 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. */ > --- 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 }, >