summaryrefslogtreecommitdiff
path: root/firmware/libc/memset.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/libc/memset.c')
-rw-r--r--firmware/libc/memset.c110
1 files changed, 110 insertions, 0 deletions
diff --git a/firmware/libc/memset.c b/firmware/libc/memset.c
new file mode 100644
index 0000000000..7b8d2137e8
--- /dev/null
+++ b/firmware/libc/memset.c
@@ -0,0 +1,110 @@
1/*
2FUNCTION
3 <<memset>>---set an area of memory
4
5INDEX
6 memset
7
8ANSI_SYNOPSIS
9 #include <string.h>
10 void *memset(const void *<[dst]>, int <[c]>, size_t <[length]>);
11
12TRAD_SYNOPSIS
13 #include <string.h>
14 void *memset(<[dst]>, <[c]>, <[length]>)
15 void *<[dst]>;
16 int <[c]>;
17 size_t <[length]>;
18
19DESCRIPTION
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.
23
24RETURNS
25 <<memset>> returns the value of <[m]>.
26
27PORTABILITY
28<<memset>> is ANSI C.
29
30 <<memset>> requires no supporting OS subroutines.
31
32QUICKREF
33 memset ansi pure
34*/
35
36#include <string.h>
37#include "_ansi.h"
38
39#define LBLOCKSIZE (sizeof(long))
40#define UNALIGNED(X) ((long)X & (LBLOCKSIZE - 1))
41#define TOO_SMALL(LEN) ((LEN) < LBLOCKSIZE)
42
43_PTR
44_DEFUN (memset, (m, c, n),
45 _PTR m _AND
46 int c _AND
47 size_t n)
48{
49#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
50 char *s = (char *) m;
51
52 while (n-- != 0)
53 {
54 *s++ = (char) c;
55 }
56
57 return m;
58#else
59 char *s = (char *) m;
60 unsigned int i;
61 unsigned long buffer;
62 unsigned long *aligned_addr;
63
64 if (!TOO_SMALL (n) && !UNALIGNED (m))
65 {
66 /* If we get this far, we know that n is large and m is word-aligned. */
67
68 aligned_addr = (unsigned long*)m;
69
70 /* Store C into each char sized location in BUFFER so that
71 we can set large blocks quickly. */
72 c &= 0xff;
73 if (LBLOCKSIZE == 4)
74 {
75 buffer = (c << 8) | c;
76 buffer |= (buffer << 16);
77 }
78 else
79 {
80 buffer = 0;
81 for (i = 0; i < LBLOCKSIZE; i++)
82 buffer = (buffer << 8) | c;
83 }
84
85 while (n >= LBLOCKSIZE*4)
86 {
87 *aligned_addr++ = buffer;
88 *aligned_addr++ = buffer;
89 *aligned_addr++ = buffer;
90 *aligned_addr++ = buffer;
91 n -= 4*LBLOCKSIZE;
92 }
93
94 while (n >= LBLOCKSIZE)
95 {
96 *aligned_addr++ = buffer;
97 n -= LBLOCKSIZE;
98 }
99 /* Pick up the remainder with a bytewise loop. */
100 s = (char*)aligned_addr;
101 }
102
103 while (n--)
104 {
105 *s++ = (char)c;
106 }
107
108 return m;
109#endif /* not PREFER_SIZE_OVER_SPEED */
110}