1/* Copyright (C) 1999-2022 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
8
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, see
16 <https://www.gnu.org/licenses/>. */
17
18#include <sysdep.h>
19
20/* void *memcpy(void *dst, const void *src, size_t n);
21 No overlap between the memory of DST and of SRC are assumed. */
22
23ENTRY(memcpy)
24 mov r4,r3 /* Save destination. */
25
26 /* If less than 11 bytes, just do a byte copy. */
27 mov #11,r0
28 cmp/gt r6,r0
29 bt L_byteloop_init
30
31 /* Check if we need to word-align source. */
32 mov r5,r0
33 tst #1,r0
34 bt L_wordalign
35
36 mov.b @r0+,r1 /* Copy one byte. */
37 add #-1,r6
38 mov.b r1,@r4
39 add #1,r4
40
41 .balignw 4,0x0009
42L_wordalign:
43 /* Check if we need to longword-align source. */
44 tst #2,r0
45 bt L_copy
46
47 mov.w @r0+,r1 /* Copy one word. */
48 add #-2,r6
49#ifdef __BIG_ENDIAN__
50 add #1,r4
51 mov.b r1,@r4
52 shlr8 r1
53 mov.b r1,@-r4
54 add #2,r4
55#else
56 mov.b r1,@r4
57 add #1,r4
58 shlr8 r1
59 mov.b r1,@r4
60 add #1,r4
61#endif
62L_copy:
63 mov r0,r5
64
65 /* Calculate the correct routine to handle the destination
66 alignment and simultaneously calculate the loop counts for
67 both the 2 word copy loop and byte copy loop. */
68 mova L_jumptable,r0
69 mov r0,r1
70 mov r4,r0
71 mov r6,r7
72 and #3,r0
73 shlr2 r7
74 shll r0
75 shlr r7
76 mov.w @(r0,r1),r2
77 mov #7,r0
78 braf r2
79 and r0,r6
80L_base:
81
82 .balign 4
83L_jumptable:
84 .word L_copydest0 - L_base
85 .word L_copydest1_or_3 - L_base
86 .word L_copydest2 - L_base
87 .word L_copydest1_or_3 - L_base
88
89 .balign 4
90 /* Copy routine for (dest mod 4) == 1 or == 3. */
91L_copydest1_or_3:
92 add #-1,r4
93 .balignw 4,0x0009
94L_copydest1_or_3_loop:
95 mov.l @r5+,r0 /* Read first longword. */
96 dt r7
97 mov.l @r5+,r1 /* Read second longword. */
98#ifdef __BIG_ENDIAN__
99 /* Write first longword as byte, word, byte. */
100 mov.b r0,@(4,r4)
101 shlr8 r0
102 mov.w r0,@(2,r4)
103 shlr16 r0
104 mov.b r0,@(1,r4)
105 mov r1,r0
106 /* Write second longword as byte, word, byte. */
107 mov.b r0,@(8,r4)
108 shlr8 r0
109 mov.w r0,@(6,r4)
110 shlr16 r0
111 mov.b r0,@(5,r4)
112#else
113 /* Write first longword as byte, word, byte. */
114 mov.b r0,@(1,r4)
115 shlr8 r0
116 mov.w r0,@(2,r4)
117 shlr16 r0
118 mov.b r0,@(4,r4)
119 mov r1,r0
120 /* Write second longword as byte, word, byte. */
121 mov.b r0,@(5,r4)
122 shlr8 r0
123 mov.w r0,@(6,r4)
124 shlr16 r0
125 mov.b r0,@(8,r4)
126#endif
127 bf/s L_copydest1_or_3_loop
128 add #8,r4
129
130 bra L_byteloop_init
131 add #1,r4
132
133 .balign 4
134 /* Copy routine for (dest mod 4) == 2. */
135L_copydest2:
136L_copydest2_loop:
137 mov.l @r5+,r0
138 dt r7
139 mov.l @r5+,r1
140#ifdef __BIG_ENDIAN__
141 mov.w r0,@(2,r4)
142 shlr16 r0
143 mov.w r0,@r4
144 mov r1,r0
145 mov.w r0,@(6,r4)
146 shlr16 r0
147 mov.w r0,@(4,r4)
148#else
149 mov.w r0,@r4
150 shlr16 r0
151 mov.w r0,@(2,r4)
152 mov r1,r0
153 mov.w r0,@(4,r4)
154 shlr16 r0
155 mov.w r0,@(6,r4)
156#endif
157 bf/s L_copydest2_loop
158 add #8,r4
159
160 bra L_byteloop_init
161 nop
162
163 .balign 4
164 /* Copy routine for (dest mod 4) == 0. */
165L_copydest0:
166 add #-8,r4
167 .balignw 4,0x0009
168L_copydest0_loop:
169 mov.l @r5+,r0
170 dt r7
171 mov.l @r5+,r1
172 add #8,r4
173 mov.l r0,@r4
174 bf/s L_copydest0_loop
175 mov.l r1,@(4,r4)
176
177 add #8,r4 /* Fall through. */
178
179L_byteloop_init:
180 tst r6,r6
181 bt L_exit
182
183 .balignw 4,0x0009
184 /* Copy remaining bytes. */
185L_byteloop:
186 mov.b @r5+,r0
187 dt r6
188 mov.b r0,@r4
189 bf/s L_byteloop
190 add #1,r4
191
192L_exit:
193 rts
194 mov r3,r0 /* Return destination. */
195END(memcpy)
196libc_hidden_builtin_def (memcpy)
197

source code of glibc/sysdeps/sh/memcpy.S