[binutils-gdb] RISC-V: check operands for Zqinx
Jan Beulich via Binutils-cvs <[email protected]> Fri, 31 Jul 2026 09:54:15 +0000 (GMT)
| Newsgroups | gmane.comp.gnu.binutils.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3D0c9151fab17d= 1c944c8f1cd0fc8afdaea42fb9a2 commit 0c9151fab17d1c944c8f1cd0fc8afdaea42fb9a2 Author: Jan Beulich <[email protected]> Date: Fri Jul 31 11:52:08 2026 +0200 RISC-V: check operands for Zqinx =20 By analogy to Zdinx on RV32, register pair operands are presumably (the= re not being any formal spec afaict) required to be encoded with the low b= it 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. Diff: --- gas/config/tc-riscv.c | 19 ++++++-- gas/testsuite/gas/riscv/zqinx-rv32-fail.d | 3 ++ gas/testsuite/gas/riscv/zqinx-rv32-fail.l | 42 ++++++++++++++++++ gas/testsuite/gas/riscv/zqinx-rv32.d | 52 ++++++++++++++++++++++ gas/testsuite/gas/riscv/zqinx-rv32.s | 54 ++++++++++++++++++++++ gas/testsuite/gas/riscv/zqinx-rv64-fail.d | 2 + gas/testsuite/gas/riscv/zqinx-rv64-fail.l | 62 ++++++++++++++++++++++++++ gas/testsuite/gas/riscv/zqinx-rv64-fail.s | 70 +++++++++++++++++++++++++++= ++ include/opcode/riscv.h | 13 ++++++ opcodes/riscv-dis.c | 19 ++++++++ opcodes/riscv-opc.c | 74 +++++++++++++++------------= ---- 11 files changed, 369 insertions(+), 41 deletions(-) diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c index 1fa33da6ec3..5567c33e88c 100644 --- a/gas/config/tc-riscv.c +++ b/gas/config/tc-riscv.c @@ -3010,6 +3010,12 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expre= ssionS *imm_expr, || (rclass) !=3D RCLASS_GPR \ || !((regno) & 1)) =20 +#define RV64_EVEN_CHECK(form, rclass, regno) \ + (!(ip->insn_mo->pinfo & INSN_RV64_EVEN_##form) \ + || xlen > 64 \ + || (rclass) !=3D RCLASS_GPR \ + || !((regno) & (xlen =3D=3D 32 ? 3 : 1))) + for (oparg =3D insn->args;; ++oparg) { opargStart =3D oparg; @@ -3689,12 +3695,14 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expr= essionS *imm_expr, 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_insn *ip, expr= essionS *imm_expr, 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_insn *ip, expres= sionS *imm_expr, } =20 #undef RV32_EVEN_CHECK +#undef RV64_EVEN_CHECK =20 out: /* Restore the character we might have clobbered above. */ diff --git a/gas/testsuite/gas/riscv/zqinx-rv32-fail.d b/gas/testsuite/gas/= riscv/zqinx-rv32-fail.d new file mode 100644 index 00000000000..0c976f63cf5 --- /dev/null +++ b/gas/testsuite/gas/riscv/zqinx-rv32-fail.d @@ -0,0 +1,3 @@ +#as: -march=3Drv32i_zqinx +#source: zqinx.s +#error_output: zqinx-rv32-fail.l diff --git a/gas/testsuite/gas/riscv/zqinx-rv32-fail.l b/gas/testsuite/gas/= riscv/zqinx-rv32-fail.l new file mode 100644 index 00000000000..66df2fb41f6 --- /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 .*' diff --git a/gas/testsuite/gas/riscv/zqinx-rv32.d b/gas/testsuite/gas/riscv= /zqinx-rv32.d new file mode 100644 index 00000000000..2872b60a803 --- /dev/null +++ b/gas/testsuite/gas/riscv/zqinx-rv32.d @@ -0,0 +1,52 @@ +#as: -march=3Drv32i_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 diff --git a/gas/testsuite/gas/riscv/zqinx-rv32.s b/gas/testsuite/gas/riscv= /zqinx-rv32.s new file mode 100644 index 00000000000..f5eb536d298 --- /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 diff --git a/gas/testsuite/gas/riscv/zqinx-rv64-fail.d b/gas/testsuite/gas/= riscv/zqinx-rv64-fail.d new file mode 100644 index 00000000000..236ae08df9c --- /dev/null +++ b/gas/testsuite/gas/riscv/zqinx-rv64-fail.d @@ -0,0 +1,2 @@ +#as: -march=3Drv64i_zqinx +#error_output: zqinx-rv64-fail.l diff --git a/gas/testsuite/gas/riscv/zqinx-rv64-fail.l b/gas/testsuite/gas/= riscv/zqinx-rv64-fail.l new file mode 100644 index 00000000000..1558997eec8 --- /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 .*' diff --git a/gas/testsuite/gas/riscv/zqinx-rv64-fail.s b/gas/testsuite/gas/= riscv/zqinx-rv64-fail.s new file mode 100644 index 00000000000..4a6546dcc6c --- /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 diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h index d142d3401fa..7c24988ac4b 100644 --- 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) =20 +/* Operands required to be an even-numbered register (pair) in RV64, and o= ne + 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 diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c index 696f2d9777f..42b0dd9c9fc 100644 --- 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 <=3D 64 + && riscv_subset_supports (&pd->riscv_rps_dis, "zqinx")) + { + unsigned int mask =3D pd->xlen =3D=3D 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; + } } =20 /* It's a match. */ diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c index 6b01851b757..617b444697e 100644 --- a/opcodes/riscv-opc.c +++ b/opcodes/riscv-opc.c @@ -956,10 +956,10 @@ const struct riscv_opcode riscv_opcodes[] =3D {"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_F= CVT_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_F= CVT_H_S, match_opcode, 0 }, {"fcvt.h.d", 0, INSN_CLASS_ZFHMIN_AND_D_INX, "D,Sm", MATCH_FCVT_H_D, MAS= K_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, MAS= K_FCVT_H_Q, match_opcode, 0 }, +{"fcvt.h.q", 0, INSN_CLASS_ZFHMIN_AND_Q_INX, "D,Sm", MATCH_FCVT_H_Q, MAS= K_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[] =3D {"flq", 0, INSN_CLASS_Q, "D,A,s", 0, (int) M_FLx, match_rs1_n= onzero, 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_rs= 1_nonzero, INSN_MACRO }, -{"fmv.q", 0, INSN_CLASS_Q_INX, "D,U", MATCH_FSGNJ_Q, MASK_FSG= NJ_Q, match_rs1_eq_rs2, INSN_ALIAS }, -{"fneg.q", 0, INSN_CLASS_Q_INX, "D,U", MATCH_FSGNJN_Q, MASK_FS= GNJN_Q, match_rs1_eq_rs2, INSN_ALIAS }, -{"fabs.q", 0, INSN_CLASS_Q_INX, "D,U", MATCH_FSGNJX_Q, MASK_FS= GNJX_Q, match_rs1_eq_rs2, INSN_ALIAS }, -{"fsgnj.q", 0, INSN_CLASS_Q_INX, "D,S,T", MATCH_FSGNJ_Q, MASK_FSG= NJ_Q, match_opcode, 0 }, -{"fsgnjn.q", 0, INSN_CLASS_Q_INX, "D,S,T", MATCH_FSGNJN_Q, MASK_FS= GNJN_Q, match_opcode, 0 }, -{"fsgnjx.q", 0, INSN_CLASS_Q_INX, "D,S,T", MATCH_FSGNJX_Q, MASK_FS= GNJX_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_FSQ= RT_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_FMA= DD_Q, match_opcode, 0 }, -{"fnmadd.q", 0, INSN_CLASS_Q_INX, "D,S,T,Rm", MATCH_FNMADD_Q, MASK_FN= MADD_Q, match_opcode, 0 }, -{"fmsub.q", 0, INSN_CLASS_Q_INX, "D,S,T,Rm", MATCH_FMSUB_Q, MASK_FMS= UB_Q, match_opcode, 0 }, -{"fnmsub.q", 0, INSN_CLASS_Q_INX, "D,S,T,Rm", MATCH_FNMSUB_Q, MASK_FN= MSUB_Q, match_opcode, 0 }, -{"fcvt.w.q", 0, INSN_CLASS_Q_INX, "d,Sm", MATCH_FCVT_W_Q, MASK_FC= VT_W_Q, match_opcode, 0 }, -{"fcvt.wu.q", 0, INSN_CLASS_Q_INX, "d,Sm", MATCH_FCVT_WU_Q, MASK_F= CVT_WU_Q, match_opcode, 0 }, -{"fcvt.q.w", 0, INSN_CLASS_Q_INX, "D,s", MATCH_FCVT_Q_W, MASK_FC= VT_Q_W|MASK_RM, match_opcode, 0 }, -{"fcvt.q.wu", 0, INSN_CLASS_Q_INX, "D,s", MATCH_FCVT_Q_WU, MASK_F= CVT_Q_WU|MASK_RM, match_opcode, 0 }, -{"fcvt.q.s", 0, INSN_CLASS_Q_INX, "D,S", MATCH_FCVT_Q_S, MASK_FC= VT_Q_S|MASK_RM, match_opcode, 0 }, -{"fcvt.q.d", 0, INSN_CLASS_Q_INX, "D,S", MATCH_FCVT_Q_D, MASK_FC= VT_Q_D|MASK_RM, match_opcode, 0 }, -{"fcvt.s.q", 0, INSN_CLASS_Q_INX, "D,Sm", MATCH_FCVT_S_Q, MASK_FC= VT_S_Q, match_opcode, 0 }, -{"fcvt.d.q", 0, INSN_CLASS_Q_INX, "D,Sm", MATCH_FCVT_D_Q, MASK_FC= VT_D_Q, match_opcode, 0 }, -{"fclass.q", 0, INSN_CLASS_Q_INX, "d,S", MATCH_FCLASS_Q, MASK_FC= LASS_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_FC= VT_L_Q, match_opcode, 0 }, -{"fcvt.lu.q", 64, INSN_CLASS_Q_INX, "d,Sm", MATCH_FCVT_LU_Q, MASK_F= CVT_LU_Q, match_opcode, 0 }, -{"fcvt.q.l", 64, INSN_CLASS_Q_INX, "D,s", MATCH_FCVT_Q_L, MASK_FC= VT_Q_L|MASK_RM, match_opcode, 0 }, -{"fcvt.q.lu", 64, INSN_CLASS_Q_INX, "D,s", MATCH_FCVT_Q_LU, MASK_F= CVT_Q_LU|MASK_RM, match_opcode, 0 }, +{"fmv.q", 0, INSN_CLASS_Q_INX, "D,U", MATCH_FSGNJ_Q, MASK_FSG= NJ_Q, match_rs1_eq_rs2, INSN_ALIAS|INSN_RV64_EVEN_DU }, +{"fneg.q", 0, INSN_CLASS_Q_INX, "D,U", MATCH_FSGNJN_Q, MASK_FS= GNJN_Q, match_rs1_eq_rs2, INSN_ALIAS|INSN_RV64_EVEN_DU }, +{"fabs.q", 0, INSN_CLASS_Q_INX, "D,U", MATCH_FSGNJX_Q, MASK_FS= GNJX_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_FSG= NJ_Q, match_opcode, INSN_RV64_EVEN_DST }, +{"fsgnjn.q", 0, INSN_CLASS_Q_INX, "D,S,T", MATCH_FSGNJN_Q, MASK_FS= GNJN_Q, match_opcode, INSN_RV64_EVEN_DST }, +{"fsgnjx.q", 0, INSN_CLASS_Q_INX, "D,S,T", MATCH_FSGNJX_Q, MASK_FS= GNJX_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_FSQ= RT_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_FMA= DD_Q, match_opcode, INSN_RV64_EVEN_DSTR }, +{"fnmadd.q", 0, INSN_CLASS_Q_INX, "D,S,T,Rm", MATCH_FNMADD_Q, MASK_FN= MADD_Q, match_opcode, INSN_RV64_EVEN_DSTR }, +{"fmsub.q", 0, INSN_CLASS_Q_INX, "D,S,T,Rm", MATCH_FMSUB_Q, MASK_FMS= UB_Q, match_opcode, INSN_RV64_EVEN_DSTR }, +{"fnmsub.q", 0, INSN_CLASS_Q_INX, "D,S,T,Rm", MATCH_FNMSUB_Q, MASK_FN= MSUB_Q, match_opcode, INSN_RV64_EVEN_DSTR }, +{"fcvt.w.q", 0, INSN_CLASS_Q_INX, "d,Sm", MATCH_FCVT_W_Q, MASK_FC= VT_W_Q, match_opcode, INSN_RV64_EVEN_S }, +{"fcvt.wu.q", 0, INSN_CLASS_Q_INX, "d,Sm", MATCH_FCVT_WU_Q, MASK_F= CVT_WU_Q, match_opcode, INSN_RV64_EVEN_S }, +{"fcvt.q.w", 0, INSN_CLASS_Q_INX, "D,s", MATCH_FCVT_Q_W, MASK_FC= VT_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_F= CVT_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_FC= VT_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_FC= VT_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_FC= VT_S_Q, match_opcode, INSN_RV64_EVEN_S }, +{"fcvt.d.q", 0, INSN_CLASS_Q_INX, "D,Sm", MATCH_FCVT_D_Q, MASK_FC= VT_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_FC= LASS_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_FC= VT_L_Q, match_opcode, INSN_RV64_EVEN_S }, +{"fcvt.lu.q", 64, INSN_CLASS_Q_INX, "d,Sm", MATCH_FCVT_LU_Q, MASK_F= CVT_LU_Q, match_opcode, INSN_RV64_EVEN_S }, +{"fcvt.q.l", 64, INSN_CLASS_Q_INX, "D,s", MATCH_FCVT_Q_L, MASK_FC= VT_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_F= CVT_Q_LU|MASK_RM, match_opcode, INSN_RV64_EVEN_D }, =20 /* Compressed instructions. */ {"c.unimp", 0, INSN_CLASS_ZCA, "", 0, 0xffffU, match_opcode= , 0 },