Re: [PATCH v4 05/12] RISC-V: make FP rounding mode an optional operand

Nelson Chu <[email protected]> Mon, 27 Jul 2026 09:49:45 +0800
Newsgroups gmane.comp.gnu.binutils
Message-ID <CAHT-pJyYub-L86G2tXuzKpkrQPj2u_m6rX8ekPzyAmJvzAbXgA@mail.gmail.com>
Cool!  I would love this idea to apply to RM!  Since to some extent,
RM is also optional and is the last operand.

Nelson

On Fri, Jul 24, 2026 at 6:03 PM Jan Beulich <[email protected]> wrote:
>
> Model this after Vm (and somewhat after its VM counterpart): It's similarly
> always last, and we can hence similarly reduce the number of entries in the
> opcode table. The exception being FCVTMOD.W.D, where M needs using.
>
> --- a/gas/config/tc-riscv.c
> +++ b/gas/config/tc-riscv.c
> @@ -1614,6 +1614,7 @@ validate_riscv_insn (const struct riscv_
>         case 't': USE_BITS (OP_MASK_RS2, OP_SH_RS2); break;
>         case 'R': /* RS3, floating point.  */
>         case 'r': USE_BITS (OP_MASK_RS3, OP_SH_RS3); break;
> +       case 'M':
>         case 'm': USE_BITS (OP_MASK_RM, OP_SH_RM); break;
>         case 'E': USE_BITS (OP_MASK_CSR, OP_SH_CSR); break;
>         case 'P': USE_BITS (OP_MASK_PRED, OP_SH_PRED); break;
> @@ -3601,7 +3602,17 @@ riscv_ip (char *str, struct riscv_cl_ins
>                 }
>               continue;
>
> -           case 'm': /* Rounding mode.  */
> +           case 'm': /* Optional rounding mode.  */
> +             if (*asarg == '\0')
> +               {
> +                 INSERT_OPERAND (RM, *ip, OP_MASK_RM);
> +                 continue;
> +               }
> +             if (*asarg != ',')
> +               break;
> +             ++asarg;
> +             /* Fall through. */
> +           case 'M': /* Rounding mode.  */
>               if (arg_lookup (&asarg, riscv_rm,
>                               ARRAY_SIZE (riscv_rm), &regno))
>                 {
> --- a/opcodes/riscv-dis.c
> +++ b/opcodes/riscv-dis.c
> @@ -573,6 +573,11 @@ print_insn_args (const char *oparg, insn
>           break;
>
>         case 'm':
> +         if (EXTRACT_OPERAND (RM, l) == OP_MASK_RM)
> +           break;
> +         print (info->stream, dis_style_text, ",");
> +         /* Fall through. */
> +       case 'M':
>           arg_print (info, EXTRACT_OPERAND (RM, l),
>                      riscv_rm, ARRAY_SIZE (riscv_rm));
>           break;
> --- a/opcodes/riscv-opc.c
> +++ b/opcodes/riscv-opc.c
> @@ -939,61 +939,40 @@ const struct riscv_opcode riscv_opcodes[
>  {"fsgnj.h",    0, INSN_CLASS_ZFH_INX,   "D,S,T",     MATCH_FSGNJ_H, MASK_FSGNJ_H, match_opcode, 0 },
>  {"fsgnjn.h",   0, INSN_CLASS_ZFH_INX,   "D,S,T",     MATCH_FSGNJN_H, MASK_FSGNJN_H, match_opcode, 0 },
>  {"fsgnjx.h",   0, INSN_CLASS_ZFH_INX,   "D,S,T",     MATCH_FSGNJX_H, MASK_FSGNJX_H, match_opcode, 0 },
> -{"fadd.h",     0, INSN_CLASS_ZFH_INX,   "D,S,T",     MATCH_FADD_H|MASK_RM, MASK_FADD_H|MASK_RM, match_opcode, 0 },
> -{"fadd.h",     0, INSN_CLASS_ZFH_INX,   "D,S,T,m",   MATCH_FADD_H, MASK_FADD_H, match_opcode, 0 },
> -{"fsub.h",     0, INSN_CLASS_ZFH_INX,   "D,S,T",     MATCH_FSUB_H|MASK_RM, MASK_FSUB_H|MASK_RM, match_opcode, 0 },
> -{"fsub.h",     0, INSN_CLASS_ZFH_INX,   "D,S,T,m",   MATCH_FSUB_H, MASK_FSUB_H, match_opcode, 0 },
> -{"fmul.h",     0, INSN_CLASS_ZFH_INX,   "D,S,T",     MATCH_FMUL_H|MASK_RM, MASK_FMUL_H|MASK_RM, match_opcode, 0 },
> -{"fmul.h",     0, INSN_CLASS_ZFH_INX,   "D,S,T,m",   MATCH_FMUL_H, MASK_FMUL_H, match_opcode, 0 },
> -{"fdiv.h",     0, INSN_CLASS_ZFH_INX,   "D,S,T",     MATCH_FDIV_H|MASK_RM, MASK_FDIV_H|MASK_RM, match_opcode, 0 },
> -{"fdiv.h",     0, INSN_CLASS_ZFH_INX,   "D,S,T,m",   MATCH_FDIV_H, MASK_FDIV_H, match_opcode, 0 },
> -{"fsqrt.h",    0, INSN_CLASS_ZFH_INX,   "D,S",       MATCH_FSQRT_H|MASK_RM, MASK_FSQRT_H|MASK_RM, match_opcode, 0 },
> -{"fsqrt.h",    0, INSN_CLASS_ZFH_INX,   "D,S,m",     MATCH_FSQRT_H, MASK_FSQRT_H, match_opcode, 0 },
> +{"fadd.h",     0, INSN_CLASS_ZFH_INX,  "D,S,Tm",    MATCH_FADD_H, MASK_FADD_H, match_opcode, 0 },
> +{"fsub.h",     0, INSN_CLASS_ZFH_INX,  "D,S,Tm",    MATCH_FSUB_H, MASK_FSUB_H, match_opcode, 0 },
> +{"fmul.h",     0, INSN_CLASS_ZFH_INX,  "D,S,Tm",    MATCH_FMUL_H, MASK_FMUL_H, match_opcode, 0 },
> +{"fdiv.h",     0, INSN_CLASS_ZFH_INX,  "D,S,Tm",    MATCH_FDIV_H, MASK_FDIV_H, match_opcode, 0 },
> +{"fsqrt.h",    0, INSN_CLASS_ZFH_INX,  "D,Sm",      MATCH_FSQRT_H, MASK_FSQRT_H, match_opcode, 0 },
>  {"fmin.h",     0, INSN_CLASS_ZFH_INX,   "D,S,T",     MATCH_FMIN_H, MASK_FMIN_H, match_opcode, 0 },
>  {"fmax.h",     0, INSN_CLASS_ZFH_INX,   "D,S,T",     MATCH_FMAX_H, MASK_FMAX_H, match_opcode, 0 },
> -{"fmadd.h",    0, INSN_CLASS_ZFH_INX,   "D,S,T,R",   MATCH_FMADD_H|MASK_RM, MASK_FMADD_H|MASK_RM, match_opcode, 0 },
> -{"fmadd.h",    0, INSN_CLASS_ZFH_INX,   "D,S,T,R,m", MATCH_FMADD_H, MASK_FMADD_H, match_opcode, 0 },
> -{"fnmadd.h",   0, INSN_CLASS_ZFH_INX,   "D,S,T,R",   MATCH_FNMADD_H|MASK_RM, MASK_FNMADD_H|MASK_RM, match_opcode, 0 },
> -{"fnmadd.h",   0, INSN_CLASS_ZFH_INX,   "D,S,T,R,m", MATCH_FNMADD_H, MASK_FNMADD_H, match_opcode, 0 },
> -{"fmsub.h",    0, INSN_CLASS_ZFH_INX,   "D,S,T,R",   MATCH_FMSUB_H|MASK_RM, MASK_FMSUB_H|MASK_RM, match_opcode, 0 },
> -{"fmsub.h",    0, INSN_CLASS_ZFH_INX,   "D,S,T,R,m", MATCH_FMSUB_H, MASK_FMSUB_H, match_opcode, 0 },
> -{"fnmsub.h",   0, INSN_CLASS_ZFH_INX,   "D,S,T,R",   MATCH_FNMSUB_H|MASK_RM, MASK_FNMSUB_H|MASK_RM, match_opcode, 0 },
> -{"fnmsub.h",   0, INSN_CLASS_ZFH_INX,   "D,S,T,R,m", MATCH_FNMSUB_H, MASK_FNMSUB_H, match_opcode, 0 },
> -{"fcvt.w.h",   0, INSN_CLASS_ZFH_INX,   "d,S",       MATCH_FCVT_W_H|MASK_RM, MASK_FCVT_W_H|MASK_RM, match_opcode, 0 },
> -{"fcvt.w.h",   0, INSN_CLASS_ZFH_INX,   "d,S,m",     MATCH_FCVT_W_H, MASK_FCVT_W_H, match_opcode, 0 },
> -{"fcvt.wu.h",  0, INSN_CLASS_ZFH_INX,   "d,S",       MATCH_FCVT_WU_H|MASK_RM, MASK_FCVT_WU_H|MASK_RM, match_opcode, 0 },
> -{"fcvt.wu.h",  0, INSN_CLASS_ZFH_INX,   "d,S,m",     MATCH_FCVT_WU_H, MASK_FCVT_WU_H, match_opcode, 0 },
> -{"fcvt.h.w",   0, INSN_CLASS_ZFH_INX,   "D,s",       MATCH_FCVT_H_W|MASK_RM, MASK_FCVT_H_W|MASK_RM, match_opcode, 0 },
> -{"fcvt.h.w",   0, INSN_CLASS_ZFH_INX,   "D,s,m",     MATCH_FCVT_H_W, MASK_FCVT_H_W, match_opcode, 0 },
> -{"fcvt.h.wu",  0, INSN_CLASS_ZFH_INX,   "D,s",       MATCH_FCVT_H_WU|MASK_RM, MASK_FCVT_H_WU|MASK_RM, match_opcode, 0 },
> -{"fcvt.h.wu",  0, INSN_CLASS_ZFH_INX,   "D,s,m",     MATCH_FCVT_H_WU, MASK_FCVT_H_WU, match_opcode, 0 },
> +{"fmadd.h",    0, INSN_CLASS_ZFH_INX,  "D,S,T,Rm",  MATCH_FMADD_H, MASK_FMADD_H, match_opcode, 0 },
> +{"fnmadd.h",   0, INSN_CLASS_ZFH_INX,  "D,S,T,Rm",  MATCH_FNMADD_H, MASK_FNMADD_H, match_opcode, 0 },
> +{"fmsub.h",    0, INSN_CLASS_ZFH_INX,  "D,S,T,Rm",  MATCH_FMSUB_H, MASK_FMSUB_H, match_opcode, 0 },
> +{"fnmsub.h",   0, INSN_CLASS_ZFH_INX,  "D,S,T,Rm",  MATCH_FNMSUB_H, MASK_FNMSUB_H, match_opcode, 0 },
> +{"fcvt.w.h",   0, INSN_CLASS_ZFH_INX,  "d,Sm",      MATCH_FCVT_W_H, MASK_FCVT_W_H, match_opcode, 0 },
> +{"fcvt.wu.h",  0, INSN_CLASS_ZFH_INX,  "d,Sm",      MATCH_FCVT_WU_H, MASK_FCVT_WU_H, match_opcode, 0 },
> +{"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.h.s",   0, INSN_CLASS_ZFHMIN_INX, "D,S",     MATCH_FCVT_H_S|MASK_RM, MASK_FCVT_H_S|MASK_RM, match_opcode, 0 },
> -{"fcvt.h.s",   0, INSN_CLASS_ZFHMIN_INX, "D,S,m",   MATCH_FCVT_H_S, MASK_FCVT_H_S, match_opcode, 0 },
> -{"fcvt.h.d",   0, INSN_CLASS_ZFHMIN_AND_D_INX,     "D,S",       MATCH_FCVT_H_D|MASK_RM, MASK_FCVT_H_D|MASK_RM, match_opcode, 0 },
> -{"fcvt.h.d",   0, INSN_CLASS_ZFHMIN_AND_D_INX,     "D,S,m",     MATCH_FCVT_H_D, MASK_FCVT_H_D, match_opcode, 0 },
> -{"fcvt.h.q",   0, INSN_CLASS_ZFHMIN_AND_Q_INX,     "D,S",       MATCH_FCVT_H_Q|MASK_RM, MASK_FCVT_H_Q|MASK_RM, match_opcode, 0 },
> -{"fcvt.h.q",   0, INSN_CLASS_ZFHMIN_AND_Q_INX,     "D,S,m",     MATCH_FCVT_H_Q, MASK_FCVT_H_Q, 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.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 },
>  {"flt.h",      0, INSN_CLASS_ZFH_INX,   "d,S,T",     MATCH_FLT_H, MASK_FLT_H, match_opcode, 0 },
>  {"fle.h",      0, INSN_CLASS_ZFH_INX,   "d,S,T",     MATCH_FLE_H, MASK_FLE_H, match_opcode, 0 },
>  {"fgt.h",      0, INSN_CLASS_ZFH_INX,   "d,T,S",     MATCH_FLT_H, MASK_FLT_H, match_opcode, INSN_ALIAS },
>  {"fge.h",      0, INSN_CLASS_ZFH_INX,   "d,T,S",     MATCH_FLE_H, MASK_FLE_H, match_opcode, INSN_ALIAS },
> -{"fcvt.l.h",  64, INSN_CLASS_ZFH_INX,   "d,S",       MATCH_FCVT_L_H|MASK_RM, MASK_FCVT_L_H|MASK_RM, match_opcode, 0 },
> -{"fcvt.l.h",  64, INSN_CLASS_ZFH_INX,   "d,S,m",     MATCH_FCVT_L_H, MASK_FCVT_L_H, match_opcode, 0 },
> -{"fcvt.lu.h", 64, INSN_CLASS_ZFH_INX,   "d,S",       MATCH_FCVT_LU_H|MASK_RM, MASK_FCVT_LU_H|MASK_RM, match_opcode, 0 },
> -{"fcvt.lu.h", 64, INSN_CLASS_ZFH_INX,   "d,S,m",     MATCH_FCVT_LU_H, MASK_FCVT_LU_H, match_opcode, 0 },
> -{"fcvt.h.l",  64, INSN_CLASS_ZFH_INX,   "D,s",       MATCH_FCVT_H_L|MASK_RM, MASK_FCVT_H_L|MASK_RM, match_opcode, 0 },
> -{"fcvt.h.l",  64, INSN_CLASS_ZFH_INX,   "D,s,m",     MATCH_FCVT_H_L, MASK_FCVT_H_L, match_opcode, 0 },
> -{"fcvt.h.lu", 64, INSN_CLASS_ZFH_INX,   "D,s",       MATCH_FCVT_H_LU|MASK_RM, MASK_FCVT_H_LU|MASK_RM, match_opcode, 0 },
> -{"fcvt.h.lu", 64, INSN_CLASS_ZFH_INX,   "D,s,m",     MATCH_FCVT_H_LU, MASK_FCVT_H_LU, match_opcode, 0 },
> +{"fcvt.l.h",  64, INSN_CLASS_ZFH_INX,  "d,Sm",      MATCH_FCVT_L_H, MASK_FCVT_L_H, match_opcode, 0 },
> +{"fcvt.lu.h", 64, INSN_CLASS_ZFH_INX,  "d,Sm",      MATCH_FCVT_LU_H, MASK_FCVT_LU_H, match_opcode, 0 },
> +{"fcvt.h.l",  64, INSN_CLASS_ZFH_INX,  "D,sm",      MATCH_FCVT_H_L, MASK_FCVT_H_L, match_opcode, 0 },
> +{"fcvt.h.lu", 64, INSN_CLASS_ZFH_INX,  "D,sm",      MATCH_FCVT_H_LU, MASK_FCVT_H_LU, match_opcode, 0 },
>
>  /* Zfbfmin instructions.  */
> -{"fcvt.bf16.s", 0, INSN_CLASS_ZFBFMIN, "D,S",   MATCH_FCVT_BF16_S|MASK_RM, MASK_FCVT_BF16_S|MASK_RM, match_opcode, 0 },
> -{"fcvt.bf16.s", 0, INSN_CLASS_ZFBFMIN, "D,S,m", MATCH_FCVT_BF16_S, MASK_FCVT_BF16_S, match_opcode, 0 },
> +{"fcvt.bf16.s", 0, INSN_CLASS_ZFBFMIN, "D,Sm",  MATCH_FCVT_BF16_S, MASK_FCVT_BF16_S, match_opcode, 0 },
>  {"fcvt.s.bf16", 0, INSN_CLASS_ZFBFMIN, "D,S",   MATCH_FCVT_S_BF16, MASK_FCVT_S_BF16|MASK_RM, match_opcode, 0 },
>
>  /* Single-precision floating-point instruction subset.  */
> @@ -1031,48 +1010,31 @@ const struct riscv_opcode riscv_opcodes[
>  {"fsgnj.s",    0, INSN_CLASS_F_INX,   "D,S,T",     MATCH_FSGNJ_S, MASK_FSGNJ_S, match_opcode, 0 },
>  {"fsgnjn.s",   0, INSN_CLASS_F_INX,   "D,S,T",     MATCH_FSGNJN_S, MASK_FSGNJN_S, match_opcode, 0 },
>  {"fsgnjx.s",   0, INSN_CLASS_F_INX,   "D,S,T",     MATCH_FSGNJX_S, MASK_FSGNJX_S, match_opcode, 0 },
> -{"fadd.s",     0, INSN_CLASS_F_INX,   "D,S,T",     MATCH_FADD_S|MASK_RM, MASK_FADD_S|MASK_RM, match_opcode, 0 },
> -{"fadd.s",     0, INSN_CLASS_F_INX,   "D,S,T,m",   MATCH_FADD_S, MASK_FADD_S, match_opcode, 0 },
> -{"fsub.s",     0, INSN_CLASS_F_INX,   "D,S,T",     MATCH_FSUB_S|MASK_RM, MASK_FSUB_S|MASK_RM, match_opcode, 0 },
> -{"fsub.s",     0, INSN_CLASS_F_INX,   "D,S,T,m",   MATCH_FSUB_S, MASK_FSUB_S, match_opcode, 0 },
> -{"fmul.s",     0, INSN_CLASS_F_INX,   "D,S,T",     MATCH_FMUL_S|MASK_RM, MASK_FMUL_S|MASK_RM, match_opcode, 0 },
> -{"fmul.s",     0, INSN_CLASS_F_INX,   "D,S,T,m",   MATCH_FMUL_S, MASK_FMUL_S, match_opcode, 0 },
> -{"fdiv.s",     0, INSN_CLASS_F_INX,   "D,S,T",     MATCH_FDIV_S|MASK_RM, MASK_FDIV_S|MASK_RM, match_opcode, 0 },
> -{"fdiv.s",     0, INSN_CLASS_F_INX,   "D,S,T,m",   MATCH_FDIV_S, MASK_FDIV_S, match_opcode, 0 },
> -{"fsqrt.s",    0, INSN_CLASS_F_INX,   "D,S",       MATCH_FSQRT_S|MASK_RM, MASK_FSQRT_S|MASK_RM, match_opcode, 0 },
> -{"fsqrt.s",    0, INSN_CLASS_F_INX,   "D,S,m",     MATCH_FSQRT_S, MASK_FSQRT_S, match_opcode, 0 },
> +{"fadd.s",     0, INSN_CLASS_F_INX,   "D,S,Tm",    MATCH_FADD_S, MASK_FADD_S, match_opcode, 0 },
> +{"fsub.s",     0, INSN_CLASS_F_INX,   "D,S,Tm",    MATCH_FSUB_S, MASK_FSUB_S, match_opcode, 0 },
> +{"fmul.s",     0, INSN_CLASS_F_INX,   "D,S,Tm",    MATCH_FMUL_S, MASK_FMUL_S, match_opcode, 0 },
> +{"fdiv.s",     0, INSN_CLASS_F_INX,   "D,S,Tm",    MATCH_FDIV_S, MASK_FDIV_S, match_opcode, 0 },
> +{"fsqrt.s",    0, INSN_CLASS_F_INX,   "D,Sm",      MATCH_FSQRT_S, MASK_FSQRT_S, match_opcode, 0 },
>  {"fmin.s",     0, INSN_CLASS_F_INX,   "D,S,T",     MATCH_FMIN_S, MASK_FMIN_S, match_opcode, 0 },
>  {"fmax.s",     0, INSN_CLASS_F_INX,   "D,S,T",     MATCH_FMAX_S, MASK_FMAX_S, match_opcode, 0 },
> -{"fmadd.s",    0, INSN_CLASS_F_INX,   "D,S,T,R",   MATCH_FMADD_S|MASK_RM, MASK_FMADD_S|MASK_RM, match_opcode, 0 },
> -{"fmadd.s",    0, INSN_CLASS_F_INX,   "D,S,T,R,m", MATCH_FMADD_S, MASK_FMADD_S, match_opcode, 0 },
> -{"fnmadd.s",   0, INSN_CLASS_F_INX,   "D,S,T,R",   MATCH_FNMADD_S|MASK_RM, MASK_FNMADD_S|MASK_RM, match_opcode, 0 },
> -{"fnmadd.s",   0, INSN_CLASS_F_INX,   "D,S,T,R,m", MATCH_FNMADD_S, MASK_FNMADD_S, match_opcode, 0 },
> -{"fmsub.s",    0, INSN_CLASS_F_INX,   "D,S,T,R",   MATCH_FMSUB_S|MASK_RM, MASK_FMSUB_S|MASK_RM, match_opcode, 0 },
> -{"fmsub.s",    0, INSN_CLASS_F_INX,   "D,S,T,R,m", MATCH_FMSUB_S, MASK_FMSUB_S, match_opcode, 0 },
> -{"fnmsub.s",   0, INSN_CLASS_F_INX,   "D,S,T,R",   MATCH_FNMSUB_S|MASK_RM, MASK_FNMSUB_S|MASK_RM, match_opcode, 0 },
> -{"fnmsub.s",   0, INSN_CLASS_F_INX,   "D,S,T,R,m", MATCH_FNMSUB_S, MASK_FNMSUB_S, match_opcode, 0 },
> -{"fcvt.w.s",   0, INSN_CLASS_F_INX,   "d,S",       MATCH_FCVT_W_S|MASK_RM, MASK_FCVT_W_S|MASK_RM, match_opcode, 0 },
> -{"fcvt.w.s",   0, INSN_CLASS_F_INX,   "d,S,m",     MATCH_FCVT_W_S, MASK_FCVT_W_S, match_opcode, 0 },
> -{"fcvt.wu.s",  0, INSN_CLASS_F_INX,   "d,S",       MATCH_FCVT_WU_S|MASK_RM, MASK_FCVT_WU_S|MASK_RM, match_opcode, 0 },
> -{"fcvt.wu.s",  0, INSN_CLASS_F_INX,   "d,S,m",     MATCH_FCVT_WU_S, MASK_FCVT_WU_S, match_opcode, 0 },
> -{"fcvt.s.w",   0, INSN_CLASS_F_INX,   "D,s",       MATCH_FCVT_S_W|MASK_RM, MASK_FCVT_S_W|MASK_RM, match_opcode, 0 },
> -{"fcvt.s.w",   0, INSN_CLASS_F_INX,   "D,s,m",     MATCH_FCVT_S_W, MASK_FCVT_S_W, match_opcode, 0 },
> -{"fcvt.s.wu",  0, INSN_CLASS_F_INX,   "D,s",       MATCH_FCVT_S_WU|MASK_RM, MASK_FCVT_S_WU|MASK_RM, match_opcode, 0 },
> -{"fcvt.s.wu",  0, INSN_CLASS_F_INX,   "D,s,m",     MATCH_FCVT_S_WU, MASK_FCVT_S_WU, match_opcode, 0 },
> +{"fmadd.s",    0, INSN_CLASS_F_INX,   "D,S,T,Rm",  MATCH_FMADD_S, MASK_FMADD_S, match_opcode, 0 },
> +{"fnmadd.s",   0, INSN_CLASS_F_INX,   "D,S,T,Rm",  MATCH_FNMADD_S, MASK_FNMADD_S, match_opcode, 0 },
> +{"fmsub.s",    0, INSN_CLASS_F_INX,   "D,S,T,Rm",  MATCH_FMSUB_S, MASK_FMSUB_S, match_opcode, 0 },
> +{"fnmsub.s",   0, INSN_CLASS_F_INX,   "D,S,T,Rm",  MATCH_FNMSUB_S, MASK_FNMSUB_S, match_opcode, 0 },
> +{"fcvt.w.s",   0, INSN_CLASS_F_INX,   "d,Sm",      MATCH_FCVT_W_S, MASK_FCVT_W_S, match_opcode, 0 },
> +{"fcvt.wu.s",  0, INSN_CLASS_F_INX,   "d,Sm",      MATCH_FCVT_WU_S, MASK_FCVT_WU_S, match_opcode, 0 },
> +{"fcvt.s.w",   0, INSN_CLASS_F_INX,   "D,sm",      MATCH_FCVT_S_W, MASK_FCVT_S_W, match_opcode, 0 },
> +{"fcvt.s.wu",  0, INSN_CLASS_F_INX,   "D,sm",      MATCH_FCVT_S_WU, MASK_FCVT_S_WU, match_opcode, 0 },
>  {"fclass.s",   0, INSN_CLASS_F_INX,   "d,S",       MATCH_FCLASS_S, MASK_FCLASS_S, match_opcode, 0 },
>  {"feq.s",      0, INSN_CLASS_F_INX,   "d,S,T",     MATCH_FEQ_S, MASK_FEQ_S, match_opcode, 0 },
>  {"flt.s",      0, INSN_CLASS_F_INX,   "d,S,T",     MATCH_FLT_S, MASK_FLT_S, match_opcode, 0 },
>  {"fle.s",      0, INSN_CLASS_F_INX,   "d,S,T",     MATCH_FLE_S, MASK_FLE_S, match_opcode, 0 },
>  {"fgt.s",      0, INSN_CLASS_F_INX,   "d,T,S",     MATCH_FLT_S, MASK_FLT_S, match_opcode, INSN_ALIAS },
>  {"fge.s",      0, INSN_CLASS_F_INX,   "d,T,S",     MATCH_FLE_S, MASK_FLE_S, match_opcode, INSN_ALIAS },
> -{"fcvt.l.s",  64, INSN_CLASS_F_INX,   "d,S",       MATCH_FCVT_L_S|MASK_RM, MASK_FCVT_L_S|MASK_RM, match_opcode, 0 },
> -{"fcvt.l.s",  64, INSN_CLASS_F_INX,   "d,S,m",     MATCH_FCVT_L_S, MASK_FCVT_L_S, match_opcode, 0 },
> -{"fcvt.lu.s", 64, INSN_CLASS_F_INX,   "d,S",       MATCH_FCVT_LU_S|MASK_RM, MASK_FCVT_LU_S|MASK_RM, match_opcode, 0 },
> -{"fcvt.lu.s", 64, INSN_CLASS_F_INX,   "d,S,m",     MATCH_FCVT_LU_S, MASK_FCVT_LU_S, match_opcode, 0 },
> -{"fcvt.s.l",  64, INSN_CLASS_F_INX,   "D,s",       MATCH_FCVT_S_L|MASK_RM, MASK_FCVT_S_L|MASK_RM, match_opcode, 0 },
> -{"fcvt.s.l",  64, INSN_CLASS_F_INX,   "D,s,m",     MATCH_FCVT_S_L, MASK_FCVT_S_L, match_opcode, 0 },
> -{"fcvt.s.lu", 64, INSN_CLASS_F_INX,   "D,s",       MATCH_FCVT_S_LU|MASK_RM, MASK_FCVT_S_LU|MASK_RM, match_opcode, 0 },
> -{"fcvt.s.lu", 64, INSN_CLASS_F_INX,   "D,s,m",     MATCH_FCVT_S_LU, MASK_FCVT_S_LU, match_opcode, 0 },
> +{"fcvt.l.s",  64, INSN_CLASS_F_INX,   "d,Sm",      MATCH_FCVT_L_S, MASK_FCVT_L_S, match_opcode, 0 },
> +{"fcvt.lu.s", 64, INSN_CLASS_F_INX,   "d,Sm",      MATCH_FCVT_LU_S, MASK_FCVT_LU_S, match_opcode, 0 },
> +{"fcvt.s.l",  64, INSN_CLASS_F_INX,   "D,sm",      MATCH_FCVT_S_L, MASK_FCVT_S_L, match_opcode, 0 },
> +{"fcvt.s.lu", 64, INSN_CLASS_F_INX,   "D,sm",      MATCH_FCVT_S_LU, MASK_FCVT_S_LU, match_opcode, 0 },
>
>  /* Double-precision floating-point instruction subset.  */
>  {"fld",        0, INSN_CLASS_ZCD, "D,Cn(Cc)",  MATCH_C_FLDSP, MASK_C_FLDSP, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
> @@ -1089,35 +1051,23 @@ const struct riscv_opcode riscv_opcodes[
>  {"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,T",     MATCH_FADD_D|MASK_RM, MASK_FADD_D|MASK_RM, match_opcode, 0 },
> -{"fadd.d",     0, INSN_CLASS_D_INX,   "D,S,T,m",   MATCH_FADD_D, MASK_FADD_D, match_opcode, 0 },
> -{"fsub.d",     0, INSN_CLASS_D_INX,   "D,S,T",     MATCH_FSUB_D|MASK_RM, MASK_FSUB_D|MASK_RM, match_opcode, 0 },
> -{"fsub.d",     0, INSN_CLASS_D_INX,   "D,S,T,m",   MATCH_FSUB_D, MASK_FSUB_D, match_opcode, 0 },
> -{"fmul.d",     0, INSN_CLASS_D_INX,   "D,S,T",     MATCH_FMUL_D|MASK_RM, MASK_FMUL_D|MASK_RM, match_opcode, 0 },
> -{"fmul.d",     0, INSN_CLASS_D_INX,   "D,S,T,m",   MATCH_FMUL_D, MASK_FMUL_D, match_opcode, 0 },
> -{"fdiv.d",     0, INSN_CLASS_D_INX,   "D,S,T",     MATCH_FDIV_D|MASK_RM, MASK_FDIV_D|MASK_RM, match_opcode, 0 },
> -{"fdiv.d",     0, INSN_CLASS_D_INX,   "D,S,T,m",   MATCH_FDIV_D, MASK_FDIV_D, match_opcode, 0 },
> -{"fsqrt.d",    0, INSN_CLASS_D_INX,   "D,S",       MATCH_FSQRT_D|MASK_RM, MASK_FSQRT_D|MASK_RM, match_opcode, 0 },
> -{"fsqrt.d",    0, INSN_CLASS_D_INX,   "D,S,m",     MATCH_FSQRT_D, MASK_FSQRT_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,R",   MATCH_FMADD_D|MASK_RM, MASK_FMADD_D|MASK_RM, match_opcode, 0 },
> -{"fmadd.d",    0, INSN_CLASS_D_INX,   "D,S,T,R,m", MATCH_FMADD_D, MASK_FMADD_D, match_opcode, 0 },
> -{"fnmadd.d",   0, INSN_CLASS_D_INX,   "D,S,T,R",   MATCH_FNMADD_D|MASK_RM, MASK_FNMADD_D|MASK_RM, match_opcode, 0 },
> -{"fnmadd.d",   0, INSN_CLASS_D_INX,   "D,S,T,R,m", MATCH_FNMADD_D, MASK_FNMADD_D, match_opcode, 0 },
> -{"fmsub.d",    0, INSN_CLASS_D_INX,   "D,S,T,R",   MATCH_FMSUB_D|MASK_RM, MASK_FMSUB_D|MASK_RM, match_opcode, 0 },
> -{"fmsub.d",    0, INSN_CLASS_D_INX,   "D,S,T,R,m", MATCH_FMSUB_D, MASK_FMSUB_D, match_opcode, 0 },
> -{"fnmsub.d",   0, INSN_CLASS_D_INX,   "D,S,T,R",   MATCH_FNMSUB_D|MASK_RM, MASK_FNMSUB_D|MASK_RM, match_opcode, 0 },
> -{"fnmsub.d",   0, INSN_CLASS_D_INX,   "D,S,T,R,m", MATCH_FNMSUB_D, MASK_FNMSUB_D, match_opcode, 0 },
> -{"fcvt.w.d",   0, INSN_CLASS_D_INX,   "d,S",       MATCH_FCVT_W_D|MASK_RM, MASK_FCVT_W_D|MASK_RM, match_opcode, 0 },
> -{"fcvt.w.d",   0, INSN_CLASS_D_INX,   "d,S,m",     MATCH_FCVT_W_D, MASK_FCVT_W_D, match_opcode, 0 },
> -{"fcvt.wu.d",  0, INSN_CLASS_D_INX,   "d,S",       MATCH_FCVT_WU_D|MASK_RM, MASK_FCVT_WU_D|MASK_RM, match_opcode, 0 },
> -{"fcvt.wu.d",  0, INSN_CLASS_D_INX,   "d,S,m",     MATCH_FCVT_WU_D, MASK_FCVT_WU_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,S",       MATCH_FCVT_S_D|MASK_RM, MASK_FCVT_S_D|MASK_RM, match_opcode, 0 },
> -{"fcvt.s.d",   0, INSN_CLASS_D_INX,   "D,S,m",     MATCH_FCVT_S_D, MASK_FCVT_S_D, 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 },
> @@ -1126,14 +1076,10 @@ const struct riscv_opcode riscv_opcodes[
>  {"fge.d",      0, INSN_CLASS_D_INX,   "d,T,S",     MATCH_FLE_D, MASK_FLE_D, match_opcode, INSN_ALIAS },
>  {"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,S",       MATCH_FCVT_L_D|MASK_RM, MASK_FCVT_L_D|MASK_RM, match_opcode, 0 },
> -{"fcvt.l.d",  64, INSN_CLASS_D_INX,   "d,S,m",     MATCH_FCVT_L_D, MASK_FCVT_L_D, match_opcode, 0 },
> -{"fcvt.lu.d", 64, INSN_CLASS_D_INX,   "d,S",       MATCH_FCVT_LU_D|MASK_RM, MASK_FCVT_LU_D|MASK_RM, match_opcode, 0 },
> -{"fcvt.lu.d", 64, INSN_CLASS_D_INX,   "d,S,m",     MATCH_FCVT_LU_D, MASK_FCVT_LU_D, match_opcode, 0 },
> -{"fcvt.d.l",  64, INSN_CLASS_D_INX,   "D,s",       MATCH_FCVT_D_L|MASK_RM, MASK_FCVT_D_L|MASK_RM, match_opcode, 0 },
> -{"fcvt.d.l",  64, INSN_CLASS_D_INX,   "D,s,m",     MATCH_FCVT_D_L, MASK_FCVT_D_L, match_opcode, 0 },
> -{"fcvt.d.lu", 64, INSN_CLASS_D_INX,   "D,s",       MATCH_FCVT_D_LU|MASK_RM, MASK_FCVT_D_LU|MASK_RM, match_opcode, 0 },
> -{"fcvt.d.lu", 64, INSN_CLASS_D_INX,   "D,s,m",     MATCH_FCVT_D_LU, MASK_FCVT_D_LU, match_opcode, 0 },
> +{"fcvt.l.d",  64, INSN_CLASS_D_INX,   "d,Sm",      MATCH_FCVT_L_D, MASK_FCVT_L_D, match_opcode, 0 },
> +{"fcvt.lu.d", 64, INSN_CLASS_D_INX,   "d,Sm",      MATCH_FCVT_LU_D, MASK_FCVT_LU_D, match_opcode, 0 },
> +{"fcvt.d.l",  64, INSN_CLASS_D_INX,   "D,sm",      MATCH_FCVT_D_L, MASK_FCVT_D_L, match_opcode, 0 },
> +{"fcvt.d.lu", 64, INSN_CLASS_D_INX,   "D,sm",      MATCH_FCVT_D_LU, MASK_FCVT_D_LU, match_opcode, 0 },
>
>  /* Quad-precision floating-point instruction subset.  */
>  {"flq",        0, INSN_CLASS_Q,   "D,o(s)",    MATCH_FLQ, MASK_FLQ, match_opcode, INSN_DREF|INSN_16_BYTE },
> @@ -1146,48 +1092,33 @@ const struct riscv_opcode riscv_opcodes[
>  {"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,T",     MATCH_FADD_Q|MASK_RM, MASK_FADD_Q|MASK_RM, match_opcode, 0 },
> -{"fadd.q",     0, INSN_CLASS_Q_INX,   "D,S,T,m",   MATCH_FADD_Q, MASK_FADD_Q, match_opcode, 0 },
> -{"fsub.q",     0, INSN_CLASS_Q_INX,   "D,S,T",     MATCH_FSUB_Q|MASK_RM, MASK_FSUB_Q|MASK_RM, match_opcode, 0 },
> -{"fsub.q",     0, INSN_CLASS_Q_INX,   "D,S,T,m",   MATCH_FSUB_Q, MASK_FSUB_Q, match_opcode, 0 },
> -{"fmul.q",     0, INSN_CLASS_Q_INX,   "D,S,T",     MATCH_FMUL_Q|MASK_RM, MASK_FMUL_Q|MASK_RM, match_opcode, 0 },
> -{"fmul.q",     0, INSN_CLASS_Q_INX,   "D,S,T,m",   MATCH_FMUL_Q, MASK_FMUL_Q, match_opcode, 0 },
> -{"fdiv.q",     0, INSN_CLASS_Q_INX,   "D,S,T",     MATCH_FDIV_Q|MASK_RM, MASK_FDIV_Q|MASK_RM, match_opcode, 0 },
> -{"fdiv.q",     0, INSN_CLASS_Q_INX,   "D,S,T,m",   MATCH_FDIV_Q, MASK_FDIV_Q, match_opcode, 0 },
> -{"fsqrt.q",    0, INSN_CLASS_Q_INX,   "D,S",       MATCH_FSQRT_Q|MASK_RM, MASK_FSQRT_Q|MASK_RM, match_opcode, 0 },
> -{"fsqrt.q",    0, INSN_CLASS_Q_INX,   "D,S,m",     MATCH_FSQRT_Q, MASK_FSQRT_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,R",   MATCH_FMADD_Q|MASK_RM, MASK_FMADD_Q|MASK_RM, match_opcode, 0 },
> -{"fmadd.q",    0, INSN_CLASS_Q_INX,   "D,S,T,R,m", MATCH_FMADD_Q, MASK_FMADD_Q, match_opcode, 0 },
> -{"fnmadd.q",   0, INSN_CLASS_Q_INX,   "D,S,T,R",   MATCH_FNMADD_Q|MASK_RM, MASK_FNMADD_Q|MASK_RM, match_opcode, 0 },
> -{"fnmadd.q",   0, INSN_CLASS_Q_INX,   "D,S,T,R,m", MATCH_FNMADD_Q, MASK_FNMADD_Q, match_opcode, 0 },
> -{"fmsub.q",    0, INSN_CLASS_Q_INX,   "D,S,T,R",   MATCH_FMSUB_Q|MASK_RM, MASK_FMSUB_Q|MASK_RM, match_opcode, 0 },
> -{"fmsub.q",    0, INSN_CLASS_Q_INX,   "D,S,T,R,m", MATCH_FMSUB_Q, MASK_FMSUB_Q, match_opcode, 0 },
> -{"fnmsub.q",   0, INSN_CLASS_Q_INX,   "D,S,T,R",   MATCH_FNMSUB_Q|MASK_RM, MASK_FNMSUB_Q|MASK_RM, match_opcode, 0 },
> -{"fnmsub.q",   0, INSN_CLASS_Q_INX,   "D,S,T,R,m", MATCH_FNMSUB_Q, MASK_FNMSUB_Q, match_opcode, 0 },
> -{"fcvt.w.q",   0, INSN_CLASS_Q_INX,   "d,S",       MATCH_FCVT_W_Q|MASK_RM, MASK_FCVT_W_Q|MASK_RM, match_opcode, 0 },
> -{"fcvt.w.q",   0, INSN_CLASS_Q_INX,   "d,S,m",     MATCH_FCVT_W_Q, MASK_FCVT_W_Q, match_opcode, 0 },
> -{"fcvt.wu.q",  0, INSN_CLASS_Q_INX,   "d,S",       MATCH_FCVT_WU_Q|MASK_RM, MASK_FCVT_WU_Q|MASK_RM, match_opcode, 0 },
> -{"fcvt.wu.q",  0, INSN_CLASS_Q_INX,   "d,S,m",     MATCH_FCVT_WU_Q, MASK_FCVT_WU_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,S",       MATCH_FCVT_S_Q|MASK_RM, MASK_FCVT_S_Q|MASK_RM, match_opcode, 0 },
> -{"fcvt.s.q",   0, INSN_CLASS_Q_INX,   "D,S,m",     MATCH_FCVT_S_Q, MASK_FCVT_S_Q, match_opcode, 0 },
> -{"fcvt.d.q",   0, INSN_CLASS_Q_INX,   "D,S",       MATCH_FCVT_D_Q|MASK_RM, MASK_FCVT_D_Q|MASK_RM, match_opcode, 0 },
> -{"fcvt.d.q",   0, INSN_CLASS_Q_INX,   "D,S,m",     MATCH_FCVT_D_Q, MASK_FCVT_D_Q, 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,S",       MATCH_FCVT_L_Q|MASK_RM, MASK_FCVT_L_Q|MASK_RM, match_opcode, 0 },
> -{"fcvt.l.q",  64, INSN_CLASS_Q_INX,   "d,S,m",     MATCH_FCVT_L_Q, MASK_FCVT_L_Q, match_opcode, 0 },
> -{"fcvt.lu.q", 64, INSN_CLASS_Q_INX,   "d,S",       MATCH_FCVT_LU_Q|MASK_RM, MASK_FCVT_LU_Q|MASK_RM, match_opcode, 0 },
> -{"fcvt.lu.q", 64, INSN_CLASS_Q_INX,   "d,S,m",     MATCH_FCVT_LU_Q, MASK_FCVT_LU_Q, match_opcode, 0 },
> +{"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 },
>
> @@ -1330,23 +1261,15 @@ const struct riscv_opcode riscv_opcodes[
>  {"fmaxm.q",     0, INSN_CLASS_Q_AND_ZFA,   "D,S,T", MATCH_FMAXM_Q, MASK_FMAXM_Q, match_opcode, 0 },
>  {"fminm.h",     0, INSN_CLASS_ZFH_AND_ZFA, "D,S,T", MATCH_FMINM_H, MASK_FMINM_H, match_opcode, 0 },
>  {"fmaxm.h",     0, INSN_CLASS_ZFH_AND_ZFA, "D,S,T", MATCH_FMAXM_H, MASK_FMAXM_H, match_opcode, 0 },
> -{"fround.s",    0, INSN_CLASS_ZFA,         "D,S",   MATCH_FROUND_S|MASK_RM, MASK_FROUND_S|MASK_RM, match_opcode, 0 },
> -{"fround.s",    0, INSN_CLASS_ZFA,         "D,S,m", MATCH_FROUND_S, MASK_FROUND_S, match_opcode, 0 },
> -{"froundnx.s",  0, INSN_CLASS_ZFA,         "D,S",   MATCH_FROUNDNX_S|MASK_RM, MASK_FROUNDNX_S|MASK_RM, match_opcode, 0 },
> -{"froundnx.s",  0, INSN_CLASS_ZFA,         "D,S,m", MATCH_FROUNDNX_S, MASK_FROUNDNX_S, match_opcode, 0 },
> -{"fround.d",    0, INSN_CLASS_D_AND_ZFA,   "D,S",   MATCH_FROUND_D|MASK_RM, MASK_FROUND_D|MASK_RM, match_opcode, 0 },
> -{"fround.d",    0, INSN_CLASS_D_AND_ZFA,   "D,S,m", MATCH_FROUND_D, MASK_FROUND_D, match_opcode, 0 },
> -{"froundnx.d",  0, INSN_CLASS_D_AND_ZFA,   "D,S",   MATCH_FROUNDNX_D|MASK_RM, MASK_FROUNDNX_D|MASK_RM, match_opcode, 0 },
> -{"froundnx.d",  0, INSN_CLASS_D_AND_ZFA,   "D,S,m", MATCH_FROUNDNX_D, MASK_FROUNDNX_D, match_opcode, 0 },
> -{"fround.q",    0, INSN_CLASS_Q_AND_ZFA,   "D,S",   MATCH_FROUND_Q|MASK_RM, MASK_FROUND_Q|MASK_RM, match_opcode, 0 },
> -{"fround.q",    0, INSN_CLASS_Q_AND_ZFA,   "D,S,m", MATCH_FROUND_Q, MASK_FROUND_Q, match_opcode, 0 },
> -{"froundnx.q",  0, INSN_CLASS_Q_AND_ZFA,   "D,S",   MATCH_FROUNDNX_Q|MASK_RM, MASK_FROUNDNX_Q|MASK_RM, match_opcode, 0 },
> -{"froundnx.q",  0, INSN_CLASS_Q_AND_ZFA,   "D,S,m", MATCH_FROUNDNX_Q, MASK_FROUNDNX_Q, match_opcode, 0 },
> -{"fround.h",    0, INSN_CLASS_ZFH_AND_ZFA, "D,S",   MATCH_FROUND_H|MASK_RM, MASK_FROUND_H|MASK_RM, match_opcode, 0 },
> -{"fround.h",    0, INSN_CLASS_ZFH_AND_ZFA, "D,S,m", MATCH_FROUND_H, MASK_FROUND_H, match_opcode, 0 },
> -{"froundnx.h",  0, INSN_CLASS_ZFH_AND_ZFA, "D,S",   MATCH_FROUNDNX_H|MASK_RM, MASK_FROUNDNX_H|MASK_RM, match_opcode, 0 },
> -{"froundnx.h",  0, INSN_CLASS_ZFH_AND_ZFA, "D,S,m", MATCH_FROUNDNX_H, MASK_FROUNDNX_H, match_opcode, 0 },
> -{"fcvtmod.w.d", 0, INSN_CLASS_D_AND_ZFA,   "d,S,m", MATCH_FCVTMOD_W_D, MASK_FCVTMOD_W_D, match_opcode, 0 },
> +{"fround.s",    0, INSN_CLASS_ZFA,         "D,Sm",  MATCH_FROUND_S, MASK_FROUND_S, match_opcode, 0 },
> +{"froundnx.s",  0, INSN_CLASS_ZFA,         "D,Sm",  MATCH_FROUNDNX_S, MASK_FROUNDNX_S, match_opcode, 0 },
> +{"fround.d",    0, INSN_CLASS_D_AND_ZFA,   "D,Sm",  MATCH_FROUND_D, MASK_FROUND_D, match_opcode, 0 },
> +{"froundnx.d",  0, INSN_CLASS_D_AND_ZFA,   "D,Sm",  MATCH_FROUNDNX_D, MASK_FROUNDNX_D, match_opcode, 0 },
> +{"fround.q",    0, INSN_CLASS_Q_AND_ZFA,   "D,Sm",  MATCH_FROUND_Q, MASK_FROUND_Q, match_opcode, 0 },
> +{"froundnx.q",  0, INSN_CLASS_Q_AND_ZFA,   "D,Sm",  MATCH_FROUNDNX_Q, MASK_FROUNDNX_Q, match_opcode, 0 },
> +{"fround.h",    0, INSN_CLASS_ZFH_AND_ZFA, "D,Sm",  MATCH_FROUND_H, MASK_FROUND_H, match_opcode, 0 },
> +{"froundnx.h",  0, INSN_CLASS_ZFH_AND_ZFA, "D,Sm",  MATCH_FROUNDNX_H, MASK_FROUNDNX_H, match_opcode, 0 },
> +{"fcvtmod.w.d", 0, INSN_CLASS_D_AND_ZFA,   "d,S,M", MATCH_FCVTMOD_W_D, MASK_FCVTMOD_W_D, match_opcode, 0 },
>  {"fmvh.x.d",   32, INSN_CLASS_D_AND_ZFA,   "d,S",   MATCH_FMVH_X_D, MASK_FMVH_X_D, match_opcode, 0 },
>  {"fmvp.d.x",   32, INSN_CLASS_D_AND_ZFA,   "D,s,t", MATCH_FMVP_D_X, MASK_FMVP_D_X, match_opcode, 0 },
>  {"fmvh.x.q",   64, INSN_CLASS_Q_AND_ZFA,   "d,S",   MATCH_FMVH_X_Q, MASK_FMVH_X_Q, match_opcode, 0 },
>