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