xref: /csrg-svn/lib/libc/string/memset.c (revision 61193)
141967Sbostic /*-
2*61193Sbostic  * Copyright (c) 1990, 1993
3*61193Sbostic  *	The Regents of the University of California.  All rights reserved.
434479Sbostic  *
541967Sbostic  * This code is derived from software contributed to Berkeley by
659959Sbostic  * Mike Hibler and Chris Torek.
741967Sbostic  *
841967Sbostic  * %sccs.include.redist.c%
924197Skre  */
1024197Skre 
1126529Sdonn #if defined(LIBC_SCCS) && !defined(lint)
12*61193Sbostic static char sccsid[] = "@(#)memset.c	8.1 (Berkeley) 06/04/93";
1334479Sbostic #endif /* LIBC_SCCS and not lint */
1424197Skre 
1559959Sbostic #include <sys/types.h>
1659959Sbostic 
1759959Sbostic #include <limits.h>
1841967Sbostic #include <string.h>
1941967Sbostic 
2059959Sbostic #define	wsize	sizeof(u_int)
2159959Sbostic #define	wmask	(wsize - 1)
2259959Sbostic 
2359960Sbostic #ifdef BZERO
2459983Sbostic #define	RETURN	return
2559983Sbostic #define	VAL	0
2659983Sbostic #define	WIDEVAL	0
2759983Sbostic 
2859960Sbostic void
bzero(dst0,length)2959960Sbostic bzero(dst0, length)
3059960Sbostic 	void *dst0;
3159960Sbostic 	register size_t length;
3259960Sbostic #else
3359983Sbostic #define	RETURN	return (dst0)
3459983Sbostic #define	VAL	c0
3559983Sbostic #define	WIDEVAL	c
3659983Sbostic 
3741967Sbostic void *
3859959Sbostic memset(dst0, c0, length)
3959959Sbostic 	void *dst0;
4059959Sbostic 	register int c0;
4159959Sbostic 	register size_t length;
4259960Sbostic #endif
4324197Skre {
4459959Sbostic 	register size_t t;
4559959Sbostic 	register u_int c;
4659960Sbostic 	register u_char *dst;
4724197Skre 
4859960Sbostic 	dst = dst0;
4959959Sbostic 	/*
5059959Sbostic 	 * If not enough words, just fill bytes.  A length >= 2 words
5159959Sbostic 	 * guarantees that at least one of them is `complete' after
5259959Sbostic 	 * any necessary alignment.  For instance:
5359959Sbostic 	 *
5459959Sbostic 	 *	|-----------|-----------|-----------|
5559959Sbostic 	 *	|00|01|02|03|04|05|06|07|08|09|0A|00|
5659959Sbostic 	 *	          ^---------------------^
5759959Sbostic 	 *		 dst		 dst+length-1
5859959Sbostic 	 *
5959959Sbostic 	 * but we use a minimum of 3 here since the overhead of the code
6059959Sbostic 	 * to do word writes is substantial.
6159959Sbostic 	 */
6259959Sbostic 	if (length < 3 * wsize) {
6359959Sbostic 		while (length != 0) {
6459983Sbostic 			*dst++ = VAL;
6559959Sbostic 			--length;
6659959Sbostic 		}
6759983Sbostic 		RETURN;
6859959Sbostic 	}
6924197Skre 
7059960Sbostic #ifndef BZERO
7159960Sbostic 	if ((c = (u_char)c0) != 0) {	/* Fill the word. */
7259959Sbostic 		c = (c << 8) | c;	/* u_int is 16 bits. */
7359960Sbostic #if UINT_MAX > 0xffff
7459959Sbostic 		c = (c << 16) | c;	/* u_int is 32 bits. */
7559959Sbostic #endif
7659960Sbostic #if UINT_MAX > 0xffffffff
7759959Sbostic 		c = (c << 32) | c;	/* u_int is 64 bits. */
7859959Sbostic #endif
7941967Sbostic 	}
8059960Sbostic #endif
8159959Sbostic 	/* Align destination by filling in bytes. */
8259959Sbostic 	if ((t = (int)dst & wmask) != 0) {
8359959Sbostic 		t = wsize - t;
8459959Sbostic 		length -= t;
8559959Sbostic 		do {
8659983Sbostic 			*dst++ = VAL;
8759959Sbostic 		} while (--t != 0);
8859959Sbostic 	}
8959959Sbostic 
9059959Sbostic 	/* Fill words.  Length was >= 2*words so we know t >= 1 here. */
9159959Sbostic 	t = length / wsize;
9259959Sbostic 	do {
9359983Sbostic 		*(u_int *)dst = WIDEVAL;
9459959Sbostic 		dst += wsize;
9559959Sbostic 	} while (--t != 0);
9659959Sbostic 
9759959Sbostic 	/* Mop up trailing bytes, if any. */
9859959Sbostic 	t = length & wmask;
9959959Sbostic 	if (t != 0)
10059959Sbostic 		do {
10159983Sbostic 			*dst++ = VAL;
10259959Sbostic 		} while (--t != 0);
10359983Sbostic 	RETURN;
10424197Skre }
105