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