1/* Set a block of memory to some byte value.
2   For SPARC v7.
3   Copyright (C) 1996-2022 Free Software Foundation, Inc.
4   This file is part of the GNU C Library.
5
6   The GNU C Library is free software; you can redistribute it and/or
7   modify it under the terms of the GNU Lesser General Public
8   License as published by the Free Software Foundation; either
9   version 2.1 of the License, or (at your option) any later version.
10
11   The GNU C Library is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   Lesser General Public License for more details.
15
16   You should have received a copy of the GNU Lesser General Public
17   License along with the GNU C Library; if not, see
18   <https://www.gnu.org/licenses/>.  */
19
20#include <sysdep.h>
21
22	/* Store 64 bytes at (BASE + OFFSET) using value SOURCE. */
23#define ZERO_BIG_BLOCK(base, offset, source)    	\
24	std		source, [base + offset + 0x00]; \
25	std		source, [base + offset + 0x08]; \
26	std		source, [base + offset + 0x10]; \
27	std		source, [base + offset + 0x18]; \
28	std		source, [base + offset + 0x20]; \
29	std		source, [base + offset + 0x28]; \
30	std		source, [base + offset + 0x30]; \
31	std		source, [base + offset + 0x38];
32
33#define ZERO_LAST_BLOCKS(base, offset, source)		\
34	std		source, [base - offset - 0x38]; \
35	std		source, [base - offset - 0x30]; \
36	std		source, [base - offset - 0x28]; \
37	std		source, [base - offset - 0x20]; \
38	std		source, [base - offset - 0x18]; \
39	std		source, [base - offset - 0x10]; \
40	std		source, [base - offset - 0x08]; \
41	std		source, [base - offset - 0x00];
42
43	.text
44	.align 4
45ENTRY(memset)
46	and		%o1, 0xff, %g3
47	sll		%g3, 8, %g2
48	or		%g3, %g2, %g3
49	sll		%g3, 16, %g2
50	or		%g3, %g2, %g3
51	orcc		%o2, %g0, %o1
521:	cmp		%o1, 7
53	bleu		7f
54	 mov		%o0, %g1
55
56	andcc		%o0, 3, %o2
57	bne		3f
584:	 andcc		%o0, 4, %g0
59
60	be		2f
61	 mov		%g3, %g2
62
63	st		%g3, [%o0]
64	sub		%o1, 4, %o1
65	add		%o0, 4, %o0
662:	andcc		%o1, 0xffffff80, %o3
67	be		9f
68	 andcc		%o1, 0x78, %o2
694:	ZERO_BIG_BLOCK	(%o0, 0x00, %g2)
70	subcc		%o3, 128, %o3
71	ZERO_BIG_BLOCK	(%o0, 0x40, %g2)
72	bne		4b
73	 add		%o0, 128, %o0
74
75	orcc		%o2, %g0, %g0
769:	be		6f
77	 andcc		%o1, 7, %o1
78
79	mov		%o7, %g4
80101:	call		100f
81	 srl		%o2, 1, %o3
82	mov		%g4, %o7
83	jmpl		%o4 + (20f + 64 - 101b), %g0
84	 add		%o0, %o2, %o0
85
86100:	retl
87	 sub		%o7, %o3, %o4
88
8920:	ZERO_LAST_BLOCKS(%o0, 0x48, %g2)
90	ZERO_LAST_BLOCKS(%o0, 0x08, %g2)
91
926:	be		8f
93	 andcc		%o1, 4, %g0
94	be		1f
95	 andcc		%o1, 2, %g0
96	st		%g3, [%o0]
97	add		%o0, 4, %o0
981:	be		1f
99	 andcc		%o1, 1, %g0
100	sth		%g3, [%o0]
101	add		%o0, 2, %o0
1021:	bne,a		8f
103	 stb		%g3, [%o0]
1048:	retl
105	 mov		%g1, %o0
1067:	orcc		%o1, 0, %g0
107	be		0f
108	 subcc		%o1, 1, %o1
109	stb		%g3, [%o0]
110	be		0f
111	 subcc		%o1, 1, %o1
112	stb		%g3, [%o0 + 1]
113	be		0f
114	 subcc		%o1, 1, %o1
115	stb		%g3, [%o0 + 2]
116	be		0f
117	 subcc		%o1, 1, %o1
118	stb		%g3, [%o0 + 3]
119	be		0f
120	 subcc		%o1, 1, %o1
121	stb		%g3, [%o0 + 4]
122	be		0f
123	 subcc		%o1, 1, %o1
124	stb		%g3, [%o0 + 5]
125	be		0f
126	 subcc		%o1, 1, %o1
127	stb		%g3, [%o0 + 6]
1280:	retl
129	 nop
130
1313:	cmp		%o2, 3
132	be		2f
133	 stb		%g3, [%o0]
134
135	cmp		%o2, 2
136	be		2f
137	 stb		%g3, [%o0 + 0x01]
138
139	stb		%g3, [%o0 + 0x02]
1402:	sub		%o2, 4, %o2
141	add		%o1, %o2, %o1
142	b		4b
143	 sub		%o0, %o2, %o0
144END(memset)
145libc_hidden_builtin_def (memset)
146