1 // Copyright 2026 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 #include "asm_riscv64.h"
6 #include "textflag.h"
7
8 // Packs the non-nil values of bufp[0:n] at the front of bufp, returning the
9 // packed length.
10 //
11 // func filterNilRVV(bufp *uintptr, n int32) int32
12 TEXT ·filterNilRVV(SB), NOSPLIT, $0-20
13 MOV bufp+0(FP), X10 // X10 = read ptr
14 MOVW n+8(FP), X11 // X11 = remaining
15 MOV $0, X13 // X13 = counter (init before n==0 skip)
16 BLEZ X11, done // in case n < 0
17 MOV X10, X12 // X12 = write ptr
18 loop:
19 VSETVLI X11, E64, M2, TA, MA, X14 // X14 = vl = min(remaining, VLMAX)
20 VLE64V (X10), V16
21 VMSNEVX X0, V16, V0 // mask = words != 0
22 VCPOPM V0, X15 // X15 = count of non-nil (mask view, over vl)
23 BEQZ X15, skip // all-nil chunk: no write, no out advance
24 VCOMPRESSVM V0, V16, V24
25 VSE64V V24, (X12) // write at out ptr
26 ADD X15, X13 // counter += popcount
27 #ifdef hasZba
28 SH3ADD X12, X15, X12 // write ptr += 8*popcount
29 #else
30 SLLI $3, X15 // 8*popcount
31 ADD X15, X12, X12 // write ptr += 8*popcount
32 #endif
33 skip:
34 #ifdef hasZba
35 SH3ADD X10, X14, X10 // read ptr += 8*vl
36 #else
37 SLLI $3, X14, X15 // X15 = 8*vl
38 ADD X15, X10, X10 // read ptr += 8*vl
39 #endif
40 SUB X14, X11, X11 // remaining -= vl
41 BNEZ X11, loop
42 done:
43 MOVW X13, ret+16(FP)
44 RET
45
View as plain text