|
|
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/memset.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: * This code is loosely based on some work done by Mike DeMoney ! 34: * for the m88k. ! 35: * ! 36: * HISTORY ! 37: * 14-Aug-92 Bruce Martin ([email protected]) ! 38: * Created. ! 39: */ ! 40: ! 41: #define MIN_TO_ALIGN 32 ! 42: ! 43: /* ! 44: * Convert a void * into a unsigned int so arithmetic can be done ! 45: * (Technically, the gnu C compiler is tolerant of arithmetic ! 46: * on void *, but ansi isn't; so we do this.) ! 47: */ ! 48: #define UNS(voidp) ((unsigned int)(voidp)) ! 49: ! 50: /* ! 51: * Number of bytes addr is past an object of 'align' size. ! 52: */ ! 53: #define BYTES_PAST_ALIGNMENT(voidp, align) \ ! 54: (UNS(voidp) & (align - 1)) ! 55: ! 56: /* ! 57: * Bytes moved by an unrolled loop ! 58: */ ! 59: #define LOOP_STRIDE(type, unroll) ((unroll) * sizeof(type)) ! 60: ! 61: ! 62: /* ! 63: * Len modulo LOOP_STRIDE ! 64: */ ! 65: #define MODULO_LOOP_UNROLL(len, type, unroll) \ ! 66: ((len) & (LOOP_STRIDE(type, unroll) - 1) & ~(sizeof(type) - 1)) ! 67: ! 68: ! 69: /* ! 70: * Convert a void * + offset into char, short, int, or long long reference ! 71: * based at that address ! 72: */ ! 73: #define CHAR(voidp, offset) (*(char *)(UNS(voidp) + (offset))) ! 74: #define SHORT(voidp, offset) (*(short *)(UNS(voidp) + (offset))) ! 75: #define INT(voidp, offset) (*(int *)(UNS(voidp) + (offset))) ! 76: ! 77: ! 78: ! 79: static inline void ! 80: simple_char_set(char *dst, int val, int len) ! 81: { ! 82: switch (len) { ! 83: case 31: CHAR(dst, 30) = val; ! 84: case 30: SHORT(dst, 28) = val; ! 85: INT(dst, 24) = val; ! 86: INT(dst, 20) = val; ! 87: INT(dst, 16) = val; ! 88: INT(dst, 12) = val; ! 89: INT(dst, 8) = val; ! 90: INT(dst, 4) = val; ! 91: INT(dst, 0) = val; ! 92: break; ! 93: case 29: CHAR(dst, 28) = val; ! 94: case 28: INT(dst, 24) = val; ! 95: INT(dst, 20) = val; ! 96: INT(dst, 16) = val; ! 97: INT(dst, 12) = val; ! 98: INT(dst, 8) = val; ! 99: INT(dst, 4) = val; ! 100: INT(dst, 0) = val; ! 101: break; ! 102: case 27: CHAR(dst, 26) = val; ! 103: case 26: SHORT(dst, 24) = val; ! 104: INT(dst, 20) = val; ! 105: INT(dst, 16) = val; ! 106: INT(dst, 12) = val; ! 107: INT(dst, 8) = val; ! 108: INT(dst, 4) = val; ! 109: INT(dst, 0) = val; ! 110: break; ! 111: case 25: CHAR(dst, 24) = val; ! 112: case 24: INT(dst, 20) = val; ! 113: INT(dst, 16) = val; ! 114: INT(dst, 12) = val; ! 115: INT(dst, 8) = val; ! 116: INT(dst, 4) = val; ! 117: INT(dst, 0) = val; ! 118: break; ! 119: case 23: CHAR(dst, 22) = val; ! 120: case 22: SHORT(dst, 20) = val; ! 121: INT(dst, 16) = val; ! 122: INT(dst, 12) = val; ! 123: INT(dst, 8) = val; ! 124: INT(dst, 4) = val; ! 125: INT(dst, 0) = val; ! 126: break; ! 127: case 21: CHAR(dst, 20) = val; ! 128: case 20: INT(dst, 16) = val; ! 129: INT(dst, 12) = val; ! 130: INT(dst, 8) = val; ! 131: INT(dst, 4) = val; ! 132: INT(dst, 0) = val; ! 133: break; ! 134: case 19: CHAR(dst, 18) = val; ! 135: case 18: SHORT(dst, 16) = val; ! 136: INT(dst, 12) = val; ! 137: INT(dst, 8) = val; ! 138: INT(dst, 4) = val; ! 139: INT(dst, 0) = val; ! 140: break; ! 141: case 17: CHAR(dst, 16) = val; ! 142: case 16: INT(dst, 12) = val; ! 143: INT(dst, 8) = val; ! 144: INT(dst, 4) = val; ! 145: INT(dst, 0) = val; ! 146: break; ! 147: case 15: CHAR(dst, 14) = val; ! 148: case 14: SHORT(dst, 12) = val; ! 149: INT(dst, 8) = val; ! 150: INT(dst, 4) = val; ! 151: INT(dst, 0) = val; ! 152: break; ! 153: case 13: CHAR(dst, 12) = val; ! 154: case 12: INT(dst, 8) = val; ! 155: INT(dst, 4) = val; ! 156: INT(dst, 0) = val; ! 157: break; ! 158: case 11: CHAR(dst, 10) = val; ! 159: case 10: SHORT(dst, 8) = val; ! 160: INT(dst, 4) = val; ! 161: INT(dst, 0) = val; ! 162: break; ! 163: case 9: CHAR(dst, 8) = val; ! 164: case 8: INT(dst, 4) = val; ! 165: INT(dst, 0) = val; ! 166: break; ! 167: case 7: CHAR(dst, 6) = val; ! 168: case 6: SHORT(dst, 4) = val; ! 169: INT(dst, 0) = val; ! 170: break; ! 171: case 5: CHAR(dst, 4) = val; ! 172: case 4: INT(dst, 0) = val; ! 173: break; ! 174: case 3: CHAR(dst, 2) = val; ! 175: case 2: SHORT(dst, 0) = val; ! 176: break; ! 177: case 1: CHAR(dst, 0) = val; ! 178: } ! 179: return; ! 180: } ! 181: ! 182: ! 183: ! 184: void *memset(void *, int, unsigned long); ! 185: ! 186: void bzero(void *dst, unsigned long ulen) ! 187: { ! 188: (void) memset(dst, 0, ulen); ! 189: } ! 190: ! 191: void blkclr(void *dst, unsigned long ulen) ! 192: { ! 193: (void) memset(dst, 0, ulen); ! 194: } ! 195: ! 196: ! 197: ! 198: void *memset(void *dst, int val, unsigned long ulen) ! 199: { ! 200: int len = ulen; ! 201: void *orig_dst = dst; ! 202: int need_to_set; ! 203: int alignment; ! 204: ! 205: val |= (val << 8); ! 206: val |= (val << 16); ! 207: ! 208: /* Always do a forward copy */ ! 209: ! 210: if (len < MIN_TO_ALIGN) { ! 211: simple_char_set(dst, val, len); ! 212: return orig_dst; ! 213: } ! 214: ! 215: if (need_to_set = BYTES_PAST_ALIGNMENT(dst, 2 * sizeof(int))) { ! 216: need_to_set = (2 * sizeof(int)) - need_to_set; ! 217: simple_char_set(dst, val, need_to_set); ! 218: len -= need_to_set; ! 219: UNS(dst) += need_to_set; ! 220: } ! 221: ! 222: alignment = MODULO_LOOP_UNROLL(len, int, 8); ! 223: UNS(dst) += alignment - LOOP_STRIDE(int, 8); ! 224: switch (alignment) { ! 225: do { ! 226: INT(dst, 0) = val; ! 227: case 28: INT(dst, 4) = val; ! 228: case 24: INT(dst, 8) = val; ! 229: case 20: INT(dst, 12) = val; ! 230: case 16: INT(dst, 16) = val; ! 231: case 12: INT(dst, 20) = val; ! 232: case 8: INT(dst, 24) = val; ! 233: case 4: INT(dst, 28) = val; ! 234: case 0: ! 235: UNS(dst) += LOOP_STRIDE(int, 8); ! 236: len -= LOOP_STRIDE(int, 8); ! 237: } while (len >= 0); ! 238: len &= sizeof(int) - 1; ! 239: } ! 240: ! 241: switch (len) { ! 242: case 3: CHAR(dst, 2) = val; ! 243: case 2: CHAR(dst, 1) = val; ! 244: case 1: CHAR(dst, 0) = val; ! 245: } ! 246: ! 247: return orig_dst; ! 248: } ! 249: ! 250: #import <mach/mach_types.h> ! 251: #import <sys/errno.h> ! 252: ! 253: /* ! 254: * Maintain the recover field in the thread_t structure ! 255: */ ! 256: static inline void ! 257: set_recover(int (*vector)()) ! 258: { ! 259: current_thread()->recover = (vm_offset_t)vector; ! 260: return; ! 261: } ! 262: ! 263: static inline void ! 264: clear_recover() ! 265: { ! 266: current_thread()->recover = 0; ! 267: } ! 268: ! 269: void *safe_memset(void *, int, unsigned long); ! 270: ! 271: int safe_bzero(void *dst, unsigned long ulen) ! 272: { ! 273: if (safe_memset(dst, 0, ulen) == (void *)(-1)) ! 274: return EFAULT; ! 275: else ! 276: return 0; ! 277: } ! 278: ! 279: ! 280: void *safe_memset(void *dst, int val, unsigned long ulen) ! 281: { ! 282: int len = ulen; ! 283: void *orig_dst = dst; ! 284: int need_to_set; ! 285: int alignment; ! 286: ! 287: val |= (val << 8); ! 288: val |= (val << 16); ! 289: ! 290: set_recover(&&do_fault); ! 291: ! 292: /* Always do a forward copy */ ! 293: ! 294: if (len < MIN_TO_ALIGN) { ! 295: simple_char_set(dst, val, len); ! 296: clear_recover(); ! 297: return orig_dst; ! 298: } ! 299: ! 300: if (need_to_set = BYTES_PAST_ALIGNMENT(dst, 2 * sizeof(int))) { ! 301: need_to_set = (2 * sizeof(int)) - need_to_set; ! 302: simple_char_set(dst, val, need_to_set); ! 303: len -= need_to_set; ! 304: UNS(dst) += need_to_set; ! 305: } ! 306: ! 307: alignment = MODULO_LOOP_UNROLL(len, int, 8); ! 308: UNS(dst) += alignment - LOOP_STRIDE(int, 8); ! 309: switch (alignment) { ! 310: do { ! 311: INT(dst, 0) = val; ! 312: case 28: INT(dst, 4) = val; ! 313: case 24: INT(dst, 8) = val; ! 314: case 20: INT(dst, 12) = val; ! 315: case 16: INT(dst, 16) = val; ! 316: case 12: INT(dst, 20) = val; ! 317: case 8: INT(dst, 24) = val; ! 318: case 4: INT(dst, 28) = val; ! 319: case 0: ! 320: UNS(dst) += LOOP_STRIDE(int, 8); ! 321: len -= LOOP_STRIDE(int, 8); ! 322: } while (len >= 0); ! 323: len &= sizeof(int) - 1; ! 324: } ! 325: ! 326: switch (len) { ! 327: case 3: CHAR(dst, 2) = val; ! 328: case 2: CHAR(dst, 1) = val; ! 329: case 1: CHAR(dst, 0) = val; ! 330: } ! 331: ! 332: clear_recover(); ! 333: return orig_dst; ! 334: ! 335: do_fault: ! 336: clear_recover(); ! 337: return (void *)(-1); ! 338: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.