📄 unixalib.s
字号:
/* unixALib.s - Assembler optimised UNIX kernel compatability library *//* Copyright 1996-1998 Wind River Systems, Inc. */ .data .globl _copyright_wind_river .long _copyright_wind_river/*modification history--------------------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"#if (defined(PORTABLE))#define unixALib_PORTABLE#endif#ifndef unixALib_PORTABLE/* Exports */ .global _cksum /* checksum routine */ .global __insque /* insert node in queue after specified node */ .global __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;* )*/_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 */ add r0, r0, r3, lsl #8 /* Add upper byte */ 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 */ and ip, r1, #3 /* Get no of bytes do 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 */ 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 */ /* Adjustment required */ add r0, r0, r3 /* Add bytes */ tst r1, #1 /* Odd alignment */ moveq lr, #0 /* No offset */ movne lr, #8 /* Offset from different base */ movne r0, r0, lsl #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 */ 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 */ 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* )*/__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* )*/__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 + -