1 #if defined __thumb__ || defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
2
3 #include "../../string/strlen.c"
4
5 #else
6
7 #include <string.h>
8 #include "xscale.h"
9
10 size_t
strlen(const char * str)11 strlen (const char *str)
12 {
13 _CONST char *start = str;
14
15 /* Skip unaligned part. */
16 if ((long)str & 3)
17 {
18 str--;
19 do
20 {
21 if (*++str == '\0')
22 goto out;
23 }
24 while ((long)str & 3);
25 }
26
27 /* Load two constants:
28 R4 = 0xfefefeff [ == ~(0x80808080 << 1) ]
29 R5 = 0x80808080 */
30
31 asm ("mov r5, #0x80\n\
32 add r5, r5, #0x8000\n\
33 add r5, r5, r5, lsl #16\n\
34 mvn r4, r5, lsl #1\n\
35 "
36
37 #if defined __ARM_ARCH_5__ || defined __ARM_ARCH_5T__ || defined __ARM_ARCH_5E__ || defined __ARM_ARCH_5TE__
38
39 " tst %0, #0x7\n\
40 ldreqd r6, [%0]\n\
41 beq 1f\n\
42 ldr r2, [%0]\n\
43 add r3, r2, r4\n\
44 bic r3, r3, r2\n\
45 ands r2, r3, r5\n\
46 bne 2f\n\
47 sub %0, %0, #4\n\
48 \n\
49 0:\n\
50 ldrd r6, [%0, #8]!\n\
51 "
52 PRELOADSTR ("%0")
53 "\n\
54 1:\n\
55 add r3, r6, r4\n\
56 add r2, r7, r4\n\
57 bic r3, r3, r6\n\
58 bic r2, r2, r7\n\
59 and r3, r3, r5\n\
60 and r2, r2, r5\n\
61 orrs r3, r2, r3\n\
62 beq 0b\n\
63 "
64 #else
65
66 " sub %0, %0, #4\n\
67 \n\
68 0:\n\
69 ldr r6, [%0, #4]!\n\
70 "
71 PRELOADSTR ("%0")
72 "\n\
73 add r3, r6, r4\n\
74 bic r3, r3, r6\n\
75 ands r3, r3, r5\n\
76 beq 0b\n\
77 "
78 #endif /* __ARM_ARCH_5[T][E]__ */
79 "\n\
80 2:\n\
81 ldrb r3, [%0]\n\
82 cmp r3, #0x0\n\
83 beq 1f\n\
84 \n\
85 0:\n\
86 ldrb r3, [%0, #1]!\n\
87 "
88 PRELOADSTR ("%0")
89 "\n\
90 cmp r3, #0x0\n\
91 bne 0b\n\
92 1:\n\
93 "
94 : "=r" (str) : "0" (str) : "r2", "r3", "r4", "r5", "r6", "r7");
95
96 out:
97 return str - start;
98 }
99
100 #endif
101