xref: /optee_os/lib/libutils/isoc/newlib/memset.c (revision b01047730e77127c23a36591643eeb8bb0487d68)
1*b0104773SPascal Brand /*
2*b0104773SPascal Brand  * Copyright (c) 1994-2009  Red Hat, Inc.
3*b0104773SPascal Brand  * All rights reserved.
4*b0104773SPascal Brand  *
5*b0104773SPascal Brand  * Redistribution and use in source and binary forms, with or without
6*b0104773SPascal Brand  * modification, are permitted provided that the following conditions are met:
7*b0104773SPascal Brand  *
8*b0104773SPascal Brand  * 1. Redistributions of source code must retain the above copyright notice,
9*b0104773SPascal Brand  * this list of conditions and the following disclaimer.
10*b0104773SPascal Brand  *
11*b0104773SPascal Brand  * 2. Redistributions in binary form must reproduce the above copyright notice,
12*b0104773SPascal Brand  * this list of conditions and the following disclaimer in the documentation
13*b0104773SPascal Brand  * and/or other materials provided with the distribution.
14*b0104773SPascal Brand  *
15*b0104773SPascal Brand  * 3. Neither the name of the copyright holder nor the names of its
16*b0104773SPascal Brand  * contributors may be used to endorse or promote products derived from this
17*b0104773SPascal Brand  * software without specific prior written permission.
18*b0104773SPascal Brand  *
19*b0104773SPascal Brand  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20*b0104773SPascal Brand  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21*b0104773SPascal Brand  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22*b0104773SPascal Brand  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23*b0104773SPascal Brand  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24*b0104773SPascal Brand  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25*b0104773SPascal Brand  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26*b0104773SPascal Brand  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27*b0104773SPascal Brand  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28*b0104773SPascal Brand  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29*b0104773SPascal Brand  * POSSIBILITY OF SUCH DAMAGE.
30*b0104773SPascal Brand  */
31*b0104773SPascal Brand 
32*b0104773SPascal Brand /*
33*b0104773SPascal Brand FUNCTION
34*b0104773SPascal Brand 	<<memset>>---set an area of memory
35*b0104773SPascal Brand 
36*b0104773SPascal Brand INDEX
37*b0104773SPascal Brand 	memset
38*b0104773SPascal Brand 
39*b0104773SPascal Brand ANSI_SYNOPSIS
40*b0104773SPascal Brand 	#include <string.h>
41*b0104773SPascal Brand 	void *memset(void *<[dst]>, int <[c]>, size_t <[length]>);
42*b0104773SPascal Brand 
43*b0104773SPascal Brand TRAD_SYNOPSIS
44*b0104773SPascal Brand 	#include <string.h>
45*b0104773SPascal Brand 	void *memset(<[dst]>, <[c]>, <[length]>)
46*b0104773SPascal Brand 	void *<[dst]>;
47*b0104773SPascal Brand 	int <[c]>;
48*b0104773SPascal Brand 	size_t <[length]>;
49*b0104773SPascal Brand 
50*b0104773SPascal Brand DESCRIPTION
51*b0104773SPascal Brand 	This function converts the argument <[c]> into an unsigned
52*b0104773SPascal Brand 	char and fills the first <[length]> characters of the array
53*b0104773SPascal Brand 	pointed to by <[dst]> to the value.
54*b0104773SPascal Brand 
55*b0104773SPascal Brand RETURNS
56*b0104773SPascal Brand 	<<memset>> returns the value of <[dst]>.
57*b0104773SPascal Brand 
58*b0104773SPascal Brand PORTABILITY
59*b0104773SPascal Brand <<memset>> is ANSI C.
60*b0104773SPascal Brand 
61*b0104773SPascal Brand     <<memset>> requires no supporting OS subroutines.
62*b0104773SPascal Brand 
63*b0104773SPascal Brand QUICKREF
64*b0104773SPascal Brand 	memset ansi pure
65*b0104773SPascal Brand */
66*b0104773SPascal Brand 
67*b0104773SPascal Brand #include "_ansi.h"
68*b0104773SPascal Brand #include <string.h>
69*b0104773SPascal Brand 
70*b0104773SPascal Brand #define LBLOCKSIZE (sizeof(long))
71*b0104773SPascal Brand #define UNALIGNED(X)   ((long)X & (LBLOCKSIZE - 1))
72*b0104773SPascal Brand #define TOO_SMALL(LEN) ((LEN) < LBLOCKSIZE)
73*b0104773SPascal Brand 
74*b0104773SPascal Brand _PTR _DEFUN(memset, (m, c, n), _PTR m _AND int c _AND size_t n)
75*b0104773SPascal Brand {
76*b0104773SPascal Brand 	char *s = (char *)m;
77*b0104773SPascal Brand 
78*b0104773SPascal Brand #if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
79*b0104773SPascal Brand 	int i;
80*b0104773SPascal Brand 	unsigned long buffer;
81*b0104773SPascal Brand 	unsigned long *aligned_addr;
82*b0104773SPascal Brand 	unsigned int d = c & 0xff;	/* To avoid sign extension, copy C to an
83*b0104773SPascal Brand 					   unsigned variable.  */
84*b0104773SPascal Brand 
85*b0104773SPascal Brand 	while (UNALIGNED(s)) {
86*b0104773SPascal Brand 		if (n--)
87*b0104773SPascal Brand 			*s++ = (char)c;
88*b0104773SPascal Brand 		else
89*b0104773SPascal Brand 			return m;
90*b0104773SPascal Brand 	}
91*b0104773SPascal Brand 
92*b0104773SPascal Brand 	if (!TOO_SMALL(n)) {
93*b0104773SPascal Brand 		/*
94*b0104773SPascal Brand 		 * If we get this far, we know that n is large and s is
95*b0104773SPascal Brand 		 * word-aligned.
96*b0104773SPascal Brand 		 */
97*b0104773SPascal Brand 		aligned_addr = (unsigned long *)s;
98*b0104773SPascal Brand 
99*b0104773SPascal Brand 		/* Store D into each char sized location in BUFFER so that
100*b0104773SPascal Brand 		   we can set large blocks quickly.  */
101*b0104773SPascal Brand 		buffer = (d << 8) | d;
102*b0104773SPascal Brand 		buffer |= (buffer << 16);
103*b0104773SPascal Brand 		for (i = 32; i < LBLOCKSIZE * 8; i <<= 1)
104*b0104773SPascal Brand 			buffer = (buffer << i) | buffer;
105*b0104773SPascal Brand 
106*b0104773SPascal Brand 		/* Unroll the loop.  */
107*b0104773SPascal Brand 		while (n >= LBLOCKSIZE * 4) {
108*b0104773SPascal Brand 			*aligned_addr++ = buffer;
109*b0104773SPascal Brand 			*aligned_addr++ = buffer;
110*b0104773SPascal Brand 			*aligned_addr++ = buffer;
111*b0104773SPascal Brand 			*aligned_addr++ = buffer;
112*b0104773SPascal Brand 			n -= 4 * LBLOCKSIZE;
113*b0104773SPascal Brand 		}
114*b0104773SPascal Brand 
115*b0104773SPascal Brand 		while (n >= LBLOCKSIZE) {
116*b0104773SPascal Brand 			*aligned_addr++ = buffer;
117*b0104773SPascal Brand 			n -= LBLOCKSIZE;
118*b0104773SPascal Brand 		}
119*b0104773SPascal Brand 		/* Pick up the remainder with a bytewise loop.  */
120*b0104773SPascal Brand 		s = (char *)aligned_addr;
121*b0104773SPascal Brand 	}
122*b0104773SPascal Brand #endif /* not PREFER_SIZE_OVER_SPEED */
123*b0104773SPascal Brand 
124*b0104773SPascal Brand 	while (n--)
125*b0104773SPascal Brand 		*s++ = (char)c;
126*b0104773SPascal Brand 
127*b0104773SPascal Brand 	return m;
128*b0104773SPascal Brand }
129