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