|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24:
25: /* Copyright (c) 1991 NeXT Computer, Inc. All rights reserved.
26: *
27: * File: libc/i386/ansi/memcmp.c
28: * Author: Bruce Martin, NeXT Computer, Inc.
29: *
30: * This file contains machine dependent code for block compares
31: * on NeXT i386-based products. Currently tuned for the i486.
32: *
33: * HISTORY
34: * 12-Aug-92 Bruce Martin ([email protected])
35: * Created.
36: */
37:
38: /*
39: * 486 factoids:
40: * - Using 'repe cmp' is a very marginal win. You can easily beat it
41: * with a aggressively unrolled loop, but that typically has much more
42: * setup time. So, we go with less setup, assuming shorter comparisons
43: * will be the rule.
44: */
45:
46:
47: #define MIN_TO_ALIGN 16
48:
49: /*
50: * Convert a void * into a unsigned int so arithmetic can be done
51: * (Technically, the gnu C compiler is tolerant of arithmetic
52: * on void *, but ansi isn't; so we do this.)
53: */
54: #define UNS(voidp) ((unsigned int)(voidp))
55:
56: /*
57: * Number of bytes addr is past an integer alignment
58: */
59: #define BYTES_PAST_INT_ALIGNMENT(voidp) (UNS(voidp) & (sizeof(int) - 1))
60:
61: #if defined(NX_CURRENT_COMPILER_RELEASE) && (NX_CURRENT_COMPILER_RELEASE < 320)
62: #define SIREG "e"
63: #else
64: #define SIREG "S"
65: #endif
66:
67:
68: static inline char
69: simple_fwd_char_cmp(const char *s1, const char *s2, int len)
70: {
71: int diff;
72: asm(" repe; cmpsb
73: jz 1f
74: movb -1(%2), %1
75: movb -1(%3), %2
76: subb %2, %1
77: 1: movl %1, %0
78: "
79: : "=r" (diff)
80: : "c" (len), "D" (s1), SIREG (s2)
81: : "ecx", "edi", "esi");
82: return diff;
83: }
84:
85: static inline int
86: simple_fwd_int_cmp(const int *s1, const int *s2, int len)
87: {
88: int diff;
89: len >>= 2;
90: asm(" repe; cmpsl
91: jz 1f
92: movl -4(%2), %1
93: movl -4(%3), %2
94: subl %2, %1
95: 1: movl %1, %0
96: "
97: : "=r" (diff)
98: : "c" (len), "D" (s1), SIREG (s2)
99: : "ecx", "edi", "esi");
100: return diff;
101: }
102:
103:
104: int memcmp(const void *, const void *, unsigned long);
105:
106: int bcmp(const void *src1, const void *src2, unsigned long ulen)
107: {
108: return memcmp(src1, src2, ulen);
109: }
110:
111:
112: int memcmp(const void *s1, const void *s2, unsigned long ulen)
113: {
114: int len = ulen;
115: int need_to_cmp;
116: int res;
117:
118: if (len == 0)
119: return 0;
120:
121: /* Always do a forward compare */
122:
123: if (len < MIN_TO_ALIGN) {
124: return simple_fwd_char_cmp(s1, s2, len);
125: }
126:
127: if (need_to_cmp = BYTES_PAST_INT_ALIGNMENT(s2)) {
128: need_to_cmp = sizeof(int) - need_to_cmp;
129: if (res = simple_fwd_char_cmp(s1, s2, need_to_cmp))
130: return res;
131: len -= need_to_cmp;
132: UNS(s1) += need_to_cmp;
133: UNS(s2) += need_to_cmp;
134: }
135:
136: res = simple_fwd_int_cmp(s1, s2, len);
137:
138: if (!res && (need_to_cmp = (len & 3))) {
139: UNS(s2) += (len & ~3);
140: UNS(s1) += (len & ~3);
141: res = simple_fwd_char_cmp(s1, s2, need_to_cmp);
142: }
143: return res;
144: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.