Re: [PATCH v4 07/12] RISC-V: check operands for Zqinx
Nelson Chu <[email protected]> Mon, 27 Jul 2026 11:15:06 +0800
| Newsgroups | gmane.comp.gnu.binutils |
|---|---|
| Message-ID | <CAHT-pJydDYqBS4S4ecj9Kma6nW2wq++ewjUKM9dRNgZORoS9WQ@mail.gmail.com> |
On Fri, Jul 24, 2026 at 6:04 PM Jan Beulich <[email protected]> wrote: > > 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. Okay, same reason as the previous patch. > --- > 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). Jiawei, You should know the best for these finx changes, do you think zqinx should be allowed under rv32? Thanks Nelson > 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.) > --- > v3: Fix typo in comment. > v2: New. > > --- a/gas/config/tc-riscv.c > +++ b/gas/config/tc-riscv.c > @@ -3010,6 +3010,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; > @@ -3689,12 +3695,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; > @@ -3702,12 +3710,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; > @@ -4547,6 +4557,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 > @@ -721,6 +721,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 > --- a/opcodes/riscv-dis.c > +++ b/opcodes/riscv-dis.c > @@ -1155,6 +1155,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 > @@ -956,10 +956,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 }, > @@ -1086,41 +1086,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 }, >