xref: /csrg-svn/lib/libc/string/memset.c (revision 59959)
141967Sbostic /*-
241967Sbostic  * Copyright (c) 1990 The Regents of the University of California.
334479Sbostic  * All rights reserved.
434479Sbostic  *
541967Sbostic  * This code is derived from software contributed to Berkeley by
6*59959Sbostic  * Mike Hibler and Chris Torek.
741967Sbostic  *
841967Sbostic  * %sccs.include.redist.c%
924197Skre  */
1024197Skre 
1126529Sdonn #if defined(LIBC_SCCS) && !defined(lint)
12*59959Sbostic static char sccsid[] = "@(#)memset.c	5.7 (Berkeley) 05/12/93";
1334479Sbostic #endif /* LIBC_SCCS and not lint */
1424197Skre 
15*59959Sbostic #include <sys/types.h>
16*59959Sbostic 
17*59959Sbostic #include <limits.h>
1841967Sbostic #include <string.h>
1941967Sbostic 
20*59959Sbostic #define	wsize	sizeof(u_int)
21*59959Sbostic #define	wmask	(wsize - 1)
22*59959Sbostic 
2341967Sbostic void *
24*59959Sbostic memset(dst0, c0, length)
25*59959Sbostic 	void *dst0;
26*59959Sbostic 	register int c0;
27*59959Sbostic 	register size_t length;
2824197Skre {
29*59959Sbostic 	register size_t t;
30*59959Sbostic 	register u_int c;
31*59959Sbostic 	register char *dst;
3224197Skre 
33*59959Sbostic 	dst = (char *)dst0;
34*59959Sbostic 	/*
35*59959Sbostic 	 * If not enough words, just fill bytes.  A length >= 2 words
36*59959Sbostic 	 * guarantees that at least one of them is `complete' after
37*59959Sbostic 	 * any necessary alignment.  For instance:
38*59959Sbostic 	 *
39*59959Sbostic 	 *	|-----------|-----------|-----------|
40*59959Sbostic 	 *	|00|01|02|03|04|05|06|07|08|09|0A|00|
41*59959Sbostic 	 *	          ^---------------------^
42*59959Sbostic 	 *		 dst		 dst+length-1
43*59959Sbostic 	 *
44*59959Sbostic 	 * but we use a minimum of 3 here since the overhead of the code
45*59959Sbostic 	 * to do word writes is substantial.
46*59959Sbostic 	 */
47*59959Sbostic 	if (length < 3 * wsize) {
48*59959Sbostic 		while (length != 0) {
49*59959Sbostic 			*dst++ = c0;
50*59959Sbostic 			--length;
51*59959Sbostic 		}
52*59959Sbostic 		return (dst0);
53*59959Sbostic 	}
5424197Skre 
55*59959Sbostic 	if ((c = (u_char)c0) != 0) {	/* Copy value into the word. */
56*59959Sbostic 		c = (c << 8) | c;	/* u_int is 16 bits. */
57*59959Sbostic #if UINT_MAX > 65535
58*59959Sbostic 		c = (c << 16) | c;	/* u_int is 32 bits. */
59*59959Sbostic #endif
60*59959Sbostic #if UINT_MAX > 0xffffffff		/* GCC will bitch, otherwise. */
61*59959Sbostic 		c = (c << 32) | c;	/* u_int is 64 bits. */
62*59959Sbostic #endif
6341967Sbostic 	}
64*59959Sbostic 
65*59959Sbostic 	/* Align destination by filling in bytes. */
66*59959Sbostic 	if ((t = (int)dst & wmask) != 0) {
67*59959Sbostic 		t = wsize - t;
68*59959Sbostic 		length -= t;
69*59959Sbostic 		do {
70*59959Sbostic 			*dst++ = c0;
71*59959Sbostic 		} while (--t != 0);
72*59959Sbostic 	}
73*59959Sbostic 
74*59959Sbostic 	/* Fill words.  Length was >= 2*words so we know t >= 1 here. */
75*59959Sbostic 	t = length / wsize;
76*59959Sbostic 	do {
77*59959Sbostic 		*(u_int *)dst = c;
78*59959Sbostic 		dst += wsize;
79*59959Sbostic 	} while (--t != 0);
80*59959Sbostic 
81*59959Sbostic 	/* Mop up trailing bytes, if any. */
82*59959Sbostic 	t = length & wmask;
83*59959Sbostic 	if (t != 0)
84*59959Sbostic 		do {
85*59959Sbostic 			*dst++ = c0;
86*59959Sbostic 		} while (--t != 0);
87*59959Sbostic 	return (dst0);
8824197Skre }
89