📄 balib.s
字号:
bge Down_LT16b /* tmp1 contains three bytes */Down_LT4b: /* Less than four bytes to go - readjust the src address. */ add src, src, #3 b Down_TrailingBytes/* * The last two source bytes are in tmp1, two bytes must * come from the previous source word. At least four bytes * more must be stored. */Down_TwoBytes: cmp n, #16-4 /* at least 16 bytes? */ blt Down_LT16c /* no */ sub n, n, #16-4 /* (n+16) bytes to go */ stmfd sp!, {v1, v2, lr} /* Save registers */ /* * loop doing 32 bytes at a time. There are currently * two useful bytes in tmp1 (a4). */Down_32c: mov lr, tmp1, SHA #16 /* last two bytes */ ldmdb src!, {tmp1, v1, v2, tmp3} orr lr, lr, tmp3, SLA #16 /* word 4 */ mov tmp3, tmp3, SHA #16 orr tmp3, tmp3, v2, SLA #16 /* word 3 */ mov v2, v2, SHA #16 orr v2, v2, v1, SLA #16 /* word 2 */ mov v1, v1, SHA #16 orr v1, v1, tmp1, SLA #16 /* word 1 */ stmdb dst!, {v1, v2, tmp3, lr} subs n, n, #16 bge Down_32c ldmfd sp!, {v1, v2, lr} /* Reload registers */ adds n, n, #16-4 /* check for at least 4 */ blt Down_LT4c /* < 4 bytes */Down_LT16c: mov tmp3, tmp1, SHA #16 /* last two bytes */ ldr tmp1, [src, #-4]! /* previous four bytes */ orr tmp3, tmp3, tmp1, SLA #16 str tmp3, [dst, #-4]! subs n, n, #4 bge Down_LT16c /* tmp1 contains two bytes */Down_LT4c: /* Less than four bytes to go - readjust the src address. */ add src, src, #2 b Down_TrailingBytes/* * The last source byte is in tmp1, three bytes must * come from the previous source word. At least four bytes * more must be stored. */Down_OneByte: cmp n, #16-4 /* at least 16 bytes? */ blt Down_4d /* no */ sub n, n, #16-4 /* (n+16) bytes to go */ stmfd sp!, {v1, v2, lr} /* save registers */ /* * loop doing 32 bytes at a time. There is currently * one useful byte in tmp1 (a4). */Down_32d: mov lr, tmp1, SHA #24 /* last byte */ ldmdb src!, {tmp1, v1, v2, tmp3} orr lr, lr, tmp3, SLA #8 /* word 4 */ mov tmp3, tmp3, SHA #24 orr tmp3, tmp3, v2, SLA #8 /* word 3 */ mov v2, v2, SHA #24 orr v2, v2, v1, SLA #8 /* word 2 */ mov v1, v1, SHA #24 orr v1, v1, tmp1, SLA #8 /* word 1 */ stmdb dst!, {v1, v2, tmp3, lr} subs n, n, #16 bge Down_32d ldmfd sp!, {v1, v2, lr} /* Reload registers */ adds n, n, #16-4 /* check for at least 4 */ blt Down_LT4d /* < 4 bytes */Down_4d: mov tmp3, tmp1, SHA #24 /* last byte */ ldr tmp1, [src, #-4]! /* previous four bytes */ orr tmp3, tmp3, tmp1, SLA #8 str tmp3, [dst, #-4]! subs n, n, #4 bge Down_4d /* tmp1 contains one byte */Down_LT4d: /* Less than four bytes to go - one already in tmp3. */ add src, src, #1 b Down_TrailingBytes/********************************************************************************* bcopyBytes - copy one buffer to another one byte at a time** This routine copies the first <nbytes> characters from <source> to* <destination> one byte at a time. This may be desirable if a buffer can* only be accessed with byte instructions, as in certain byte-wide* memory-mapped peripherals.** RETURNS N/A** NOMANUAL** void bcopyBytes* (* char * source, /@ pointer to source buffer @/* char * destination, /@ pointer to destination buffer @/* int nbytes /@ number of bytes to copy @/* )*/FUNC_LABEL(bcopyBytes)#ifdef STACK_FRAMES mov ip, sp stmdb sp!, {fp, ip, lr, pc} sub fp, ip, #4#endif /* STACK_FRAMES */ /* Quick check for 0 */ cmp n, #0#ifdef STACK_FRAMES ldmeqdb fp, {fp, sp, pc}#else /* !STACK_FRAMES */ moveq pc, lr#endif /* STACK_FRAMES */ /* Determine if forward or backward copy required */ subs tmp1, dst, src#ifdef STACK_FRAMES ldmeqdb fp, {fp, sp, pc} /* Same */#else /* !STACK_FRAMES */ moveq pc, lr /* Same */#endif /* STACK_FRAMES */ blt copyBytes_Forward cmp tmp1, n bge copyBytes_Forward/* * backward copy * The copy loop is rolled out in one loop of 16 byte copies. The loop is * initiated by jumping into the loop at location (n % 16). */ /* Adjust pointers to the end of the buffer */ add dst, dst, n add src, src, n /* Compute jump offset if necessary */ ands tmp1, n, #0x0f /* Odd count */ rsbne tmp1, tmp1, #16 /* Offset to jump into */ addne tmp1, pc, tmp1, lsl #3 /* Jump address */ movne pc, tmp1 /* Do the dirty */BacwB_Loop: /* Loop here while we have bytes to copy */ ldrb tmp3, [src, #-1]! /* 16 */ strb tmp3, [dst, #-1]! ldrb tmp3, [src, #-1]! /* 15 */ strb tmp3, [dst, #-1]! ldrb tmp3, [src, #-1]! /* 14 */ strb tmp3, [dst, #-1]! ldrb tmp3, [src, #-1]! /* 13 */ strb tmp3, [dst, #-1]! ldrb tmp3, [src, #-1]! /* 12 */ strb tmp3, [dst, #-1]! ldrb tmp3, [src, #-1]! /* 11 */ strb tmp3, [dst, #-1]! ldrb tmp3, [src, #-1]! /* 10 */ strb tmp3, [dst, #-1]! ldrb tmp3, [src, #-1]! /* 9 */ strb tmp3, [dst, #-1]! ldrb tmp3, [src, #-1]! /* 8 */ strb tmp3, [dst, #-1]! ldrb tmp3, [src, #-1]! /* 7 */ strb tmp3, [dst, #-1]! ldrb tmp3, [src, #-1]! /* 6 */ strb tmp3, [dst, #-1]! ldrb tmp3, [src, #-1]! /* 5 */ strb tmp3, [dst, #-1]! ldrb tmp3, [src, #-1]! /* 4 */ strb tmp3, [dst, #-1]! ldrb tmp3, [src, #-1]! /* 3 */ strb tmp3, [dst, #-1]! ldrb tmp3, [src, #-1]! /* 2 */ strb tmp3, [dst, #-1]! ldrb tmp3, [src, #-1]! /* 1 */ strb tmp3, [dst, #-1]! /* Finished iteration */ subs n, n, #16 /* > 0 (and / 16) if any left */ bgt BacwB_Loop /* Another 16 ? */ /* Return */#ifdef STACK_FRAMES ldmdb fp, {fp, sp, pc}#else /* !STACK_FRAMES */ mov pc, lr#endif /* STACK_FRAMES *//* * forward copy * The copy loop is rolled out in one loop of 16 byte copies. The loop is * initiated by jumping into the loop at location (n % 16). */copyBytes_Forward: /* Compute jump offset if necessary */ ands tmp1, n, #0x0f /* Odd count */ rsbne tmp1, tmp1, #16 /* Offset to jump into */ addne tmp1, pc, tmp1, lsl #3 /* Jump address */ movne pc, tmp1 /* Do the dirty */ForwB_Loop: /* Loop here while we have bytes to copy */ ldrb tmp1, [src], #1 /* 16 */ strb tmp1, [dst], #1 ldrb tmp1, [src], #1 /* 15 */ strb tmp1, [dst], #1 ldrb tmp1, [src], #1 /* 14 */ strb tmp1, [dst], #1 ldrb tmp1, [src], #1 /* 13 */ strb tmp1, [dst], #1 ldrb tmp1, [src], #1 /* 12 */ strb tmp1, [dst], #1 ldrb tmp1, [src], #1 /* 11 */ strb tmp1, [dst], #1 ldrb tmp1, [src], #1 /* 10 */ strb tmp1, [dst], #1 ldrb tmp1, [src], #1 /* 9 */ strb tmp1, [dst], #1 ldrb tmp1, [src], #1 /* 8 */ strb tmp1, [dst], #1 ldrb tmp1, [src], #1 /* 7 */ strb tmp1, [dst], #1 ldrb tmp1, [src], #1 /* 6 */ strb tmp1, [dst], #1 ldrb tmp1, [src], #1 /* 5 */ strb tmp1, [dst], #1 ldrb tmp1, [src], #1 /* 4 */ strb tmp1, [dst], #1 ldrb tmp1, [src], #1 /* 3 */ strb tmp1, [dst], #1 ldrb tmp1, [src], #1 /* 2 */ strb tmp1, [dst], #1 ldrb tmp1, [src], #1 /* 1 */ strb tmp1, [dst], #1 /* Next iteration ? */ subs n, n, #16 /* > 0 (and / 16) if any left */ bgt ForwB_Loop /* Another 16 ? */ /* Return */#ifdef STACK_FRAMES ldmdb fp, {fp, sp, pc}#else /* !STACK_FRAMES */ mov pc, lr#endif /* STACK_FRAMES *//********************************************************************************* bcopyWords - copy one buffer to another one half-word (16 bits) at a time** This routine copies the first <nwords> words from <source> to <destination>* one word at a time. This may be desirable if a buffer can only be accessed* with word instructions, as in certain word-wide memory-mapped peripherals.* The source and destination must be word-aligned.** RETURNS: N/A** NOMANUAL** void bcopyWords* (* char * source, /@ pointer to source buffer @/* char * destination, /@ pointer to destination buffer @/* int nwords /@ number of words to copy @/* )*/FUNC_LABEL(bcopyWords)#ifdef STACK_FRAMES mov ip, sp stmdb sp!, {v1, fp, ip, lr, pc} sub fp, ip, #4#endif /* STACK_FRAMES */ /* Quick check for 0 */ cmp n, #0#ifdef STACK_FRAMES ldmeqdb fp, {v1, fp, sp, pc}#else /* !STACK_FRAMES */ moveq pc, lr#endif /* STACK_FRAMES */ /* Determine if forward or backward copy required */ subs tmp1, dst, src#ifdef STACK_FRAMES ldmeqdb fp, {v1, fp, sp, pc}#else /* !STACK_FRAMES */ moveq pc, lr /* Same */#endif /* STACK_FRAMES */#if ARM_HAS_HALFWORD_INSTRUCTIONS /* Find direction */ blt copyWords_Forward mov tmp3, n, asl #1 /* Convert to bytes */ cmp tmp1, tmp3 bge copyWords_Forward/* * backward copy * The copy loop is rolled out in one loop of 16 word copies. The loop is * initiated by jumping into the loop at location (n % 16). */ /* Adjust pointers to the end of the buffer */ add dst, dst, tmp3 add src, src, tmp3 /* Compute jump offset if necessary */ ands tmp1, n, #0x0f /* Odd count */ rsbne tmp1, tmp1, #16 /* Offset to jump into */ addne tmp1, pc, tmp1, lsl #3 /* Jump address */ movne pc, tmp1 /* Do the dirty */BacwW_Loop: /* Loop here while we have words to copy */ ldrh tmp3, [src, #-2]! /* 16 */ strh tmp3, [dst, #-2]! ldrh tmp3, [src, #-2]! /* 15 */ strh tmp3, [dst, #-2]! ldrh tmp3, [src, #-2]! /* 14 */ strh tmp3, [dst, #-2]! ldrh tmp3, [src, #-2]! /* 13 */ strh tmp3, [dst, #-2]! ldrh tmp3, [src, #-2]! /* 12 */ strh tmp3, [dst, #-2]! ldrh tmp3, [src, #-2]! /* 11 */ strh tmp3, [dst, #-2]! ldrh tmp3, [src, #-2]! /* 10 */ strh tmp3, [dst, #-2]! ldrh tmp3, [src, #-2]! /* 9 */ strh tmp3, [dst, #-2]! ldrh tmp3, [src, #-2]! /* 8 */ strh tmp3, [dst, #-2]! ldrh tmp3, [src, #-2]! /* 7 */ strh tmp3, [dst, #-2]! ldrh tmp3, [src, #-2]! /* 6 */ strh tmp3, [dst, #-2]! ldrh tmp3, [src, #-2]! /* 5 */ strh tmp3, [dst, #-2]! ldrh tmp3, [src, #-2]! /* 4 */ strh tmp3, [dst, #-2]! ldrh tmp3, [src, #-2]! /* 3 */ strh tmp3, [dst, #-2]! ldrh tmp3, [src, #-2]! /* 2 */ strh tmp3, [dst, #-2]! ldrh tmp3, [src, #-2]! /* 1 */ strh tmp3, [dst, #-2]! /* Iteration complete */ subs n, n, #16 /* > 0 (and / 16) if any left */ bgt BacwW_Loop /* Another 16 ? */ /* Return */#ifdef STACK_FRAMES ldmdb fp, {v1, fp, sp, pc}#else /* !STACK_FRAMES */ mov pc, lr#endif /* STACK_FRAMES *//* * forward copy * The copy loop is rolled out in one loop of 16 word copies. The loop is * initiated by jumping into the loop at location (n % 16). */copyWords_Forward: /* Compute jump offset if necessary */ ands tmp1, n, #0x0f /* Odd count */ rsbne tmp1, tmp1, #16 /* Offset to jump into */ addne tmp1, pc, tmp1, lsl #3 /* Jump address */ movne pc, tmp1 /* Do the dirty */ForwW_Loop: /* Loop here while we have words to copy */ ldrh tmp1, [src], #2 /* 16 */ strh tmp1, [dst], #2 ldrh tmp1, [src], #2 /* 15 */ strh tmp1, [dst], #2 ldrh tmp1, [src], #2 /* 14 */ strh tmp1, [dst], #2 ldrh tmp1, [src], #2 /* 13 */ strh tmp1, [dst], #2 ldrh tmp1, [src], #2 /* 12 */ strh tmp1, [dst], #2 ldrh tmp1, [src], #2 /* 11 */ strh tmp1, [dst], #2 ldrh tmp1, [src], #2 /* 10 */ strh tmp1, [dst], #2 ldrh tmp1, [src], #2 /* 9 */ strh tmp1, [dst], #2 ldrh tmp1, [src], #2 /* 8 */ strh tmp1, [dst], #2 ldrh tmp1, [src], #2 /* 7 */ strh tmp1, [dst], #2 ldrh tmp1, [src], #2 /* 6 */ strh tmp1, [dst], #2 ldrh tmp1, [src], #2 /* 5 */ strh tmp1, [dst], #2 ldrh tmp1, [src], #2 /* 4 */ strh tmp1, [dst], #2 ldrh tmp1, [src], #2 /* 3 */ strh tmp1, [dst], #2 ldrh tmp1, [src], #2 /* 2 */ strh tmp1, [dst], #2 ldrh tmp1, [src], #2 /* 1 */ strh tmp1, [dst], #2 /* Iteration complete */ subs n, n, #16 /* > 0 (and / 16) if any left */ bgt ForwW_Loop /* Another 16 ? */ /* Return */#ifdef STACK_FRAMES ldmdb fp, {v1, fp, sp, pc}#else /* !STACK_FRAMES */ mov pc, lr#endif /* STACK_FRAMES */#else /* ! ARM_HAS_HALFWORD_INSTRUCTIONS */#ifndef STACK_FRAMES stmfd sp!, {v1, lr} /* Save regs */#endif /* STACK_FRAMES */ /* Find direction */ blt copyWords_Forward mov tmp3, n, asl #1 /* Convert to bytes */ cmp tmp1, tmp3 bge copyWords_Forward/* backward copy: adjust pointers to the end of the buffer */ add dst, dst, tmp3 add src, src, tmp3 /* Check if 16-bit aligned */ tst src, #2 /* 16 bit aligned */ beq BacwW_Aligned ldrb tmp3, [src, #-1]! /* Extra word, 1st byte*/ strb tmp3, [dst, #-1]! ldrb tmp3, [src, #-1]! /* Extra word, 2nd byte*/ strb tmp3, [dst, #-1]! subs n, n, #1 /* One less */#ifdef STACK_FRAMES ldmeqdb fp, {v1, fp, sp, pc} /* Done ? */#else /* !STACK_FRAMES */ ldmeqfd sp!, {v1, pc} /* Done ? */#endif /* STACK_FRAMES */BacwW_Aligned:/* The copy loop is rolled out in one loop of 16 32-bit copies. */ /* Copy 16 longs (32 shorts) ? */ subs n, n, #32 blt CWB_LT32BacwW_Loop: /* Loop here while we have > 32 words to copy */ ldmdb src!, {tmp1, v1, tmp3, lr} /* 8 */ stmdb dst!, {tmp1, v1, tmp3, lr} ldmdb src!, {tmp1, v1, tmp3, lr} /* 16 */ stmdb dst!, {tmp1, v1, tmp3, lr} ldmdb src!, {tmp1, v1, tmp3, lr} /* 24 */ stmdb dst!, {tmp1, v1, tmp3, lr} ldmdb src!, {tmp1, v1, tmp3, lr} /* 32 */ stmdb dst!, {tmp1, v1, tmp3, lr} subs n, n, #32 bge BacwW_LoopCWB_LT32: /* Here if less than 32 longs to copy */ adds n, n, #32#ifdef STACK_FRAMES ldmeqdb fp, {v1, fp, sp, pc} /* Done */#else /* !STACK_FRAMES */ ldmeqfd sp!, {v1, pc} /* Done */#endif /* STACK_FRAMES */ /* Possible 24 to copy */ movs tmp1, n, asr #3 /* How many groups of 8 ? */ beq CWB_LT8 /* None */ /* Remove 8/16/24 from the counter */ sub n, n, tmp1, asl #3 /* 8, 16 or 24 words */ cmp tmp1, #2 ldmdb src!, {tmp1, v1, tmp3, lr} /* 8 */ stmdb dst!, {tmp1, v1, tmp3, lr} ldmgedb src!, {tmp1, v1, tmp3, lr} /* 16 */ stmgedb dst!, {tmp1, v1, tmp3, lr} ldmgtdb src!, {tmp1, v1, tmp3, lr} /* 24 */ stmgtdb dst!, {tmp1, v1, tmp3, lr} /* Less than 8 words to copy */ cmp n, #0 /* Anything left ? */#ifdef STACK_FRAMES ldmeqdb fp, {v1, fp, sp, pc} /* Nope, done */#else /* !STACK_FRAMES */ ldmeqfd sp!, {v1, pc} /* Nope, done */#endif /* STACK_FRAMES */CWB_LT8: /* Convert to complete 32-bit words (0,1,2,3) */ movs tmp1, n, asr #1 /* 32-bit words */ beq CWB_EQ1 /* 0*32-bit, 1*16 words left? */ cmp tmp1, #2 ldr tmp3, [src, #-4]! /* 1 */ str tmp3, [dst, #-4]! ldrge tmp3, [src, #-4]! /* 2 */ strge tmp3, [dst, #-4]! ldrgt tmp3, [src, #-4]! /* 3 */ strgt tmp3, [dst, #-4]! subs n, n, tmp1, asl #1 /* Take off what we copied */#ifdef STACK_FRAMES ldmeqdb fp, {v1, fp, sp, pc} /* Done ? */#else /* !STACK_FRAMES */ ldmeqfd sp!, {v1, pc} /* Done ? */#endif /* STACK_FRAMES */ CWB_EQ1:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -