fixes for host gcc 4.6.1
[zpugcc/jano.git] / toolchain / gcc / newlib / libc / string / memchr.c
blob2fd3c861d49db8f637ad9341765ff3c1cbd29c29
1 /*
2 FUNCTION
3 <<memchr>>---find character in memory
5 INDEX
6 memchr
8 ANSI_SYNOPSIS
9 #include <string.h>
10 void *memchr(const void *<[src]>, int <[c]>, size_t <[length]>);
12 TRAD_SYNOPSIS
13 #include <string.h>
14 void *memchr(<[src]>, <[c]>, <[length]>)
15 void *<[src]>;
16 void *<[c]>;
17 size_t <[length]>;
19 DESCRIPTION
20 This function searches memory starting at <<*<[src]>>> for the
21 character <[c]>. The search only ends with the first
22 occurrence of <[c]>, or after <[length]> characters; in
23 particular, <<NULL>> does not terminate the search.
25 RETURNS
26 If the character <[c]> is found within <[length]> characters
27 of <<*<[src]>>>, a pointer to the character is returned. If
28 <[c]> is not found, then <<NULL>> is returned.
30 PORTABILITY
31 <<memchr>>> is ANSI C.
33 <<memchr>> requires no supporting OS subroutines.
35 QUICKREF
36 memchr ansi pure
39 #include <_ansi.h>
40 #include <string.h>
41 #include <limits.h>
43 /* Nonzero if either X or Y is not aligned on a "long" boundary. */
44 #define UNALIGNED(X) ((long)X & (sizeof (long) - 1))
46 /* How many bytes are loaded each iteration of the word copy loop. */
47 #define LBLOCKSIZE (sizeof (long))
49 /* Threshhold for punting to the bytewise iterator. */
50 #define TOO_SMALL(LEN) ((LEN) < LBLOCKSIZE)
52 #if LONG_MAX == 2147483647L
53 #define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
54 #else
55 #if LONG_MAX == 9223372036854775807L
56 /* Nonzero if X (a long int) contains a NULL byte. */
57 #define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
58 #else
59 #error long int is not a 32bit or 64bit type.
60 #endif
61 #endif
63 #ifndef DETECTNULL
64 #error long int is not a 32bit or 64bit byte
65 #endif
68 _PTR
69 _DEFUN (memchr, (src_void, c, length),
70 _CONST _PTR src_void _AND
71 int c _AND
72 size_t length)
74 #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
75 _CONST unsigned char *src = (_CONST unsigned char *) src_void;
77 c &= 0xff;
79 while (length--)
81 if (*src == c)
82 return (char *) src;
83 src++;
85 return NULL;
86 #else
87 _CONST unsigned char *src = (_CONST unsigned char *) src_void;
88 unsigned long *asrc;
89 unsigned long buffer;
90 unsigned long mask;
91 int i, j;
93 c &= 0xff;
95 /* If the size is small, or src is unaligned, then
96 use the bytewise loop. We can hope this is rare. */
97 if (!TOO_SMALL (length) && !UNALIGNED (src))
99 /* The fast code reads the ASCII one word at a time and only
100 performs the bytewise search on word-sized segments if they
101 contain the search character, which is detected by XORing
102 the word-sized segment with a word-sized block of the search
103 character and then detecting for the presence of NULL in the
104 result. */
105 asrc = (unsigned long*) src;
106 mask = 0;
107 for (i = 0; i < LBLOCKSIZE; i++)
108 mask = (mask << 8) + c;
110 while (length >= LBLOCKSIZE)
112 buffer = *asrc;
113 buffer ^= mask;
114 if (DETECTNULL (buffer))
116 src = (unsigned char*) asrc;
117 for ( j = 0; j < LBLOCKSIZE; j++ )
119 if (*src == c)
120 return (char*) src;
121 src++;
124 length -= LBLOCKSIZE;
125 asrc++;
128 /* If there are fewer than LBLOCKSIZE characters left,
129 then we resort to the bytewise loop. */
131 src = (unsigned char*) asrc;
134 while (length--)
136 if (*src == c)
137 return (char*) src;
138 src++;
141 return NULL;
142 #endif /* not PREFER_SIZE_OVER_SPEED */