18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * include/asm/xor.h
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Optimized RAID-5 checksumming functions for 32-bit Sparc.
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci/*
98c2ecf20Sopenharmony_ci * High speed xor_block operation for RAID4/5 utilizing the
108c2ecf20Sopenharmony_ci * ldd/std SPARC instructions.
118c2ecf20Sopenharmony_ci *
128c2ecf20Sopenharmony_ci * Copyright (C) 1999 Jakub Jelinek (jj@ultra.linux.cz)
138c2ecf20Sopenharmony_ci */
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_cistatic void
168c2ecf20Sopenharmony_cisparc_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
178c2ecf20Sopenharmony_ci{
188c2ecf20Sopenharmony_ci	int lines = bytes / (sizeof (long)) / 8;
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ci	do {
218c2ecf20Sopenharmony_ci		__asm__ __volatile__(
228c2ecf20Sopenharmony_ci		  "ldd [%0 + 0x00], %%g2\n\t"
238c2ecf20Sopenharmony_ci		  "ldd [%0 + 0x08], %%g4\n\t"
248c2ecf20Sopenharmony_ci		  "ldd [%0 + 0x10], %%o0\n\t"
258c2ecf20Sopenharmony_ci		  "ldd [%0 + 0x18], %%o2\n\t"
268c2ecf20Sopenharmony_ci		  "ldd [%1 + 0x00], %%o4\n\t"
278c2ecf20Sopenharmony_ci		  "ldd [%1 + 0x08], %%l0\n\t"
288c2ecf20Sopenharmony_ci		  "ldd [%1 + 0x10], %%l2\n\t"
298c2ecf20Sopenharmony_ci		  "ldd [%1 + 0x18], %%l4\n\t"
308c2ecf20Sopenharmony_ci		  "xor %%g2, %%o4, %%g2\n\t"
318c2ecf20Sopenharmony_ci		  "xor %%g3, %%o5, %%g3\n\t"
328c2ecf20Sopenharmony_ci		  "xor %%g4, %%l0, %%g4\n\t"
338c2ecf20Sopenharmony_ci		  "xor %%g5, %%l1, %%g5\n\t"
348c2ecf20Sopenharmony_ci		  "xor %%o0, %%l2, %%o0\n\t"
358c2ecf20Sopenharmony_ci		  "xor %%o1, %%l3, %%o1\n\t"
368c2ecf20Sopenharmony_ci		  "xor %%o2, %%l4, %%o2\n\t"
378c2ecf20Sopenharmony_ci		  "xor %%o3, %%l5, %%o3\n\t"
388c2ecf20Sopenharmony_ci		  "std %%g2, [%0 + 0x00]\n\t"
398c2ecf20Sopenharmony_ci		  "std %%g4, [%0 + 0x08]\n\t"
408c2ecf20Sopenharmony_ci		  "std %%o0, [%0 + 0x10]\n\t"
418c2ecf20Sopenharmony_ci		  "std %%o2, [%0 + 0x18]\n"
428c2ecf20Sopenharmony_ci		:
438c2ecf20Sopenharmony_ci		: "r" (p1), "r" (p2)
448c2ecf20Sopenharmony_ci		: "g2", "g3", "g4", "g5",
458c2ecf20Sopenharmony_ci		  "o0", "o1", "o2", "o3", "o4", "o5",
468c2ecf20Sopenharmony_ci		  "l0", "l1", "l2", "l3", "l4", "l5");
478c2ecf20Sopenharmony_ci		p1 += 8;
488c2ecf20Sopenharmony_ci		p2 += 8;
498c2ecf20Sopenharmony_ci	} while (--lines > 0);
508c2ecf20Sopenharmony_ci}
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_cistatic void
538c2ecf20Sopenharmony_cisparc_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
548c2ecf20Sopenharmony_ci	unsigned long *p3)
558c2ecf20Sopenharmony_ci{
568c2ecf20Sopenharmony_ci	int lines = bytes / (sizeof (long)) / 8;
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_ci	do {
598c2ecf20Sopenharmony_ci		__asm__ __volatile__(
608c2ecf20Sopenharmony_ci		  "ldd [%0 + 0x00], %%g2\n\t"
618c2ecf20Sopenharmony_ci		  "ldd [%0 + 0x08], %%g4\n\t"
628c2ecf20Sopenharmony_ci		  "ldd [%0 + 0x10], %%o0\n\t"
638c2ecf20Sopenharmony_ci		  "ldd [%0 + 0x18], %%o2\n\t"
648c2ecf20Sopenharmony_ci		  "ldd [%1 + 0x00], %%o4\n\t"
658c2ecf20Sopenharmony_ci		  "ldd [%1 + 0x08], %%l0\n\t"
668c2ecf20Sopenharmony_ci		  "ldd [%1 + 0x10], %%l2\n\t"
678c2ecf20Sopenharmony_ci		  "ldd [%1 + 0x18], %%l4\n\t"
688c2ecf20Sopenharmony_ci		  "xor %%g2, %%o4, %%g2\n\t"
698c2ecf20Sopenharmony_ci		  "xor %%g3, %%o5, %%g3\n\t"
708c2ecf20Sopenharmony_ci		  "ldd [%2 + 0x00], %%o4\n\t"
718c2ecf20Sopenharmony_ci		  "xor %%g4, %%l0, %%g4\n\t"
728c2ecf20Sopenharmony_ci		  "xor %%g5, %%l1, %%g5\n\t"
738c2ecf20Sopenharmony_ci		  "ldd [%2 + 0x08], %%l0\n\t"
748c2ecf20Sopenharmony_ci		  "xor %%o0, %%l2, %%o0\n\t"
758c2ecf20Sopenharmony_ci		  "xor %%o1, %%l3, %%o1\n\t"
768c2ecf20Sopenharmony_ci		  "ldd [%2 + 0x10], %%l2\n\t"
778c2ecf20Sopenharmony_ci		  "xor %%o2, %%l4, %%o2\n\t"
788c2ecf20Sopenharmony_ci		  "xor %%o3, %%l5, %%o3\n\t"
798c2ecf20Sopenharmony_ci		  "ldd [%2 + 0x18], %%l4\n\t"
808c2ecf20Sopenharmony_ci		  "xor %%g2, %%o4, %%g2\n\t"
818c2ecf20Sopenharmony_ci		  "xor %%g3, %%o5, %%g3\n\t"
828c2ecf20Sopenharmony_ci		  "xor %%g4, %%l0, %%g4\n\t"
838c2ecf20Sopenharmony_ci		  "xor %%g5, %%l1, %%g5\n\t"
848c2ecf20Sopenharmony_ci		  "xor %%o0, %%l2, %%o0\n\t"
858c2ecf20Sopenharmony_ci		  "xor %%o1, %%l3, %%o1\n\t"
868c2ecf20Sopenharmony_ci		  "xor %%o2, %%l4, %%o2\n\t"
878c2ecf20Sopenharmony_ci		  "xor %%o3, %%l5, %%o3\n\t"
888c2ecf20Sopenharmony_ci		  "std %%g2, [%0 + 0x00]\n\t"
898c2ecf20Sopenharmony_ci		  "std %%g4, [%0 + 0x08]\n\t"
908c2ecf20Sopenharmony_ci		  "std %%o0, [%0 + 0x10]\n\t"
918c2ecf20Sopenharmony_ci		  "std %%o2, [%0 + 0x18]\n"
928c2ecf20Sopenharmony_ci		:
938c2ecf20Sopenharmony_ci		: "r" (p1), "r" (p2), "r" (p3)
948c2ecf20Sopenharmony_ci		: "g2", "g3", "g4", "g5",
958c2ecf20Sopenharmony_ci		  "o0", "o1", "o2", "o3", "o4", "o5",
968c2ecf20Sopenharmony_ci		  "l0", "l1", "l2", "l3", "l4", "l5");
978c2ecf20Sopenharmony_ci		p1 += 8;
988c2ecf20Sopenharmony_ci		p2 += 8;
998c2ecf20Sopenharmony_ci		p3 += 8;
1008c2ecf20Sopenharmony_ci	} while (--lines > 0);
1018c2ecf20Sopenharmony_ci}
1028c2ecf20Sopenharmony_ci
1038c2ecf20Sopenharmony_cistatic void
1048c2ecf20Sopenharmony_cisparc_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
1058c2ecf20Sopenharmony_ci	unsigned long *p3, unsigned long *p4)
1068c2ecf20Sopenharmony_ci{
1078c2ecf20Sopenharmony_ci	int lines = bytes / (sizeof (long)) / 8;
1088c2ecf20Sopenharmony_ci
1098c2ecf20Sopenharmony_ci	do {
1108c2ecf20Sopenharmony_ci		__asm__ __volatile__(
1118c2ecf20Sopenharmony_ci		  "ldd [%0 + 0x00], %%g2\n\t"
1128c2ecf20Sopenharmony_ci		  "ldd [%0 + 0x08], %%g4\n\t"
1138c2ecf20Sopenharmony_ci		  "ldd [%0 + 0x10], %%o0\n\t"
1148c2ecf20Sopenharmony_ci		  "ldd [%0 + 0x18], %%o2\n\t"
1158c2ecf20Sopenharmony_ci		  "ldd [%1 + 0x00], %%o4\n\t"
1168c2ecf20Sopenharmony_ci		  "ldd [%1 + 0x08], %%l0\n\t"
1178c2ecf20Sopenharmony_ci		  "ldd [%1 + 0x10], %%l2\n\t"
1188c2ecf20Sopenharmony_ci		  "ldd [%1 + 0x18], %%l4\n\t"
1198c2ecf20Sopenharmony_ci		  "xor %%g2, %%o4, %%g2\n\t"
1208c2ecf20Sopenharmony_ci		  "xor %%g3, %%o5, %%g3\n\t"
1218c2ecf20Sopenharmony_ci		  "ldd [%2 + 0x00], %%o4\n\t"
1228c2ecf20Sopenharmony_ci		  "xor %%g4, %%l0, %%g4\n\t"
1238c2ecf20Sopenharmony_ci		  "xor %%g5, %%l1, %%g5\n\t"
1248c2ecf20Sopenharmony_ci		  "ldd [%2 + 0x08], %%l0\n\t"
1258c2ecf20Sopenharmony_ci		  "xor %%o0, %%l2, %%o0\n\t"
1268c2ecf20Sopenharmony_ci		  "xor %%o1, %%l3, %%o1\n\t"
1278c2ecf20Sopenharmony_ci		  "ldd [%2 + 0x10], %%l2\n\t"
1288c2ecf20Sopenharmony_ci		  "xor %%o2, %%l4, %%o2\n\t"
1298c2ecf20Sopenharmony_ci		  "xor %%o3, %%l5, %%o3\n\t"
1308c2ecf20Sopenharmony_ci		  "ldd [%2 + 0x18], %%l4\n\t"
1318c2ecf20Sopenharmony_ci		  "xor %%g2, %%o4, %%g2\n\t"
1328c2ecf20Sopenharmony_ci		  "xor %%g3, %%o5, %%g3\n\t"
1338c2ecf20Sopenharmony_ci		  "ldd [%3 + 0x00], %%o4\n\t"
1348c2ecf20Sopenharmony_ci		  "xor %%g4, %%l0, %%g4\n\t"
1358c2ecf20Sopenharmony_ci		  "xor %%g5, %%l1, %%g5\n\t"
1368c2ecf20Sopenharmony_ci		  "ldd [%3 + 0x08], %%l0\n\t"
1378c2ecf20Sopenharmony_ci		  "xor %%o0, %%l2, %%o0\n\t"
1388c2ecf20Sopenharmony_ci		  "xor %%o1, %%l3, %%o1\n\t"
1398c2ecf20Sopenharmony_ci		  "ldd [%3 + 0x10], %%l2\n\t"
1408c2ecf20Sopenharmony_ci		  "xor %%o2, %%l4, %%o2\n\t"
1418c2ecf20Sopenharmony_ci		  "xor %%o3, %%l5, %%o3\n\t"
1428c2ecf20Sopenharmony_ci		  "ldd [%3 + 0x18], %%l4\n\t"
1438c2ecf20Sopenharmony_ci		  "xor %%g2, %%o4, %%g2\n\t"
1448c2ecf20Sopenharmony_ci		  "xor %%g3, %%o5, %%g3\n\t"
1458c2ecf20Sopenharmony_ci		  "xor %%g4, %%l0, %%g4\n\t"
1468c2ecf20Sopenharmony_ci		  "xor %%g5, %%l1, %%g5\n\t"
1478c2ecf20Sopenharmony_ci		  "xor %%o0, %%l2, %%o0\n\t"
1488c2ecf20Sopenharmony_ci		  "xor %%o1, %%l3, %%o1\n\t"
1498c2ecf20Sopenharmony_ci		  "xor %%o2, %%l4, %%o2\n\t"
1508c2ecf20Sopenharmony_ci		  "xor %%o3, %%l5, %%o3\n\t"
1518c2ecf20Sopenharmony_ci		  "std %%g2, [%0 + 0x00]\n\t"
1528c2ecf20Sopenharmony_ci		  "std %%g4, [%0 + 0x08]\n\t"
1538c2ecf20Sopenharmony_ci		  "std %%o0, [%0 + 0x10]\n\t"
1548c2ecf20Sopenharmony_ci		  "std %%o2, [%0 + 0x18]\n"
1558c2ecf20Sopenharmony_ci		:
1568c2ecf20Sopenharmony_ci		: "r" (p1), "r" (p2), "r" (p3), "r" (p4)
1578c2ecf20Sopenharmony_ci		: "g2", "g3", "g4", "g5",
1588c2ecf20Sopenharmony_ci		  "o0", "o1", "o2", "o3", "o4", "o5",
1598c2ecf20Sopenharmony_ci		  "l0", "l1", "l2", "l3", "l4", "l5");
1608c2ecf20Sopenharmony_ci		p1 += 8;
1618c2ecf20Sopenharmony_ci		p2 += 8;
1628c2ecf20Sopenharmony_ci		p3 += 8;
1638c2ecf20Sopenharmony_ci		p4 += 8;
1648c2ecf20Sopenharmony_ci	} while (--lines > 0);
1658c2ecf20Sopenharmony_ci}
1668c2ecf20Sopenharmony_ci
1678c2ecf20Sopenharmony_cistatic void
1688c2ecf20Sopenharmony_cisparc_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
1698c2ecf20Sopenharmony_ci	unsigned long *p3, unsigned long *p4, unsigned long *p5)
1708c2ecf20Sopenharmony_ci{
1718c2ecf20Sopenharmony_ci	int lines = bytes / (sizeof (long)) / 8;
1728c2ecf20Sopenharmony_ci
1738c2ecf20Sopenharmony_ci	do {
1748c2ecf20Sopenharmony_ci		__asm__ __volatile__(
1758c2ecf20Sopenharmony_ci		  "ldd [%0 + 0x00], %%g2\n\t"
1768c2ecf20Sopenharmony_ci		  "ldd [%0 + 0x08], %%g4\n\t"
1778c2ecf20Sopenharmony_ci		  "ldd [%0 + 0x10], %%o0\n\t"
1788c2ecf20Sopenharmony_ci		  "ldd [%0 + 0x18], %%o2\n\t"
1798c2ecf20Sopenharmony_ci		  "ldd [%1 + 0x00], %%o4\n\t"
1808c2ecf20Sopenharmony_ci		  "ldd [%1 + 0x08], %%l0\n\t"
1818c2ecf20Sopenharmony_ci		  "ldd [%1 + 0x10], %%l2\n\t"
1828c2ecf20Sopenharmony_ci		  "ldd [%1 + 0x18], %%l4\n\t"
1838c2ecf20Sopenharmony_ci		  "xor %%g2, %%o4, %%g2\n\t"
1848c2ecf20Sopenharmony_ci		  "xor %%g3, %%o5, %%g3\n\t"
1858c2ecf20Sopenharmony_ci		  "ldd [%2 + 0x00], %%o4\n\t"
1868c2ecf20Sopenharmony_ci		  "xor %%g4, %%l0, %%g4\n\t"
1878c2ecf20Sopenharmony_ci		  "xor %%g5, %%l1, %%g5\n\t"
1888c2ecf20Sopenharmony_ci		  "ldd [%2 + 0x08], %%l0\n\t"
1898c2ecf20Sopenharmony_ci		  "xor %%o0, %%l2, %%o0\n\t"
1908c2ecf20Sopenharmony_ci		  "xor %%o1, %%l3, %%o1\n\t"
1918c2ecf20Sopenharmony_ci		  "ldd [%2 + 0x10], %%l2\n\t"
1928c2ecf20Sopenharmony_ci		  "xor %%o2, %%l4, %%o2\n\t"
1938c2ecf20Sopenharmony_ci		  "xor %%o3, %%l5, %%o3\n\t"
1948c2ecf20Sopenharmony_ci		  "ldd [%2 + 0x18], %%l4\n\t"
1958c2ecf20Sopenharmony_ci		  "xor %%g2, %%o4, %%g2\n\t"
1968c2ecf20Sopenharmony_ci		  "xor %%g3, %%o5, %%g3\n\t"
1978c2ecf20Sopenharmony_ci		  "ldd [%3 + 0x00], %%o4\n\t"
1988c2ecf20Sopenharmony_ci		  "xor %%g4, %%l0, %%g4\n\t"
1998c2ecf20Sopenharmony_ci		  "xor %%g5, %%l1, %%g5\n\t"
2008c2ecf20Sopenharmony_ci		  "ldd [%3 + 0x08], %%l0\n\t"
2018c2ecf20Sopenharmony_ci		  "xor %%o0, %%l2, %%o0\n\t"
2028c2ecf20Sopenharmony_ci		  "xor %%o1, %%l3, %%o1\n\t"
2038c2ecf20Sopenharmony_ci		  "ldd [%3 + 0x10], %%l2\n\t"
2048c2ecf20Sopenharmony_ci		  "xor %%o2, %%l4, %%o2\n\t"
2058c2ecf20Sopenharmony_ci		  "xor %%o3, %%l5, %%o3\n\t"
2068c2ecf20Sopenharmony_ci		  "ldd [%3 + 0x18], %%l4\n\t"
2078c2ecf20Sopenharmony_ci		  "xor %%g2, %%o4, %%g2\n\t"
2088c2ecf20Sopenharmony_ci		  "xor %%g3, %%o5, %%g3\n\t"
2098c2ecf20Sopenharmony_ci		  "ldd [%4 + 0x00], %%o4\n\t"
2108c2ecf20Sopenharmony_ci		  "xor %%g4, %%l0, %%g4\n\t"
2118c2ecf20Sopenharmony_ci		  "xor %%g5, %%l1, %%g5\n\t"
2128c2ecf20Sopenharmony_ci		  "ldd [%4 + 0x08], %%l0\n\t"
2138c2ecf20Sopenharmony_ci		  "xor %%o0, %%l2, %%o0\n\t"
2148c2ecf20Sopenharmony_ci		  "xor %%o1, %%l3, %%o1\n\t"
2158c2ecf20Sopenharmony_ci		  "ldd [%4 + 0x10], %%l2\n\t"
2168c2ecf20Sopenharmony_ci		  "xor %%o2, %%l4, %%o2\n\t"
2178c2ecf20Sopenharmony_ci		  "xor %%o3, %%l5, %%o3\n\t"
2188c2ecf20Sopenharmony_ci		  "ldd [%4 + 0x18], %%l4\n\t"
2198c2ecf20Sopenharmony_ci		  "xor %%g2, %%o4, %%g2\n\t"
2208c2ecf20Sopenharmony_ci		  "xor %%g3, %%o5, %%g3\n\t"
2218c2ecf20Sopenharmony_ci		  "xor %%g4, %%l0, %%g4\n\t"
2228c2ecf20Sopenharmony_ci		  "xor %%g5, %%l1, %%g5\n\t"
2238c2ecf20Sopenharmony_ci		  "xor %%o0, %%l2, %%o0\n\t"
2248c2ecf20Sopenharmony_ci		  "xor %%o1, %%l3, %%o1\n\t"
2258c2ecf20Sopenharmony_ci		  "xor %%o2, %%l4, %%o2\n\t"
2268c2ecf20Sopenharmony_ci		  "xor %%o3, %%l5, %%o3\n\t"
2278c2ecf20Sopenharmony_ci		  "std %%g2, [%0 + 0x00]\n\t"
2288c2ecf20Sopenharmony_ci		  "std %%g4, [%0 + 0x08]\n\t"
2298c2ecf20Sopenharmony_ci		  "std %%o0, [%0 + 0x10]\n\t"
2308c2ecf20Sopenharmony_ci		  "std %%o2, [%0 + 0x18]\n"
2318c2ecf20Sopenharmony_ci		:
2328c2ecf20Sopenharmony_ci		: "r" (p1), "r" (p2), "r" (p3), "r" (p4), "r" (p5)
2338c2ecf20Sopenharmony_ci		: "g2", "g3", "g4", "g5",
2348c2ecf20Sopenharmony_ci		  "o0", "o1", "o2", "o3", "o4", "o5",
2358c2ecf20Sopenharmony_ci		  "l0", "l1", "l2", "l3", "l4", "l5");
2368c2ecf20Sopenharmony_ci		p1 += 8;
2378c2ecf20Sopenharmony_ci		p2 += 8;
2388c2ecf20Sopenharmony_ci		p3 += 8;
2398c2ecf20Sopenharmony_ci		p4 += 8;
2408c2ecf20Sopenharmony_ci		p5 += 8;
2418c2ecf20Sopenharmony_ci	} while (--lines > 0);
2428c2ecf20Sopenharmony_ci}
2438c2ecf20Sopenharmony_ci
2448c2ecf20Sopenharmony_cistatic struct xor_block_template xor_block_SPARC = {
2458c2ecf20Sopenharmony_ci	.name	= "SPARC",
2468c2ecf20Sopenharmony_ci	.do_2	= sparc_2,
2478c2ecf20Sopenharmony_ci	.do_3	= sparc_3,
2488c2ecf20Sopenharmony_ci	.do_4	= sparc_4,
2498c2ecf20Sopenharmony_ci	.do_5	= sparc_5,
2508c2ecf20Sopenharmony_ci};
2518c2ecf20Sopenharmony_ci
2528c2ecf20Sopenharmony_ci/* For grins, also test the generic routines.  */
2538c2ecf20Sopenharmony_ci#include <asm-generic/xor.h>
2548c2ecf20Sopenharmony_ci
2558c2ecf20Sopenharmony_ci#undef XOR_TRY_TEMPLATES
2568c2ecf20Sopenharmony_ci#define XOR_TRY_TEMPLATES				\
2578c2ecf20Sopenharmony_ci	do {						\
2588c2ecf20Sopenharmony_ci		xor_speed(&xor_block_8regs);		\
2598c2ecf20Sopenharmony_ci		xor_speed(&xor_block_32regs);		\
2608c2ecf20Sopenharmony_ci		xor_speed(&xor_block_SPARC);		\
2618c2ecf20Sopenharmony_ci	} while (0)
262