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

📄 unixalib.s

📁 VXWORKS源代码
💻 S
字号:
/* unixALib.s - Assembler optimised UNIX kernel compatability library *//* Copyright 1996-2001 Wind River Systems, Inc. *//*modification history--------------------01h,17oct01,t_m  convert to FUNC_LABEL:01g,11oct01,jb  Enabling removal of pre-pended underscores for new compilers                 (Diab/Gnu elf)01f,21feb01,cdp  fix cksum loss of carry into high-byte (SPR #29703). Comment.01e,08jul98,cdp  added preliminary big-endian support.01d,10mar98,jpd  layout tidying.01c,27oct97,kkk  took out "***EOF***" line from end of file.01b,23may97,jpd  Amalgamated into VxWorks.01a,16jul96,ams  written.*//*DESCRIPTIONThis library provides routines that simulate or replace Unix kernel functionsthat are used in the network code.*/#define _ASMLANGUAGE#include "vxWorks.h"#include "asm.h"	.data	.globl	FUNC(copyright_wind_river)	.long	FUNC(copyright_wind_river)#if (defined(PORTABLE))#define unixALib_PORTABLE#endif#ifndef unixALib_PORTABLE/* Exports */	.global	FUNC(cksum)		/* checksum routine */	.global	FUNC(_insque)	/* insert node in queue after specified node */	.global	FUNC(_remque)	/* remove specified node */	.text	.balign	4/********************************************************************************* cksum - compute check sum** return 16bit sum of 'sum' and the 16bit sum of the string 'string' of byte* length 'len'. Complicated by 'len' or 'sumlen' not being even.* Note, the one's complement is handled by the caller.** RETURNS: the checksum caclulated** NOMANUAL** int cksum*	(*	int	sum;*	char *	string;*	int	len;*	int	sumlen;*	)*/FUNC_LABEL(cksum)#ifdef STACK_FRAMES	mov	ip, sp	stmdb	sp!, {fp, ip, lr, pc}	sub	fp, ip, #4#endif /* STACK_FRAMES */	cmp	r2, #0#ifdef STACK_FRAMES	ldmeqdb	fp, {fp, sp, pc}#else /* !STACK_FRAMES */	moveq	pc, lr			/* Capture 0 */	stmdb	sp!, {lr}		/* Keep return address */#endif /* STACK_FRAMES */	tst	r3, #1			/* Test sumlen for odd count */	beq	L$_Even_Byte	ldrb	r3, [r1], #1		/* Byte left over from last call */#if (_BYTE_ORDER == _BIG_ENDIAN)	add	r0, r0, r3#else	add	r0, r0, r3, lsl #8	/* Add upper byte */#endif	subs	r2, r2, #1		/* One less byte */	beq	L$_All_DoneL$_Even_Byte:	/* Now try to align to a word boundary */	tst	r1, #3			/* Aligned ? */	moveq	lr, #0			/* No offset */	beq	L$_Word_Align	ldr	r3, [r1, #0]		/* Load word */	/*	 * The following may help with understanding of the next bit.	 * If the bytes in memory from address a contain 11 22 33 44	 * LDR from a+0 => 44332211 (little-endian) 11223344 (big-endian)	 *          a+1 => 11443322                 44112233	 *          a+2 => 22114433                 33441122	 *          a+3 => 33221144                 22334411	 */	and	ip, r1, #3		/* Get no of bytes we need from r3 */	rsb	ip, ip, #4		/* The number of bytes we can get */	cmp	r2, ip			/* Have == Got */	movlt	ip, r2			/* Got == Have */#if (_BYTE_ORDER == _BIG_ENDIAN)	tsts	r1, #1	movne	r3, r3, ror #16		/* move addressed byte to b31..24 */	cmps	ip, #2	mov	lr, #0xff000000		/* At least one byte */	orrge	lr, lr, lr, lsr #8	/* The 2nd byte */	orrgt	lr, lr, lr, lsr #8	/* The third byte */	and	r3, r3, lr		/* Mask out bytes we do not want */	/*	 * r3 contains up to 3 bytes to add, in highest 3 bytes of register	 * This can cause carry (e.g 0xffff + 0xffffff00).	 */	adds	r0, r0, r3		/* Add bytes */	adc	r0, r0, #0		/* add in any possible carry */#else	cmp	ip, #2	mov	lr, #0xff		/* At least one byte */	orrge	lr, lr, lr, lsl #8	/* The 2nd byte */	orrgt	lr, lr, lr, lsl #8	/* The third byte */	and	r3, r3, lr		/* Mask out bytes we do not want */	/*	 * r3 contains up to 3 bytes to add, in lowest 3 bytes of register	 * This cannot cause carry.	 */	add	r0, r0, r3		/* Add bytes */#endif	/*	 * Check if rotation of checksum required now so that we do the	 * addition of all the next words the right way round. If we do rotate,	 * save the rotation in lr so we can undo it at the end.	 */	tst	r1, #1			/* Odd alignment */	moveq	lr, #0			/* No offset */	movne	lr, #8			/* Offset from different base */	/*	 * SPR #29703 (T3 SPR #64293): above addition was of a one, two or	 * three byte number to a 16-bit sum and may have caused overflow into	 * the fourth (highest) byte. Original (little-endian) code did an LSL	 * here instead of ROR, incorrectly discarding such overflow. New code	 * is same as big-endian code: it preserves the high byte. (Unimportant	 * whether we shift 8 or 24 bits.)	 */	movne	r0, r0, ror #8		/* Offset, work from a different base */	subs	r2, r2, ip		/* Less bytes */	add	r1, r1, ip		/* Move the pointer */	beq	L$_Boundary_Done	/* We know we will shift */	/* Now we are word aligned */L$_Word_Align:	movs	ip, r2, lsr #2		/* How many words can we add */	beq	L$_Left_123		/* No complete words left */	sub	r2, r2, ip, lsl #2	/* Take number of words off total */	adds	r0, r0, #0		/* Clear carry */	ands	r3, ip, #0x0f		/* Last 16 ? (Does not clear carry) */	/* Compute offset to start with in the loop */	rsbne	r3, r3, #16		/* Where to start */	addne	r3, pc, r3, lsl #3	/* Where to jump */	movne	pc, r3			/* And jump */0:	ldr	r3, [r1], #4		/* 1 */	adds	r0, r0, r3		/* Carry already added */	ldr	r3, [r1], #4		/* 2 */	adcs	r0, r0, r3	ldr	r3, [r1], #4		/* 3 */	adcs	r0, r0, r3	ldr	r3, [r1], #4		/* 4 */	adcs	r0, r0, r3	ldr	r3, [r1], #4		/* 5 */	adcs	r0, r0, r3	ldr	r3, [r1], #4		/* 6 */	adcs	r0, r0, r3	ldr	r3, [r1], #4		/* 7 */	adcs	r0, r0, r3	ldr	r3, [r1], #4		/* 8 */	adcs	r0, r0, r3	ldr	r3, [r1], #4		/* 9 */	adcs	r0, r0, r3	ldr	r3, [r1], #4		/* 10 */	adcs	r0, r0, r3	ldr	r3, [r1], #4		/* 11 */	adcs	r0, r0, r3	ldr	r3, [r1], #4		/* 12 */	adcs	r0, r0, r3	ldr	r3, [r1], #4		/* 13 */	adcs	r0, r0, r3	ldr	r3, [r1], #4		/* 14 */	adcs	r0, r0, r3	ldr	r3, [r1], #4		/* 15 */	adcs	r0, r0, r3	ldr	r3, [r1], #4		/* 16 */	adcs	r0, r0, r3	adc	r0, r0, #0		/* Add Carry */	subs	ip, ip, #16		/* 16 words less ! */	bgt	0b	/* Main loop complete, less than 4 bytes left */	cmp	r2, #0	beq	L$_Boundary_Done	/* Completed on a word boundary */	/* 1, 2 or 3 bytes left */L$_Left_123:	/* Completed on an odd boundary, do we shift the sum back ? */	mov	r0, r0, ror lr		/* Shift total */	/* Extract the last byte/s */#if (_BYTE_ORDER == _BIG_ENDIAN)	cmp	r2, #2	mov	r2, #0xff000000		/* At least one byte */	orrge	r2, r2, r2, lsr #8	/* The 2nd byte */	orrgt	r2, r2, r2, lsr #8	/* The third byte */	ldr	r3, [r1, #0]		/* Load word */	and	r3, r3, r2		/* Mask out bytes we do not want */	adds	r0, r0, r3, lsr lr	/* Add bytes */#else	cmp	r2, #2	mov	r2, #0xff		/* At least one byte */	orrge	r2, r2, r2, lsl #8	/* The 2nd byte */	orrgt	r2, r2, r2, lsl #8	/* The third byte */	ldr	r3, [r1, #0]		/* Load word */	and	r3, r3, r2		/* Mask out bytes we do not want */	adds	r0, r0, r3, lsl lr	/* Add bytes */#endif	adc	r0, r0, #0		/* Add carry */	adds	r0, r0, r0, lsl #16	/* Result in upper 16 bits + C */	mov	r0, r0, lsr #16		/* Get upper 16 bits */	adc	r0, r0, #0		/* Add carry */#ifdef STACK_FRAMES	ldmdb	fp, {fp, sp, pc}	/* Return (sum is in r0) */#else /* !STACK_FRAMES */	ldmia	sp!, {pc}		/* Return (sum is in r0) */#endif /* STACK_FRAMES */	/* Completed on a boundary */L$_Boundary_Done:	mov	r0, r0, ror lr		/* Shift total back 8 */L$_All_Done:	adds	r0, r0, r0, lsl #16	/* Result in upper 16 bits + C */	mov	r0, r0, lsr #16		/* Get upper 16 bits */	adc	r0, r0, #0		/* Add carry */#ifdef STACK_FRAMES	ldmdb	fp, {fp, sp, pc}	/* Return (sum is in r0) */#else /* !STACK_FRAMES */	ldmia	sp!, {pc}		/* Return (sum is in r0) */#endif /* STACK_FRAMES *//********************************************************************************* _insque - insert node in list after specified node.** RETURNS: N/A** NOMANUAL** void _insque*	(*	NODE *	pNode,*	NODE *	pPrev*	)*/FUNC_LABEL(_insque)#ifdef STACK_FRAMES	mov	ip, sp	stmdb	sp!, {fp, ip, lr, pc}	sub	fp, ip, #4#endif /* STACK_FRAMES */	ldr	r3, [r1, #0]		/* r3 = pPrev->next */	str	r0, [r1, #0]		/* pPrev->next = pNode */	str	r0, [r3, #4]		/* r3->previous = pNode */	str	r3, [r0, #0]		/* pNode->next = r3 */	str	r1, [r0, #4]		/* pNode->previous = pPrev */	/* Done */#ifdef STACK_FRAMES	ldmdb	fp, {fp, sp, pc}#else /* !STACK_FRAMES */	mov	pc, lr#endif /* STACK_FRAMES *//********************************************************************************* _remque - remove specified node in list.** RETURNS: N/A** NOMANUAL** void _remque*	(*	NODE *	pNode*	)*/FUNC_LABEL(_remque)#ifdef STACK_FRAMES	mov	ip, sp	stmdb	sp!, {fp, ip, lr, pc}	sub	fp, ip, #4#endif /* STACK_FRAMES */	/* Setup */	ldr	r2, [r0, #4]		/* r2 = pNode->previous */	ldr	r3, [r0, #0]		/* r3 = pNode->next */	/*  pNode->previous->next = pNode->next */	str	r3, [r2, #0]		/* r2->next = r3 */	/* pNode->next->previous = pNode->previous */	str	r2, [r3, #4]#ifdef STACK_FRAMES	ldmdb	fp, {fp, sp, pc}#else /* !STACK_FRAMES */	mov	pc, lr#endif /* STACK_FRAMES */#endif /* ! unixALib_PORTABLE */

⌨️ 快捷键说明

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