OSDN Git Service

hidden_def/hidden_proto: convert all users (I hope) termios split, add some missing...
[uclinux-h8/uClibc.git] / libc / string / sparc / sparc32 / memcpy.S
1 /* Copy SIZE bytes from SRC to DEST.
2    For SPARC v7.
3    Copyright (C) 1996, 1999, 2003 Free Software Foundation, Inc.
4    This file is part of the GNU C Library.
5    Contributed by David S. Miller <davem@caip.rutgers.edu>,
6                   Eddie C. Dost <ecd@skynet.be> and
7                   Jakub Jelinek <jj@ultra.linux.cz>.
8
9    The GNU C Library is free software; you can redistribute it and/or
10    modify it under the terms of the GNU Lesser General Public
11    License as published by the Free Software Foundation; either
12    version 2.1 of the License, or (at your option) any later version.
13
14    The GNU C Library is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17    Lesser General Public License for more details.
18
19    You should have received a copy of the GNU Lesser General Public
20    License along with the GNU C Library; if not, write to the Free
21    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22    02111-1307 USA.  */
23
24 /* Both these macros have to start with exactly the same insn */
25 #define MOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7)                                 \
26         ldd     [%src + offset + 0x00], %t0;                                                            \
27         ldd     [%src + offset + 0x08], %t2;                                                            \
28         ldd     [%src + offset + 0x10], %t4;                                                            \
29         ldd     [%src + offset + 0x18], %t6;                                                            \
30         st      %t0, [%dst + offset + 0x00];                                                            \
31         st      %t1, [%dst + offset + 0x04];                                                            \
32         st      %t2, [%dst + offset + 0x08];                                                            \
33         st      %t3, [%dst + offset + 0x0c];                                                            \
34         st      %t4, [%dst + offset + 0x10];                                                            \
35         st      %t5, [%dst + offset + 0x14];                                                            \
36         st      %t6, [%dst + offset + 0x18];                                                            \
37         st      %t7, [%dst + offset + 0x1c];
38
39 #define MOVE_BIGALIGNCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7)                            \
40         ldd     [%src + offset + 0x00], %t0;                                                            \
41         ldd     [%src + offset + 0x08], %t2;                                                            \
42         ldd     [%src + offset + 0x10], %t4;                                                            \
43         ldd     [%src + offset + 0x18], %t6;                                                            \
44         std     %t0, [%dst + offset + 0x00];                                                            \
45         std     %t2, [%dst + offset + 0x08];                                                            \
46         std     %t4, [%dst + offset + 0x10];                                                            \
47         std     %t6, [%dst + offset + 0x18];
48
49 #define MOVE_LASTCHUNK(src, dst, offset, t0, t1, t2, t3)                                                \
50         ldd     [%src - offset - 0x10], %t0;                                                            \
51         ldd     [%src - offset - 0x08], %t2;                                                            \
52         st      %t0, [%dst - offset - 0x10];                                                            \
53         st      %t1, [%dst - offset - 0x0c];                                                            \
54         st      %t2, [%dst - offset - 0x08];                                                            \
55         st      %t3, [%dst - offset - 0x04];
56
57 #define MOVE_LASTALIGNCHUNK(src, dst, offset, t0, t1, t2, t3)                                           \
58         ldd     [%src - offset - 0x10], %t0;                                                            \
59         ldd     [%src - offset - 0x08], %t2;                                                            \
60         std     %t0, [%dst - offset - 0x10];                                                            \
61         std     %t2, [%dst - offset - 0x08];
62
63 #define MOVE_SHORTCHUNK(src, dst, offset, t0, t1)                                                       \
64         ldub    [%src - offset - 0x02], %t0;                                                            \
65         ldub    [%src - offset - 0x01], %t1;                                                            \
66         stb     %t0, [%dst - offset - 0x02];                                                            \
67         stb     %t1, [%dst - offset - 0x01];
68
69 /* Both these macros have to start with exactly the same insn */
70 #define RMOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7)                                \
71         ldd     [%src - offset - 0x20], %t0;                                                            \
72         ldd     [%src - offset - 0x18], %t2;                                                            \
73         ldd     [%src - offset - 0x10], %t4;                                                            \
74         ldd     [%src - offset - 0x08], %t6;                                                            \
75         st      %t0, [%dst - offset - 0x20];                                                            \
76         st      %t1, [%dst - offset - 0x1c];                                                            \
77         st      %t2, [%dst - offset - 0x18];                                                            \
78         st      %t3, [%dst - offset - 0x14];                                                            \
79         st      %t4, [%dst - offset - 0x10];                                                            \
80         st      %t5, [%dst - offset - 0x0c];                                                            \
81         st      %t6, [%dst - offset - 0x08];                                                            \
82         st      %t7, [%dst - offset - 0x04];
83
84 #define RMOVE_BIGALIGNCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7)                           \
85         ldd     [%src - offset - 0x20], %t0;                                                            \
86         ldd     [%src - offset - 0x18], %t2;                                                            \
87         ldd     [%src - offset - 0x10], %t4;                                                            \
88         ldd     [%src - offset - 0x08], %t6;                                                            \
89         std     %t0, [%dst - offset - 0x20];                                                            \
90         std     %t2, [%dst - offset - 0x18];                                                            \
91         std     %t4, [%dst - offset - 0x10];                                                            \
92         std     %t6, [%dst - offset - 0x08];
93
94 #define RMOVE_LASTCHUNK(src, dst, offset, t0, t1, t2, t3)                                               \
95         ldd     [%src + offset + 0x00], %t0;                                                            \
96         ldd     [%src + offset + 0x08], %t2;                                                            \
97         st      %t0, [%dst + offset + 0x00];                                                            \
98         st      %t1, [%dst + offset + 0x04];                                                            \
99         st      %t2, [%dst + offset + 0x08];                                                            \
100         st      %t3, [%dst + offset + 0x0c];
101
102 #define RMOVE_SHORTCHUNK(src, dst, offset, t0, t1)                                                      \
103         ldub    [%src + offset + 0x00], %t0;                                                            \
104         ldub    [%src + offset + 0x01], %t1;                                                            \
105         stb     %t0, [%dst + offset + 0x00];                                                            \
106         stb     %t1, [%dst + offset + 0x01];
107
108 #define SMOVE_CHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, prev, shil, shir, offset2)            \
109         ldd     [%src + offset + 0x00], %t0;                                                            \
110         ldd     [%src + offset + 0x08], %t2;                                                            \
111         srl     %t0, shir, %t5;                                                                         \
112         srl     %t1, shir, %t6;                                                                         \
113         sll     %t0, shil, %t0;                                                                         \
114         or      %t5, %prev, %t5;                                                                        \
115         sll     %t1, shil, %prev;                                                                       \
116         or      %t6, %t0, %t0;                                                                          \
117         srl     %t2, shir, %t1;                                                                         \
118         srl     %t3, shir, %t6;                                                                         \
119         sll     %t2, shil, %t2;                                                                         \
120         or      %t1, %prev, %t1;                                                                        \
121         std     %t4, [%dst + offset + offset2 - 0x04];                                                  \
122         std     %t0, [%dst + offset + offset2 + 0x04];                                                  \
123         sll     %t3, shil, %prev;                                                                       \
124         or      %t6, %t2, %t4;
125
126 #define SMOVE_ALIGNCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, prev, shil, shir, offset2)       \
127         ldd     [%src + offset + 0x00], %t0;                                                            \
128         ldd     [%src + offset + 0x08], %t2;                                                            \
129         srl     %t0, shir, %t4;                                                                         \
130         srl     %t1, shir, %t5;                                                                         \
131         sll     %t0, shil, %t6;                                                                         \
132         or      %t4, %prev, %t0;                                                                        \
133         sll     %t1, shil, %prev;                                                                       \
134         or      %t5, %t6, %t1;                                                                          \
135         srl     %t2, shir, %t4;                                                                         \
136         srl     %t3, shir, %t5;                                                                         \
137         sll     %t2, shil, %t6;                                                                         \
138         or      %t4, %prev, %t2;                                                                        \
139         sll     %t3, shil, %prev;                                                                       \
140         or      %t5, %t6, %t3;                                                                          \
141         std     %t0, [%dst + offset + offset2 + 0x00];                                                  \
142         std     %t2, [%dst + offset + offset2 + 0x08];
143
144         .text
145         .align  4
146
147 70:     andcc           %o1, 1, %g0
148         be              4f
149          andcc          %o1, 2, %g0
150
151         ldub            [%o1 - 1], %g2
152         sub             %o1, 1, %o1
153         stb             %g2, [%o0 - 1]
154         sub             %o2, 1, %o2
155         be              3f
156          sub            %o0, 1, %o0
157 4:      lduh            [%o1 - 2], %g2
158         sub             %o1, 2, %o1
159         sth             %g2, [%o0 - 2]
160         sub             %o2, 2, %o2
161         b               3f
162          sub            %o0, 2, %o0
163
164 ENTRY(bcopy)
165         mov             %o0, %o3
166         mov             %o1, %o0
167         mov             %o3, %o1
168 END(bcopy)
169 libc_hidden_def(bcopy)
170
171 ENTRY(memmove)
172         cmp             %o0, %o1
173         st              %o0, [%sp + 64]
174         bleu            9f
175          sub            %o0, %o1, %o4
176
177         add             %o1, %o2, %o3
178         cmp             %o3, %o0
179         bleu            0f
180          andcc          %o4, 3, %o5
181
182         add             %o1, %o2, %o1
183         add             %o0, %o2, %o0
184         bne             77f
185          cmp            %o2, 15
186         bleu            91f
187          andcc          %o1, 3, %g0
188         bne             70b
189 3:       andcc          %o1, 4, %g0
190
191         be              2f
192          mov            %o2, %g1
193
194         ld              [%o1 - 4], %o4
195         sub             %g1, 4, %g1
196         st              %o4, [%o0 - 4]
197         sub             %o1, 4, %o1
198         sub             %o0, 4, %o0
199 2:      andcc           %g1, 0xffffff80, %g6
200         be              3f
201          andcc          %o0, 4, %g0
202
203         be              74f + 4
204 5:      RMOVE_BIGCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5)
205         RMOVE_BIGCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5)
206         RMOVE_BIGCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5)
207         RMOVE_BIGCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5)
208         subcc           %g6, 128, %g6
209         sub             %o1, 128, %o1
210         bne             5b
211          sub            %o0, 128, %o0
212
213 3:      andcc           %g1, 0x70, %g6
214         be              72f
215          andcc          %g1, 8, %g0
216
217         srl             %g6, 1, %o4
218         mov             %o7, %g2
219         add             %g6, %o4, %o4
220 101:    call            100f
221          sub            %o1, %g6, %o1
222         mov             %g2, %o7
223         jmpl            %o5 + (72f - 101b), %g0
224          sub            %o0, %g6, %o0
225
226 71:     RMOVE_LASTCHUNK(o1, o0, 0x60, g2, g3, g4, g5)
227         RMOVE_LASTCHUNK(o1, o0, 0x50, g2, g3, g4, g5)
228         RMOVE_LASTCHUNK(o1, o0, 0x40, g2, g3, g4, g5)
229         RMOVE_LASTCHUNK(o1, o0, 0x30, g2, g3, g4, g5)
230         RMOVE_LASTCHUNK(o1, o0, 0x20, g2, g3, g4, g5)
231         RMOVE_LASTCHUNK(o1, o0, 0x10, g2, g3, g4, g5)
232         RMOVE_LASTCHUNK(o1, o0, 0x00, g2, g3, g4, g5)
233 72:     be              73f
234          andcc          %g1, 4, %g0
235
236         ldd             [%o1 - 0x08], %g2
237         sub             %o0, 8, %o0
238         sub             %o1, 8, %o1
239         st              %g2, [%o0]
240         st              %g3, [%o0 + 0x04]
241 73:     be              1f
242          andcc          %g1, 2, %g0
243
244         ld              [%o1 - 4], %g2
245         sub             %o1, 4, %o1
246         st              %g2, [%o0 - 4]
247         sub             %o0, 4, %o0
248 1:      be              1f
249          andcc          %g1, 1, %g0
250
251         lduh            [%o1 - 2], %g2
252         sub             %o1, 2, %o1
253         sth             %g2, [%o0 - 2]
254         sub             %o0, 2, %o0
255 1:      be              1f
256          nop
257
258         ldub            [%o1 - 1], %g2
259         stb             %g2, [%o0 - 1]
260 1:      retl
261          ld             [%sp + 64], %o0
262
263 74:     RMOVE_BIGALIGNCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5)
264         RMOVE_BIGALIGNCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5)
265         RMOVE_BIGALIGNCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5)
266         RMOVE_BIGALIGNCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5)
267         subcc           %g6, 128, %g6
268         sub             %o1, 128, %o1
269         bne             74b
270          sub            %o0, 128, %o0
271
272         andcc           %g1, 0x70, %g6
273         be              72b
274          andcc          %g1, 8, %g0
275
276         srl             %g6, 1, %o4
277         mov             %o7, %g2
278         add             %g6, %o4, %o4
279 102:    call            100f
280          sub            %o1, %g6, %o1
281         mov             %g2, %o7
282         jmpl            %o5 + (72b - 102b), %g0
283          sub            %o0, %g6, %o0
284
285 75:     and             %o2, 0xe, %o3
286         mov             %o7, %g2
287         sll             %o3, 3, %o4
288         sub             %o0, %o3, %o0
289 103:    call            100f
290          sub            %o1, %o3, %o1
291         mov             %g2, %o7
292         jmpl            %o5 + (76f - 103b), %g0
293          andcc          %o2, 1, %g0
294
295         RMOVE_SHORTCHUNK(o1, o0, 0x0c, g2, g3)
296         RMOVE_SHORTCHUNK(o1, o0, 0x0a, g2, g3)
297         RMOVE_SHORTCHUNK(o1, o0, 0x08, g2, g3)
298         RMOVE_SHORTCHUNK(o1, o0, 0x06, g2, g3)
299         RMOVE_SHORTCHUNK(o1, o0, 0x04, g2, g3)
300         RMOVE_SHORTCHUNK(o1, o0, 0x02, g2, g3)
301         RMOVE_SHORTCHUNK(o1, o0, 0x00, g2, g3)
302
303 76:     be              1f
304          nop
305         ldub            [%o1 - 1], %g2
306         stb             %g2, [%o0 - 1]
307 1:      retl
308          ld             [%sp + 64], %o0
309
310 91:     bne             75b
311          andcc          %o2, 8, %g0
312
313         be              1f
314          andcc          %o2, 4, %g0
315
316         ld              [%o1 - 0x08], %g2
317         ld              [%o1 - 0x04], %g3
318         sub             %o1, 8, %o1
319         st              %g2, [%o0 - 0x08]
320         st              %g3, [%o0 - 0x04]
321         sub             %o0, 8, %o0
322 1:      b               73b
323          mov            %o2, %g1
324
325 77:     cmp             %o2, 15
326         bleu            75b
327          andcc          %o0, 3, %g0
328         be              64f
329          andcc          %o0, 1, %g0
330         be              63f
331          andcc          %o0, 2, %g0
332         ldub            [%o1 - 1], %g5
333         sub             %o1, 1, %o1
334         stb             %g5, [%o0 - 1]
335         sub             %o0, 1, %o0
336         be              64f
337          sub            %o2, 1, %o2
338
339 63:     ldub            [%o1 - 1], %g5
340         sub             %o1, 2, %o1
341         stb             %g5, [%o0 - 1]
342         sub             %o0, 2, %o0
343         ldub            [%o1], %g5
344         sub             %o2, 2, %o2
345         stb             %g5, [%o0]
346 64:     and             %o1, 3, %g2
347         and             %o1, -4, %o1
348         and             %o2, 0xc, %g3
349         add             %o1, 4, %o1
350         cmp             %g3, 4
351         sll             %g2, 3, %g4
352         mov             32, %g2
353         be              4f
354          sub            %g2, %g4, %g6
355
356         blu             3f
357          cmp            %g3, 8
358
359         be              2f
360          srl            %o2, 2, %g3
361
362         ld              [%o1 - 4], %o3
363         add             %o0, -8, %o0
364         ld              [%o1 - 8], %o4
365         add             %o1, -16, %o1
366         b               7f
367          add            %g3, 1, %g3
368 2:      ld              [%o1 - 4], %o4
369         add             %o0, -4, %o0
370         ld              [%o1 - 8], %g1
371         add             %o1, -12, %o1
372         b               8f
373          add            %g3, 2, %g3
374 3:      ld              [%o1 - 4], %o5
375         add             %o0, -12, %o0
376         ld              [%o1 - 8], %o3
377         add             %o1, -20, %o1
378         b               6f
379          srl            %o2, 2, %g3
380 4:      ld              [%o1 - 4], %g1
381         srl             %o2, 2, %g3
382         ld              [%o1 - 8], %o5
383         add             %o1, -24, %o1
384         add             %o0, -16, %o0
385         add             %g3, -1, %g3
386
387         ld              [%o1 + 12], %o3
388 5:      sll             %o5, %g4, %g2
389         srl             %g1, %g6, %g5
390         or              %g2, %g5, %g2
391         st              %g2, [%o0 + 12]
392 6:      ld              [%o1 + 8], %o4
393         sll             %o3, %g4, %g2
394         srl             %o5, %g6, %g5
395         or              %g2, %g5, %g2
396         st              %g2, [%o0 + 8]
397 7:      ld              [%o1 + 4], %g1
398         sll             %o4, %g4, %g2
399         srl             %o3, %g6, %g5
400         or              %g2, %g5, %g2
401         st              %g2, [%o0 + 4]
402 8:      ld              [%o1], %o5
403         sll             %g1, %g4, %g2
404         srl             %o4, %g6, %g5
405         addcc           %g3, -4, %g3
406         or              %g2, %g5, %g2
407         add             %o1, -16, %o1
408         st              %g2, [%o0]
409         add             %o0, -16, %o0
410         bne,a           5b      
411          ld             [%o1 + 12], %o3
412         sll             %o5, %g4, %g2
413         srl             %g1, %g6, %g5
414         srl             %g4, 3, %g3
415         or              %g2, %g5, %g2
416         add             %o1, %g3, %o1
417         andcc           %o2, 2, %g0
418         st              %g2, [%o0 + 12]
419         be              1f
420          andcc          %o2, 1, %g0
421         
422         ldub            [%o1 + 15], %g5
423         add             %o1, -2, %o1
424         stb             %g5, [%o0 + 11]
425         add             %o0, -2, %o0
426         ldub            [%o1 + 16], %g5
427         stb             %g5, [%o0 + 12]
428 1:      be              1f
429          nop
430         ldub            [%o1 + 15], %g5
431         stb             %g5, [%o0 + 11]
432 1:      retl
433          ld             [%sp + 64], %o0
434
435 78:     andcc           %o1, 1, %g0
436         be              4f
437          andcc          %o1, 2, %g0
438
439         ldub            [%o1], %g2
440         add             %o1, 1, %o1
441         stb             %g2, [%o0]
442         sub             %o2, 1, %o2
443         bne             3f
444          add            %o0, 1, %o0
445 4:      lduh            [%o1], %g2
446         add             %o1, 2, %o1
447         sth             %g2, [%o0]
448         sub             %o2, 2, %o2
449         b               3f
450          add            %o0, 2, %o0
451 END(memmove)
452 libc_hidden_def(memmove)
453
454 ENTRY(memcpy)           /* %o0=dst %o1=src %o2=len */
455         sub             %o0, %o1, %o4
456         st              %o0, [%sp + 64]
457 9:      andcc           %o4, 3, %o5
458 0:      bne             86f
459          cmp            %o2, 15
460
461         bleu            90f
462          andcc          %o1, 3, %g0
463
464         bne             78b
465 3:       andcc          %o1, 4, %g0
466
467         be              2f
468          mov            %o2, %g1
469
470         ld              [%o1], %o4
471         sub             %g1, 4, %g1
472         st              %o4, [%o0]
473         add             %o1, 4, %o1
474         add             %o0, 4, %o0
475 2:      andcc           %g1, 0xffffff80, %g6
476         be              3f
477          andcc          %o0, 4, %g0
478
479         be              82f + 4
480 5:      MOVE_BIGCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5)
481         MOVE_BIGCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5)
482         MOVE_BIGCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5)
483         MOVE_BIGCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5)
484         subcc           %g6, 128, %g6
485         add             %o1, 128, %o1
486         bne             5b
487          add            %o0, 128, %o0
488 3:      andcc           %g1, 0x70, %g6
489         be              80f
490          andcc          %g1, 8, %g0
491
492         srl             %g6, 1, %o4
493         mov             %o7, %g2
494         add             %g6, %o4, %o4
495         add             %o1, %g6, %o1
496 104:    call            100f
497          add            %o0, %g6, %o0
498         jmpl            %o5 + (80f - 104b), %g0
499          mov            %g2, %o7
500
501 79:     MOVE_LASTCHUNK(o1, o0, 0x60, g2, g3, g4, g5)
502         MOVE_LASTCHUNK(o1, o0, 0x50, g2, g3, g4, g5)
503         MOVE_LASTCHUNK(o1, o0, 0x40, g2, g3, g4, g5)
504         MOVE_LASTCHUNK(o1, o0, 0x30, g2, g3, g4, g5)
505         MOVE_LASTCHUNK(o1, o0, 0x20, g2, g3, g4, g5)
506         MOVE_LASTCHUNK(o1, o0, 0x10, g2, g3, g4, g5)
507         MOVE_LASTCHUNK(o1, o0, 0x00, g2, g3, g4, g5)
508
509 80:     be              81f
510          andcc          %g1, 4, %g0
511
512         ldd             [%o1], %g2
513         add             %o0, 8, %o0
514         st              %g2, [%o0 - 0x08]
515         add             %o1, 8, %o1
516         st              %g3, [%o0 - 0x04]
517
518 81:     be              1f
519          andcc          %g1, 2, %g0
520
521         ld              [%o1], %g2
522         add             %o1, 4, %o1
523         st              %g2, [%o0]
524         add             %o0, 4, %o0
525 1:      be              1f
526          andcc          %g1, 1, %g0
527
528         lduh            [%o1], %g2
529         add             %o1, 2, %o1
530         sth             %g2, [%o0]
531         add             %o0, 2, %o0
532 1:      be              1f
533          nop
534
535         ldub            [%o1], %g2
536         stb             %g2, [%o0]
537 1:      retl
538          ld             [%sp + 64], %o0
539
540 82:     /* ldd_std */
541         MOVE_BIGALIGNCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5)
542         MOVE_BIGALIGNCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5)
543         MOVE_BIGALIGNCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5)
544         MOVE_BIGALIGNCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5)
545         subcc           %g6, 128, %g6
546         add             %o1, 128, %o1
547         bne             82b
548          add            %o0, 128, %o0
549
550         andcc           %g1, 0x70, %g6
551         be              84f
552          andcc          %g1, 8, %g0
553
554         mov             %o7, %g2
555 111:    call            110f
556          add            %o1, %g6, %o1
557         mov             %g2, %o7
558         jmpl            %o5 + (84f - 111b), %g0
559          add            %o0, %g6, %o0
560
561 83:     MOVE_LASTALIGNCHUNK(o1, o0, 0x60, g2, g3, g4, g5)
562         MOVE_LASTALIGNCHUNK(o1, o0, 0x50, g2, g3, g4, g5)
563         MOVE_LASTALIGNCHUNK(o1, o0, 0x40, g2, g3, g4, g5)
564         MOVE_LASTALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5)
565         MOVE_LASTALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5)
566         MOVE_LASTALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5)
567         MOVE_LASTALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5)
568
569 84:     be              85f
570          andcc          %g1, 4, %g0
571
572         ldd             [%o1], %g2
573         add             %o0, 8, %o0
574         std             %g2, [%o0 - 0x08]
575         add             %o1, 8, %o1
576 85:     be              1f
577          andcc          %g1, 2, %g0
578
579         ld              [%o1], %g2
580         add             %o1, 4, %o1
581         st              %g2, [%o0]
582         add             %o0, 4, %o0
583 1:      be              1f
584          andcc          %g1, 1, %g0
585
586         lduh            [%o1], %g2
587         add             %o1, 2, %o1
588         sth             %g2, [%o0]
589         add             %o0, 2, %o0
590 1:      be              1f
591          nop
592
593         ldub            [%o1], %g2
594         stb             %g2, [%o0]
595 1:      retl
596          ld             [%sp + 64], %o0
597
598 86:     cmp             %o2, 6
599         bleu            88f
600
601          cmp            %o2, 256
602         bcc             87f
603
604          andcc          %o0, 3, %g0
605         be              61f
606          andcc          %o0, 1, %g0
607         be              60f
608          andcc          %o0, 2, %g0
609
610         ldub            [%o1], %g5
611         add             %o1, 1, %o1
612         stb             %g5, [%o0]
613         sub             %o2, 1, %o2
614         bne             61f
615          add            %o0, 1, %o0
616 60:     ldub            [%o1], %g3
617         add             %o1, 2, %o1
618         stb             %g3, [%o0]
619         sub             %o2, 2, %o2
620         ldub            [%o1 - 1], %g3
621         add             %o0, 2, %o0
622         stb             %g3, [%o0 - 1]
623 61:     and             %o1, 3, %g2
624         and             %o2, 0xc, %g3
625         and             %o1, -4, %o1
626         cmp             %g3, 4
627         sll             %g2, 3, %g4
628         mov             32, %g2
629         be              4f
630          sub            %g2, %g4, %g6
631         
632         blu             3f
633          cmp            %g3, 0x8
634
635         be              2f
636          srl            %o2, 2, %g3
637
638         ld              [%o1], %o3
639         add             %o0, -8, %o0
640         ld              [%o1 + 4], %o4
641         b               8f
642          add            %g3, 1, %g3
643 2:      ld              [%o1], %o4
644         add             %o0, -12, %o0
645         ld              [%o1 + 4], %o5
646         add             %g3, 2, %g3
647         b               9f
648          add            %o1, -4, %o1
649 3:      ld              [%o1], %g1
650         add             %o0, -4, %o0
651         ld              [%o1 + 4], %o3
652         srl             %o2, 2, %g3
653         b               7f
654          add            %o1, 4, %o1
655 4:      ld              [%o1], %o5
656         cmp             %o2, 7
657         ld              [%o1 + 4], %g1
658         srl             %o2, 2, %g3
659         bleu            10f
660          add            %o1, 8, %o1
661
662         ld              [%o1], %o3
663         add             %g3, -1, %g3
664 5:      sll             %o5, %g4, %g2
665         srl             %g1, %g6, %g5
666         or              %g2, %g5, %g2
667         st              %g2, [%o0]
668 7:      ld              [%o1 + 4], %o4
669         sll             %g1, %g4, %g2
670         srl             %o3, %g6, %g5
671         or              %g2, %g5, %g2
672         st              %g2, [%o0 + 4]
673 8:      ld              [%o1 + 8], %o5
674         sll             %o3, %g4, %g2
675         srl             %o4, %g6, %g5
676         or              %g2, %g5, %g2
677         st              %g2, [%o0 + 8]
678 9:      ld              [%o1 + 12], %g1
679         sll             %o4, %g4, %g2
680         srl             %o5, %g6, %g5
681         addcc           %g3, -4, %g3
682         or              %g2, %g5, %g2
683         add             %o1, 16, %o1
684         st              %g2, [%o0 + 12]
685         add             %o0, 16, %o0
686         bne,a           5b
687          ld             [%o1], %o3
688 10:     sll             %o5, %g4, %g2
689         srl             %g1, %g6, %g5
690         srl             %g6, 3, %g3
691         or              %g2, %g5, %g2
692         sub             %o1, %g3, %o1
693         andcc           %o2, 2, %g0
694         st              %g2, [%o0]
695         be              1f
696          andcc          %o2, 1, %g0
697
698         ldub            [%o1], %g2
699         add             %o1, 2, %o1
700         stb             %g2, [%o0 + 4]
701         add             %o0, 2, %o0
702         ldub            [%o1 - 1], %g2
703         stb             %g2, [%o0 + 3]
704 1:      be              1f
705          nop
706         ldub            [%o1], %g2
707         stb             %g2, [%o0 + 4]
708 1:      retl
709          ld             [%sp + 64], %o0
710
711 87:     andcc           %o1, 3, %g0
712         be              3f
713          andcc          %o1, 1, %g0
714
715         be              4f
716          andcc          %o1, 2, %g0
717
718         ldub            [%o1], %g2
719         add             %o1, 1, %o1
720         stb             %g2, [%o0]
721         sub             %o2, 1, %o2
722         bne             3f
723          add            %o0, 1, %o0
724 4:      lduh            [%o1], %g2
725         add             %o1, 2, %o1
726         srl             %g2, 8, %g3
727         sub             %o2, 2, %o2
728         stb             %g3, [%o0]
729         add             %o0, 2, %o0
730         stb             %g2, [%o0 - 1]
731 3:       andcc          %o1, 4, %g0
732
733         bne             2f
734          cmp            %o5, 1
735
736         ld              [%o1], %o4
737         srl             %o4, 24, %g2
738         stb             %g2, [%o0]
739         srl             %o4, 16, %g3
740         stb             %g3, [%o0 + 1]
741         srl             %o4, 8, %g2
742         stb             %g2, [%o0 + 2]
743         sub             %o2, 4, %o2
744         stb             %o4, [%o0 + 3]
745         add             %o1, 4, %o1
746         add             %o0, 4, %o0
747 2:      be              33f
748          cmp            %o5, 2
749         be              32f
750          sub            %o2, 4, %o2
751 31:     ld              [%o1], %g2
752         add             %o1, 4, %o1
753         srl             %g2, 24, %g3
754         and             %o0, 7, %g5
755         stb             %g3, [%o0]
756         cmp             %g5, 7
757         sll             %g2, 8, %g1
758         add             %o0, 4, %o0
759         be              41f
760          and            %o2, 0xffffffc0, %o3
761         ld              [%o0 - 7], %o4
762 4:      SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 8, 24, -3)
763         SMOVE_CHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g6, g1, 8, 24, -3)
764         SMOVE_CHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g6, g1, 8, 24, -3)
765         SMOVE_CHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g6, g1, 8, 24, -3)
766         subcc           %o3, 64, %o3
767         add             %o1, 64, %o1
768         bne             4b
769          add            %o0, 64, %o0
770
771         andcc           %o2, 0x30, %o3
772         be,a            1f
773          srl            %g1, 16, %g2
774 4:      SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 8, 24, -3)
775         subcc           %o3, 16, %o3
776         add             %o1, 16, %o1
777         bne             4b
778          add            %o0, 16, %o0
779
780         srl             %g1, 16, %g2
781 1:      st              %o4, [%o0 - 7]
782         sth             %g2, [%o0 - 3]
783         srl             %g1, 8, %g4
784         b               88f
785          stb            %g4, [%o0 - 1]
786 32:     ld              [%o1], %g2
787         add             %o1, 4, %o1
788         srl             %g2, 16, %g3
789         and             %o0, 7, %g5
790         sth             %g3, [%o0]
791         cmp             %g5, 6
792         sll             %g2, 16, %g1
793         add             %o0, 4, %o0
794         be              42f
795          and            %o2, 0xffffffc0, %o3
796         ld              [%o0 - 6], %o4
797 4:      SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 16, 16, -2)
798         SMOVE_CHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g6, g1, 16, 16, -2)
799         SMOVE_CHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g6, g1, 16, 16, -2)
800         SMOVE_CHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g6, g1, 16, 16, -2)
801         subcc           %o3, 64, %o3
802         add             %o1, 64, %o1
803         bne             4b
804          add            %o0, 64, %o0
805
806         andcc           %o2, 0x30, %o3
807         be,a            1f
808          srl            %g1, 16, %g2
809 4:      SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 16, 16, -2)
810         subcc           %o3, 16, %o3
811         add             %o1, 16, %o1
812         bne             4b
813          add            %o0, 16, %o0
814
815         srl             %g1, 16, %g2
816 1:      st              %o4, [%o0 - 6]
817         b               88f
818          sth            %g2, [%o0 - 2]
819 33:     ld              [%o1], %g2
820         sub             %o2, 4, %o2
821         srl             %g2, 24, %g3
822         and             %o0, 7, %g5
823         stb             %g3, [%o0]
824         cmp             %g5, 5
825         srl             %g2, 8, %g4
826         sll             %g2, 24, %g1
827         sth             %g4, [%o0 + 1]
828         add             %o1, 4, %o1
829         be              43f
830          and            %o2, 0xffffffc0, %o3
831
832         ld              [%o0 - 1], %o4
833         add             %o0, 4, %o0
834 4:      SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 24, 8, -1)
835         SMOVE_CHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g6, g1, 24, 8, -1)
836         SMOVE_CHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g6, g1, 24, 8, -1)
837         SMOVE_CHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g6, g1, 24, 8, -1)
838         subcc           %o3, 64, %o3
839         add             %o1, 64, %o1
840         bne             4b
841          add            %o0, 64, %o0
842
843         andcc           %o2, 0x30, %o3
844         be,a            1f
845          srl            %g1, 24, %g2
846 4:      SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 24, 8, -1)
847         subcc           %o3, 16, %o3
848         add             %o1, 16, %o1
849         bne             4b
850          add            %o0, 16, %o0
851
852         srl             %g1, 24, %g2
853 1:      st              %o4, [%o0 - 5]
854         b               88f
855          stb            %g2, [%o0 - 1]
856 41:     SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 8, 24, -3)
857         SMOVE_ALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g6, g1, 8, 24, -3)
858         SMOVE_ALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g6, g1, 8, 24, -3)
859         SMOVE_ALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g6, g1, 8, 24, -3)
860         subcc           %o3, 64, %o3
861         add             %o1, 64, %o1
862         bne             41b
863          add            %o0, 64, %o0
864          
865         andcc           %o2, 0x30, %o3
866         be,a            1f
867          srl            %g1, 16, %g2
868 4:      SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 8, 24, -3)
869         subcc           %o3, 16, %o3
870         add             %o1, 16, %o1
871         bne             4b
872          add            %o0, 16, %o0
873
874         srl             %g1, 16, %g2
875 1:      sth             %g2, [%o0 - 3]
876         srl             %g1, 8, %g4
877         b               88f
878          stb            %g4, [%o0 - 1]
879 43:     SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 24, 8, 3)
880         SMOVE_ALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g6, g1, 24, 8, 3)
881         SMOVE_ALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g6, g1, 24, 8, 3)
882         SMOVE_ALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g6, g1, 24, 8, 3)
883         subcc           %o3, 64, %o3
884         add             %o1, 64, %o1
885         bne             43b
886          add            %o0, 64, %o0
887
888         andcc           %o2, 0x30, %o3
889         be,a            1f
890          srl            %g1, 24, %g2
891 4:      SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 24, 8, 3)
892         subcc           %o3, 16, %o3
893         add             %o1, 16, %o1
894         bne             4b
895          add            %o0, 16, %o0
896
897         srl             %g1, 24, %g2
898 1:      stb             %g2, [%o0 + 3]
899         b               88f
900          add            %o0, 4, %o0
901 42:     SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 16, 16, -2)
902         SMOVE_ALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g6, g1, 16, 16, -2)
903         SMOVE_ALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g6, g1, 16, 16, -2)
904         SMOVE_ALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g6, g1, 16, 16, -2)
905         subcc           %o3, 64, %o3
906         add             %o1, 64, %o1
907         bne             42b
908          add            %o0, 64, %o0
909          
910         andcc           %o2, 0x30, %o3
911         be,a            1f
912          srl            %g1, 16, %g2
913 4:      SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 16, 16, -2)
914         subcc           %o3, 16, %o3
915         add             %o1, 16, %o1
916         bne             4b
917          add            %o0, 16, %o0
918
919         srl             %g1, 16, %g2
920 1:      sth             %g2, [%o0 - 2]
921
922         /* Fall through */
923          
924 88:     and             %o2, 0xe, %o3
925         mov             %o7, %g2
926         sll             %o3, 3, %o4
927         add             %o0, %o3, %o0
928 106:    call            100f
929          add            %o1, %o3, %o1
930         mov             %g2, %o7
931         jmpl            %o5 + (89f - 106b), %g0
932          andcc          %o2, 1, %g0
933
934         MOVE_SHORTCHUNK(o1, o0, 0x0c, g2, g3)
935         MOVE_SHORTCHUNK(o1, o0, 0x0a, g2, g3)
936         MOVE_SHORTCHUNK(o1, o0, 0x08, g2, g3)
937         MOVE_SHORTCHUNK(o1, o0, 0x06, g2, g3)
938         MOVE_SHORTCHUNK(o1, o0, 0x04, g2, g3)
939         MOVE_SHORTCHUNK(o1, o0, 0x02, g2, g3)
940         MOVE_SHORTCHUNK(o1, o0, 0x00, g2, g3)
941
942 89:     be              1f
943          nop
944
945         ldub            [%o1], %g2
946         stb             %g2, [%o0]
947 1:      retl
948          ld             [%sp + 64], %o0
949
950 90:     bne             88b
951          andcc          %o2, 8, %g0
952
953         be              1f
954          andcc          %o2, 4, %g0
955
956         ld              [%o1 + 0x00], %g2
957         ld              [%o1 + 0x04], %g3
958         add             %o1, 8, %o1
959         st              %g2, [%o0 + 0x00]
960         st              %g3, [%o0 + 0x04]
961         add             %o0, 8, %o0
962 1:      b               81b
963          mov            %o2, %g1
964
965 100:    retl
966          sub            %o7, %o4, %o5
967 110:    retl
968          sub            %o7, %g6, %o5
969 END(memcpy)
970 libc_hidden_def(memcpy)