xref: /freebsd/lib/libc/aarch64/string/strlen.S (revision 6c05f3a74f30934ee60919cc97e16ec69b542b06)
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	fmov	x1, d0
37	cbz	x1, .Lloop
38.Ldone:
39	sub	x0, x10, x0
40	rbit	x1, x1			// reverse bits as NEON has no ctz
41	clz	x3, x1
42	lsr	x3, x3, #2
43	add	x0, x0, x3
44	ret
45END(__strlen)
46