1 /*
2  * __strcmp_aarch64_sve - compare two strings
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 (__strcmp_aarch64_sve)
18 	PTR_ARG (0)
19 	PTR_ARG (1)
20 	setffr				/* initialize FFR */
21 	ptrue	p1.b, all		/* all ones; loop invariant */
22 	mov	x2, 0			/* initialize offset */
23 
24 	/* Read a vector's worth of bytes, stopping on first fault.  */
25 	.p2align 4
26 0:	ldff1b	z0.b, p1/z, [x0, x2]
27 	ldff1b	z1.b, p1/z, [x1, x2]
28 	rdffrs	p0.b, p1/z
29 	b.nlast	2f
30 
31 	/* First fault did not fail: the whole vector is valid.
32 	   Avoid depending on the contents of FFR beyond the branch.  */
33 	incb	x2, all			/* skip bytes for next round */
34 	cmpeq	p2.b, p1/z, z0.b, z1.b	/* compare strings */
35 	cmpne	p3.b, p1/z, z0.b, 0	/* search for ~zero */
36 	nands	p2.b, p1/z, p2.b, p3.b	/* ~(eq & ~zero) -> ne | zero */
37 	b.none	0b
38 
39 	/* Found end-of-string or inequality.  */
40 1:	brkb	p2.b, p1/z, p2.b	/* find first such */
41 	lasta	w0, p2, z0.b		/* extract each char */
42 	lasta	w1, p2, z1.b
43 	sub	x0, x0, x1		/* return comparison */
44 	ret
45 
46 	/* First fault failed: only some of the vector is valid.
47 	   Perform the comparison only on the valid bytes.  */
48 2:	incp	x2, p0.b		/* skip bytes for next round */
49 	setffr				/* re-init FFR for next round */
50 	cmpeq	p2.b, p0/z, z0.b, z1.b	/* compare strings, as above */
51 	cmpne	p3.b, p0/z, z0.b, 0
52 	nands	p2.b, p0/z, p2.b, p3.b
53 	b.none	0b
54 	b	1b
55 
56 END (__strcmp_aarch64_sve)
57 
58 #endif
59 
60