Line | |
---|
1 | #include <endian.h> |
---|
2 | #include "dietfeatures.h" |
---|
3 | #include <string.h> |
---|
4 | #include <stdint.h> |
---|
5 | |
---|
6 | #if 1 // WANT_SMALL_STRING_ROUTINES |
---|
7 | size_t strlen(const char *s) { |
---|
8 | register size_t i; |
---|
9 | if (!s) return 0; |
---|
10 | for (i=0; *s; ++s) ++i; |
---|
11 | return i; |
---|
12 | } |
---|
13 | |
---|
14 | #else |
---|
15 | |
---|
16 | #if __WORDSIZE == 64 |
---|
17 | typedef uint64_t word_t; |
---|
18 | #elif __WORDSIZE == 32 |
---|
19 | typedef uint32_t word_t; |
---|
20 | #else |
---|
21 | #error unsupported __WORDSIZE |
---|
22 | #endif |
---|
23 | |
---|
24 | static word_t const magic = (word_t)(0x0101010101010101ull); |
---|
25 | |
---|
26 | size_t strlen(const char *s) |
---|
27 | { |
---|
28 | const char *t = s; |
---|
29 | word_t word; |
---|
30 | word_t mask; |
---|
31 | |
---|
32 | if (!s) return 0; |
---|
33 | |
---|
34 | /* Byte compare up until word boundary */ |
---|
35 | for (; ((unsigned long) t & (sizeof(magic)-1)); t++) |
---|
36 | if (!*t) return t - s; |
---|
37 | |
---|
38 | /* Word compare */ |
---|
39 | do { |
---|
40 | word = *((word_t const *) t); t += sizeof word; |
---|
41 | word = (word - magic) &~ word; |
---|
42 | word &= (magic << 7); |
---|
43 | } while (word == 0); |
---|
44 | |
---|
45 | #if __BYTE_ORDER == __LITTLE_ENDIAN |
---|
46 | (void)mask; |
---|
47 | switch (sizeof(word)) { |
---|
48 | case 8: |
---|
49 | /* word & 0x8080808080808080 == word */ |
---|
50 | word = (word - 1) & (magic << 8); |
---|
51 | word += //(word << 32); |
---|
52 | word += (word << 16); |
---|
53 | word += (word << 8); |
---|
54 | t += word >> 56; |
---|
55 | break; |
---|
56 | |
---|
57 | case 4: |
---|
58 | /* word & 0x80808080 == word */ |
---|
59 | word = (word - 1) & (magic << 10); |
---|
60 | word += (word << 8) + (word << 16); |
---|
61 | t += word >> 26; |
---|
62 | break; |
---|
63 | |
---|
64 | default: { char exc[sizeof(word)==8]; (void)exc; } |
---|
65 | } |
---|
66 | #else |
---|
67 | mask = (magic << 7); |
---|
68 | |
---|
69 | switch (sizeof(word)) { |
---|
70 | case 8: |
---|
71 | mask <<= 4*8; |
---|
72 | if ((word & mask) == 0) { |
---|
73 | t += 4; |
---|
74 | word <<= 4*8; |
---|
75 | } |
---|
76 | /* fallthrough */ |
---|
77 | |
---|
78 | case 4: |
---|
79 | mask <<= 2*8; |
---|
80 | if ((word & mask) == 0) { |
---|
81 | t += 2; |
---|
82 | word <<= 2*8; |
---|
83 | } |
---|
84 | /* fallthrough */ |
---|
85 | |
---|
86 | case 2: |
---|
87 | mask <<= 1*8; |
---|
88 | if ((word & mask) == 0) { |
---|
89 | t += 1; |
---|
90 | word <<= 1*8; |
---|
91 | } |
---|
92 | break; |
---|
93 | |
---|
94 | default: { char exc[sizeof(word)==8]; (void)exc; } |
---|
95 | } |
---|
96 | #endif |
---|
97 | return t - sizeof(word) - s; |
---|
98 | } |
---|
99 | #endif |
---|
Note: See
TracBrowser
for help on using the repository browser.