memcpy.s
来自「SAMSUNG S3C6410 CPU BSP for winmobile6」· S 代码 · 共 660 行 · 第 1/2 页
S
660 行
;++
;
; Module Name:
;
; memcpy.s
;
;--
;
OPT 2 ; disable listing
INCLUDE kxarm.h
; INCLUDE addrtab_cfg.inc
OPT 1 ; reenable listing
TEXTAREA
EXPORT memcpy32
memcpy32
; Check for zero length or source and target being the same
cmp r2, #0
cmpne r0, r1
addeq r0, r0, r2
moveq pc, lr ; __JUMP(eq,lr);
; If <16 bytes, just do byte moves
cmp r2, #15
bhi large_copy
cmp r1, r0
bhi small_copy_fwd
add r0, r0, r2
add r1, r1, r2
mov r3, r0
add r12, pc, #small_copy_back_end-.-8
sub pc, r12, r2, lsl #3
ldrb r12, [r1, #-1]!
strb r12, [r3, #-1]!
ldrb r12, [r1, #-1]!
strb r12, [r3, #-1]!
ldrb r12, [r1, #-1]!
strb r12, [r3, #-1]!
ldrb r12, [r1, #-1]!
strb r12, [r3, #-1]!
ldrb r12, [r1, #-1]!
strb r12, [r3, #-1]!
ldrb r12, [r1, #-1]!
strb r12, [r3, #-1]!
ldrb r12, [r1, #-1]!
strb r12, [r3, #-1]!
ldrb r12, [r1, #-1]!
strb r12, [r3, #-1]!
ldrb r12, [r1, #-1]!
strb r12, [r3, #-1]!
ldrb r12, [r1, #-1]!
strb r12, [r3, #-1]!
ldrb r12, [r1, #-1]!
strb r12, [r3, #-1]!
ldrb r12, [r1, #-1]!
strb r12, [r3, #-1]!
ldrb r12, [r1, #-1]!
strb r12, [r3, #-1]!
ldrb r12, [r1, #-1]!
strb r12, [r3, #-1]!
ldrb r12, [r1, #-1]!
strb r12, [r3, #-1]!
small_copy_back_end
mov pc, lr ;__JUMP(,lr)
small_copy_fwd
add r12, pc, #small_copy_fwd_end-.-8
sub pc, r12, r2, lsl #3
ldrb r12, [r1], #1
strb r12, [r0], #1
ldrb r12, [r1], #1
strb r12, [r0], #1
ldrb r12, [r1], #1
strb r12, [r0], #1
ldrb r12, [r1], #1
strb r12, [r0], #1
ldrb r12, [r1], #1
strb r12, [r0], #1
ldrb r12, [r1], #1
strb r12, [r0], #1
ldrb r12, [r1], #1
strb r12, [r0], #1
ldrb r12, [r1], #1
strb r12, [r0], #1
ldrb r12, [r1], #1
strb r12, [r0], #1
ldrb r12, [r1], #1
strb r12, [r0], #1
ldrb r12, [r1], #1
strb r12, [r0], #1
ldrb r12, [r1], #1
strb r12, [r0], #1
ldrb r12, [r1], #1
strb r12, [r0], #1
ldrb r12, [r1], #1
strb r12, [r0], #1
ldrb r12, [r1], #1
strb r12, [r0], #1
small_copy_fwd_end
mov pc, lr ;__JUMP(,lr)
large_copy
; Check for possible overlap of source and target
cmp r1, r0
bcc copy_back
stmfd sp!, {r4-r11,lr}
; Do byte moves if necessary to word-align destination
movs r3, r0, lsl #30
rsbne r3, r3, #0 ; r3=number of bytes to align destination
msr cpsr_f, r3
ldrmib lr, [r1], #1 ; move bytes to align destination
strmib lr, [r0], #1
ldrmib lr, [r1], #1
strmib lr, [r0], #1
ldreqb lr, [r1], #1
streqb lr, [r0], #1
sub r2, r2, r3, lsr #30 ; adjust length
; Normal copy forwards. r0 should point to end address on exit
; Destination now word-aligned; if source is also word-aligned, do aligned copy.
ands r12, r1, #3 ; r12=alignment of source
beq same_alignment_copy_fore
bic r1, r1, #3 ; align source
ldr r11, [r1], #4 ; get first word
cmp r12, #2
beq start_copy_fwd_nonaligned_2
bhi start_copy_fwd_nonaligned_3
start_copy_fwd_nonaligned_1
movs lr, r2, lsr #5 ; lr=number of 32-byte blocks
beq copy_fwd_smaller_1
copy_fwd_nonaligned_1
mov r3, r11, lsr #8
ldmia r1!, {r4-r11}
orr r3, r3, r4, lsl #24
mov r4, r4, lsr #8
orr r4, r4, r5, lsl #24
mov r5, r5, lsr #8
orr r5, r5, r6, lsl #24
mov r6, r6, lsr #8
orr r6, r6, r7, lsl #24
mov r7, r7, lsr #8
orr r7, r7, r8, lsl #24
mov r8, r8, lsr #8
orr r8, r8, r9, lsl #24
mov r9, r9, lsr #8
orr r9, r9, r10, lsl #24
mov r10, r10, lsr #8
orr r10, r10, r11, lsl #24
stmia r0!, {r3-r10}
subs lr, lr, #1
bne copy_fwd_nonaligned_1
copy_fwd_smaller_1
mov r2, r2, lsl #26
msr cpsr_f, r2
moveq r3, r11, lsr #8
ldmeqia r1!, {r4-r6,r11}
orreq r3, r3, r4, lsl #24
moveq r4, r4, lsr #8
orreq r4, r4, r5, lsl #24
moveq r5, r5, lsr #8
orreq r5, r5, r6, lsl #24
moveq r6, r6, lsr #8
orreq r6, r6, r11, lsl #24
stmeqia r0!, {r3-r6}
movcs r3, r11, lsr #8
ldmcsia r1!, {r4,r11}
orrcs r3, r3, r4, lsl #24
movcs r4, r4, lsr #8
orrcs r4, r4, r11, lsl #24
stmcsia r0!, {r3,r4}
movvs r3, r11, lsr #8
ldmvsia r1!, {r11}
orrvs r3, r3, r11, lsl #24
stmvsia r0!, {r3}
b copy_fwd_remainder
start_copy_fwd_nonaligned_2
movs lr, r2, lsr #5 ; lr=number of 32-byte blocks
beq copy_fwd_smaller_2
copy_fwd_nonaligned_2
mov r3, r11, lsr #16
ldmia r1!, {r4-r11}
orr r3, r3, r4, lsl #16
mov r4, r4, lsr #16
orr r4, r4, r5, lsl #16
mov r5, r5, lsr #16
orr r5, r5, r6, lsl #16
mov r6, r6, lsr #16
orr r6, r6, r7, lsl #16
mov r7, r7, lsr #16
orr r7, r7, r8, lsl #16
mov r8, r8, lsr #16
orr r8, r8, r9, lsl #16
mov r9, r9, lsr #16
orr r9, r9, r10, lsl #16
mov r10, r10, lsr #16
orr r10, r10, r11, lsl #16
stmia r0!, {r3-r10}
subs lr, lr, #1
bne copy_fwd_nonaligned_2
copy_fwd_smaller_2
mov r2, r2, lsl #26
msr cpsr_f, r2
moveq r3, r11, lsr #16
ldmeqia r1!, {r4-r6,r11}
orreq r3, r3, r4, lsl #16
moveq r4, r4, lsr #16
orreq r4, r4, r5, lsl #16
moveq r5, r5, lsr #16
orreq r5, r5, r6, lsl #16
moveq r6, r6, lsr #16
orreq r6, r6, r11, lsl #16
stmeqia r0!, {r3-r6}
movcs r3, r11, lsr #16
ldmcsia r1!, {r4,r11}
orrcs r3, r3, r4, lsl #16
movcs r4, r4, lsr #16
orrcs r4, r4, r11, lsl #16
stmcsia r0!, {r3,r4}
movvs r3, r11, lsr #16
ldmvsia r1!, {r11}
orrvs r3, r3, r11, lsl #16
stmvsia r0!, {r3}
b copy_fwd_remainder
start_copy_fwd_nonaligned_3
movs lr, r2, lsr #5 ;lr=number of 32-byte blocks
beq copy_fwd_smaller_3
copy_fwd_nonaligned_3
mov r3, r11, lsr #24
ldmia r1!, {r4-r11}
orr r3, r3, r4, lsl #8
mov r4, r4, lsr #24
orr r4, r4, r5, lsl #8
mov r5, r5, lsr #24
orr r5, r5, r6, lsl #8
mov r6, r6, lsr #24
orr r6, r6, r7, lsl #8
mov r7, r7, lsr #24
orr r7, r7, r8, lsl #8
mov r8, r8, lsr #24
orr r8, r8, r9, lsl #8
mov r9, r9, lsr #24
orr r9, r9, r10, lsl #8
mov r10, r10, lsr #24
orr r10, r10, r11, lsl #8
stmia r0!, {r3-r10}
subs lr, lr, #1
bne copy_fwd_nonaligned_3
copy_fwd_smaller_3
mov r2, r2, lsl #26
msr cpsr_f, r2
moveq r3, r11, lsr #24
ldmeqia r1!, {r4-r6,r11}
orreq r3, r3, r4, lsl #8
moveq r4, r4, lsr #24
orreq r4, r4, r5, lsl #8
moveq r5, r5, lsr #24
orreq r5, r5, r6, lsl #8
moveq r6, r6, lsr #24
orreq r6, r6, r11, lsl #8
stmeqia r0!, {r3-r6}
movcs r3, r11, lsr #24
ldmcsia r1!, {r4,r11}
orrcs r3, r3, r4, lsl #8
movcs r4, r4, lsr #24
orrcs r4, r4, r11, lsl #8
stmcsia r0!, {r3,r4}
movvs r3, r11, lsr #24
ldmvsia r1!, {r11}
orrvs r3, r3, r11, lsl #8
stmvsia r0!, {r3}
copy_fwd_remainder
sub r1, r1, #4
mov r2, r2, lsl #2
msr cpsr_f, r2
add r1, r1, r12 ; true source address (nonaligned)
ldrcsb lr, [r1], #1 ; do byte copies to finish
strcsb lr, [r0], #1
ldrcsb lr, [r1], #1
strcsb lr, [r0], #1
ldrvsb lr, [r1], #1
strvsb lr, [r0], #1
ldmfd sp!, {r4-r11, pc} ;__POPRET("r4-r11,")
; Source is before target, so need to copy backwards incase they overlap
copy_back
add r0, r0, r2 ; r0=last dest address+1
add r1, r1, r2 ; r1=last source address+1
stmfd sp!, {r0,r4-r11,lr} ; save registers and return value
mov r3, r0, lsl #30 ; destination alignment into r3
msr cpsr_f, r3 ; and into N,Z flags
ldrmib lr, [r1, #-1]! ; do byte moves to align destination
strmib lr, [r0, #-1]!
ldrmib lr, [r1, #-1]!
strmib lr, [r0, #-1]!
ldreqb lr, [r1, #-1]!
streqb lr, [r0, #-1]!
sub r2, r2, r3, lsr #30 ; adjust length
ands r12, r1, #3 ; r12=alignment of source
beq same_alignment_copy_back ; if source also aligned, do aligned copy
bic r1, r1, #3 ; align source
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?