1/*
2 * strcpy/stpcpy - copy a string returning pointer to start/end.
3 *
4 * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 * See https://llvm.org/LICENSE.txt for license information.
6 * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 */
8
9#if __ARM_FEATURE_SVE
10/* Assumptions:
11 *
12 * ARMv8-a, AArch64
13 * SVE Available.
14 */
15
16 .arch armv8-a+sve
17 .text
18
19/* To build as stpcpy, define BUILD_STPCPY before compiling this file. */
20#ifdef BUILD_STPCPY
21#define FUNC __stpcpy_aarch64_sve
22#else
23#define FUNC __strcpy_aarch64_sve
24#endif
25
26 .globl FUNC
27 .type FUNC, %function
28 .p2align 4
29FUNC:
30 setffr /* initialize FFR */
31 ptrue p2.b, all /* all ones; loop invariant */
32 mov x2, 0 /* initialize offset */
33
34 .p2align 4
35 /* Read a vector's worth of bytes, stopping on first fault. */
360: ldff1b z0.b, p2/z, [x1, x2]
37 rdffrs p0.b, p2/z
38 b.nlast 1f
39
40 /* First fault did not fail: the whole vector is valid.
41 Avoid depending on the contexts of FFR beyond the branch. */
42 cmpeq p1.b, p2/z, z0.b, 0 /* search for zeros */
43 b.any 2f
44
45 /* No zero found. Store the whole vector and loop. */
46 st1b z0.b, p2, [x0, x2]
47 incb x2, all
48 b 0b
49
50 /* First fault failed: only some of the vector is valid.
51 Perform the comparison only on the valid bytes. */
521: cmpeq p1.b, p0/z, z0.b, 0 /* search for zeros */
53 b.any 2f
54
55 /* No zero found. Store the valid portion of the vector and loop. */
56 setffr /* re-init FFR */
57 st1b z0.b, p0, [x0, x2]
58 incp x2, p0.b
59 b 0b
60
61 /* Zero found. Crop the vector to the found zero and finish. */
622: brka p0.b, p2/z, p1.b
63 st1b z0.b, p0, [x0, x2]
64#ifdef BUILD_STPCPY
65 add x0, x0, x2
66 sub x0, x0, 1
67 incp x0, p0.b
68#endif
69 ret
70
71 .size FUNC, . - FUNC
72#endif
73

source code of libc/AOR_v20.02/string/aarch64/strcpy-sve.S