~ubuntu-branches/ubuntu/trusty/libprelude/trusty

« back to all changes in this revision

Viewing changes to libmissing/memchr.c

  • Committer: Bazaar Package Importer
  • Author(s): Pierre Chifflier
  • Date: 2008-04-28 15:23:30 UTC
  • mfrom: (1.1.9 upstream)
  • Revision ID: james.westby@ubuntu.com-20080428152330-su7zlfscjjeh30ig
Tags: 0.9.17.1-1
New upstream release (remove debug output)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 1991, 1993, 1996, 1997, 1999, 2000, 2003, 2004, 2006 Free
2
 
   Software Foundation, Inc.
 
1
/* Copyright (C) 1991, 1993, 1996, 1997, 1999, 2000, 2003, 2004, 2006, 2008
 
2
   Free Software Foundation, Inc.
3
3
 
4
4
   Based on strlen implementation by Torbjorn Granlund (tege@sics.se),
5
5
   with help from Dan Sahlin (dan@sics.se) and
45
45
# define BP_SYM(sym) sym
46
46
#endif
47
47
 
48
 
#undef memchr
 
48
#include "intprops.h"
 
49
 
49
50
#undef __memchr
 
51
#ifdef _LIBC
 
52
# undef memchr
 
53
#endif
 
54
 
 
55
#ifndef weak_alias
 
56
# define __memchr memchr
 
57
#endif
50
58
 
51
59
/* Search no more than N bytes of S for C.  */
52
60
void *
53
61
__memchr (void const *s, int c_in, size_t n)
54
62
{
 
63
  /* On 32-bit hardware, choosing longword to be a 32-bit unsigned
 
64
     long instead of a 64-bit uintmax_t tends to give better
 
65
     performance.  On 64-bit hardware, unsigned long is generally 64
 
66
     bits already.  Change this typedef to experiment with
 
67
     performance.  */
 
68
  typedef unsigned long longword;
 
69
 
55
70
  const unsigned char *char_ptr;
56
 
  const unsigned long int *longword_ptr;
57
 
  unsigned long int longword, magic_bits, charmask;
 
71
  const longword *longword_ptr;
 
72
  longword repeated_one;
 
73
  longword repeated_c;
58
74
  unsigned reg_char c;
59
 
  int i;
60
75
 
61
76
  c = (unsigned char) c_in;
62
77
 
63
 
  /* Handle the first few characters by reading one character at a time.
 
78
  /* Handle the first few bytes by reading one byte at a time.
64
79
     Do this until CHAR_PTR is aligned on a longword boundary.  */
65
80
  for (char_ptr = (const unsigned char *) s;
66
 
       n > 0 && (size_t) char_ptr % sizeof longword != 0;
 
81
       n > 0 && (size_t) char_ptr % sizeof (longword) != 0;
67
82
       --n, ++char_ptr)
68
83
    if (*char_ptr == c)
69
84
      return (void *) char_ptr;
70
85
 
 
86
  longword_ptr = (const longword *) char_ptr;
 
87
 
71
88
  /* All these elucidatory comments refer to 4-byte longwords,
72
89
     but the theory applies equally well to any size longwords.  */
73
90
 
74
 
  longword_ptr = (const unsigned long int *) char_ptr;
75
 
 
76
 
  /* Bits 31, 24, 16, and 8 of this number are zero.  Call these bits
77
 
     the "holes."  Note that there is a hole just to the left of
78
 
     each byte, with an extra at the end:
79
 
 
80
 
     bits:  01111110 11111110 11111110 11111111
81
 
     bytes: AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD
82
 
 
83
 
     The 1-bits make sure that carries propagate to the next 0-bit.
84
 
     The 0-bits provide holes for carries to fall into.  */
85
 
 
86
 
  /* Set MAGIC_BITS to be this pattern of 1 and 0 bits.
87
 
     Set CHARMASK to be a longword, each of whose bytes is C.  */
88
 
 
89
 
  magic_bits = 0xfefefefe;
90
 
  charmask = c | (c << 8);
91
 
  charmask |= charmask << 16;
92
 
#if 0xffffffffU < ULONG_MAX
93
 
  magic_bits |= magic_bits << 32;
94
 
  charmask |= charmask << 32;
95
 
  if (8 < sizeof longword)
96
 
    for (i = 64; i < sizeof longword * 8; i *= 2)
97
 
      {
98
 
        magic_bits |= magic_bits << i;
99
 
        charmask |= charmask << i;
100
 
      }
101
 
#endif
102
 
  magic_bits = (ULONG_MAX >> 1) & (magic_bits | 1);
103
 
 
104
 
  /* Instead of the traditional loop which tests each character,
105
 
     we will test a longword at a time.  The tricky part is testing
106
 
     if *any of the four* bytes in the longword in question are zero.  */
107
 
  while (n >= sizeof longword)
 
91
  /* Compute auxiliary longword values:
 
92
     repeated_one is a value which has a 1 in every byte.
 
93
     repeated_c has c in every byte.  */
 
94
  repeated_one = 0x01010101;
 
95
  repeated_c = c | (c << 8);
 
96
  repeated_c |= repeated_c << 16;
 
97
  if (0xffffffffU < TYPE_MAXIMUM (longword))
108
98
    {
109
 
      /* We tentatively exit the loop if adding MAGIC_BITS to
110
 
         LONGWORD fails to change any of the hole bits of LONGWORD.
111
 
 
112
 
         1) Is this safe?  Will it catch all the zero bytes?
113
 
         Suppose there is a byte with all zeros.  Any carry bits
114
 
         propagating from its left will fall into the hole at its
115
 
         least significant bit and stop.  Since there will be no
116
 
         carry from its most significant bit, the LSB of the
117
 
         byte to the left will be unchanged, and the zero will be
118
 
         detected.
119
 
 
120
 
         2) Is this worthwhile?  Will it ignore everything except
121
 
         zero bytes?  Suppose every byte of LONGWORD has a bit set
122
 
         somewhere.  There will be a carry into bit 8.  If bit 8
123
 
         is set, this will carry into bit 16.  If bit 8 is clear,
124
 
         one of bits 9-15 must be set, so there will be a carry
125
 
         into bit 16.  Similarly, there will be a carry into bit
126
 
         24.  If one of bits 24-30 is set, there will be a carry
127
 
         into bit 31, so all of the hole bits will be changed.
128
 
 
129
 
         The one misfire occurs when bits 24-30 are clear and bit
130
 
         31 is set; in this case, the hole at bit 31 is not
131
 
         changed.  If we had access to the processor carry flag,
132
 
         we could close this loophole by putting the fourth hole
133
 
         at bit 32!
134
 
 
135
 
         So it ignores everything except 128's, when they're aligned
136
 
         properly.
137
 
 
138
 
         3) But wait!  Aren't we looking for C, not zero?
139
 
         Good point.  So what we do is XOR LONGWORD with a longword,
140
 
         each of whose bytes is C.  This turns each byte that is C
141
 
         into a zero.  */
142
 
 
143
 
      longword = *longword_ptr++ ^ charmask;
144
 
 
145
 
      /* Add MAGIC_BITS to LONGWORD.  */
146
 
      if ((((longword + magic_bits)
147
 
 
148
 
            /* Set those bits that were unchanged by the addition.  */
149
 
            ^ ~longword)
150
 
 
151
 
           /* Look at only the hole bits.  If any of the hole bits
152
 
              are unchanged, most likely one of the bytes was a
153
 
              zero.  */
154
 
           & ~magic_bits) != 0)
 
99
      repeated_one |= repeated_one << 31 << 1;
 
100
      repeated_c |= repeated_c << 31 << 1;
 
101
      if (8 < sizeof (longword))
155
102
        {
156
 
          /* Which of the bytes was C?  If none of them were, it was
157
 
             a misfire; continue the search.  */
158
 
 
159
 
          const unsigned char *cp = (const unsigned char *) (longword_ptr - 1);
160
 
 
161
 
          if (cp[0] == c)
162
 
            return (void *) cp;
163
 
          if (cp[1] == c)
164
 
            return (void *) &cp[1];
165
 
          if (cp[2] == c)
166
 
            return (void *) &cp[2];
167
 
          if (cp[3] == c)
168
 
            return (void *) &cp[3];
169
 
          if (4 < sizeof longword && cp[4] == c)
170
 
            return (void *) &cp[4];
171
 
          if (5 < sizeof longword && cp[5] == c)
172
 
            return (void *) &cp[5];
173
 
          if (6 < sizeof longword && cp[6] == c)
174
 
            return (void *) &cp[6];
175
 
          if (7 < sizeof longword && cp[7] == c)
176
 
            return (void *) &cp[7];
177
 
          if (8 < sizeof longword)
178
 
            for (i = 8; i < sizeof longword; i++)
179
 
              if (cp[i] == c)
180
 
                return (void *) &cp[i];
 
103
          size_t i;
 
104
 
 
105
          for (i = 64; i < sizeof (longword) * 8; i *= 2)
 
106
            {
 
107
              repeated_one |= repeated_one << i;
 
108
              repeated_c |= repeated_c << i;
 
109
            }
181
110
        }
182
 
 
183
 
      n -= sizeof longword;
 
111
    }
 
112
 
 
113
  /* Instead of the traditional loop which tests each byte, we will test a
 
114
     longword at a time.  The tricky part is testing if *any of the four*
 
115
     bytes in the longword in question are equal to c.  We first use an xor
 
116
     with repeated_c.  This reduces the task to testing whether *any of the
 
117
     four* bytes in longword1 is zero.
 
118
 
 
119
     We compute tmp =
 
120
       ((longword1 - repeated_one) & ~longword1) & (repeated_one << 7).
 
121
     That is, we perform the following operations:
 
122
       1. Subtract repeated_one.
 
123
       2. & ~longword1.
 
124
       3. & a mask consisting of 0x80 in every byte.
 
125
     Consider what happens in each byte:
 
126
       - If a byte of longword1 is zero, step 1 and 2 transform it into 0xff,
 
127
         and step 3 transforms it into 0x80.  A carry can also be propagated
 
128
         to more significant bytes.
 
129
       - If a byte of longword1 is nonzero, let its lowest 1 bit be at
 
130
         position k (0 <= k <= 7); so the lowest k bits are 0.  After step 1,
 
131
         the byte ends in a single bit of value 0 and k bits of value 1.
 
132
         After step 2, the result is just k bits of value 1: 2^k - 1.  After
 
133
         step 3, the result is 0.  And no carry is produced.
 
134
     So, if longword1 has only non-zero bytes, tmp is zero.
 
135
     Whereas if longword1 has a zero byte, call j the position of the least
 
136
     significant zero byte.  Then the result has a zero at positions 0, ...,
 
137
     j-1 and a 0x80 at position j.  We cannot predict the result at the more
 
138
     significant bytes (positions j+1..3), but it does not matter since we
 
139
     already have a non-zero bit at position 8*j+7.
 
140
 
 
141
     So, the test whether any byte in longword1 is zero is equivalent to
 
142
     testing whether tmp is nonzero.  */
 
143
 
 
144
  while (n >= sizeof (longword))
 
145
    {
 
146
      longword longword1 = *longword_ptr ^ repeated_c;
 
147
 
 
148
      if ((((longword1 - repeated_one) & ~longword1)
 
149
           & (repeated_one << 7)) != 0)
 
150
        break;
 
151
      longword_ptr++;
 
152
      n -= sizeof (longword);
184
153
    }
185
154
 
186
155
  char_ptr = (const unsigned char *) longword_ptr;
187
156
 
188
 
  while (n-- > 0)
 
157
  /* At this point, we know that either n < sizeof (longword), or one of the
 
158
     sizeof (longword) bytes starting at char_ptr is == c.  On little-endian
 
159
     machines, we could determine the first such byte without any further
 
160
     memory accesses, just by looking at the tmp result from the last loop
 
161
     iteration.  But this does not work on big-endian machines.  Choose code
 
162
     that works in both cases.  */
 
163
 
 
164
  for (; n > 0; --n, ++char_ptr)
189
165
    {
190
166
      if (*char_ptr == c)
191
167
        return (void *) char_ptr;
192
 
      else
193
 
        ++char_ptr;
194
168
    }
195
169
 
196
 
  return 0;
 
170
  return NULL;
197
171
}
198
172
#ifdef weak_alias
199
173
weak_alias (__memchr, BP_SYM (memchr))