📄 memory_asm_cpu.s
字号:
waligni wR3, wR3, wR3, #2LABEL(L105) tst LENGTH, #1 wstrbne wR3, [r6] ldmfd sp!, {r4-r7,lr} BR_REG(lr) /* Return to caller. */ LABEL(LM2) /* Do alignment for the starting part. If the unaligned byte number of src is smaller than that of dest, |<-src wR0 -> s6 s5 s4 s3 s2 s1 s0 x0 wR3 -> y7 y6 y5 y4 y3 y2 y1 y0 |<-dest Result -> s4 s3 s2 s1 s0 y2 y1 y0. Step 1 -> y2 y1 y0 z4 z3 z2 z1 z0 Step 2 -> z0 s6 s5 s4 s3 s2 s1 s0 Step 3 -> s4 s3 s2 s1 s0 y2 y1 y0 */ add r7, r7, #8 bic r6, DEST, #7 /*r6 = address 8-byte aligned */ wldrd wR3, [r6] bic r4, SRC, #7 /*r4 = address 8-byte aligned */ wldrd wR0, [r4], #8 tmcr wCGR2, r5 /*wCGR0 = number of bytes to be aligned */ tmcr wCGR1, r3 /*wCGR1 = number of bytes to be aligned */ tmcr wCGR0, r7 /*wCGR2 = number of bytes to be aligned */ rsb r12, r5, #8 sub LENGTH, LENGTH, r12 tmcr wCGR3, r12 /*wCGR3 = number of bytes to be aligned */ walignr2 wR2, wR1, wR3 /* Step 1 */ walignr1 wR4, wR0, wR1 /* Step 2 */ wldrd wR1, [r4], #8 sub LENGTH, LENGTH, #24 walignr3 wR4, wR2, wR4 /* Step 3 */ wldrd wR2, [r4], #8 wstrd wR4, [r6], #8 /* The first unaligned 8-byte has been done. Begin mainloop of 8-byte memmove. */ b LM1 LABEL(memmove8Bit_smallLength)#endif /* IAI_MEMMOVE */ tst SRC, #0x3 /* Check if already word aligned. */ bne memmove8Bit_alignedLeadingByteLABEL(memmove8Bit_alignedWords) and r12, LENGTH, #0x3 bic LENGTH, LENGTH, #0x3 subs LENGTH, LENGTH, #4 blt memmove8Bit_alignedWordsTrailingHalfword /* Check if the DEST is word aligned. The SRC * is already word aligned when we get here. */ tst DEST, #0x3 /* Check if low 2 bits are 0. */ bne memmove8Bit_unalignedLoopLABEL(memmove8Bit_alignedWordsLoop) ldr r3, [SRC], #4 subs LENGTH, LENGTH, #4 str r3, [DEST], #4 bge memmove8Bit_alignedWordsLoopLABEL(memmove8Bit_alignedWordsTrailingHalfword) /* Copy the trailing half word if necessary: */ tst r12, #0x2 beq memmove8Bit_alignedTrailingByte ldrh r3, [SRC], #2 /* Can't do strh because the DEST pointer * is not guaranteed to be half-word aligned. */#if CVM_ENDIANNESS == CVM_BIG_ENDIAN mov r3, r3, ror #8 strb r3, [DEST], #1 mov r3, r3, ror #24 strb r3, [DEST], #1#elif CVM_ENDIANNESS == CVM_LITTLE_ENDIAN strb r3, [DEST], #1 mov r3, r3, lsr #8 strb r3, [DEST], #1#endifLABEL(memmove8Bit_alignedTrailingByte) /* Copy the trailing byte if necessary: */ tst r12, #0x1 BRCOND_REG(lr,eq) /* Done. Return to caller. */ ldrb r3, [SRC] strb r3, [DEST]LABEL(memmove8Bit_alignedWordsDone) BR_REG(lr) /* Return to caller. */LABEL(memmove8Bit_alignedLeadingByte) /* Copy leading byte if necessary: */ tst SRC, #0x1 beq memmove8Bit_alignedLeadingHalfWord ldrb r3, [SRC], #1 subs LENGTH, LENGTH, #1 strb r3, [DEST], #1 BRCOND_REG(lr,ls) /* Done. LENGTH = 1 */ LABEL(memmove8Bit_alignedLeadingHalfWord) /* Copy the leading halfword if necessary: */ tst SRC, #0x2 beq memmove8Bit_alignedWords ldrh r3, [SRC], #2 subs LENGTH, LENGTH, #2 /* Can't do strh because the DEST pointer * is not guaranteed to be half-word aligned. */#if CVM_ENDIANNESS == CVM_BIG_ENDIAN mov r3, r3, ror #8 strb r3, [DEST], #1 mov r3, r3, ror #24 strgeb r3, [DEST], #1 /* LENGTH >= 2 */#elif CVM_ENDIANNESS == CVM_LITTLE_ENDIAN strb r3, [DEST], #1 mov r3, r3, lsr #8 strgeb r3, [DEST], #1 /* LENGTH >= 2 */#endif bgt memmove8Bit_alignedWords BR_REG(lr) /* Done. */LABEL(memmove8Bit_unalignedLoop) /* The SRC pointer is word aligned when we get here. The * DEST pointer however is not. */ ldr r3, [SRC], #4 subs LENGTH, LENGTH, #4#if CVM_ENDIANNESS == CVM_BIG_ENDIAN mov r3, r3, ror #24 strb r3, [DEST], #1 mov r3, r3, ror #24 strb r3, [DEST], #1 mov r3, r3, ror #24 strb r3, [DEST], #1 mov r3, r3, ror #24 strb r3, [DEST], #1#elif CVM_ENDIANNESS == CVM_LITTLE_ENDIAN strb r3, [DEST], #1 mov r3, r3, lsr #8 strb r3, [DEST], #1 mov r3, r3, lsr #8 strb r3, [DEST], #1 mov r3, r3, lsr #8 strb r3, [DEST], #1#endif bge memmove8Bit_unalignedLoop b memmove8Bit_alignedWordsTrailingHalfword /* Loop done */ /* ===============================================================*/LABEL(memmove8Bit_inverse)/* IAI-01 */#ifdef IAI_MEMMOVE cmp LENGTH, #64 blt memmove8Bit_inverse_smallLength#ifdef IAI_MEMMOVE_PLD pld [SRC] pld [SRC, #32] pld [SRC, #64] pld [DEST] pld [DEST, #32] pld [DEST, #64]#endif add SRC, SRC, LENGTH add DEST, DEST, LENGTH /* Check if the DEST and SRC pointers are similarly aligned: */ eor r3, SRC, DEST /* Equal bits will become 0. */ tst r3, #0x7 /* Check if low 3 bits are equal. */ bne memmove8Bit_inverse_unaligned /* Do aligned copying: */ tst SRC, #0x7 /* Check if already double word aligned. */ bne memmove8Bit_inverse_alignedDoubleWordsLeadingByte LABEL(memmove8Bit_inverse_alignedDoubleWords) wldrd wR0, [SRC, #-8]! and r12, LENGTH, #7 wldrd wR1, [SRC, #-8]! sub LENGTH, LENGTH, #24 wldrd wR2, [SRC, #-8]! LABEL(IL10)#ifdef IAI_MEMMOVE_PLD2 pld [SRC, #-64] pld [DEST, #-64]#endif wstrd wR0, [DEST, #-8]! wldrd wR0, [SRC, #-8]! wstrd wR1, [DEST, #-8]! wldrd wR1, [SRC, #-8]! wstrd wR2, [DEST, #-8]! wldrd wR2, [SRC, #-8]! subs LENGTH, LENGTH, #24 bge IL10 LABEL(memmove8Bit_inverse_alignedDoubleWordsTrailingTripleword) adds LENGTH, LENGTH, #8 blt memmove8Bit_inverse_alignedDoubleWordsTrailingDoubleword wstrd wR0, [DEST, #-8]! wmov wR0, wR1 wmov wR1, wR2 LABEL(memmove8Bit_inverse_alignedDoubleWordsTrailingDoubleword) adds LENGTH, LENGTH, #8 blt memmove8Bit_inverse_alignedDoubleWordsTrailingword wstrd wR0, [DEST, #-8]! wmov wR0, wR1 LABEL(memmove8Bit_inverse_alignedDoubleWordsTrailingword) /* Copy the trailing word if necessary: */ tst r12, #0x4 beq memmove8Bit_inverse_alignedDoubleWordsTrailingHalfword waligni wR0, wR0, wR0, #4 wstrw wR0, [DEST, #-4]! LABEL(memmove8Bit_inverse_alignedDoubleWordsTrailingHalfword) /* Copy the trailing half word if necessary: */ tst r12, #0x2 beq memmove8Bit_inverse_alignedDoubleWordsTrailingByte waligni wR0, wR0, wR0, #6 wstrh wR0, [DEST, #-2]!LABEL(memmove8Bit_inverse_alignedDoubleWordsTrailingByte) /* Copy the trailing byte if necessary: */ tst r12, #0x1 walignine wR0, wR0, wR0, #7 wstrbne wR0, [DEST, #-1]LABEL(memmove8Bit_inverse_alignedDoubleWordsDone) BR_REG(lr) /* Return to caller. */LABEL(memmove8Bit_inverse_alignedDoubleWordsLeadingByte) /* Copy leading byte if necessary: */ tst SRC, #0x1 beq memmove8Bit_inverse_alignedDoubleWordsLeadingHalfWord ldrb r3, [SRC, #-1]! sub LENGTH, LENGTH, #1 strb r3, [DEST, #-1]!LABEL(memmove8Bit_inverse_alignedDoubleWordsLeadingHalfWord) /* Copy the leading halfword if necessary: */ tst SRC, #0x2 beq memmove8Bit_inverse_alignedDoubleWordsLeadingWord ldrh r3, [SRC, #-2]! sub LENGTH, LENGTH, #2 strh r3, [DEST, #-2]! LABEL(memmove8Bit_inverse_alignedDoubleWordsLeadingWord) /* Copy the leading word if necessary: */ tst SRC, #0x4 beq memmove8Bit_inverse_alignedDoubleWords ldr r3, [SRC, #-4]! sub LENGTH, LENGTH, #4 str r3, [DEST, #-4]! b memmove8Bit_inverse_alignedDoubleWordsLABEL(memmove8Bit_inverse_alignedWordCheck) tst SRC, #0x7 /* Check if already double word aligned. */ bne memmove8Bit_inverse_alignedWordLeadingByte LABEL(memmove8Bit_inverse_alignedWord) wldrd wR0, [SRC, #-8]! ldr r12, [SRC, #4] wldrd wR1, [SRC, #-8]! sub LENGTH, LENGTH, #28 str r12, [DEST, #-4]! wldrd wR2, [SRC, #-8]! and r12, LENGTH, #7 LABEL(IL11)#ifdef IAI_MEMMOVE_PLD2 pld [SRC, #-64] pld [DEST, #-64]#endif waligni wR3, wR1, wR0, #4 wldrd wR0, [SRC, #-8]! wstrd wR3, [DEST, #-8]! waligni wR4, wR2, wR1, #4 wldrd wR1, [SRC, #-8]! wstrd wR4, [DEST, #-8]! waligni wR5, wR0, wR2, #4 wldrd wR2, [SRC, #-8]! wstrd wR5, [DEST, #-8]! subs LENGTH, LENGTH, #24 bge IL11 LABEL(memmove8Bit_inverse_alignedWordTrailingTripleword) adds LENGTH, LENGTH, #8 blt memmove8Bit_inverse_alignedWordTrailingDoubleword waligni wR3, wR1, wR0, #4 wmov wR0, wR1 wmov wR1, wR2 wldrd wR2, [SRC, #-8]! wstrd wR3, [DEST, #-8]!LABEL(memmove8Bit_inverse_alignedWordTrailingDoubleword) adds LENGTH, LENGTH, #8 blt memmove8Bit_inverse_alignedWordTrailingword waligni wR3, wR1, wR0, #4 wstrd wR3, [DEST, #-8]! wmov wR0, wR1 wmov wR1, wR2 LABEL(memmove8Bit_inverse_alignedWordTrailingword) /* Copy the trailing word if necessary: */ tst r12, #0x4 beq memmove8Bit_inverse_alignedWordTrailingHalfword wstrw wR0, [DEST, #-4]! waligni wR0, wR1, wR1, #4 LABEL(memmove8Bit_inverse_alignedWordTrailingHalfword) /* Copy the trailing half word if necessary: */ tst r12, #0x2 beq memmove8Bit_inverse_alignedWordTrailingByte waligni wR1, wR0, wR0, #2 wstrh wR1, [DEST, #-2]! waligni wR0, wR0, wR0, #6LABEL(memmove8Bit_inverse_alignedWordTrailingByte) /* Copy the trailing byte if necessary: */ tst r12, #0x1 walignine wR0, wR0, wR0, #3 wstrbne wR0, [DEST, #-1]LABEL(memmove8Bit_inverse_alignedWordDone) BR_REG(lr) /* Return to caller. */LABEL(memmove8Bit_inverse_alignedWordLeadingByte) /* Copy leading byte if necessary: */ tst SRC, #0x1 beq memmove8Bit_inverse_alignedWordLeadingHalfWord ldrb r3, [SRC, #-1]! sub LENGTH, LENGTH, #1 strb r3, [DEST, #-1]!LABEL(memmove8Bit_inverse_alignedWordLeadingHalfWord) /* Copy the leading halfword if necessary: */ tst SRC, #0x2 beq memmove8Bit_inverse_alignedWordLeadingWord ldrh r3, [SRC, #-2]! sub LENGTH, LENGTH, #2 strh r3, [DEST, #-2]! LABEL(memmove8Bit_inverse_alignedWordLeadingWord) /* Copy the leading word if necessary: */ tst SRC, #0x4 beq memmove8Bit_inverse_alignedWord
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -