xref: /openbmc/linux/arch/sparc/include/asm/xor_32.h (revision a36954f5)
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 
23 static void
24 sparc_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 
60 static void
61 sparc_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 
111 static void
112 sparc_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 
175 static void
176 sparc_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 
252 static 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