Rev | Line | |
---|
[1] | 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.