diff options
author | Jens Arnold <amiconn@rockbox.org> | 2006-02-22 01:20:45 +0000 |
---|---|---|
committer | Jens Arnold <amiconn@rockbox.org> | 2006-02-22 01:20:45 +0000 |
commit | eb65f89f0e1b88e3d7576eee3e490c007d02076d (patch) | |
tree | 7415e87f06bc131f362e69d2e25cd0e625d48841 /firmware/common/memset16.c | |
parent | a875703e6e0e26cfd4dfd74d56a7d28feb37bdc5 (diff) | |
download | rockbox-eb65f89f0e1b88e3d7576eee3e490c007d02076d.tar.gz rockbox-eb65f89f0e1b88e3d7576eee3e490c007d02076d.zip |
Added memset16() for filling memory regions with 16 bit values, needed for upcoming 16 bit LCD driver opts. ASM optimised for coldfire.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8773 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/common/memset16.c')
-rwxr-xr-x | firmware/common/memset16.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/firmware/common/memset16.c b/firmware/common/memset16.c new file mode 100755 index 0000000000..0aee97a169 --- /dev/null +++ b/firmware/common/memset16.c @@ -0,0 +1,79 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2006 by Jens Arnold + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include <string.h> +#define LBLOCKSIZE (sizeof(long)/2) +#define UNALIGNED(X) ((long)X & (LBLOCKSIZE - 1)) +#define TOO_SMALL(LEN) ((LEN) < LBLOCKSIZE) + +void *memset16(void *dst, int val, size_t len) +{ +#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__) + unsigned short *p = (unsigned short *)dst; + + while (len--) + *p++ = val; + + return dst; +#else + unsigned short *p = (unsigned short *)dst; + unsigned int i; + unsigned long buffer; + unsigned long *aligned_addr; + + if (!TOO_SMALL(len) && !UNALIGNED(dst)) + { + aligned_addr = (unsigned long *)dst; + + val &= 0xffff; + if (LBLOCKSIZE == 2) + { + buffer = (val << 16) | val; + } + else + { + buffer = 0; + for (i = 0; i < LBLOCKSIZE; i++) + buffer = (buffer << 16) | val; + } + + while (len >= LBLOCKSIZE*4) + { + *aligned_addr++ = buffer; + *aligned_addr++ = buffer; + *aligned_addr++ = buffer; + *aligned_addr++ = buffer; + len -= 4*LBLOCKSIZE; + } + + while (len >= LBLOCKSIZE) + { + *aligned_addr++ = buffer; + len -= LBLOCKSIZE; + } + + p = (unsigned short *)aligned_addr; + } + + while (len--) + *p++ = val; + + return dst; +#endif /* not PREFER_SIZE_OVER_SPEED */ +} |