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); \