| 37 | */ |
| 38 | #ifndef RT_KLIBC_USING_USER_MEMSET |
| 39 | void *rt_memset(void *s, int c, rt_ubase_t count) |
| 40 | { |
| 41 | #if defined(RT_KLIBC_USING_LIBC_MEMSET) |
| 42 | return memset(s, c, count); |
| 43 | #elif defined(RT_KLIBC_USING_TINY_MEMSET) |
| 44 | char *xs = (char *)s; |
| 45 | |
| 46 | while (count--) |
| 47 | *xs++ = c; |
| 48 | |
| 49 | return s; |
| 50 | #else |
| 51 | |
| 52 | #define LBLOCKSIZE (sizeof(rt_ubase_t)) |
| 53 | #define UNALIGNED(X) ((long)X & (LBLOCKSIZE - 1)) |
| 54 | #define TOO_SMALL(LEN) ((LEN) < LBLOCKSIZE) |
| 55 | |
| 56 | unsigned int i = 0; |
| 57 | char *m = (char *)s; |
| 58 | unsigned long buffer = 0; |
| 59 | unsigned long *aligned_addr = RT_NULL; |
| 60 | unsigned char d = (unsigned int)c & (unsigned char)(-1); /* To avoid sign extension, copy C to an |
| 61 | unsigned variable. (unsigned)((char)(-1))=0xFF for 8bit and =0xFFFF for 16bit: word independent */ |
| 62 | |
| 63 | RT_ASSERT(LBLOCKSIZE == 2 || LBLOCKSIZE == 4 || LBLOCKSIZE == 8); |
| 64 | |
| 65 | if (!TOO_SMALL(count) && !UNALIGNED(s)) |
| 66 | { |
| 67 | /* If we get this far, we know that count is large and s is word-aligned. */ |
| 68 | aligned_addr = (unsigned long *)s; |
| 69 | |
| 70 | /* Store d into each char sized location in buffer so that |
| 71 | * we can set large blocks quickly. |
| 72 | */ |
| 73 | for (i = 0; i < LBLOCKSIZE; i++) |
| 74 | { |
| 75 | *(((unsigned char *)&buffer)+i) = d; |
| 76 | } |
| 77 | |
| 78 | while (count >= LBLOCKSIZE * 4) |
| 79 | { |
| 80 | *aligned_addr++ = buffer; |
| 81 | *aligned_addr++ = buffer; |
| 82 | *aligned_addr++ = buffer; |
| 83 | *aligned_addr++ = buffer; |
| 84 | count -= 4 * LBLOCKSIZE; |
| 85 | } |
| 86 | |
| 87 | while (count >= LBLOCKSIZE) |
| 88 | { |
| 89 | *aligned_addr++ = buffer; |
| 90 | count -= LBLOCKSIZE; |
| 91 | } |
| 92 | |
| 93 | /* Pick up the remainder with a bytewise loop. */ |
| 94 | m = (char *)aligned_addr; |
| 95 | } |
| 96 |
no outgoing calls