📄 memory_asm_cpu.s
字号:
wldrw wR0, [SRC, #-4]! sub LENGTH, LENGTH, #24 wldrd wR1, [SRC, #-8]! and r12, LENGTH, #7 wldrd wR2, [SRC, #-8]! b IL11 LABEL(memmove8Bit_inverse_unaligned) tst r3, #0x3 /* Check if low 2 bits are equal. */ beq memmove8Bit_inverse_alignedWordCheck stmfd sp!, {r4-r7,lr} and r3, SRC, #7 /*r3 = number of SRC end unaligned */ and r5, DEST, #7 /*r5 = number of DEST end unaligned */ subs r7, r3, r5 /*r7 = difference of unaligned */ blt IL2 /* Do alignment for the end part. If the unaligned byte number of src is bigger than that of dest, |<-src end wR0 -> x4 x3 x2 x1 x0 s2 s1 s0 wR3 -> y5 y4 y3 y2 y1 y0 d1 d0 |<-dest end Result -> y5 y4 y3 y2 y1 y0 s2 s1 Step 1 -> xx xx x3 x2 x1 x0 s2 s1 (wR2) Step 2 -> s2 s1 y5 y4 y3 y2 y1 y0 (WR4) Step 3 -> y5 y4 y3 y2 y1 y0 s2 s1 */ bic r6, DEST, #7 /*r6 = address 8-byte aligned */ wldrd wR3, [r6] bic r4, SRC, #7 /*r4 = address 8-byte aligned */ wldrd wR0, [r4] tmcr wCGR0, r7 /*wCGR0 = number of bytes to be aligned */ wldrd wR1, [r4, #-8]! tmcr wCGR1, r5 /*wCGR1 = number of bytes to be aligned */ rsb r12, r5, #8 sub LENGTH, LENGTH, r5 mov r12, r12, LSL #3 tmcr wCGR2, r12 /*wCGR2 = number of bits to be rotated */ walignr0 wR2, wR0, wR0 /* Step 1 */ sub LENGTH, LENGTH, #24 walignr1 wR4, wR3, wR2 /* Step 2 */ wldrd wR2, [r4, #-8]! wrordg wR4, wR4, wCGR2 /* Step 3 */ wstrd wR4, [r6] /* The first unaligned 8-byte has been done. Begin mainloop of 8-byte memmove. */LABEL(IL1)#ifdef IAI_MEMMOVE_PLD2 pld [r4, #-64] pld [r6, #-64]#endif walignr0 wR3, wR1, wR0 wldrd wR0, [r4, #-8]! wstrd wR3, [r6, #-8]! walignr0 wR4, wR2, wR1 wldrd wR1, [r4, #-8]! wstrd wR4, [r6, #-8]! walignr0 wR5, wR0, wR2 wldrd wR2, [r4, #-8]! wstrd wR5, [r6, #-8]! subs LENGTH, LENGTH, #24 bge IL1 /* Do the end unaligned part */LABEL(IL101) adds LENGTH, LENGTH, #8 blt IL102 walignr0 wR3, wR1, wR0 wmov wR0, wR1 wmov wR1, wR2 wldrd wR2, [r4, #-8]! wstrd wR3, [r6, #-8]!LABEL(IL102) adds LENGTH, LENGTH, #8 blt IL103 walignr0 wR3, wR1, wR0 wstrd wR3, [r6, #-8]! wmov wR0, wR1 wmov wR1, wR2 LABEL(IL103) walignr0 wR3, wR1, wR0 tst LENGTH, #4 beq IL104 waligni wR3, wR3, wR3, #4 wstrw wR3, [r6, #-4]! LABEL(IL104) tst LENGTH, #2 beq IL105 waligni wR3, wR3, wR3, #6 wstrh wR3, [r6, #-2]!LABEL(IL105) tst LENGTH, #1 walignine wR3, wR3, wR3, #7 wstrbne wR3, [r6, #-1] ldmfd sp!, {r4-r7,lr} BR_REG(lr) /* Return to caller. */ /* unaligned number of SRC end is less than the one of DEST end */LABEL(IL2) /* Do alignment for the end part. If the unaligned byte number of src is bigger than that of dest, |<-src end wR0:wR1 -> x5 x4 x3 x2 x1 x0 s9 s8 : s7 s6 s5 s4 s3 s2 s1 s0 wR3 -> y4 y3 y2 y1 y0 d2 d1 d0 |<-dest end Result -> y4 y3 y2 y1 y0 s9 s8 s7 Step 1 -> s9 s8 s7 s6 s5 s4 s3 s2 (wR2) Step 2 -> yy yy yy y4 y3 y2 y1 y0 (wR4) Step 3 -> y4 y3 y2 y1 y0 s9 s8 s7 */ 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] wldrd wR1, [r4, #-8]! tmcr wCGR2, r3 /*wCGR0 = number of bytes to be aligned */ tmcr wCGR1, r5 /*wCGR1 = number of bytes to be aligned */ tmcr wCGR0, r7 /*wCGR2 = number of bytes to be aligned */ rsb r12, r5, #8 sub LENGTH, LENGTH, r5 tmcr wCGR3, r12 /*wCGR3 = number of bytes to be aligned */ walignr2 wR2, wR1, wR0 /* Step 1 */ walignr1 wR4, wR3, wR3 /* Step 2 */ wmov wR0, wR1 wldrd wR1, [r4, #-8]! sub LENGTH, LENGTH, #24 walignr3 wR4, wR2, wR4 /* Step 3 */ wldrd wR2, [r4, #-8]! wstrd wR4, [r6] /* The first unaligned 8-byte has been done. Begin mainloop of 8-byte memmove. */ b IL1 LABEL(memmove8Bit_inverse_smallLength)#endif /* IAI_MEMMOVE */LABEL(memmove8Bit_copyBackward) /* Do backward copying: */ subs LENGTH, LENGTH, #1 add SRC, SRC, LENGTH add DEST, DEST, LENGTH blt memmove8Bit_copyBackwardLoopDoneLABEL(memmove8Bit_copyBackwardLoop) ldrb r3, [SRC], #-1 subs LENGTH, LENGTH, #1 strb r3, [DEST], #-1 bge memmove8Bit_copyBackwardLoopLABEL(memmove8Bit_copyBackwardLoopDone) BR_REG(lr) /* Return to caller. */#undef DEST#undef SRC#undef LENGTH SET_SIZE( CVMARMmemmove8Bit ) ENTRY (CVMARMmemmove16Bit)ENTRY1(CVMARMmemmove16Bit) /* r0 = a1 = dest r1 = a2 = src r2 = a3 = length */#define DEST r0#define SRC r1#define LENGTH r2 /* Check to see if the length is 0. Also check to see if which direction we need to do the copying in: */ cmp LENGTH, #0 cmpne DEST, SRC BRCOND_REG(lr,eq) /* Nothing to copy. Return to caller. */ /* If (dest >= src + length) or (dest < src), then we can do forward copying: */ addhi r12, SRC, LENGTH cmphi r12, DEST bhi memmove16Bit_copyBackwardLABEL(memmove16Bit_copyForward) tst SRC, #0x3 /* Check low 2 bits for word alignment. */ beq memmove16Bit_alignedWords /* Copy the leading halfword if necessary: */ subs LENGTH, LENGTH, #2 /* If there's nothing to */ blt memmove16Bit_alignedWordsDone /* copy,then branch to done. */ ldrh r3, [SRC], #2 strh r3, [DEST], #2LABEL(memmove16Bit_alignedWords) and r12, LENGTH, #0x3 bic LENGTH, LENGTH, #0x3 subs LENGTH, LENGTH, #4 blt memmove16Bit_alignedWordsTrailingHalfword /* Check if the DEST is word aligned. The SRC * is already word algined when we get here. */ tst DEST, #0x3 /* Check if the low 2 bits are 0. */ bne memmove16Bit_unalignedLoopLABEL(memmove16Bit_alignedWordsLoop) ldr r3, [SRC], #4 subs LENGTH, LENGTH, #4 str r3, [DEST], #4 bge memmove16Bit_alignedWordsLoopLABEL(memmove16Bit_alignedWordsTrailingHalfword) /* Copy the trailing half word if necessary: */ tst r12, #0x2 BRCOND_REG(lr,eq) /* Done. Return to caller. */ ldrh r3, [SRC], #2 strh r3, [DEST], #2LABEL(memmove16Bit_alignedWordsDone) BR_REG(lr) /* Return to caller. */LABEL(memmove16Bit_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 #16 strh r3, [DEST], #2 mov r3, r3, ror #16 strh r3, [DEST], #2#elif CVM_ENDIANNESS == CVM_LITTLE_ENDIAN strh r3, [DEST], #2 mov r3, r3, lsr #16 strh r3, [DEST], #2#endif bge memmove16Bit_unalignedLoop b memmove16Bit_alignedWordsTrailingHalfword /* ===============================================================*/LABEL(memmove16Bit_copyBackward) /* Do backward copying: */ subs LENGTH, LENGTH, #2 add SRC, SRC, LENGTH add DEST, DEST, LENGTH blt memmove16Bit_copyBackwardLoopDoneLABEL(memmove16Bit_copyBackwardLoop) ldrh r3, [SRC], #-2 subs LENGTH, LENGTH, #2 strh r3, [DEST], #-2 bge memmove16Bit_copyBackwardLoopLABEL(memmove16Bit_copyBackwardLoopDone) BR_REG(lr) /* Return to caller. */#undef DEST#undef SRC#undef LENGTH SET_SIZE( CVMARMmemmove16Bit ) ENTRY (CVMARMmemmove32Bit)ENTRY1(CVMARMmemmove32Bit) /* r0 = a1 = dest r1 = a2 = src r2 = a3 = length */#define DEST r0#define SRC r1#define LENGTH r2 /* Check to see if the length is 0. Also check to see if which direction we need to do the copying in: */ cmp LENGTH, #0 cmpne DEST, SRC BRCOND_REG(lr,eq) /* Nothing to copy. Return to caller. */ bhi memmove32Bit_inverseLABEL(memmove32Bit_copyForward)#ifdef IAI_MEMMOVE_PLD2 pld [SRC, #32] pld [SRC, #64] pld [SRC, #96] pld [DEST, #32] pld [DEST, #64] pld [DEST, #96] #endif /* Do forward copying: */ subs LENGTH, LENGTH, #4 blt memmove32Bit_alignedWordsDoneLABEL(memmove32Bit_alignedWordsLoop) ldr r3, [SRC], #4 subs LENGTH, LENGTH, #4 str r3, [DEST], #4 bge memmove32Bit_alignedWordsLoopLABEL(memmove32Bit_alignedWordsDone) BR_REG(lr) /* Return to caller. */LABEL(memmove32Bit_inverse) /* Do backward copying: */#ifdef IAI_MEMMOVE_PLD2 pld [SRC, #-32] pld [SRC, #-64] pld [SRC, #-96] pld [DEST, #-32] pld [DEST, #-64] pld [DEST, #-96]#endif subs LENGTH, LENGTH, #4 add SRC, SRC, LENGTH add DEST, DEST, LENGTH blt memmove32Bit_copyBackwardLoopDoneLABEL(memmove32Bit_copyBackwardLoop) ldr r3, [SRC], #-4 subs LENGTH, LENGTH, #4 str r3, [DEST], #-4 bge memmove32Bit_copyBackwardLoopLABEL(memmove32Bit_copyBackwardLoopDone) BR_REG(lr) /* Return to caller. */#undef DEST#undef SRC#undef LENGTH SET_SIZE( CVMARMmemmove32Bit )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -