xref: /freebsd/lib/libc/aarch64/string/strcspn.S (revision dd21556857e8d40f66bf5ad54754d9d52669ebf7)
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2024 Getz Mikalsen <getz@FreeBSD.org>
5*/
6
7#include <machine/asm.h>
8
9	.weak	strcspn
10	.set	strcspn, __strcspn
11	.text
12
13ENTRY(__strcspn)
14	stp	x29, x30, [sp, #-16]!
15	mov	x29, sp
16	mov	x15, #1			// preload register with 1 for stores
17
18	/* check for special cases */
19	ldrb	w4, [x1]		// first character in the set
20	cbz	w4, .Lstrlen
21
22	movi	v0.16b, #0
23
24	ldrb	w5, [x1, #1]		// second character in the set
25	cbz	w5, .Lstrchr
26
27	sub	sp, sp, #256		// allocate 256 bytes on the stack
28
29	/* no special case matches -- prepare lookup table */
30	mov	w3, #20
31	.p2align 4
320:	add	x9, sp, x3, lsl #3
33	stp	xzr, xzr, [x9]
34	stp	xzr, xzr, [x9, #16]
35	subs	w3, w3, #4
36	b.cs	0b
37
38	/* utilize SIMD stores to speed up zeroing the table */
39	stp	q0, q0, [sp, #6*32]
40	stp	q0, q0, [sp, #7*32]
41
42	add	x1, x1, #2
43	strb	w15, [sp, x4]		// register first chars in the set
44	strb	w15, [sp, x5]
45
46	mov	x4, x0			// stash a copy of src
47
48	/* process remaining chars in set */
49	.p2align 4
500:	ldrb	w5, [x1]
51	strb	w15, [sp, x5]
52	cbz	w5, 1f			// end of set?
53
54	ldrb	w5, [x1, #1]
55	strb	w15, [sp, x5]
56	cbz	w5, 1f
57
58	add	x1, x1, #2
59	b	0b
60
61	/* find match */
62	.p2align 4
631:	ldrb	w8, [x0]
64	ldrb	w9, [sp, x8]
65	cbnz	w9, 2f
66
67	ldrb	w8, [x0, #1]
68	ldrb	w9, [sp, x8]
69	cbnz	w9, 3f
70
71	ldrb	w8, [x0, #2]
72	ldrb	w9, [sp, x8]
73	cbnz	w9, 4f
74
75	ldrb	w8, [x0, #3]
76	ldrb	w9, [sp, x8]
77	add	x0, x0, #4
78	cbz	w9, 1b
79
80	sub	x0, x0, #3		// fix up return value
814:	sub	x4, x4, #1
823:	add	x0, x0, #1
832:	sub	x0, x0, x4
84	mov	sp, x29
85	ldp	x29, x30, [sp], #16	// restore sp and lr
86	ret
87
88	/* set is empty, degrades to strlen */
89	.p2align 4
90.Lstrlen:
91	mov	sp, x29
92	ldp	x29, x30, [sp], #16	// restore sp and lr
93	b	strlen
94
95	/* just one character in set, degrades to strchrnul */
96	.p2align 4
97.Lstrchr:
98	stp	x0, x1, [sp, #-16]!
99	mov	x1, x4
100
101	bl	strchrnul
102
103	ldp	x18, x17, [sp], #16	// restore stashed src
104	sub	x0, x0, x18
105
106	ldp	x29, x30, [sp], #16	// Restore sp and lr
107	ret
108
109END(__strcspn)
110