xref: /linux/arch/powerpc/crypto/crc32-vpmsum_core.S (revision a4eb44a6435d6d8f9e642407a4a06f65eb90ca04)
1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*
3 * Core of the accelerated CRC algorithm.
4 * In your file, define the constants and CRC_FUNCTION_NAME
5 * Then include this file.
6 *
7 * Calculate the checksum of data that is 16 byte aligned and a multiple of
8 * 16 bytes.
9 *
10 * The first step is to reduce it to 1024 bits. We do this in 8 parallel
11 * chunks in order to mask the latency of the vpmsum instructions. If we
12 * have more than 32 kB of data to checksum we repeat this step multiple
13 * times, passing in the previous 1024 bits.
14 *
15 * The next step is to reduce the 1024 bits to 64 bits. This step adds
16 * 32 bits of 0s to the end - this matches what a CRC does. We just
17 * calculate constants that land the data in this 32 bits.
18 *
19 * We then use fixed point Barrett reduction to compute a mod n over GF(2)
20 * for n = CRC using POWER8 instructions. We use x = 32.
21 *
22 * https://en.wikipedia.org/wiki/Barrett_reduction
23 *
24 * Copyright (C) 2015 Anton Blanchard <anton@au.ibm.com>, IBM
25*/
26
27#include <asm/ppc_asm.h>
28#include <asm/ppc-opcode.h>
29
30#define MAX_SIZE	32768
31
32	.text
33
34#if defined(__BIG_ENDIAN__) && defined(REFLECT)
35#define BYTESWAP_DATA
36#elif defined(__LITTLE_ENDIAN__) && !defined(REFLECT)
37#define BYTESWAP_DATA
38#else
39#undef BYTESWAP_DATA
40#endif
41
42#define off16		r25
43#define off32		r26
44#define off48		r27
45#define off64		r28
46#define off80		r29
47#define off96		r30
48#define off112		r31
49
50#define const1		v24
51#define const2		v25
52
53#define byteswap	v26
54#define	mask_32bit	v27
55#define	mask_64bit	v28
56#define zeroes		v29
57
58#ifdef BYTESWAP_DATA
59#define VPERM(A, B, C, D) vperm	A, B, C, D
60#else
61#define VPERM(A, B, C, D)
62#endif
63
64/* unsigned int CRC_FUNCTION_NAME(unsigned int crc, void *p, unsigned long len) */
65FUNC_START(CRC_FUNCTION_NAME)
66	std	r31,-8(r1)
67	std	r30,-16(r1)
68	std	r29,-24(r1)
69	std	r28,-32(r1)
70	std	r27,-40(r1)
71	std	r26,-48(r1)
72	std	r25,-56(r1)
73
74	li	off16,16
75	li	off32,32
76	li	off48,48
77	li	off64,64
78	li	off80,80
79	li	off96,96
80	li	off112,112
81	li	r0,0
82
83	/* Enough room for saving 10 non volatile VMX registers */
84	subi	r6,r1,56+10*16
85	subi	r7,r1,56+2*16
86
87	stvx	v20,0,r6
88	stvx	v21,off16,r6
89	stvx	v22,off32,r6
90	stvx	v23,off48,r6
91	stvx	v24,off64,r6
92	stvx	v25,off80,r6
93	stvx	v26,off96,r6
94	stvx	v27,off112,r6
95	stvx	v28,0,r7
96	stvx	v29,off16,r7
97
98	mr	r10,r3
99
100	vxor	zeroes,zeroes,zeroes
101	vspltisw v0,-1
102
103	vsldoi	mask_32bit,zeroes,v0,4
104	vsldoi	mask_64bit,zeroes,v0,8
105
106	/* Get the initial value into v8 */
107	vxor	v8,v8,v8
108	MTVRD(v8, R3)
109#ifdef REFLECT
110	vsldoi	v8,zeroes,v8,8	/* shift into bottom 32 bits */
111#else
112	vsldoi	v8,v8,zeroes,4	/* shift into top 32 bits */
113#endif
114
115#ifdef BYTESWAP_DATA
116	addis	r3,r2,.byteswap_constant@toc@ha
117	addi	r3,r3,.byteswap_constant@toc@l
118
119	lvx	byteswap,0,r3
120	addi	r3,r3,16
121#endif
122
123	cmpdi	r5,256
124	blt	.Lshort
125
126	rldicr	r6,r5,0,56
127
128	/* Checksum in blocks of MAX_SIZE */
1291:	lis	r7,MAX_SIZE@h
130	ori	r7,r7,MAX_SIZE@l
131	mr	r9,r7
132	cmpd	r6,r7
133	bgt	2f
134	mr	r7,r6
1352:	subf	r6,r7,r6
136
137	/* our main loop does 128 bytes at a time */
138	srdi	r7,r7,7
139
140	/*
141	 * Work out the offset into the constants table to start at. Each
142	 * constant is 16 bytes, and it is used against 128 bytes of input
143	 * data - 128 / 16 = 8
144	 */
145	sldi	r8,r7,4
146	srdi	r9,r9,3
147	subf	r8,r8,r9
148
149	/* We reduce our final 128 bytes in a separate step */
150	addi	r7,r7,-1
151	mtctr	r7
152
153	addis	r3,r2,.constants@toc@ha
154	addi	r3,r3,.constants@toc@l
155
156	/* Find the start of our constants */
157	add	r3,r3,r8
158
159	/* zero v0-v7 which will contain our checksums */
160	vxor	v0,v0,v0
161	vxor	v1,v1,v1
162	vxor	v2,v2,v2
163	vxor	v3,v3,v3
164	vxor	v4,v4,v4
165	vxor	v5,v5,v5
166	vxor	v6,v6,v6
167	vxor	v7,v7,v7
168
169	lvx	const1,0,r3
170
171	/*
172	 * If we are looping back to consume more data we use the values
173	 * already in v16-v23.
174	 */
175	cmpdi	r0,1
176	beq	2f
177
178	/* First warm up pass */
179	lvx	v16,0,r4
180	lvx	v17,off16,r4
181	VPERM(v16,v16,v16,byteswap)
182	VPERM(v17,v17,v17,byteswap)
183	lvx	v18,off32,r4
184	lvx	v19,off48,r4
185	VPERM(v18,v18,v18,byteswap)
186	VPERM(v19,v19,v19,byteswap)
187	lvx	v20,off64,r4
188	lvx	v21,off80,r4
189	VPERM(v20,v20,v20,byteswap)
190	VPERM(v21,v21,v21,byteswap)
191	lvx	v22,off96,r4
192	lvx	v23,off112,r4
193	VPERM(v22,v22,v22,byteswap)
194	VPERM(v23,v23,v23,byteswap)
195	addi	r4,r4,8*16
196
197	/* xor in initial value */
198	vxor	v16,v16,v8
199
2002:	bdz	.Lfirst_warm_up_done
201
202	addi	r3,r3,16
203	lvx	const2,0,r3
204
205	/* Second warm up pass */
206	VPMSUMD(v8,v16,const1)
207	lvx	v16,0,r4
208	VPERM(v16,v16,v16,byteswap)
209	ori	r2,r2,0
210
211	VPMSUMD(v9,v17,const1)
212	lvx	v17,off16,r4
213	VPERM(v17,v17,v17,byteswap)
214	ori	r2,r2,0
215
216	VPMSUMD(v10,v18,const1)
217	lvx	v18,off32,r4
218	VPERM(v18,v18,v18,byteswap)
219	ori	r2,r2,0
220
221	VPMSUMD(v11,v19,const1)
222	lvx	v19,off48,r4
223	VPERM(v19,v19,v19,byteswap)
224	ori	r2,r2,0
225
226	VPMSUMD(v12,v20,const1)
227	lvx	v20,off64,r4
228	VPERM(v20,v20,v20,byteswap)
229	ori	r2,r2,0
230
231	VPMSUMD(v13,v21,const1)
232	lvx	v21,off80,r4
233	VPERM(v21,v21,v21,byteswap)
234	ori	r2,r2,0
235
236	VPMSUMD(v14,v22,const1)
237	lvx	v22,off96,r4
238	VPERM(v22,v22,v22,byteswap)
239	ori	r2,r2,0
240
241	VPMSUMD(v15,v23,const1)
242	lvx	v23,off112,r4
243	VPERM(v23,v23,v23,byteswap)
244
245	addi	r4,r4,8*16
246
247	bdz	.Lfirst_cool_down
248
249	/*
250	 * main loop. We modulo schedule it such that it takes three iterations
251	 * to complete - first iteration load, second iteration vpmsum, third
252	 * iteration xor.
253	 */
254	.balign	16
2554:	lvx	const1,0,r3
256	addi	r3,r3,16
257	ori	r2,r2,0
258
259	vxor	v0,v0,v8
260	VPMSUMD(v8,v16,const2)
261	lvx	v16,0,r4
262	VPERM(v16,v16,v16,byteswap)
263	ori	r2,r2,0
264
265	vxor	v1,v1,v9
266	VPMSUMD(v9,v17,const2)
267	lvx	v17,off16,r4
268	VPERM(v17,v17,v17,byteswap)
269	ori	r2,r2,0
270
271	vxor	v2,v2,v10
272	VPMSUMD(v10,v18,const2)
273	lvx	v18,off32,r4
274	VPERM(v18,v18,v18,byteswap)
275	ori	r2,r2,0
276
277	vxor	v3,v3,v11
278	VPMSUMD(v11,v19,const2)
279	lvx	v19,off48,r4
280	VPERM(v19,v19,v19,byteswap)
281	lvx	const2,0,r3
282	ori	r2,r2,0
283
284	vxor	v4,v4,v12
285	VPMSUMD(v12,v20,const1)
286	lvx	v20,off64,r4
287	VPERM(v20,v20,v20,byteswap)
288	ori	r2,r2,0
289
290	vxor	v5,v5,v13
291	VPMSUMD(v13,v21,const1)
292	lvx	v21,off80,r4
293	VPERM(v21,v21,v21,byteswap)
294	ori	r2,r2,0
295
296	vxor	v6,v6,v14
297	VPMSUMD(v14,v22,const1)
298	lvx	v22,off96,r4
299	VPERM(v22,v22,v22,byteswap)
300	ori	r2,r2,0
301
302	vxor	v7,v7,v15
303	VPMSUMD(v15,v23,const1)
304	lvx	v23,off112,r4
305	VPERM(v23,v23,v23,byteswap)
306
307	addi	r4,r4,8*16
308
309	bdnz	4b
310
311.Lfirst_cool_down:
312	/* First cool down pass */
313	lvx	const1,0,r3
314	addi	r3,r3,16
315
316	vxor	v0,v0,v8
317	VPMSUMD(v8,v16,const1)
318	ori	r2,r2,0
319
320	vxor	v1,v1,v9
321	VPMSUMD(v9,v17,const1)
322	ori	r2,r2,0
323
324	vxor	v2,v2,v10
325	VPMSUMD(v10,v18,const1)
326	ori	r2,r2,0
327
328	vxor	v3,v3,v11
329	VPMSUMD(v11,v19,const1)
330	ori	r2,r2,0
331
332	vxor	v4,v4,v12
333	VPMSUMD(v12,v20,const1)
334	ori	r2,r2,0
335
336	vxor	v5,v5,v13
337	VPMSUMD(v13,v21,const1)
338	ori	r2,r2,0
339
340	vxor	v6,v6,v14
341	VPMSUMD(v14,v22,const1)
342	ori	r2,r2,0
343
344	vxor	v7,v7,v15
345	VPMSUMD(v15,v23,const1)
346	ori	r2,r2,0
347
348.Lsecond_cool_down:
349	/* Second cool down pass */
350	vxor	v0,v0,v8
351	vxor	v1,v1,v9
352	vxor	v2,v2,v10
353	vxor	v3,v3,v11
354	vxor	v4,v4,v12
355	vxor	v5,v5,v13
356	vxor	v6,v6,v14
357	vxor	v7,v7,v15
358
359#ifdef REFLECT
360	/*
361	 * vpmsumd produces a 96 bit result in the least significant bits
362	 * of the register. Since we are bit reflected we have to shift it
363	 * left 32 bits so it occupies the least significant bits in the
364	 * bit reflected domain.
365	 */
366	vsldoi	v0,v0,zeroes,4
367	vsldoi	v1,v1,zeroes,4
368	vsldoi	v2,v2,zeroes,4
369	vsldoi	v3,v3,zeroes,4
370	vsldoi	v4,v4,zeroes,4
371	vsldoi	v5,v5,zeroes,4
372	vsldoi	v6,v6,zeroes,4
373	vsldoi	v7,v7,zeroes,4
374#endif
375
376	/* xor with last 1024 bits */
377	lvx	v8,0,r4
378	lvx	v9,off16,r4
379	VPERM(v8,v8,v8,byteswap)
380	VPERM(v9,v9,v9,byteswap)
381	lvx	v10,off32,r4
382	lvx	v11,off48,r4
383	VPERM(v10,v10,v10,byteswap)
384	VPERM(v11,v11,v11,byteswap)
385	lvx	v12,off64,r4
386	lvx	v13,off80,r4
387	VPERM(v12,v12,v12,byteswap)
388	VPERM(v13,v13,v13,byteswap)
389	lvx	v14,off96,r4
390	lvx	v15,off112,r4
391	VPERM(v14,v14,v14,byteswap)
392	VPERM(v15,v15,v15,byteswap)
393
394	addi	r4,r4,8*16
395
396	vxor	v16,v0,v8
397	vxor	v17,v1,v9
398	vxor	v18,v2,v10
399	vxor	v19,v3,v11
400	vxor	v20,v4,v12
401	vxor	v21,v5,v13
402	vxor	v22,v6,v14
403	vxor	v23,v7,v15
404
405	li	r0,1
406	cmpdi	r6,0
407	addi	r6,r6,128
408	bne	1b
409
410	/* Work out how many bytes we have left */
411	andi.	r5,r5,127
412
413	/* Calculate where in the constant table we need to start */
414	subfic	r6,r5,128
415	add	r3,r3,r6
416
417	/* How many 16 byte chunks are in the tail */
418	srdi	r7,r5,4
419	mtctr	r7
420
421	/*
422	 * Reduce the previously calculated 1024 bits to 64 bits, shifting
423	 * 32 bits to include the trailing 32 bits of zeros
424	 */
425	lvx	v0,0,r3
426	lvx	v1,off16,r3
427	lvx	v2,off32,r3
428	lvx	v3,off48,r3
429	lvx	v4,off64,r3
430	lvx	v5,off80,r3
431	lvx	v6,off96,r3
432	lvx	v7,off112,r3
433	addi	r3,r3,8*16
434
435	VPMSUMW(v0,v16,v0)
436	VPMSUMW(v1,v17,v1)
437	VPMSUMW(v2,v18,v2)
438	VPMSUMW(v3,v19,v3)
439	VPMSUMW(v4,v20,v4)
440	VPMSUMW(v5,v21,v5)
441	VPMSUMW(v6,v22,v6)
442	VPMSUMW(v7,v23,v7)
443
444	/* Now reduce the tail (0 - 112 bytes) */
445	cmpdi	r7,0
446	beq	1f
447
448	lvx	v16,0,r4
449	lvx	v17,0,r3
450	VPERM(v16,v16,v16,byteswap)
451	VPMSUMW(v16,v16,v17)
452	vxor	v0,v0,v16
453	bdz	1f
454
455	lvx	v16,off16,r4
456	lvx	v17,off16,r3
457	VPERM(v16,v16,v16,byteswap)
458	VPMSUMW(v16,v16,v17)
459	vxor	v0,v0,v16
460	bdz	1f
461
462	lvx	v16,off32,r4
463	lvx	v17,off32,r3
464	VPERM(v16,v16,v16,byteswap)
465	VPMSUMW(v16,v16,v17)
466	vxor	v0,v0,v16
467	bdz	1f
468
469	lvx	v16,off48,r4
470	lvx	v17,off48,r3
471	VPERM(v16,v16,v16,byteswap)
472	VPMSUMW(v16,v16,v17)
473	vxor	v0,v0,v16
474	bdz	1f
475
476	lvx	v16,off64,r4
477	lvx	v17,off64,r3
478	VPERM(v16,v16,v16,byteswap)
479	VPMSUMW(v16,v16,v17)
480	vxor	v0,v0,v16
481	bdz	1f
482
483	lvx	v16,off80,r4
484	lvx	v17,off80,r3
485	VPERM(v16,v16,v16,byteswap)
486	VPMSUMW(v16,v16,v17)
487	vxor	v0,v0,v16
488	bdz	1f
489
490	lvx	v16,off96,r4
491	lvx	v17,off96,r3
492	VPERM(v16,v16,v16,byteswap)
493	VPMSUMW(v16,v16,v17)
494	vxor	v0,v0,v16
495
496	/* Now xor all the parallel chunks together */
4971:	vxor	v0,v0,v1
498	vxor	v2,v2,v3
499	vxor	v4,v4,v5
500	vxor	v6,v6,v7
501
502	vxor	v0,v0,v2
503	vxor	v4,v4,v6
504
505	vxor	v0,v0,v4
506
507.Lbarrett_reduction:
508	/* Barrett constants */
509	addis	r3,r2,.barrett_constants@toc@ha
510	addi	r3,r3,.barrett_constants@toc@l
511
512	lvx	const1,0,r3
513	lvx	const2,off16,r3
514
515	vsldoi	v1,v0,v0,8
516	vxor	v0,v0,v1		/* xor two 64 bit results together */
517
518#ifdef REFLECT
519	/* shift left one bit */
520	vspltisb v1,1
521	vsl	v0,v0,v1
522#endif
523
524	vand	v0,v0,mask_64bit
525#ifndef REFLECT
526	/*
527	 * Now for the Barrett reduction algorithm. The idea is to calculate q,
528	 * the multiple of our polynomial that we need to subtract. By
529	 * doing the computation 2x bits higher (ie 64 bits) and shifting the
530	 * result back down 2x bits, we round down to the nearest multiple.
531	 */
532	VPMSUMD(v1,v0,const1)	/* ma */
533	vsldoi	v1,zeroes,v1,8	/* q = floor(ma/(2^64)) */
534	VPMSUMD(v1,v1,const2)	/* qn */
535	vxor	v0,v0,v1	/* a - qn, subtraction is xor in GF(2) */
536
537	/*
538	 * Get the result into r3. We need to shift it left 8 bytes:
539	 * V0 [ 0 1 2 X ]
540	 * V0 [ 0 X 2 3 ]
541	 */
542	vsldoi	v0,v0,zeroes,8	/* shift result into top 64 bits */
543#else
544	/*
545	 * The reflected version of Barrett reduction. Instead of bit
546	 * reflecting our data (which is expensive to do), we bit reflect our
547	 * constants and our algorithm, which means the intermediate data in
548	 * our vector registers goes from 0-63 instead of 63-0. We can reflect
549	 * the algorithm because we don't carry in mod 2 arithmetic.
550	 */
551	vand	v1,v0,mask_32bit	/* bottom 32 bits of a */
552	VPMSUMD(v1,v1,const1)		/* ma */
553	vand	v1,v1,mask_32bit	/* bottom 32bits of ma */
554	VPMSUMD(v1,v1,const2)		/* qn */
555	vxor	v0,v0,v1		/* a - qn, subtraction is xor in GF(2) */
556
557	/*
558	 * Since we are bit reflected, the result (ie the low 32 bits) is in
559	 * the high 32 bits. We just need to shift it left 4 bytes
560	 * V0 [ 0 1 X 3 ]
561	 * V0 [ 0 X 2 3 ]
562	 */
563	vsldoi	v0,v0,zeroes,4		/* shift result into top 64 bits of */
564#endif
565
566	/* Get it into r3 */
567	MFVRD(R3, v0)
568
569.Lout:
570	subi	r6,r1,56+10*16
571	subi	r7,r1,56+2*16
572
573	lvx	v20,0,r6
574	lvx	v21,off16,r6
575	lvx	v22,off32,r6
576	lvx	v23,off48,r6
577	lvx	v24,off64,r6
578	lvx	v25,off80,r6
579	lvx	v26,off96,r6
580	lvx	v27,off112,r6
581	lvx	v28,0,r7
582	lvx	v29,off16,r7
583
584	ld	r31,-8(r1)
585	ld	r30,-16(r1)
586	ld	r29,-24(r1)
587	ld	r28,-32(r1)
588	ld	r27,-40(r1)
589	ld	r26,-48(r1)
590	ld	r25,-56(r1)
591
592	blr
593
594.Lfirst_warm_up_done:
595	lvx	const1,0,r3
596	addi	r3,r3,16
597
598	VPMSUMD(v8,v16,const1)
599	VPMSUMD(v9,v17,const1)
600	VPMSUMD(v10,v18,const1)
601	VPMSUMD(v11,v19,const1)
602	VPMSUMD(v12,v20,const1)
603	VPMSUMD(v13,v21,const1)
604	VPMSUMD(v14,v22,const1)
605	VPMSUMD(v15,v23,const1)
606
607	b	.Lsecond_cool_down
608
609.Lshort:
610	cmpdi	r5,0
611	beq	.Lzero
612
613	addis	r3,r2,.short_constants@toc@ha
614	addi	r3,r3,.short_constants@toc@l
615
616	/* Calculate where in the constant table we need to start */
617	subfic	r6,r5,256
618	add	r3,r3,r6
619
620	/* How many 16 byte chunks? */
621	srdi	r7,r5,4
622	mtctr	r7
623
624	vxor	v19,v19,v19
625	vxor	v20,v20,v20
626
627	lvx	v0,0,r4
628	lvx	v16,0,r3
629	VPERM(v0,v0,v16,byteswap)
630	vxor	v0,v0,v8	/* xor in initial value */
631	VPMSUMW(v0,v0,v16)
632	bdz	.Lv0
633
634	lvx	v1,off16,r4
635	lvx	v17,off16,r3
636	VPERM(v1,v1,v17,byteswap)
637	VPMSUMW(v1,v1,v17)
638	bdz	.Lv1
639
640	lvx	v2,off32,r4
641	lvx	v16,off32,r3
642	VPERM(v2,v2,v16,byteswap)
643	VPMSUMW(v2,v2,v16)
644	bdz	.Lv2
645
646	lvx	v3,off48,r4
647	lvx	v17,off48,r3
648	VPERM(v3,v3,v17,byteswap)
649	VPMSUMW(v3,v3,v17)
650	bdz	.Lv3
651
652	lvx	v4,off64,r4
653	lvx	v16,off64,r3
654	VPERM(v4,v4,v16,byteswap)
655	VPMSUMW(v4,v4,v16)
656	bdz	.Lv4
657
658	lvx	v5,off80,r4
659	lvx	v17,off80,r3
660	VPERM(v5,v5,v17,byteswap)
661	VPMSUMW(v5,v5,v17)
662	bdz	.Lv5
663
664	lvx	v6,off96,r4
665	lvx	v16,off96,r3
666	VPERM(v6,v6,v16,byteswap)
667	VPMSUMW(v6,v6,v16)
668	bdz	.Lv6
669
670	lvx	v7,off112,r4
671	lvx	v17,off112,r3
672	VPERM(v7,v7,v17,byteswap)
673	VPMSUMW(v7,v7,v17)
674	bdz	.Lv7
675
676	addi	r3,r3,128
677	addi	r4,r4,128
678
679	lvx	v8,0,r4
680	lvx	v16,0,r3
681	VPERM(v8,v8,v16,byteswap)
682	VPMSUMW(v8,v8,v16)
683	bdz	.Lv8
684
685	lvx	v9,off16,r4
686	lvx	v17,off16,r3
687	VPERM(v9,v9,v17,byteswap)
688	VPMSUMW(v9,v9,v17)
689	bdz	.Lv9
690
691	lvx	v10,off32,r4
692	lvx	v16,off32,r3
693	VPERM(v10,v10,v16,byteswap)
694	VPMSUMW(v10,v10,v16)
695	bdz	.Lv10
696
697	lvx	v11,off48,r4
698	lvx	v17,off48,r3
699	VPERM(v11,v11,v17,byteswap)
700	VPMSUMW(v11,v11,v17)
701	bdz	.Lv11
702
703	lvx	v12,off64,r4
704	lvx	v16,off64,r3
705	VPERM(v12,v12,v16,byteswap)
706	VPMSUMW(v12,v12,v16)
707	bdz	.Lv12
708
709	lvx	v13,off80,r4
710	lvx	v17,off80,r3
711	VPERM(v13,v13,v17,byteswap)
712	VPMSUMW(v13,v13,v17)
713	bdz	.Lv13
714
715	lvx	v14,off96,r4
716	lvx	v16,off96,r3
717	VPERM(v14,v14,v16,byteswap)
718	VPMSUMW(v14,v14,v16)
719	bdz	.Lv14
720
721	lvx	v15,off112,r4
722	lvx	v17,off112,r3
723	VPERM(v15,v15,v17,byteswap)
724	VPMSUMW(v15,v15,v17)
725
726.Lv15:	vxor	v19,v19,v15
727.Lv14:	vxor	v20,v20,v14
728.Lv13:	vxor	v19,v19,v13
729.Lv12:	vxor	v20,v20,v12
730.Lv11:	vxor	v19,v19,v11
731.Lv10:	vxor	v20,v20,v10
732.Lv9:	vxor	v19,v19,v9
733.Lv8:	vxor	v20,v20,v8
734.Lv7:	vxor	v19,v19,v7
735.Lv6:	vxor	v20,v20,v6
736.Lv5:	vxor	v19,v19,v5
737.Lv4:	vxor	v20,v20,v4
738.Lv3:	vxor	v19,v19,v3
739.Lv2:	vxor	v20,v20,v2
740.Lv1:	vxor	v19,v19,v1
741.Lv0:	vxor	v20,v20,v0
742
743	vxor	v0,v19,v20
744
745	b	.Lbarrett_reduction
746
747.Lzero:
748	mr	r3,r10
749	b	.Lout
750
751FUNC_END(CRC_FUNCTION_NAME)
752