Merge git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6
[linux-2.6] / arch / sh / lib / memcpy.S
1 /* $Id: memcpy.S,v 1.3 2001/07/27 11:50:52 gniibe Exp $
2  *
3  * "memcpy" implementation of SuperH
4  *
5  * Copyright (C) 1999  Niibe Yutaka
6  *
7  */
8
9 /*
10  * void *memcpy(void *dst, const void *src, size_t n);
11  * No overlap between the memory of DST and of SRC are assumed.
12  */
13
14 #include <linux/linkage.h>
15 ENTRY(memcpy)
16         tst     r6,r6
17         bt/s    9f              ! if n=0, do nothing
18          mov    r4,r0
19         sub     r4,r5           ! From here, r5 has the distance to r0
20         add     r6,r0           ! From here, r0 points the end of copying point
21         mov     #12,r1
22         cmp/gt  r6,r1
23         bt/s    7f              ! if it's too small, copy a byte at once
24          add    #-1,r5
25         add     #1,r5
26         !                       From here, r6 is free
27         !
28         !      r4   -->  [ ...  ] DST             [ ...  ] SRC
29         !                [ ...  ]                 [ ...  ]
30         !                  :                        :
31         !      r0   -->  [ ...  ]       r0+r5 --> [ ...  ]
32         !
33         !
34         mov     r5,r1
35         mov     #3,r2
36         and     r2,r1
37         shll2   r1
38         mov     r0,r3           ! Save the value on R0 to R3
39         mova    jmptable,r0
40         add     r1,r0
41         mov.l   @r0,r1
42         jmp     @r1
43          mov    r3,r0           ! and back to R0
44         .balign 4
45 jmptable:
46         .long   case0
47         .long   case1
48         .long   case2
49         .long   case3
50
51         ! copy a byte at once
52 7:      mov     r4,r2
53         add     #1,r2
54 8:
55         cmp/hi  r2,r0
56         mov.b   @(r0,r5),r1
57         bt/s    8b                      ! while (r0>r2)
58          mov.b  r1,@-r0
59 9:
60         rts
61          nop
62
63 case0:
64         !
65         !       GHIJ KLMN OPQR -->  GHIJ KLMN OPQR
66         !
67         ! First, align to long word boundary
68         mov     r0,r3
69         and     r2,r3
70         tst     r3,r3
71         bt/s    2f
72          add    #-4,r5
73         add     #3,r5
74 1:      dt      r3
75         mov.b   @(r0,r5),r1
76         bf/s    1b
77          mov.b  r1,@-r0
78         !
79         add     #-3,r5
80 2:      ! Second, copy a long word at once
81         mov     r4,r2
82         add     #7,r2
83 3:      mov.l   @(r0,r5),r1
84         cmp/hi  r2,r0
85         bt/s    3b
86          mov.l  r1,@-r0
87         !
88         ! Third, copy a byte at once, if necessary
89         cmp/eq  r4,r0
90         bt/s    9b
91          add    #3,r5
92         bra     8b
93          add    #-6,r2
94
95 case1:
96         !
97         !       GHIJ KLMN OPQR -->  ...G HIJK LMNO PQR.
98         !
99         ! First, align to long word boundary
100         mov     r0,r3
101         and     r2,r3
102         tst     r3,r3
103         bt/s    2f
104          add    #-1,r5
105 1:      dt      r3
106         mov.b   @(r0,r5),r1
107         bf/s    1b
108          mov.b  r1,@-r0
109         !
110 2:      ! Second, read a long word and write a long word at once
111         mov.l   @(r0,r5),r1
112         add     #-4,r5
113         mov     r4,r2
114         add     #7,r2
115         !
116 #ifdef __LITTLE_ENDIAN__
117 3:      mov     r1,r3           ! RQPO
118         shll16  r3
119         shll8   r3              ! Oxxx
120         mov.l   @(r0,r5),r1     ! NMLK
121         mov     r1,r6
122         shlr8   r6              ! xNML
123         or      r6,r3           ! ONML
124         cmp/hi  r2,r0
125         bt/s    3b
126          mov.l  r3,@-r0
127 #else
128 3:      mov     r1,r3           ! OPQR
129         shlr16  r3
130         shlr8   r3              ! xxxO
131         mov.l   @(r0,r5),r1     ! KLMN
132         mov     r1,r6
133         shll8   r6              ! LMNx
134         or      r6,r3           ! LMNO
135         cmp/hi  r2,r0
136         bt/s    3b
137          mov.l  r3,@-r0
138 #endif
139         !
140         ! Third, copy a byte at once, if necessary
141         cmp/eq  r4,r0
142         bt/s    9b
143          add    #4,r5
144         bra     8b
145          add    #-6,r2
146
147 case2:
148         !
149         !       GHIJ KLMN OPQR -->  ..GH IJKL MNOP QR..
150         !
151         ! First, align to word boundary
152         tst     #1,r0
153         bt/s    2f
154          add    #-1,r5
155         mov.b   @(r0,r5),r1
156         mov.b   r1,@-r0
157         !
158 2:      ! Second, read a word and write a word at once
159         add     #-1,r5
160         mov     r4,r2
161         add     #3,r2
162         !
163 3:      mov.w   @(r0,r5),r1
164         cmp/hi  r2,r0
165         bt/s    3b
166          mov.w  r1,@-r0
167         !
168         ! Third, copy a byte at once, if necessary
169         cmp/eq  r4,r0
170         bt/s    9b
171          add    #1,r5
172         mov.b   @(r0,r5),r1
173         rts
174          mov.b  r1,@-r0
175
176 case3:
177         !
178         !       GHIJ KLMN OPQR -->  .GHI JKLM NOPQ R...
179         !
180         ! First, align to long word boundary
181         mov     r0,r3
182         and     r2,r3
183         tst     r3,r3
184         bt/s    2f
185          add    #-1,r5
186 1:      dt      r3
187         mov.b   @(r0,r5),r1
188         bf/s    1b
189          mov.b  r1,@-r0
190         !
191 2:      ! Second, read a long word and write a long word at once
192         add     #-2,r5
193         mov.l   @(r0,r5),r1
194         add     #-4,r5
195         mov     r4,r2
196         add     #7,r2
197         !
198 #ifdef __LITTLE_ENDIAN__
199 3:      mov     r1,r3           ! RQPO
200         shll8   r3              ! QPOx
201         mov.l   @(r0,r5),r1     ! NMLK
202         mov     r1,r6
203         shlr16  r6
204         shlr8   r6              ! xxxN
205         or      r6,r3           ! QPON
206         cmp/hi  r2,r0
207         bt/s    3b
208          mov.l  r3,@-r0
209 #else
210 3:      mov     r1,r3           ! OPQR
211         shlr8   r3              ! xOPQ
212         mov.l   @(r0,r5),r1     ! KLMN
213         mov     r1,r6
214         shll16  r6
215         shll8   r6              ! Nxxx
216         or      r6,r3           ! NOPQ
217         cmp/hi  r2,r0
218         bt/s    3b
219          mov.l  r3,@-r0
220 #endif
221         !
222         ! Third, copy a byte at once, if necessary
223         cmp/eq  r4,r0
224         bt/s    9b
225          add    #6,r5
226         bra     8b
227          add    #-6,r2