Merge commit '1276d1e1a1b128f7093a3021d3f6bc27afa80d23' into amd64
[dragonfly.git] / lib / libc / amd64 / string / memset.S
1 /*
2  * Written by J.T. Conklin <jtc@NetBSD.org>.
3  * Public domain.
4  * Adapted for NetBSD/x86_64 by Frank van der Linden <fvdl@wasabisystems.com>
5  *
6  * $NetBSD: memset.S,v 1.3 2004/02/26 20:50:06 drochner Exp $
7  * $FreeBSD: src/lib/libc/amd64/string/memset.S,v 1.2 2008/11/02 01:10:54 peter Exp $
8  */
9
10 #include <machine/asm.h>
11
12 ENTRY(memset)
13         movq    %rsi,%rax
14         andq    $0xff,%rax
15         movq    %rdx,%rcx
16         movq    %rdi,%r11
17
18         cld                             /* set fill direction forward */
19
20         /*
21          * if the string is too short, it's really not worth the overhead
22          * of aligning to word boundries, etc.  So we jump to a plain
23          * unaligned set.
24          */
25         cmpq    $0x0f,%rcx
26         jle     L1
27
28         movb    %al,%ah                 /* copy char to all bytes in word */
29         movl    %eax,%edx
30         sall    $16,%eax
31         orl     %edx,%eax
32
33         movl    %eax,%edx
34         salq    $32,%rax
35         orq     %rdx,%rax
36
37         movq    %rdi,%rdx               /* compute misalignment */
38         negq    %rdx
39         andq    $7,%rdx
40         movq    %rcx,%r8
41         subq    %rdx,%r8
42
43         movq    %rdx,%rcx               /* set until word aligned */
44         rep
45         stosb
46
47         movq    %r8,%rcx
48         shrq    $3,%rcx                 /* set by words */
49         rep
50         stosq
51
52         movq    %r8,%rcx                /* set remainder by bytes */
53         andq    $7,%rcx
54 L1:     rep
55         stosb
56         movq    %r11,%rax
57
58         ret
59 END(memset)