Mercurial > flash_v2
annotate packages/infra/current/src/memset.c @ 210:d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
| author | jlarmour |
|---|---|
| date | Thu, 23 May 2002 22:59:51 +0000 |
| parents | e0c0827131d1 |
| children |
| rev | line source |
|---|---|
| 0 | 1 /*=========================================================================== |
| 2 // | |
| 3 // memset.c | |
| 4 // | |
| 5 // ANSI standard memset() routine | |
| 6 // | |
| 7 //========================================================================== | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
8 //####ECOSGPLCOPYRIGHTBEGIN#### |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
9 // ------------------------------------------- |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
10 // This file is part of eCos, the Embedded Configurable Operating System. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
12 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
13 // eCos is free software; you can redistribute it and/or modify it under |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
14 // the terms of the GNU General Public License as published by the Free |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
15 // Software Foundation; either version 2 or (at your option) any later version. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
16 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
19 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
20 // for more details. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
21 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
22 // You should have received a copy of the GNU General Public License along |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
23 // with eCos; if not, write to the Free Software Foundation, Inc., |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
25 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
26 // As a special exception, if other files instantiate templates or use macros |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
27 // or inline functions from this file, or you compile this file and link it |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
28 // with other works to produce a work based on this file, this file does not |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
29 // by itself cause the resulting work to be covered by the GNU General Public |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
30 // License. However the source code for this file must still be made available |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
31 // in accordance with section (3) of the GNU General Public License. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
32 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
33 // This exception does not invalidate any other reasons why a work based on |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
34 // this file might be covered by the GNU General Public License. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
35 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
|
210
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
37 // at http://sources.redhat.com/ecos/ecos-license/ |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
38 // ------------------------------------------- |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
39 //####ECOSGPLCOPYRIGHTEND#### |
| 0 | 40 //========================================================================== |
| 41 //#####DESCRIPTIONBEGIN#### | |
| 42 // | |
| 2 | 43 // Author(s): jlarmour |
| 44 // Contributors: jlarmour | |
| 0 | 45 // Date: 1998-06-04 |
| 46 // Purpose: This file implements the ANSI memset() function | |
| 47 // Description: This file implements the memset() function defined in ANSI para | |
| 48 // 7.11.6.1. This is implemented in the kernel rather than the | |
| 49 // C library due to it being required by gcc whether or not the | |
| 50 // C library has been configured in. | |
| 51 // | |
| 52 //####DESCRIPTIONEND#### | |
| 53 // | |
| 54 //==========================================================================*/ | |
| 55 | |
| 56 | |
| 57 /* INCLUDES */ | |
| 58 | |
| 59 #include <pkgconf/infra.h> /* Configuration of infra package */ | |
| 60 | |
| 61 #include <cyg/infra/cyg_type.h> /* Common type definitions */ | |
| 62 #include <cyg/infra/cyg_trac.h> /* Tracing support */ | |
| 63 #include <cyg/infra/cyg_ass.h> /* Assertion support */ | |
| 64 #include <stddef.h> /* Compiler defns such as size_t, NULL etc. */ | |
| 65 | |
| 66 /* MACROS */ | |
| 67 | |
| 68 /* Nonzero if X is not aligned on a word boundary. */ | |
| 69 #define CYG_STR_UNALIGNED(X) ((CYG_WORD)(X) & (sizeof (CYG_WORD) - 1)) | |
| 70 | |
| 71 /* How many bytes are copied each iteration of the word copy loop in the | |
| 72 * optimised string implementation | |
| 73 */ | |
| 74 #define CYG_STR_OPT_LITTLEBLOCKSIZE (sizeof (CYG_WORD)) | |
| 75 | |
| 76 /* EXPORTED SYMBOLS */ | |
| 77 | |
| 78 externC void * | |
| 79 memset( void *s, int c, size_t n ) __attribute__ ((weak, alias("_memset"))); | |
| 80 | |
| 81 /* FUNCTIONS */ | |
| 82 | |
| 83 void * | |
| 84 _memset( void *s, int c, size_t n ) | |
| 85 { | |
| 86 #if defined(CYGIMP_INFRA_PREFER_SMALL_TO_FAST_MEMSET) || defined(__OPTIMIZE_SIZE__) | |
| 87 char *char_ptr = (char *)s; | |
| 88 | |
| 89 #ifdef CYG_TRACING_FIXED | |
| 90 CYG_REPORT_FUNCNAMETYPE( "_memset", "returning %08x" ); | |
| 91 CYG_REPORT_FUNCARG3( "s=%08x, c=%d, n=%d", s, c, n ); | |
| 92 | |
| 93 if (n != 0) | |
| 94 { | |
| 2 | 95 CYG_CHECK_DATA_PTR( char_ptr, "s is not a valid pointer!" ); |
| 96 CYG_CHECK_DATA_PTR( (&char_ptr[n-1]), "s+n-1 is not a valid address!" ); | |
| 0 | 97 } |
| 98 #endif | |
| 99 | |
| 100 while (n-- != 0) | |
| 101 { | |
| 102 *char_ptr++ = (char) c; | |
| 103 } | |
| 104 | |
| 105 #ifdef CYG_TRACING_FIXED | |
| 106 CYG_REPORT_RETVAL( s ); | |
| 107 #endif | |
| 108 return s; | |
| 109 #else | |
| 110 char *char_ptr = (char *)s; | |
| 111 cyg_ucount8 count; | |
| 112 CYG_WORD buffer; | |
| 113 CYG_WORD *aligned_addr; | |
| 114 char *unaligned_addr; | |
| 115 | |
| 116 #ifdef CYG_TRACING_FIXED | |
| 117 CYG_REPORT_FUNCNAMETYPE( "_memset", "returning %08x" ); | |
| 118 CYG_REPORT_FUNCARG3( "s=%08x, c=%d, n=%d", s, c, n ); | |
| 119 | |
| 120 if (n != 0) | |
| 121 { | |
| 122 CYG_CHECK_DATA_PTR( s, "s is not a valid pointer!" ); | |
| 123 CYG_CHECK_DATA_PTR( (char *)s+n-1, "s+n-1 is not a valid address!" ); | |
| 124 } | |
| 125 #endif | |
| 126 | |
| 127 if (n < sizeof(CYG_WORD) || CYG_STR_UNALIGNED (s)) | |
| 128 { | |
| 129 while (n-- != 0) | |
| 130 { | |
| 131 *char_ptr++ = (char) c; | |
| 132 } | |
| 133 #ifdef CYG_TRACING_FIXED | |
| 134 CYG_REPORT_RETVAL( s ); | |
| 135 #endif | |
| 136 return s; | |
| 137 } | |
| 138 | |
| 139 /* If we get this far, we know that n is large and s is word-aligned. */ | |
| 140 | |
| 141 aligned_addr = (CYG_WORD *)s; | |
| 142 | |
| 143 /* Store C into each char sized location in BUFFER so that | |
| 144 * we can set large blocks quickly. | |
| 145 */ | |
| 146 c &= 0xff; | |
| 147 if (CYG_STR_OPT_LITTLEBLOCKSIZE == 4) | |
| 148 { | |
| 149 buffer = (c << 8) | c; | |
| 150 buffer |= (buffer << 16); | |
| 151 } | |
| 152 else | |
| 153 { | |
| 154 buffer = 0; | |
| 155 for (count = 0; count < CYG_STR_OPT_LITTLEBLOCKSIZE; count++) | |
| 156 buffer = (buffer << 8) | c; | |
| 157 } | |
| 158 | |
| 159 while (n >= CYG_STR_OPT_LITTLEBLOCKSIZE*4) | |
| 160 { | |
| 161 *aligned_addr++ = buffer; | |
| 162 *aligned_addr++ = buffer; | |
| 163 *aligned_addr++ = buffer; | |
| 164 *aligned_addr++ = buffer; | |
| 165 n -= 4*CYG_STR_OPT_LITTLEBLOCKSIZE; | |
| 166 } | |
| 167 | |
| 168 while (n >= CYG_STR_OPT_LITTLEBLOCKSIZE) | |
| 169 { | |
| 170 *aligned_addr++ = buffer; | |
| 171 n -= CYG_STR_OPT_LITTLEBLOCKSIZE; | |
| 172 } | |
| 173 | |
| 174 /* Pick up the remainder with a bytewise loop. */ | |
| 175 unaligned_addr = (char*)aligned_addr; | |
| 176 while (n) | |
| 177 { | |
| 178 *unaligned_addr++ = (char)c; | |
| 179 n--; | |
| 180 } | |
| 181 | |
| 182 #ifdef CYG_TRACING_FIXED | |
| 183 CYG_REPORT_RETVAL( s ); | |
| 184 #endif | |
| 185 return s; | |
| 186 #endif /* not defined(CYGIMP_PREFER_SMALL_TO_FAST_MEMSET) || | |
| 187 * defined(__OPTIMIZE_SIZE__) */ | |
| 188 } /* _memset() */ | |
| 189 | |
| 190 /* EOF memset.c */ |
