xref: /linux/lib/raid/xor/arm/xor.c (revision 440d6635b20037bc9ad46b20817d7b61cef0fc1b)
10d64a24eSChristoph Hellwig // SPDX-License-Identifier: GPL-2.0-only
20d64a24eSChristoph Hellwig /*
30d64a24eSChristoph Hellwig  *  Copyright (C) 2001 Russell King
40d64a24eSChristoph Hellwig  */
5e20043b4SChristoph Hellwig #include "xor_impl.h"
6e20043b4SChristoph Hellwig #include "xor_arch.h"
70d64a24eSChristoph Hellwig 
80d64a24eSChristoph Hellwig #define __XOR(a1, a2) a1 ^= a2
90d64a24eSChristoph Hellwig 
100d64a24eSChristoph Hellwig #define GET_BLOCK_2(dst) \
110d64a24eSChristoph Hellwig 	__asm__("ldmia	%0, {%1, %2}" \
120d64a24eSChristoph Hellwig 		: "=r" (dst), "=r" (a1), "=r" (a2) \
130d64a24eSChristoph Hellwig 		: "0" (dst))
140d64a24eSChristoph Hellwig 
150d64a24eSChristoph Hellwig #define GET_BLOCK_4(dst) \
160d64a24eSChristoph Hellwig 	__asm__("ldmia	%0, {%1, %2, %3, %4}" \
170d64a24eSChristoph Hellwig 		: "=r" (dst), "=r" (a1), "=r" (a2), "=r" (a3), "=r" (a4) \
180d64a24eSChristoph Hellwig 		: "0" (dst))
190d64a24eSChristoph Hellwig 
200d64a24eSChristoph Hellwig #define XOR_BLOCK_2(src) \
210d64a24eSChristoph Hellwig 	__asm__("ldmia	%0!, {%1, %2}" \
220d64a24eSChristoph Hellwig 		: "=r" (src), "=r" (b1), "=r" (b2) \
230d64a24eSChristoph Hellwig 		: "0" (src)); \
240d64a24eSChristoph Hellwig 	__XOR(a1, b1); __XOR(a2, b2);
250d64a24eSChristoph Hellwig 
260d64a24eSChristoph Hellwig #define XOR_BLOCK_4(src) \
270d64a24eSChristoph Hellwig 	__asm__("ldmia	%0!, {%1, %2, %3, %4}" \
280d64a24eSChristoph Hellwig 		: "=r" (src), "=r" (b1), "=r" (b2), "=r" (b3), "=r" (b4) \
290d64a24eSChristoph Hellwig 		: "0" (src)); \
300d64a24eSChristoph Hellwig 	__XOR(a1, b1); __XOR(a2, b2); __XOR(a3, b3); __XOR(a4, b4)
310d64a24eSChristoph Hellwig 
320d64a24eSChristoph Hellwig #define PUT_BLOCK_2(dst) \
330d64a24eSChristoph Hellwig 	__asm__ __volatile__("stmia	%0!, {%2, %3}" \
340d64a24eSChristoph Hellwig 		: "=r" (dst) \
350d64a24eSChristoph Hellwig 		: "0" (dst), "r" (a1), "r" (a2))
360d64a24eSChristoph Hellwig 
370d64a24eSChristoph Hellwig #define PUT_BLOCK_4(dst) \
380d64a24eSChristoph Hellwig 	__asm__ __volatile__("stmia	%0!, {%2, %3, %4, %5}" \
390d64a24eSChristoph Hellwig 		: "=r" (dst) \
400d64a24eSChristoph Hellwig 		: "0" (dst), "r" (a1), "r" (a2), "r" (a3), "r" (a4))
410d64a24eSChristoph Hellwig 
420d64a24eSChristoph Hellwig static void
430d64a24eSChristoph Hellwig xor_arm4regs_2(unsigned long bytes, unsigned long * __restrict p1,
440d64a24eSChristoph Hellwig 	       const unsigned long * __restrict p2)
450d64a24eSChristoph Hellwig {
460d64a24eSChristoph Hellwig 	unsigned int lines = bytes / sizeof(unsigned long) / 4;
470d64a24eSChristoph Hellwig 	register unsigned int a1 __asm__("r4");
480d64a24eSChristoph Hellwig 	register unsigned int a2 __asm__("r5");
490d64a24eSChristoph Hellwig 	register unsigned int a3 __asm__("r6");
500d64a24eSChristoph Hellwig 	register unsigned int a4 __asm__("r10");
510d64a24eSChristoph Hellwig 	register unsigned int b1 __asm__("r8");
520d64a24eSChristoph Hellwig 	register unsigned int b2 __asm__("r9");
530d64a24eSChristoph Hellwig 	register unsigned int b3 __asm__("ip");
540d64a24eSChristoph Hellwig 	register unsigned int b4 __asm__("lr");
550d64a24eSChristoph Hellwig 
560d64a24eSChristoph Hellwig 	do {
570d64a24eSChristoph Hellwig 		GET_BLOCK_4(p1);
580d64a24eSChristoph Hellwig 		XOR_BLOCK_4(p2);
590d64a24eSChristoph Hellwig 		PUT_BLOCK_4(p1);
600d64a24eSChristoph Hellwig 	} while (--lines);
610d64a24eSChristoph Hellwig }
620d64a24eSChristoph Hellwig 
630d64a24eSChristoph Hellwig static void
640d64a24eSChristoph Hellwig xor_arm4regs_3(unsigned long bytes, unsigned long * __restrict p1,
650d64a24eSChristoph Hellwig 	       const unsigned long * __restrict p2,
660d64a24eSChristoph Hellwig 	       const unsigned long * __restrict p3)
670d64a24eSChristoph Hellwig {
680d64a24eSChristoph Hellwig 	unsigned int lines = bytes / sizeof(unsigned long) / 4;
690d64a24eSChristoph Hellwig 	register unsigned int a1 __asm__("r4");
700d64a24eSChristoph Hellwig 	register unsigned int a2 __asm__("r5");
710d64a24eSChristoph Hellwig 	register unsigned int a3 __asm__("r6");
720d64a24eSChristoph Hellwig 	register unsigned int a4 __asm__("r10");
730d64a24eSChristoph Hellwig 	register unsigned int b1 __asm__("r8");
740d64a24eSChristoph Hellwig 	register unsigned int b2 __asm__("r9");
750d64a24eSChristoph Hellwig 	register unsigned int b3 __asm__("ip");
760d64a24eSChristoph Hellwig 	register unsigned int b4 __asm__("lr");
770d64a24eSChristoph Hellwig 
780d64a24eSChristoph Hellwig 	do {
790d64a24eSChristoph Hellwig 		GET_BLOCK_4(p1);
800d64a24eSChristoph Hellwig 		XOR_BLOCK_4(p2);
810d64a24eSChristoph Hellwig 		XOR_BLOCK_4(p3);
820d64a24eSChristoph Hellwig 		PUT_BLOCK_4(p1);
830d64a24eSChristoph Hellwig 	} while (--lines);
840d64a24eSChristoph Hellwig }
850d64a24eSChristoph Hellwig 
860d64a24eSChristoph Hellwig static void
870d64a24eSChristoph Hellwig xor_arm4regs_4(unsigned long bytes, unsigned long * __restrict p1,
880d64a24eSChristoph Hellwig 	       const unsigned long * __restrict p2,
890d64a24eSChristoph Hellwig 	       const unsigned long * __restrict p3,
900d64a24eSChristoph Hellwig 	       const unsigned long * __restrict p4)
910d64a24eSChristoph Hellwig {
920d64a24eSChristoph Hellwig 	unsigned int lines = bytes / sizeof(unsigned long) / 2;
930d64a24eSChristoph Hellwig 	register unsigned int a1 __asm__("r8");
940d64a24eSChristoph Hellwig 	register unsigned int a2 __asm__("r9");
950d64a24eSChristoph Hellwig 	register unsigned int b1 __asm__("ip");
960d64a24eSChristoph Hellwig 	register unsigned int b2 __asm__("lr");
970d64a24eSChristoph Hellwig 
980d64a24eSChristoph Hellwig 	do {
990d64a24eSChristoph Hellwig 		GET_BLOCK_2(p1);
1000d64a24eSChristoph Hellwig 		XOR_BLOCK_2(p2);
1010d64a24eSChristoph Hellwig 		XOR_BLOCK_2(p3);
1020d64a24eSChristoph Hellwig 		XOR_BLOCK_2(p4);
1030d64a24eSChristoph Hellwig 		PUT_BLOCK_2(p1);
1040d64a24eSChristoph Hellwig 	} while (--lines);
1050d64a24eSChristoph Hellwig }
1060d64a24eSChristoph Hellwig 
1070d64a24eSChristoph Hellwig static void
1080d64a24eSChristoph Hellwig xor_arm4regs_5(unsigned long bytes, unsigned long * __restrict p1,
1090d64a24eSChristoph Hellwig 	       const unsigned long * __restrict p2,
1100d64a24eSChristoph Hellwig 	       const unsigned long * __restrict p3,
1110d64a24eSChristoph Hellwig 	       const unsigned long * __restrict p4,
1120d64a24eSChristoph Hellwig 	       const unsigned long * __restrict p5)
1130d64a24eSChristoph Hellwig {
1140d64a24eSChristoph Hellwig 	unsigned int lines = bytes / sizeof(unsigned long) / 2;
1150d64a24eSChristoph Hellwig 	register unsigned int a1 __asm__("r8");
1160d64a24eSChristoph Hellwig 	register unsigned int a2 __asm__("r9");
1170d64a24eSChristoph Hellwig 	register unsigned int b1 __asm__("ip");
1180d64a24eSChristoph Hellwig 	register unsigned int b2 __asm__("lr");
1190d64a24eSChristoph Hellwig 
1200d64a24eSChristoph Hellwig 	do {
1210d64a24eSChristoph Hellwig 		GET_BLOCK_2(p1);
1220d64a24eSChristoph Hellwig 		XOR_BLOCK_2(p2);
1230d64a24eSChristoph Hellwig 		XOR_BLOCK_2(p3);
1240d64a24eSChristoph Hellwig 		XOR_BLOCK_2(p4);
1250d64a24eSChristoph Hellwig 		XOR_BLOCK_2(p5);
1260d64a24eSChristoph Hellwig 		PUT_BLOCK_2(p1);
1270d64a24eSChristoph Hellwig 	} while (--lines);
1280d64a24eSChristoph Hellwig }
1290d64a24eSChristoph Hellwig 
130*80dcf0a7SChristoph Hellwig DO_XOR_BLOCKS(arm4regs, xor_arm4regs_2, xor_arm4regs_3, xor_arm4regs_4,
131*80dcf0a7SChristoph Hellwig 		xor_arm4regs_5);
132*80dcf0a7SChristoph Hellwig 
1330d64a24eSChristoph Hellwig struct xor_block_template xor_block_arm4regs = {
1340d64a24eSChristoph Hellwig 	.name		= "arm4regs",
135*80dcf0a7SChristoph Hellwig 	.xor_gen	= xor_gen_arm4regs,
1360d64a24eSChristoph Hellwig };
137