Merge branch 'address-masking'
[linux-2.6-microblaze.git] / lib / raid6 / avx2.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* -*- linux-c -*- ------------------------------------------------------- *
3  *
4  *   Copyright (C) 2012 Intel Corporation
5  *   Author: Yuanhan Liu <yuanhan.liu@linux.intel.com>
6  *
7  *   Based on sse2.c: Copyright 2002 H. Peter Anvin - All Rights Reserved
8  *
9  * ----------------------------------------------------------------------- */
10
11 /*
12  * AVX2 implementation of RAID-6 syndrome functions
13  *
14  */
15
16 #include <linux/raid/pq.h>
17 #include "x86.h"
18
19 static const struct raid6_avx2_constants {
20         u64 x1d[4];
21 } raid6_avx2_constants __aligned(32) = {
22         { 0x1d1d1d1d1d1d1d1dULL, 0x1d1d1d1d1d1d1d1dULL,
23           0x1d1d1d1d1d1d1d1dULL, 0x1d1d1d1d1d1d1d1dULL,},
24 };
25
26 static int raid6_have_avx2(void)
27 {
28         return boot_cpu_has(X86_FEATURE_AVX2) && boot_cpu_has(X86_FEATURE_AVX);
29 }
30
31 /*
32  * Plain AVX2 implementation
33  */
34 static void raid6_avx21_gen_syndrome(int disks, size_t bytes, void **ptrs)
35 {
36         u8 **dptr = (u8 **)ptrs;
37         u8 *p, *q;
38         int d, z, z0;
39
40         z0 = disks - 3;         /* Highest data disk */
41         p = dptr[z0+1];         /* XOR parity */
42         q = dptr[z0+2];         /* RS syndrome */
43
44         kernel_fpu_begin();
45
46         asm volatile("vmovdqa %0,%%ymm0" : : "m" (raid6_avx2_constants.x1d[0]));
47         asm volatile("vpxor %ymm3,%ymm3,%ymm3");        /* Zero temp */
48
49         for (d = 0; d < bytes; d += 32) {
50                 asm volatile("prefetchnta %0" : : "m" (dptr[z0][d]));
51                 asm volatile("vmovdqa %0,%%ymm2" : : "m" (dptr[z0][d]));/* P[0] */
52                 asm volatile("prefetchnta %0" : : "m" (dptr[z0-1][d]));
53                 asm volatile("vmovdqa %ymm2,%ymm4");/* Q[0] */
54                 asm volatile("vmovdqa %0,%%ymm6" : : "m" (dptr[z0-1][d]));
55                 for (z = z0-2; z >= 0; z--) {
56                         asm volatile("prefetchnta %0" : : "m" (dptr[z][d]));
57                         asm volatile("vpcmpgtb %ymm4,%ymm3,%ymm5");
58                         asm volatile("vpaddb %ymm4,%ymm4,%ymm4");
59                         asm volatile("vpand %ymm0,%ymm5,%ymm5");
60                         asm volatile("vpxor %ymm5,%ymm4,%ymm4");
61                         asm volatile("vpxor %ymm6,%ymm2,%ymm2");
62                         asm volatile("vpxor %ymm6,%ymm4,%ymm4");
63                         asm volatile("vmovdqa %0,%%ymm6" : : "m" (dptr[z][d]));
64                 }
65                 asm volatile("vpcmpgtb %ymm4,%ymm3,%ymm5");
66                 asm volatile("vpaddb %ymm4,%ymm4,%ymm4");
67                 asm volatile("vpand %ymm0,%ymm5,%ymm5");
68                 asm volatile("vpxor %ymm5,%ymm4,%ymm4");
69                 asm volatile("vpxor %ymm6,%ymm2,%ymm2");
70                 asm volatile("vpxor %ymm6,%ymm4,%ymm4");
71
72                 asm volatile("vmovntdq %%ymm2,%0" : "=m" (p[d]));
73                 asm volatile("vpxor %ymm2,%ymm2,%ymm2");
74                 asm volatile("vmovntdq %%ymm4,%0" : "=m" (q[d]));
75                 asm volatile("vpxor %ymm4,%ymm4,%ymm4");
76         }
77
78         asm volatile("sfence" : : : "memory");
79         kernel_fpu_end();
80 }
81
82 static void raid6_avx21_xor_syndrome(int disks, int start, int stop,
83                                      size_t bytes, void **ptrs)
84 {
85         u8 **dptr = (u8 **)ptrs;
86         u8 *p, *q;
87         int d, z, z0;
88
89         z0 = stop;              /* P/Q right side optimization */
90         p = dptr[disks-2];      /* XOR parity */
91         q = dptr[disks-1];      /* RS syndrome */
92
93         kernel_fpu_begin();
94
95         asm volatile("vmovdqa %0,%%ymm0" : : "m" (raid6_avx2_constants.x1d[0]));
96
97         for (d = 0 ; d < bytes ; d += 32) {
98                 asm volatile("vmovdqa %0,%%ymm4" :: "m" (dptr[z0][d]));
99                 asm volatile("vmovdqa %0,%%ymm2" : : "m" (p[d]));
100                 asm volatile("vpxor %ymm4,%ymm2,%ymm2");
101                 /* P/Q data pages */
102                 for (z = z0-1 ; z >= start ; z--) {
103                         asm volatile("vpxor %ymm5,%ymm5,%ymm5");
104                         asm volatile("vpcmpgtb %ymm4,%ymm5,%ymm5");
105                         asm volatile("vpaddb %ymm4,%ymm4,%ymm4");
106                         asm volatile("vpand %ymm0,%ymm5,%ymm5");
107                         asm volatile("vpxor %ymm5,%ymm4,%ymm4");
108                         asm volatile("vmovdqa %0,%%ymm5" :: "m" (dptr[z][d]));
109                         asm volatile("vpxor %ymm5,%ymm2,%ymm2");
110                         asm volatile("vpxor %ymm5,%ymm4,%ymm4");
111                 }
112                 /* P/Q left side optimization */
113                 for (z = start-1 ; z >= 0 ; z--) {
114                         asm volatile("vpxor %ymm5,%ymm5,%ymm5");
115                         asm volatile("vpcmpgtb %ymm4,%ymm5,%ymm5");
116                         asm volatile("vpaddb %ymm4,%ymm4,%ymm4");
117                         asm volatile("vpand %ymm0,%ymm5,%ymm5");
118                         asm volatile("vpxor %ymm5,%ymm4,%ymm4");
119                 }
120                 asm volatile("vpxor %0,%%ymm4,%%ymm4" : : "m" (q[d]));
121                 /* Don't use movntdq for r/w memory area < cache line */
122                 asm volatile("vmovdqa %%ymm4,%0" : "=m" (q[d]));
123                 asm volatile("vmovdqa %%ymm2,%0" : "=m" (p[d]));
124         }
125
126         asm volatile("sfence" : : : "memory");
127         kernel_fpu_end();
128 }
129
130 const struct raid6_calls raid6_avx2x1 = {
131         raid6_avx21_gen_syndrome,
132         raid6_avx21_xor_syndrome,
133         raid6_have_avx2,
134         "avx2x1",
135         .priority = 2           /* Prefer AVX2 over priority 1 (SSE2 and others) */
136 };
137
138 /*
139  * Unrolled-by-2 AVX2 implementation
140  */
141 static void raid6_avx22_gen_syndrome(int disks, size_t bytes, void **ptrs)
142 {
143         u8 **dptr = (u8 **)ptrs;
144         u8 *p, *q;
145         int d, z, z0;
146
147         z0 = disks - 3;         /* Highest data disk */
148         p = dptr[z0+1];         /* XOR parity */
149         q = dptr[z0+2];         /* RS syndrome */
150
151         kernel_fpu_begin();
152
153         asm volatile("vmovdqa %0,%%ymm0" : : "m" (raid6_avx2_constants.x1d[0]));
154         asm volatile("vpxor %ymm1,%ymm1,%ymm1"); /* Zero temp */
155
156         /* We uniformly assume a single prefetch covers at least 32 bytes */
157         for (d = 0; d < bytes; d += 64) {
158                 asm volatile("prefetchnta %0" : : "m" (dptr[z0][d]));
159                 asm volatile("prefetchnta %0" : : "m" (dptr[z0][d+32]));
160                 asm volatile("vmovdqa %0,%%ymm2" : : "m" (dptr[z0][d]));/* P[0] */
161                 asm volatile("vmovdqa %0,%%ymm3" : : "m" (dptr[z0][d+32]));/* P[1] */
162                 asm volatile("vmovdqa %ymm2,%ymm4"); /* Q[0] */
163                 asm volatile("vmovdqa %ymm3,%ymm6"); /* Q[1] */
164                 for (z = z0-1; z >= 0; z--) {
165                         asm volatile("prefetchnta %0" : : "m" (dptr[z][d]));
166                         asm volatile("prefetchnta %0" : : "m" (dptr[z][d+32]));
167                         asm volatile("vpcmpgtb %ymm4,%ymm1,%ymm5");
168                         asm volatile("vpcmpgtb %ymm6,%ymm1,%ymm7");
169                         asm volatile("vpaddb %ymm4,%ymm4,%ymm4");
170                         asm volatile("vpaddb %ymm6,%ymm6,%ymm6");
171                         asm volatile("vpand %ymm0,%ymm5,%ymm5");
172                         asm volatile("vpand %ymm0,%ymm7,%ymm7");
173                         asm volatile("vpxor %ymm5,%ymm4,%ymm4");
174                         asm volatile("vpxor %ymm7,%ymm6,%ymm6");
175                         asm volatile("vmovdqa %0,%%ymm5" : : "m" (dptr[z][d]));
176                         asm volatile("vmovdqa %0,%%ymm7" : : "m" (dptr[z][d+32]));
177                         asm volatile("vpxor %ymm5,%ymm2,%ymm2");
178                         asm volatile("vpxor %ymm7,%ymm3,%ymm3");
179                         asm volatile("vpxor %ymm5,%ymm4,%ymm4");
180                         asm volatile("vpxor %ymm7,%ymm6,%ymm6");
181                 }
182                 asm volatile("vmovntdq %%ymm2,%0" : "=m" (p[d]));
183                 asm volatile("vmovntdq %%ymm3,%0" : "=m" (p[d+32]));
184                 asm volatile("vmovntdq %%ymm4,%0" : "=m" (q[d]));
185                 asm volatile("vmovntdq %%ymm6,%0" : "=m" (q[d+32]));
186         }
187
188         asm volatile("sfence" : : : "memory");
189         kernel_fpu_end();
190 }
191
192 static void raid6_avx22_xor_syndrome(int disks, int start, int stop,
193                                      size_t bytes, void **ptrs)
194 {
195         u8 **dptr = (u8 **)ptrs;
196         u8 *p, *q;
197         int d, z, z0;
198
199         z0 = stop;              /* P/Q right side optimization */
200         p = dptr[disks-2];      /* XOR parity */
201         q = dptr[disks-1];      /* RS syndrome */
202
203         kernel_fpu_begin();
204
205         asm volatile("vmovdqa %0,%%ymm0" : : "m" (raid6_avx2_constants.x1d[0]));
206
207         for (d = 0 ; d < bytes ; d += 64) {
208                 asm volatile("vmovdqa %0,%%ymm4" :: "m" (dptr[z0][d]));
209                 asm volatile("vmovdqa %0,%%ymm6" :: "m" (dptr[z0][d+32]));
210                 asm volatile("vmovdqa %0,%%ymm2" : : "m" (p[d]));
211                 asm volatile("vmovdqa %0,%%ymm3" : : "m" (p[d+32]));
212                 asm volatile("vpxor %ymm4,%ymm2,%ymm2");
213                 asm volatile("vpxor %ymm6,%ymm3,%ymm3");
214                 /* P/Q data pages */
215                 for (z = z0-1 ; z >= start ; z--) {
216                         asm volatile("vpxor %ymm5,%ymm5,%ymm5");
217                         asm volatile("vpxor %ymm7,%ymm7,%ymm7");
218                         asm volatile("vpcmpgtb %ymm4,%ymm5,%ymm5");
219                         asm volatile("vpcmpgtb %ymm6,%ymm7,%ymm7");
220                         asm volatile("vpaddb %ymm4,%ymm4,%ymm4");
221                         asm volatile("vpaddb %ymm6,%ymm6,%ymm6");
222                         asm volatile("vpand %ymm0,%ymm5,%ymm5");
223                         asm volatile("vpand %ymm0,%ymm7,%ymm7");
224                         asm volatile("vpxor %ymm5,%ymm4,%ymm4");
225                         asm volatile("vpxor %ymm7,%ymm6,%ymm6");
226                         asm volatile("vmovdqa %0,%%ymm5" :: "m" (dptr[z][d]));
227                         asm volatile("vmovdqa %0,%%ymm7"
228                                      :: "m" (dptr[z][d+32]));
229                         asm volatile("vpxor %ymm5,%ymm2,%ymm2");
230                         asm volatile("vpxor %ymm7,%ymm3,%ymm3");
231                         asm volatile("vpxor %ymm5,%ymm4,%ymm4");
232                         asm volatile("vpxor %ymm7,%ymm6,%ymm6");
233                 }
234                 /* P/Q left side optimization */
235                 for (z = start-1 ; z >= 0 ; z--) {
236                         asm volatile("vpxor %ymm5,%ymm5,%ymm5");
237                         asm volatile("vpxor %ymm7,%ymm7,%ymm7");
238                         asm volatile("vpcmpgtb %ymm4,%ymm5,%ymm5");
239                         asm volatile("vpcmpgtb %ymm6,%ymm7,%ymm7");
240                         asm volatile("vpaddb %ymm4,%ymm4,%ymm4");
241                         asm volatile("vpaddb %ymm6,%ymm6,%ymm6");
242                         asm volatile("vpand %ymm0,%ymm5,%ymm5");
243                         asm volatile("vpand %ymm0,%ymm7,%ymm7");
244                         asm volatile("vpxor %ymm5,%ymm4,%ymm4");
245                         asm volatile("vpxor %ymm7,%ymm6,%ymm6");
246                 }
247                 asm volatile("vpxor %0,%%ymm4,%%ymm4" : : "m" (q[d]));
248                 asm volatile("vpxor %0,%%ymm6,%%ymm6" : : "m" (q[d+32]));
249                 /* Don't use movntdq for r/w memory area < cache line */
250                 asm volatile("vmovdqa %%ymm4,%0" : "=m" (q[d]));
251                 asm volatile("vmovdqa %%ymm6,%0" : "=m" (q[d+32]));
252                 asm volatile("vmovdqa %%ymm2,%0" : "=m" (p[d]));
253                 asm volatile("vmovdqa %%ymm3,%0" : "=m" (p[d+32]));
254         }
255
256         asm volatile("sfence" : : : "memory");
257         kernel_fpu_end();
258 }
259
260 const struct raid6_calls raid6_avx2x2 = {
261         raid6_avx22_gen_syndrome,
262         raid6_avx22_xor_syndrome,
263         raid6_have_avx2,
264         "avx2x2",
265         .priority = 2           /* Prefer AVX2 over priority 1 (SSE2 and others) */
266 };
267
268 #ifdef CONFIG_X86_64
269
270 /*
271  * Unrolled-by-4 AVX2 implementation
272  */
273 static void raid6_avx24_gen_syndrome(int disks, size_t bytes, void **ptrs)
274 {
275         u8 **dptr = (u8 **)ptrs;
276         u8 *p, *q;
277         int d, z, z0;
278
279         z0 = disks - 3;         /* Highest data disk */
280         p = dptr[z0+1];         /* XOR parity */
281         q = dptr[z0+2];         /* RS syndrome */
282
283         kernel_fpu_begin();
284
285         asm volatile("vmovdqa %0,%%ymm0" : : "m" (raid6_avx2_constants.x1d[0]));
286         asm volatile("vpxor %ymm1,%ymm1,%ymm1");        /* Zero temp */
287         asm volatile("vpxor %ymm2,%ymm2,%ymm2");        /* P[0] */
288         asm volatile("vpxor %ymm3,%ymm3,%ymm3");        /* P[1] */
289         asm volatile("vpxor %ymm4,%ymm4,%ymm4");        /* Q[0] */
290         asm volatile("vpxor %ymm6,%ymm6,%ymm6");        /* Q[1] */
291         asm volatile("vpxor %ymm10,%ymm10,%ymm10");     /* P[2] */
292         asm volatile("vpxor %ymm11,%ymm11,%ymm11");     /* P[3] */
293         asm volatile("vpxor %ymm12,%ymm12,%ymm12");     /* Q[2] */
294         asm volatile("vpxor %ymm14,%ymm14,%ymm14");     /* Q[3] */
295
296         for (d = 0; d < bytes; d += 128) {
297                 for (z = z0; z >= 0; z--) {
298                         asm volatile("prefetchnta %0" : : "m" (dptr[z][d]));
299                         asm volatile("prefetchnta %0" : : "m" (dptr[z][d+32]));
300                         asm volatile("prefetchnta %0" : : "m" (dptr[z][d+64]));
301                         asm volatile("prefetchnta %0" : : "m" (dptr[z][d+96]));
302                         asm volatile("vpcmpgtb %ymm4,%ymm1,%ymm5");
303                         asm volatile("vpcmpgtb %ymm6,%ymm1,%ymm7");
304                         asm volatile("vpcmpgtb %ymm12,%ymm1,%ymm13");
305                         asm volatile("vpcmpgtb %ymm14,%ymm1,%ymm15");
306                         asm volatile("vpaddb %ymm4,%ymm4,%ymm4");
307                         asm volatile("vpaddb %ymm6,%ymm6,%ymm6");
308                         asm volatile("vpaddb %ymm12,%ymm12,%ymm12");
309                         asm volatile("vpaddb %ymm14,%ymm14,%ymm14");
310                         asm volatile("vpand %ymm0,%ymm5,%ymm5");
311                         asm volatile("vpand %ymm0,%ymm7,%ymm7");
312                         asm volatile("vpand %ymm0,%ymm13,%ymm13");
313                         asm volatile("vpand %ymm0,%ymm15,%ymm15");
314                         asm volatile("vpxor %ymm5,%ymm4,%ymm4");
315                         asm volatile("vpxor %ymm7,%ymm6,%ymm6");
316                         asm volatile("vpxor %ymm13,%ymm12,%ymm12");
317                         asm volatile("vpxor %ymm15,%ymm14,%ymm14");
318                         asm volatile("vmovdqa %0,%%ymm5" : : "m" (dptr[z][d]));
319                         asm volatile("vmovdqa %0,%%ymm7" : : "m" (dptr[z][d+32]));
320                         asm volatile("vmovdqa %0,%%ymm13" : : "m" (dptr[z][d+64]));
321                         asm volatile("vmovdqa %0,%%ymm15" : : "m" (dptr[z][d+96]));
322                         asm volatile("vpxor %ymm5,%ymm2,%ymm2");
323                         asm volatile("vpxor %ymm7,%ymm3,%ymm3");
324                         asm volatile("vpxor %ymm13,%ymm10,%ymm10");
325                         asm volatile("vpxor %ymm15,%ymm11,%ymm11");
326                         asm volatile("vpxor %ymm5,%ymm4,%ymm4");
327                         asm volatile("vpxor %ymm7,%ymm6,%ymm6");
328                         asm volatile("vpxor %ymm13,%ymm12,%ymm12");
329                         asm volatile("vpxor %ymm15,%ymm14,%ymm14");
330                 }
331                 asm volatile("vmovntdq %%ymm2,%0" : "=m" (p[d]));
332                 asm volatile("vpxor %ymm2,%ymm2,%ymm2");
333                 asm volatile("vmovntdq %%ymm3,%0" : "=m" (p[d+32]));
334                 asm volatile("vpxor %ymm3,%ymm3,%ymm3");
335                 asm volatile("vmovntdq %%ymm10,%0" : "=m" (p[d+64]));
336                 asm volatile("vpxor %ymm10,%ymm10,%ymm10");
337                 asm volatile("vmovntdq %%ymm11,%0" : "=m" (p[d+96]));
338                 asm volatile("vpxor %ymm11,%ymm11,%ymm11");
339                 asm volatile("vmovntdq %%ymm4,%0" : "=m" (q[d]));
340                 asm volatile("vpxor %ymm4,%ymm4,%ymm4");
341                 asm volatile("vmovntdq %%ymm6,%0" : "=m" (q[d+32]));
342                 asm volatile("vpxor %ymm6,%ymm6,%ymm6");
343                 asm volatile("vmovntdq %%ymm12,%0" : "=m" (q[d+64]));
344                 asm volatile("vpxor %ymm12,%ymm12,%ymm12");
345                 asm volatile("vmovntdq %%ymm14,%0" : "=m" (q[d+96]));
346                 asm volatile("vpxor %ymm14,%ymm14,%ymm14");
347         }
348
349         asm volatile("sfence" : : : "memory");
350         kernel_fpu_end();
351 }
352
353 static void raid6_avx24_xor_syndrome(int disks, int start, int stop,
354                                      size_t bytes, void **ptrs)
355 {
356         u8 **dptr = (u8 **)ptrs;
357         u8 *p, *q;
358         int d, z, z0;
359
360         z0 = stop;              /* P/Q right side optimization */
361         p = dptr[disks-2];      /* XOR parity */
362         q = dptr[disks-1];      /* RS syndrome */
363
364         kernel_fpu_begin();
365
366         asm volatile("vmovdqa %0,%%ymm0" :: "m" (raid6_avx2_constants.x1d[0]));
367
368         for (d = 0 ; d < bytes ; d += 128) {
369                 asm volatile("vmovdqa %0,%%ymm4" :: "m" (dptr[z0][d]));
370                 asm volatile("vmovdqa %0,%%ymm6" :: "m" (dptr[z0][d+32]));
371                 asm volatile("vmovdqa %0,%%ymm12" :: "m" (dptr[z0][d+64]));
372                 asm volatile("vmovdqa %0,%%ymm14" :: "m" (dptr[z0][d+96]));
373                 asm volatile("vmovdqa %0,%%ymm2" : : "m" (p[d]));
374                 asm volatile("vmovdqa %0,%%ymm3" : : "m" (p[d+32]));
375                 asm volatile("vmovdqa %0,%%ymm10" : : "m" (p[d+64]));
376                 asm volatile("vmovdqa %0,%%ymm11" : : "m" (p[d+96]));
377                 asm volatile("vpxor %ymm4,%ymm2,%ymm2");
378                 asm volatile("vpxor %ymm6,%ymm3,%ymm3");
379                 asm volatile("vpxor %ymm12,%ymm10,%ymm10");
380                 asm volatile("vpxor %ymm14,%ymm11,%ymm11");
381                 /* P/Q data pages */
382                 for (z = z0-1 ; z >= start ; z--) {
383                         asm volatile("prefetchnta %0" :: "m" (dptr[z][d]));
384                         asm volatile("prefetchnta %0" :: "m" (dptr[z][d+64]));
385                         asm volatile("vpxor %ymm5,%ymm5,%ymm5");
386                         asm volatile("vpxor %ymm7,%ymm7,%ymm7");
387                         asm volatile("vpxor %ymm13,%ymm13,%ymm13");
388                         asm volatile("vpxor %ymm15,%ymm15,%ymm15");
389                         asm volatile("vpcmpgtb %ymm4,%ymm5,%ymm5");
390                         asm volatile("vpcmpgtb %ymm6,%ymm7,%ymm7");
391                         asm volatile("vpcmpgtb %ymm12,%ymm13,%ymm13");
392                         asm volatile("vpcmpgtb %ymm14,%ymm15,%ymm15");
393                         asm volatile("vpaddb %ymm4,%ymm4,%ymm4");
394                         asm volatile("vpaddb %ymm6,%ymm6,%ymm6");
395                         asm volatile("vpaddb %ymm12,%ymm12,%ymm12");
396                         asm volatile("vpaddb %ymm14,%ymm14,%ymm14");
397                         asm volatile("vpand %ymm0,%ymm5,%ymm5");
398                         asm volatile("vpand %ymm0,%ymm7,%ymm7");
399                         asm volatile("vpand %ymm0,%ymm13,%ymm13");
400                         asm volatile("vpand %ymm0,%ymm15,%ymm15");
401                         asm volatile("vpxor %ymm5,%ymm4,%ymm4");
402                         asm volatile("vpxor %ymm7,%ymm6,%ymm6");
403                         asm volatile("vpxor %ymm13,%ymm12,%ymm12");
404                         asm volatile("vpxor %ymm15,%ymm14,%ymm14");
405                         asm volatile("vmovdqa %0,%%ymm5" :: "m" (dptr[z][d]));
406                         asm volatile("vmovdqa %0,%%ymm7"
407                                      :: "m" (dptr[z][d+32]));
408                         asm volatile("vmovdqa %0,%%ymm13"
409                                      :: "m" (dptr[z][d+64]));
410                         asm volatile("vmovdqa %0,%%ymm15"
411                                      :: "m" (dptr[z][d+96]));
412                         asm volatile("vpxor %ymm5,%ymm2,%ymm2");
413                         asm volatile("vpxor %ymm7,%ymm3,%ymm3");
414                         asm volatile("vpxor %ymm13,%ymm10,%ymm10");
415                         asm volatile("vpxor %ymm15,%ymm11,%ymm11");
416                         asm volatile("vpxor %ymm5,%ymm4,%ymm4");
417                         asm volatile("vpxor %ymm7,%ymm6,%ymm6");
418                         asm volatile("vpxor %ymm13,%ymm12,%ymm12");
419                         asm volatile("vpxor %ymm15,%ymm14,%ymm14");
420                 }
421                 asm volatile("prefetchnta %0" :: "m" (q[d]));
422                 asm volatile("prefetchnta %0" :: "m" (q[d+64]));
423                 /* P/Q left side optimization */
424                 for (z = start-1 ; z >= 0 ; z--) {
425                         asm volatile("vpxor %ymm5,%ymm5,%ymm5");
426                         asm volatile("vpxor %ymm7,%ymm7,%ymm7");
427                         asm volatile("vpxor %ymm13,%ymm13,%ymm13");
428                         asm volatile("vpxor %ymm15,%ymm15,%ymm15");
429                         asm volatile("vpcmpgtb %ymm4,%ymm5,%ymm5");
430                         asm volatile("vpcmpgtb %ymm6,%ymm7,%ymm7");
431                         asm volatile("vpcmpgtb %ymm12,%ymm13,%ymm13");
432                         asm volatile("vpcmpgtb %ymm14,%ymm15,%ymm15");
433                         asm volatile("vpaddb %ymm4,%ymm4,%ymm4");
434                         asm volatile("vpaddb %ymm6,%ymm6,%ymm6");
435                         asm volatile("vpaddb %ymm12,%ymm12,%ymm12");
436                         asm volatile("vpaddb %ymm14,%ymm14,%ymm14");
437                         asm volatile("vpand %ymm0,%ymm5,%ymm5");
438                         asm volatile("vpand %ymm0,%ymm7,%ymm7");
439                         asm volatile("vpand %ymm0,%ymm13,%ymm13");
440                         asm volatile("vpand %ymm0,%ymm15,%ymm15");
441                         asm volatile("vpxor %ymm5,%ymm4,%ymm4");
442                         asm volatile("vpxor %ymm7,%ymm6,%ymm6");
443                         asm volatile("vpxor %ymm13,%ymm12,%ymm12");
444                         asm volatile("vpxor %ymm15,%ymm14,%ymm14");
445                 }
446                 asm volatile("vmovntdq %%ymm2,%0" : "=m" (p[d]));
447                 asm volatile("vmovntdq %%ymm3,%0" : "=m" (p[d+32]));
448                 asm volatile("vmovntdq %%ymm10,%0" : "=m" (p[d+64]));
449                 asm volatile("vmovntdq %%ymm11,%0" : "=m" (p[d+96]));
450                 asm volatile("vpxor %0,%%ymm4,%%ymm4" : : "m" (q[d]));
451                 asm volatile("vpxor %0,%%ymm6,%%ymm6" : : "m" (q[d+32]));
452                 asm volatile("vpxor %0,%%ymm12,%%ymm12" : : "m" (q[d+64]));
453                 asm volatile("vpxor %0,%%ymm14,%%ymm14" : : "m" (q[d+96]));
454                 asm volatile("vmovntdq %%ymm4,%0" : "=m" (q[d]));
455                 asm volatile("vmovntdq %%ymm6,%0" : "=m" (q[d+32]));
456                 asm volatile("vmovntdq %%ymm12,%0" : "=m" (q[d+64]));
457                 asm volatile("vmovntdq %%ymm14,%0" : "=m" (q[d+96]));
458         }
459         asm volatile("sfence" : : : "memory");
460         kernel_fpu_end();
461 }
462
463 const struct raid6_calls raid6_avx2x4 = {
464         raid6_avx24_gen_syndrome,
465         raid6_avx24_xor_syndrome,
466         raid6_have_avx2,
467         "avx2x4",
468         .priority = 2           /* Prefer AVX2 over priority 1 (SSE2 and others) */
469 };
470 #endif /* CONFIG_X86_64 */