source: trunk/sys/dietlibc/strlen.c @ 178

Last change on this file since 178 was 1, checked in by alain, 8 years ago

First import

File size: 1.8 KB
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
7size_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
17typedef uint64_t        word_t;
18#elif __WORDSIZE == 32
19typedef uint32_t        word_t;
20#else
21#error unsupported __WORDSIZE
22#endif
23
24static word_t const     magic = (word_t)(0x0101010101010101ull);
25
26size_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.