xref: /netbsd-src/external/bsd/nvi/dist/clib/memset.c (revision 2f698edb5c1cb2dcd9e762b0abb50c41dde8b6b7)
1dbd550edSchristos /*-
2dbd550edSchristos  * Copyright (c) 1990, 1993
3dbd550edSchristos  *	The Regents of the University of California.  All rights reserved.
4dbd550edSchristos  *
5dbd550edSchristos  * This code is derived from software contributed to Berkeley by
6dbd550edSchristos  * Mike Hibler and Chris Torek.
7dbd550edSchristos  *
8dbd550edSchristos  * Redistribution and use in source and binary forms, with or without
9dbd550edSchristos  * modification, are permitted provided that the following conditions
10dbd550edSchristos  * are met:
11dbd550edSchristos  * 1. Redistributions of source code must retain the above copyright
12dbd550edSchristos  *    notice, this list of conditions and the following disclaimer.
13dbd550edSchristos  * 2. Redistributions in binary form must reproduce the above copyright
14dbd550edSchristos  *    notice, this list of conditions and the following disclaimer in the
15dbd550edSchristos  *    documentation and/or other materials provided with the distribution.
16dbd550edSchristos  * 3. All advertising materials mentioning features or use of this software
17dbd550edSchristos  *    must display the following acknowledgement:
18dbd550edSchristos  *	This product includes software developed by the University of
19dbd550edSchristos  *	California, Berkeley and its contributors.
20dbd550edSchristos  * 4. Neither the name of the University nor the names of its contributors
21dbd550edSchristos  *    may be used to endorse or promote products derived from this software
22dbd550edSchristos  *    without specific prior written permission.
23dbd550edSchristos  *
24dbd550edSchristos  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25dbd550edSchristos  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26dbd550edSchristos  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27dbd550edSchristos  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28dbd550edSchristos  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29dbd550edSchristos  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30dbd550edSchristos  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31dbd550edSchristos  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32dbd550edSchristos  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33dbd550edSchristos  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34dbd550edSchristos  * SUCH DAMAGE.
35dbd550edSchristos  */
36dbd550edSchristos 
37dbd550edSchristos #include "config.h"
38dbd550edSchristos 
39dbd550edSchristos #if defined(LIBC_SCCS) && !defined(lint)
40dbd550edSchristos static const char sccsid[] = "@(#)memset.c	8.1 (Berkeley) 6/4/93";
41dbd550edSchristos #endif /* LIBC_SCCS and not lint */
42*2f698edbSchristos #else
43*2f698edbSchristos __RCSID("$NetBSD: memset.c,v 1.2 2014/01/26 21:43:45 christos Exp $");
44*2f698edbSchristos #endif
45dbd550edSchristos 
46dbd550edSchristos #include <sys/types.h>
47dbd550edSchristos 
48dbd550edSchristos #include <limits.h>
49dbd550edSchristos #include <string.h>
50dbd550edSchristos 
51dbd550edSchristos /*
52dbd550edSchristos  * PUBLIC: #ifndef HAVE_MEMSET
53dbd550edSchristos  * PUBLIC: void *memset __P((void *, int, size_t));
54dbd550edSchristos  * PUBLIC: #endif
55dbd550edSchristos  */
56dbd550edSchristos #define	wsize	sizeof(u_int)
57dbd550edSchristos #define	wmask	(wsize - 1)
58dbd550edSchristos 
59dbd550edSchristos #ifdef BZERO
60dbd550edSchristos #define	RETURN	return
61dbd550edSchristos #define	VAL	0
62dbd550edSchristos #define	WIDEVAL	0
63dbd550edSchristos 
64dbd550edSchristos void
bzero(dst0,length)65dbd550edSchristos bzero(dst0, length)
66dbd550edSchristos 	void *dst0;
67dbd550edSchristos 	register size_t length;
68dbd550edSchristos #else
69dbd550edSchristos #define	RETURN	return (dst0)
70dbd550edSchristos #define	VAL	c0
71dbd550edSchristos #define	WIDEVAL	c
72dbd550edSchristos 
73dbd550edSchristos void *
74dbd550edSchristos memset(void *dst0, register int c0, register size_t length)
75dbd550edSchristos 
76dbd550edSchristos 
77dbd550edSchristos 
78dbd550edSchristos #endif
79dbd550edSchristos {
80dbd550edSchristos 	register size_t t;
81dbd550edSchristos 	register u_int c;
82dbd550edSchristos 	register u_char *dst;
83dbd550edSchristos 
84dbd550edSchristos 	dst = dst0;
85dbd550edSchristos 	/*
86dbd550edSchristos 	 * If not enough words, just fill bytes.  A length >= 2 words
87dbd550edSchristos 	 * guarantees that at least one of them is `complete' after
88dbd550edSchristos 	 * any necessary alignment.  For instance:
89dbd550edSchristos 	 *
90dbd550edSchristos 	 *	|-----------|-----------|-----------|
91dbd550edSchristos 	 *	|00|01|02|03|04|05|06|07|08|09|0A|00|
92dbd550edSchristos 	 *	          ^---------------------^
93dbd550edSchristos 	 *		 dst		 dst+length-1
94dbd550edSchristos 	 *
95dbd550edSchristos 	 * but we use a minimum of 3 here since the overhead of the code
96dbd550edSchristos 	 * to do word writes is substantial.
97dbd550edSchristos 	 */
98dbd550edSchristos 	if (length < 3 * wsize) {
99dbd550edSchristos 		while (length != 0) {
100dbd550edSchristos 			*dst++ = VAL;
101dbd550edSchristos 			--length;
102dbd550edSchristos 		}
103dbd550edSchristos 		RETURN;
104dbd550edSchristos 	}
105dbd550edSchristos 
106dbd550edSchristos #ifndef BZERO
107dbd550edSchristos 	if ((c = (u_char)c0) != 0) {	/* Fill the word. */
108dbd550edSchristos 		c = (c << 8) | c;	/* u_int is 16 bits. */
109dbd550edSchristos #if UINT_MAX > 0xffff
110dbd550edSchristos 		c = (c << 16) | c;	/* u_int is 32 bits. */
111dbd550edSchristos #endif
112dbd550edSchristos #if UINT_MAX > 0xffffffff
113dbd550edSchristos 		c = (c << 32) | c;	/* u_int is 64 bits. */
114dbd550edSchristos #endif
115dbd550edSchristos 	}
116dbd550edSchristos #endif
117dbd550edSchristos 	/* Align destination by filling in bytes. */
118dbd550edSchristos 	if ((t = (int)dst & wmask) != 0) {
119dbd550edSchristos 		t = wsize - t;
120dbd550edSchristos 		length -= t;
121dbd550edSchristos 		do {
122dbd550edSchristos 			*dst++ = VAL;
123dbd550edSchristos 		} while (--t != 0);
124dbd550edSchristos 	}
125dbd550edSchristos 
126dbd550edSchristos 	/* Fill words.  Length was >= 2*words so we know t >= 1 here. */
127dbd550edSchristos 	t = length / wsize;
128dbd550edSchristos 	do {
129dbd550edSchristos 		*(u_int *)dst = WIDEVAL;
130dbd550edSchristos 		dst += wsize;
131dbd550edSchristos 	} while (--t != 0);
132dbd550edSchristos 
133dbd550edSchristos 	/* Mop up trailing bytes, if any. */
134dbd550edSchristos 	t = length & wmask;
135dbd550edSchristos 	if (t != 0)
136dbd550edSchristos 		do {
137dbd550edSchristos 			*dst++ = VAL;
138dbd550edSchristos 		} while (--t != 0);
139dbd550edSchristos 	RETURN;
140dbd550edSchristos }
141