checksum.s

来自「linux-2.4.29操作系统的源码」· S 代码 · 共 657 行 · 第 1/2 页

S
657
字号
/* * This file is subject to the terms and conditions of the GNU General Public * License.  See the file "COPYING" in the main directory of this archive * for more details. * * arch/sh5/lib/checksum.S * * Copyright (C) 2000, 2001  Paolo Alberelli, Stefano D'Andrea * *//* * * 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 * * SH-5 version:  Copyright (C) 2000  Paolo Alberelli, Stefano D'Andrea * *		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 <asm/registers.h>	.section	.text64, "ax"/*	 * unsigned int csum_partial(const unsigned char *buf, *			     int 	          len, *                           unsigned int         sum); * * * computes a partial checksum, e.g. for TCP/UDP fragments *//* * SH-5 ABI convention: *    Input parameters: *    		r2  = *buf *    		r3  =  len *    		r4  =  sum	so far computed checksum (may be zero) *    return value must be in: *              r2		returned checksum */	/*	 * 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.	 */#ifndef NOTDEF  	/* This version of _csum_partial is an easy but unefficient	 * implementation. 	 * It's mainteined only for historical reasons.		 */	.global csum_partialcsum_partial:	_ptar		.byte_footer, t1	/* t1 = .byte_footer         */	_ptar		.add_short_loop, t2	/* t2 = checksum eval loop   */	_ptar		.exiting, t3		/* t3 = add carry...	     */	movi		2, r1	/* we assume buf short aligned */	/* Short must be checksummed   */.add_short_loop:	bgt		r1, r3, t1		/* Size = 1 or 0 (remind)    */	ld.uw		r2, 0, r7		/* r7 = word to be checksumed*/	add		r4, r7, r4	addi		r2, 2, r2		/* move buf forward...       */	addi		r3, -2, r3		/* decrement len             */	blink		t2, ZERO		/* goto .add_short_loop      */	.byte_footer:	/* still one byte to be checksummed ? */	xor		r7, r7, r7	beqi		r3, 0, t3	ld.ub		r2, 0, r7		/* r7 = last byte...	     */#ifndef __LITTLE_ENDIAN__	shlli		r7, 8, r7#endif.exiting:	add		r4, r7, r2		ptabs		r18, t0	blink		t0, ZERO#else  /* NOTDEF ---------------------------------------------------- */	.global csum_partialcsum_partial:	movi		32, r8			/* r8 = sizeof(8 * int)   */	_ptar		.byte_footer, t1	/* t1 = .byte_footer      */	_ptar		.word_footer, t2	/* t2 = .word_footer      */	_ptar		.long_footer, t3	/* t3 = .long_footer      */	_ptar		.exit, t4		/* t4 = exit point        */	_ptar		.long_aligned, t0	/* t0 = .long_aligned	  */	or		r2, ZERO, r5		/* r5 = buffer pointer    */	or		r3, ZERO, r6		/* r6 = original length   */	andi		r2, 2, r7 			beq		r7, ZERO, t0		/* It's buf long aligned */	/* we assume buf short aligned */	beqi		r3, 1, t1		/* Size = 1 */	/* Short must be checksummed */	ld.uw		r2, 0, r7		/* r7 = word to be checksumed*/	add		r4, r7, r4	or		ZERO, ZERO, r7	mshflo.l	r4, r7, r7	shlri		r4, 32, r4	add		r4, r7, r4		/* Add eventual "carry" */	addi		r6, -2, r6	addi		r5, 2, r5		/* r5 is now long aligned */	beq		r6, ZERO, t4		/* Exit if done */		or		ZERO, ZERO, r7		/* Clean up r7 */	.long_aligned:	bgt		r8, r6, t3		/* 8 Longs to be checksummed */	ld.l		r5, 0, r7		/* r7 = data to be checksummed*/	add		r4, r7, r4	or		ZERO, ZERO, r7	mshflo.l	r4, r7, r7	shlri		r4, 32, r4	add		r4, r7, r4		/* Add eventual "carry" */	ld.l		r5, 4, r7		/* r7 = data to be checksummed*/	add		r4, r7, r4	or		ZERO, ZERO, r7	mshflo.l	r4, r7, r7	shlri		r4, 32, r4	add		r4, r7, r4		/* Add eventual "carry" */	ld.l		r5, 8, r7		/* r7 = data to be checksummed*/	add		r4, r7, r4	or		ZERO, ZERO, r7	mshflo.l	r4, r7, r7	shlri		r4, 32, r4	add		r4, r7, r4		/* Add eventual "carry" */	ld.l		r5, 12, r7		/* r7 = data to be checksummed*/	add		r4, r7, r4	or		ZERO, ZERO, r7	mshflo.l	r4, r7, r7	shlri		r4, 32, r4	add		r4, r7, r4		/* Add eventual "carry" */	ld.l		r5, 16, r7		/* r7 = data to be checksummed*/	add		r4, r7, r4	or		ZERO, ZERO, r7	mshflo.l	r4, r7, r7	shlri		r4, 32, r4	add		r4, r7, r4		/* Add eventual "carry" */	ld.l		r5, 20, r7		/* r7 = data to be checksummed*/	add		r4, r7, r4	or		ZERO, ZERO, r7	mshflo.l	r4, r7, r7	shlri		r4, 32, r4	add		r4, r7, r4		/* Add eventual "carry" */	ld.l		r5, 24, r7		/* r7 = data to be checksummed*/	add		r4, r7, r4	or		ZERO, ZERO, r7	mshflo.l	r4, r7, r7	shlri		r4, 32, r4	add		r4, r7, r4		/* Add eventual "carry" */	ld.l		r5, 28, r7		/* r7 = data to be checksummed*/	add		r4, r7, r4	or		ZERO, ZERO, r7	mshflo.l	r4, r7, r7	shlri		r4, 32, r4	add		r4, r7, r4		/* Add eventual "carry" */	sub		r6, r8, r6	add		r5, r8, r5	blink		t0, ZERO	.long_footer:	movi		4, r8	bgt		r8, r6, t2		/* Long to be checksummed */	ld.l		r5, 0, r7		/* r7 = data to be checksummed*/	add		r4, r7, r4	or		ZERO, ZERO, r7	mshflo.l	r4, r7, r7	shlri		r4, 32, r4	add		r4, r7, r4		/* Add eventual "carry" */	sub		r6, r8, r6	add		r5, r8, r5	blink		t3, ZERO	.word_footer:	movi		2, r8	bgt		r8, r6, t1	/* Short to be checksummed */	ld.uw		r5, 0, r7		/* r7 = data to be checksummed*/	add		r4, r7, r4	or		ZERO, ZERO, r7	mshflo.l	r4, r7, r7	shlri		r4, 32, r4	add		r4, r7, r4		/* Add eventual "carry" */	sub		r6, r8, r6	add		r5, r8, r5	.byte_footer:	beqi		r6, 0, t4	/* Short to be checksummed */	ld.ub		r5, 0, r7		/* r7 = data to be checksummed*/#ifndef __LITTLE_ENDIAN__	shlli		r7, 8, r7#endif	add		r4, r7, r4	or		ZERO, ZERO, r7	mshflo.l	r4, r7, r7	shlri		r4, 32, r4	add		r4, r7, r4		/* Add eventual "carry" */.exit:	or		r4, ZERO, r2	ptabs		r18, t0	blink		t0, ZERO#endif  /*NOTDEF*//* * 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. *//* * SH-5 ABI convention: *    Input parameters: *    		r2  = const char  *src *    		r3  = char	  *dst *    		r4  = int          len *    		r5  = int          sum   so far computed checksum (may be zero) *    		r6  = int         *src_err_ptr *    		r7  = int         *dst_err_ptr *    return value must be in: *              r2	returned checksum */#ifndef NOTDEF  	/* 	** This version of _csum_partial_copy_generic is an easy but	** unefficient implementation. 	** It's mainteined only for historical reasons.		*/	.global csum_partial_copy_genericcsum_partial_copy_generic:	_ptar		.gc_byte_footer, t1	/* t1 = .byte_footer         */	_ptar		.gc_add_short_loop, t2	/* t2 = checksum eval loop   */	_ptar		.gc_exiting, t3		/* t3 = add carry...	     */	or		r2, ZERO, r20		/* r20 = source pointer      */ 	or		r3, ZERO, r21		/* r21 = destination pointer */ 	movi		2, r1	/* we assume buf short aligned */	/* Short must be checksummed   */.gc_add_short_loop:	bgt		r1, r4, t1		/* Size = 1 or 0 (remind)    */

⌨️ 快捷键说明

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