rf_nwayxor.c revision 1.5 1 1.5 lukem /* $NetBSD: rf_nwayxor.c,v 1.5 2001/11/13 07:11:15 lukem Exp $ */
2 1.1 oster /*
3 1.1 oster * Copyright (c) 1995 Carnegie-Mellon University.
4 1.1 oster * All rights reserved.
5 1.1 oster *
6 1.1 oster * Author: Mark Holland, Daniel Stodolsky
7 1.1 oster *
8 1.1 oster * Permission to use, copy, modify and distribute this software and
9 1.1 oster * its documentation is hereby granted, provided that both the copyright
10 1.1 oster * notice and this permission notice appear in all copies of the
11 1.1 oster * software, derivative works or modified versions, and any portions
12 1.1 oster * thereof, and that both notices appear in supporting documentation.
13 1.1 oster *
14 1.1 oster * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
15 1.1 oster * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
16 1.1 oster * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
17 1.1 oster *
18 1.1 oster * Carnegie Mellon requests users of this software to return to
19 1.1 oster *
20 1.1 oster * Software Distribution Coordinator or Software.Distribution (at) CS.CMU.EDU
21 1.1 oster * School of Computer Science
22 1.1 oster * Carnegie Mellon University
23 1.1 oster * Pittsburgh PA 15213-3890
24 1.1 oster *
25 1.1 oster * any improvements or extensions that they make and grant Carnegie the
26 1.1 oster * rights to redistribute these changes.
27 1.1 oster */
28 1.1 oster
29 1.1 oster /************************************************************
30 1.1 oster *
31 1.1 oster * nwayxor.c -- code to do N-way xors for reconstruction
32 1.1 oster *
33 1.1 oster * nWayXorN xors N input buffers into the destination buffer.
34 1.1 oster * adapted from danner's longword_bxor code.
35 1.1 oster *
36 1.1 oster ************************************************************/
37 1.5 lukem
38 1.5 lukem #include <sys/cdefs.h>
39 1.5 lukem __KERNEL_RCSID(0, "$NetBSD: rf_nwayxor.c,v 1.5 2001/11/13 07:11:15 lukem Exp $");
40 1.1 oster
41 1.1 oster #include "rf_nwayxor.h"
42 1.1 oster #include "rf_shutdown.h"
43 1.1 oster
44 1.1 oster static int callcount[10];
45 1.1 oster static void rf_ShutdownNWayXor(void *);
46 1.1 oster
47 1.3 oster static void
48 1.3 oster rf_ShutdownNWayXor(ignored)
49 1.3 oster void *ignored;
50 1.3 oster {
51 1.3 oster int i;
52 1.3 oster
53 1.3 oster if (rf_showXorCallCounts == 0)
54 1.3 oster return;
55 1.3 oster printf("Call counts for n-way xor routines: ");
56 1.3 oster for (i = 0; i < 10; i++)
57 1.3 oster printf("%d ", callcount[i]);
58 1.3 oster printf("\n");
59 1.1 oster }
60 1.1 oster
61 1.3 oster int
62 1.3 oster rf_ConfigureNWayXor(listp)
63 1.3 oster RF_ShutdownList_t **listp;
64 1.3 oster {
65 1.3 oster int i, rc;
66 1.3 oster
67 1.3 oster for (i = 0; i < 10; i++)
68 1.3 oster callcount[i] = 0;
69 1.3 oster rc = rf_ShutdownCreate(listp, rf_ShutdownNWayXor, NULL);
70 1.3 oster return (rc);
71 1.1 oster }
72 1.1 oster
73 1.3 oster void
74 1.3 oster rf_nWayXor1(src_rbs, dest_rb, len)
75 1.3 oster RF_ReconBuffer_t **src_rbs;
76 1.3 oster RF_ReconBuffer_t *dest_rb;
77 1.3 oster int len;
78 1.3 oster {
79 1.4 augustss unsigned long *src = (unsigned long *) src_rbs[0]->buffer;
80 1.4 augustss unsigned long *dest = (unsigned long *) dest_rb->buffer;
81 1.4 augustss unsigned long *end = src + len;
82 1.4 augustss unsigned long d0, d1, d2, d3, s0, s1, s2, s3;
83 1.3 oster
84 1.3 oster callcount[1]++;
85 1.3 oster while (len >= 4) {
86 1.3 oster d0 = dest[0];
87 1.3 oster d1 = dest[1];
88 1.3 oster d2 = dest[2];
89 1.3 oster d3 = dest[3];
90 1.3 oster s0 = src[0];
91 1.3 oster s1 = src[1];
92 1.3 oster s2 = src[2];
93 1.3 oster s3 = src[3];
94 1.3 oster dest[0] = d0 ^ s0;
95 1.3 oster dest[1] = d1 ^ s1;
96 1.3 oster dest[2] = d2 ^ s2;
97 1.3 oster dest[3] = d3 ^ s3;
98 1.3 oster src += 4;
99 1.3 oster dest += 4;
100 1.3 oster len -= 4;
101 1.3 oster }
102 1.3 oster while (src < end) {
103 1.3 oster *dest++ ^= *src++;
104 1.3 oster }
105 1.1 oster }
106 1.1 oster
107 1.3 oster void
108 1.3 oster rf_nWayXor2(src_rbs, dest_rb, len)
109 1.3 oster RF_ReconBuffer_t **src_rbs;
110 1.3 oster RF_ReconBuffer_t *dest_rb;
111 1.3 oster int len;
112 1.3 oster {
113 1.4 augustss unsigned long *dst = (unsigned long *) dest_rb->buffer;
114 1.4 augustss unsigned long *a = dst;
115 1.4 augustss unsigned long *b = (unsigned long *) src_rbs[0]->buffer;
116 1.4 augustss unsigned long *c = (unsigned long *) src_rbs[1]->buffer;
117 1.3 oster unsigned long a0, a1, a2, a3, b0, b1, b2, b3;
118 1.3 oster
119 1.3 oster callcount[2]++;
120 1.3 oster /* align dest to cache line */
121 1.3 oster while ((((unsigned long) dst) & 0x1f)) {
122 1.3 oster *dst++ = *a++ ^ *b++ ^ *c++;
123 1.3 oster len--;
124 1.3 oster }
125 1.3 oster while (len > 4) {
126 1.3 oster a0 = a[0];
127 1.3 oster len -= 4;
128 1.3 oster
129 1.3 oster a1 = a[1];
130 1.3 oster a2 = a[2];
131 1.3 oster
132 1.3 oster a3 = a[3];
133 1.3 oster a += 4;
134 1.3 oster
135 1.3 oster b0 = b[0];
136 1.3 oster b1 = b[1];
137 1.3 oster
138 1.3 oster b2 = b[2];
139 1.3 oster b3 = b[3];
140 1.3 oster /* start dual issue */
141 1.3 oster a0 ^= b0;
142 1.3 oster b0 = c[0];
143 1.3 oster
144 1.3 oster b += 4;
145 1.3 oster a1 ^= b1;
146 1.3 oster
147 1.3 oster a2 ^= b2;
148 1.3 oster a3 ^= b3;
149 1.3 oster
150 1.3 oster b1 = c[1];
151 1.3 oster a0 ^= b0;
152 1.3 oster
153 1.3 oster b2 = c[2];
154 1.3 oster a1 ^= b1;
155 1.3 oster
156 1.3 oster b3 = c[3];
157 1.3 oster a2 ^= b2;
158 1.3 oster
159 1.3 oster dst[0] = a0;
160 1.3 oster a3 ^= b3;
161 1.3 oster dst[1] = a1;
162 1.3 oster c += 4;
163 1.3 oster dst[2] = a2;
164 1.3 oster dst[3] = a3;
165 1.3 oster dst += 4;
166 1.3 oster }
167 1.3 oster while (len) {
168 1.3 oster *dst++ = *a++ ^ *b++ ^ *c++;
169 1.3 oster len--;
170 1.3 oster }
171 1.1 oster }
172 1.1 oster /* note that first arg is not incremented but 2nd arg is */
173 1.1 oster #define LOAD_FIRST(_dst,_b) \
174 1.1 oster a0 = _dst[0]; len -= 4; \
175 1.1 oster a1 = _dst[1]; \
176 1.1 oster a2 = _dst[2]; \
177 1.1 oster a3 = _dst[3]; \
178 1.1 oster b0 = _b[0]; \
179 1.1 oster b1 = _b[1]; \
180 1.1 oster b2 = _b[2]; \
181 1.1 oster b3 = _b[3]; _b += 4;
182 1.1 oster
183 1.1 oster /* note: arg is incremented */
184 1.1 oster #define XOR_AND_LOAD_NEXT(_n) \
185 1.1 oster a0 ^= b0; b0 = _n[0]; \
186 1.1 oster a1 ^= b1; b1 = _n[1]; \
187 1.1 oster a2 ^= b2; b2 = _n[2]; \
188 1.1 oster a3 ^= b3; b3 = _n[3]; \
189 1.1 oster _n += 4;
190 1.1 oster
191 1.1 oster /* arg is incremented */
192 1.1 oster #define XOR_AND_STORE(_dst) \
193 1.1 oster a0 ^= b0; _dst[0] = a0; \
194 1.1 oster a1 ^= b1; _dst[1] = a1; \
195 1.1 oster a2 ^= b2; _dst[2] = a2; \
196 1.1 oster a3 ^= b3; _dst[3] = a3; \
197 1.1 oster _dst += 4;
198 1.1 oster
199 1.1 oster
200 1.3 oster void
201 1.3 oster rf_nWayXor3(src_rbs, dest_rb, len)
202 1.3 oster RF_ReconBuffer_t **src_rbs;
203 1.3 oster RF_ReconBuffer_t *dest_rb;
204 1.3 oster int len;
205 1.3 oster {
206 1.4 augustss unsigned long *dst = (unsigned long *) dest_rb->buffer;
207 1.4 augustss unsigned long *b = (unsigned long *) src_rbs[0]->buffer;
208 1.4 augustss unsigned long *c = (unsigned long *) src_rbs[1]->buffer;
209 1.4 augustss unsigned long *d = (unsigned long *) src_rbs[2]->buffer;
210 1.3 oster unsigned long a0, a1, a2, a3, b0, b1, b2, b3;
211 1.3 oster
212 1.3 oster callcount[3]++;
213 1.3 oster /* align dest to cache line */
214 1.3 oster while ((((unsigned long) dst) & 0x1f)) {
215 1.3 oster *dst++ ^= *b++ ^ *c++ ^ *d++;
216 1.3 oster len--;
217 1.3 oster }
218 1.3 oster while (len > 4) {
219 1.3 oster LOAD_FIRST(dst, b);
220 1.3 oster XOR_AND_LOAD_NEXT(c);
221 1.3 oster XOR_AND_LOAD_NEXT(d);
222 1.3 oster XOR_AND_STORE(dst);
223 1.3 oster }
224 1.3 oster while (len) {
225 1.3 oster *dst++ ^= *b++ ^ *c++ ^ *d++;
226 1.3 oster len--;
227 1.3 oster }
228 1.1 oster }
229 1.1 oster
230 1.3 oster void
231 1.3 oster rf_nWayXor4(src_rbs, dest_rb, len)
232 1.3 oster RF_ReconBuffer_t **src_rbs;
233 1.3 oster RF_ReconBuffer_t *dest_rb;
234 1.3 oster int len;
235 1.3 oster {
236 1.4 augustss unsigned long *dst = (unsigned long *) dest_rb->buffer;
237 1.4 augustss unsigned long *b = (unsigned long *) src_rbs[0]->buffer;
238 1.4 augustss unsigned long *c = (unsigned long *) src_rbs[1]->buffer;
239 1.4 augustss unsigned long *d = (unsigned long *) src_rbs[2]->buffer;
240 1.4 augustss unsigned long *e = (unsigned long *) src_rbs[3]->buffer;
241 1.3 oster unsigned long a0, a1, a2, a3, b0, b1, b2, b3;
242 1.3 oster
243 1.3 oster callcount[4]++;
244 1.3 oster /* align dest to cache line */
245 1.3 oster while ((((unsigned long) dst) & 0x1f)) {
246 1.3 oster *dst++ ^= *b++ ^ *c++ ^ *d++ ^ *e++;
247 1.3 oster len--;
248 1.3 oster }
249 1.3 oster while (len > 4) {
250 1.3 oster LOAD_FIRST(dst, b);
251 1.3 oster XOR_AND_LOAD_NEXT(c);
252 1.3 oster XOR_AND_LOAD_NEXT(d);
253 1.3 oster XOR_AND_LOAD_NEXT(e);
254 1.3 oster XOR_AND_STORE(dst);
255 1.3 oster }
256 1.3 oster while (len) {
257 1.3 oster *dst++ ^= *b++ ^ *c++ ^ *d++ ^ *e++;
258 1.3 oster len--;
259 1.3 oster }
260 1.1 oster }
261 1.1 oster
262 1.3 oster void
263 1.3 oster rf_nWayXor5(src_rbs, dest_rb, len)
264 1.3 oster RF_ReconBuffer_t **src_rbs;
265 1.3 oster RF_ReconBuffer_t *dest_rb;
266 1.3 oster int len;
267 1.3 oster {
268 1.4 augustss unsigned long *dst = (unsigned long *) dest_rb->buffer;
269 1.4 augustss unsigned long *b = (unsigned long *) src_rbs[0]->buffer;
270 1.4 augustss unsigned long *c = (unsigned long *) src_rbs[1]->buffer;
271 1.4 augustss unsigned long *d = (unsigned long *) src_rbs[2]->buffer;
272 1.4 augustss unsigned long *e = (unsigned long *) src_rbs[3]->buffer;
273 1.4 augustss unsigned long *f = (unsigned long *) src_rbs[4]->buffer;
274 1.3 oster unsigned long a0, a1, a2, a3, b0, b1, b2, b3;
275 1.3 oster
276 1.3 oster callcount[5]++;
277 1.3 oster /* align dest to cache line */
278 1.3 oster while ((((unsigned long) dst) & 0x1f)) {
279 1.3 oster *dst++ ^= *b++ ^ *c++ ^ *d++ ^ *e++ ^ *f++;
280 1.3 oster len--;
281 1.3 oster }
282 1.3 oster while (len > 4) {
283 1.3 oster LOAD_FIRST(dst, b);
284 1.3 oster XOR_AND_LOAD_NEXT(c);
285 1.3 oster XOR_AND_LOAD_NEXT(d);
286 1.3 oster XOR_AND_LOAD_NEXT(e);
287 1.3 oster XOR_AND_LOAD_NEXT(f);
288 1.3 oster XOR_AND_STORE(dst);
289 1.3 oster }
290 1.3 oster while (len) {
291 1.3 oster *dst++ ^= *b++ ^ *c++ ^ *d++ ^ *e++ ^ *f++;
292 1.3 oster len--;
293 1.3 oster }
294 1.1 oster }
295 1.1 oster
296 1.3 oster void
297 1.3 oster rf_nWayXor6(src_rbs, dest_rb, len)
298 1.3 oster RF_ReconBuffer_t **src_rbs;
299 1.3 oster RF_ReconBuffer_t *dest_rb;
300 1.3 oster int len;
301 1.3 oster {
302 1.4 augustss unsigned long *dst = (unsigned long *) dest_rb->buffer;
303 1.4 augustss unsigned long *b = (unsigned long *) src_rbs[0]->buffer;
304 1.4 augustss unsigned long *c = (unsigned long *) src_rbs[1]->buffer;
305 1.4 augustss unsigned long *d = (unsigned long *) src_rbs[2]->buffer;
306 1.4 augustss unsigned long *e = (unsigned long *) src_rbs[3]->buffer;
307 1.4 augustss unsigned long *f = (unsigned long *) src_rbs[4]->buffer;
308 1.4 augustss unsigned long *g = (unsigned long *) src_rbs[5]->buffer;
309 1.3 oster unsigned long a0, a1, a2, a3, b0, b1, b2, b3;
310 1.3 oster
311 1.3 oster callcount[6]++;
312 1.3 oster /* align dest to cache line */
313 1.3 oster while ((((unsigned long) dst) & 0x1f)) {
314 1.3 oster *dst++ ^= *b++ ^ *c++ ^ *d++ ^ *e++ ^ *f++ ^ *g++;
315 1.3 oster len--;
316 1.3 oster }
317 1.3 oster while (len > 4) {
318 1.3 oster LOAD_FIRST(dst, b);
319 1.3 oster XOR_AND_LOAD_NEXT(c);
320 1.3 oster XOR_AND_LOAD_NEXT(d);
321 1.3 oster XOR_AND_LOAD_NEXT(e);
322 1.3 oster XOR_AND_LOAD_NEXT(f);
323 1.3 oster XOR_AND_LOAD_NEXT(g);
324 1.3 oster XOR_AND_STORE(dst);
325 1.3 oster }
326 1.3 oster while (len) {
327 1.3 oster *dst++ ^= *b++ ^ *c++ ^ *d++ ^ *e++ ^ *f++ ^ *g++;
328 1.3 oster len--;
329 1.3 oster }
330 1.1 oster }
331 1.1 oster
332 1.3 oster void
333 1.3 oster rf_nWayXor7(src_rbs, dest_rb, len)
334 1.3 oster RF_ReconBuffer_t **src_rbs;
335 1.3 oster RF_ReconBuffer_t *dest_rb;
336 1.3 oster int len;
337 1.3 oster {
338 1.4 augustss unsigned long *dst = (unsigned long *) dest_rb->buffer;
339 1.4 augustss unsigned long *b = (unsigned long *) src_rbs[0]->buffer;
340 1.4 augustss unsigned long *c = (unsigned long *) src_rbs[1]->buffer;
341 1.4 augustss unsigned long *d = (unsigned long *) src_rbs[2]->buffer;
342 1.4 augustss unsigned long *e = (unsigned long *) src_rbs[3]->buffer;
343 1.4 augustss unsigned long *f = (unsigned long *) src_rbs[4]->buffer;
344 1.4 augustss unsigned long *g = (unsigned long *) src_rbs[5]->buffer;
345 1.4 augustss unsigned long *h = (unsigned long *) src_rbs[6]->buffer;
346 1.3 oster unsigned long a0, a1, a2, a3, b0, b1, b2, b3;
347 1.3 oster
348 1.3 oster callcount[7]++;
349 1.3 oster /* align dest to cache line */
350 1.3 oster while ((((unsigned long) dst) & 0x1f)) {
351 1.3 oster *dst++ ^= *b++ ^ *c++ ^ *d++ ^ *e++ ^ *f++ ^ *g++ ^ *h++;
352 1.3 oster len--;
353 1.3 oster }
354 1.3 oster while (len > 4) {
355 1.3 oster LOAD_FIRST(dst, b);
356 1.3 oster XOR_AND_LOAD_NEXT(c);
357 1.3 oster XOR_AND_LOAD_NEXT(d);
358 1.3 oster XOR_AND_LOAD_NEXT(e);
359 1.3 oster XOR_AND_LOAD_NEXT(f);
360 1.3 oster XOR_AND_LOAD_NEXT(g);
361 1.3 oster XOR_AND_LOAD_NEXT(h);
362 1.3 oster XOR_AND_STORE(dst);
363 1.3 oster }
364 1.3 oster while (len) {
365 1.3 oster *dst++ ^= *b++ ^ *c++ ^ *d++ ^ *e++ ^ *f++ ^ *g++ ^ *h++;
366 1.3 oster len--;
367 1.3 oster }
368 1.1 oster }
369 1.1 oster
370 1.3 oster void
371 1.3 oster rf_nWayXor8(src_rbs, dest_rb, len)
372 1.3 oster RF_ReconBuffer_t **src_rbs;
373 1.3 oster RF_ReconBuffer_t *dest_rb;
374 1.3 oster int len;
375 1.3 oster {
376 1.4 augustss unsigned long *dst = (unsigned long *) dest_rb->buffer;
377 1.4 augustss unsigned long *b = (unsigned long *) src_rbs[0]->buffer;
378 1.4 augustss unsigned long *c = (unsigned long *) src_rbs[1]->buffer;
379 1.4 augustss unsigned long *d = (unsigned long *) src_rbs[2]->buffer;
380 1.4 augustss unsigned long *e = (unsigned long *) src_rbs[3]->buffer;
381 1.4 augustss unsigned long *f = (unsigned long *) src_rbs[4]->buffer;
382 1.4 augustss unsigned long *g = (unsigned long *) src_rbs[5]->buffer;
383 1.4 augustss unsigned long *h = (unsigned long *) src_rbs[6]->buffer;
384 1.4 augustss unsigned long *i = (unsigned long *) src_rbs[7]->buffer;
385 1.3 oster unsigned long a0, a1, a2, a3, b0, b1, b2, b3;
386 1.3 oster
387 1.3 oster callcount[8]++;
388 1.3 oster /* align dest to cache line */
389 1.3 oster while ((((unsigned long) dst) & 0x1f)) {
390 1.3 oster *dst++ ^= *b++ ^ *c++ ^ *d++ ^ *e++ ^ *f++ ^ *g++ ^ *h++ ^ *i++;
391 1.3 oster len--;
392 1.3 oster }
393 1.3 oster while (len > 4) {
394 1.3 oster LOAD_FIRST(dst, b);
395 1.3 oster XOR_AND_LOAD_NEXT(c);
396 1.3 oster XOR_AND_LOAD_NEXT(d);
397 1.3 oster XOR_AND_LOAD_NEXT(e);
398 1.3 oster XOR_AND_LOAD_NEXT(f);
399 1.3 oster XOR_AND_LOAD_NEXT(g);
400 1.3 oster XOR_AND_LOAD_NEXT(h);
401 1.3 oster XOR_AND_LOAD_NEXT(i);
402 1.3 oster XOR_AND_STORE(dst);
403 1.3 oster }
404 1.3 oster while (len) {
405 1.3 oster *dst++ ^= *b++ ^ *c++ ^ *d++ ^ *e++ ^ *f++ ^ *g++ ^ *h++ ^ *i++;
406 1.3 oster len--;
407 1.3 oster }
408 1.1 oster }
409 1.1 oster
410 1.1 oster
411 1.3 oster void
412 1.3 oster rf_nWayXor9(src_rbs, dest_rb, len)
413 1.3 oster RF_ReconBuffer_t **src_rbs;
414 1.3 oster RF_ReconBuffer_t *dest_rb;
415 1.3 oster int len;
416 1.3 oster {
417 1.4 augustss unsigned long *dst = (unsigned long *) dest_rb->buffer;
418 1.4 augustss unsigned long *b = (unsigned long *) src_rbs[0]->buffer;
419 1.4 augustss unsigned long *c = (unsigned long *) src_rbs[1]->buffer;
420 1.4 augustss unsigned long *d = (unsigned long *) src_rbs[2]->buffer;
421 1.4 augustss unsigned long *e = (unsigned long *) src_rbs[3]->buffer;
422 1.4 augustss unsigned long *f = (unsigned long *) src_rbs[4]->buffer;
423 1.4 augustss unsigned long *g = (unsigned long *) src_rbs[5]->buffer;
424 1.4 augustss unsigned long *h = (unsigned long *) src_rbs[6]->buffer;
425 1.4 augustss unsigned long *i = (unsigned long *) src_rbs[7]->buffer;
426 1.4 augustss unsigned long *j = (unsigned long *) src_rbs[8]->buffer;
427 1.3 oster unsigned long a0, a1, a2, a3, b0, b1, b2, b3;
428 1.3 oster
429 1.3 oster callcount[9]++;
430 1.3 oster /* align dest to cache line */
431 1.3 oster while ((((unsigned long) dst) & 0x1f)) {
432 1.3 oster *dst++ ^= *b++ ^ *c++ ^ *d++ ^ *e++ ^ *f++ ^ *g++ ^ *h++ ^ *i++ ^ *j++;
433 1.3 oster len--;
434 1.3 oster }
435 1.3 oster while (len > 4) {
436 1.3 oster LOAD_FIRST(dst, b);
437 1.3 oster XOR_AND_LOAD_NEXT(c);
438 1.3 oster XOR_AND_LOAD_NEXT(d);
439 1.3 oster XOR_AND_LOAD_NEXT(e);
440 1.3 oster XOR_AND_LOAD_NEXT(f);
441 1.3 oster XOR_AND_LOAD_NEXT(g);
442 1.3 oster XOR_AND_LOAD_NEXT(h);
443 1.3 oster XOR_AND_LOAD_NEXT(i);
444 1.3 oster XOR_AND_LOAD_NEXT(j);
445 1.3 oster XOR_AND_STORE(dst);
446 1.3 oster }
447 1.3 oster while (len) {
448 1.3 oster *dst++ ^= *b++ ^ *c++ ^ *d++ ^ *e++ ^ *f++ ^ *g++ ^ *h++ ^ *i++ ^ *j++;
449 1.3 oster len--;
450 1.3 oster }
451 1.1 oster }
452