xref: /freebsd/lib/libc/amd64/string/memset.S (revision e0c4386e)
1/*-
2 * Copyright (c) 2018 The FreeBSD Foundation
3 *
4 * This software was developed by Mateusz Guzik <mjg@FreeBSD.org>
5 * under sponsorship from the FreeBSD Foundation.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#include <machine/asm.h>
30/*
31 * Note: this routine was written with kernel use in mind (read: no simd),
32 * it is only present in userspace as a temporary measure until something
33 * better gets imported.
34 */
35
36#define ALIGN_TEXT      .p2align 4,0x90 /* 16-byte alignment, nop filled */
37
38.macro MEMSET erms
39	movq	%rdi,%rax
40	movq	%rdx,%rcx
41	movzbq	%sil,%r8
42	movabs	$0x0101010101010101,%r10
43	imulq	%r8,%r10
44
45	cmpq	$32,%rcx
46	jbe	101632f
47
48	cmpq	$256,%rcx
49	ja	1256f
50
51	ALIGN_TEXT
52103200:
53	movq	%r10,(%rdi)
54	movq	%r10,8(%rdi)
55	movq	%r10,16(%rdi)
56	movq	%r10,24(%rdi)
57	leaq	32(%rdi),%rdi
58	subq	$32,%rcx
59	cmpq	$32,%rcx
60	ja	103200b
61	cmpb	$16,%cl
62	ja	201632f
63	movq	%r10,-16(%rdi,%rcx)
64	movq	%r10,-8(%rdi,%rcx)
65	ret
66	ALIGN_TEXT
67101632:
68	cmpb	$16,%cl
69	jl	100816f
70201632:
71	movq	%r10,(%rdi)
72	movq	%r10,8(%rdi)
73	movq	%r10,-16(%rdi,%rcx)
74	movq	%r10,-8(%rdi,%rcx)
75	ret
76	ALIGN_TEXT
77100816:
78	cmpb	$8,%cl
79	jl	100408f
80	movq	%r10,(%rdi)
81	movq	%r10,-8(%rdi,%rcx)
82	ret
83	ALIGN_TEXT
84100408:
85	cmpb	$4,%cl
86	jl	100204f
87	movl	%r10d,(%rdi)
88	movl	%r10d,-4(%rdi,%rcx)
89	ret
90	ALIGN_TEXT
91100204:
92	cmpb	$2,%cl
93	jl	100001f
94	movw	%r10w,(%rdi)
95	movw	%r10w,-2(%rdi,%rcx)
96	ret
97	ALIGN_TEXT
98100001:
99	cmpb	$0,%cl
100	je	100000f
101	movb	%r10b,(%rdi)
102100000:
103	ret
104	ALIGN_TEXT
1051256:
106	movq	%rdi,%r9
107	movq	%r10,%rax
108	testl	$15,%edi
109	jnz	3f
1101:
111.if \erms == 1
112	rep
113	stosb
114	movq	%r9,%rax
115.else
116	movq	%rcx,%rdx
117	shrq	$3,%rcx
118	rep
119	stosq
120	movq	%r9,%rax
121	andl	$7,%edx
122	jnz	2f
123	ret
1242:
125	movq	%r10,-8(%rdi,%rdx)
126.endif
127	ret
128	ALIGN_TEXT
1293:
130	movq	%r10,(%rdi)
131	movq	%r10,8(%rdi)
132	movq	%rdi,%r8
133	andq	$15,%r8
134	leaq	-16(%rcx,%r8),%rcx
135	neg	%r8
136	leaq	16(%rdi,%r8),%rdi
137	jmp	1b
138.endm
139
140
141ENTRY(memset)
142	MEMSET erms=0
143END(memset)
144
145	.section .note.GNU-stack,"",%progbits
146