xref: /freebsd/lib/libc/aarch64/string/strspn.S (revision b91003acffe7b50dd6506be15116c6b42fc512c6)
1*b91003acSGetz Mikalsen/*-
2*b91003acSGetz Mikalsen * SPDX-License-Identifier: BSD-2-Clause
3*b91003acSGetz Mikalsen *
4*b91003acSGetz Mikalsen * Copyright (c) 2024 Getz Mikalsen <getz@FreeBSD.org>
5*b91003acSGetz Mikalsen*/
6*b91003acSGetz Mikalsen
7*b91003acSGetz Mikalsen#include <machine/asm.h>
8*b91003acSGetz Mikalsen
9*b91003acSGetz Mikalsen	.weak	strspn
10*b91003acSGetz Mikalsen	.set	strspn, __strspn
11*b91003acSGetz Mikalsen	.text
12*b91003acSGetz Mikalsen
13*b91003acSGetz MikalsenENTRY(__strspn)
14*b91003acSGetz Mikalsen
15*b91003acSGetz Mikalsen	/* check for special cases */
16*b91003acSGetz Mikalsen	ldrb	w4, [x1]		// first character in set
17*b91003acSGetz Mikalsen	cbz	w4, .Lzero		// empty set always returns 0
18*b91003acSGetz Mikalsen
19*b91003acSGetz Mikalsen	mov	x15, #1			// preload register with 1 for stores
20*b91003acSGetz Mikalsen
21*b91003acSGetz Mikalsen	// set is only one character
22*b91003acSGetz Mikalsen	ldrb	w5, [x1, #1]		// second character in the set
23*b91003acSGetz Mikalsen	cbz	w5, .Lsingle
24*b91003acSGetz Mikalsen
25*b91003acSGetz Mikalsen	stp	x29, x30, [sp, #-16]!
26*b91003acSGetz Mikalsen	mov	x29, sp
27*b91003acSGetz Mikalsen	sub	sp, sp, #256		// allocate 256 bytes on the stack
28*b91003acSGetz Mikalsen
29*b91003acSGetz Mikalsen	/* no special case matches -- prepare lookup table */
30*b91003acSGetz Mikalsen	mov	w3, #28
31*b91003acSGetz Mikalsen0:	add	x9, sp, x3, lsl #3
32*b91003acSGetz Mikalsen	stp	xzr, xzr, [x9]
33*b91003acSGetz Mikalsen	stp	xzr, xzr, [x9, #16]
34*b91003acSGetz Mikalsen	subs	w3, w3, #4
35*b91003acSGetz Mikalsen	b.cs	0b
36*b91003acSGetz Mikalsen
37*b91003acSGetz Mikalsen	strb	w15, [sp, x4]		// register first character in set
38*b91003acSGetz Mikalsen	add	x1, x1, #2
39*b91003acSGetz Mikalsen
40*b91003acSGetz Mikalsen	/* process remaining chars in set */
41*b91003acSGetz Mikalsen	.p2align 4
42*b91003acSGetz Mikalsen
43*b91003acSGetz Mikalsen
44*b91003acSGetz Mikalsen0:	ldrb	w4, [x1]		// next char in set
45*b91003acSGetz Mikalsen	strb	w15, [sp, x5]		// register previous char
46*b91003acSGetz Mikalsen	cbz	w4, 1f			// NUL encountered?
47*b91003acSGetz Mikalsen
48*b91003acSGetz Mikalsen	ldrb	w5, [x1, #1]
49*b91003acSGetz Mikalsen	add	x1, x1, #2
50*b91003acSGetz Mikalsen	strb	w15, [sp, x4]
51*b91003acSGetz Mikalsen	cbnz	w5, 0b
52*b91003acSGetz Mikalsen
53*b91003acSGetz Mikalsen1:	mov	x5, x0			// stash a copy of src
54*b91003acSGetz Mikalsen
55*b91003acSGetz Mikalsen	/* find mismatch */
56*b91003acSGetz Mikalsen	.p2align 4
57*b91003acSGetz Mikalsen0:	ldrb	w8, [x0]
58*b91003acSGetz Mikalsen	ldrb	w9, [sp, x8]
59*b91003acSGetz Mikalsen	cbz	w9, 2f
60*b91003acSGetz Mikalsen
61*b91003acSGetz Mikalsen	ldrb	w8, [x0, #1]
62*b91003acSGetz Mikalsen	ldrb	w9, [sp, x8]
63*b91003acSGetz Mikalsen	cbz	w9, 3f
64*b91003acSGetz Mikalsen
65*b91003acSGetz Mikalsen	ldrb	w8, [x0, #2]
66*b91003acSGetz Mikalsen	ldrb	w9, [sp, x8]
67*b91003acSGetz Mikalsen	cbz	w9, 4f
68*b91003acSGetz Mikalsen
69*b91003acSGetz Mikalsen	ldrb	w8, [x0, #3]
70*b91003acSGetz Mikalsen	add	x0, x0, #4
71*b91003acSGetz Mikalsen	ldrb	w9, [sp, x8]
72*b91003acSGetz Mikalsen	cbnz	w9, 0b
73*b91003acSGetz Mikalsen
74*b91003acSGetz Mikalsen	sub	x0, x0, #3
75*b91003acSGetz Mikalsen4:	sub	x5, x5, #1
76*b91003acSGetz Mikalsen3:	add	x0, x0, #1
77*b91003acSGetz Mikalsen2:	sub	x0, x0, x5
78*b91003acSGetz Mikalsen	mov	sp, x29
79*b91003acSGetz Mikalsen	ldp	x29, x30, [sp], #16
80*b91003acSGetz Mikalsen	ret
81*b91003acSGetz Mikalsen
82*b91003acSGetz Mikalsen.Lzero:
83*b91003acSGetz Mikalsen	mov	x0, #0
84*b91003acSGetz Mikalsen	ret
85*b91003acSGetz Mikalsen
86*b91003acSGetz Mikalsen.Lsingle:
87*b91003acSGetz Mikalsen	ldrb	w8, [x0, x5]
88*b91003acSGetz Mikalsen	cmp	w4, w8
89*b91003acSGetz Mikalsen	b.ne	1f
90*b91003acSGetz Mikalsen
91*b91003acSGetz Mikalsen	add	x5, x5, #1
92*b91003acSGetz Mikalsen	ldrb	w8, [x0, x5]
93*b91003acSGetz Mikalsen	cmp	w4, w8
94*b91003acSGetz Mikalsen	b.ne	1f
95*b91003acSGetz Mikalsen
96*b91003acSGetz Mikalsen	add	x5, x5, #1
97*b91003acSGetz Mikalsen	ldrb	w8, [x0, x5]
98*b91003acSGetz Mikalsen	cmp	w4, w8
99*b91003acSGetz Mikalsen	b.ne	1f
100*b91003acSGetz Mikalsen
101*b91003acSGetz Mikalsen	add	x5, x5, #1
102*b91003acSGetz Mikalsen	ldrb	w8, [x0, x5]
103*b91003acSGetz Mikalsen	add	x5, x5, #1
104*b91003acSGetz Mikalsen	cmp	w4, w8
105*b91003acSGetz Mikalsen	b.eq	.Lsingle
106*b91003acSGetz Mikalsen
107*b91003acSGetz Mikalsen	sub	x5, x5, #1
108*b91003acSGetz Mikalsen1:	mov	x0, x5
109*b91003acSGetz Mikalsen	ret
110*b91003acSGetz Mikalsen
111*b91003acSGetz MikalsenEND(__strspn)
112