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 */
9
10/*
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 */
14
15#include <linux/linkage.h>
16ENTRY(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
46jmptable:
47 .long case0
48 .long case1
49 .long case2
50 .long case3
51
52 ! copy a byte at once
537: mov r4,r2
54 add #1,r2
558:
56 cmp/hi r2,r0
57 mov.b @(r0,r5),r1
58 bt/s 8b ! while (r0>r2)
59 mov.b r1,@-r0
609:
61 rts
62 nop
63
64case0:
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
751: dt r3
76 mov.b @(r0,r5),r1
77 bf/s 1b
78 mov.b r1,@-r0
79 !
80 add #-3,r5
812: ! Second, copy a long word at once
82 mov r4,r2
83 add #7,r2
843: 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
95
96case1:
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
1061: dt r3
107 mov.b @(r0,r5),r1
108 bf/s 1b
109 mov.b r1,@-r0
110 !
1112: ! 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__
1183: 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
1293: 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
147
148case2:
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 !
1592: ! Second, read a word and write a word at once
160 add #-1,r5
161 mov r4,r2
162 add #3,r2
163 !
1643: 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
176
177case3:
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
1871: dt r3
188 mov.b @(r0,r5),r1
189 bf/s 1b
190 mov.b r1,@-r0
191 !
1922: ! 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__
2003: 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
2113: 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
229

source code of linux/arch/sh/lib/memcpy.S