1 /* Copy SIZE bytes from SRC to DEST.
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
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];
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];
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];
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];
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];
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];
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];
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];
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];
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; \
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; \
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; \
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; \
141 std %t0, [%dst + offset + offset2 + 0x00]; \
142 std %t2, [%dst + offset + offset2 + 0x08];
147 70: andcc %o1, 1, %g0
157 4: lduh [%o1 - 2], %g2
169 libc_hidden_def(bcopy)
199 2: andcc %g1, 0xffffff80, %g6
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)
213 3: andcc %g1, 0x70, %g6
223 jmpl %o5 + (72f - 101b), %g0
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)
236 ldd [%o1 - 0x08], %g2
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)
282 jmpl %o5 + (72b - 102b), %g0
285 75: and %o2, 0xe, %o3
292 jmpl %o5 + (76f - 103b), %g0
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)
339 63: ldub [%o1 - 1], %g5
435 78: andcc %o1, 1, %g0
452 libc_hidden_def(memmove)
454 ENTRY(memcpy) /* %o0=dst %o1=src %o2=len */
475 2: andcc %g1, 0xffffff80, %g6
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)
488 3: andcc %g1, 0x70, %g6
498 jmpl %o5 + (80f - 104b), %g0
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)
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)
558 jmpl %o5 + (84f - 111b), %g0
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)
574 std %g2, [%o0 - 0x08]
678 9: ld [%o1 + 12], %g1
688 10: sll %o5, %g4, %g2
711 87: andcc %o1, 3, %g0
760 and %o2, 0xffffffc0, %o3
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)
774 4: SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 8, 24, -3)
795 and %o2, 0xffffffc0, %o3
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)
809 4: SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 16, 16, -2)
830 and %o2, 0xffffffc0, %o3
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)
846 4: SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 24, 8, -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)
868 4: SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 8, 24, -3)
875 1: sth %g2, [%o0 - 3]
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)
891 4: SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 24, 8, 3)
898 1: stb %g2, [%o0 + 3]
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)
913 4: SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 16, 16, -2)
920 1: sth %g2, [%o0 - 2]
924 88: and %o2, 0xe, %o3
931 jmpl %o5 + (89f - 106b), %g0
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)
970 libc_hidden_def(memcpy)