123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 |
- /* $Id: memcpy.S,v 1.3 2001/07/27 11:50:52 gniibe Exp $
- *
- * "memcpy" implementation of SuperH
- *
- * Copyright (C) 1999 Niibe Yutaka
- *
- */
- /*
- * void *memcpy(void *dst, const void *src, size_t n);
- * No overlap between the memory of DST and of SRC are assumed.
- */
- #include <linux/linkage.h>
- 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 #12,r1
- cmp/gt r6,r1
- bt/s 7f ! if it's too small, copy a byte at once
- add #-1,r5
- add #1,r5
- ! From here, r6 is free
- !
- ! r4 --> [ ... ] DST [ ... ] SRC
- ! [ ... ] [ ... ]
- ! : :
- ! r0 --> [ ... ] r0+r5 --> [ ... ]
- !
- !
- mov r5,r1
- mov #3,r2
- 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 #1,r2
- 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 #-4,r5
- add #3,r5
- 1: dt r3
- mov.b @(r0,r5),r1
- bf/s 1b
- mov.b r1,@-r0
- !
- add #-3,r5
- 2: ! Second, copy a long word at once
- mov r4,r2
- add #7,r2
- 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 #3,r5
- bra 8b
- add #-6,r2
- 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,r5
- 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 #-4,r5
- mov r4,r2
- add #7,r2
- !
- #ifdef __LITTLE_ENDIAN__
- 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
- #else
- 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
- #endif
- !
- ! Third, copy a byte at once, if necessary
- cmp/eq r4,r0
- bt/s 9b
- add #4,r5
- bra 8b
- add #-6,r2
- case2:
- !
- ! GHIJ KLMN OPQR --> ..GH IJKL MNOP QR..
- !
- ! First, align to word boundary
- tst #1,r0
- bt/s 2f
- add #-1,r5
- mov.b @(r0,r5),r1
- mov.b r1,@-r0
- !
- 2: ! Second, read a word and write a word at once
- add #-1,r5
- mov r4,r2
- add #3,r2
- !
- 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 #1,r5
- 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,r5
- 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 #-2,r5
- mov.l @(r0,r5),r1
- add #-4,r5
- mov r4,r2
- add #7,r2
- !
- #ifdef __LITTLE_ENDIAN__
- 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
- #else
- 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
- #endif
- !
- ! Third, copy a byte at once, if necessary
- cmp/eq r4,r0
- bt/s 9b
- add #6,r5
- bra 8b
- add #-6,r2
|