⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 checksum.s

📁 linux-2.6.15.6
💻 S
字号:
/* $Id: checksum.S,v 1.10 2001/07/06 13:11:32 gniibe Exp $ * * INET		An implementation of the TCP/IP protocol suite for the LINUX *		operating system.  INET is implemented using the  BSD Socket *		interface as the means of communication with the user level. * *		IP/TCP/UDP checksumming routines * * Authors:	Jorge Cwik, <jorge@laser.satlink.net> *		Arnt Gulbrandsen, <agulbra@nvg.unit.no> *		Tom May, <ftom@netcom.com> *              Pentium Pro/II routines: *              Alexander Kjeldaas <astor@guardian.no> *              Finn Arne Gangstad <finnag@guardian.no> *		Lots of code moved from tcp.c and ip.c; see those files *		for more names. * * Changes:     Ingo Molnar, converted csum_partial_copy() to 2.1 exception *			     handling. *		Andi Kleen,  add zeroing on error *                   converted to pure assembler * * SuperH version:  Copyright (C) 1999  Niibe Yutaka * *		This program is free software; you can redistribute it and/or *		modify it under the terms of the GNU General Public License *		as published by the Free Software Foundation; either version *		2 of the License, or (at your option) any later version. */#include <asm/errno.h>#include <linux/linkage.h>/* * computes a partial checksum, e.g. for TCP/UDP fragments *//*	 * unsigned int csum_partial(const unsigned char *buf, int len, *                           unsigned int sum); */.textENTRY(csum_partial)	  /*	   * Experiments with Ethernet and SLIP connections show that buff	   * is aligned on either a 2-byte or 4-byte boundary.  We get at	   * least a twofold speedup on 486 and Pentium if it is 4-byte aligned.	   * Fortunately, it is easy to convert 2-byte alignment to 4-byte	   * alignment for the unrolled loop.	   */	mov	r5, r1	mov	r4, r0	tst	#2, r0		! Check alignment.	bt	2f		! Jump if alignment is ok.	!	add	#-2, r5		! Alignment uses up two bytes.	cmp/pz	r5		!	bt/s	1f		! Jump if we had at least two bytes.	 clrt	bra	6f	 add	#2, r5		! r5 was < 2.  Deal with it.1:	mov	r5, r1		! Save new len for later use.	mov.w	@r4+, r0	extu.w	r0, r0	addc	r0, r6	bf	2f	add	#1, r62:	mov	#-5, r0	shld	r0, r5	tst	r5, r5	bt/s	4f		! if it's =0, go to 4f	 clrt	.align	23:	mov.l	@r4+, r0	mov.l	@r4+, r2	mov.l	@r4+, r3	addc	r0, r6	mov.l	@r4+, r0	addc	r2, r6	mov.l	@r4+, r2	addc	r3, r6	mov.l	@r4+, r3	addc	r0, r6	mov.l	@r4+, r0	addc	r2, r6	mov.l	@r4+, r2	addc	r3, r6	addc	r0, r6	addc	r2, r6	movt	r0	dt	r5	bf/s	3b	 cmp/eq	#1, r0	! here, we know r5==0	addc	r5, r6			! add carry to r64:	mov	r1, r0	and	#0x1c, r0	tst	r0, r0	bt/s	6f	 mov	r0, r5	shlr2	r5	mov	#0, r25:	addc	r2, r6	mov.l	@r4+, r2	movt	r0	dt	r5	bf/s	5b	 cmp/eq	#1, r0	addc	r2, r6	addc	r5, r6		! r5==0 here, so it means add carry-bit6:	mov	r1, r5	mov	#3, r0	and	r0, r5	tst	r5, r5	bt	9f		! if it's =0 go to 9f	mov	#2, r1	cmp/hs  r1, r5	bf	7f	mov.w	@r4+, r0	extu.w	r0, r0	cmp/eq	r1, r5	bt/s	8f	 clrt	shll16	r0	addc	r0, r67:	mov.b	@r4+, r0	extu.b	r0, r0#ifndef	__LITTLE_ENDIAN__	shll8	r0#endif8:	addc	r0, r6	mov	#0, r0	addc	r0, r6 9:	rts	 mov	r6, r0/*unsigned int csum_partial_copy_generic (const char *src, char *dst, int len, 					int sum, int *src_err_ptr, int *dst_err_ptr) */ /* * Copy from ds while checksumming, otherwise like csum_partial * * The macros SRC and DST specify the type of access for the instruction. * thus we can call a custom exception handler for all access types. * * FIXME: could someone double-check whether I haven't mixed up some SRC and *	  DST definitions? It's damn hard to trigger all cases.  I hope I got *	  them all but there's no guarantee. */#define SRC(...)			\	9999: __VA_ARGS__ ;		\	.section __ex_table, "a";	\	.long 9999b, 6001f	;	\	.previous#define DST(...)			\	9999: __VA_ARGS__ ;		\	.section __ex_table, "a";	\	.long 9999b, 6002f	;	\	.previous!! r4:	const char *SRC! r5:	char *DST! r6:	int LEN! r7:	int SUM!! on stack:! int *SRC_ERR_PTR! int *DST_ERR_PTR!ENTRY(csum_partial_copy_generic)	mov.l	r5,@-r15	mov.l	r6,@-r15	mov	#3,r0		! Check src and dest are equally aligned	mov	r4,r1	and	r0,r1	and	r5,r0	cmp/eq	r1,r0	bf	3f		! Different alignments, use slow version	tst	#1,r0		! Check dest word aligned	bf	3f		! If not, do it the slow way	mov	#2,r0	tst	r0,r5		! Check dest alignment. 	bt	2f		! Jump if alignment is ok.	add	#-2,r6		! Alignment uses up two bytes.	cmp/pz	r6		! Jump if we had at least two bytes.	bt/s	1f	 clrt	bra	4f	 add	#2,r6		! r6 was < 2.	Deal with it.3:	! Handle different src and dest alignments.	! This is not common, so simple byte by byte copy will do.	mov	r6,r2	shlr	r6	tst	r6,r6	bt	4f	clrt	.align	25:SRC(	mov.b	@r4+,r1 	)SRC(	mov.b	@r4+,r0		)	extu.b	r1,r1DST(	mov.b	r1,@r5		)DST(	mov.b	r0,@(1,r5)	)	extu.b	r0,r0	add	#2,r5#ifdef	__LITTLE_ENDIAN__	shll8	r0#else	shll8	r1#endif	or	r1,r0	addc	r0,r7	movt	r0	dt	r6	bf/s	5b	 cmp/eq	#1,r0	mov	#0,r0	addc	r0, r7	mov	r2, r0	tst	#1, r0	bt	7f	bra	5f	 clrt	! src and dest equally aligned, but to a two byte boundary.	! Handle first two bytes as a special case	.align	21:	SRC(	mov.w	@r4+,r0		)DST(	mov.w	r0,@r5		)	add	#2,r5	extu.w	r0,r0	addc	r0,r7	mov	#0,r0	addc	r0,r72:	mov	r6,r2	mov	#-5,r0	shld	r0,r6	tst	r6,r6	bt/s	2f	 clrt	.align	21:	SRC(	mov.l	@r4+,r0		)SRC(	mov.l	@r4+,r1		)	addc	r0,r7DST(	mov.l	r0,@r5		)DST(	mov.l	r1,@(4,r5)	)	addc	r1,r7SRC(	mov.l	@r4+,r0		)SRC(	mov.l	@r4+,r1		)	addc	r0,r7DST(	mov.l	r0,@(8,r5)	)DST(	mov.l	r1,@(12,r5)	)	addc	r1,r7SRC(	mov.l	@r4+,r0 	)SRC(	mov.l	@r4+,r1		)	addc	r0,r7DST(	mov.l	r0,@(16,r5)	)DST(	mov.l	r1,@(20,r5)	)	addc	r1,r7SRC(	mov.l	@r4+,r0		)SRC(	mov.l	@r4+,r1		)	addc	r0,r7DST(	mov.l	r0,@(24,r5)	)DST(	mov.l	r1,@(28,r5)	)	addc	r1,r7	add	#32,r5	movt	r0	dt	r6	bf/s	1b	 cmp/eq	#1,r0	mov	#0,r0	addc	r0,r72:	mov	r2,r6	mov	#0x1c,r0	and	r0,r6	cmp/pl	r6	bf/s	4f	 clrt	shlr2	r63:	SRC(	mov.l	@r4+,r0	)	addc	r0,r7DST(	mov.l	r0,@r5	)	add	#4,r5	movt	r0	dt	r6	bf/s	3b	 cmp/eq	#1,r0	mov	#0,r0	addc	r0,r74:	mov	r2,r6	mov	#3,r0	and	r0,r6	cmp/pl	r6	bf	7f	mov	#2,r1	cmp/hs	r1,r6	bf	5fSRC(	mov.w	@r4+,r0	)DST(	mov.w	r0,@r5	)	extu.w	r0,r0	add	#2,r5	cmp/eq	r1,r6	bt/s	6f	 clrt	shll16	r0	addc	r0,r75:	SRC(	mov.b	@r4+,r0	)DST(	mov.b	r0,@r5	)	extu.b	r0,r0#ifndef	__LITTLE_ENDIAN__	shll8	r0#endif6:	addc	r0,r7	mov	#0,r0	addc	r0,r77:5000:# Exception handler:.section .fixup, "ax"							6001:	mov.l	@(8,r15),r0			! src_err_ptr	mov	#-EFAULT,r1	mov.l	r1,@r0	! zero the complete destination - computing the rest	! is too much work 	mov.l	@(4,r15),r5		! dst	mov.l	@r15,r6			! len	mov	#0,r71:	mov.b	r7,@r5	dt	r6	bf/s	1b	 add	#1,r5	mov.l	8000f,r0	jmp	@r0	 nop	.align	28000:	.long	5000b6002:	mov.l	@(12,r15),r0			! dst_err_ptr	mov	#-EFAULT,r1	mov.l	r1,@r0	mov.l	8001f,r0	jmp	@r0	 nop	.align	28001:	.long	5000b.previous	add	#8,r15	rts	 mov	r7,r0

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -