ENTRY(memcpy)
tst r6,r6
bt/s 9f ! if n=0, do nothing
mov r4,r0
sub r4,r5 ! From here, r5 has the distance to r0
add r6,r0 ! From here, r0 points the end of copying point
mov
cmp/gt r6,r1
bt/s 7f ! if it's too small, copy a byte at once
add
add
! From here, r6 is free
!
! r4 --> [ ... ] DST [ ... ] SRC
! [ ... ] [ ... ]
! : :
! r0 --> [ ... ] r0+r5 --> [ ... ]
!
!
mov r5,r1
mov
and r2,r1
shll2 r1
mov r0,r3 ! Save the value on R0 to R3
mova jmptable,r0
add r1,r0
mov.l @r0,r1
jmp @r1
mov r3,r0 ! and back to R0
.balign 4
jmptable:
.long case0
.long case1
.long case2
.long case3
! copy a byte at once
7: mov r4,r2
add
8:
cmp/hi r2,r0
mov.b @(r0,r5),r1
bt/s 8b ! while (r0>r2)
mov.b r1,@-r0
9:
rts
nop
case0:
!
! GHIJ KLMN OPQR --> GHIJ KLMN OPQR
!
! First, align to long word boundary
mov r0,r3
and r2,r3
tst r3,r3
bt/s 2f
add
add
1: dt r3
mov.b @(r0,r5),r1
bf/s 1b
mov.b r1,@-r0
!
add
2: ! Second, copy a long word at once
mov r4,r2
add
3: mov.l @(r0,r5),r1
cmp/hi r2,r0
bt/s 3b
mov.l r1,@-r0
!
! Third, copy a byte at once, if necessary
cmp/eq r4,r0
bt/s 9b
add
bra 8b
add
case1:
!
! GHIJ KLMN OPQR --> ...G HIJK LMNO PQR.
!
! First, align to long word boundary
mov r0,r3
and r2,r3
tst r3,r3
bt/s 2f
add
1: dt r3
mov.b @(r0,r5),r1
bf/s 1b
mov.b r1,@-r0
!
2: ! Second, read a long word and write a long word at once
mov.l @(r0,r5),r1
add
mov r4,r2
add
!
3: mov r1,r3 ! RQPO
shll16 r3
shll8 r3 ! Oxxx
mov.l @(r0,r5),r1 ! NMLK
mov r1,r6
shlr8 r6 ! xNML
or r6,r3 ! ONML
cmp/hi r2,r0
bt/s 3b
mov.l r3,@-r0
3: mov r1,r3 ! OPQR
shlr16 r3
shlr8 r3 ! xxxO
mov.l @(r0,r5),r1 ! KLMN
mov r1,r6
shll8 r6 ! LMNx
or r6,r3 ! LMNO
cmp/hi r2,r0
bt/s 3b
mov.l r3,@-r0
!
! Third, copy a byte at once, if necessary
cmp/eq r4,r0
bt/s 9b
add
bra 8b
add
case2:
!
! GHIJ KLMN OPQR --> ..GH IJKL MNOP QR..
!
! First, align to word boundary
tst
bt/s 2f
add
mov.b @(r0,r5),r1
mov.b r1,@-r0
!
2: ! Second, read a word and write a word at once
add
mov r4,r2
add
!
3: mov.w @(r0,r5),r1
cmp/hi r2,r0
bt/s 3b
mov.w r1,@-r0
!
! Third, copy a byte at once, if necessary
cmp/eq r4,r0
bt/s 9b
add
mov.b @(r0,r5),r1
rts
mov.b r1,@-r0
case3:
!
! GHIJ KLMN OPQR --> .GHI JKLM NOPQ R...
!
! First, align to long word boundary
mov r0,r3
and r2,r3
tst r3,r3
bt/s 2f
add
1: dt r3
mov.b @(r0,r5),r1
bf/s 1b
mov.b r1,@-r0
!
2: ! Second, read a long word and write a long word at once
add
mov.l @(r0,r5),r1
add
mov r4,r2
add
!
3: mov r1,r3 ! RQPO
shll8 r3 ! QPOx
mov.l @(r0,r5),r1 ! NMLK
mov r1,r6
shlr16 r6
shlr8 r6 ! xxxN
or r6,r3 ! QPON
cmp/hi r2,r0
bt/s 3b
mov.l r3,@-r0
3: mov r1,r3 ! OPQR
shlr8 r3 ! xOPQ
mov.l @(r0,r5),r1 ! KLMN
mov r1,r6
shll16 r6
shll8 r6 ! Nxxx
or r6,r3 ! NOPQ
cmp/hi r2,r0
bt/s 3b
mov.l r3,@-r0
!
! Third, copy a byte at once, if necessary
cmp/eq r4,r0
bt/s 9b
add
bra 8b
add