xref: /freebsd/lib/libc/riscv/string/memset.S (revision 40a958d5850ddda6d863558c8b31572f700d53ca)
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2024 Strahinja Stanisic <strajabot@FreeBSD.org>
5 */
6
7#include <machine/asm.h>
8
9/*
10 * register a0 - void *dest
11 * register a1 - int c
12 * register a2 - size_t len
13 */
14ENTRY(memset)
15	andi a1, a1, 0xFF
16
17	sltiu t1, a2, 8
18	mv t0, a0
19	bnez t1, .Lend
20
21	li t1, 0x0101010101010101
22	mul a1, a1, t1
23
24	andi t1, a0, 0b111
25	andi t0, a0, ~0b111
26
27	beqz t1, .Lloop_store_64
28
29	la t2, .Lduff_start
30	slli t3, t1, 2
31	add t2, t2, t3
32	jr -4(t2)
33.Lduff_start:
34	sb a1, 1(t0)
35	sb a1, 2(t0)
36	sb a1, 3(t0)
37	sb a1, 4(t0)
38	sb a1, 5(t0)
39	sb a1, 6(t0)
40	sb a1, 7(t0)
41
42	/* a3 = a3 -(8-a) <=> a3 = a3 + (a-8) */
43	addi t1, t1, -8
44	add a2, a2, t1
45	addi t0, t0, 8
46
47.Lloop_store_64:
48	slti t1, a2, 64
49	bnez t1, .Lstore_rest
50	sd a1, 0(t0)
51	sd a1, 8(t0)
52	sd a1, 16(t0)
53	sd a1, 24(t0)
54	sd a1, 32(t0)
55	sd a1, 40(t0)
56	sd a1, 48(t0)
57	sd a1, 56(t0)
58	addi a2, a2, -64
59	addi t0, t0, 64
60	j .Lloop_store_64
61
62.Lstore_rest:
63	la t2, .Lduff_rest
64	andi t3, a2, ~0b111
65	srli t4, t3, 1
66	sub t2, t2, t4
67	jr t2
68	sd a1, 56(t0)
69	sd a1, 48(t0)
70	sd a1, 40(t0)
71	sd a1, 32(t0)
72	sd a1, 24(t0)
73	sd a1, 16(t0)
74	sd a1, 8(t0)
75	sd a1, 0(t0)
76.Lduff_rest:
77	add t0, t0, t3
78	sub a2, a2, t3
79
80.Lend:
81	slli a2, a2, 2
82	la t2, .Lduff_end
83	sub t2, t2, a2
84	jr t2
85	sb a1, 6(t0)
86	sb a1, 5(t0)
87	sb a1, 4(t0)
88	sb a1, 3(t0)
89	sb a1, 2(t0)
90	sb a1, 1(t0)
91	sb a1, (t0)
92.Lduff_end:
93	ret
94END(memset)
95
96