comparison packages/infra/current/src/memset.c @ 0:3111d98ba7b3 ecos-v1_1-release

Initial commit of eCos version 1.1
author jlarmour
date Tue, 11 May 1999 11:16:07 +0000
parents
children 443894e2e912
comparison
equal deleted inserted replaced
-1:000000000000 0:3111d98ba7b3
1 /*===========================================================================
2 //
3 // memset.c
4 //
5 // ANSI standard memset() routine
6 //
7 //==========================================================================
8 //####COPYRIGHTBEGIN####
9 //
10 // -------------------------------------------
11 // The contents of this file are subject to the Cygnus eCos Public License
12 // Version 1.0 (the "License"); you may not use this file except in
13 // compliance with the License. You may obtain a copy of the License at
14 // http://sourceware.cygnus.com/ecos
15 //
16 // Software distributed under the License is distributed on an "AS IS"
17 // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
18 // License for the specific language governing rights and limitations under
19 // the License.
20 //
21 // The Original Code is eCos - Embedded Cygnus Operating System, released
22 // September 30, 1998.
23 //
24 // The Initial Developer of the Original Code is Cygnus. Portions created
25 // by Cygnus are Copyright (C) 1998 Cygnus Solutions. All Rights Reserved.
26 // -------------------------------------------
27 //
28 //####COPYRIGHTEND####
29 //==========================================================================
30 //#####DESCRIPTIONBEGIN####
31 //
32 // Author(s): jlarmour@cygnus.co.uk
33 // Contributors: jlarmour@cygnus.co.uk
34 // Date: 1998-06-04
35 // Purpose: This file implements the ANSI memset() function
36 // Description: This file implements the memset() function defined in ANSI para
37 // 7.11.6.1. This is implemented in the kernel rather than the
38 // C library due to it being required by gcc whether or not the
39 // C library has been configured in.
40 //
41 //####DESCRIPTIONEND####
42 //
43 //==========================================================================*/
44
45
46 /* INCLUDES */
47
48 #include <pkgconf/infra.h> /* Configuration of infra package */
49
50 #include <cyg/infra/cyg_type.h> /* Common type definitions */
51 #include <cyg/infra/cyg_trac.h> /* Tracing support */
52 #include <cyg/infra/cyg_ass.h> /* Assertion support */
53 #include <stddef.h> /* Compiler defns such as size_t, NULL etc. */
54
55 /* MACROS */
56
57 /* Nonzero if X is not aligned on a word boundary. */
58 #define CYG_STR_UNALIGNED(X) ((CYG_WORD)(X) & (sizeof (CYG_WORD) - 1))
59
60 /* How many bytes are copied each iteration of the word copy loop in the
61 * optimised string implementation
62 */
63 #define CYG_STR_OPT_LITTLEBLOCKSIZE (sizeof (CYG_WORD))
64
65 /* EXPORTED SYMBOLS */
66
67 externC void *
68 memset( void *s, int c, size_t n ) __attribute__ ((weak, alias("_memset")));
69
70 /* FUNCTIONS */
71
72 void *
73 _memset( void *s, int c, size_t n )
74 {
75 #if defined(CYGIMP_INFRA_PREFER_SMALL_TO_FAST_MEMSET) || defined(__OPTIMIZE_SIZE__)
76 char *char_ptr = (char *)s;
77
78 #ifdef CYG_TRACING_FIXED
79 CYG_REPORT_FUNCNAMETYPE( "_memset", "returning %08x" );
80 CYG_REPORT_FUNCARG3( "s=%08x, c=%d, n=%d", s, c, n );
81
82 if (n != 0)
83 {
84 CYG_CHECK_DATA_PTR( s, "s is not a valid pointer!" );
85 CYG_CHECK_DATA_PTR( s+n-1, "s+n-1 is not a valid address!" );
86 }
87 #endif
88
89 while (n-- != 0)
90 {
91 *char_ptr++ = (char) c;
92 }
93
94 #ifdef CYG_TRACING_FIXED
95 CYG_REPORT_RETVAL( s );
96 #endif
97 return s;
98 #else
99 char *char_ptr = (char *)s;
100 cyg_ucount8 count;
101 CYG_WORD buffer;
102 CYG_WORD *aligned_addr;
103 char *unaligned_addr;
104
105 #ifdef CYG_TRACING_FIXED
106 CYG_REPORT_FUNCNAMETYPE( "_memset", "returning %08x" );
107 CYG_REPORT_FUNCARG3( "s=%08x, c=%d, n=%d", s, c, n );
108
109 if (n != 0)
110 {
111 CYG_CHECK_DATA_PTR( s, "s is not a valid pointer!" );
112 CYG_CHECK_DATA_PTR( (char *)s+n-1, "s+n-1 is not a valid address!" );
113 }
114 #endif
115
116 if (n < sizeof(CYG_WORD) || CYG_STR_UNALIGNED (s))
117 {
118 while (n-- != 0)
119 {
120 *char_ptr++ = (char) c;
121 }
122 #ifdef CYG_TRACING_FIXED
123 CYG_REPORT_RETVAL( s );
124 #endif
125 return s;
126 }
127
128 /* If we get this far, we know that n is large and s is word-aligned. */
129
130 aligned_addr = (CYG_WORD *)s;
131
132 /* Store C into each char sized location in BUFFER so that
133 * we can set large blocks quickly.
134 */
135 c &= 0xff;
136 if (CYG_STR_OPT_LITTLEBLOCKSIZE == 4)
137 {
138 buffer = (c << 8) | c;
139 buffer |= (buffer << 16);
140 }
141 else
142 {
143 buffer = 0;
144 for (count = 0; count < CYG_STR_OPT_LITTLEBLOCKSIZE; count++)
145 buffer = (buffer << 8) | c;
146 }
147
148 while (n >= CYG_STR_OPT_LITTLEBLOCKSIZE*4)
149 {
150 *aligned_addr++ = buffer;
151 *aligned_addr++ = buffer;
152 *aligned_addr++ = buffer;
153 *aligned_addr++ = buffer;
154 n -= 4*CYG_STR_OPT_LITTLEBLOCKSIZE;
155 }
156
157 while (n >= CYG_STR_OPT_LITTLEBLOCKSIZE)
158 {
159 *aligned_addr++ = buffer;
160 n -= CYG_STR_OPT_LITTLEBLOCKSIZE;
161 }
162
163 /* Pick up the remainder with a bytewise loop. */
164 unaligned_addr = (char*)aligned_addr;
165 while (n)
166 {
167 *unaligned_addr++ = (char)c;
168 n--;
169 }
170
171 #ifdef CYG_TRACING_FIXED
172 CYG_REPORT_RETVAL( s );
173 #endif
174 return s;
175 #endif /* not defined(CYGIMP_PREFER_SMALL_TO_FAST_MEMSET) ||
176 * defined(__OPTIMIZE_SIZE__) */
177 } /* _memset() */
178
179 /* EOF memset.c */