4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
30 * Fast strcmp. This works one int at a time, using aligned pointers
31 * if possible, misaligned pointers if necessary. To avoid taking
32 * faults from going off the end of a page, the code is careful to go
33 * a byte-at-a-time when a misaligned pointer is near a page boundary.
34 * The code is almost portable, but see the assumptions below.
39 * sizeof (int) is not greater than 8.
40 * sizeof (int) is a power of 2.
41 * An int pointer can always be dereferenced even if it is not properly
42 * aligned (though aligned references are assumed to be faster).
43 * It is OK to assign bogus values to a pointer (in particular, a
44 * value that is before the beginning of the string) as long as that
45 * pointer is only used with indices big enough to bring us back into
47 * It is OK to reference bytes past the end of a string as long as we
48 * don't cross a page boundary.
54 #include <sys/sysconfig.h>
58 * This strange expression will test to see if *any* byte in the int is
59 * a NUL. The constants are big enough to allow for ints up to 8 bytes.
60 * The two arguments are actually two copies of the same value; this
61 * allows the compiler freedom to play with both values for efficiency.
63 #define ANYNUL(i1, i2) (((i1) - (int)0x0101010101010101LL) & ~(i2) & \
64 (int)0x8080808080808080ULL)
67 strcmp(const char *str1
, const char *str2
)
79 * Go 1 byte at a time until at least one pointer is word aligned.
80 * Assumes that sizeof (int) is a power of 2.
82 while ((((int) str1
) & (sizeof (int) - 1)) &&
83 (((int) str2
) & (sizeof (int) - 1))) {
86 return ((unsigned char)*str1
- (unsigned char)*str2
);
94 * If one pointer is misaligned, we must be careful not to
95 * dereference it when it points across a page boundary.
96 * If we did, we might go past the end of the segment and
97 * get a SIGSEGV. Set "count" to the number of ints we can
98 * scan before running into such a boundary.
101 if (((int) str1
) & (sizeof (int) - 1)) {
103 pagesize
= _sysconfig(_CONFIG_PAGESIZE
);
104 count
= (pagesize
- ((int)str1
& (pagesize
- 1))) /
106 } else if (((int) str2
) & (sizeof (int) - 1)) {
108 pagesize
= _sysconfig(_CONFIG_PAGESIZE
);
109 count
= (pagesize
- ((int)str2
& (pagesize
- 1))) /
117 * Go "sizeof (int)" bytes at a time until at least one pointer
120 * Unwrap the loop for even a bit more speed.
124 * Check whether we can test the next 4 ints without
125 * hitting a page boundary. If we can only test 1, 2,
126 * or 3, go and do that first. If we can't check any
127 * more, go and test one byte, realign, and start again.
134 goto do3
; /* check only 3 ints */
138 goto do2
; /* check only 2 ints */
142 goto do1
; /* check only 1 int */
144 case -5: /* -5, -6, and -7 come up on the */
145 case -6: /* next time around after we do one */
146 case -7: /* of the 3 gotos above */
151 * The goto above should be explained. By going
152 * into the middle of the loop, it makes sure
153 * that we advance at least one byte. We will
154 * stay in that loop until the misaligned pointer
155 * becomes aligned (at the page boundary). We
156 * will then break out of that loop with the
157 * formerly misaligned pointer now aligned, the
158 * formerly aligned pointer now misaligned, and
159 * we will come back into this loop until the
160 * latter pointer reaches a page boundary.
162 default: /* at least 4 ints to go */
170 else if (ANYNUL(i1
, i2
))
178 else if (ANYNUL(i1
, i2
))
186 else if (ANYNUL(i1
, i2
))
194 else if (ANYNUL(i1
, i2
))
201 /* We found a difference. Go one byte at a time to find where. */
202 b1
= i1
; /* save the ints in memory */
204 str1
= (void *) &b1
; /* point at them */
206 while (*str1
== *str2
) {
212 return ((unsigned char)*str1
- (unsigned char)*str2
);