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