|
|
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.