cubefs

Форк
0
394 строки · 10.5 Кб
1
//+build !noasm
2
//+build !appengine
3
//+build !gccgo
4

5
// Copyright 2015, Klaus Post, see LICENSE for details.
6

7
// Based on http://www.snia.org/sites/default/files2/SDC2013/presentations/NewThinking/EthanMiller_Screaming_Fast_Galois_Field%20Arithmetic_SIMD%20Instructions.pdf
8
// and http://jerasure.org/jerasure/gf-complete/tree/master
9

10
// func galMulSSSE3Xor(low, high, in, out []byte)
11
TEXT ·galMulSSSE3Xor(SB), 7, $0
12
	MOVQ   low+0(FP), SI     // SI: &low
13
	MOVQ   high+24(FP), DX   // DX: &high
14
	MOVOU  (SI), X6          // X6 low
15
	MOVOU  (DX), X7          // X7: high
16
	MOVQ   $15, BX           // BX: low mask
17
	MOVQ   BX, X8
18
	PXOR   X5, X5
19
	MOVQ   in+48(FP), SI     // R11: &in
20
	MOVQ   in_len+56(FP), R9 // R9: len(in)
21
	MOVQ   out+72(FP), DX    // DX: &out
22
	PSHUFB X5, X8            // X8: lomask (unpacked)
23
	SHRQ   $4, R9            // len(in) / 16
24
	MOVQ   SI, AX
25
	MOVQ   DX, BX
26
	ANDQ   $15, AX
27
	ANDQ   $15, BX
28
	CMPQ   R9, $0
29
	JEQ    done_xor
30
	ORQ    AX, BX
31
	CMPQ   BX, $0
32
	JNZ    loopback_xor
33

34
loopback_xor_aligned:
35
	MOVOA  (SI), X0             // in[x]
36
	MOVOA  (DX), X4             // out[x]
37
	MOVOA  X0, X1               // in[x]
38
	MOVOA  X6, X2               // low copy
39
	MOVOA  X7, X3               // high copy
40
	PSRLQ  $4, X1               // X1: high input
41
	PAND   X8, X0               // X0: low input
42
	PAND   X8, X1               // X0: high input
43
	PSHUFB X0, X2               // X2: mul low part
44
	PSHUFB X1, X3               // X3: mul high part
45
	PXOR   X2, X3               // X3: Result
46
	PXOR   X4, X3               // X3: Result xor existing out
47
	MOVOA  X3, (DX)             // Store
48
	ADDQ   $16, SI              // in+=16
49
	ADDQ   $16, DX              // out+=16
50
	SUBQ   $1, R9
51
	JNZ    loopback_xor_aligned
52
	JMP    done_xor
53

54
loopback_xor:
55
	MOVOU  (SI), X0     // in[x]
56
	MOVOU  (DX), X4     // out[x]
57
	MOVOU  X0, X1       // in[x]
58
	MOVOU  X6, X2       // low copy
59
	MOVOU  X7, X3       // high copy
60
	PSRLQ  $4, X1       // X1: high input
61
	PAND   X8, X0       // X0: low input
62
	PAND   X8, X1       // X0: high input
63
	PSHUFB X0, X2       // X2: mul low part
64
	PSHUFB X1, X3       // X3: mul high part
65
	PXOR   X2, X3       // X3: Result
66
	PXOR   X4, X3       // X3: Result xor existing out
67
	MOVOU  X3, (DX)     // Store
68
	ADDQ   $16, SI      // in+=16
69
	ADDQ   $16, DX      // out+=16
70
	SUBQ   $1, R9
71
	JNZ    loopback_xor
72

73
done_xor:
74
	RET
75

76
// func galMulSSSE3(low, high, in, out []byte)
77
TEXT ·galMulSSSE3(SB), 7, $0
78
	MOVQ   low+0(FP), SI     // SI: &low
79
	MOVQ   high+24(FP), DX   // DX: &high
80
	MOVOU  (SI), X6          // X6 low
81
	MOVOU  (DX), X7          // X7: high
82
	MOVQ   $15, BX           // BX: low mask
83
	MOVQ   BX, X8
84
	PXOR   X5, X5
85
	MOVQ   in+48(FP), SI     // R11: &in
86
	MOVQ   in_len+56(FP), R9 // R9: len(in)
87
	MOVQ   out+72(FP), DX    // DX: &out
88
	PSHUFB X5, X8            // X8: lomask (unpacked)
89
	MOVQ   SI, AX
90
	MOVQ   DX, BX
91
	SHRQ   $4, R9            // len(in) / 16
92
	ANDQ   $15, AX
93
	ANDQ   $15, BX
94
	CMPQ   R9, $0
95
	JEQ    done
96
	ORQ    AX, BX
97
	CMPQ   BX, $0
98
	JNZ    loopback
99

100
loopback_aligned:
101
	MOVOA  (SI), X0         // in[x]
102
	MOVOA  X0, X1           // in[x]
103
	MOVOA  X6, X2           // low copy
104
	MOVOA  X7, X3           // high copy
105
	PSRLQ  $4, X1           // X1: high input
106
	PAND   X8, X0           // X0: low input
107
	PAND   X8, X1           // X0: high input
108
	PSHUFB X0, X2           // X2: mul low part
109
	PSHUFB X1, X3           // X3: mul high part
110
	PXOR   X2, X3           // X3: Result
111
	MOVOA  X3, (DX)         // Store
112
	ADDQ   $16, SI          // in+=16
113
	ADDQ   $16, DX          // out+=16
114
	SUBQ   $1, R9
115
	JNZ    loopback_aligned
116
	JMP    done
117

118
loopback:
119
	MOVOU  (SI), X0 // in[x]
120
	MOVOU  X0, X1   // in[x]
121
	MOVOA  X6, X2   // low copy
122
	MOVOA  X7, X3   // high copy
123
	PSRLQ  $4, X1   // X1: high input
124
	PAND   X8, X0   // X0: low input
125
	PAND   X8, X1   // X0: high input
126
	PSHUFB X0, X2   // X2: mul low part
127
	PSHUFB X1, X3   // X3: mul high part
128
	PXOR   X2, X3   // X3: Result
129
	MOVOU  X3, (DX) // Store
130
	ADDQ   $16, SI  // in+=16
131
	ADDQ   $16, DX  // out+=16
132
	SUBQ   $1, R9
133
	JNZ    loopback
134

135
done:
136
	RET
137

138
// func galMulAVX2Xor(low, high, in, out []byte)
139
TEXT ·galMulAVX2Xor(SB), 7, $0
140
	MOVQ  low+0(FP), SI     // SI: &low
141
	MOVQ  high+24(FP), DX   // DX: &high
142
	MOVQ  $15, BX           // BX: low mask
143
	MOVQ  BX, X5
144
	MOVOU (SI), X6          // X6: low
145
	MOVOU (DX), X7          // X7: high
146
	MOVQ  in_len+56(FP), R9 // R9: len(in)
147

148
	VINSERTI128  $1, X6, Y6, Y6 // low
149
	VINSERTI128  $1, X7, Y7, Y7 // high
150
	VPBROADCASTB X5, Y8         // Y8: lomask (unpacked)
151

152
	SHRQ  $5, R9         // len(in) / 32
153
	MOVQ  out+72(FP), DX // DX: &out
154
	MOVQ  in+48(FP), SI  // SI: &in
155
	TESTQ R9, R9
156
	JZ    done_xor_avx2
157

158
loopback_xor_avx2:
159
	VMOVDQU (SI), Y0
160
	VMOVDQU (DX), Y4
161
	VPSRLQ  $4, Y0, Y1 // Y1: high input
162
	VPAND   Y8, Y0, Y0 // Y0: low input
163
	VPAND   Y8, Y1, Y1 // Y1: high input
164
	VPSHUFB Y0, Y6, Y2 // Y2: mul low part
165
	VPSHUFB Y1, Y7, Y3 // Y3: mul high part
166
	VPXOR   Y3, Y2, Y3 // Y3: Result
167
	VPXOR   Y4, Y3, Y4 // Y4: Result
168
	VMOVDQU Y4, (DX)
169

170
	ADDQ $32, SI           // in+=32
171
	ADDQ $32, DX           // out+=32
172
	SUBQ $1, R9
173
	JNZ  loopback_xor_avx2
174

175
done_xor_avx2:
176
	VZEROUPPER
177
	RET
178

179
// func galMulAVX2(low, high, in, out []byte)
180
TEXT ·galMulAVX2(SB), 7, $0
181
	MOVQ  low+0(FP), SI     // SI: &low
182
	MOVQ  high+24(FP), DX   // DX: &high
183
	MOVQ  $15, BX           // BX: low mask
184
	MOVQ  BX, X5
185
	MOVOU (SI), X6          // X6: low
186
	MOVOU (DX), X7          // X7: high
187
	MOVQ  in_len+56(FP), R9 // R9: len(in)
188

189
	VINSERTI128  $1, X6, Y6, Y6 // low
190
	VINSERTI128  $1, X7, Y7, Y7 // high
191
	VPBROADCASTB X5, Y8         // Y8: lomask (unpacked)
192

193
	SHRQ  $5, R9         // len(in) / 32
194
	MOVQ  out+72(FP), DX // DX: &out
195
	MOVQ  in+48(FP), SI  // SI: &in
196
	TESTQ R9, R9
197
	JZ    done_avx2
198

199
loopback_avx2:
200
	VMOVDQU (SI), Y0
201
	VPSRLQ  $4, Y0, Y1 // Y1: high input
202
	VPAND   Y8, Y0, Y0 // Y0: low input
203
	VPAND   Y8, Y1, Y1 // Y1: high input
204
	VPSHUFB Y0, Y6, Y2 // Y2: mul low part
205
	VPSHUFB Y1, Y7, Y3 // Y3: mul high part
206
	VPXOR   Y3, Y2, Y4 // Y4: Result
207
	VMOVDQU Y4, (DX)
208

209
	ADDQ $32, SI       // in+=32
210
	ADDQ $32, DX       // out+=32
211
	SUBQ $1, R9
212
	JNZ  loopback_avx2
213

214
done_avx2:
215
	VZEROUPPER
216
	RET
217

218
// func sSE2XorSlice(in, out []byte)
219
TEXT ·sSE2XorSlice(SB), 7, $0
220
	MOVQ in+0(FP), SI     // SI: &in
221
	MOVQ in_len+8(FP), R9 // R9: len(in)
222
	MOVQ out+24(FP), DX   // DX: &out
223
	SHRQ $4, R9           // len(in) / 16
224
	CMPQ R9, $0
225
	JEQ  done_xor_sse2
226

227
loopback_xor_sse2:
228
	MOVOU (SI), X0          // in[x]
229
	MOVOU (DX), X1          // out[x]
230
	PXOR  X0, X1
231
	MOVOU X1, (DX)
232
	ADDQ  $16, SI           // in+=16
233
	ADDQ  $16, DX           // out+=16
234
	SUBQ  $1, R9
235
	JNZ   loopback_xor_sse2
236

237
done_xor_sse2:
238
	RET
239

240
// func galMulAVX2Xor_64(low, high, in, out []byte)
241
TEXT ·galMulAVX2Xor_64(SB), 7, $0
242
	MOVQ low+0(FP), SI     // SI: &low
243
	MOVQ high+24(FP), DX   // DX: &high
244
	MOVQ $15, BX           // BX: low mask
245
	MOVQ BX, X5
246
	MOVQ in_len+56(FP), R9 // R9: len(in)
247

248
	VBROADCASTI128 (SI), Y6 // low table
249
	VBROADCASTI128 (DX), Y7 // high high table
250
	VPBROADCASTB   X5, Y8   // Y8: lomask (unpacked)
251

252
	SHRQ  $6, R9           // len(in) / 64
253
	MOVQ  out+72(FP), DX   // DX: &out
254
	MOVQ  in+48(FP), SI    // SI: &in
255
	TESTQ R9, R9
256
	JZ    done_xor_avx2_64
257

258
loopback_xor_avx2_64:
259
	VMOVDQU (SI), Y0
260
	VMOVDQU 32(SI), Y10
261
	VMOVDQU (DX), Y4
262
	VMOVDQU 32(DX), Y14
263
	VPSRLQ  $4, Y0, Y1    // Y1: high input
264
	VPSRLQ  $4, Y10, Y11  // Y11: high input 2
265
	VPAND   Y8, Y0, Y0    // Y0: low input
266
	VPAND   Y8, Y10, Y10  // Y10: low input 2
267
	VPAND   Y8, Y1, Y1    // Y11: high input
268
	VPAND   Y8, Y11, Y11  // Y11: high input 2
269
	VPSHUFB Y0, Y6, Y2    // Y2: mul low part
270
	VPSHUFB Y10, Y6, Y12  // Y12: mul low part 2
271
	VPSHUFB Y1, Y7, Y3    // Y3: mul high part
272
	VPSHUFB Y11, Y7, Y13  // Y13: mul high part 2
273
	VPXOR   Y3, Y2, Y3    // Y3: Result
274
	VPXOR   Y13, Y12, Y13 // Y13: Result 2
275
	VPXOR   Y4, Y3, Y4    // Y4: Result
276
	VPXOR   Y14, Y13, Y14 // Y4: Result 2
277
	VMOVDQU Y4, (DX)
278
	VMOVDQU Y14, 32(DX)
279

280
	ADDQ $64, SI              // in+=64
281
	ADDQ $64, DX              // out+=64
282
	SUBQ $1, R9
283
	JNZ  loopback_xor_avx2_64
284

285
done_xor_avx2_64:
286
	VZEROUPPER
287
	RET
288

289
// func galMulAVX2_64(low, high, in, out []byte)
290
TEXT ·galMulAVX2_64(SB), 7, $0
291
	MOVQ           low+0(FP), SI     // SI: &low
292
	MOVQ           high+24(FP), DX   // DX: &high
293
	MOVQ           $15, BX           // BX: low mask
294
	MOVQ           BX, X5
295
	MOVQ           in_len+56(FP), R9 // R9: len(in)
296
	VBROADCASTI128 (SI), Y6          // low table
297
	VBROADCASTI128 (DX), Y7          // high high table
298
	VPBROADCASTB   X5, Y8            // Y8: lomask (unpacked)
299

300
	SHRQ  $6, R9         // len(in) / 64
301
	MOVQ  out+72(FP), DX // DX: &out
302
	MOVQ  in+48(FP), SI  // SI: &in
303
	TESTQ R9, R9
304
	JZ    done_avx2_64
305

306
loopback_avx2_64:
307
	VMOVDQU (SI), Y0
308
	VMOVDQU 32(SI), Y10
309
	VPSRLQ  $4, Y0, Y1    // Y1: high input
310
	VPSRLQ  $4, Y10, Y11  // Y11: high input 2
311
	VPAND   Y8, Y0, Y0    // Y0: low input
312
	VPAND   Y8, Y10, Y10  // Y10: low input
313
	VPAND   Y8, Y1, Y1    // Y1: high input
314
	VPAND   Y8, Y11, Y11  // Y11: high input 2
315
	VPSHUFB Y0, Y6, Y2    // Y2: mul low part
316
	VPSHUFB Y10, Y6, Y12  // Y12: mul low part 2
317
	VPSHUFB Y1, Y7, Y3    // Y3: mul high part
318
	VPSHUFB Y11, Y7, Y13  // Y13: mul high part 2
319
	VPXOR   Y3, Y2, Y4    // Y4: Result
320
	VPXOR   Y13, Y12, Y14 // Y14: Result 2
321
	VMOVDQU Y4, (DX)
322
	VMOVDQU Y14, 32(DX)
323

324
	ADDQ $64, SI          // in+=64
325
	ADDQ $64, DX          // out+=64
326
	SUBQ $1, R9
327
	JNZ  loopback_avx2_64
328

329
done_avx2_64:
330
	VZEROUPPER
331
	RET
332

333
// func sSE2XorSlice_64(in, out []byte)
334
TEXT ·sSE2XorSlice_64(SB), 7, $0
335
	MOVQ in+0(FP), SI     // SI: &in
336
	MOVQ in_len+8(FP), R9 // R9: len(in)
337
	MOVQ out+24(FP), DX   // DX: &out
338
	SHRQ $6, R9           // len(in) / 64
339
	CMPQ R9, $0
340
	JEQ  done_xor_sse2_64
341

342
loopback_xor_sse2_64:
343
	MOVOU (SI), X0             // in[x]
344
	MOVOU 16(SI), X2           // in[x]
345
	MOVOU 32(SI), X4           // in[x]
346
	MOVOU 48(SI), X6           // in[x]
347
	MOVOU (DX), X1             // out[x]
348
	MOVOU 16(DX), X3           // out[x]
349
	MOVOU 32(DX), X5           // out[x]
350
	MOVOU 48(DX), X7           // out[x]
351
	PXOR  X0, X1
352
	PXOR  X2, X3
353
	PXOR  X4, X5
354
	PXOR  X6, X7
355
	MOVOU X1, (DX)
356
	MOVOU X3, 16(DX)
357
	MOVOU X5, 32(DX)
358
	MOVOU X7, 48(DX)
359
	ADDQ  $64, SI              // in+=64
360
	ADDQ  $64, DX              // out+=64
361
	SUBQ  $1, R9
362
	JNZ   loopback_xor_sse2_64
363

364
done_xor_sse2_64:
365
	RET
366

367
// func avx2XorSlice_64(in, out []byte)
368
TEXT ·avx2XorSlice_64(SB), 7, $0
369
	MOVQ in+0(FP), SI     // SI: &in
370
	MOVQ in_len+8(FP), R9 // R9: len(in)
371
	MOVQ out+24(FP), DX   // DX: &out
372
	SHRQ $6, R9           // len(in) / 64
373
	CMPQ R9, $0
374
	JEQ  done_xor_avx2_64
375

376
loopback_xor_avx2_64:
377
	VMOVDQU (SI), Y0
378
	VMOVDQU 32(SI), Y2
379
	VMOVDQU (DX), Y1
380
	VMOVDQU 32(DX), Y3
381
	VPXOR   Y0, Y1, Y1
382
	VPXOR   Y2, Y3, Y3
383
	VMOVDQU Y1, (DX)
384
	VMOVDQU Y3, 32(DX)
385

386
	ADDQ $64, SI              // in+=64
387
	ADDQ $64, DX              // out+=64
388
	SUBQ $1, R9
389
	JNZ  loopback_xor_avx2_64
390
	VZEROUPPER
391

392
done_xor_avx2_64:
393

394
	RET
395

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.