Cygwin: mmap: allow remapping part of an existing anonymous mapping
[newlib-cygwin.git] / newlib / libc / string / memset.c
blobe8e667a241baf54ce40cfa2f424135a6bd5c4eaf
1 /*
2 FUNCTION
3 <<memset>>---set an area of memory
5 INDEX
6 memset
8 SYNOPSIS
9 #include <string.h>
10 void *memset(void *<[dst]>, int <[c]>, size_t <[length]>);
12 DESCRIPTION
13 This function converts the argument <[c]> into an unsigned
14 char and fills the first <[length]> characters of the array
15 pointed to by <[dst]> to the value.
17 RETURNS
18 <<memset>> returns the value of <[dst]>.
20 PORTABILITY
21 <<memset>> is ANSI C.
23 <<memset>> requires no supporting OS subroutines.
25 QUICKREF
26 memset ansi pure
29 #include <string.h>
30 #include "local.h"
32 #define LBLOCKSIZE (sizeof(long))
33 #define UNALIGNED(X) ((long)X & (LBLOCKSIZE - 1))
34 #define TOO_SMALL(LEN) ((LEN) < LBLOCKSIZE)
36 void *
37 __inhibit_loop_to_libcall
38 memset (void *m,
39 int c,
40 size_t n)
42 char *s = (char *) m;
44 #if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
45 unsigned int i;
46 unsigned long buffer;
47 unsigned long *aligned_addr;
48 unsigned int d = c & 0xff; /* To avoid sign extension, copy C to an
49 unsigned variable. */
51 while (UNALIGNED (s))
53 if (n--)
54 *s++ = (char) c;
55 else
56 return m;
59 if (!TOO_SMALL (n))
61 /* If we get this far, we know that n is large and s is word-aligned. */
62 aligned_addr = (unsigned long *) s;
64 /* Store D into each char sized location in BUFFER so that
65 we can set large blocks quickly. */
66 buffer = (d << 8) | d;
67 buffer |= (buffer << 16);
68 for (i = 32; i < LBLOCKSIZE * 8; i <<= 1)
69 buffer = (buffer << i) | buffer;
71 /* Unroll the loop. */
72 while (n >= LBLOCKSIZE*4)
74 *aligned_addr++ = buffer;
75 *aligned_addr++ = buffer;
76 *aligned_addr++ = buffer;
77 *aligned_addr++ = buffer;
78 n -= 4*LBLOCKSIZE;
81 while (n >= LBLOCKSIZE)
83 *aligned_addr++ = buffer;
84 n -= LBLOCKSIZE;
86 /* Pick up the remainder with a bytewise loop. */
87 s = (char*)aligned_addr;
90 #endif /* not PREFER_SIZE_OVER_SPEED */
92 while (n--)
93 *s++ = (char) c;
95 return m;