[03/19] RISC-V: add dedicated vector arithmetic .insn forms

Jiawei jiawei@iscas.ac.cn
Tue Apr 28 02:18:52 GMT 2026


> As .insn documentation states, using the available .insn forms can be a
> little challenging. For OP_V, help the situation by providing a few more
> dedicated forms.
> ---
> RFC: OP_VE reuses (at least) OPMVV, so "mvv" would end up ambiguous if we
>      wanted to also introduce insn forms there. I wanted to avoid having
>      O4 as the first operand everywhere, though. An option might be to
>      distinguish future OP_VE ones (in the once supposed P extension
>      encoding space iirc) by e.g. prefixing with P, or - derived from
>      OP_VE - with E.
>
> No form is provided for OPCFG: Such insns may better use "r" forms, or
> whatever is best suited there.
>
> For OPIVI permitting both signed (Vi) and unsigned (Vj) immediates might
> be nice, but won't work with the present parsing (needs delaying
> as_bad()).
>
> To help encoding V*UNARY* insns, forms with immediates in the respective
> positions may be helpful. Thoughts? (Some of the testcase additions are
> commented upon accordingly.)
>
This looks useful to me. The new OP-V .insn forms make vector arithmetic
encodings much easier to write than the generic r form, and adding F6 
for the
funct6 field looks natural.

For the OP-VE ambiguity mentioned in the RFC note, I think keeping
ivv/fvv/mvv/... for OP-V is fine. Future OP-VE forms could use a distinct
prefix, such as e* or p*, to avoid overloading mvv.

For V*UNARY* instructions, dedicated forms may indeed be clearer, especially
when an operand position is effectively used as an opcode/immediate field.
But I think that can be handled as a follow-up; the current forms already
improve the common OP-V cases.

Best regards,

Jiawei


>
> --- a/gas/config/tc-riscv.c
> +++ b/gas/config/tc-riscv.c
> @@ -1611,6 +1611,7 @@ validate_riscv_insn (const struct riscv_
>        switch (*++oparg)
>          {
>          case '7': USE_BITS (OP_MASK_FUNCT7, OP_SH_FUNCT7); break;
> +        case '6': USE_BITS (OP_MASK_FUNCT6, OP_SH_FUNCT6); break;
>          case '3': USE_BITS (OP_MASK_FUNCT3, OP_SH_FUNCT3); break;
>          case '2': USE_BITS (OP_MASK_FUNCT2, OP_SH_FUNCT2); break;
>          default:
> @@ -3750,6 +3751,10 @@ riscv_ip (char *str, struct riscv_cl_ins
>            INSERT_OPERAND (FUNCT7, *ip, imm_expr->X_add_number);
>            break;
>
> +        case 6:
> +          INSERT_OPERAND (FUNCT6, *ip, imm_expr->X_add_number);
> +          break;
> +
>          case 3:
>            INSERT_OPERAND (FUNCT3, *ip, imm_expr->X_add_number);
>            break;
> --- a/gas/testsuite/gas/riscv/insn.d
> +++ b/gas/testsuite/gas/riscv/insn.d
> @@ -70,6 +70,19 @@ Disassembly of section .text:
>  [^:]+:[     ]+00c58533[     ]+add[     ]+a0,a1,a2
>  [^:]+:[     ]+00c58533[     ]+add[     ]+a0,a1,a2
>  [^:]+:[     ]+022180d7[     ]+vadd\.vv[     ]+v1,v2,v3
> +[^:]+:[     ]+2c2081d7[     ]+vxor\.vv[     ]+v3,v2,v1,v0\.t
> +[^:]+:[     ]+182091d7[     ]+vfmax\.vv[     ]+v3,v2,v1,v0\.t
> +[^:]+:[     ]+fc1111d7[     ]+vfwnmsac\.vv[  ]+v3,v2,v1,v0\.t
> +[^:]+:[     ]+422010d7[     ]+vfmv\.f\.s[     ]+ft1,v2
> +[^:]+:[     ]+7a20a1d7[     ]+vmnor\.mm[     ]+v3,v2,v1
> +[^:]+:[     ]+422020d7[     ]+vmv\.x\.s[     ]+ra,v2
> +[^:]+:[     ]+2c20b1d7[     ]+vxor\.vi[     ]+v3,v2,1,v0\.t
> +[^:]+:[     ]+2c20c1d7[     ]+vxor\.vx[     ]+v3,v2,ra,v0\.t
> +[^:]+:[     ]+1820d1d7[     ]+vfmax\.vf[     ]+v3,v2,ft1,v0\.t
> +[^:]+:[     ]+fc1151d7[     ]+vfwnmsac\.vf[  ]+v3,ft2,v1,v0\.t
> +[^:]+:[     ]+420150d7[     ]+vfmv\.s\.f[     ]+v1,ft2
> +[^:]+:[     ]+bc1161d7[     ]+vnmsac\.vx[     ]+v3,sp,v1,v0\.t
> +[^:]+:[     ]+420160d7[     ]+vmv\.s\.x[     ]+v1,sp
>  [^:]+:[     ]+0001[     ]+nop
>  [^:]+:[     ]+00000013[     ]+nop
>  [^:]+:[     ]+001f 0000 0000[     ].*
> --- a/gas/testsuite/gas/riscv/insn.s
> +++ b/gas/testsuite/gas/riscv/insn.s
> @@ -56,6 +56,23 @@ target:
>
>      .insn r  OP_V, 0, 1, x1, x3, x2
>
> +    .option push
> +    .option arch, +v
> +    .insn ivv 0x0b, v3, v2, v1, v0.t
> +    .insn fvv 0x06, v3, v2, v1, v0.t
> +    .insn fvv 0x3f, v3, v1, v2, v0.t
> +    .insn fvv 0x10, f1, v2, v0        # last operand is opcode
> +    .insn mvv 0x1e, v3, v2, v1
> +    .insn mvv 0x10, x1, v2, v0        # last operand is opcode
> +    .insn ivi 0x0b, v3, v2, 1, v0.t
> +    .insn ivx 0x0b, v3, v2, x1, v0.t
> +    .insn fvf 0x06, v3, v2, f1, v0.t
> +    .insn fvf 0x3f, v3, v1, f2, v0.t
> +    .insn fvf 0x10, v1, v0, f2        # middle operand is opcode
> +    .insn mvx 0x2f, v3, v1, x2, v0.t
> +    .insn mvx 0x10, v1, v0, x2        # middle operand is opcode
> +    .option pop
> +
>      .insn 0x0001
>      .insn 0x00000013
>      .insn 0x0000001f
> --- a/gas/testsuite/gas/riscv/insn-dwarf.d
> +++ b/gas/testsuite/gas/riscv/insn-dwarf.d
> @@ -60,28 +60,41 @@ insn.s +53 +0x9a.*
>  insn.s +54 +0x9e.*
>  insn.s +55 +0xa2.*
>  insn.s +57 +0xa6.*
> -insn.s +59 +0xaa.*
> -insn.s +60 +0xac.*
> -insn.s +61 +0xb0.*
> -insn.s +62 +0xb6.*
> -insn.s +63 +0xbe.*
> -insn.s +64 +0xc8.*
> -insn.s +65 +0xd4.*
> -insn.s +66 +0xea.*
> -insn.s +67 +0xec.*
> -insn.s +68 +0xf0.*
> -insn.s +69 +0xf6.*
> -insn.s +70 +0xfe.*
> -insn.s +71 +0x108.*
> -insn.s +72 +0x114.*
> -insn.s +74 +0x12a.*
> -insn.s +75 +0x134.*
> -insn.s +76 +0x13e.*
> -insn.s +77 +0x154.*
> -insn.s +78 +0x16a.*
> -insn.s +79 +0x180.*
> -insn.s +80 +0x196.*
> -insn.s +81 +0x1ac.*
> -insn.s +83 +0x1c2.*
> -insn.s +- +0x1c6
> +insn.s +61 +0xaa.*
> +insn.s +62 +0xae.*
> +insn.s +63 +0xb2.*
> +insn.s +64 +0xb6.*
> +insn.s +65 +0xba.*
> +insn.s +66 +0xbe.*
> +insn.s +67 +0xc2.*
> +insn.s +68 +0xc6.*
> +insn.s +69 +0xca.*
> +insn.s +70 +0xce.*
> +insn.s +71 +0xd2.*
> +insn.s +72 +0xd6.*
> +insn.s +73 +0xda.*
> +insn.s +76 +0xde.*
> +insn.s +77 +0xe0.*
> +insn.s +78 +0xe4.*
> +insn.s +79 +0xea.*
> +insn.s +80 +0xf2.*
> +insn.s +81 +0xfc.*
> +insn.s +82 +0x108.*
> +insn.s +83 +0x11e.*
> +insn.s +84 +0x120.*
> +insn.s +85 +0x124.*
> +insn.s +86 +0x12a.*
> +insn.s +87 +0x132.*
> +insn.s +88 +0x13c.*
> +insn.s +89 +0x148.*
> +insn.s +91 +0x15e.*
> +insn.s +92 +0x168.*
> +insn.s +93 +0x172.*
> +insn.s +94 +0x188.*
> +insn.s +95 +0x19e.*
> +insn.s +96 +0x1b4.*
> +insn.s +97 +0x1ca.*
> +insn.s +98 +0x1e0.*
> +insn.s +100 +0x1f6.*
> +insn.s +- +0x1fa
>  #pass
> --- a/gas/testsuite/gas/riscv/insn-na.d
> +++ b/gas/testsuite/gas/riscv/insn-na.d
> @@ -59,6 +59,19 @@ Disassembly of section .text:
>  [^:]+:[     ]+00c58533[     ]+add[     ]+a0,a1,a2
>  [^:]+:[     ]+00c58533[     ]+add[     ]+a0,a1,a2
>  [^:]+:[     ]+022180d7[     ]+vadd\.vv[     ]+v1,v2,v3
> +[^:]+:[     ]+2c2081d7[     ]+vxor\.vv[     ]+v3,v2,v1,v0\.t
> +[^:]+:[     ]+182091d7[     ]+vfmax\.vv[     ]+v3,v2,v1,v0\.t
> +[^:]+:[     ]+fc1111d7[     ]+vfwnmsac\.vv[  ]+v3,v2,v1,v0\.t
> +[^:]+:[     ]+422010d7[     ]+vfmv\.f\.s[     ]+ft1,v2
> +[^:]+:[     ]+7a20a1d7[     ]+vmnor\.mm[     ]+v3,v2,v1
> +[^:]+:[     ]+422020d7[     ]+vmv\.x\.s[     ]+ra,v2
> +[^:]+:[     ]+2c20b1d7[     ]+vxor\.vi[     ]+v3,v2,1,v0\.t
> +[^:]+:[     ]+2c20c1d7[     ]+vxor\.vx[     ]+v3,v2,ra,v0\.t
> +[^:]+:[     ]+1820d1d7[     ]+vfmax\.vf[     ]+v3,v2,ft1,v0\.t
> +[^:]+:[     ]+fc1151d7[     ]+vfwnmsac\.vf[  ]+v3,ft2,v1,v0\.t
> +[^:]+:[     ]+420150d7[     ]+vfmv\.s\.f[     ]+v1,ft2
> +[^:]+:[     ]+bc1161d7[     ]+vnmsac\.vx[     ]+v3,sp,v1,v0\.t
> +[^:]+:[     ]+420160d7[     ]+vmv\.s\.x[     ]+v1,sp
>  [^:]+:[     ]+0001[     ]+c\.addi[     ]+zero,0
>  [^:]+:[     ]+00000013[     ]+addi[     ]+zero,zero,0
>  [^:]+:[     ]+001f 0000 0000[     ].*
> --- a/include/opcode/riscv.h
> +++ b/include/opcode/riscv.h
> @@ -351,6 +351,9 @@ static inline unsigned int riscv_insn_le
>
>  /* RVV fields.  */
>
> +#define OP_MASK_FUNCT6        0x3fU
> +#define OP_SH_FUNCT6        26
> +
>  #define OP_MASK_VD        0x1f
>  #define OP_SH_VD        7
>  #define OP_MASK_VS1        0x1f
> --- a/opcodes/riscv-opc.c
> +++ b/opcodes/riscv-opc.c
> @@ -3656,6 +3656,17 @@ const struct riscv_opcode riscv_insn_typ
>  {"j",       0, INSN_CLASS_I,       "O4,d,a",            0, 0, NULL, 0 },
>  {"j",       0, INSN_CLASS_F,       "O4,D,a",            0, 0, NULL, 0 },
>
> +{"ivv",     0, INSN_CLASS_V,       "F6,Vd,Vt,VsVm", 0x0057, 0x707f, 
> NULL, 0 },
> +{"fvv",     0, INSN_CLASS_ZVEF,    "F6,Vd,Vt,VsVm", 0x1057, 0x707f, 
> NULL, 0 },
> +{"fvv",     0, INSN_CLASS_ZVEF,    "F6,D,Vt,VsVm",  0x1057, 0x707f, 
> NULL, 0 },
> +{"mvv",     0, INSN_CLASS_V,       "F6,Vd,Vt,VsVm", 0x2057, 0x707f, 
> NULL, 0 },
> +{"mvv",     0, INSN_CLASS_V,       "F6,d,Vt,VsVm",  0x2057, 0x707f, 
> NULL, 0 },
> +{"ivi",     0, INSN_CLASS_V,       "F6,Vd,Vt,ViVm", 0x3057, 0x707f, 
> NULL, 0 },
> +{"ivx",     0, INSN_CLASS_V,       "F6,Vd,Vt,sVm",  0x4057, 0x707f, 
> NULL, 0 },
> +{"fvf",     0, INSN_CLASS_ZVEF,    "F6,Vd,Vt,SVm",  0x5057, 0x707f, 
> NULL, 0 },
> +{"mvx",     0, INSN_CLASS_V,       "F6,Vd,Vt,sVm",  0x6057, 0x707f, 
> NULL, 0 },
> +{"mvx",     0, INSN_CLASS_V,       "F6,d,Vt,sVm",   0x6057, 0x707f, 
> NULL, 0 },
> +
>  {"cr",      0, INSN_CLASS_ZCA,       "O2,CF4,d,CV",       0, 0, NULL, 
> 0 },
>  {"cr",      0, INSN_CLASS_ZCF, "O2,CF4,D,CV",       0, 0, NULL, 0 },
>  {"cr",      0, INSN_CLASS_ZCF, "O2,CF4,d,CT",       0, 0, NULL, 0 },
>



More information about the Binutils mailing list