PageRenderTime 29ms CodeModel.GetById 17ms app.highlight 9ms RepoModel.GetById 1ms app.codeStats 0ms

/arch/powerpc/lib/checksum_32.S

https://bitbucket.org/cresqo/cm7-p500-kernel
Assembly | 225 lines | 221 code | 4 blank | 0 comment | 2 complexity | 5f77d3312226c315de080959758ad5b4 MD5 | raw file
Possible License(s): LGPL-2.0, AGPL-1.0, GPL-2.0
  1/*
  2 * This file contains assembly-language implementations
  3 * of IP-style 1's complement checksum routines.
  4 *	
  5 *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  6 *
  7 *  This program is free software; you can redistribute it and/or
  8 *  modify it under the terms of the GNU General Public License
  9 *  as published by the Free Software Foundation; either version
 10 *  2 of the License, or (at your option) any later version.
 11 *
 12 * Severely hacked about by Paul Mackerras (paulus@cs.anu.edu.au).
 13 */
 14
 15#include <linux/sys.h>
 16#include <asm/processor.h>
 17#include <asm/errno.h>
 18#include <asm/ppc_asm.h>
 19
 20	.text
 21
 22/*
 23 * ip_fast_csum(buf, len) -- Optimized for IP header
 24 * len is in words and is always >= 5.
 25 */
 26_GLOBAL(ip_fast_csum)
 27	lwz	r0,0(r3)
 28	lwzu	r5,4(r3)
 29	addic.	r4,r4,-2
 30	addc	r0,r0,r5
 31	mtctr	r4
 32	blelr-
 331:	lwzu	r4,4(r3)
 34	adde	r0,r0,r4
 35	bdnz	1b
 36	addze	r0,r0		/* add in final carry */
 37	rlwinm	r3,r0,16,0,31	/* fold two halves together */
 38	add	r3,r0,r3
 39	not	r3,r3
 40	srwi	r3,r3,16
 41	blr
 42
 43/*
 44 * Compute checksum of TCP or UDP pseudo-header:
 45 *   csum_tcpudp_magic(saddr, daddr, len, proto, sum)
 46 */	
 47_GLOBAL(csum_tcpudp_magic)
 48	rlwimi	r5,r6,16,0,15	/* put proto in upper half of len */
 49	addc	r0,r3,r4	/* add 4 32-bit words together */
 50	adde	r0,r0,r5
 51	adde	r0,r0,r7
 52	addze	r0,r0		/* add in final carry */
 53	rlwinm	r3,r0,16,0,31	/* fold two halves together */
 54	add	r3,r0,r3
 55	not	r3,r3
 56	srwi	r3,r3,16
 57	blr
 58
 59/*
 60 * computes the checksum of a memory block at buff, length len,
 61 * and adds in "sum" (32-bit)
 62 *
 63 * csum_partial(buff, len, sum)
 64 */
 65_GLOBAL(csum_partial)
 66	addic	r0,r5,0
 67	subi	r3,r3,4
 68	srwi.	r6,r4,2
 69	beq	3f		/* if we're doing < 4 bytes */
 70	andi.	r5,r3,2		/* Align buffer to longword boundary */
 71	beq+	1f
 72	lhz	r5,4(r3)	/* do 2 bytes to get aligned */
 73	addi	r3,r3,2
 74	subi	r4,r4,2
 75	addc	r0,r0,r5
 76	srwi.	r6,r4,2		/* # words to do */
 77	beq	3f
 781:	mtctr	r6
 792:	lwzu	r5,4(r3)	/* the bdnz has zero overhead, so it should */
 80	adde	r0,r0,r5	/* be unnecessary to unroll this loop */
 81	bdnz	2b
 82	andi.	r4,r4,3
 833:	cmpwi	0,r4,2
 84	blt+	4f
 85	lhz	r5,4(r3)
 86	addi	r3,r3,2
 87	subi	r4,r4,2
 88	adde	r0,r0,r5
 894:	cmpwi	0,r4,1
 90	bne+	5f
 91	lbz	r5,4(r3)
 92	slwi	r5,r5,8		/* Upper byte of word */
 93	adde	r0,r0,r5
 945:	addze	r3,r0		/* add in final carry */
 95	blr
 96
 97/*
 98 * Computes the checksum of a memory block at src, length len,
 99 * and adds in "sum" (32-bit), while copying the block to dst.
100 * If an access exception occurs on src or dst, it stores -EFAULT
101 * to *src_err or *dst_err respectively, and (for an error on
102 * src) zeroes the rest of dst.
103 *
104 * csum_partial_copy_generic(src, dst, len, sum, src_err, dst_err)
105 */
106_GLOBAL(csum_partial_copy_generic)
107	addic	r0,r6,0
108	subi	r3,r3,4
109	subi	r4,r4,4
110	srwi.	r6,r5,2
111	beq	3f		/* if we're doing < 4 bytes */
112	andi.	r9,r4,2		/* Align dst to longword boundary */
113	beq+	1f
11481:	lhz	r6,4(r3)	/* do 2 bytes to get aligned */
115	addi	r3,r3,2
116	subi	r5,r5,2
11791:	sth	r6,4(r4)
118	addi	r4,r4,2
119	addc	r0,r0,r6
120	srwi.	r6,r5,2		/* # words to do */
121	beq	3f
1221:	srwi.	r6,r5,4		/* # groups of 4 words to do */
123	beq	10f
124	mtctr	r6
12571:	lwz	r6,4(r3)
12672:	lwz	r9,8(r3)
12773:	lwz	r10,12(r3)
12874:	lwzu	r11,16(r3)
129	adde	r0,r0,r6
13075:	stw	r6,4(r4)
131	adde	r0,r0,r9
13276:	stw	r9,8(r4)
133	adde	r0,r0,r10
13477:	stw	r10,12(r4)
135	adde	r0,r0,r11
13678:	stwu	r11,16(r4)
137	bdnz	71b
13810:	rlwinm.	r6,r5,30,30,31	/* # words left to do */
139	beq	13f
140	mtctr	r6
14182:	lwzu	r9,4(r3)
14292:	stwu	r9,4(r4)
143	adde	r0,r0,r9
144	bdnz	82b
14513:	andi.	r5,r5,3
1463:	cmpwi	0,r5,2
147	blt+	4f
14883:	lhz	r6,4(r3)
149	addi	r3,r3,2
150	subi	r5,r5,2
15193:	sth	r6,4(r4)
152	addi	r4,r4,2
153	adde	r0,r0,r6
1544:	cmpwi	0,r5,1
155	bne+	5f
15684:	lbz	r6,4(r3)
15794:	stb	r6,4(r4)
158	slwi	r6,r6,8		/* Upper byte of word */
159	adde	r0,r0,r6
1605:	addze	r3,r0		/* add in final carry */
161	blr
162
163/* These shouldn't go in the fixup section, since that would
164   cause the ex_table addresses to get out of order. */
165
166src_error_4:
167	mfctr	r6		/* update # bytes remaining from ctr */
168	rlwimi	r5,r6,4,0,27
169	b	79f
170src_error_1:
171	li	r6,0
172	subi	r5,r5,2
17395:	sth	r6,4(r4)
174	addi	r4,r4,2
17579:	srwi.	r6,r5,2
176	beq	3f
177	mtctr	r6
178src_error_2:
179	li	r6,0
18096:	stwu	r6,4(r4)
181	bdnz	96b
1823:	andi.	r5,r5,3
183	beq	src_error
184src_error_3:
185	li	r6,0
186	mtctr	r5
187	addi	r4,r4,3
18897:	stbu	r6,1(r4)
189	bdnz	97b
190src_error:
191	cmpwi	0,r7,0
192	beq	1f
193	li	r6,-EFAULT
194	stw	r6,0(r7)
1951:	addze	r3,r0
196	blr
197
198dst_error:
199	cmpwi	0,r8,0
200	beq	1f
201	li	r6,-EFAULT
202	stw	r6,0(r8)
2031:	addze	r3,r0
204	blr
205
206.section __ex_table,"a"
207	.long	81b,src_error_1
208	.long	91b,dst_error
209	.long	71b,src_error_4
210	.long	72b,src_error_4
211	.long	73b,src_error_4
212	.long	74b,src_error_4
213	.long	75b,dst_error
214	.long	76b,dst_error
215	.long	77b,dst_error
216	.long	78b,dst_error
217	.long	82b,src_error_2
218	.long	92b,dst_error
219	.long	83b,src_error_3
220	.long	93b,dst_error
221	.long	84b,src_error_3
222	.long	94b,dst_error
223	.long	95b,dst_error
224	.long	96b,dst_error
225	.long	97b,dst_error