fixes for host gcc 4.6.1
[zpugcc/jano.git] / toolchain / gcc / newlib / libc / string / memset.c
blobac3590ea49f034942eb45fd5378328c375eb0a1f
1 /*
2 FUNCTION
3 <<memset>>---set an area of memory
5 INDEX
6 memset
8 ANSI_SYNOPSIS
9 #include <string.h>
10 void *memset(const void *<[dst]>, int <[c]>, size_t <[length]>);
12 TRAD_SYNOPSIS
13 #include <string.h>
14 void *memset(<[dst]>, <[c]>, <[length]>)
15 void *<[dst]>;
16 int <[c]>;
17 size_t <[length]>;
19 DESCRIPTION
20 This function converts the argument <[c]> into an unsigned
21 char and fills the first <[length]> characters of the array
22 pointed to by <[dst]> to the value.
24 RETURNS
25 <<memset>> returns the value of <[m]>.
27 PORTABILITY
28 <<memset>> is ANSI C.
30 <<memset>> requires no supporting OS subroutines.
32 QUICKREF
33 memset ansi pure
36 #include <string.h>
38 #define LBLOCKSIZE (sizeof(long))
39 #define UNALIGNED(X) ((long)X & (LBLOCKSIZE - 1))
40 #define TOO_SMALL(LEN) ((LEN) < LBLOCKSIZE)
42 _PTR
43 _DEFUN (memset, (m, c, n),
44 _PTR m _AND
45 int c _AND
46 size_t n)
48 #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
49 char *s = (char *) m;
51 while (n-- != 0)
53 *s++ = (char) c;
56 return m;
57 #else
58 char *s = (char *) m;
59 int i;
60 unsigned long buffer;
61 unsigned long *aligned_addr;
62 unsigned int d = c & 0xff; /* To avoid sign extension, copy C to an
63 unsigned variable. */
65 if (!TOO_SMALL (n) && !UNALIGNED (m))
67 /* If we get this far, we know that n is large and m is word-aligned. */
68 aligned_addr = (unsigned long*)m;
70 /* Store D into each char sized location in BUFFER so that
71 we can set large blocks quickly. */
72 if (LBLOCKSIZE == 4)
74 buffer = (d << 8) | d;
75 buffer |= (buffer << 16);
77 else
79 buffer = 0;
80 for (i = 0; i < LBLOCKSIZE; i++)
81 buffer = (buffer << 8) | d;
84 while (n >= LBLOCKSIZE*4)
86 *aligned_addr++ = buffer;
87 *aligned_addr++ = buffer;
88 *aligned_addr++ = buffer;
89 *aligned_addr++ = buffer;
90 n -= 4*LBLOCKSIZE;
93 while (n >= LBLOCKSIZE)
95 *aligned_addr++ = buffer;
96 n -= LBLOCKSIZE;
98 /* Pick up the remainder with a bytewise loop. */
99 s = (char*)aligned_addr;
102 while (n--)
104 *s++ = (char)d;
107 return m;
108 #endif /* not PREFER_SIZE_OVER_SPEED */