~linaro-toolchain-dev/cortex-strings/trunk

« back to all changes in this revision

Viewing changes to reference/glibc-c/strlen.c

  • Committer: Michael Hope
  • Date: 2012-06-12 03:19:48 UTC
  • Revision ID: michael.hope@linaro.org-20120612031948-4ii8jicywtzjprak
Added the C only routines from GLIBC 2.16+20120607~git24a6dbe

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 1991,1993,1997,2000,2003,2009 Free Software Foundation, Inc.
 
2
   This file is part of the GNU C Library.
 
3
   Written by Torbjorn Granlund (tege@sics.se),
 
4
   with help from Dan Sahlin (dan@sics.se);
 
5
   commentary by Jim Blandy (jimb@ai.mit.edu).
 
6
 
 
7
   The GNU C Library is free software; you can redistribute it and/or
 
8
   modify it under the terms of the GNU Lesser General Public
 
9
   License as published by the Free Software Foundation; either
 
10
   version 2.1 of the License, or (at your option) any later version.
 
11
 
 
12
   The GNU C Library is distributed in the hope that it will be useful,
 
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
15
   Lesser General Public License for more details.
 
16
 
 
17
   You should have received a copy of the GNU Lesser General Public
 
18
   License along with the GNU C Library; if not, see
 
19
   <http://www.gnu.org/licenses/>.  */
 
20
 
 
21
#include <string.h>
 
22
#include <stdlib.h>
 
23
 
 
24
#undef strlen
 
25
 
 
26
/* Return the length of the null-terminated string STR.  Scan for
 
27
   the null terminator quickly by testing four bytes at a time.  */
 
28
size_t
 
29
strlen (str)
 
30
     const char *str;
 
31
{
 
32
  const char *char_ptr;
 
33
  const unsigned long int *longword_ptr;
 
34
  unsigned long int longword, himagic, lomagic;
 
35
 
 
36
  /* Handle the first few characters by reading one character at a time.
 
37
     Do this until CHAR_PTR is aligned on a longword boundary.  */
 
38
  for (char_ptr = str; ((unsigned long int) char_ptr
 
39
                        & (sizeof (longword) - 1)) != 0;
 
40
       ++char_ptr)
 
41
    if (*char_ptr == '\0')
 
42
      return char_ptr - str;
 
43
 
 
44
  /* All these elucidatory comments refer to 4-byte longwords,
 
45
     but the theory applies equally well to 8-byte longwords.  */
 
46
 
 
47
  longword_ptr = (unsigned long int *) char_ptr;
 
48
 
 
49
  /* Bits 31, 24, 16, and 8 of this number are zero.  Call these bits
 
50
     the "holes."  Note that there is a hole just to the left of
 
51
     each byte, with an extra at the end:
 
52
 
 
53
     bits:  01111110 11111110 11111110 11111111
 
54
     bytes: AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD
 
55
 
 
56
     The 1-bits make sure that carries propagate to the next 0-bit.
 
57
     The 0-bits provide holes for carries to fall into.  */
 
58
  himagic = 0x80808080L;
 
59
  lomagic = 0x01010101L;
 
60
  if (sizeof (longword) > 4)
 
61
    {
 
62
      /* 64-bit version of the magic.  */
 
63
      /* Do the shift in two steps to avoid a warning if long has 32 bits.  */
 
64
      himagic = ((himagic << 16) << 16) | himagic;
 
65
      lomagic = ((lomagic << 16) << 16) | lomagic;
 
66
    }
 
67
  if (sizeof (longword) > 8)
 
68
    abort ();
 
69
 
 
70
  /* Instead of the traditional loop which tests each character,
 
71
     we will test a longword at a time.  The tricky part is testing
 
72
     if *any of the four* bytes in the longword in question are zero.  */
 
73
  for (;;)
 
74
    {
 
75
      longword = *longword_ptr++;
 
76
 
 
77
      if (((longword - lomagic) & ~longword & himagic) != 0)
 
78
        {
 
79
          /* Which of the bytes was the zero?  If none of them were, it was
 
80
             a misfire; continue the search.  */
 
81
 
 
82
          const char *cp = (const char *) (longword_ptr - 1);
 
83
 
 
84
          if (cp[0] == 0)
 
85
            return cp - str;
 
86
          if (cp[1] == 0)
 
87
            return cp - str + 1;
 
88
          if (cp[2] == 0)
 
89
            return cp - str + 2;
 
90
          if (cp[3] == 0)
 
91
            return cp - str + 3;
 
92
          if (sizeof (longword) > 4)
 
93
            {
 
94
              if (cp[4] == 0)
 
95
                return cp - str + 4;
 
96
              if (cp[5] == 0)
 
97
                return cp - str + 5;
 
98
              if (cp[6] == 0)
 
99
                return cp - str + 6;
 
100
              if (cp[7] == 0)
 
101
                return cp - str + 7;
 
102
            }
 
103
        }
 
104
    }
 
105
}