4 * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 * See https://llvm.org/LICENSE.txt for license information.
6 * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
9 #if defined (__thumb2__) && !defined (__thumb__)
19 #define magic1(REG) "#0x01010101"
20 #define magic2(REG) "#0x80808080"
22 #define magic1(REG) #REG
23 #define magic2(REG) #REG ", lsl #7"
26 char* __attribute__((naked
))
27 __strcpy_arm (char* dst
, const char* src
)
39 "str r5, [sp, #-4]!\n\t"
41 "orr r5, r5, r5, lsl #8\n\t"
42 "orr r5, r5, r5, lsl #16\n\t"
45 "str r4, [sp, #-4]!\n\t"
47 "ldr r3, [r1], #4\n\t"
49 "sub r2, r3, "magic1(r5
)"\n\t"
51 "tst r2, "magic2(r5
)"\n\t"
53 "streq r3, [ip], #4\n\t"
54 "ldreq r3, [r1], #4\n"
56 /* Inner loop. We now know that r1 is 64-bit aligned, so we
57 can safely fetch up to two words. This allows us to avoid
62 "ldr r4, [r1], #4\n\t"
63 "sub r2, r3, "magic1(r5
)"\n\t"
65 "tst r2, "magic2(r5
)"\n\t"
66 "sub r2, r4, "magic1(r5
)"\n\t"
68 "str r3, [ip], #4\n\t"
70 "tst r2, "magic2(r5
)"\n\t"
72 "ldreq r3, [r1], #4\n\t"
73 "streq r4, [ip], #4\n\t"
78 "rors r3, r3, #24\n\t"
80 "strb r3, [ip], #1\n\t"
86 "ldr r4, [sp], #4\n\t"
88 "ldr r5, [sp], #4\n\t"
92 /* Strings have the same offset from word alignment, but it's
97 "ldrb r2, [r1], #1\n\t"
98 "strb r2, [ip], #1\n\t"
105 "ldrh r2, [r1], #2\n\t"
107 "tst r2, #0xff00\n\t"
109 "strneh r2, [ip], #2\n\t"
110 "lsreq r2, r2, #8\n\t"
111 "streqb r2, [ip]\n\t"
112 "tstne r2, #0xff\n\t"
116 "strneh r2, [ip], #2\n\t"
117 "streqb r2, [ip]\n\t"
118 "tstne r2, #0xff00\n\t"
123 /* src and dst do not have a common word-alignment. Fall back to
126 "ldrb r2, [r1], #1\n\t"
127 "strb r2, [ip], #1\n\t"
132 /* For GLIBC: libc_hidden_builtin_def (strcpy) */
134 #endif /* defined (__thumb2__) && !defined (__thumb__) */