1 /*
2  * __strlen_aarch64_sve - compute the length of a string
3  *
4  * Copyright (c) 2018-2021, Arm Limited.
5  * SPDX-License-Identifier: MIT
6  */
7 
8 #include "../asmdefs.h"
9 
10 #if __ARM_FEATURE_SVE
11 /* Assumptions:
12  *
13  * ARMv8-a, AArch64
14  * SVE Available.
15  */
16 
17 ENTRY (__strlen_aarch64_sve)
18 	PTR_ARG (0)
19 	setffr			/* initialize FFR */
20 	ptrue	p2.b		/* all ones; loop invariant */
21 	mov	x1, 0		/* initialize length */
22 
23 	/* Read a vector's worth of bytes, stopping on first fault.  */
24 	.p2align 4
25 0:	ldff1b	z0.b, p2/z, [x0, x1]
26 	rdffrs	p0.b, p2/z
27 	b.nlast	2f
28 
29 	/* First fault did not fail: the whole vector is valid.
30 	   Avoid depending on the contents of FFR beyond the branch.  */
31 	incb	x1, all			/* speculate increment */
32 	cmpeq	p1.b, p2/z, z0.b, 0	/* loop if no zeros */
33 	b.none	0b
34 	decb	x1, all			/* undo speculate */
35 
36 	/* Zero found.  Select the bytes before the first and count them.  */
37 1:	brkb	p0.b, p2/z, p1.b
38 	incp	x1, p0.b
39 	mov	x0, x1
40 	ret
41 
42 	/* First fault failed: only some of the vector is valid.
43 	   Perform the comparison only on the valid bytes.  */
44 2:	cmpeq	p1.b, p0/z, z0.b, 0
45 	b.any	1b
46 
47 	/* No zero found.  Re-init FFR, increment, and loop.  */
48 	setffr
49 	incp	x1, p0.b
50 	b	0b
51 
52 END (__strlen_aarch64_sve)
53 
54 #endif
55 
56