162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * include/asm/xor.h
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Optimized RAID-5 checksumming functions for 32-bit Sparc.
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci/*
962306a36Sopenharmony_ci * High speed xor_block operation for RAID4/5 utilizing the
1062306a36Sopenharmony_ci * ldd/std SPARC instructions.
1162306a36Sopenharmony_ci *
1262306a36Sopenharmony_ci * Copyright (C) 1999 Jakub Jelinek (jj@ultra.linux.cz)
1362306a36Sopenharmony_ci */
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_cistatic void
1662306a36Sopenharmony_cisparc_2(unsigned long bytes, unsigned long * __restrict p1,
1762306a36Sopenharmony_ci	const unsigned long * __restrict p2)
1862306a36Sopenharmony_ci{
1962306a36Sopenharmony_ci	int lines = bytes / (sizeof (long)) / 8;
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci	do {
2262306a36Sopenharmony_ci		__asm__ __volatile__(
2362306a36Sopenharmony_ci		  "ldd [%0 + 0x00], %%g2\n\t"
2462306a36Sopenharmony_ci		  "ldd [%0 + 0x08], %%g4\n\t"
2562306a36Sopenharmony_ci		  "ldd [%0 + 0x10], %%o0\n\t"
2662306a36Sopenharmony_ci		  "ldd [%0 + 0x18], %%o2\n\t"
2762306a36Sopenharmony_ci		  "ldd [%1 + 0x00], %%o4\n\t"
2862306a36Sopenharmony_ci		  "ldd [%1 + 0x08], %%l0\n\t"
2962306a36Sopenharmony_ci		  "ldd [%1 + 0x10], %%l2\n\t"
3062306a36Sopenharmony_ci		  "ldd [%1 + 0x18], %%l4\n\t"
3162306a36Sopenharmony_ci		  "xor %%g2, %%o4, %%g2\n\t"
3262306a36Sopenharmony_ci		  "xor %%g3, %%o5, %%g3\n\t"
3362306a36Sopenharmony_ci		  "xor %%g4, %%l0, %%g4\n\t"
3462306a36Sopenharmony_ci		  "xor %%g5, %%l1, %%g5\n\t"
3562306a36Sopenharmony_ci		  "xor %%o0, %%l2, %%o0\n\t"
3662306a36Sopenharmony_ci		  "xor %%o1, %%l3, %%o1\n\t"
3762306a36Sopenharmony_ci		  "xor %%o2, %%l4, %%o2\n\t"
3862306a36Sopenharmony_ci		  "xor %%o3, %%l5, %%o3\n\t"
3962306a36Sopenharmony_ci		  "std %%g2, [%0 + 0x00]\n\t"
4062306a36Sopenharmony_ci		  "std %%g4, [%0 + 0x08]\n\t"
4162306a36Sopenharmony_ci		  "std %%o0, [%0 + 0x10]\n\t"
4262306a36Sopenharmony_ci		  "std %%o2, [%0 + 0x18]\n"
4362306a36Sopenharmony_ci		:
4462306a36Sopenharmony_ci		: "r" (p1), "r" (p2)
4562306a36Sopenharmony_ci		: "g2", "g3", "g4", "g5",
4662306a36Sopenharmony_ci		  "o0", "o1", "o2", "o3", "o4", "o5",
4762306a36Sopenharmony_ci		  "l0", "l1", "l2", "l3", "l4", "l5");
4862306a36Sopenharmony_ci		p1 += 8;
4962306a36Sopenharmony_ci		p2 += 8;
5062306a36Sopenharmony_ci	} while (--lines > 0);
5162306a36Sopenharmony_ci}
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_cistatic void
5462306a36Sopenharmony_cisparc_3(unsigned long bytes, unsigned long * __restrict p1,
5562306a36Sopenharmony_ci	const unsigned long * __restrict p2,
5662306a36Sopenharmony_ci	const unsigned long * __restrict p3)
5762306a36Sopenharmony_ci{
5862306a36Sopenharmony_ci	int lines = bytes / (sizeof (long)) / 8;
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci	do {
6162306a36Sopenharmony_ci		__asm__ __volatile__(
6262306a36Sopenharmony_ci		  "ldd [%0 + 0x00], %%g2\n\t"
6362306a36Sopenharmony_ci		  "ldd [%0 + 0x08], %%g4\n\t"
6462306a36Sopenharmony_ci		  "ldd [%0 + 0x10], %%o0\n\t"
6562306a36Sopenharmony_ci		  "ldd [%0 + 0x18], %%o2\n\t"
6662306a36Sopenharmony_ci		  "ldd [%1 + 0x00], %%o4\n\t"
6762306a36Sopenharmony_ci		  "ldd [%1 + 0x08], %%l0\n\t"
6862306a36Sopenharmony_ci		  "ldd [%1 + 0x10], %%l2\n\t"
6962306a36Sopenharmony_ci		  "ldd [%1 + 0x18], %%l4\n\t"
7062306a36Sopenharmony_ci		  "xor %%g2, %%o4, %%g2\n\t"
7162306a36Sopenharmony_ci		  "xor %%g3, %%o5, %%g3\n\t"
7262306a36Sopenharmony_ci		  "ldd [%2 + 0x00], %%o4\n\t"
7362306a36Sopenharmony_ci		  "xor %%g4, %%l0, %%g4\n\t"
7462306a36Sopenharmony_ci		  "xor %%g5, %%l1, %%g5\n\t"
7562306a36Sopenharmony_ci		  "ldd [%2 + 0x08], %%l0\n\t"
7662306a36Sopenharmony_ci		  "xor %%o0, %%l2, %%o0\n\t"
7762306a36Sopenharmony_ci		  "xor %%o1, %%l3, %%o1\n\t"
7862306a36Sopenharmony_ci		  "ldd [%2 + 0x10], %%l2\n\t"
7962306a36Sopenharmony_ci		  "xor %%o2, %%l4, %%o2\n\t"
8062306a36Sopenharmony_ci		  "xor %%o3, %%l5, %%o3\n\t"
8162306a36Sopenharmony_ci		  "ldd [%2 + 0x18], %%l4\n\t"
8262306a36Sopenharmony_ci		  "xor %%g2, %%o4, %%g2\n\t"
8362306a36Sopenharmony_ci		  "xor %%g3, %%o5, %%g3\n\t"
8462306a36Sopenharmony_ci		  "xor %%g4, %%l0, %%g4\n\t"
8562306a36Sopenharmony_ci		  "xor %%g5, %%l1, %%g5\n\t"
8662306a36Sopenharmony_ci		  "xor %%o0, %%l2, %%o0\n\t"
8762306a36Sopenharmony_ci		  "xor %%o1, %%l3, %%o1\n\t"
8862306a36Sopenharmony_ci		  "xor %%o2, %%l4, %%o2\n\t"
8962306a36Sopenharmony_ci		  "xor %%o3, %%l5, %%o3\n\t"
9062306a36Sopenharmony_ci		  "std %%g2, [%0 + 0x00]\n\t"
9162306a36Sopenharmony_ci		  "std %%g4, [%0 + 0x08]\n\t"
9262306a36Sopenharmony_ci		  "std %%o0, [%0 + 0x10]\n\t"
9362306a36Sopenharmony_ci		  "std %%o2, [%0 + 0x18]\n"
9462306a36Sopenharmony_ci		:
9562306a36Sopenharmony_ci		: "r" (p1), "r" (p2), "r" (p3)
9662306a36Sopenharmony_ci		: "g2", "g3", "g4", "g5",
9762306a36Sopenharmony_ci		  "o0", "o1", "o2", "o3", "o4", "o5",
9862306a36Sopenharmony_ci		  "l0", "l1", "l2", "l3", "l4", "l5");
9962306a36Sopenharmony_ci		p1 += 8;
10062306a36Sopenharmony_ci		p2 += 8;
10162306a36Sopenharmony_ci		p3 += 8;
10262306a36Sopenharmony_ci	} while (--lines > 0);
10362306a36Sopenharmony_ci}
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_cistatic void
10662306a36Sopenharmony_cisparc_4(unsigned long bytes, unsigned long * __restrict p1,
10762306a36Sopenharmony_ci	const unsigned long * __restrict p2,
10862306a36Sopenharmony_ci	const unsigned long * __restrict p3,
10962306a36Sopenharmony_ci	const unsigned long * __restrict p4)
11062306a36Sopenharmony_ci{
11162306a36Sopenharmony_ci	int lines = bytes / (sizeof (long)) / 8;
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci	do {
11462306a36Sopenharmony_ci		__asm__ __volatile__(
11562306a36Sopenharmony_ci		  "ldd [%0 + 0x00], %%g2\n\t"
11662306a36Sopenharmony_ci		  "ldd [%0 + 0x08], %%g4\n\t"
11762306a36Sopenharmony_ci		  "ldd [%0 + 0x10], %%o0\n\t"
11862306a36Sopenharmony_ci		  "ldd [%0 + 0x18], %%o2\n\t"
11962306a36Sopenharmony_ci		  "ldd [%1 + 0x00], %%o4\n\t"
12062306a36Sopenharmony_ci		  "ldd [%1 + 0x08], %%l0\n\t"
12162306a36Sopenharmony_ci		  "ldd [%1 + 0x10], %%l2\n\t"
12262306a36Sopenharmony_ci		  "ldd [%1 + 0x18], %%l4\n\t"
12362306a36Sopenharmony_ci		  "xor %%g2, %%o4, %%g2\n\t"
12462306a36Sopenharmony_ci		  "xor %%g3, %%o5, %%g3\n\t"
12562306a36Sopenharmony_ci		  "ldd [%2 + 0x00], %%o4\n\t"
12662306a36Sopenharmony_ci		  "xor %%g4, %%l0, %%g4\n\t"
12762306a36Sopenharmony_ci		  "xor %%g5, %%l1, %%g5\n\t"
12862306a36Sopenharmony_ci		  "ldd [%2 + 0x08], %%l0\n\t"
12962306a36Sopenharmony_ci		  "xor %%o0, %%l2, %%o0\n\t"
13062306a36Sopenharmony_ci		  "xor %%o1, %%l3, %%o1\n\t"
13162306a36Sopenharmony_ci		  "ldd [%2 + 0x10], %%l2\n\t"
13262306a36Sopenharmony_ci		  "xor %%o2, %%l4, %%o2\n\t"
13362306a36Sopenharmony_ci		  "xor %%o3, %%l5, %%o3\n\t"
13462306a36Sopenharmony_ci		  "ldd [%2 + 0x18], %%l4\n\t"
13562306a36Sopenharmony_ci		  "xor %%g2, %%o4, %%g2\n\t"
13662306a36Sopenharmony_ci		  "xor %%g3, %%o5, %%g3\n\t"
13762306a36Sopenharmony_ci		  "ldd [%3 + 0x00], %%o4\n\t"
13862306a36Sopenharmony_ci		  "xor %%g4, %%l0, %%g4\n\t"
13962306a36Sopenharmony_ci		  "xor %%g5, %%l1, %%g5\n\t"
14062306a36Sopenharmony_ci		  "ldd [%3 + 0x08], %%l0\n\t"
14162306a36Sopenharmony_ci		  "xor %%o0, %%l2, %%o0\n\t"
14262306a36Sopenharmony_ci		  "xor %%o1, %%l3, %%o1\n\t"
14362306a36Sopenharmony_ci		  "ldd [%3 + 0x10], %%l2\n\t"
14462306a36Sopenharmony_ci		  "xor %%o2, %%l4, %%o2\n\t"
14562306a36Sopenharmony_ci		  "xor %%o3, %%l5, %%o3\n\t"
14662306a36Sopenharmony_ci		  "ldd [%3 + 0x18], %%l4\n\t"
14762306a36Sopenharmony_ci		  "xor %%g2, %%o4, %%g2\n\t"
14862306a36Sopenharmony_ci		  "xor %%g3, %%o5, %%g3\n\t"
14962306a36Sopenharmony_ci		  "xor %%g4, %%l0, %%g4\n\t"
15062306a36Sopenharmony_ci		  "xor %%g5, %%l1, %%g5\n\t"
15162306a36Sopenharmony_ci		  "xor %%o0, %%l2, %%o0\n\t"
15262306a36Sopenharmony_ci		  "xor %%o1, %%l3, %%o1\n\t"
15362306a36Sopenharmony_ci		  "xor %%o2, %%l4, %%o2\n\t"
15462306a36Sopenharmony_ci		  "xor %%o3, %%l5, %%o3\n\t"
15562306a36Sopenharmony_ci		  "std %%g2, [%0 + 0x00]\n\t"
15662306a36Sopenharmony_ci		  "std %%g4, [%0 + 0x08]\n\t"
15762306a36Sopenharmony_ci		  "std %%o0, [%0 + 0x10]\n\t"
15862306a36Sopenharmony_ci		  "std %%o2, [%0 + 0x18]\n"
15962306a36Sopenharmony_ci		:
16062306a36Sopenharmony_ci		: "r" (p1), "r" (p2), "r" (p3), "r" (p4)
16162306a36Sopenharmony_ci		: "g2", "g3", "g4", "g5",
16262306a36Sopenharmony_ci		  "o0", "o1", "o2", "o3", "o4", "o5",
16362306a36Sopenharmony_ci		  "l0", "l1", "l2", "l3", "l4", "l5");
16462306a36Sopenharmony_ci		p1 += 8;
16562306a36Sopenharmony_ci		p2 += 8;
16662306a36Sopenharmony_ci		p3 += 8;
16762306a36Sopenharmony_ci		p4 += 8;
16862306a36Sopenharmony_ci	} while (--lines > 0);
16962306a36Sopenharmony_ci}
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_cistatic void
17262306a36Sopenharmony_cisparc_5(unsigned long bytes, unsigned long * __restrict p1,
17362306a36Sopenharmony_ci	const unsigned long * __restrict p2,
17462306a36Sopenharmony_ci	const unsigned long * __restrict p3,
17562306a36Sopenharmony_ci	const unsigned long * __restrict p4,
17662306a36Sopenharmony_ci	const unsigned long * __restrict p5)
17762306a36Sopenharmony_ci{
17862306a36Sopenharmony_ci	int lines = bytes / (sizeof (long)) / 8;
17962306a36Sopenharmony_ci
18062306a36Sopenharmony_ci	do {
18162306a36Sopenharmony_ci		__asm__ __volatile__(
18262306a36Sopenharmony_ci		  "ldd [%0 + 0x00], %%g2\n\t"
18362306a36Sopenharmony_ci		  "ldd [%0 + 0x08], %%g4\n\t"
18462306a36Sopenharmony_ci		  "ldd [%0 + 0x10], %%o0\n\t"
18562306a36Sopenharmony_ci		  "ldd [%0 + 0x18], %%o2\n\t"
18662306a36Sopenharmony_ci		  "ldd [%1 + 0x00], %%o4\n\t"
18762306a36Sopenharmony_ci		  "ldd [%1 + 0x08], %%l0\n\t"
18862306a36Sopenharmony_ci		  "ldd [%1 + 0x10], %%l2\n\t"
18962306a36Sopenharmony_ci		  "ldd [%1 + 0x18], %%l4\n\t"
19062306a36Sopenharmony_ci		  "xor %%g2, %%o4, %%g2\n\t"
19162306a36Sopenharmony_ci		  "xor %%g3, %%o5, %%g3\n\t"
19262306a36Sopenharmony_ci		  "ldd [%2 + 0x00], %%o4\n\t"
19362306a36Sopenharmony_ci		  "xor %%g4, %%l0, %%g4\n\t"
19462306a36Sopenharmony_ci		  "xor %%g5, %%l1, %%g5\n\t"
19562306a36Sopenharmony_ci		  "ldd [%2 + 0x08], %%l0\n\t"
19662306a36Sopenharmony_ci		  "xor %%o0, %%l2, %%o0\n\t"
19762306a36Sopenharmony_ci		  "xor %%o1, %%l3, %%o1\n\t"
19862306a36Sopenharmony_ci		  "ldd [%2 + 0x10], %%l2\n\t"
19962306a36Sopenharmony_ci		  "xor %%o2, %%l4, %%o2\n\t"
20062306a36Sopenharmony_ci		  "xor %%o3, %%l5, %%o3\n\t"
20162306a36Sopenharmony_ci		  "ldd [%2 + 0x18], %%l4\n\t"
20262306a36Sopenharmony_ci		  "xor %%g2, %%o4, %%g2\n\t"
20362306a36Sopenharmony_ci		  "xor %%g3, %%o5, %%g3\n\t"
20462306a36Sopenharmony_ci		  "ldd [%3 + 0x00], %%o4\n\t"
20562306a36Sopenharmony_ci		  "xor %%g4, %%l0, %%g4\n\t"
20662306a36Sopenharmony_ci		  "xor %%g5, %%l1, %%g5\n\t"
20762306a36Sopenharmony_ci		  "ldd [%3 + 0x08], %%l0\n\t"
20862306a36Sopenharmony_ci		  "xor %%o0, %%l2, %%o0\n\t"
20962306a36Sopenharmony_ci		  "xor %%o1, %%l3, %%o1\n\t"
21062306a36Sopenharmony_ci		  "ldd [%3 + 0x10], %%l2\n\t"
21162306a36Sopenharmony_ci		  "xor %%o2, %%l4, %%o2\n\t"
21262306a36Sopenharmony_ci		  "xor %%o3, %%l5, %%o3\n\t"
21362306a36Sopenharmony_ci		  "ldd [%3 + 0x18], %%l4\n\t"
21462306a36Sopenharmony_ci		  "xor %%g2, %%o4, %%g2\n\t"
21562306a36Sopenharmony_ci		  "xor %%g3, %%o5, %%g3\n\t"
21662306a36Sopenharmony_ci		  "ldd [%4 + 0x00], %%o4\n\t"
21762306a36Sopenharmony_ci		  "xor %%g4, %%l0, %%g4\n\t"
21862306a36Sopenharmony_ci		  "xor %%g5, %%l1, %%g5\n\t"
21962306a36Sopenharmony_ci		  "ldd [%4 + 0x08], %%l0\n\t"
22062306a36Sopenharmony_ci		  "xor %%o0, %%l2, %%o0\n\t"
22162306a36Sopenharmony_ci		  "xor %%o1, %%l3, %%o1\n\t"
22262306a36Sopenharmony_ci		  "ldd [%4 + 0x10], %%l2\n\t"
22362306a36Sopenharmony_ci		  "xor %%o2, %%l4, %%o2\n\t"
22462306a36Sopenharmony_ci		  "xor %%o3, %%l5, %%o3\n\t"
22562306a36Sopenharmony_ci		  "ldd [%4 + 0x18], %%l4\n\t"
22662306a36Sopenharmony_ci		  "xor %%g2, %%o4, %%g2\n\t"
22762306a36Sopenharmony_ci		  "xor %%g3, %%o5, %%g3\n\t"
22862306a36Sopenharmony_ci		  "xor %%g4, %%l0, %%g4\n\t"
22962306a36Sopenharmony_ci		  "xor %%g5, %%l1, %%g5\n\t"
23062306a36Sopenharmony_ci		  "xor %%o0, %%l2, %%o0\n\t"
23162306a36Sopenharmony_ci		  "xor %%o1, %%l3, %%o1\n\t"
23262306a36Sopenharmony_ci		  "xor %%o2, %%l4, %%o2\n\t"
23362306a36Sopenharmony_ci		  "xor %%o3, %%l5, %%o3\n\t"
23462306a36Sopenharmony_ci		  "std %%g2, [%0 + 0x00]\n\t"
23562306a36Sopenharmony_ci		  "std %%g4, [%0 + 0x08]\n\t"
23662306a36Sopenharmony_ci		  "std %%o0, [%0 + 0x10]\n\t"
23762306a36Sopenharmony_ci		  "std %%o2, [%0 + 0x18]\n"
23862306a36Sopenharmony_ci		:
23962306a36Sopenharmony_ci		: "r" (p1), "r" (p2), "r" (p3), "r" (p4), "r" (p5)
24062306a36Sopenharmony_ci		: "g2", "g3", "g4", "g5",
24162306a36Sopenharmony_ci		  "o0", "o1", "o2", "o3", "o4", "o5",
24262306a36Sopenharmony_ci		  "l0", "l1", "l2", "l3", "l4", "l5");
24362306a36Sopenharmony_ci		p1 += 8;
24462306a36Sopenharmony_ci		p2 += 8;
24562306a36Sopenharmony_ci		p3 += 8;
24662306a36Sopenharmony_ci		p4 += 8;
24762306a36Sopenharmony_ci		p5 += 8;
24862306a36Sopenharmony_ci	} while (--lines > 0);
24962306a36Sopenharmony_ci}
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_cistatic struct xor_block_template xor_block_SPARC = {
25262306a36Sopenharmony_ci	.name	= "SPARC",
25362306a36Sopenharmony_ci	.do_2	= sparc_2,
25462306a36Sopenharmony_ci	.do_3	= sparc_3,
25562306a36Sopenharmony_ci	.do_4	= sparc_4,
25662306a36Sopenharmony_ci	.do_5	= sparc_5,
25762306a36Sopenharmony_ci};
25862306a36Sopenharmony_ci
25962306a36Sopenharmony_ci/* For grins, also test the generic routines.  */
26062306a36Sopenharmony_ci#include <asm-generic/xor.h>
26162306a36Sopenharmony_ci
26262306a36Sopenharmony_ci#undef XOR_TRY_TEMPLATES
26362306a36Sopenharmony_ci#define XOR_TRY_TEMPLATES				\
26462306a36Sopenharmony_ci	do {						\
26562306a36Sopenharmony_ci		xor_speed(&xor_block_8regs);		\
26662306a36Sopenharmony_ci		xor_speed(&xor_block_32regs);		\
26762306a36Sopenharmony_ci		xor_speed(&xor_block_SPARC);		\
26862306a36Sopenharmony_ci	} while (0)
269