xref: /freebsd/lib/libc/aarch64/string/strspn.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	strspn
10	.set	strspn, __strspn
11	.text
12
13ENTRY(__strspn)
14
15	/* check for special cases */
16	ldrb	w4, [x1]		// first character in set
17	cbz	w4, .Lzero		// empty set always returns 0
18
19	mov	x15, #1			// preload register with 1 for stores
20
21	// set is only one character
22	ldrb	w5, [x1, #1]		// second character in the set
23	cbz	w5, .Lsingle
24
25	stp	x29, x30, [sp, #-16]!
26	mov	x29, sp
27	sub	sp, sp, #256		// allocate 256 bytes on the stack
28
29	/* no special case matches -- prepare lookup table */
30	mov	w3, #28
310:	add	x9, sp, x3, lsl #3
32	stp	xzr, xzr, [x9]
33	stp	xzr, xzr, [x9, #16]
34	subs	w3, w3, #4
35	b.cs	0b
36
37	strb	w15, [sp, x4]		// register first character in set
38	add	x1, x1, #2
39
40	/* process remaining chars in set */
41	.p2align 4
42
43
440:	ldrb	w4, [x1]		// next char in set
45	strb	w15, [sp, x5]		// register previous char
46	cbz	w4, 1f			// NUL encountered?
47
48	ldrb	w5, [x1, #1]
49	add	x1, x1, #2
50	strb	w15, [sp, x4]
51	cbnz	w5, 0b
52
531:	mov	x5, x0			// stash a copy of src
54
55	/* find mismatch */
56	.p2align 4
570:	ldrb	w8, [x0]
58	ldrb	w9, [sp, x8]
59	cbz	w9, 2f
60
61	ldrb	w8, [x0, #1]
62	ldrb	w9, [sp, x8]
63	cbz	w9, 3f
64
65	ldrb	w8, [x0, #2]
66	ldrb	w9, [sp, x8]
67	cbz	w9, 4f
68
69	ldrb	w8, [x0, #3]
70	add	x0, x0, #4
71	ldrb	w9, [sp, x8]
72	cbnz	w9, 0b
73
74	sub	x0, x0, #3
754:	sub	x5, x5, #1
763:	add	x0, x0, #1
772:	sub	x0, x0, x5
78	mov	sp, x29
79	ldp	x29, x30, [sp], #16
80	ret
81
82.Lzero:
83	mov	x0, #0
84	ret
85
86.Lsingle:
87	ldrb	w8, [x0, x5]
88	cmp	w4, w8
89	b.ne	1f
90
91	add	x5, x5, #1
92	ldrb	w8, [x0, x5]
93	cmp	w4, w8
94	b.ne	1f
95
96	add	x5, x5, #1
97	ldrb	w8, [x0, x5]
98	cmp	w4, w8
99	b.ne	1f
100
101	add	x5, x5, #1
102	ldrb	w8, [x0, x5]
103	add	x5, x5, #1
104	cmp	w4, w8
105	b.eq	.Lsingle
106
107	sub	x5, x5, #1
1081:	mov	x0, x5
109	ret
110
111END(__strspn)
112