1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 * include/asm-generic/xor.h
5 * Generic optimized RAID-5 checksumming functions.
8 #include <linux/prefetch.h>
11 xor_8regs_2(unsigned long bytes
, unsigned long *p1
, unsigned long *p2
)
13 long lines
= bytes
/ (sizeof (long)) / 8;
26 } while (--lines
> 0);
30 xor_8regs_3(unsigned long bytes
, unsigned long *p1
, unsigned long *p2
,
33 long lines
= bytes
/ (sizeof (long)) / 8;
36 p1
[0] ^= p2
[0] ^ p3
[0];
37 p1
[1] ^= p2
[1] ^ p3
[1];
38 p1
[2] ^= p2
[2] ^ p3
[2];
39 p1
[3] ^= p2
[3] ^ p3
[3];
40 p1
[4] ^= p2
[4] ^ p3
[4];
41 p1
[5] ^= p2
[5] ^ p3
[5];
42 p1
[6] ^= p2
[6] ^ p3
[6];
43 p1
[7] ^= p2
[7] ^ p3
[7];
47 } while (--lines
> 0);
51 xor_8regs_4(unsigned long bytes
, unsigned long *p1
, unsigned long *p2
,
52 unsigned long *p3
, unsigned long *p4
)
54 long lines
= bytes
/ (sizeof (long)) / 8;
57 p1
[0] ^= p2
[0] ^ p3
[0] ^ p4
[0];
58 p1
[1] ^= p2
[1] ^ p3
[1] ^ p4
[1];
59 p1
[2] ^= p2
[2] ^ p3
[2] ^ p4
[2];
60 p1
[3] ^= p2
[3] ^ p3
[3] ^ p4
[3];
61 p1
[4] ^= p2
[4] ^ p3
[4] ^ p4
[4];
62 p1
[5] ^= p2
[5] ^ p3
[5] ^ p4
[5];
63 p1
[6] ^= p2
[6] ^ p3
[6] ^ p4
[6];
64 p1
[7] ^= p2
[7] ^ p3
[7] ^ p4
[7];
69 } while (--lines
> 0);
73 xor_8regs_5(unsigned long bytes
, unsigned long *p1
, unsigned long *p2
,
74 unsigned long *p3
, unsigned long *p4
, unsigned long *p5
)
76 long lines
= bytes
/ (sizeof (long)) / 8;
79 p1
[0] ^= p2
[0] ^ p3
[0] ^ p4
[0] ^ p5
[0];
80 p1
[1] ^= p2
[1] ^ p3
[1] ^ p4
[1] ^ p5
[1];
81 p1
[2] ^= p2
[2] ^ p3
[2] ^ p4
[2] ^ p5
[2];
82 p1
[3] ^= p2
[3] ^ p3
[3] ^ p4
[3] ^ p5
[3];
83 p1
[4] ^= p2
[4] ^ p3
[4] ^ p4
[4] ^ p5
[4];
84 p1
[5] ^= p2
[5] ^ p3
[5] ^ p4
[5] ^ p5
[5];
85 p1
[6] ^= p2
[6] ^ p3
[6] ^ p4
[6] ^ p5
[6];
86 p1
[7] ^= p2
[7] ^ p3
[7] ^ p4
[7] ^ p5
[7];
92 } while (--lines
> 0);
96 xor_32regs_2(unsigned long bytes
, unsigned long *p1
, unsigned long *p2
)
98 long lines
= bytes
/ (sizeof (long)) / 8;
101 register long d0
, d1
, d2
, d3
, d4
, d5
, d6
, d7
;
102 d0
= p1
[0]; /* Pull the stuff into registers */
103 d1
= p1
[1]; /* ... in bursts, if possible. */
118 p1
[0] = d0
; /* Store the result (in bursts) */
128 } while (--lines
> 0);
132 xor_32regs_3(unsigned long bytes
, unsigned long *p1
, unsigned long *p2
,
135 long lines
= bytes
/ (sizeof (long)) / 8;
138 register long d0
, d1
, d2
, d3
, d4
, d5
, d6
, d7
;
139 d0
= p1
[0]; /* Pull the stuff into registers */
140 d1
= p1
[1]; /* ... in bursts, if possible. */
163 p1
[0] = d0
; /* Store the result (in bursts) */
174 } while (--lines
> 0);
178 xor_32regs_4(unsigned long bytes
, unsigned long *p1
, unsigned long *p2
,
179 unsigned long *p3
, unsigned long *p4
)
181 long lines
= bytes
/ (sizeof (long)) / 8;
184 register long d0
, d1
, d2
, d3
, d4
, d5
, d6
, d7
;
185 d0
= p1
[0]; /* Pull the stuff into registers */
186 d1
= p1
[1]; /* ... in bursts, if possible. */
217 p1
[0] = d0
; /* Store the result (in bursts) */
229 } while (--lines
> 0);
233 xor_32regs_5(unsigned long bytes
, unsigned long *p1
, unsigned long *p2
,
234 unsigned long *p3
, unsigned long *p4
, unsigned long *p5
)
236 long lines
= bytes
/ (sizeof (long)) / 8;
239 register long d0
, d1
, d2
, d3
, d4
, d5
, d6
, d7
;
240 d0
= p1
[0]; /* Pull the stuff into registers */
241 d1
= p1
[1]; /* ... in bursts, if possible. */
280 p1
[0] = d0
; /* Store the result (in bursts) */
293 } while (--lines
> 0);
297 xor_8regs_p_2(unsigned long bytes
, unsigned long *p1
, unsigned long *p2
)
299 long lines
= bytes
/ (sizeof (long)) / 8 - 1;
317 } while (--lines
> 0);
323 xor_8regs_p_3(unsigned long bytes
, unsigned long *p1
, unsigned long *p2
,
326 long lines
= bytes
/ (sizeof (long)) / 8 - 1;
336 p1
[0] ^= p2
[0] ^ p3
[0];
337 p1
[1] ^= p2
[1] ^ p3
[1];
338 p1
[2] ^= p2
[2] ^ p3
[2];
339 p1
[3] ^= p2
[3] ^ p3
[3];
340 p1
[4] ^= p2
[4] ^ p3
[4];
341 p1
[5] ^= p2
[5] ^ p3
[5];
342 p1
[6] ^= p2
[6] ^ p3
[6];
343 p1
[7] ^= p2
[7] ^ p3
[7];
347 } while (--lines
> 0);
353 xor_8regs_p_4(unsigned long bytes
, unsigned long *p1
, unsigned long *p2
,
354 unsigned long *p3
, unsigned long *p4
)
356 long lines
= bytes
/ (sizeof (long)) / 8 - 1;
369 p1
[0] ^= p2
[0] ^ p3
[0] ^ p4
[0];
370 p1
[1] ^= p2
[1] ^ p3
[1] ^ p4
[1];
371 p1
[2] ^= p2
[2] ^ p3
[2] ^ p4
[2];
372 p1
[3] ^= p2
[3] ^ p3
[3] ^ p4
[3];
373 p1
[4] ^= p2
[4] ^ p3
[4] ^ p4
[4];
374 p1
[5] ^= p2
[5] ^ p3
[5] ^ p4
[5];
375 p1
[6] ^= p2
[6] ^ p3
[6] ^ p4
[6];
376 p1
[7] ^= p2
[7] ^ p3
[7] ^ p4
[7];
381 } while (--lines
> 0);
387 xor_8regs_p_5(unsigned long bytes
, unsigned long *p1
, unsigned long *p2
,
388 unsigned long *p3
, unsigned long *p4
, unsigned long *p5
)
390 long lines
= bytes
/ (sizeof (long)) / 8 - 1;
405 p1
[0] ^= p2
[0] ^ p3
[0] ^ p4
[0] ^ p5
[0];
406 p1
[1] ^= p2
[1] ^ p3
[1] ^ p4
[1] ^ p5
[1];
407 p1
[2] ^= p2
[2] ^ p3
[2] ^ p4
[2] ^ p5
[2];
408 p1
[3] ^= p2
[3] ^ p3
[3] ^ p4
[3] ^ p5
[3];
409 p1
[4] ^= p2
[4] ^ p3
[4] ^ p4
[4] ^ p5
[4];
410 p1
[5] ^= p2
[5] ^ p3
[5] ^ p4
[5] ^ p5
[5];
411 p1
[6] ^= p2
[6] ^ p3
[6] ^ p4
[6] ^ p5
[6];
412 p1
[7] ^= p2
[7] ^ p3
[7] ^ p4
[7] ^ p5
[7];
418 } while (--lines
> 0);
424 xor_32regs_p_2(unsigned long bytes
, unsigned long *p1
, unsigned long *p2
)
426 long lines
= bytes
/ (sizeof (long)) / 8 - 1;
432 register long d0
, d1
, d2
, d3
, d4
, d5
, d6
, d7
;
437 d0
= p1
[0]; /* Pull the stuff into registers */
438 d1
= p1
[1]; /* ... in bursts, if possible. */
453 p1
[0] = d0
; /* Store the result (in bursts) */
463 } while (--lines
> 0);
469 xor_32regs_p_3(unsigned long bytes
, unsigned long *p1
, unsigned long *p2
,
472 long lines
= bytes
/ (sizeof (long)) / 8 - 1;
479 register long d0
, d1
, d2
, d3
, d4
, d5
, d6
, d7
;
485 d0
= p1
[0]; /* Pull the stuff into registers */
486 d1
= p1
[1]; /* ... in bursts, if possible. */
509 p1
[0] = d0
; /* Store the result (in bursts) */
520 } while (--lines
> 0);
526 xor_32regs_p_4(unsigned long bytes
, unsigned long *p1
, unsigned long *p2
,
527 unsigned long *p3
, unsigned long *p4
)
529 long lines
= bytes
/ (sizeof (long)) / 8 - 1;
537 register long d0
, d1
, d2
, d3
, d4
, d5
, d6
, d7
;
544 d0
= p1
[0]; /* Pull the stuff into registers */
545 d1
= p1
[1]; /* ... in bursts, if possible. */
576 p1
[0] = d0
; /* Store the result (in bursts) */
588 } while (--lines
> 0);
594 xor_32regs_p_5(unsigned long bytes
, unsigned long *p1
, unsigned long *p2
,
595 unsigned long *p3
, unsigned long *p4
, unsigned long *p5
)
597 long lines
= bytes
/ (sizeof (long)) / 8 - 1;
606 register long d0
, d1
, d2
, d3
, d4
, d5
, d6
, d7
;
614 d0
= p1
[0]; /* Pull the stuff into registers */
615 d1
= p1
[1]; /* ... in bursts, if possible. */
654 p1
[0] = d0
; /* Store the result (in bursts) */
667 } while (--lines
> 0);
672 static struct xor_block_template xor_block_8regs
= {
680 static struct xor_block_template xor_block_32regs
= {
682 .do_2
= xor_32regs_2
,
683 .do_3
= xor_32regs_3
,
684 .do_4
= xor_32regs_4
,
685 .do_5
= xor_32regs_5
,
688 static struct xor_block_template xor_block_8regs_p __maybe_unused
= {
689 .name
= "8regs_prefetch",
690 .do_2
= xor_8regs_p_2
,
691 .do_3
= xor_8regs_p_3
,
692 .do_4
= xor_8regs_p_4
,
693 .do_5
= xor_8regs_p_5
,
696 static struct xor_block_template xor_block_32regs_p __maybe_unused
= {
697 .name
= "32regs_prefetch",
698 .do_2
= xor_32regs_p_2
,
699 .do_3
= xor_32regs_p_3
,
700 .do_4
= xor_32regs_p_4
,
701 .do_5
= xor_32regs_p_5
,
704 #define XOR_TRY_TEMPLATES \
706 xor_speed(&xor_block_8regs); \
707 xor_speed(&xor_block_8regs_p); \
708 xor_speed(&xor_block_32regs); \
709 xor_speed(&xor_block_32regs_p); \