sdk-hwV1.3/lichee/brandy-2.0/spl/common/memset_sunxi.c

59 lines
1.2 KiB
C
Raw Normal View History

2024-05-07 10:09:20 +00:00
#include <common.h>
#define LBLOCKSIZE (sizeof(long))
#define UNALIGNED(X) ((long)X & (LBLOCKSIZE - 1))
#define TOO_SMALL(LEN) ((LEN) < LBLOCKSIZE)
void* memset(void *m, int c, size_t n)
{
char *s = (char *)m;
int i;
unsigned long buffer;
unsigned long *aligned_addr;
unsigned int d = c & 0xff; /* To avoid sign extension, copy C to an
unsigned variable. */
while (UNALIGNED(s)) {
if (n--)
*s++ = (char)c;
else
return m;
}
if (!TOO_SMALL(n)) {
/*
* If we get this far, we know that n is large and s is
* word-aligned.
*/
aligned_addr = (unsigned long *)s;
/* Store D into each char sized location in BUFFER so that
we can set large blocks quickly. */
buffer = (d << 8) | d;
buffer |= (buffer << 16);
for (i = 32; i < LBLOCKSIZE * 8; i <<= 1)
buffer = (buffer << i) | buffer;
/* Unroll the loop. */
while (n >= LBLOCKSIZE * 4) {
*aligned_addr++ = buffer;
*aligned_addr++ = buffer;
*aligned_addr++ = buffer;
*aligned_addr++ = buffer;
n -= 4 * LBLOCKSIZE;
}
while (n >= LBLOCKSIZE) {
*aligned_addr++ = buffer;
n -= LBLOCKSIZE;
}
/* Pick up the remainder with a bytewise loop. */
s = (char *)aligned_addr;
}
while (n--)
*s++ = (char)c;
return m;
}