xref: /freebsd/lib/libc/aarch64/string/strlen.S (revision 3863fec1ce2dc6033f094a085118605ea89db9e2)
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	strlen
10	.set	strlen, __strlen
11	.text
12
13ENTRY(__strlen)
14	bic	x10, x0, #0xf		// aligned src
15	and	x9, x0, #0xf
16	ldr	q0, [x10]
17	cmeq	v0.16b, v0.16b, #0
18	shrn	v0.8b, v0.8h, #4
19	fmov	x1, d0
20	cbz	x9, .Laligned
21	lsl	x2, x0, #2		// get the byte offset
22	lsr	x1, x1, x2		// shift by offset index
23	cbz	x1, .Lloop
24	rbit	x1, x1
25	clz	x0, x1
26	lsr	x0, x0, #2
27	ret
28
29.Laligned:
30	cbnz	x1, .Ldone
31
32.Lloop:
33	ldr	q0, [x10, #16]!
34	cmeq	v0.16b, v0.16b, #0
35	shrn	v0.8b, v0.8h, #4	// reduce to fit mask in GPR
36	fcmp	d0, #0.0
37	b.eq	.Lloop
38	fmov	x1, d0
39.Ldone:
40	sub	x0, x10, x0
41	rbit	x1, x1			// reverse bits as NEON has no ctz
42	clz	x3, x1
43	lsr	x3, x3, #2
44	add	x0, x0, x3
45	ret
46END(__strlen)
47