]>
git.saurik.com Git - apple/boot.git/blob - gen/libsa/memset.c
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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
22 * @APPLE_LICENSE_HEADER_END@
24 /* Copyright (c) 1991 NeXT Computer, Inc. All rights reserved.
26 * File: libc/i386/ansi/memset.c
27 * Author: Bruce Martin, NeXT Computer, Inc.
29 * This file contains machine dependent code for block compares
30 * on NeXT i386-based products. Currently tuned for the i486.
32 * This code is loosely based on some work done by Mike DeMoney
36 * 14-Dec-93 Curtis Galloway
37 * Modified for the booter; simplified simple_char_set.
39 * 14-Aug-92 Bruce Martin (Bruce_Martin@NeXT.COM)
43 #define MIN_TO_ALIGN 32
46 * Convert a void * into a unsigned int so arithmetic can be done
47 * (Technically, the gnu C compiler is tolerant of arithmetic
48 * on void *, but ansi isn't; so we do this.)
50 #define UNS(voidp) ((unsigned int)(voidp))
53 * Number of bytes addr is past an object of 'align' size.
55 #define BYTES_PAST_ALIGNMENT(voidp, align) \
56 (UNS(voidp) & (align - 1))
59 * Bytes moved by an unrolled loop
61 #define LOOP_STRIDE(type, unroll) ((unroll) * sizeof(type))
65 * Len modulo LOOP_STRIDE
67 #define MODULO_LOOP_UNROLL(len, type, unroll) \
68 ((len) & (LOOP_STRIDE(type, unroll) - 1) & ~(sizeof(type) - 1))
72 * Convert a void * + offset into char, short, int, or long long reference
73 * based at that address
75 #define CHAR(voidp, offset) (*(char *)(UNS(voidp) + (offset)))
76 #define SHORT(voidp, offset) (*(short *)(UNS(voidp) + (offset)))
77 #define INT(voidp, offset) (*(int *)(UNS(voidp) + (offset)))
82 simple_char_set(char *dst
, int val
, int len
)
86 : "&c" (len
), "D" (dst
), "a" (val
)
87 : "ecx", "edi", "eax");
92 void *memset(void *, int, unsigned long);
94 int bzero(void *dst
, unsigned long ulen
)
96 (void) memset(dst
, 0, ulen
);
101 void *memset(void *dst
, int val
, unsigned long ulen
)
104 void *orig_dst
= dst
;
111 /* Always do a forward copy */
113 if (len
< MIN_TO_ALIGN
) {
114 simple_char_set(dst
, val
, len
);
118 if (need_to_set
= BYTES_PAST_ALIGNMENT(dst
, 2 * sizeof(int))) {
119 need_to_set
= (2 * sizeof(int)) - need_to_set
;
120 simple_char_set(dst
, val
, need_to_set
);
122 UNS(dst
) += need_to_set
;
125 alignment
= MODULO_LOOP_UNROLL(len
, int, 8);
126 UNS(dst
) += alignment
- LOOP_STRIDE(int, 8);
130 case 28: INT(dst
, 4) = val
;
131 case 24: INT(dst
, 8) = val
;
132 case 20: INT(dst
, 12) = val
;
133 case 16: INT(dst
, 16) = val
;
134 case 12: INT(dst
, 20) = val
;
135 case 8: INT(dst
, 24) = val
;
136 case 4: INT(dst
, 28) = val
;
138 UNS(dst
) += LOOP_STRIDE(int, 8);
139 len
-= LOOP_STRIDE(int, 8);
141 len
&= sizeof(int) - 1;
145 case 3: CHAR(dst
, 2) = val
;
146 case 2: CHAR(dst
, 1) = val
;
147 case 1: CHAR(dst
, 0) = val
;