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