1/*
2 * include/asm/xor.h
3 *
4 * Optimized RAID-5 checksumming functions for 32-bit Sparc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * You should have received a copy of the GNU General Public License
12 * (for example /usr/src/linux/COPYING); if not, write to the Free
13 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
14 */
15
16/*
17 * High speed xor_block operation for RAID4/5 utilizing the
18 * ldd/std SPARC instructions.
19 *
20 * Copyright (C) 1999 Jakub Jelinek (jj@ultra.linux.cz)
21 */
22
23static void
24sparc_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
25{
26	int lines = bytes / (sizeof (long)) / 8;
27
28	do {
29		__asm__ __volatile__(
30		  "ldd [%0 + 0x00], %%g2\n\t"
31		  "ldd [%0 + 0x08], %%g4\n\t"
32		  "ldd [%0 + 0x10], %%o0\n\t"
33		  "ldd [%0 + 0x18], %%o2\n\t"
34		  "ldd [%1 + 0x00], %%o4\n\t"
35		  "ldd [%1 + 0x08], %%l0\n\t"
36		  "ldd [%1 + 0x10], %%l2\n\t"
37		  "ldd [%1 + 0x18], %%l4\n\t"
38		  "xor %%g2, %%o4, %%g2\n\t"
39		  "xor %%g3, %%o5, %%g3\n\t"
40		  "xor %%g4, %%l0, %%g4\n\t"
41		  "xor %%g5, %%l1, %%g5\n\t"
42		  "xor %%o0, %%l2, %%o0\n\t"
43		  "xor %%o1, %%l3, %%o1\n\t"
44		  "xor %%o2, %%l4, %%o2\n\t"
45		  "xor %%o3, %%l5, %%o3\n\t"
46		  "std %%g2, [%0 + 0x00]\n\t"
47		  "std %%g4, [%0 + 0x08]\n\t"
48		  "std %%o0, [%0 + 0x10]\n\t"
49		  "std %%o2, [%0 + 0x18]\n"
50		:
51		: "r" (p1), "r" (p2)
52		: "g2", "g3", "g4", "g5",
53		  "o0", "o1", "o2", "o3", "o4", "o5",
54		  "l0", "l1", "l2", "l3", "l4", "l5");
55		p1 += 8;
56		p2 += 8;
57	} while (--lines > 0);
58}
59
60static void
61sparc_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
62	unsigned long *p3)
63{
64	int lines = bytes / (sizeof (long)) / 8;
65
66	do {
67		__asm__ __volatile__(
68		  "ldd [%0 + 0x00], %%g2\n\t"
69		  "ldd [%0 + 0x08], %%g4\n\t"
70		  "ldd [%0 + 0x10], %%o0\n\t"
71		  "ldd [%0 + 0x18], %%o2\n\t"
72		  "ldd [%1 + 0x00], %%o4\n\t"
73		  "ldd [%1 + 0x08], %%l0\n\t"
74		  "ldd [%1 + 0x10], %%l2\n\t"
75		  "ldd [%1 + 0x18], %%l4\n\t"
76		  "xor %%g2, %%o4, %%g2\n\t"
77		  "xor %%g3, %%o5, %%g3\n\t"
78		  "ldd [%2 + 0x00], %%o4\n\t"
79		  "xor %%g4, %%l0, %%g4\n\t"
80		  "xor %%g5, %%l1, %%g5\n\t"
81		  "ldd [%2 + 0x08], %%l0\n\t"
82		  "xor %%o0, %%l2, %%o0\n\t"
83		  "xor %%o1, %%l3, %%o1\n\t"
84		  "ldd [%2 + 0x10], %%l2\n\t"
85		  "xor %%o2, %%l4, %%o2\n\t"
86		  "xor %%o3, %%l5, %%o3\n\t"
87		  "ldd [%2 + 0x18], %%l4\n\t"
88		  "xor %%g2, %%o4, %%g2\n\t"
89		  "xor %%g3, %%o5, %%g3\n\t"
90		  "xor %%g4, %%l0, %%g4\n\t"
91		  "xor %%g5, %%l1, %%g5\n\t"
92		  "xor %%o0, %%l2, %%o0\n\t"
93		  "xor %%o1, %%l3, %%o1\n\t"
94		  "xor %%o2, %%l4, %%o2\n\t"
95		  "xor %%o3, %%l5, %%o3\n\t"
96		  "std %%g2, [%0 + 0x00]\n\t"
97		  "std %%g4, [%0 + 0x08]\n\t"
98		  "std %%o0, [%0 + 0x10]\n\t"
99		  "std %%o2, [%0 + 0x18]\n"
100		:
101		: "r" (p1), "r" (p2), "r" (p3)
102		: "g2", "g3", "g4", "g5",
103		  "o0", "o1", "o2", "o3", "o4", "o5",
104		  "l0", "l1", "l2", "l3", "l4", "l5");
105		p1 += 8;
106		p2 += 8;
107		p3 += 8;
108	} while (--lines > 0);
109}
110
111static void
112sparc_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
113	unsigned long *p3, unsigned long *p4)
114{
115	int lines = bytes / (sizeof (long)) / 8;
116
117	do {
118		__asm__ __volatile__(
119		  "ldd [%0 + 0x00], %%g2\n\t"
120		  "ldd [%0 + 0x08], %%g4\n\t"
121		  "ldd [%0 + 0x10], %%o0\n\t"
122		  "ldd [%0 + 0x18], %%o2\n\t"
123		  "ldd [%1 + 0x00], %%o4\n\t"
124		  "ldd [%1 + 0x08], %%l0\n\t"
125		  "ldd [%1 + 0x10], %%l2\n\t"
126		  "ldd [%1 + 0x18], %%l4\n\t"
127		  "xor %%g2, %%o4, %%g2\n\t"
128		  "xor %%g3, %%o5, %%g3\n\t"
129		  "ldd [%2 + 0x00], %%o4\n\t"
130		  "xor %%g4, %%l0, %%g4\n\t"
131		  "xor %%g5, %%l1, %%g5\n\t"
132		  "ldd [%2 + 0x08], %%l0\n\t"
133		  "xor %%o0, %%l2, %%o0\n\t"
134		  "xor %%o1, %%l3, %%o1\n\t"
135		  "ldd [%2 + 0x10], %%l2\n\t"
136		  "xor %%o2, %%l4, %%o2\n\t"
137		  "xor %%o3, %%l5, %%o3\n\t"
138		  "ldd [%2 + 0x18], %%l4\n\t"
139		  "xor %%g2, %%o4, %%g2\n\t"
140		  "xor %%g3, %%o5, %%g3\n\t"
141		  "ldd [%3 + 0x00], %%o4\n\t"
142		  "xor %%g4, %%l0, %%g4\n\t"
143		  "xor %%g5, %%l1, %%g5\n\t"
144		  "ldd [%3 + 0x08], %%l0\n\t"
145		  "xor %%o0, %%l2, %%o0\n\t"
146		  "xor %%o1, %%l3, %%o1\n\t"
147		  "ldd [%3 + 0x10], %%l2\n\t"
148		  "xor %%o2, %%l4, %%o2\n\t"
149		  "xor %%o3, %%l5, %%o3\n\t"
150		  "ldd [%3 + 0x18], %%l4\n\t"
151		  "xor %%g2, %%o4, %%g2\n\t"
152		  "xor %%g3, %%o5, %%g3\n\t"
153		  "xor %%g4, %%l0, %%g4\n\t"
154		  "xor %%g5, %%l1, %%g5\n\t"
155		  "xor %%o0, %%l2, %%o0\n\t"
156		  "xor %%o1, %%l3, %%o1\n\t"
157		  "xor %%o2, %%l4, %%o2\n\t"
158		  "xor %%o3, %%l5, %%o3\n\t"
159		  "std %%g2, [%0 + 0x00]\n\t"
160		  "std %%g4, [%0 + 0x08]\n\t"
161		  "std %%o0, [%0 + 0x10]\n\t"
162		  "std %%o2, [%0 + 0x18]\n"
163		:
164		: "r" (p1), "r" (p2), "r" (p3), "r" (p4)
165		: "g2", "g3", "g4", "g5",
166		  "o0", "o1", "o2", "o3", "o4", "o5",
167		  "l0", "l1", "l2", "l3", "l4", "l5");
168		p1 += 8;
169		p2 += 8;
170		p3 += 8;
171		p4 += 8;
172	} while (--lines > 0);
173}
174
175static void
176sparc_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
177	unsigned long *p3, unsigned long *p4, unsigned long *p5)
178{
179	int lines = bytes / (sizeof (long)) / 8;
180
181	do {
182		__asm__ __volatile__(
183		  "ldd [%0 + 0x00], %%g2\n\t"
184		  "ldd [%0 + 0x08], %%g4\n\t"
185		  "ldd [%0 + 0x10], %%o0\n\t"
186		  "ldd [%0 + 0x18], %%o2\n\t"
187		  "ldd [%1 + 0x00], %%o4\n\t"
188		  "ldd [%1 + 0x08], %%l0\n\t"
189		  "ldd [%1 + 0x10], %%l2\n\t"
190		  "ldd [%1 + 0x18], %%l4\n\t"
191		  "xor %%g2, %%o4, %%g2\n\t"
192		  "xor %%g3, %%o5, %%g3\n\t"
193		  "ldd [%2 + 0x00], %%o4\n\t"
194		  "xor %%g4, %%l0, %%g4\n\t"
195		  "xor %%g5, %%l1, %%g5\n\t"
196		  "ldd [%2 + 0x08], %%l0\n\t"
197		  "xor %%o0, %%l2, %%o0\n\t"
198		  "xor %%o1, %%l3, %%o1\n\t"
199		  "ldd [%2 + 0x10], %%l2\n\t"
200		  "xor %%o2, %%l4, %%o2\n\t"
201		  "xor %%o3, %%l5, %%o3\n\t"
202		  "ldd [%2 + 0x18], %%l4\n\t"
203		  "xor %%g2, %%o4, %%g2\n\t"
204		  "xor %%g3, %%o5, %%g3\n\t"
205		  "ldd [%3 + 0x00], %%o4\n\t"
206		  "xor %%g4, %%l0, %%g4\n\t"
207		  "xor %%g5, %%l1, %%g5\n\t"
208		  "ldd [%3 + 0x08], %%l0\n\t"
209		  "xor %%o0, %%l2, %%o0\n\t"
210		  "xor %%o1, %%l3, %%o1\n\t"
211		  "ldd [%3 + 0x10], %%l2\n\t"
212		  "xor %%o2, %%l4, %%o2\n\t"
213		  "xor %%o3, %%l5, %%o3\n\t"
214		  "ldd [%3 + 0x18], %%l4\n\t"
215		  "xor %%g2, %%o4, %%g2\n\t"
216		  "xor %%g3, %%o5, %%g3\n\t"
217		  "ldd [%4 + 0x00], %%o4\n\t"
218		  "xor %%g4, %%l0, %%g4\n\t"
219		  "xor %%g5, %%l1, %%g5\n\t"
220		  "ldd [%4 + 0x08], %%l0\n\t"
221		  "xor %%o0, %%l2, %%o0\n\t"
222		  "xor %%o1, %%l3, %%o1\n\t"
223		  "ldd [%4 + 0x10], %%l2\n\t"
224		  "xor %%o2, %%l4, %%o2\n\t"
225		  "xor %%o3, %%l5, %%o3\n\t"
226		  "ldd [%4 + 0x18], %%l4\n\t"
227		  "xor %%g2, %%o4, %%g2\n\t"
228		  "xor %%g3, %%o5, %%g3\n\t"
229		  "xor %%g4, %%l0, %%g4\n\t"
230		  "xor %%g5, %%l1, %%g5\n\t"
231		  "xor %%o0, %%l2, %%o0\n\t"
232		  "xor %%o1, %%l3, %%o1\n\t"
233		  "xor %%o2, %%l4, %%o2\n\t"
234		  "xor %%o3, %%l5, %%o3\n\t"
235		  "std %%g2, [%0 + 0x00]\n\t"
236		  "std %%g4, [%0 + 0x08]\n\t"
237		  "std %%o0, [%0 + 0x10]\n\t"
238		  "std %%o2, [%0 + 0x18]\n"
239		:
240		: "r" (p1), "r" (p2), "r" (p3), "r" (p4), "r" (p5)
241		: "g2", "g3", "g4", "g5",
242		  "o0", "o1", "o2", "o3", "o4", "o5",
243		  "l0", "l1", "l2", "l3", "l4", "l5");
244		p1 += 8;
245		p2 += 8;
246		p3 += 8;
247		p4 += 8;
248		p5 += 8;
249	} while (--lines > 0);
250}
251
252static struct xor_block_template xor_block_SPARC = {
253	.name	= "SPARC",
254	.do_2	= sparc_2,
255	.do_3	= sparc_3,
256	.do_4	= sparc_4,
257	.do_5	= sparc_5,
258};
259
260/* For grins, also test the generic routines.  */
261#include <asm-generic/xor.h>
262
263#undef XOR_TRY_TEMPLATES
264#define XOR_TRY_TEMPLATES				\
265	do {						\
266		xor_speed(&xor_block_8regs);		\
267		xor_speed(&xor_block_32regs);		\
268		xor_speed(&xor_block_SPARC);		\
269	} while (0)
270