diff options
Diffstat (limited to 'firmware/asm/memset.c')
-rw-r--r-- | firmware/asm/memset.c | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/firmware/asm/memset.c b/firmware/asm/memset.c new file mode 100644 index 0000000000..7b8d2137e8 --- /dev/null +++ b/firmware/asm/memset.c | |||
@@ -0,0 +1,110 @@ | |||
1 | /* | ||
2 | FUNCTION | ||
3 | <<memset>>---set an area of memory | ||
4 | |||
5 | INDEX | ||
6 | memset | ||
7 | |||
8 | ANSI_SYNOPSIS | ||
9 | #include <string.h> | ||
10 | void *memset(const void *<[dst]>, int <[c]>, size_t <[length]>); | ||
11 | |||
12 | TRAD_SYNOPSIS | ||
13 | #include <string.h> | ||
14 | void *memset(<[dst]>, <[c]>, <[length]>) | ||
15 | void *<[dst]>; | ||
16 | int <[c]>; | ||
17 | size_t <[length]>; | ||
18 | |||
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. | ||
23 | |||
24 | RETURNS | ||
25 | <<memset>> returns the value of <[m]>. | ||
26 | |||
27 | PORTABILITY | ||
28 | <<memset>> is ANSI C. | ||
29 | |||
30 | <<memset>> requires no supporting OS subroutines. | ||
31 | |||
32 | QUICKREF | ||
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 | } | ||