[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