authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-01-16 23:26:18-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-01-17 12:34:15-08:00
loge6dc85f1b43697074eb60d3176b83a149f80894e
tree761796b8b6945b1dca6285afced2fc2b615a36d1
parentc748eb2416d067688d1f4f40af78478e7dfdc4bf

remove memcpy and memmove from bundled libcs

These are provided instead by compiler_rt. Part of #2879

15 files changed, 0 insertions(+), 1821 deletions(-)

lib/libc/musl/src/string/aarch64/memcpy.S deleted-186
...@@ -1,186 +0,0 @@
1/*
2 * memcpy - copy memory area
3 *
4 * Copyright (c) 2012-2020, Arm Limited.
5 * SPDX-License-Identifier: MIT
6 */
7
8/* Assumptions:
9 *
10 * ARMv8-a, AArch64, unaligned accesses.
11 *
12 */
13
14#define dstin x0
15#define src x1
16#define count x2
17#define dst x3
18#define srcend x4
19#define dstend x5
20#define A_l x6
21#define A_lw w6
22#define A_h x7
23#define B_l x8
24#define B_lw w8
25#define B_h x9
26#define C_l x10
27#define C_lw w10
28#define C_h x11
29#define D_l x12
30#define D_h x13
31#define E_l x14
32#define E_h x15
33#define F_l x16
34#define F_h x17
35#define G_l count
36#define G_h dst
37#define H_l src
38#define H_h srcend
39#define tmp1 x14
40
41/* This implementation of memcpy uses unaligned accesses and branchless
42 sequences to keep the code small, simple and improve performance.
43
44 Copies are split into 3 main cases: small copies of up to 32 bytes, medium
45 copies of up to 128 bytes, and large copies. The overhead of the overlap
46 check is negligible since it is only required for large copies.
47
48 Large copies use a software pipelined loop processing 64 bytes per iteration.
49 The destination pointer is 16-byte aligned to minimize unaligned accesses.
50 The loop tail is handled by always copying 64 bytes from the end.
51*/
52
53.global memcpy
54.type memcpy,%function
55memcpy:
56 add srcend, src, count
57 add dstend, dstin, count
58 cmp count, 128
59 b.hi .Lcopy_long
60 cmp count, 32
61 b.hi .Lcopy32_128
62
63 /* Small copies: 0..32 bytes. */
64 cmp count, 16
65 b.lo .Lcopy16
66 ldp A_l, A_h, [src]
67 ldp D_l, D_h, [srcend, -16]
68 stp A_l, A_h, [dstin]
69 stp D_l, D_h, [dstend, -16]
70 ret
71
72 /* Copy 8-15 bytes. */
73.Lcopy16:
74 tbz count, 3, .Lcopy8
75 ldr A_l, [src]
76 ldr A_h, [srcend, -8]
77 str A_l, [dstin]
78 str A_h, [dstend, -8]
79 ret
80
81 .p2align 3
82 /* Copy 4-7 bytes. */
83.Lcopy8:
84 tbz count, 2, .Lcopy4
85 ldr A_lw, [src]
86 ldr B_lw, [srcend, -4]
87 str A_lw, [dstin]
88 str B_lw, [dstend, -4]
89 ret
90
91 /* Copy 0..3 bytes using a branchless sequence. */
92.Lcopy4:
93 cbz count, .Lcopy0
94 lsr tmp1, count, 1
95 ldrb A_lw, [src]
96 ldrb C_lw, [srcend, -1]
97 ldrb B_lw, [src, tmp1]
98 strb A_lw, [dstin]
99 strb B_lw, [dstin, tmp1]
100 strb C_lw, [dstend, -1]
101.Lcopy0:
102 ret
103
104 .p2align 4
105 /* Medium copies: 33..128 bytes. */
106.Lcopy32_128:
107 ldp A_l, A_h, [src]
108 ldp B_l, B_h, [src, 16]
109 ldp C_l, C_h, [srcend, -32]
110 ldp D_l, D_h, [srcend, -16]
111 cmp count, 64
112 b.hi .Lcopy128
113 stp A_l, A_h, [dstin]
114 stp B_l, B_h, [dstin, 16]
115 stp C_l, C_h, [dstend, -32]
116 stp D_l, D_h, [dstend, -16]
117 ret
118
119 .p2align 4
120 /* Copy 65..128 bytes. */
121.Lcopy128:
122 ldp E_l, E_h, [src, 32]
123 ldp F_l, F_h, [src, 48]
124 cmp count, 96
125 b.ls .Lcopy96
126 ldp G_l, G_h, [srcend, -64]
127 ldp H_l, H_h, [srcend, -48]
128 stp G_l, G_h, [dstend, -64]
129 stp H_l, H_h, [dstend, -48]
130.Lcopy96:
131 stp A_l, A_h, [dstin]
132 stp B_l, B_h, [dstin, 16]
133 stp E_l, E_h, [dstin, 32]
134 stp F_l, F_h, [dstin, 48]
135 stp C_l, C_h, [dstend, -32]
136 stp D_l, D_h, [dstend, -16]
137 ret
138
139 .p2align 4
140 /* Copy more than 128 bytes. */
141.Lcopy_long:
142
143 /* Copy 16 bytes and then align dst to 16-byte alignment. */
144
145 ldp D_l, D_h, [src]
146 and tmp1, dstin, 15
147 bic dst, dstin, 15
148 sub src, src, tmp1
149 add count, count, tmp1 /* Count is now 16 too large. */
150 ldp A_l, A_h, [src, 16]
151 stp D_l, D_h, [dstin]
152 ldp B_l, B_h, [src, 32]
153 ldp C_l, C_h, [src, 48]
154 ldp D_l, D_h, [src, 64]!
155 subs count, count, 128 + 16 /* Test and readjust count. */
156 b.ls .Lcopy64_from_end
157
158.Lloop64:
159 stp A_l, A_h, [dst, 16]
160 ldp A_l, A_h, [src, 16]
161 stp B_l, B_h, [dst, 32]
162 ldp B_l, B_h, [src, 32]
163 stp C_l, C_h, [dst, 48]
164 ldp C_l, C_h, [src, 48]
165 stp D_l, D_h, [dst, 64]!
166 ldp D_l, D_h, [src, 64]!
167 subs count, count, 64
168 b.hi .Lloop64
169
170 /* Write the last iteration and copy 64 bytes from the end. */
171.Lcopy64_from_end:
172 ldp E_l, E_h, [srcend, -64]
173 stp A_l, A_h, [dst, 16]
174 ldp A_l, A_h, [srcend, -48]
175 stp B_l, B_h, [dst, 32]
176 ldp B_l, B_h, [srcend, -32]
177 stp C_l, C_h, [dst, 48]
178 ldp C_l, C_h, [srcend, -16]
179 stp D_l, D_h, [dst, 64]
180 stp E_l, E_h, [dstend, -64]
181 stp A_l, A_h, [dstend, -48]
182 stp B_l, B_h, [dstend, -32]
183 stp C_l, C_h, [dstend, -16]
184 ret
185
186.size memcpy,.-memcpy
lib/libc/musl/src/string/arm/__aeabi_memcpy.s deleted-45
...@@ -1,45 +0,0 @@
1.syntax unified
2
3.global __aeabi_memcpy8
4.global __aeabi_memcpy4
5.global __aeabi_memcpy
6.global __aeabi_memmove8
7.global __aeabi_memmove4
8.global __aeabi_memmove
9
10.type __aeabi_memcpy8,%function
11.type __aeabi_memcpy4,%function
12.type __aeabi_memcpy,%function
13.type __aeabi_memmove8,%function
14.type __aeabi_memmove4,%function
15.type __aeabi_memmove,%function
16
17__aeabi_memmove8:
18__aeabi_memmove4:
19__aeabi_memmove:
20 cmp r0, r1
21 bls 3f
22 cmp r2, #0
23 beq 2f
24 adds r0, r0, r2
25 adds r2, r1, r2
261: subs r2, r2, #1
27 ldrb r3, [r2]
28 subs r0, r0, #1
29 strb r3, [r0]
30 cmp r1, r2
31 bne 1b
322: bx lr
33__aeabi_memcpy8:
34__aeabi_memcpy4:
35__aeabi_memcpy:
363: cmp r2, #0
37 beq 2f
38 adds r2, r1, r2
391: ldrb r3, [r1]
40 adds r1, r1, #1
41 strb r3, [r0]
42 adds r0, r0, #1
43 cmp r1, r2
44 bne 1b
452: bx lr
lib/libc/musl/src/string/arm/memcpy.S deleted-479
...@@ -1,479 +0,0 @@
1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in
12 * the documentation and/or other materials provided with the
13 * distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29
30/*
31 * Optimized memcpy() for ARM.
32 *
33 * note that memcpy() always returns the destination pointer,
34 * so we have to preserve R0.
35 */
36
37/*
38 * This file has been modified from the original for use in musl libc.
39 * The main changes are: addition of .type memcpy,%function to make the
40 * code safely callable from thumb mode, adjusting the return
41 * instructions to be compatible with pre-thumb ARM cpus, removal of
42 * prefetch code that is not compatible with older cpus and support for
43 * building as thumb 2 and big-endian.
44 */
45
46.syntax unified
47
48.global memcpy
49.type memcpy,%function
50memcpy:
51 /* The stack must always be 64-bits aligned to be compliant with the
52 * ARM ABI. Since we have to save R0, we might as well save R4
53 * which we can use for better pipelining of the reads below
54 */
55 .fnstart
56 .save {r0, r4, lr}
57 stmfd sp!, {r0, r4, lr}
58 /* Making room for r5-r11 which will be spilled later */
59 .pad #28
60 sub sp, sp, #28
61
62 /* it simplifies things to take care of len<4 early */
63 cmp r2, #4
64 blo copy_last_3_and_return
65
66 /* compute the offset to align the source
67 * offset = (4-(src&3))&3 = -src & 3
68 */
69 rsb r3, r1, #0
70 ands r3, r3, #3
71 beq src_aligned
72
73 /* align source to 32 bits. We need to insert 2 instructions between
74 * a ldr[b|h] and str[b|h] because byte and half-word instructions
75 * stall 2 cycles.
76 */
77 movs r12, r3, lsl #31
78 sub r2, r2, r3 /* we know that r3 <= r2 because r2 >= 4 */
79 ldrbmi r3, [r1], #1
80 ldrbcs r4, [r1], #1
81 ldrbcs r12,[r1], #1
82 strbmi r3, [r0], #1
83 strbcs r4, [r0], #1
84 strbcs r12,[r0], #1
85
86src_aligned:
87
88 /* see if src and dst are aligned together (congruent) */
89 eor r12, r0, r1
90 tst r12, #3
91 bne non_congruent
92
93 /* Use post-incriment mode for stm to spill r5-r11 to reserved stack
94 * frame. Don't update sp.
95 */
96 stmea sp, {r5-r11}
97
98 /* align the destination to a cache-line */
99 rsb r3, r0, #0
100 ands r3, r3, #0x1C
101 beq congruent_aligned32
102 cmp r3, r2
103 andhi r3, r2, #0x1C
104
105 /* conditionnaly copies 0 to 7 words (length in r3) */
106 movs r12, r3, lsl #28
107 ldmcs r1!, {r4, r5, r6, r7} /* 16 bytes */
108 ldmmi r1!, {r8, r9} /* 8 bytes */
109 stmcs r0!, {r4, r5, r6, r7}
110 stmmi r0!, {r8, r9}
111 tst r3, #0x4
112 ldrne r10,[r1], #4 /* 4 bytes */
113 strne r10,[r0], #4
114 sub r2, r2, r3
115
116congruent_aligned32:
117 /*
118 * here source is aligned to 32 bytes.
119 */
120
121cached_aligned32:
122 subs r2, r2, #32
123 blo less_than_32_left
124
125 /*
126 * We preload a cache-line up to 64 bytes ahead. On the 926, this will
127 * stall only until the requested world is fetched, but the linefill
128 * continues in the the background.
129 * While the linefill is going, we write our previous cache-line
130 * into the write-buffer (which should have some free space).
131 * When the linefill is done, the writebuffer will
132 * start dumping its content into memory
133 *
134 * While all this is going, we then load a full cache line into
135 * 8 registers, this cache line should be in the cache by now
136 * (or partly in the cache).
137 *
138 * This code should work well regardless of the source/dest alignment.
139 *
140 */
141
142 /* Align the preload register to a cache-line because the cpu does
143 * "critical word first" (the first word requested is loaded first).
144 */
145 @ bic r12, r1, #0x1F
146 @ add r12, r12, #64
147
1481: ldmia r1!, { r4-r11 }
149 subs r2, r2, #32
150
151 /*
152 * NOTE: if r12 is more than 64 ahead of r1, the following ldrhi
153 * for ARM9 preload will not be safely guarded by the preceding subs.
154 * When it is safely guarded the only possibility to have SIGSEGV here
155 * is because the caller overstates the length.
156 */
157 @ ldrhi r3, [r12], #32 /* cheap ARM9 preload */
158 stmia r0!, { r4-r11 }
159 bhs 1b
160
161 add r2, r2, #32
162
163less_than_32_left:
164 /*
165 * less than 32 bytes left at this point (length in r2)
166 */
167
168 /* skip all this if there is nothing to do, which should
169 * be a common case (if not executed the code below takes
170 * about 16 cycles)
171 */
172 tst r2, #0x1F
173 beq 1f
174
175 /* conditionnaly copies 0 to 31 bytes */
176 movs r12, r2, lsl #28
177 ldmcs r1!, {r4, r5, r6, r7} /* 16 bytes */
178 ldmmi r1!, {r8, r9} /* 8 bytes */
179 stmcs r0!, {r4, r5, r6, r7}
180 stmmi r0!, {r8, r9}
181 movs r12, r2, lsl #30
182 ldrcs r3, [r1], #4 /* 4 bytes */
183 ldrhmi r4, [r1], #2 /* 2 bytes */
184 strcs r3, [r0], #4
185 strhmi r4, [r0], #2
186 tst r2, #0x1
187 ldrbne r3, [r1] /* last byte */
188 strbne r3, [r0]
189
190 /* we're done! restore everything and return */
1911: ldmfd sp!, {r5-r11}
192 ldmfd sp!, {r0, r4, lr}
193 bx lr
194
195 /********************************************************************/
196
197non_congruent:
198 /*
199 * here source is aligned to 4 bytes
200 * but destination is not.
201 *
202 * in the code below r2 is the number of bytes read
203 * (the number of bytes written is always smaller, because we have
204 * partial words in the shift queue)
205 */
206 cmp r2, #4
207 blo copy_last_3_and_return
208
209 /* Use post-incriment mode for stm to spill r5-r11 to reserved stack
210 * frame. Don't update sp.
211 */
212 stmea sp, {r5-r11}
213
214 /* compute shifts needed to align src to dest */
215 rsb r5, r0, #0
216 and r5, r5, #3 /* r5 = # bytes in partial words */
217 mov r12, r5, lsl #3 /* r12 = right */
218 rsb lr, r12, #32 /* lr = left */
219
220 /* read the first word */
221 ldr r3, [r1], #4
222 sub r2, r2, #4
223
224 /* write a partial word (0 to 3 bytes), such that destination
225 * becomes aligned to 32 bits (r5 = nb of words to copy for alignment)
226 */
227 movs r5, r5, lsl #31
228
229#if __ARMEB__
230 movmi r3, r3, ror #24
231 strbmi r3, [r0], #1
232 movcs r3, r3, ror #24
233 strbcs r3, [r0], #1
234 movcs r3, r3, ror #24
235 strbcs r3, [r0], #1
236#else
237 strbmi r3, [r0], #1
238 movmi r3, r3, lsr #8
239 strbcs r3, [r0], #1
240 movcs r3, r3, lsr #8
241 strbcs r3, [r0], #1
242 movcs r3, r3, lsr #8
243#endif
244
245 cmp r2, #4
246 blo partial_word_tail
247
248#if __ARMEB__
249 mov r3, r3, lsr r12
250 mov r3, r3, lsl r12
251#endif
252
253 /* Align destination to 32 bytes (cache line boundary) */
2541: tst r0, #0x1c
255 beq 2f
256 ldr r5, [r1], #4
257 sub r2, r2, #4
258#if __ARMEB__
259 mov r4, r5, lsr lr
260 orr r4, r4, r3
261 mov r3, r5, lsl r12
262#else
263 mov r4, r5, lsl lr
264 orr r4, r4, r3
265 mov r3, r5, lsr r12
266#endif
267 str r4, [r0], #4
268 cmp r2, #4
269 bhs 1b
270 blo partial_word_tail
271
272 /* copy 32 bytes at a time */
2732: subs r2, r2, #32
274 blo less_than_thirtytwo
275
276 /* Use immediate mode for the shifts, because there is an extra cycle
277 * for register shifts, which could account for up to 50% of
278 * performance hit.
279 */
280
281 cmp r12, #24
282 beq loop24
283 cmp r12, #8
284 beq loop8
285
286loop16:
287 ldr r12, [r1], #4
2881: mov r4, r12
289 ldmia r1!, { r5,r6,r7, r8,r9,r10,r11}
290 subs r2, r2, #32
291 ldrhs r12, [r1], #4
292#if __ARMEB__
293 orr r3, r3, r4, lsr #16
294 mov r4, r4, lsl #16
295 orr r4, r4, r5, lsr #16
296 mov r5, r5, lsl #16
297 orr r5, r5, r6, lsr #16
298 mov r6, r6, lsl #16
299 orr r6, r6, r7, lsr #16
300 mov r7, r7, lsl #16
301 orr r7, r7, r8, lsr #16
302 mov r8, r8, lsl #16
303 orr r8, r8, r9, lsr #16
304 mov r9, r9, lsl #16
305 orr r9, r9, r10, lsr #16
306 mov r10, r10, lsl #16
307 orr r10, r10, r11, lsr #16
308 stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10}
309 mov r3, r11, lsl #16
310#else
311 orr r3, r3, r4, lsl #16
312 mov r4, r4, lsr #16
313 orr r4, r4, r5, lsl #16
314 mov r5, r5, lsr #16
315 orr r5, r5, r6, lsl #16
316 mov r6, r6, lsr #16
317 orr r6, r6, r7, lsl #16
318 mov r7, r7, lsr #16
319 orr r7, r7, r8, lsl #16
320 mov r8, r8, lsr #16
321 orr r8, r8, r9, lsl #16
322 mov r9, r9, lsr #16
323 orr r9, r9, r10, lsl #16
324 mov r10, r10, lsr #16
325 orr r10, r10, r11, lsl #16
326 stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10}
327 mov r3, r11, lsr #16
328#endif
329 bhs 1b
330 b less_than_thirtytwo
331
332loop8:
333 ldr r12, [r1], #4
3341: mov r4, r12
335 ldmia r1!, { r5,r6,r7, r8,r9,r10,r11}
336 subs r2, r2, #32
337 ldrhs r12, [r1], #4
338#if __ARMEB__
339 orr r3, r3, r4, lsr #24
340 mov r4, r4, lsl #8
341 orr r4, r4, r5, lsr #24
342 mov r5, r5, lsl #8
343 orr r5, r5, r6, lsr #24
344 mov r6, r6, lsl #8
345 orr r6, r6, r7, lsr #24
346 mov r7, r7, lsl #8
347 orr r7, r7, r8, lsr #24
348 mov r8, r8, lsl #8
349 orr r8, r8, r9, lsr #24
350 mov r9, r9, lsl #8
351 orr r9, r9, r10, lsr #24
352 mov r10, r10, lsl #8
353 orr r10, r10, r11, lsr #24
354 stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10}
355 mov r3, r11, lsl #8
356#else
357 orr r3, r3, r4, lsl #24
358 mov r4, r4, lsr #8
359 orr r4, r4, r5, lsl #24
360 mov r5, r5, lsr #8
361 orr r5, r5, r6, lsl #24
362 mov r6, r6, lsr #8
363 orr r6, r6, r7, lsl #24
364 mov r7, r7, lsr #8
365 orr r7, r7, r8, lsl #24
366 mov r8, r8, lsr #8
367 orr r8, r8, r9, lsl #24
368 mov r9, r9, lsr #8
369 orr r9, r9, r10, lsl #24
370 mov r10, r10, lsr #8
371 orr r10, r10, r11, lsl #24
372 stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10}
373 mov r3, r11, lsr #8
374#endif
375 bhs 1b
376 b less_than_thirtytwo
377
378loop24:
379 ldr r12, [r1], #4
3801: mov r4, r12
381 ldmia r1!, { r5,r6,r7, r8,r9,r10,r11}
382 subs r2, r2, #32
383 ldrhs r12, [r1], #4
384#if __ARMEB__
385 orr r3, r3, r4, lsr #8
386 mov r4, r4, lsl #24
387 orr r4, r4, r5, lsr #8
388 mov r5, r5, lsl #24
389 orr r5, r5, r6, lsr #8
390 mov r6, r6, lsl #24
391 orr r6, r6, r7, lsr #8
392 mov r7, r7, lsl #24
393 orr r7, r7, r8, lsr #8
394 mov r8, r8, lsl #24
395 orr r8, r8, r9, lsr #8
396 mov r9, r9, lsl #24
397 orr r9, r9, r10, lsr #8
398 mov r10, r10, lsl #24
399 orr r10, r10, r11, lsr #8
400 stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10}
401 mov r3, r11, lsl #24
402#else
403 orr r3, r3, r4, lsl #8
404 mov r4, r4, lsr #24
405 orr r4, r4, r5, lsl #8
406 mov r5, r5, lsr #24
407 orr r5, r5, r6, lsl #8
408 mov r6, r6, lsr #24
409 orr r6, r6, r7, lsl #8
410 mov r7, r7, lsr #24
411 orr r7, r7, r8, lsl #8
412 mov r8, r8, lsr #24
413 orr r8, r8, r9, lsl #8
414 mov r9, r9, lsr #24
415 orr r9, r9, r10, lsl #8
416 mov r10, r10, lsr #24
417 orr r10, r10, r11, lsl #8
418 stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10}
419 mov r3, r11, lsr #24
420#endif
421 bhs 1b
422
423less_than_thirtytwo:
424 /* copy the last 0 to 31 bytes of the source */
425 rsb r12, lr, #32 /* we corrupted r12, recompute it */
426 add r2, r2, #32
427 cmp r2, #4
428 blo partial_word_tail
429
4301: ldr r5, [r1], #4
431 sub r2, r2, #4
432#if __ARMEB__
433 mov r4, r5, lsr lr
434 orr r4, r4, r3
435 mov r3, r5, lsl r12
436#else
437 mov r4, r5, lsl lr
438 orr r4, r4, r3
439 mov r3, r5, lsr r12
440#endif
441 str r4, [r0], #4
442 cmp r2, #4
443 bhs 1b
444
445partial_word_tail:
446 /* we have a partial word in the input buffer */
447 movs r5, lr, lsl #(31-3)
448#if __ARMEB__
449 movmi r3, r3, ror #24
450 strbmi r3, [r0], #1
451 movcs r3, r3, ror #24
452 strbcs r3, [r0], #1
453 movcs r3, r3, ror #24
454 strbcs r3, [r0], #1
455#else
456 strbmi r3, [r0], #1
457 movmi r3, r3, lsr #8
458 strbcs r3, [r0], #1
459 movcs r3, r3, lsr #8
460 strbcs r3, [r0], #1
461#endif
462
463 /* Refill spilled registers from the stack. Don't update sp. */
464 ldmfd sp, {r5-r11}
465
466copy_last_3_and_return:
467 movs r2, r2, lsl #31 /* copy remaining 0, 1, 2 or 3 bytes */
468 ldrbmi r2, [r1], #1
469 ldrbcs r3, [r1], #1
470 ldrbcs r12,[r1]
471 strbmi r2, [r0], #1
472 strbcs r3, [r0], #1
473 strbcs r12,[r0]
474
475 /* we're done! restore sp and spilled registers and return */
476 add sp, sp, #28
477 ldmfd sp!, {r0, r4, lr}
478 bx lr
479
lib/libc/musl/src/string/i386/memcpy.s deleted-32
...@@ -1,32 +0,0 @@
1.global memcpy
2.global __memcpy_fwd
3.hidden __memcpy_fwd
4.type memcpy,@function
5memcpy:
6__memcpy_fwd:
7 push %esi
8 push %edi
9 mov 12(%esp),%edi
10 mov 16(%esp),%esi
11 mov 20(%esp),%ecx
12 mov %edi,%eax
13 cmp $4,%ecx
14 jc 1f
15 test $3,%edi
16 jz 1f
172: movsb
18 dec %ecx
19 test $3,%edi
20 jnz 2b
211: mov %ecx,%edx
22 shr $2,%ecx
23 rep
24 movsl
25 and $3,%edx
26 jz 1f
272: movsb
28 dec %edx
29 jnz 2b
301: pop %edi
31 pop %esi
32 ret
lib/libc/musl/src/string/i386/memmove.s deleted-22
...@@ -1,22 +0,0 @@
1.global memmove
2.type memmove,@function
3memmove:
4 mov 4(%esp),%eax
5 sub 8(%esp),%eax
6 cmp 12(%esp),%eax
7.hidden __memcpy_fwd
8 jae __memcpy_fwd
9 push %esi
10 push %edi
11 mov 12(%esp),%edi
12 mov 16(%esp),%esi
13 mov 20(%esp),%ecx
14 lea -1(%edi,%ecx),%edi
15 lea -1(%esi,%ecx),%esi
16 std
17 rep movsb
18 cld
19 lea 1(%edi),%eax
20 pop %edi
21 pop %esi
22 ret
lib/libc/musl/src/string/memcpy.c deleted-124
...@@ -1,124 +0,0 @@
1#include <string.h>
2#include <stdint.h>
3#include <endian.h>
4
5void *memcpy(void *restrict dest, const void *restrict src, size_t n)
6{
7 unsigned char *d = dest;
8 const unsigned char *s = src;
9
10#ifdef __GNUC__
11
12#if __BYTE_ORDER == __LITTLE_ENDIAN
13#define LS >>
14#define RS <<
15#else
16#define LS <<
17#define RS >>
18#endif
19
20 typedef uint32_t __attribute__((__may_alias__)) u32;
21 uint32_t w, x;
22
23 for (; (uintptr_t)s % 4 && n; n--) *d++ = *s++;
24
25 if ((uintptr_t)d % 4 == 0) {
26 for (; n>=16; s+=16, d+=16, n-=16) {
27 *(u32 *)(d+0) = *(u32 *)(s+0);
28 *(u32 *)(d+4) = *(u32 *)(s+4);
29 *(u32 *)(d+8) = *(u32 *)(s+8);
30 *(u32 *)(d+12) = *(u32 *)(s+12);
31 }
32 if (n&8) {
33 *(u32 *)(d+0) = *(u32 *)(s+0);
34 *(u32 *)(d+4) = *(u32 *)(s+4);
35 d += 8; s += 8;
36 }
37 if (n&4) {
38 *(u32 *)(d+0) = *(u32 *)(s+0);
39 d += 4; s += 4;
40 }
41 if (n&2) {
42 *d++ = *s++; *d++ = *s++;
43 }
44 if (n&1) {
45 *d = *s;
46 }
47 return dest;
48 }
49
50 if (n >= 32) switch ((uintptr_t)d % 4) {
51 case 1:
52 w = *(u32 *)s;
53 *d++ = *s++;
54 *d++ = *s++;
55 *d++ = *s++;
56 n -= 3;
57 for (; n>=17; s+=16, d+=16, n-=16) {
58 x = *(u32 *)(s+1);
59 *(u32 *)(d+0) = (w LS 24) | (x RS 8);
60 w = *(u32 *)(s+5);
61 *(u32 *)(d+4) = (x LS 24) | (w RS 8);
62 x = *(u32 *)(s+9);
63 *(u32 *)(d+8) = (w LS 24) | (x RS 8);
64 w = *(u32 *)(s+13);
65 *(u32 *)(d+12) = (x LS 24) | (w RS 8);
66 }
67 break;
68 case 2:
69 w = *(u32 *)s;
70 *d++ = *s++;
71 *d++ = *s++;
72 n -= 2;
73 for (; n>=18; s+=16, d+=16, n-=16) {
74 x = *(u32 *)(s+2);
75 *(u32 *)(d+0) = (w LS 16) | (x RS 16);
76 w = *(u32 *)(s+6);
77 *(u32 *)(d+4) = (x LS 16) | (w RS 16);
78 x = *(u32 *)(s+10);
79 *(u32 *)(d+8) = (w LS 16) | (x RS 16);
80 w = *(u32 *)(s+14);
81 *(u32 *)(d+12) = (x LS 16) | (w RS 16);
82 }
83 break;
84 case 3:
85 w = *(u32 *)s;
86 *d++ = *s++;
87 n -= 1;
88 for (; n>=19; s+=16, d+=16, n-=16) {
89 x = *(u32 *)(s+3);
90 *(u32 *)(d+0) = (w LS 8) | (x RS 24);
91 w = *(u32 *)(s+7);
92 *(u32 *)(d+4) = (x LS 8) | (w RS 24);
93 x = *(u32 *)(s+11);
94 *(u32 *)(d+8) = (w LS 8) | (x RS 24);
95 w = *(u32 *)(s+15);
96 *(u32 *)(d+12) = (x LS 8) | (w RS 24);
97 }
98 break;
99 }
100 if (n&16) {
101 *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
102 *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
103 *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
104 *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
105 }
106 if (n&8) {
107 *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
108 *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
109 }
110 if (n&4) {
111 *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
112 }
113 if (n&2) {
114 *d++ = *s++; *d++ = *s++;
115 }
116 if (n&1) {
117 *d = *s;
118 }
119 return dest;
120#endif
121
122 for (; n; n--) *d++ = *s++;
123 return dest;
124}
lib/libc/musl/src/string/memmove.c deleted-42
...@@ -1,42 +0,0 @@
1#include <string.h>
2#include <stdint.h>
3
4#ifdef __GNUC__
5typedef __attribute__((__may_alias__)) size_t WT;
6#define WS (sizeof(WT))
7#endif
8
9void *memmove(void *dest, const void *src, size_t n)
10{
11 char *d = dest;
12 const char *s = src;
13
14 if (d==s) return d;
15 if ((uintptr_t)s-(uintptr_t)d-n <= -2*n) return memcpy(d, s, n);
16
17 if (d<s) {
18#ifdef __GNUC__
19 if ((uintptr_t)s % WS == (uintptr_t)d % WS) {
20 while ((uintptr_t)d % WS) {
21 if (!n--) return dest;
22 *d++ = *s++;
23 }
24 for (; n>=WS; n-=WS, d+=WS, s+=WS) *(WT *)d = *(WT *)s;
25 }
26#endif
27 for (; n; n--) *d++ = *s++;
28 } else {
29#ifdef __GNUC__
30 if ((uintptr_t)s % WS == (uintptr_t)d % WS) {
31 while ((uintptr_t)(d+n) % WS) {
32 if (!n--) return dest;
33 d[n] = s[n];
34 }
35 while (n>=WS) n-=WS, *(WT *)(d+n) = *(WT *)(s+n);
36 }
37#endif
38 while (n) n--, d[n] = s[n];
39 }
40
41 return dest;
42}
lib/libc/musl/src/string/x86_64/memcpy.s deleted-25
...@@ -1,25 +0,0 @@
1.global memcpy
2.global __memcpy_fwd
3.hidden __memcpy_fwd
4.type memcpy,@function
5memcpy:
6__memcpy_fwd:
7 mov %rdi,%rax
8 cmp $8,%rdx
9 jc 1f
10 test $7,%edi
11 jz 1f
122: movsb
13 dec %rdx
14 test $7,%edi
15 jnz 2b
161: mov %rdx,%rcx
17 shr $3,%rcx
18 rep
19 movsq
20 and $7,%edx
21 jz 1f
222: movsb
23 dec %edx
24 jnz 2b
251: ret
lib/libc/musl/src/string/x86_64/memmove.s deleted-16
...@@ -1,16 +0,0 @@
1.global memmove
2.type memmove,@function
3memmove:
4 mov %rdi,%rax
5 sub %rsi,%rax
6 cmp %rdx,%rax
7.hidden __memcpy_fwd
8 jae __memcpy_fwd
9 mov %rdx,%rcx
10 lea -1(%rdi,%rdx),%rdi
11 lea -1(%rsi,%rdx),%rsi
12 std
13 rep movsb
14 cld
15 lea 1(%rdi),%rax
16 ret
lib/libc/wasi/libc-top-half/musl/src/string/aarch64/memcpy.S deleted-186
...@@ -1,186 +0,0 @@
1/*
2 * memcpy - copy memory area
3 *
4 * Copyright (c) 2012-2020, Arm Limited.
5 * SPDX-License-Identifier: MIT
6 */
7
8/* Assumptions:
9 *
10 * ARMv8-a, AArch64, unaligned accesses.
11 *
12 */
13
14#define dstin x0
15#define src x1
16#define count x2
17#define dst x3
18#define srcend x4
19#define dstend x5
20#define A_l x6
21#define A_lw w6
22#define A_h x7
23#define B_l x8
24#define B_lw w8
25#define B_h x9
26#define C_l x10
27#define C_lw w10
28#define C_h x11
29#define D_l x12
30#define D_h x13
31#define E_l x14
32#define E_h x15
33#define F_l x16
34#define F_h x17
35#define G_l count
36#define G_h dst
37#define H_l src
38#define H_h srcend
39#define tmp1 x14
40
41/* This implementation of memcpy uses unaligned accesses and branchless
42 sequences to keep the code small, simple and improve performance.
43
44 Copies are split into 3 main cases: small copies of up to 32 bytes, medium
45 copies of up to 128 bytes, and large copies. The overhead of the overlap
46 check is negligible since it is only required for large copies.
47
48 Large copies use a software pipelined loop processing 64 bytes per iteration.
49 The destination pointer is 16-byte aligned to minimize unaligned accesses.
50 The loop tail is handled by always copying 64 bytes from the end.
51*/
52
53.global memcpy
54.type memcpy,%function
55memcpy:
56 add srcend, src, count
57 add dstend, dstin, count
58 cmp count, 128
59 b.hi .Lcopy_long
60 cmp count, 32
61 b.hi .Lcopy32_128
62
63 /* Small copies: 0..32 bytes. */
64 cmp count, 16
65 b.lo .Lcopy16
66 ldp A_l, A_h, [src]
67 ldp D_l, D_h, [srcend, -16]
68 stp A_l, A_h, [dstin]
69 stp D_l, D_h, [dstend, -16]
70 ret
71
72 /* Copy 8-15 bytes. */
73.Lcopy16:
74 tbz count, 3, .Lcopy8
75 ldr A_l, [src]
76 ldr A_h, [srcend, -8]
77 str A_l, [dstin]
78 str A_h, [dstend, -8]
79 ret
80
81 .p2align 3
82 /* Copy 4-7 bytes. */
83.Lcopy8:
84 tbz count, 2, .Lcopy4
85 ldr A_lw, [src]
86 ldr B_lw, [srcend, -4]
87 str A_lw, [dstin]
88 str B_lw, [dstend, -4]
89 ret
90
91 /* Copy 0..3 bytes using a branchless sequence. */
92.Lcopy4:
93 cbz count, .Lcopy0
94 lsr tmp1, count, 1
95 ldrb A_lw, [src]
96 ldrb C_lw, [srcend, -1]
97 ldrb B_lw, [src, tmp1]
98 strb A_lw, [dstin]
99 strb B_lw, [dstin, tmp1]
100 strb C_lw, [dstend, -1]
101.Lcopy0:
102 ret
103
104 .p2align 4
105 /* Medium copies: 33..128 bytes. */
106.Lcopy32_128:
107 ldp A_l, A_h, [src]
108 ldp B_l, B_h, [src, 16]
109 ldp C_l, C_h, [srcend, -32]
110 ldp D_l, D_h, [srcend, -16]
111 cmp count, 64
112 b.hi .Lcopy128
113 stp A_l, A_h, [dstin]
114 stp B_l, B_h, [dstin, 16]
115 stp C_l, C_h, [dstend, -32]
116 stp D_l, D_h, [dstend, -16]
117 ret
118
119 .p2align 4
120 /* Copy 65..128 bytes. */
121.Lcopy128:
122 ldp E_l, E_h, [src, 32]
123 ldp F_l, F_h, [src, 48]
124 cmp count, 96
125 b.ls .Lcopy96
126 ldp G_l, G_h, [srcend, -64]
127 ldp H_l, H_h, [srcend, -48]
128 stp G_l, G_h, [dstend, -64]
129 stp H_l, H_h, [dstend, -48]
130.Lcopy96:
131 stp A_l, A_h, [dstin]
132 stp B_l, B_h, [dstin, 16]
133 stp E_l, E_h, [dstin, 32]
134 stp F_l, F_h, [dstin, 48]
135 stp C_l, C_h, [dstend, -32]
136 stp D_l, D_h, [dstend, -16]
137 ret
138
139 .p2align 4
140 /* Copy more than 128 bytes. */
141.Lcopy_long:
142
143 /* Copy 16 bytes and then align dst to 16-byte alignment. */
144
145 ldp D_l, D_h, [src]
146 and tmp1, dstin, 15
147 bic dst, dstin, 15
148 sub src, src, tmp1
149 add count, count, tmp1 /* Count is now 16 too large. */
150 ldp A_l, A_h, [src, 16]
151 stp D_l, D_h, [dstin]
152 ldp B_l, B_h, [src, 32]
153 ldp C_l, C_h, [src, 48]
154 ldp D_l, D_h, [src, 64]!
155 subs count, count, 128 + 16 /* Test and readjust count. */
156 b.ls .Lcopy64_from_end
157
158.Lloop64:
159 stp A_l, A_h, [dst, 16]
160 ldp A_l, A_h, [src, 16]
161 stp B_l, B_h, [dst, 32]
162 ldp B_l, B_h, [src, 32]
163 stp C_l, C_h, [dst, 48]
164 ldp C_l, C_h, [src, 48]
165 stp D_l, D_h, [dst, 64]!
166 ldp D_l, D_h, [src, 64]!
167 subs count, count, 64
168 b.hi .Lloop64
169
170 /* Write the last iteration and copy 64 bytes from the end. */
171.Lcopy64_from_end:
172 ldp E_l, E_h, [srcend, -64]
173 stp A_l, A_h, [dst, 16]
174 ldp A_l, A_h, [srcend, -48]
175 stp B_l, B_h, [dst, 32]
176 ldp B_l, B_h, [srcend, -32]
177 stp C_l, C_h, [dst, 48]
178 ldp C_l, C_h, [srcend, -16]
179 stp D_l, D_h, [dst, 64]
180 stp E_l, E_h, [dstend, -64]
181 stp A_l, A_h, [dstend, -48]
182 stp B_l, B_h, [dstend, -32]
183 stp C_l, C_h, [dstend, -16]
184 ret
185
186.size memcpy,.-memcpy
lib/libc/wasi/libc-top-half/musl/src/string/arm/memcpy.S deleted-479
...@@ -1,479 +0,0 @@
1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in
12 * the documentation and/or other materials provided with the
13 * distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29
30/*
31 * Optimized memcpy() for ARM.
32 *
33 * note that memcpy() always returns the destination pointer,
34 * so we have to preserve R0.
35 */
36
37/*
38 * This file has been modified from the original for use in musl libc.
39 * The main changes are: addition of .type memcpy,%function to make the
40 * code safely callable from thumb mode, adjusting the return
41 * instructions to be compatible with pre-thumb ARM cpus, removal of
42 * prefetch code that is not compatible with older cpus and support for
43 * building as thumb 2 and big-endian.
44 */
45
46.syntax unified
47
48.global memcpy
49.type memcpy,%function
50memcpy:
51 /* The stack must always be 64-bits aligned to be compliant with the
52 * ARM ABI. Since we have to save R0, we might as well save R4
53 * which we can use for better pipelining of the reads below
54 */
55 .fnstart
56 .save {r0, r4, lr}
57 stmfd sp!, {r0, r4, lr}
58 /* Making room for r5-r11 which will be spilled later */
59 .pad #28
60 sub sp, sp, #28
61
62 /* it simplifies things to take care of len<4 early */
63 cmp r2, #4
64 blo copy_last_3_and_return
65
66 /* compute the offset to align the source
67 * offset = (4-(src&3))&3 = -src & 3
68 */
69 rsb r3, r1, #0
70 ands r3, r3, #3
71 beq src_aligned
72
73 /* align source to 32 bits. We need to insert 2 instructions between
74 * a ldr[b|h] and str[b|h] because byte and half-word instructions
75 * stall 2 cycles.
76 */
77 movs r12, r3, lsl #31
78 sub r2, r2, r3 /* we know that r3 <= r2 because r2 >= 4 */
79 ldrbmi r3, [r1], #1
80 ldrbcs r4, [r1], #1
81 ldrbcs r12,[r1], #1
82 strbmi r3, [r0], #1
83 strbcs r4, [r0], #1
84 strbcs r12,[r0], #1
85
86src_aligned:
87
88 /* see if src and dst are aligned together (congruent) */
89 eor r12, r0, r1
90 tst r12, #3
91 bne non_congruent
92
93 /* Use post-incriment mode for stm to spill r5-r11 to reserved stack
94 * frame. Don't update sp.
95 */
96 stmea sp, {r5-r11}
97
98 /* align the destination to a cache-line */
99 rsb r3, r0, #0
100 ands r3, r3, #0x1C
101 beq congruent_aligned32
102 cmp r3, r2
103 andhi r3, r2, #0x1C
104
105 /* conditionnaly copies 0 to 7 words (length in r3) */
106 movs r12, r3, lsl #28
107 ldmcs r1!, {r4, r5, r6, r7} /* 16 bytes */
108 ldmmi r1!, {r8, r9} /* 8 bytes */
109 stmcs r0!, {r4, r5, r6, r7}
110 stmmi r0!, {r8, r9}
111 tst r3, #0x4
112 ldrne r10,[r1], #4 /* 4 bytes */
113 strne r10,[r0], #4
114 sub r2, r2, r3
115
116congruent_aligned32:
117 /*
118 * here source is aligned to 32 bytes.
119 */
120
121cached_aligned32:
122 subs r2, r2, #32
123 blo less_than_32_left
124
125 /*
126 * We preload a cache-line up to 64 bytes ahead. On the 926, this will
127 * stall only until the requested world is fetched, but the linefill
128 * continues in the the background.
129 * While the linefill is going, we write our previous cache-line
130 * into the write-buffer (which should have some free space).
131 * When the linefill is done, the writebuffer will
132 * start dumping its content into memory
133 *
134 * While all this is going, we then load a full cache line into
135 * 8 registers, this cache line should be in the cache by now
136 * (or partly in the cache).
137 *
138 * This code should work well regardless of the source/dest alignment.
139 *
140 */
141
142 /* Align the preload register to a cache-line because the cpu does
143 * "critical word first" (the first word requested is loaded first).
144 */
145 @ bic r12, r1, #0x1F
146 @ add r12, r12, #64
147
1481: ldmia r1!, { r4-r11 }
149 subs r2, r2, #32
150
151 /*
152 * NOTE: if r12 is more than 64 ahead of r1, the following ldrhi
153 * for ARM9 preload will not be safely guarded by the preceding subs.
154 * When it is safely guarded the only possibility to have SIGSEGV here
155 * is because the caller overstates the length.
156 */
157 @ ldrhi r3, [r12], #32 /* cheap ARM9 preload */
158 stmia r0!, { r4-r11 }
159 bhs 1b
160
161 add r2, r2, #32
162
163less_than_32_left:
164 /*
165 * less than 32 bytes left at this point (length in r2)
166 */
167
168 /* skip all this if there is nothing to do, which should
169 * be a common case (if not executed the code below takes
170 * about 16 cycles)
171 */
172 tst r2, #0x1F
173 beq 1f
174
175 /* conditionnaly copies 0 to 31 bytes */
176 movs r12, r2, lsl #28
177 ldmcs r1!, {r4, r5, r6, r7} /* 16 bytes */
178 ldmmi r1!, {r8, r9} /* 8 bytes */
179 stmcs r0!, {r4, r5, r6, r7}
180 stmmi r0!, {r8, r9}
181 movs r12, r2, lsl #30
182 ldrcs r3, [r1], #4 /* 4 bytes */
183 ldrhmi r4, [r1], #2 /* 2 bytes */
184 strcs r3, [r0], #4
185 strhmi r4, [r0], #2
186 tst r2, #0x1
187 ldrbne r3, [r1] /* last byte */
188 strbne r3, [r0]
189
190 /* we're done! restore everything and return */
1911: ldmfd sp!, {r5-r11}
192 ldmfd sp!, {r0, r4, lr}
193 bx lr
194
195 /********************************************************************/
196
197non_congruent:
198 /*
199 * here source is aligned to 4 bytes
200 * but destination is not.
201 *
202 * in the code below r2 is the number of bytes read
203 * (the number of bytes written is always smaller, because we have
204 * partial words in the shift queue)
205 */
206 cmp r2, #4
207 blo copy_last_3_and_return
208
209 /* Use post-incriment mode for stm to spill r5-r11 to reserved stack
210 * frame. Don't update sp.
211 */
212 stmea sp, {r5-r11}
213
214 /* compute shifts needed to align src to dest */
215 rsb r5, r0, #0
216 and r5, r5, #3 /* r5 = # bytes in partial words */
217 mov r12, r5, lsl #3 /* r12 = right */
218 rsb lr, r12, #32 /* lr = left */
219
220 /* read the first word */
221 ldr r3, [r1], #4
222 sub r2, r2, #4
223
224 /* write a partial word (0 to 3 bytes), such that destination
225 * becomes aligned to 32 bits (r5 = nb of words to copy for alignment)
226 */
227 movs r5, r5, lsl #31
228
229#if __ARMEB__
230 movmi r3, r3, ror #24
231 strbmi r3, [r0], #1
232 movcs r3, r3, ror #24
233 strbcs r3, [r0], #1
234 movcs r3, r3, ror #24
235 strbcs r3, [r0], #1
236#else
237 strbmi r3, [r0], #1
238 movmi r3, r3, lsr #8
239 strbcs r3, [r0], #1
240 movcs r3, r3, lsr #8
241 strbcs r3, [r0], #1
242 movcs r3, r3, lsr #8
243#endif
244
245 cmp r2, #4
246 blo partial_word_tail
247
248#if __ARMEB__
249 mov r3, r3, lsr r12
250 mov r3, r3, lsl r12
251#endif
252
253 /* Align destination to 32 bytes (cache line boundary) */
2541: tst r0, #0x1c
255 beq 2f
256 ldr r5, [r1], #4
257 sub r2, r2, #4
258#if __ARMEB__
259 mov r4, r5, lsr lr
260 orr r4, r4, r3
261 mov r3, r5, lsl r12
262#else
263 mov r4, r5, lsl lr
264 orr r4, r4, r3
265 mov r3, r5, lsr r12
266#endif
267 str r4, [r0], #4
268 cmp r2, #4
269 bhs 1b
270 blo partial_word_tail
271
272 /* copy 32 bytes at a time */
2732: subs r2, r2, #32
274 blo less_than_thirtytwo
275
276 /* Use immediate mode for the shifts, because there is an extra cycle
277 * for register shifts, which could account for up to 50% of
278 * performance hit.
279 */
280
281 cmp r12, #24
282 beq loop24
283 cmp r12, #8
284 beq loop8
285
286loop16:
287 ldr r12, [r1], #4
2881: mov r4, r12
289 ldmia r1!, { r5,r6,r7, r8,r9,r10,r11}
290 subs r2, r2, #32
291 ldrhs r12, [r1], #4
292#if __ARMEB__
293 orr r3, r3, r4, lsr #16
294 mov r4, r4, lsl #16
295 orr r4, r4, r5, lsr #16
296 mov r5, r5, lsl #16
297 orr r5, r5, r6, lsr #16
298 mov r6, r6, lsl #16
299 orr r6, r6, r7, lsr #16
300 mov r7, r7, lsl #16
301 orr r7, r7, r8, lsr #16
302 mov r8, r8, lsl #16
303 orr r8, r8, r9, lsr #16
304 mov r9, r9, lsl #16
305 orr r9, r9, r10, lsr #16
306 mov r10, r10, lsl #16
307 orr r10, r10, r11, lsr #16
308 stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10}
309 mov r3, r11, lsl #16
310#else
311 orr r3, r3, r4, lsl #16
312 mov r4, r4, lsr #16
313 orr r4, r4, r5, lsl #16
314 mov r5, r5, lsr #16
315 orr r5, r5, r6, lsl #16
316 mov r6, r6, lsr #16
317 orr r6, r6, r7, lsl #16
318 mov r7, r7, lsr #16
319 orr r7, r7, r8, lsl #16
320 mov r8, r8, lsr #16
321 orr r8, r8, r9, lsl #16
322 mov r9, r9, lsr #16
323 orr r9, r9, r10, lsl #16
324 mov r10, r10, lsr #16
325 orr r10, r10, r11, lsl #16
326 stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10}
327 mov r3, r11, lsr #16
328#endif
329 bhs 1b
330 b less_than_thirtytwo
331
332loop8:
333 ldr r12, [r1], #4
3341: mov r4, r12
335 ldmia r1!, { r5,r6,r7, r8,r9,r10,r11}
336 subs r2, r2, #32
337 ldrhs r12, [r1], #4
338#if __ARMEB__
339 orr r3, r3, r4, lsr #24
340 mov r4, r4, lsl #8
341 orr r4, r4, r5, lsr #24
342 mov r5, r5, lsl #8
343 orr r5, r5, r6, lsr #24
344 mov r6, r6, lsl #8
345 orr r6, r6, r7, lsr #24
346 mov r7, r7, lsl #8
347 orr r7, r7, r8, lsr #24
348 mov r8, r8, lsl #8
349 orr r8, r8, r9, lsr #24
350 mov r9, r9, lsl #8
351 orr r9, r9, r10, lsr #24
352 mov r10, r10, lsl #8
353 orr r10, r10, r11, lsr #24
354 stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10}
355 mov r3, r11, lsl #8
356#else
357 orr r3, r3, r4, lsl #24
358 mov r4, r4, lsr #8
359 orr r4, r4, r5, lsl #24
360 mov r5, r5, lsr #8
361 orr r5, r5, r6, lsl #24
362 mov r6, r6, lsr #8
363 orr r6, r6, r7, lsl #24
364 mov r7, r7, lsr #8
365 orr r7, r7, r8, lsl #24
366 mov r8, r8, lsr #8
367 orr r8, r8, r9, lsl #24
368 mov r9, r9, lsr #8
369 orr r9, r9, r10, lsl #24
370 mov r10, r10, lsr #8
371 orr r10, r10, r11, lsl #24
372 stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10}
373 mov r3, r11, lsr #8
374#endif
375 bhs 1b
376 b less_than_thirtytwo
377
378loop24:
379 ldr r12, [r1], #4
3801: mov r4, r12
381 ldmia r1!, { r5,r6,r7, r8,r9,r10,r11}
382 subs r2, r2, #32
383 ldrhs r12, [r1], #4
384#if __ARMEB__
385 orr r3, r3, r4, lsr #8
386 mov r4, r4, lsl #24
387 orr r4, r4, r5, lsr #8
388 mov r5, r5, lsl #24
389 orr r5, r5, r6, lsr #8
390 mov r6, r6, lsl #24
391 orr r6, r6, r7, lsr #8
392 mov r7, r7, lsl #24
393 orr r7, r7, r8, lsr #8
394 mov r8, r8, lsl #24
395 orr r8, r8, r9, lsr #8
396 mov r9, r9, lsl #24
397 orr r9, r9, r10, lsr #8
398 mov r10, r10, lsl #24
399 orr r10, r10, r11, lsr #8
400 stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10}
401 mov r3, r11, lsl #24
402#else
403 orr r3, r3, r4, lsl #8
404 mov r4, r4, lsr #24
405 orr r4, r4, r5, lsl #8
406 mov r5, r5, lsr #24
407 orr r5, r5, r6, lsl #8
408 mov r6, r6, lsr #24
409 orr r6, r6, r7, lsl #8
410 mov r7, r7, lsr #24
411 orr r7, r7, r8, lsl #8
412 mov r8, r8, lsr #24
413 orr r8, r8, r9, lsl #8
414 mov r9, r9, lsr #24
415 orr r9, r9, r10, lsl #8
416 mov r10, r10, lsr #24
417 orr r10, r10, r11, lsl #8
418 stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10}
419 mov r3, r11, lsr #24
420#endif
421 bhs 1b
422
423less_than_thirtytwo:
424 /* copy the last 0 to 31 bytes of the source */
425 rsb r12, lr, #32 /* we corrupted r12, recompute it */
426 add r2, r2, #32
427 cmp r2, #4
428 blo partial_word_tail
429
4301: ldr r5, [r1], #4
431 sub r2, r2, #4
432#if __ARMEB__
433 mov r4, r5, lsr lr
434 orr r4, r4, r3
435 mov r3, r5, lsl r12
436#else
437 mov r4, r5, lsl lr
438 orr r4, r4, r3
439 mov r3, r5, lsr r12
440#endif
441 str r4, [r0], #4
442 cmp r2, #4
443 bhs 1b
444
445partial_word_tail:
446 /* we have a partial word in the input buffer */
447 movs r5, lr, lsl #(31-3)
448#if __ARMEB__
449 movmi r3, r3, ror #24
450 strbmi r3, [r0], #1
451 movcs r3, r3, ror #24
452 strbcs r3, [r0], #1
453 movcs r3, r3, ror #24
454 strbcs r3, [r0], #1
455#else
456 strbmi r3, [r0], #1
457 movmi r3, r3, lsr #8
458 strbcs r3, [r0], #1
459 movcs r3, r3, lsr #8
460 strbcs r3, [r0], #1
461#endif
462
463 /* Refill spilled registers from the stack. Don't update sp. */
464 ldmfd sp, {r5-r11}
465
466copy_last_3_and_return:
467 movs r2, r2, lsl #31 /* copy remaining 0, 1, 2 or 3 bytes */
468 ldrbmi r2, [r1], #1
469 ldrbcs r3, [r1], #1
470 ldrbcs r12,[r1]
471 strbmi r2, [r0], #1
472 strbcs r3, [r0], #1
473 strbcs r12,[r0]
474
475 /* we're done! restore sp and spilled registers and return */
476 add sp, sp, #28
477 ldmfd sp!, {r0, r4, lr}
478 bx lr
479
lib/libc/wasi/libc-top-half/musl/src/string/memcpy.c deleted-128
...@@ -1,128 +0,0 @@
1#include <string.h>
2#include <stdint.h>
3#include <endian.h>
4
5void *memcpy(void *restrict dest, const void *restrict src, size_t n)
6{
7#if defined(__wasm_bulk_memory__)
8 if (n > BULK_MEMORY_THRESHOLD)
9 return __builtin_memcpy(dest, src, n);
10#endif
11 unsigned char *d = dest;
12 const unsigned char *s = src;
13
14#ifdef __GNUC__
15
16#if __BYTE_ORDER == __LITTLE_ENDIAN
17#define LS >>
18#define RS <<
19#else
20#define LS <<
21#define RS >>
22#endif
23
24 typedef uint32_t __attribute__((__may_alias__)) u32;
25 uint32_t w, x;
26
27 for (; (uintptr_t)s % 4 && n; n--) *d++ = *s++;
28
29 if ((uintptr_t)d % 4 == 0) {
30 for (; n>=16; s+=16, d+=16, n-=16) {
31 *(u32 *)(d+0) = *(u32 *)(s+0);
32 *(u32 *)(d+4) = *(u32 *)(s+4);
33 *(u32 *)(d+8) = *(u32 *)(s+8);
34 *(u32 *)(d+12) = *(u32 *)(s+12);
35 }
36 if (n&8) {
37 *(u32 *)(d+0) = *(u32 *)(s+0);
38 *(u32 *)(d+4) = *(u32 *)(s+4);
39 d += 8; s += 8;
40 }
41 if (n&4) {
42 *(u32 *)(d+0) = *(u32 *)(s+0);
43 d += 4; s += 4;
44 }
45 if (n&2) {
46 *d++ = *s++; *d++ = *s++;
47 }
48 if (n&1) {
49 *d = *s;
50 }
51 return dest;
52 }
53
54 if (n >= 32) switch ((uintptr_t)d % 4) {
55 case 1:
56 w = *(u32 *)s;
57 *d++ = *s++;
58 *d++ = *s++;
59 *d++ = *s++;
60 n -= 3;
61 for (; n>=17; s+=16, d+=16, n-=16) {
62 x = *(u32 *)(s+1);
63 *(u32 *)(d+0) = (w LS 24) | (x RS 8);
64 w = *(u32 *)(s+5);
65 *(u32 *)(d+4) = (x LS 24) | (w RS 8);
66 x = *(u32 *)(s+9);
67 *(u32 *)(d+8) = (w LS 24) | (x RS 8);
68 w = *(u32 *)(s+13);
69 *(u32 *)(d+12) = (x LS 24) | (w RS 8);
70 }
71 break;
72 case 2:
73 w = *(u32 *)s;
74 *d++ = *s++;
75 *d++ = *s++;
76 n -= 2;
77 for (; n>=18; s+=16, d+=16, n-=16) {
78 x = *(u32 *)(s+2);
79 *(u32 *)(d+0) = (w LS 16) | (x RS 16);
80 w = *(u32 *)(s+6);
81 *(u32 *)(d+4) = (x LS 16) | (w RS 16);
82 x = *(u32 *)(s+10);
83 *(u32 *)(d+8) = (w LS 16) | (x RS 16);
84 w = *(u32 *)(s+14);
85 *(u32 *)(d+12) = (x LS 16) | (w RS 16);
86 }
87 break;
88 case 3:
89 w = *(u32 *)s;
90 *d++ = *s++;
91 n -= 1;
92 for (; n>=19; s+=16, d+=16, n-=16) {
93 x = *(u32 *)(s+3);
94 *(u32 *)(d+0) = (w LS 8) | (x RS 24);
95 w = *(u32 *)(s+7);
96 *(u32 *)(d+4) = (x LS 8) | (w RS 24);
97 x = *(u32 *)(s+11);
98 *(u32 *)(d+8) = (w LS 8) | (x RS 24);
99 w = *(u32 *)(s+15);
100 *(u32 *)(d+12) = (x LS 8) | (w RS 24);
101 }
102 break;
103 }
104 if (n&16) {
105 *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
106 *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
107 *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
108 *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
109 }
110 if (n&8) {
111 *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
112 *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
113 }
114 if (n&4) {
115 *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
116 }
117 if (n&2) {
118 *d++ = *s++; *d++ = *s++;
119 }
120 if (n&1) {
121 *d = *s;
122 }
123 return dest;
124#endif
125
126 for (; n; n--) *d++ = *s++;
127 return dest;
128}
lib/libc/wasi/libc-top-half/musl/src/string/memmove.c deleted-46
...@@ -1,46 +0,0 @@
1#include <string.h>
2#include <stdint.h>
3
4#ifdef __GNUC__
5typedef __attribute__((__may_alias__)) size_t WT;
6#define WS (sizeof(WT))
7#endif
8
9void *memmove(void *dest, const void *src, size_t n)
10{
11#if defined(__wasm_bulk_memory__)
12 if (n > BULK_MEMORY_THRESHOLD)
13 return __builtin_memmove(dest, src, n);
14#endif
15 char *d = dest;
16 const char *s = src;
17
18 if (d==s) return d;
19 if ((uintptr_t)s-(uintptr_t)d-n <= -2*n) return memcpy(d, s, n);
20
21 if (d<s) {
22#ifdef __GNUC__
23 if ((uintptr_t)s % WS == (uintptr_t)d % WS) {
24 while ((uintptr_t)d % WS) {
25 if (!n--) return dest;
26 *d++ = *s++;
27 }
28 for (; n>=WS; n-=WS, d+=WS, s+=WS) *(WT *)d = *(WT *)s;
29 }
30#endif
31 for (; n; n--) *d++ = *s++;
32 } else {
33#ifdef __GNUC__
34 if ((uintptr_t)s % WS == (uintptr_t)d % WS) {
35 while ((uintptr_t)(d+n) % WS) {
36 if (!n--) return dest;
37 d[n] = s[n];
38 }
39 while (n>=WS) n-=WS, *(WT *)(d+n) = *(WT *)(s+n);
40 }
41#endif
42 while (n) n--, d[n] = s[n];
43 }
44
45 return dest;
46}
src/musl.zig-9
...@@ -1899,25 +1899,18 @@ const src_files = [_][]const u8{...@@ -1899,25 +1899,18 @@ const src_files = [_][]const u8{
1899 "musl/src/stdlib/strtol.c",1899 "musl/src/stdlib/strtol.c",
1900 "musl/src/stdlib/wcstod.c",1900 "musl/src/stdlib/wcstod.c",
1901 "musl/src/stdlib/wcstol.c",1901 "musl/src/stdlib/wcstol.c",
1902 "musl/src/string/aarch64/memcpy.S",
1903 "musl/src/string/aarch64/memset.S",1902 "musl/src/string/aarch64/memset.S",
1904 "musl/src/string/arm/__aeabi_memcpy.s",
1905 "musl/src/string/arm/__aeabi_memset.s",1903 "musl/src/string/arm/__aeabi_memset.s",
1906 "musl/src/string/arm/memcpy.S",
1907 "musl/src/string/bcmp.c",1904 "musl/src/string/bcmp.c",
1908 "musl/src/string/bcopy.c",1905 "musl/src/string/bcopy.c",
1909 "musl/src/string/bzero.c",1906 "musl/src/string/bzero.c",
1910 "musl/src/string/explicit_bzero.c",1907 "musl/src/string/explicit_bzero.c",
1911 "musl/src/string/i386/memcpy.s",
1912 "musl/src/string/i386/memmove.s",
1913 "musl/src/string/i386/memset.s",1908 "musl/src/string/i386/memset.s",
1914 "musl/src/string/index.c",1909 "musl/src/string/index.c",
1915 "musl/src/string/memccpy.c",1910 "musl/src/string/memccpy.c",
1916 "musl/src/string/memchr.c",1911 "musl/src/string/memchr.c",
1917 "musl/src/string/memcmp.c",1912 "musl/src/string/memcmp.c",
1918 "musl/src/string/memcpy.c",
1919 "musl/src/string/memmem.c",1913 "musl/src/string/memmem.c",
1920 "musl/src/string/memmove.c",
1921 "musl/src/string/mempcpy.c",1914 "musl/src/string/mempcpy.c",
1922 "musl/src/string/memrchr.c",1915 "musl/src/string/memrchr.c",
1923 "musl/src/string/memset.c",1916 "musl/src/string/memset.c",
...@@ -1981,8 +1974,6 @@ const src_files = [_][]const u8{...@@ -1981,8 +1974,6 @@ const src_files = [_][]const u8{
1981 "musl/src/string/wmemcpy.c",1974 "musl/src/string/wmemcpy.c",
1982 "musl/src/string/wmemmove.c",1975 "musl/src/string/wmemmove.c",
1983 "musl/src/string/wmemset.c",1976 "musl/src/string/wmemset.c",
1984 "musl/src/string/x86_64/memcpy.s",
1985 "musl/src/string/x86_64/memmove.s",
1986 "musl/src/string/x86_64/memset.s",1977 "musl/src/string/x86_64/memset.s",
1987 "musl/src/temp/mkdtemp.c",1978 "musl/src/temp/mkdtemp.c",
1988 "musl/src/temp/mkostemp.c",1979 "musl/src/temp/mkostemp.c",
src/wasi_libc.zig-2
...@@ -694,9 +694,7 @@ const libc_top_half_src_files = [_][]const u8{...@@ -694,9 +694,7 @@ const libc_top_half_src_files = [_][]const u8{
694 "wasi/libc-top-half/musl/src/string/memccpy.c",694 "wasi/libc-top-half/musl/src/string/memccpy.c",
695 "wasi/libc-top-half/musl/src/string/memchr.c",695 "wasi/libc-top-half/musl/src/string/memchr.c",
696 "wasi/libc-top-half/musl/src/string/memcmp.c",696 "wasi/libc-top-half/musl/src/string/memcmp.c",
697 "wasi/libc-top-half/musl/src/string/memcpy.c",
698 "wasi/libc-top-half/musl/src/string/memmem.c",697 "wasi/libc-top-half/musl/src/string/memmem.c",
699 "wasi/libc-top-half/musl/src/string/memmove.c",
700 "wasi/libc-top-half/musl/src/string/mempcpy.c",698 "wasi/libc-top-half/musl/src/string/mempcpy.c",
701 "wasi/libc-top-half/musl/src/string/memrchr.c",699 "wasi/libc-top-half/musl/src/string/memrchr.c",
702 "wasi/libc-top-half/musl/src/string/memset.c",700 "wasi/libc-top-half/musl/src/string/memset.c",