1 /* Copy SIZE bytes from SRC to DEST.
3 Copyright (C) 1996-2024 Free Software Foundation, Inc.
4 This file is part of the GNU C Library.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, see
18 <https://www.gnu.org/licenses/>. */
22 /* Both these macros have to start with exactly the same insn */
23 #define MOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) \
24 ldd [%src + offset + 0x00], %t0; \
25 ldd [%src + offset + 0x08], %t2; \
26 ldd [%src + offset + 0x10], %t4; \
27 ldd [%src + offset + 0x18], %t6; \
28 st %t0, [%dst + offset + 0x00]; \
29 st %t1, [%dst + offset + 0x04]; \
30 st %t2, [%dst + offset + 0x08]; \
31 st %t3, [%dst + offset + 0x0c]; \
32 st %t4, [%dst + offset + 0x10]; \
33 st %t5, [%dst + offset + 0x14]; \
34 st %t6, [%dst + offset + 0x18]; \
35 st %t7, [%dst + offset + 0x1c];
37 #define MOVE_BIGALIGNCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) \
38 ldd [%src + offset + 0x00], %t0; \
39 ldd [%src + offset + 0x08], %t2; \
40 ldd [%src + offset + 0x10], %t4; \
41 ldd [%src + offset + 0x18], %t6; \
42 std %t0, [%dst + offset + 0x00]; \
43 std %t2, [%dst + offset + 0x08]; \
44 std %t4, [%dst + offset + 0x10]; \
45 std %t6, [%dst + offset + 0x18];
47 #define MOVE_LASTCHUNK(src, dst, offset, t0, t1, t2, t3) \
48 ldd [%src - offset - 0x10], %t0; \
49 ldd [%src - offset - 0x08], %t2; \
50 st %t0, [%dst - offset - 0x10]; \
51 st %t1, [%dst - offset - 0x0c]; \
52 st %t2, [%dst - offset - 0x08]; \
53 st %t3, [%dst - offset - 0x04];
55 #define MOVE_LASTALIGNCHUNK(src, dst, offset, t0, t1, t2, t3) \
56 ldd [%src - offset - 0x10], %t0; \
57 ldd [%src - offset - 0x08], %t2; \
58 std %t0, [%dst - offset - 0x10]; \
59 std %t2, [%dst - offset - 0x08];
61 #define MOVE_SHORTCHUNK(src, dst, offset, t0, t1) \
62 ldub [%src - offset - 0x02], %t0; \
63 ldub [%src - offset - 0x01], %t1; \
64 stb %t0, [%dst - offset - 0x02]; \
65 stb %t1, [%dst - offset - 0x01];
67 #define SMOVE_CHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, prev, shil, shir, offset2) \
68 ldd [%src + offset + 0x00], %t0; \
69 ldd [%src + offset + 0x08], %t2; \
74 sll %t1, shil, %prev; \
80 std %t4, [%dst + offset + offset2 - 0x04]; \
81 std %t0, [%dst + offset + offset2 + 0x04]; \
82 sll %t3, shil, %prev; \
85 #define SMOVE_ALIGNCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, prev, shil, shir, offset2) \
86 ldd [%src + offset + 0x00], %t0; \
87 ldd [%src + offset + 0x08], %t2; \
92 sll %t1, shil, %prev; \
98 sll %t3, shil, %prev; \
100 std %t0, [%dst + offset + offset2 + 0x00]; \
101 std %t2, [%dst + offset + offset2 + 0x08];
111 ENTRY(memcpy) /* %o0=dst %o1=src %o2=len */
141 77: andcc %o1, 4, %g0
150 2: andcc %g1, 0xffffff80, %g6
155 5: MOVE_BIGCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5)
156 MOVE_BIGCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5)
157 MOVE_BIGCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5)
158 MOVE_BIGCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5)
163 3: andcc %g1, 0x70, %g6
173 jmpl %o5 + (80f - 104b), %g0
176 79: MOVE_LASTCHUNK(o1, o0, 0x60, g2, g3, g4, g5)
177 MOVE_LASTCHUNK(o1, o0, 0x50, g2, g3, g4, g5)
178 MOVE_LASTCHUNK(o1, o0, 0x40, g2, g3, g4, g5)
179 MOVE_LASTCHUNK(o1, o0, 0x30, g2, g3, g4, g5)
180 MOVE_LASTCHUNK(o1, o0, 0x20, g2, g3, g4, g5)
181 MOVE_LASTCHUNK(o1, o0, 0x10, g2, g3, g4, g5)
182 MOVE_LASTCHUNK(o1, o0, 0x00, g2, g3, g4, g5)
216 MOVE_BIGALIGNCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5)
217 MOVE_BIGALIGNCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5)
218 MOVE_BIGALIGNCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5)
219 MOVE_BIGALIGNCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5)
233 jmpl %o5 + (84f - 111b), %g0
236 83: MOVE_LASTALIGNCHUNK(o1, o0, 0x60, g2, g3, g4, g5)
237 MOVE_LASTALIGNCHUNK(o1, o0, 0x50, g2, g3, g4, g5)
238 MOVE_LASTALIGNCHUNK(o1, o0, 0x40, g2, g3, g4, g5)
239 MOVE_LASTALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5)
240 MOVE_LASTALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5)
241 MOVE_LASTALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5)
242 MOVE_LASTALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5)
249 std %g2, [%o0 - 0x08]
353 9: ld [%o1 + 12], %g1
363 10: sll %o5, %g4, %g2
386 87: andcc %o1, 3, %g0
435 and %o2, 0xffffffc0, %o3
437 4: SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 8, 24, -3)
438 SMOVE_CHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g6, g1, 8, 24, -3)
439 SMOVE_CHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g6, g1, 8, 24, -3)
440 SMOVE_CHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g6, g1, 8, 24, -3)
449 4: SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 8, 24, -3)
470 and %o2, 0xffffffc0, %o3
472 4: SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 16, 16, -2)
473 SMOVE_CHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g6, g1, 16, 16, -2)
474 SMOVE_CHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g6, g1, 16, 16, -2)
475 SMOVE_CHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g6, g1, 16, 16, -2)
484 4: SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 16, 16, -2)
505 and %o2, 0xffffffc0, %o3
509 4: SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 24, 8, -1)
510 SMOVE_CHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g6, g1, 24, 8, -1)
511 SMOVE_CHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g6, g1, 24, 8, -1)
512 SMOVE_CHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g6, g1, 24, 8, -1)
521 4: SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 24, 8, -1)
531 41: SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 8, 24, -3)
532 SMOVE_ALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g6, g1, 8, 24, -3)
533 SMOVE_ALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g6, g1, 8, 24, -3)
534 SMOVE_ALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g6, g1, 8, 24, -3)
543 4: SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 8, 24, -3)
550 1: sth %g2, [%o0 - 3]
554 43: SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 24, 8, 3)
555 SMOVE_ALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g6, g1, 24, 8, 3)
556 SMOVE_ALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g6, g1, 24, 8, 3)
557 SMOVE_ALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g6, g1, 24, 8, 3)
566 4: SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 24, 8, 3)
573 1: stb %g2, [%o0 + 3]
576 42: SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 16, 16, -2)
577 SMOVE_ALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g6, g1, 16, 16, -2)
578 SMOVE_ALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g6, g1, 16, 16, -2)
579 SMOVE_ALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g6, g1, 16, 16, -2)
588 4: SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 16, 16, -2)
595 1: sth %g2, [%o0 - 2]
599 88: and %o2, 0xe, %o3
606 jmpl %o5 + (89f - 106b), %g0
609 MOVE_SHORTCHUNK(o1, o0, 0x0c, g2, g3)
610 MOVE_SHORTCHUNK(o1, o0, 0x0a, g2, g3)
611 MOVE_SHORTCHUNK(o1, o0, 0x08, g2, g3)
612 MOVE_SHORTCHUNK(o1, o0, 0x06, g2, g3)
613 MOVE_SHORTCHUNK(o1, o0, 0x04, g2, g3)
614 MOVE_SHORTCHUNK(o1, o0, 0x02, g2, g3)
615 MOVE_SHORTCHUNK(o1, o0, 0x00, g2, g3)
646 libc_hidden_builtin_def (memcpy)
648 libc_hidden_def (__mempcpy)
649 weak_alias (__mempcpy, mempcpy)
650 libc_hidden_builtin_def (mempcpy)