]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj/riscv: implement vector load/store instructions
authorJoel Sing <joel@sing.id.au>
Mon, 17 Jun 2024 17:00:47 +0000 (03:00 +1000)
committerJoel Sing <joel@sing.id.au>
Thu, 27 Feb 2025 11:47:20 +0000 (03:47 -0800)
Implement vector unit stride, vector strided, vector indexed and
vector whole register load and store instructions.

The vector unit stride instructions take an optional vector mask
register, which if specified must be register V0. If only two
operands are given, the instruction is encoded as unmasked.

The vector strided and vector indexed instructions also take an
optional vector mask register, which if specified must be register
V0. If only three operands are given, the instruction is encoded as
unmasked.

Cq-Include-Trybots: luci.golang.try:gotip-linux-riscv64
Change-Id: I35e43bb8f1cf6ae8826fbeec384b95ac945da50f
Reviewed-on: https://go-review.googlesource.com/c/go/+/631937
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Mark Ryan <markdryan@rivosinc.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Meng Zhuo <mengzhuo1203@gmail.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Pengcheng Wang <wangpengcheng.pp@bytedance.com>
src/cmd/asm/internal/asm/testdata/riscv64.s
src/cmd/asm/internal/asm/testdata/riscv64error.s
src/cmd/internal/obj/riscv/anames.go
src/cmd/internal/obj/riscv/cpu.go
src/cmd/internal/obj/riscv/obj.go

index fc44f561f259ab2e2eb25bf0d6c186418f05207d..5aa2563b6ffb0da37c7393e28b0c6476946a5718 100644 (file)
@@ -448,6 +448,104 @@ start:
        VSETIVLI $31, E32, M1, TA, MA, X12              // 57f60fcd
        VSETVL  X10, X11, X12                           // 57f6a580
 
+       // 31.7.4: Vector Unit-Stride Instructions
+       VLE8V           (X10), V3                       // 87010502
+       VLE8V           (X10), V0, V3                   // 87010500
+       VLE16V          (X10), V3                       // 87510502
+       VLE16V          (X10), V0, V3                   // 87510500
+       VLE32V          (X10), V3                       // 87610502
+       VLE32V          (X10), V0, V3                   // 87610500
+       VLE64V          (X10), V3                       // 87710502
+       VLE64V          (X10), V0, V3                   // 87710500
+       VSE8V           V3, (X10)                       // a7010502
+       VSE8V           V3, V0, (X10)                   // a7010500
+       VSE16V          V3, (X10)                       // a7510502
+       VSE16V          V3, V0, (X10)                   // a7510500
+       VSE32V          V3, (X10)                       // a7610502
+       VSE32V          V3, V0, (X10)                   // a7610500
+       VSE64V          V3, (X10)                       // a7710502
+       VSE64V          V3, V0, (X10)                   // a7710500
+       VLMV            (X10), V3                       // 8701b502
+       VSMV            V3, (X10)                       // a701b502
+
+       // 31.7.5: Vector Strided Instructions
+       VLSE8V          (X10), X11, V3                  // 8701b50a
+       VLSE8V          (X10), X11, V0, V3              // 8701b508
+       VLSE16V         (X10), X11, V3                  // 8751b50a
+       VLSE16V         (X10), X11, V0, V3              // 8751b508
+       VLSE32V         (X10), X11, V3                  // 8761b50a
+       VLSE32V         (X10), X11, V0, V3              // 8761b508
+       VLSE64V         (X10), X11, V3                  // 8771b50a
+       VLSE64V         (X10), X11, V0, V3              // 8771b508
+       VSSE8V          V3, X11, (X10)                  // a701b50a
+       VSSE8V          V3, X11, V0, (X10)              // a701b508
+       VSSE16V         V3, X11, (X10)                  // a751b50a
+       VSSE16V         V3, X11, V0, (X10)              // a751b508
+       VSSE32V         V3, X11, (X10)                  // a761b50a
+       VSSE32V         V3, X11, V0, (X10)              // a761b508
+       VSSE64V         V3, X11, (X10)                  // a771b50a
+       VSSE64V         V3, X11, V0, (X10)              // a771b508
+
+       // 31.7.6: Vector Indexed Instructions
+       VLUXEI8V        (X10), V2, V3                   // 87012506
+       VLUXEI8V        (X10), V2, V0, V3               // 87012504
+       VLUXEI16V       (X10), V2, V3                   // 87512506
+       VLUXEI16V       (X10), V2, V0, V3               // 87512504
+       VLUXEI32V       (X10), V2, V3                   // 87612506
+       VLUXEI32V       (X10), V2, V0, V3               // 87612504
+       VLUXEI64V       (X10), V2, V3                   // 87712506
+       VLUXEI64V       (X10), V2, V0, V3               // 87712504
+       VLOXEI8V        (X10), V2, V3                   // 8701250e
+       VLOXEI8V        (X10), V2, V0, V3               // 8701250c
+       VLOXEI16V       (X10), V2, V3                   // 8751250e
+       VLOXEI16V       (X10), V2, V0, V3               // 8751250c
+       VLOXEI32V       (X10), V2, V3                   // 8761250e
+       VLOXEI32V       (X10), V2, V0, V3               // 8761250c
+       VLOXEI64V       (X10), V2, V3                   // 8771250e
+       VLOXEI64V       (X10), V2, V0, V3               // 8771250c
+       VSUXEI8V        V3, V2, (X10)                   // a7012506
+       VSUXEI8V        V3, V2, V0, (X10)               // a7012504
+       VSUXEI16V       V3, V2, (X10)                   // a7512506
+       VSUXEI16V       V3, V2, V0, (X10)               // a7512504
+       VSUXEI32V       V3, V2, (X10)                   // a7612506
+       VSUXEI32V       V3, V2, V0, (X10)               // a7612504
+       VSUXEI64V       V3, V2, (X10)                   // a7712506
+       VSUXEI64V       V3, V2, V0, (X10)               // a7712504
+       VSOXEI8V        V3, V2, (X10)                   // a701250e
+       VSOXEI8V        V3, V2, V0, (X10)               // a701250c
+       VSOXEI16V       V3, V2, (X10)                   // a751250e
+       VSOXEI16V       V3, V2, V0, (X10)               // a751250c
+       VSOXEI32V       V3, V2, (X10)                   // a761250e
+       VSOXEI32V       V3, V2, V0, (X10)               // a761250c
+       VSOXEI64V       V3, V2, (X10)                   // a771250e
+       VSOXEI64V       V3, V2, V0, (X10)               // a771250c
+
+       // 31.7.9: Vector Load/Store Whole Register Instructions
+       VL1RV           (X10), V3                       // 87018502
+       VL1RE8V         (X10), V3                       // 87018502
+       VL1RE16V        (X10), V3                       // 87518502
+       VL1RE32V        (X10), V3                       // 87618502
+       VL1RE64V        (X10), V3                       // 87718502
+       VL2RV           (X10), V2                       // 07018522
+       VL2RE8V         (X10), V2                       // 07018522
+       VL2RE16V        (X10), V2                       // 07518522
+       VL2RE32V        (X10), V2                       // 07618522
+       VL2RE64V        (X10), V2                       // 07718522
+       VL4RV           (X10), V4                       // 07028562
+       VL4RE8V         (X10), V4                       // 07028562
+       VL4RE16V        (X10), V4                       // 07528562
+       VL4RE32V        (X10), V4                       // 07628562
+       VL4RE64V        (X10), V4                       // 07728562
+       VL8RV           (X10), V8                       // 070485e2
+       VL8RE8V         (X10), V8                       // 070485e2
+       VL8RE16V        (X10), V8                       // 075485e2
+       VL8RE32V        (X10), V8                       // 076485e2
+       VL8RE64V        (X10), V8                       // 077485e2
+       VS1RV           V3, (X11)                       // a7818502
+       VS2RV           V2, (X11)                       // 27818522
+       VS4RV           V4, (X11)                       // 27828562
+       VS8RV           V8, (X11)                       // 278485e2
+
        //
        // Privileged ISA
        //
index a90f22af9f40b886d20270669bb47a09dc07e76c..82a23488946a368e64f6bde8e12c3e345975b655 100644 (file)
@@ -50,4 +50,43 @@ TEXT errors(SB),$0
        VSETVLI $-1, E32, M2, TA, MA, X12       // ERROR "must be in range [0, 31] (5 bits)"
        VSETIVLI X10, E32, M2, TA, MA, X12      // ERROR "expected immediate value"
        VSETVL  X10, X11                        // ERROR "expected integer register in rs1 position"
+       VLE8V   (X10), X10                      // ERROR "expected vector register in rd position"
+       VLE8V   (V1), V3                        // ERROR "expected integer register in rs1 position"
+       VLE8V   (X10), V1, V3                   // ERROR "invalid vector mask register"
+       VSE8V   X10, (X10)                      // ERROR "expected vector register in rs1 position"
+       VSE8V   V3, (V1)                        // ERROR "expected integer register in rd position"
+       VSE8V   V3, V1, (X10)                   // ERROR "invalid vector mask register"
+       VLSE8V  (X10), V3                       // ERROR "expected integer register in rs2 position"
+       VLSE8V  (X10), X10, X11                 // ERROR "expected vector register in rd position"
+       VLSE8V  (V1), X10, V3                   // ERROR "expected integer register in rs1 position"
+       VLSE8V  (X10), V1, V0, V3               // ERROR "expected integer register in rs2 position"
+       VLSE8V  (X10), X10, V1, V3              // ERROR "invalid vector mask register"
+       VSSE8V  V3, (X10)                       // ERROR "expected integer register in rs2 position"
+       VSSE8V  X10, X11, (X10)                 // ERROR "expected vector register in rd position"
+       VSSE8V  V3, X11, (V1)                   // ERROR "expected integer register in rs1 position"
+       VSSE8V  V3, V1, V0, (X10)               // ERROR "expected integer register in rs2 position"
+       VSSE8V  V3, X11, V1, (X10)              // ERROR "invalid vector mask register"
+       VLUXEI8V (X10), V2, X11                 // ERROR "expected vector register in rd position"
+       VLUXEI8V (X10), V2, X11                 // ERROR "expected vector register in rd position"
+       VLUXEI8V (V1), V2, V3                   // ERROR "expected integer register in rs1 position"
+       VLUXEI8V (X10), X11, V0, V3             // ERROR "expected vector register in rs2 position"
+       VLUXEI8V (X10), V2, V1, V3              // ERROR "invalid vector mask register"
+       VSUXEI8V X10, V2, (X10)                 // ERROR "expected vector register in rd position"
+       VSUXEI8V V3, V2, (V1)                   // ERROR "expected integer register in rs1 position"
+       VSUXEI8V V3, X11, V0, (X10)             // ERROR "expected vector register in rs2 position"
+       VSUXEI8V V3, V2, V1, (X10)              // ERROR "invalid vector mask register"
+       VLOXEI8V (X10), V2, X11                 // ERROR "expected vector register in rd position"
+       VLOXEI8V (V1), V2, V3                   // ERROR "expected integer register in rs1 position"
+       VLOXEI8V (X10), X11, V0, V3             // ERROR "expected vector register in rs2 position"
+       VLOXEI8V (X10), V2, V1, V3              // ERROR "invalid vector mask register"
+       VSOXEI8V X10, V2, (X10)                 // ERROR "expected vector register in rd position"
+       VSOXEI8V V3, V2, (V1)                   // ERROR "expected integer register in rs1 position"
+       VSOXEI8V V3, X11, V0, (X10)             // ERROR "expected vector register in rs2 position"
+       VSOXEI8V V3, V2, V1, (X10)              // ERROR "invalid vector mask register"
+       VL1RV   (X10), V0, V3                   // ERROR "too many operands for instruction"
+       VL1RV   (X10), X10                      // ERROR "expected vector register in rd position"
+       VL1RV   (V1), V3                        // ERROR "expected integer register in rs1 position"
+       VS1RV   V3, V0, (X11)                   // ERROR "too many operands for instruction"
+       VS1RV   X11, (X11)                      // ERROR "expected vector register in rs1 position"
+       VS1RV   V3, (V1)                        // ERROR "expected integer register in rd position"
        RET
index c49569c943d9b10c34f570cf2b55781e4dbcba14..6df5f0a17374dcecdc1dd212727f57f9a89f1cf6 100644 (file)
@@ -650,5 +650,9 @@ var Anames = []string{
        "RDTIME",
        "SEQZ",
        "SNEZ",
+       "VL1RV",
+       "VL2RV",
+       "VL4RV",
+       "VL8RV",
        "LAST",
 }
index 143164ac411139f4d76ca4f6368e483dcc81c798..0ecf6dbae26c38450bd2f6cddf360e8b3d10e115 100644 (file)
@@ -1178,6 +1178,10 @@ const (
        ARDTIME
        ASEQZ
        ASNEZ
+       AVL1RV
+       AVL2RV
+       AVL4RV
+       AVL8RV
 
        // End marker
        ALAST
index c41d99c0c7a659680ebdc851ccd30ea0a4d25ebe..16bd1310c1ac853ee1d971007174e56229b3a5c3 100644 (file)
@@ -1339,6 +1339,27 @@ func validateIF(ctxt *obj.Link, ins *instruction) {
        wantNoneReg(ctxt, ins, "rs3", ins.rs3)
 }
 
+func validateIV(ctxt *obj.Link, ins *instruction) {
+       wantVectorReg(ctxt, ins, "rd", ins.rd)
+       wantIntReg(ctxt, ins, "rs1", ins.rs1)
+       wantNoneReg(ctxt, ins, "rs2", ins.rs2)
+       wantNoneReg(ctxt, ins, "rs3", ins.rs3)
+}
+
+func validateIIIV(ctxt *obj.Link, ins *instruction) {
+       wantVectorReg(ctxt, ins, "rd", ins.rd)
+       wantIntReg(ctxt, ins, "rs1", ins.rs1)
+       wantIntReg(ctxt, ins, "rs2", ins.rs2)
+       wantNoneReg(ctxt, ins, "rs3", ins.rs3)
+}
+
+func validateIVIV(ctxt *obj.Link, ins *instruction) {
+       wantVectorReg(ctxt, ins, "rd", ins.rd)
+       wantIntReg(ctxt, ins, "rs1", ins.rs1)
+       wantVectorReg(ctxt, ins, "rs2", ins.rs2)
+       wantNoneReg(ctxt, ins, "rs3", ins.rs3)
+}
+
 func validateSI(ctxt *obj.Link, ins *instruction) {
        wantImmI(ctxt, ins, ins.imm, 12)
        wantIntReg(ctxt, ins, "rd", ins.rd)
@@ -1355,6 +1376,27 @@ func validateSF(ctxt *obj.Link, ins *instruction) {
        wantNoneReg(ctxt, ins, "rs3", ins.rs3)
 }
 
+func validateSV(ctxt *obj.Link, ins *instruction) {
+       wantIntReg(ctxt, ins, "rd", ins.rd)
+       wantVectorReg(ctxt, ins, "rs1", ins.rs1)
+       wantNoneReg(ctxt, ins, "rs2", ins.rs2)
+       wantNoneReg(ctxt, ins, "rs3", ins.rs3)
+}
+
+func validateSVII(ctxt *obj.Link, ins *instruction) {
+       wantVectorReg(ctxt, ins, "rd", ins.rd)
+       wantIntReg(ctxt, ins, "rs1", ins.rs1)
+       wantIntReg(ctxt, ins, "rs2", ins.rs2)
+       wantNoneReg(ctxt, ins, "rs3", ins.rs3)
+}
+
+func validateSVIV(ctxt *obj.Link, ins *instruction) {
+       wantVectorReg(ctxt, ins, "rd", ins.rd)
+       wantIntReg(ctxt, ins, "rs1", ins.rs1)
+       wantVectorReg(ctxt, ins, "rs2", ins.rs2)
+       wantNoneReg(ctxt, ins, "rs3", ins.rs3)
+}
+
 func validateB(ctxt *obj.Link, ins *instruction) {
        // Offsets are multiples of two, so accept 13 bit immediates for the
        // 12 bit slot. We implicitly drop the least significant bit in encodeB.
@@ -1431,7 +1473,10 @@ func encodeR(as obj.As, rs1, rs2, rd, funct3, funct7 uint32) uint32 {
        if enc.rs2 != 0 && rs2 != 0 {
                panic("encodeR: instruction uses rs2, but rs2 was nonzero")
        }
-       return funct7<<25 | enc.funct7<<25 | enc.rs2<<20 | rs2<<20 | rs1<<15 | enc.funct3<<12 | funct3<<12 | rd<<7 | enc.opcode
+       funct3 |= enc.funct3
+       funct7 |= enc.funct7
+       rs2 |= enc.rs2
+       return funct7<<25 | rs2<<20 | rs1<<15 | funct3<<12 | rd<<7 | enc.opcode
 }
 
 // encodeR4 encodes an R4-type RISC-V instruction.
@@ -1483,38 +1528,67 @@ func encodeRFF(ins *instruction) uint32 {
 }
 
 // encodeI encodes an I-type RISC-V instruction.
-func encodeI(as obj.As, rs1, rd, imm uint32) uint32 {
+func encodeI(as obj.As, rs1, rd, imm, funct7 uint32) uint32 {
        enc := encode(as)
        if enc == nil {
                panic("encodeI: could not encode instruction")
        }
        imm |= uint32(enc.csr)
-       return imm<<20 | rs1<<15 | enc.funct3<<12 | rd<<7 | enc.opcode
+       return funct7<<25 | imm<<20 | rs1<<15 | enc.funct3<<12 | rd<<7 | enc.opcode
 }
 
 func encodeIII(ins *instruction) uint32 {
-       return encodeI(ins.as, regI(ins.rs1), regI(ins.rd), uint32(ins.imm))
+       return encodeI(ins.as, regI(ins.rs1), regI(ins.rd), uint32(ins.imm), 0)
 }
 
 func encodeIF(ins *instruction) uint32 {
-       return encodeI(ins.as, regI(ins.rs1), regF(ins.rd), uint32(ins.imm))
+       return encodeI(ins.as, regI(ins.rs1), regF(ins.rd), uint32(ins.imm), 0)
+}
+
+func encodeIV(ins *instruction) uint32 {
+       return encodeI(ins.as, regI(ins.rs1), regV(ins.rd), uint32(ins.imm), ins.funct7)
+}
+
+func encodeIIIV(ins *instruction) uint32 {
+       return encodeI(ins.as, regI(ins.rs1), regV(ins.rd), regI(ins.rs2), ins.funct7)
+}
+
+func encodeIVIV(ins *instruction) uint32 {
+       return encodeI(ins.as, regI(ins.rs1), regV(ins.rd), regV(ins.rs2), ins.funct7)
 }
 
 // encodeS encodes an S-type RISC-V instruction.
-func encodeS(as obj.As, rs1, rs2, imm uint32) uint32 {
+func encodeS(as obj.As, rs1, rs2, imm, funct7 uint32) uint32 {
        enc := encode(as)
        if enc == nil {
                panic("encodeS: could not encode instruction")
        }
-       return (imm>>5)<<25 | rs2<<20 | rs1<<15 | enc.funct3<<12 | (imm&0x1f)<<7 | enc.opcode
+       if enc.rs2 != 0 && rs2 != 0 {
+               panic("encodeS: instruction uses rs2, but rs2 was nonzero")
+       }
+       rs2 |= enc.rs2
+       imm |= uint32(enc.csr) &^ 0x1f
+       return funct7<<25 | (imm>>5)<<25 | rs2<<20 | rs1<<15 | enc.funct3<<12 | (imm&0x1f)<<7 | enc.opcode
 }
 
 func encodeSI(ins *instruction) uint32 {
-       return encodeS(ins.as, regI(ins.rd), regI(ins.rs1), uint32(ins.imm))
+       return encodeS(ins.as, regI(ins.rd), regI(ins.rs1), uint32(ins.imm), 0)
 }
 
 func encodeSF(ins *instruction) uint32 {
-       return encodeS(ins.as, regI(ins.rd), regF(ins.rs1), uint32(ins.imm))
+       return encodeS(ins.as, regI(ins.rd), regF(ins.rs1), uint32(ins.imm), 0)
+}
+
+func encodeSV(ins *instruction) uint32 {
+       return encodeS(ins.as, regI(ins.rd), 0, regV(ins.rs1), ins.funct7)
+}
+
+func encodeSVII(ins *instruction) uint32 {
+       return encodeS(ins.as, regI(ins.rs1), regI(ins.rs2), regV(ins.rd), ins.funct7)
+}
+
+func encodeSVIV(ins *instruction) uint32 {
+       return encodeS(ins.as, regI(ins.rs1), regV(ins.rs2), regV(ins.rd), ins.funct7)
 }
 
 // encodeBImmediate encodes an immediate for a B-type RISC-V instruction.
@@ -1721,7 +1795,7 @@ var (
        //
        //  1. the instruction encoding (R/I/S/B/U/J), in lowercase
        //  2. zero or more register operand identifiers (I = integer
-       //     register, F = float register), in uppercase
+       //     register, F = float register, V = vector register), in uppercase
        //  3. the word "Encoding"
        //
        // For example, rIIIEncoding indicates an R-type instruction with two
@@ -1737,11 +1811,17 @@ var (
        rIFEncoding   = encoding{encode: encodeRIF, validate: validateRIF, length: 4}
        rFFEncoding   = encoding{encode: encodeRFF, validate: validateRFF, length: 4}
 
-       iIIEncoding = encoding{encode: encodeIII, validate: validateIII, length: 4}
-       iFEncoding  = encoding{encode: encodeIF, validate: validateIF, length: 4}
+       iIIEncoding  = encoding{encode: encodeIII, validate: validateIII, length: 4}
+       iFEncoding   = encoding{encode: encodeIF, validate: validateIF, length: 4}
+       iVEncoding   = encoding{encode: encodeIV, validate: validateIV, length: 4}
+       iIIVEncoding = encoding{encode: encodeIIIV, validate: validateIIIV, length: 4}
+       iVIVEncoding = encoding{encode: encodeIVIV, validate: validateIVIV, length: 4}
 
-       sIEncoding = encoding{encode: encodeSI, validate: validateSI, length: 4}
-       sFEncoding = encoding{encode: encodeSF, validate: validateSF, length: 4}
+       sIEncoding   = encoding{encode: encodeSI, validate: validateSI, length: 4}
+       sFEncoding   = encoding{encode: encodeSF, validate: validateSF, length: 4}
+       sVEncoding   = encoding{encode: encodeSV, validate: validateSV, length: 4}
+       sVIIEncoding = encoding{encode: encodeSVII, validate: validateSVII, length: 4}
+       sVIVEncoding = encoding{encode: encodeSVIV, validate: validateSVIV, length: 4}
 
        bEncoding = encoding{encode: encodeB, validate: validateB, length: 4}
        uEncoding = encoding{encode: encodeU, validate: validateU, length: 4}
@@ -2022,11 +2102,73 @@ var instructions = [ALAST & obj.AMask]instructionData{
        // "V" Standard Extension for Vector Operations, Version 1.0
        //
 
-       // 31.6. Vector Configuration-Setting Instructions
+       // 31.6: Vector Configuration-Setting Instructions
        AVSETVLI & obj.AMask:  {enc: vsetvliEncoding, immForm: AVSETIVLI},
        AVSETIVLI & obj.AMask: {enc: vsetivliEncoding},
        AVSETVL & obj.AMask:   {enc: vsetvlEncoding},
 
+       // 31.7.4: Vector Unit-Stride Instructions
+       AVLE8V & obj.AMask:  {enc: iVEncoding},
+       AVLE16V & obj.AMask: {enc: iVEncoding},
+       AVLE32V & obj.AMask: {enc: iVEncoding},
+       AVLE64V & obj.AMask: {enc: iVEncoding},
+       AVSE8V & obj.AMask:  {enc: sVEncoding},
+       AVSE16V & obj.AMask: {enc: sVEncoding},
+       AVSE32V & obj.AMask: {enc: sVEncoding},
+       AVSE64V & obj.AMask: {enc: sVEncoding},
+       AVLMV & obj.AMask:   {enc: iVEncoding},
+       AVSMV & obj.AMask:   {enc: sVEncoding},
+
+       // 31.7.5: Vector Strided Instructions
+       AVLSE8V & obj.AMask:  {enc: iIIVEncoding},
+       AVLSE16V & obj.AMask: {enc: iIIVEncoding},
+       AVLSE32V & obj.AMask: {enc: iIIVEncoding},
+       AVLSE64V & obj.AMask: {enc: iIIVEncoding},
+       AVSSE8V & obj.AMask:  {enc: sVIIEncoding},
+       AVSSE16V & obj.AMask: {enc: sVIIEncoding},
+       AVSSE32V & obj.AMask: {enc: sVIIEncoding},
+       AVSSE64V & obj.AMask: {enc: sVIIEncoding},
+
+       // 31.7.6: Vector Indexed Instructions
+       AVLUXEI8V & obj.AMask:  {enc: iVIVEncoding},
+       AVLUXEI16V & obj.AMask: {enc: iVIVEncoding},
+       AVLUXEI32V & obj.AMask: {enc: iVIVEncoding},
+       AVLUXEI64V & obj.AMask: {enc: iVIVEncoding},
+       AVLOXEI8V & obj.AMask:  {enc: iVIVEncoding},
+       AVLOXEI16V & obj.AMask: {enc: iVIVEncoding},
+       AVLOXEI32V & obj.AMask: {enc: iVIVEncoding},
+       AVLOXEI64V & obj.AMask: {enc: iVIVEncoding},
+       AVSUXEI8V & obj.AMask:  {enc: sVIVEncoding},
+       AVSUXEI16V & obj.AMask: {enc: sVIVEncoding},
+       AVSUXEI32V & obj.AMask: {enc: sVIVEncoding},
+       AVSUXEI64V & obj.AMask: {enc: sVIVEncoding},
+       AVSOXEI8V & obj.AMask:  {enc: sVIVEncoding},
+       AVSOXEI16V & obj.AMask: {enc: sVIVEncoding},
+       AVSOXEI32V & obj.AMask: {enc: sVIVEncoding},
+       AVSOXEI64V & obj.AMask: {enc: sVIVEncoding},
+
+       // 31.7.9. Vector Load/Store Whole Register Instructions
+       AVL1RE8V & obj.AMask:  {enc: iVEncoding},
+       AVL1RE16V & obj.AMask: {enc: iVEncoding},
+       AVL1RE32V & obj.AMask: {enc: iVEncoding},
+       AVL1RE64V & obj.AMask: {enc: iVEncoding},
+       AVL2RE8V & obj.AMask:  {enc: iVEncoding},
+       AVL2RE16V & obj.AMask: {enc: iVEncoding},
+       AVL2RE32V & obj.AMask: {enc: iVEncoding},
+       AVL2RE64V & obj.AMask: {enc: iVEncoding},
+       AVL4RE8V & obj.AMask:  {enc: iVEncoding},
+       AVL4RE16V & obj.AMask: {enc: iVEncoding},
+       AVL4RE32V & obj.AMask: {enc: iVEncoding},
+       AVL4RE64V & obj.AMask: {enc: iVEncoding},
+       AVL8RE8V & obj.AMask:  {enc: iVEncoding},
+       AVL8RE16V & obj.AMask: {enc: iVEncoding},
+       AVL8RE32V & obj.AMask: {enc: iVEncoding},
+       AVL8RE64V & obj.AMask: {enc: iVEncoding},
+       AVS1RV & obj.AMask:    {enc: sVEncoding},
+       AVS2RV & obj.AMask:    {enc: sVEncoding},
+       AVS4RV & obj.AMask:    {enc: sVEncoding},
+       AVS8RV & obj.AMask:    {enc: sVEncoding},
+
        //
        // Privileged ISA
        //
@@ -2849,6 +2991,60 @@ func instructionsForProg(p *obj.Prog) []*instruction {
                        ins.rs1 = uint32(p.From.Offset)
                }
 
+       case AVLE8V, AVLE16V, AVLE32V, AVLE64V, AVSE8V, AVSE16V, AVSE32V, AVSE64V, AVLMV, AVSMV:
+               // Set mask bit
+               switch {
+               case ins.rs1 == obj.REG_NONE:
+                       ins.funct7 |= 1 // unmasked
+               case ins.rs1 != REG_V0:
+                       p.Ctxt.Diag("%v: invalid vector mask register", p)
+               }
+               ins.rd, ins.rs1, ins.rs2 = uint32(p.To.Reg), uint32(p.From.Reg), obj.REG_NONE
+
+       case AVLSE8V, AVLSE16V, AVLSE32V, AVLSE64V,
+               AVLUXEI8V, AVLUXEI16V, AVLUXEI32V, AVLUXEI64V, AVLOXEI8V, AVLOXEI16V, AVLOXEI32V, AVLOXEI64V:
+               // Set mask bit
+               switch {
+               case ins.rs3 == obj.REG_NONE:
+                       ins.funct7 |= 1 // unmasked
+               case ins.rs3 != REG_V0:
+                       p.Ctxt.Diag("%v: invalid vector mask register", p)
+               }
+               ins.rs1, ins.rs2, ins.rs3 = ins.rs2, ins.rs1, obj.REG_NONE
+
+       case AVSSE8V, AVSSE16V, AVSSE32V, AVSSE64V,
+               AVSUXEI8V, AVSUXEI16V, AVSUXEI32V, AVSUXEI64V, AVSOXEI8V, AVSOXEI16V, AVSOXEI32V, AVSOXEI64V:
+               // Set mask bit
+               switch {
+               case ins.rs3 == obj.REG_NONE:
+                       ins.funct7 |= 1 // unmasked
+               case ins.rs3 != REG_V0:
+                       p.Ctxt.Diag("%v: invalid vector mask register", p)
+               }
+               ins.rd, ins.rs1, ins.rs2, ins.rs3 = ins.rs2, ins.rd, ins.rs1, obj.REG_NONE
+
+       case AVL1RV, AVL1RE8V, AVL1RE16V, AVL1RE32V, AVL1RE64V, AVL2RV, AVL2RE8V, AVL2RE16V, AVL2RE32V, AVL2RE64V,
+               AVL4RV, AVL4RE8V, AVL4RE16V, AVL4RE32V, AVL4RE64V, AVL8RV, AVL8RE8V, AVL8RE16V, AVL8RE32V, AVL8RE64V:
+               switch ins.as {
+               case AVL1RV:
+                       ins.as = AVL1RE8V
+               case AVL2RV:
+                       ins.as = AVL2RE8V
+               case AVL4RV:
+                       ins.as = AVL4RE8V
+               case AVL8RV:
+                       ins.as = AVL8RE8V
+               }
+               if ins.rs1 != obj.REG_NONE {
+                       p.Ctxt.Diag("%v: too many operands for instruction", p)
+               }
+               ins.rd, ins.rs1, ins.rs2 = uint32(p.To.Reg), uint32(p.From.Reg), obj.REG_NONE
+
+       case AVS1RV, AVS2RV, AVS4RV, AVS8RV:
+               if ins.rs1 != obj.REG_NONE {
+                       p.Ctxt.Diag("%v: too many operands for instruction", p)
+               }
+               ins.rd, ins.rs1, ins.rs2 = uint32(p.To.Reg), uint32(p.From.Reg), obj.REG_NONE
        }
 
        for _, ins := range inss {