Introduction
The vector extension has 32 vector registers whose length (VLEN) the implementation chooses. The program sets the
element width (SEW: 8, 16, 32, 64), the register grouping (LMUL: 1/8 to 8) and the vector length (vl) with
vsetvli; the same instruction then works on as many elements as vl says. The explorer
decodes the instruction and does not track vtype, so it cannot say how many elements an operation
covers. Vector instructions are in the OP-V major opcode (1010111, bits 6:0), vector loads and
stores in LOAD-FP and STORE-FP, and the vector cryptography instructions in OP-VE (1110111).
The mask operand: bit 25 (vm) is 1 for an unmasked instruction; 0 means the instruction is masked by
v0, written , v0.t after the operands. A few instructions (add with carry, merge) take
v0 as an explicit operand and need vm = 0.
Zve32x, Zve32f, Zve64x, Zve64f and Zve64d are the embedded subsets of V: the decoder takes the
floating-point instructions from Zve32f (single precision) and the 64-bit element forms from Zve64x. Indexed
loads and stores with 64-bit index elements are decoded on RV64 only (as llvm-mc does).
Configuration
| Instruction | Encoding | What it does |
|---|---|---|
vsetvli rd, rs1, vtypei | OP-V, funct3 111, bit 31 = 0, vtype in bits 30:20 | vl = min(rs1, VLMAX) with the new vtype; rd receives vl. With rs1 = x0 and rd ≠ x0 it asks for VLMAX; with both x0 it only changes vtype. |
vsetivli rd, uimm, vtypei | funct3 111, bits 31:30 = 11, vtype in bits 29:20, uimm in the rs1 field | As vsetvli with a five-bit immediate length. |
vsetvl rd, rs1, rs2 | funct3 111, bits 31:25 = 1000000 | As vsetvli, vtype from rs2. |
vtype: bits 2:0 vlmul (0 m1, 1 m2, 2 m4, 3 m8, 5 mf8, 6 mf4, 7 mf2; 4 is reserved), bits 5:3 vsew (0 e8, 1 e16, 2 e32, 3 e64), bit 6
vta (ta tail agnostic, tu undisturbed), bit 7 vma (ma, mu). The
explorer writes e32, m1, ta, ma; a vtype with reserved bits is written as the number.
Loads and stores
Bits 31:29 are nf (the number of fields minus one: 0 for a plain access, 1 to 7 for a segment access of 2 to 8 fields), bit 28 is mew (0), bits 27:26 the addressing mode (mop), bit 25 vm, bits 24:20 a sub-opcode or register, and funct3 gives the element width: 000 = 8, 101 = 16, 110 = 32, 111 = 64 bits (the other values are the scalar floating-point loads and stores). The base address is in rs1.
| Form | mop | Bits 24:20 | Mnemonics |
|---|---|---|---|
| Unit-stride | 00 | 00000 | vle8.v to vle64.v, vse8.v to vse64.v; segments vlseg2e8.v to vlseg8e64.v, vsseg… |
| Unit-stride, fault-only-first | 00 | 10000 | vle8ff.v … vle64ff.v, vlseg2e8ff.v … |
| Mask | 00 | 01011 | vlm.v, vsm.v (vm must be 1) |
| Whole register | 00 | 01000 | vl1re8.v … vl8re64.v (nf = 0, 1, 3, 7), vs1r.v, vs2r.v, vs4r.v, vs8r.v; the register number must be a multiple of the count |
| Strided | 10 | rs2 (the stride) | vlse8.v … vlse64.v, vsse…, vlsseg2e8.v … |
| Indexed, unordered | 01 | vs2 (the offsets) | vluxei8.v … vluxei64.v, vsuxei…, vluxseg2ei8.v … |
| Indexed, ordered | 11 | vs2 | vloxei8.v …, vsoxei…, vloxseg2ei8.v … |
Arithmetic by funct6
Bits 31:26 (funct6) and funct3 choose the instruction: funct3 000 is OPIVV (.vv: vector and vector),
100 OPIVX (.vx: vector and scalar register), 011 OPIVI (.vi: vector and a 5-bit immediate),
010 OPMVV and 110 OPMVX (the “M” group of mask, multiply, divide, widening and reductions), 001 OPFVV and 101 OPFVF
(floating point, .vv and .vf). Operands are vd, vs2, vs1|rs1|imm; the
multiply-add group is written vd, vs1|rs1, vs2. Suffix .w means a wide operand
(vwadd.wv, vnsrl.wx); .vs a reduction into element 0;
.vvm, .vxm, .vim use v0 as an input.
| funct6 | OPIVV / OPIVX / OPIVI | OPMVV / OPMVX | OPFVV / OPFVF |
|---|---|---|---|
000000 | vadd | vredsum | vfadd |
000001 | vandn (Zvkb) | vredand | vfredusum |
000010 | vsub | vredor | vfsub |
000011 | vrsub (.vx .vi) | vredxor | vfredosum |
000100 | vminu | vredminu | vfmin |
000101 | vmin | vredmin | vfredmin |
000110 | vmaxu | vredmaxu | vfmax |
000111 | vmax | vredmax | vfredmax |
001000 | vaaddu | vfsgnj | |
001001 | vand | vaadd | vfsgnjn |
001010 | vor | vasubu | vfsgnjx |
001011 | vxor | vasub | |
001100 | vrgather | vclmul (Zvbc) | |
001101 | vclmulh (Zvbc) | ||
001110 | vrgatherei16 (.vv), vslideup (.vx .vi) | vslide1up (.vx) | vfslide1up (.vf) |
001111 | vslidedown (.vx .vi) | vslide1down (.vx) | vfslide1down (.vf) |
010000 | vadc, vmadc with carry in (vm = 0) | vmv.x.s, vcpop.m, vfirst.m (vs1 = 0, 16, 17); vmv.s.x | vfmv.f.s; vfmv.s.f |
010001 | vmadc (carry out; vm = 1: without carry in) | ||
010010 | vsbc (vm = 0) | vzext, vsext (vs1 = 2 to 7); Zvbb: vbrev8, vrev8, vbrev, vclz, vctz, vcpop (vs1 = 8, 9, 10, 12, 13, 14) | vfcvt, vfwcvt, vfncvt (vs1 selects the conversion) |
010011 | vmsbc | vfsqrt, vfrsqrt7, vfrec7, vfclass (vs1 = 0, 4, 5, 16) | |
010100 | vror (Zvkb) | vmsbf, vmsof, vmsif, viota (vs1 = 1, 2, 3, 16), vid (vs1 = 17) | |
010101 | vrol (Zvkb) | ||
010111 | vmerge (vm = 0) and vmv.v.* (vm = 1, vs2 = 0) | vcompress | vfmerge, vfmv.v.f |
011000 | vmseq | vmandn | vmfeq |
011001 | vmsne | vmand | vmfle |
011010 | vmsltu | vmor | |
011011 | vmslt | vmxor | vmflt |
011100 | vmsleu | vmorn | vmfne |
011101 | vmsle | vmnand | vmfgt (.vf) |
011110 | vmsgtu (.vx .vi) | vmnor | |
011111 | vmsgt (.vx .vi) | vmxnor | vmfge (.vf) |
100000 | vsaddu | vdivu | vfdiv |
100001 | vsadd | vdiv | vfrdiv (.vf) |
100010 | vssubu | vremu | |
100011 | vssub | vrem | |
100100 | vmulhu | vfmul | |
100101 | vsll | vmul | |
100110 | vmulhsu | ||
100111 | vsmul (.vv .vx); vmv1r, vmv2r, vmv4r, vmv8r (.vi) | vmulh | vfrsub (.vf) |
101000 | vsrl | vfmadd | |
101001 | vsra | vmadd | vfnmadd |
101010 | vssrl | vfmsub | |
101011 | vssra | vnmsub | vfnmsub |
101100 | vnsrl | vfmacc | |
101101 | vnsra | vmacc | vfnmacc |
101110 | vnclipu | vfmsac | |
101111 | vnclip | vnmsac | vfnmsac |
110000 | vwredsumu | vwaddu | vfwadd |
110001 | vwredsum | vwadd | vfwredusum |
110010 | vwsubu | vfwsub | |
110011 | vwsub | vfwredosum | |
110100 | vwaddu.w | vfwadd.w | |
110101 | vwsll (Zvbb) | vwadd.w | |
110110 | vwsubu.w | vfwsub.w | |
110111 | vwsub.w | ||
111000 | vwmulu | vfwmul | |
111010 | vwmulsu | ||
111011 | vwmul | vfwmaccbf16 (Zvfbfwma) | |
111100 | vwmaccu | vfwmacc | |
111101 | vwmacc | vfwnmacc | |
111110 | vwmaccus (.vx) | vfwmsac | |
111111 | vwmaccsu | vfwnmsac |
The conversion group (funct6 010010, OPFVV) has vfcvt.xu.f.v (vs1 = 0), x.f (1),
f.xu (2), f.x (3), rtz.xu.f (6), rtz.x.f (7); the widening
vfwcvt forms at 8 to 15 (xu.f 8, x.f 9, f.xu 10, f.x
11, f.f 12, vfwcvtbf16.f.f.v 13, rtz.xu.f 14, rtz.x.f 15); the
narrowing vfncvt forms at 16 to 23 (xu.f 16, x.f 17, f.xu 18,
f.x 19, f.f 20, rod.f.f 21, rtz.xu.f 22, rtz.x.f 23)
and vfncvtbf16.f.f.w at 29.
Vector cryptography (OP-VE, opcode 1110111)
All have vm = 1 and funct3 010. Zvkned: vaesdm.vv, vaesdf.vv, vaesem.vv,
vaesef.vv (funct6 101000, vs1 = 0 to 3) and the .vs forms (101001), vaesz.vs
(101001, vs1 = 7), vaeskf1.vi (100010), vaeskf2.vi (101010). Zvksed:
vsm4r.vv and .vs (vs1 = 16), vsm4k.vi (100001). Zvksh:
vsm3me.vv (100000), vsm3c.vi (101011). Zvkg: vghsh.vv
(101100), vgmul.vv (101000, vs1 = 17). Zvknha and Zvknhb: vsha2ms.vv,
vsha2ch.vv, vsha2cl.vv (101101, 101110, 101111).
Not described
- What each operation does to the elements (masked-off, tail and prestart elements, LMUL and EEW constraints): see the vector chapter of the manual; the explorer shows the instruction and its operands.
- Register-overlap rules between destination and source groups (the decoder checks only the alignment of the whole-register moves, loads and stores).
- Other vector sub-extensions (Zvfofp8min, Zvqdotq, Zvzip and the like, still under development) and the vendor vector extensions.