1 /* $NetBSD: rf_nwayxor.c,v 1.10 2006/10/12 01:31:51 christos Exp $ */
3 * Copyright (c) 1995 Carnegie-Mellon University.
6 * Author: Mark Holland, Daniel Stodolsky
8 * Permission to use, copy, modify and distribute this software and
9 * its documentation is hereby granted, provided that both the copyright
10 * notice and this permission notice appear in all copies of the
11 * software, derivative works or modified versions, and any portions
12 * thereof, and that both notices appear in supporting documentation.
14 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
15 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
16 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
18 * Carnegie Mellon requests users of this software to return to
20 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
21 * School of Computer Science
22 * Carnegie Mellon University
23 * Pittsburgh PA 15213-3890
25 * any improvements or extensions that they make and grant Carnegie the
26 * rights to redistribute these changes.
29 /************************************************************
31 * nwayxor.c -- code to do N-way xors for reconstruction
33 * nWayXorN xors N input buffers into the destination buffer.
34 * adapted from danner's longword_bxor code.
36 ************************************************************/
38 #include <sys/cdefs.h>
39 __KERNEL_RCSID(0, "$NetBSD: rf_nwayxor.c,v 1.10 2006/10/12 01:31:51 christos Exp $");
41 #include "rf_nwayxor.h"
42 #include "rf_shutdown.h"
44 static int callcount
[10];
45 static void rf_ShutdownNWayXor(void *);
48 rf_ShutdownNWayXor(void *ignored
)
52 if (rf_showXorCallCounts
== 0)
54 printf("Call counts for n-way xor routines: ");
55 for (i
= 0; i
< 10; i
++)
56 printf("%d ", callcount
[i
]);
61 rf_ConfigureNWayXor(RF_ShutdownList_t
**listp
)
65 for (i
= 0; i
< 10; i
++)
67 rf_ShutdownCreate(listp
, rf_ShutdownNWayXor
, NULL
);
72 rf_nWayXor1(RF_ReconBuffer_t
**src_rbs
, RF_ReconBuffer_t
*dest_rb
, int len
)
74 unsigned long *src
= (unsigned long *) src_rbs
[0]->buffer
;
75 unsigned long *dest
= (unsigned long *) dest_rb
->buffer
;
76 unsigned long *end
= src
+ len
;
77 unsigned long d0
, d1
, d2
, d3
, s0
, s1
, s2
, s3
;
103 rf_nWayXor2(RF_ReconBuffer_t
**src_rbs
, RF_ReconBuffer_t
*dest_rb
, int len
)
105 unsigned long *dst
= (unsigned long *) dest_rb
->buffer
;
106 unsigned long *a
= dst
;
107 unsigned long *b
= (unsigned long *) src_rbs
[0]->buffer
;
108 unsigned long *c
= (unsigned long *) src_rbs
[1]->buffer
;
109 unsigned long a0
, a1
, a2
, a3
, b0
, b1
, b2
, b3
;
112 /* align dest to cache line */
113 while ((((unsigned long) dst
) & 0x1f)) {
114 *dst
++ = *a
++ ^ *b
++ ^ *c
++;
132 /* start dual issue */
160 *dst
++ = *a
++ ^ *b
++ ^ *c
++;
164 /* note that first arg is not incremented but 2nd arg is */
165 #define LOAD_FIRST(_dst,_b) \
166 a0 = _dst[0]; len -= 4; \
175 /* note: arg is incremented */
176 #define XOR_AND_LOAD_NEXT(_n) \
177 a0 ^= b0; b0 = _n[0]; \
178 a1 ^= b1; b1 = _n[1]; \
179 a2 ^= b2; b2 = _n[2]; \
180 a3 ^= b3; b3 = _n[3]; \
183 /* arg is incremented */
184 #define XOR_AND_STORE(_dst) \
185 a0 ^= b0; _dst[0] = a0; \
186 a1 ^= b1; _dst[1] = a1; \
187 a2 ^= b2; _dst[2] = a2; \
188 a3 ^= b3; _dst[3] = a3; \
193 rf_nWayXor3(RF_ReconBuffer_t
**src_rbs
, RF_ReconBuffer_t
*dest_rb
, int len
)
195 unsigned long *dst
= (unsigned long *) dest_rb
->buffer
;
196 unsigned long *b
= (unsigned long *) src_rbs
[0]->buffer
;
197 unsigned long *c
= (unsigned long *) src_rbs
[1]->buffer
;
198 unsigned long *d
= (unsigned long *) src_rbs
[2]->buffer
;
199 unsigned long a0
, a1
, a2
, a3
, b0
, b1
, b2
, b3
;
202 /* align dest to cache line */
203 while ((((unsigned long) dst
) & 0x1f)) {
204 *dst
++ ^= *b
++ ^ *c
++ ^ *d
++;
209 XOR_AND_LOAD_NEXT(c
);
210 XOR_AND_LOAD_NEXT(d
);
214 *dst
++ ^= *b
++ ^ *c
++ ^ *d
++;
220 rf_nWayXor4(RF_ReconBuffer_t
**src_rbs
, RF_ReconBuffer_t
*dest_rb
, int len
)
222 unsigned long *dst
= (unsigned long *) dest_rb
->buffer
;
223 unsigned long *b
= (unsigned long *) src_rbs
[0]->buffer
;
224 unsigned long *c
= (unsigned long *) src_rbs
[1]->buffer
;
225 unsigned long *d
= (unsigned long *) src_rbs
[2]->buffer
;
226 unsigned long *e
= (unsigned long *) src_rbs
[3]->buffer
;
227 unsigned long a0
, a1
, a2
, a3
, b0
, b1
, b2
, b3
;
230 /* align dest to cache line */
231 while ((((unsigned long) dst
) & 0x1f)) {
232 *dst
++ ^= *b
++ ^ *c
++ ^ *d
++ ^ *e
++;
237 XOR_AND_LOAD_NEXT(c
);
238 XOR_AND_LOAD_NEXT(d
);
239 XOR_AND_LOAD_NEXT(e
);
243 *dst
++ ^= *b
++ ^ *c
++ ^ *d
++ ^ *e
++;
249 rf_nWayXor5(RF_ReconBuffer_t
**src_rbs
, RF_ReconBuffer_t
*dest_rb
, int len
)
251 unsigned long *dst
= (unsigned long *) dest_rb
->buffer
;
252 unsigned long *b
= (unsigned long *) src_rbs
[0]->buffer
;
253 unsigned long *c
= (unsigned long *) src_rbs
[1]->buffer
;
254 unsigned long *d
= (unsigned long *) src_rbs
[2]->buffer
;
255 unsigned long *e
= (unsigned long *) src_rbs
[3]->buffer
;
256 unsigned long *f
= (unsigned long *) src_rbs
[4]->buffer
;
257 unsigned long a0
, a1
, a2
, a3
, b0
, b1
, b2
, b3
;
260 /* align dest to cache line */
261 while ((((unsigned long) dst
) & 0x1f)) {
262 *dst
++ ^= *b
++ ^ *c
++ ^ *d
++ ^ *e
++ ^ *f
++;
267 XOR_AND_LOAD_NEXT(c
);
268 XOR_AND_LOAD_NEXT(d
);
269 XOR_AND_LOAD_NEXT(e
);
270 XOR_AND_LOAD_NEXT(f
);
274 *dst
++ ^= *b
++ ^ *c
++ ^ *d
++ ^ *e
++ ^ *f
++;
280 rf_nWayXor6(RF_ReconBuffer_t
**src_rbs
, RF_ReconBuffer_t
*dest_rb
, int len
)
282 unsigned long *dst
= (unsigned long *) dest_rb
->buffer
;
283 unsigned long *b
= (unsigned long *) src_rbs
[0]->buffer
;
284 unsigned long *c
= (unsigned long *) src_rbs
[1]->buffer
;
285 unsigned long *d
= (unsigned long *) src_rbs
[2]->buffer
;
286 unsigned long *e
= (unsigned long *) src_rbs
[3]->buffer
;
287 unsigned long *f
= (unsigned long *) src_rbs
[4]->buffer
;
288 unsigned long *g
= (unsigned long *) src_rbs
[5]->buffer
;
289 unsigned long a0
, a1
, a2
, a3
, b0
, b1
, b2
, b3
;
292 /* align dest to cache line */
293 while ((((unsigned long) dst
) & 0x1f)) {
294 *dst
++ ^= *b
++ ^ *c
++ ^ *d
++ ^ *e
++ ^ *f
++ ^ *g
++;
299 XOR_AND_LOAD_NEXT(c
);
300 XOR_AND_LOAD_NEXT(d
);
301 XOR_AND_LOAD_NEXT(e
);
302 XOR_AND_LOAD_NEXT(f
);
303 XOR_AND_LOAD_NEXT(g
);
307 *dst
++ ^= *b
++ ^ *c
++ ^ *d
++ ^ *e
++ ^ *f
++ ^ *g
++;
313 rf_nWayXor7(RF_ReconBuffer_t
**src_rbs
, RF_ReconBuffer_t
*dest_rb
, int len
)
315 unsigned long *dst
= (unsigned long *) dest_rb
->buffer
;
316 unsigned long *b
= (unsigned long *) src_rbs
[0]->buffer
;
317 unsigned long *c
= (unsigned long *) src_rbs
[1]->buffer
;
318 unsigned long *d
= (unsigned long *) src_rbs
[2]->buffer
;
319 unsigned long *e
= (unsigned long *) src_rbs
[3]->buffer
;
320 unsigned long *f
= (unsigned long *) src_rbs
[4]->buffer
;
321 unsigned long *g
= (unsigned long *) src_rbs
[5]->buffer
;
322 unsigned long *h
= (unsigned long *) src_rbs
[6]->buffer
;
323 unsigned long a0
, a1
, a2
, a3
, b0
, b1
, b2
, b3
;
326 /* align dest to cache line */
327 while ((((unsigned long) dst
) & 0x1f)) {
328 *dst
++ ^= *b
++ ^ *c
++ ^ *d
++ ^ *e
++ ^ *f
++ ^ *g
++ ^ *h
++;
333 XOR_AND_LOAD_NEXT(c
);
334 XOR_AND_LOAD_NEXT(d
);
335 XOR_AND_LOAD_NEXT(e
);
336 XOR_AND_LOAD_NEXT(f
);
337 XOR_AND_LOAD_NEXT(g
);
338 XOR_AND_LOAD_NEXT(h
);
342 *dst
++ ^= *b
++ ^ *c
++ ^ *d
++ ^ *e
++ ^ *f
++ ^ *g
++ ^ *h
++;
348 rf_nWayXor8(RF_ReconBuffer_t
**src_rbs
, RF_ReconBuffer_t
*dest_rb
, int len
)
350 unsigned long *dst
= (unsigned long *) dest_rb
->buffer
;
351 unsigned long *b
= (unsigned long *) src_rbs
[0]->buffer
;
352 unsigned long *c
= (unsigned long *) src_rbs
[1]->buffer
;
353 unsigned long *d
= (unsigned long *) src_rbs
[2]->buffer
;
354 unsigned long *e
= (unsigned long *) src_rbs
[3]->buffer
;
355 unsigned long *f
= (unsigned long *) src_rbs
[4]->buffer
;
356 unsigned long *g
= (unsigned long *) src_rbs
[5]->buffer
;
357 unsigned long *h
= (unsigned long *) src_rbs
[6]->buffer
;
358 unsigned long *i
= (unsigned long *) src_rbs
[7]->buffer
;
359 unsigned long a0
, a1
, a2
, a3
, b0
, b1
, b2
, b3
;
362 /* align dest to cache line */
363 while ((((unsigned long) dst
) & 0x1f)) {
364 *dst
++ ^= *b
++ ^ *c
++ ^ *d
++ ^ *e
++ ^ *f
++ ^ *g
++ ^ *h
++ ^ *i
++;
369 XOR_AND_LOAD_NEXT(c
);
370 XOR_AND_LOAD_NEXT(d
);
371 XOR_AND_LOAD_NEXT(e
);
372 XOR_AND_LOAD_NEXT(f
);
373 XOR_AND_LOAD_NEXT(g
);
374 XOR_AND_LOAD_NEXT(h
);
375 XOR_AND_LOAD_NEXT(i
);
379 *dst
++ ^= *b
++ ^ *c
++ ^ *d
++ ^ *e
++ ^ *f
++ ^ *g
++ ^ *h
++ ^ *i
++;
386 rf_nWayXor9(RF_ReconBuffer_t
**src_rbs
, RF_ReconBuffer_t
*dest_rb
, int len
)
388 unsigned long *dst
= (unsigned long *) dest_rb
->buffer
;
389 unsigned long *b
= (unsigned long *) src_rbs
[0]->buffer
;
390 unsigned long *c
= (unsigned long *) src_rbs
[1]->buffer
;
391 unsigned long *d
= (unsigned long *) src_rbs
[2]->buffer
;
392 unsigned long *e
= (unsigned long *) src_rbs
[3]->buffer
;
393 unsigned long *f
= (unsigned long *) src_rbs
[4]->buffer
;
394 unsigned long *g
= (unsigned long *) src_rbs
[5]->buffer
;
395 unsigned long *h
= (unsigned long *) src_rbs
[6]->buffer
;
396 unsigned long *i
= (unsigned long *) src_rbs
[7]->buffer
;
397 unsigned long *j
= (unsigned long *) src_rbs
[8]->buffer
;
398 unsigned long a0
, a1
, a2
, a3
, b0
, b1
, b2
, b3
;
401 /* align dest to cache line */
402 while ((((unsigned long) dst
) & 0x1f)) {
403 *dst
++ ^= *b
++ ^ *c
++ ^ *d
++ ^ *e
++ ^ *f
++ ^ *g
++ ^ *h
++ ^ *i
++ ^ *j
++;
408 XOR_AND_LOAD_NEXT(c
);
409 XOR_AND_LOAD_NEXT(d
);
410 XOR_AND_LOAD_NEXT(e
);
411 XOR_AND_LOAD_NEXT(f
);
412 XOR_AND_LOAD_NEXT(g
);
413 XOR_AND_LOAD_NEXT(h
);
414 XOR_AND_LOAD_NEXT(i
);
415 XOR_AND_LOAD_NEXT(j
);
419 *dst
++ ^= *b
++ ^ *c
++ ^ *d
++ ^ *e
++ ^ *f
++ ^ *g
++ ^ *h
++ ^ *i
++ ^ *j
++;