Source file
src/hash/adler32/adler32_simd_arm64.go
1
2
3
4
5
6
7 package adler32
8
9 import "simd/archsimd"
10
11 const (
12 haveSIMD = true
13
14
15
16 minSIMD = 64
17
18
19
20 blockSize = 32
21
22
23
24
25 nmaxSIMD = nmax - nmax%blockSize
26 )
27
28
29
30
31
32 var taps = [blockSize]uint16{
33 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17,
34 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,
35 }
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 func updateSIMD(d digest, p []byte) digest {
54 s1, s2 := uint32(d&0xffff), uint32(d>>16)
55
56 w0 := archsimd.LoadUint16x8(taps[0:])
57 w1 := archsimd.LoadUint16x8(taps[8:])
58 w2 := archsimd.LoadUint16x8(taps[16:])
59 w3 := archsimd.LoadUint16x8(taps[24:])
60
61 for len(p) >= blockSize {
62 n := nmaxSIMD
63 if n > len(p) {
64 n = len(p) - len(p)%blockSize
65 }
66 q := p[:n]
67 var vs1, vs2, vps archsimd.Uint32x4
68 for len(q) >= blockSize {
69 a := archsimd.LoadUint8x16(q)
70 b := archsimd.LoadUint8x16(q[16:])
71 vps = vps.Add(vs1)
72
73
74 alo := a.ExtendLo8ToUint16()
75 ahi := a.HiToLo().ExtendLo8ToUint16()
76 blo := b.ExtendLo8ToUint16()
77 bhi := b.HiToLo().ExtendLo8ToUint16()
78
79
80
81
82 t := alo.Add(ahi).Add(blo.Add(bhi))
83 t2 := t.ConcatAddPairs(t)
84 vs1 = vs1.Add(t2.ExtendLo4ToUint32())
85
86
87
88
89
90 pa := alo.Mul(w0)
91 pb := ahi.Mul(w1)
92 pc := blo.Mul(w2)
93 pd := bhi.Mul(w3)
94 r := pa.ConcatAddPairs(pb).ConcatAddPairs(pc.ConcatAddPairs(pd))
95 r2 := r.ConcatAddPairs(r)
96 vs2 = vs2.Add(r2.ExtendLo4ToUint32())
97
98 q = q[blockSize:]
99 }
100 vs2 = vs2.Add(vps.ShiftAllLeft(5))
101 s2 += uint32(n)*s1 + vs2.ReduceSum()
102 s1 += vs1.ReduceSum()
103 s1 %= mod
104 s2 %= mod
105 p = p[n:]
106 }
107 if len(p) > 0 {
108 return updateGeneric(digest(s2<<16|s1), p)
109 }
110 return digest(s2<<16 | s1)
111 }
112
View as plain text