summaryrefslogtreecommitdiff
path: root/lib/libutils/isoc/newlib/memset.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libutils/isoc/newlib/memset.c')
-rw-r--r--lib/libutils/isoc/newlib/memset.c128
1 files changed, 128 insertions, 0 deletions
diff --git a/lib/libutils/isoc/newlib/memset.c b/lib/libutils/isoc/newlib/memset.c
new file mode 100644
index 0000000..09eca31
--- /dev/null
+++ b/lib/libutils/isoc/newlib/memset.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 1994-2009 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+FUNCTION
+ <<memset>>---set an area of memory
+
+INDEX
+ memset
+
+ANSI_SYNOPSIS
+ #include <string.h>
+ void *memset(void *<[dst]>, int <[c]>, size_t <[length]>);
+
+TRAD_SYNOPSIS
+ #include <string.h>
+ void *memset(<[dst]>, <[c]>, <[length]>)
+ void *<[dst]>;
+ int <[c]>;
+ size_t <[length]>;
+
+DESCRIPTION
+ This function converts the argument <[c]> into an unsigned
+ char and fills the first <[length]> characters of the array
+ pointed to by <[dst]> to the value.
+
+RETURNS
+ <<memset>> returns the value of <[dst]>.
+
+PORTABILITY
+<<memset>> is ANSI C.
+
+ <<memset>> requires no supporting OS subroutines.
+
+QUICKREF
+ memset ansi pure
+*/
+
+#include "_ansi.h"
+#include <string.h>
+
+#define LBLOCKSIZE (sizeof(long))
+#define UNALIGNED(X) ((long)X & (LBLOCKSIZE - 1))
+#define TOO_SMALL(LEN) ((LEN) < LBLOCKSIZE)
+
+_PTR _DEFUN(memset, (m, c, n), _PTR m _AND int c _AND size_t n)
+{
+ char *s = (char *)m;
+
+#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
+ int i;
+ unsigned long buffer;
+ unsigned long *aligned_addr;
+ unsigned int d = c & 0xff; /* To avoid sign extension, copy C to an
+ unsigned variable. */
+
+ while (UNALIGNED(s)) {
+ if (n--)
+ *s++ = (char)c;
+ else
+ return m;
+ }
+
+ if (!TOO_SMALL(n)) {
+ /*
+ * If we get this far, we know that n is large and s is
+ * word-aligned.
+ */
+ aligned_addr = (unsigned long *)s;
+
+ /* Store D into each char sized location in BUFFER so that
+ we can set large blocks quickly. */
+ buffer = (d << 8) | d;
+ buffer |= (buffer << 16);
+ for (i = 32; i < LBLOCKSIZE * 8; i <<= 1)
+ buffer = (buffer << i) | buffer;
+
+ /* Unroll the loop. */
+ while (n >= LBLOCKSIZE * 4) {
+ *aligned_addr++ = buffer;
+ *aligned_addr++ = buffer;
+ *aligned_addr++ = buffer;
+ *aligned_addr++ = buffer;
+ n -= 4 * LBLOCKSIZE;
+ }
+
+ while (n >= LBLOCKSIZE) {
+ *aligned_addr++ = buffer;
+ n -= LBLOCKSIZE;
+ }
+ /* Pick up the remainder with a bytewise loop. */
+ s = (char *)aligned_addr;
+ }
+#endif /* not PREFER_SIZE_OVER_SPEED */
+
+ while (n--)
+ *s++ = (char)c;
+
+ return m;
+}