1 /*
2  * strcpy/stpcpy - copy a string returning pointer to start/end.
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 /* To build as stpcpy, define BUILD_STPCPY before compiling this file.  */
18 #ifdef BUILD_STPCPY
19 #define FUNC  __stpcpy_aarch64_sve
20 #else
21 #define FUNC  __strcpy_aarch64_sve
22 #endif
23 
24 ENTRY (FUNC)
25 	PTR_ARG (0)
26 	PTR_ARG (1)
27 	setffr				/* initialize FFR */
28 	ptrue	p2.b, all		/* all ones; loop invariant */
29 	mov	x2, 0			/* initialize offset */
30 
31 	.p2align 4
32 	/* Read a vector's worth of bytes, stopping on first fault.  */
33 0:	ldff1b	z0.b, p2/z, [x1, x2]
34 	rdffrs	p0.b, p2/z
35 	b.nlast	1f
36 
37 	/* First fault did not fail: the whole vector is valid.
38 	   Avoid depending on the contexts of FFR beyond the branch.  */
39 	cmpeq	p1.b, p2/z, z0.b, 0	/* search for zeros */
40 	b.any	2f
41 
42 	/* No zero found.  Store the whole vector and loop.  */
43 	st1b	z0.b, p2, [x0, x2]
44 	incb	x2, all
45 	b	0b
46 
47 	/* First fault failed: only some of the vector is valid.
48 	   Perform the comparison only on the valid bytes.  */
49 1:	cmpeq	p1.b, p0/z, z0.b, 0	/* search for zeros */
50 	b.any	2f
51 
52 	/* No zero found.  Store the valid portion of the vector and loop.  */
53 	setffr				/* re-init FFR */
54 	st1b	z0.b, p0, [x0, x2]
55 	incp	x2, p0.b
56 	b	0b
57 
58 	/* Zero found.  Crop the vector to the found zero and finish.  */
59 2:	brka	p0.b, p2/z, p1.b
60 	st1b	z0.b, p0, [x0, x2]
61 #ifdef BUILD_STPCPY
62 	add	x0, x0, x2
63 	sub	x0, x0, 1
64 	incp	x0, p0.b
65 #endif
66 	ret
67 
68 END (FUNC)
69 
70 #endif
71 
72