diff options
Diffstat (limited to 'libc/arch-x86/string/memset.S')
-rw-r--r-- | libc/arch-x86/string/memset.S | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/libc/arch-x86/string/memset.S b/libc/arch-x86/string/memset.S new file mode 100644 index 0000000..1059ccc --- /dev/null +++ b/libc/arch-x86/string/memset.S @@ -0,0 +1,55 @@ +/* $OpenBSD: memset.S,v 1.3 2005/08/07 11:30:38 espie Exp $ */ +/* + * Written by J.T. Conklin <jtc@netbsd.org>. + * Public domain. + */ + +#include <machine/asm.h> + +ENTRY(memset) + pushl %edi + pushl %ebx + movl 12(%esp),%edi + movzbl 16(%esp),%eax /* unsigned char, zero extend */ + movl 20(%esp),%ecx + pushl %edi /* push address of buffer */ + + cld /* set fill direction forward */ + + /* + * if the string is too short, it's really not worth the overhead + * of aligning to word boundries, etc. So we jump to a plain + * unaligned set. + */ + cmpl $0x0f,%ecx + jle L1 + + movb %al,%ah /* copy char to all bytes in word */ + movl %eax,%edx + sall $16,%eax + orl %edx,%eax + + movl %edi,%edx /* compute misalignment */ + negl %edx + andl $3,%edx + movl %ecx,%ebx + subl %edx,%ebx + + movl %edx,%ecx /* set until word aligned */ + rep + stosb + + movl %ebx,%ecx + shrl $2,%ecx /* set by words */ + rep + stosl + + movl %ebx,%ecx /* set remainder by bytes */ + andl $3,%ecx +L1: rep + stosb + + popl %eax /* pop address of buffer */ + popl %ebx + popl %edi + ret |